blob: ce09904264ee51da555a2271e5514be5be725048 [file] [log] [blame]
// 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);
}