• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fpdfapi/parser/cpdf_simple_parser.h"
8 
9 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
10 
CPDF_SimpleParser(pdfium::span<const uint8_t> input)11 CPDF_SimpleParser::CPDF_SimpleParser(pdfium::span<const uint8_t> input)
12     : data_(input) {}
13 
14 CPDF_SimpleParser::~CPDF_SimpleParser() = default;
15 
GetWord()16 ByteStringView CPDF_SimpleParser::GetWord() {
17   uint8_t ch;
18 
19   // Skip whitespace and comment lines.
20   while (true) {
21     if (data_.size() <= cur_pos_)
22       return ByteStringView();
23 
24     ch = data_[cur_pos_++];
25     while (PDFCharIsWhitespace(ch)) {
26       if (data_.size() <= cur_pos_)
27         return ByteStringView();
28       ch = data_[cur_pos_++];
29     }
30 
31     if (ch != '%')
32       break;
33 
34     while (true) {
35       if (data_.size() <= cur_pos_)
36         return ByteStringView();
37 
38       ch = data_[cur_pos_++];
39       if (PDFCharIsLineEnding(ch))
40         break;
41     }
42   }
43 
44   uint8_t dwSize = 0;
45   uint32_t start_pos = cur_pos_ - 1;
46   if (PDFCharIsDelimiter(ch)) {
47     // Find names
48     if (ch == '/') {
49       while (true) {
50         if (data_.size() <= cur_pos_)
51           break;
52 
53         ch = data_[cur_pos_++];
54         if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
55           cur_pos_--;
56           dwSize = cur_pos_ - start_pos;
57           break;
58         }
59       }
60       return data_.subspan(start_pos, dwSize);
61     }
62 
63     dwSize = 1;
64     if (ch == '<') {
65       if (data_.size() <= cur_pos_)
66         return data_.subspan(start_pos, dwSize);
67 
68       ch = data_[cur_pos_++];
69       if (ch == '<') {
70         dwSize = 2;
71       } else {
72         while (cur_pos_ < data_.size() && data_[cur_pos_] != '>')
73           cur_pos_++;
74 
75         if (cur_pos_ < data_.size())
76           cur_pos_++;
77 
78         dwSize = cur_pos_ - start_pos;
79       }
80     } else if (ch == '>') {
81       if (data_.size() <= cur_pos_)
82         return data_.subspan(start_pos, dwSize);
83 
84       ch = data_[cur_pos_++];
85       if (ch == '>')
86         dwSize = 2;
87       else
88         cur_pos_--;
89     } else if (ch == '(') {
90       int level = 1;
91       while (cur_pos_ < data_.size()) {
92         if (data_[cur_pos_] == ')') {
93           level--;
94           if (level == 0)
95             break;
96         }
97 
98         if (data_[cur_pos_] == '\\') {
99           if (data_.size() <= cur_pos_)
100             break;
101 
102           cur_pos_++;
103         } else if (data_[cur_pos_] == '(') {
104           level++;
105         }
106         if (data_.size() <= cur_pos_)
107           break;
108 
109         cur_pos_++;
110       }
111       if (cur_pos_ < data_.size())
112         cur_pos_++;
113 
114       dwSize = cur_pos_ - start_pos;
115     }
116     return data_.subspan(start_pos, dwSize);
117   }
118 
119   dwSize = 1;
120   while (cur_pos_ < data_.size()) {
121     ch = data_[cur_pos_++];
122 
123     if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
124       cur_pos_--;
125       break;
126     }
127     dwSize++;
128   }
129   return data_.subspan(start_pos, dwSize);
130 }
131