parse method

Tokenizes the whole stream.

Implementation

List<PdfContentOperator> parse() {
  final lexer = PdfContentLexer(data);
  final operators = <PdfContentOperator>[];
  var operands = <PdfContentValue>[];

  while (true) {
    final token = lexer.next();
    if (token.kind == PdfContentTokenKind.endOfData) break;

    switch (token.kind) {
      case PdfContentTokenKind.comment:
        if (keepComments) operators.add(PdfContentComment(token.text));
        break;

      case PdfContentTokenKind.keyword:
        final word = token.text;
        if (word == 'true') {
          _push(operands, const PdfContentBool(true));
          break;
        }
        if (word == 'false') {
          _push(operands, const PdfContentBool(false));
          break;
        }
        if (word == 'null') {
          _push(operands, const PdfContentNull());
          break;
        }
        if (word == 'BI') {
          final image = _readInlineImage(lexer);
          if (image != null) operators.add(image);
          operands = <PdfContentValue>[];
          break;
        }
        if (word == '{' || word == '}') {
          // PostScript function delimiters do not occur in content
          // streams; if they show up they are preserved as a bare
          // operator.
          operators.add(PdfContentOperator(word));
          operands = <PdfContentValue>[];
          break;
        }
        operators.add(PdfContentOperator(word, operands));
        operands = <PdfContentValue>[];
        break;

      default:
        final value = _valueOf(token, lexer);
        if (value != null) _push(operands, value);
    }
  }

  // Operands with no operator at the end of the stream are discarded:
  // there is no operation for them to belong to.
  return operators;
}