|  | // Copyright 2016 The PDFium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
|  |  | 
|  | #include "core/fpdfapi/parser/cpdf_simple_parser.h" | 
|  |  | 
|  | #include "core/fpdfapi/parser/fpdf_parser_utility.h" | 
|  |  | 
|  | CPDF_SimpleParser::CPDF_SimpleParser(pdfium::span<const uint8_t> input) | 
|  | : data_(input) {} | 
|  |  | 
|  | CPDF_SimpleParser::~CPDF_SimpleParser() = default; | 
|  |  | 
|  | ByteStringView CPDF_SimpleParser::GetWord() { | 
|  | uint8_t ch; | 
|  |  | 
|  | // Skip whitespace and comment lines. | 
|  | while (true) { | 
|  | if (data_.size() <= cur_pos_) | 
|  | return ByteStringView(); | 
|  |  | 
|  | ch = data_[cur_pos_++]; | 
|  | while (PDFCharIsWhitespace(ch)) { | 
|  | if (data_.size() <= cur_pos_) | 
|  | return ByteStringView(); | 
|  | ch = data_[cur_pos_++]; | 
|  | } | 
|  |  | 
|  | if (ch != '%') | 
|  | break; | 
|  |  | 
|  | while (true) { | 
|  | if (data_.size() <= cur_pos_) | 
|  | return ByteStringView(); | 
|  |  | 
|  | ch = data_[cur_pos_++]; | 
|  | if (PDFCharIsLineEnding(ch)) | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | uint8_t dwSize = 0; | 
|  | uint32_t start_pos = cur_pos_ - 1; | 
|  | if (PDFCharIsDelimiter(ch)) { | 
|  | // Find names | 
|  | if (ch == '/') { | 
|  | while (true) { | 
|  | if (data_.size() <= cur_pos_) | 
|  | break; | 
|  |  | 
|  | ch = data_[cur_pos_++]; | 
|  | if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) { | 
|  | cur_pos_--; | 
|  | dwSize = cur_pos_ - start_pos; | 
|  | break; | 
|  | } | 
|  | } | 
|  | return data_.subspan(start_pos, dwSize); | 
|  | } | 
|  |  | 
|  | dwSize = 1; | 
|  | if (ch == '<') { | 
|  | if (data_.size() <= cur_pos_) | 
|  | return data_.subspan(start_pos, dwSize); | 
|  |  | 
|  | ch = data_[cur_pos_++]; | 
|  | if (ch == '<') { | 
|  | dwSize = 2; | 
|  | } else { | 
|  | while (cur_pos_ < data_.size() && data_[cur_pos_] != '>') | 
|  | cur_pos_++; | 
|  |  | 
|  | if (cur_pos_ < data_.size()) | 
|  | cur_pos_++; | 
|  |  | 
|  | dwSize = cur_pos_ - start_pos; | 
|  | } | 
|  | } else if (ch == '>') { | 
|  | if (data_.size() <= cur_pos_) | 
|  | return data_.subspan(start_pos, dwSize); | 
|  |  | 
|  | ch = data_[cur_pos_++]; | 
|  | if (ch == '>') | 
|  | dwSize = 2; | 
|  | else | 
|  | cur_pos_--; | 
|  | } else if (ch == '(') { | 
|  | int level = 1; | 
|  | while (cur_pos_ < data_.size()) { | 
|  | if (data_[cur_pos_] == ')') { | 
|  | level--; | 
|  | if (level == 0) | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (data_[cur_pos_] == '\\') { | 
|  | if (data_.size() <= cur_pos_) | 
|  | break; | 
|  |  | 
|  | cur_pos_++; | 
|  | } else if (data_[cur_pos_] == '(') { | 
|  | level++; | 
|  | } | 
|  | if (data_.size() <= cur_pos_) | 
|  | break; | 
|  |  | 
|  | cur_pos_++; | 
|  | } | 
|  | if (cur_pos_ < data_.size()) | 
|  | cur_pos_++; | 
|  |  | 
|  | dwSize = cur_pos_ - start_pos; | 
|  | } | 
|  | return data_.subspan(start_pos, dwSize); | 
|  | } | 
|  |  | 
|  | dwSize = 1; | 
|  | while (cur_pos_ < data_.size()) { | 
|  | ch = data_[cur_pos_++]; | 
|  |  | 
|  | if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { | 
|  | cur_pos_--; | 
|  | break; | 
|  | } | 
|  | dwSize++; | 
|  | } | 
|  | return data_.subspan(start_pos, dwSize); | 
|  | } |