decode method

({Map<BlankNodeTerm, String> blankNodeLabels, Iterable<Quad> quads}) decode(
  1. String input, {
  2. String? documentUrl,
  3. Map<String, BlankNodeTerm>? bnodeMap,
})

Implementation

({Iterable<Quad> quads, Map<BlankNodeTerm, String> blankNodeLabels}) decode(
    String input,
    {String? documentUrl,
    Map<String, BlankNodeTerm>? bnodeMap}) {
  _logger.fine(
    'Parsing N-Quads document${documentUrl != null ? " with base URL: $documentUrl" : ""}',
  );

  final List<Quad> quads = [];
  final List<String> lines = input.split('\n');
  final Map<String, BlankNodeTerm> blankNodeMap = bnodeMap ?? {};
  int lineNumber = 0;

  for (final line in lines) {
    lineNumber++;
    final trimmed = line.trim();

    // Skip empty lines and comments
    if (trimmed.isEmpty || trimmed.startsWith('#')) {
      continue;
    }

    // Remove trailing comments while respecting literals and IRIs.
    final withoutComment = _stripComment(trimmed).trim();
    if (withoutComment.isEmpty) {
      continue;
    }

    try {
      final quad = _parseLine(withoutComment, lineNumber, blankNodeMap);
      quads.add(quad);
    } catch (e) {
      throw RdfDecoderException(
        'Error parsing N-Quads at line $lineNumber: ${e.toString()}',
        format: _formatName,
        source: SourceLocation(
          line: lineNumber - 1, // Convert to 0-based line number
          column: 0,
          context: withoutComment,
        ),
      );
    }
  }

  final blankNodeLabels = {
    for (final entry in blankNodeMap.entries) entry.value: entry.key
  };

  if (blankNodeLabels.length != blankNodeMap.length) {
    throw RdfException(
        'Inconsistent blank node labeling: some blank nodes have duplicate labels.');
  }

  return (quads: quads, blankNodeLabels: blankNodeLabels);
}