OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fpdfapi/fpdf_parser.h" | 7 #include "../../../include/fpdfapi/fpdf_parser.h" |
8 const char PDF_CharType[256] = { | 8 const char PDF_CharType[256] = { |
9 //NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO S
I | 9 // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO |
10 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', '
R', | 10 // SI |
11 | 11 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', |
12 //DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS U
S | 12 'R', |
13 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 13 |
14 | 14 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS |
15 //SP ! " # $ % & ´ ( ) * + , - .
/ | 15 // US |
16 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', '
D', | 16 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
17 | 17 'R', |
18 // 0 1 2 3 4 5 6 7 8 9 : ; < = >
? | 18 |
19 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', '
R', | 19 // SP ! " # $ % & ´ ( ) * + , - . |
20 | 20 // / |
21 // @ A B C D E F G H I J K L M N
O | 21 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', |
22 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 22 'D', |
23 | 23 |
24 // P Q R S T U V W X Y Z [ \ ] ^
_ | 24 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
25 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', '
R', | 25 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', |
26 | 26 'R', |
27 // ` a b c d e f g h i j k l m n
o | 27 |
28 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 28 // @ A B C D E F G H I J K L M N O |
29 | 29 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
30 // p q r s t u v w x y z { | } ~ D
EL | 30 'R', |
31 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', '
R', | 31 |
32 | 32 // P Q R S T U V W X Y Z [ \ ] ^ _ |
33 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 33 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', |
34 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 34 'R', |
35 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 35 |
36 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 36 // ` a b c d e f g h i j k l m n o |
37 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 37 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
38 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 38 'R', |
39 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
R', | 39 |
40 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', '
W' | 40 // p q r s t u v w x y z { | } ~ |
41 }; | 41 // DEL |
| 42 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', |
| 43 'R', |
| 44 |
| 45 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 46 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 47 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 48 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 49 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 50 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 51 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 52 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', |
| 53 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'}; |
42 | 54 |
43 #ifndef MAX_PATH | 55 #ifndef MAX_PATH |
44 #define MAX_PATH 4096 | 56 #define MAX_PATH 4096 |
45 #endif | 57 #endif |
46 CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) | 58 CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) { |
47 { | 59 m_pData = pData; |
48 m_pData = pData; | 60 m_dwSize = dwSize; |
49 m_dwSize = dwSize; | 61 m_dwCurPos = 0; |
50 m_dwCurPos = 0; | 62 } |
51 } | 63 CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) { |
52 CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) | 64 m_pData = str.GetPtr(); |
53 { | 65 m_dwSize = str.GetLength(); |
54 m_pData = str.GetPtr(); | 66 m_dwCurPos = 0; |
55 m_dwSize = str.GetLength(); | 67 } |
56 m_dwCurPos = 0; | 68 void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, |
57 } | 69 FX_DWORD& dwSize, |
58 void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, FX_DWORD& dwSize, int&
type) | 70 int& type) { |
59 { | 71 pStart = NULL; |
60 pStart = NULL; | 72 dwSize = 0; |
61 dwSize = 0; | 73 type = PDFWORD_EOF; |
62 type = PDFWORD_EOF; | 74 uint8_t ch; |
63 uint8_t ch; | 75 char chartype; |
64 char chartype; | 76 while (1) { |
| 77 if (m_dwSize <= m_dwCurPos) { |
| 78 return; |
| 79 } |
| 80 ch = m_pData[m_dwCurPos++]; |
| 81 chartype = PDF_CharType[ch]; |
| 82 while (chartype == 'W') { |
| 83 if (m_dwSize <= m_dwCurPos) { |
| 84 return; |
| 85 } |
| 86 ch = m_pData[m_dwCurPos++]; |
| 87 chartype = PDF_CharType[ch]; |
| 88 } |
| 89 if (ch != '%') { |
| 90 break; |
| 91 } |
65 while (1) { | 92 while (1) { |
| 93 if (m_dwSize <= m_dwCurPos) { |
| 94 return; |
| 95 } |
| 96 ch = m_pData[m_dwCurPos++]; |
| 97 if (ch == '\r' || ch == '\n') { |
| 98 break; |
| 99 } |
| 100 } |
| 101 chartype = PDF_CharType[ch]; |
| 102 } |
| 103 FX_DWORD start_pos = m_dwCurPos - 1; |
| 104 pStart = m_pData + start_pos; |
| 105 if (chartype == 'D') { |
| 106 if (ch == '/') { |
| 107 while (1) { |
66 if (m_dwSize <= m_dwCurPos) { | 108 if (m_dwSize <= m_dwCurPos) { |
67 return; | 109 return; |
68 } | 110 } |
69 ch = m_pData[m_dwCurPos++]; | 111 ch = m_pData[m_dwCurPos++]; |
70 chartype = PDF_CharType[ch]; | 112 chartype = PDF_CharType[ch]; |
71 while (chartype == 'W') { | 113 if (chartype != 'R' && chartype != 'N') { |
72 if (m_dwSize <= m_dwCurPos) { | 114 m_dwCurPos--; |
73 return; | 115 dwSize = m_dwCurPos - start_pos; |
74 } | 116 type = PDFWORD_NAME; |
75 ch = m_pData[m_dwCurPos++]; | 117 return; |
76 chartype = PDF_CharType[ch]; | 118 } |
77 } | 119 } |
78 if (ch != '%') { | 120 } else { |
79 break; | 121 type = PDFWORD_DELIMITER; |
80 } | 122 dwSize = 1; |
81 while (1) { | 123 if (ch == '<') { |
82 if (m_dwSize <= m_dwCurPos) { | 124 if (m_dwSize <= m_dwCurPos) { |
83 return; | 125 return; |
84 } | 126 } |
85 ch = m_pData[m_dwCurPos++]; | 127 ch = m_pData[m_dwCurPos++]; |
86 if (ch == '\r' || ch == '\n') { | 128 if (ch == '<') { |
87 break; | 129 dwSize = 2; |
88 } | |
89 } | |
90 chartype = PDF_CharType[ch]; | |
91 } | |
92 FX_DWORD start_pos = m_dwCurPos - 1; | |
93 pStart = m_pData + start_pos; | |
94 if (chartype == 'D') { | |
95 if (ch == '/') { | |
96 while (1) { | |
97 if (m_dwSize <= m_dwCurPos) { | |
98 return; | |
99 } | |
100 ch = m_pData[m_dwCurPos++]; | |
101 chartype = PDF_CharType[ch]; | |
102 if (chartype != 'R' && chartype != 'N') { | |
103 m_dwCurPos --; | |
104 dwSize = m_dwCurPos - start_pos; | |
105 type = PDFWORD_NAME; | |
106 return; | |
107 } | |
108 } | |
109 } else { | 130 } else { |
110 type = PDFWORD_DELIMITER; | 131 m_dwCurPos--; |
111 dwSize = 1; | 132 } |
112 if (ch == '<') { | 133 } else if (ch == '>') { |
113 if (m_dwSize <= m_dwCurPos) { | |
114 return; | |
115 } | |
116 ch = m_pData[m_dwCurPos++]; | |
117 if (ch == '<') { | |
118 dwSize = 2; | |
119 } else { | |
120 m_dwCurPos --; | |
121 } | |
122 } else if (ch == '>') { | |
123 if (m_dwSize <= m_dwCurPos) { | |
124 return; | |
125 } | |
126 ch = m_pData[m_dwCurPos++]; | |
127 if (ch == '>') { | |
128 dwSize = 2; | |
129 } else { | |
130 m_dwCurPos --; | |
131 } | |
132 } | |
133 } | |
134 return; | |
135 } | |
136 type = PDFWORD_NUMBER; | |
137 dwSize = 1; | |
138 while (1) { | |
139 if (chartype != 'N') { | |
140 type = PDFWORD_TEXT; | |
141 } | |
142 if (m_dwSize <= m_dwCurPos) { | 134 if (m_dwSize <= m_dwCurPos) { |
143 return; | 135 return; |
144 } | 136 } |
145 ch = m_pData[m_dwCurPos++]; | 137 ch = m_pData[m_dwCurPos++]; |
146 chartype = PDF_CharType[ch]; | 138 if (ch == '>') { |
147 if (chartype == 'D' || chartype == 'W') { | 139 dwSize = 2; |
148 m_dwCurPos --; | 140 } else { |
149 break; | 141 m_dwCurPos--; |
150 } | 142 } |
151 dwSize ++; | 143 } |
152 } | 144 } |
153 } | 145 return; |
154 CFX_ByteStringC CPDF_SimpleParser::GetWord() | 146 } |
155 { | 147 type = PDFWORD_NUMBER; |
156 const uint8_t* pStart; | 148 dwSize = 1; |
157 FX_DWORD dwSize; | 149 while (1) { |
158 int type; | 150 if (chartype != 'N') { |
159 ParseWord(pStart, dwSize, type); | 151 type = PDFWORD_TEXT; |
160 if (dwSize == 1 && pStart[0] == '<') { | 152 } |
161 while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { | 153 if (m_dwSize <= m_dwCurPos) { |
162 m_dwCurPos ++; | 154 return; |
163 } | 155 } |
164 if (m_dwCurPos < m_dwSize) { | 156 ch = m_pData[m_dwCurPos++]; |
165 m_dwCurPos ++; | 157 chartype = PDF_CharType[ch]; |
166 } | 158 if (chartype == 'D' || chartype == 'W') { |
167 return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pDa
ta))); | 159 m_dwCurPos--; |
168 } | 160 break; |
169 if (dwSize == 1 && pStart[0] == '(') { | 161 } |
170 int level = 1; | 162 dwSize++; |
171 while (m_dwCurPos < m_dwSize) { | 163 } |
172 if (m_pData[m_dwCurPos] == ')') { | 164 } |
173 level --; | 165 CFX_ByteStringC CPDF_SimpleParser::GetWord() { |
174 if (level == 0) { | 166 const uint8_t* pStart; |
175 break; | 167 FX_DWORD dwSize; |
176 } | 168 int type; |
177 } | 169 ParseWord(pStart, dwSize, type); |
178 if (m_pData[m_dwCurPos] == '\\') { | 170 if (dwSize == 1 && pStart[0] == '<') { |
179 if (m_dwSize <= m_dwCurPos) { | 171 while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { |
180 break; | 172 m_dwCurPos++; |
181 } | 173 } |
182 m_dwCurPos ++; | 174 if (m_dwCurPos < m_dwSize) { |
183 } else if (m_pData[m_dwCurPos] == '(') { | 175 m_dwCurPos++; |
184 level ++; | 176 } |
185 } | 177 return CFX_ByteStringC(pStart, |
186 if (m_dwSize <= m_dwCurPos) { | 178 (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
187 break; | 179 } |
188 } | 180 if (dwSize == 1 && pStart[0] == '(') { |
189 m_dwCurPos ++; | 181 int level = 1; |
190 } | 182 while (m_dwCurPos < m_dwSize) { |
191 if (m_dwCurPos < m_dwSize) { | 183 if (m_pData[m_dwCurPos] == ')') { |
192 m_dwCurPos ++; | 184 level--; |
193 } | 185 if (level == 0) { |
194 return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pDa
ta))); | 186 break; |
195 } | 187 } |
196 return CFX_ByteStringC(pStart, dwSize); | 188 } |
197 } | 189 if (m_pData[m_dwCurPos] == '\\') { |
198 FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) | 190 if (m_dwSize <= m_dwCurPos) { |
199 { | 191 break; |
200 int token_len = token.GetLength(); | 192 } |
201 while (m_dwCurPos < m_dwSize - token_len) { | 193 m_dwCurPos++; |
202 if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0)
{ | 194 } else if (m_pData[m_dwCurPos] == '(') { |
203 break; | 195 level++; |
204 } | 196 } |
205 m_dwCurPos ++; | 197 if (m_dwSize <= m_dwCurPos) { |
206 } | 198 break; |
207 if (m_dwCurPos == m_dwSize - token_len) { | 199 } |
208 return FALSE; | 200 m_dwCurPos++; |
209 } | 201 } |
210 m_dwCurPos += token_len; | 202 if (m_dwCurPos < m_dwSize) { |
211 return TRUE; | 203 m_dwCurPos++; |
212 } | 204 } |
213 FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) | 205 return CFX_ByteStringC(pStart, |
214 { | 206 (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
215 while (1) { | 207 } |
216 CFX_ByteStringC word = GetWord(); | 208 return CFX_ByteStringC(pStart, dwSize); |
217 if (word.IsEmpty()) { | 209 } |
218 return FALSE; | 210 FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) { |
219 } | 211 int token_len = token.GetLength(); |
220 if (word == token) { | 212 while (m_dwCurPos < m_dwSize - token_len) { |
221 return TRUE; | 213 if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0) { |
222 } | 214 break; |
223 } | 215 } |
| 216 m_dwCurPos++; |
| 217 } |
| 218 if (m_dwCurPos == m_dwSize - token_len) { |
224 return FALSE; | 219 return FALSE; |
225 } | 220 } |
226 FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, const
CFX_ByteStringC& end_token, | 221 m_dwCurPos += token_len; |
227 FX_DWORD& start_pos, FX_DWORD& end_pos) | 222 return TRUE; |
228 { | 223 } |
229 if (!start_token.IsEmpty()) { | 224 FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) { |
230 if (!SkipWord(start_token)) { | 225 while (1) { |
231 return FALSE; | 226 CFX_ByteStringC word = GetWord(); |
232 } | 227 if (word.IsEmpty()) { |
233 start_pos = m_dwCurPos; | 228 return FALSE; |
234 } | 229 } |
235 while (1) { | 230 if (word == token) { |
236 end_pos = m_dwCurPos; | 231 return TRUE; |
237 CFX_ByteStringC word = GetWord(); | 232 } |
238 if (word.IsEmpty()) { | 233 } |
239 return FALSE; | 234 return FALSE; |
240 } | 235 } |
241 if (word == end_token) { | 236 FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, |
242 return TRUE; | 237 const CFX_ByteStringC& end_token, |
243 } | 238 FX_DWORD& start_pos, |
244 } | 239 FX_DWORD& end_pos) { |
245 return FALSE; | 240 if (!start_token.IsEmpty()) { |
246 } | 241 if (!SkipWord(start_token)) { |
247 FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, int nParam
s) | 242 return FALSE; |
248 { | 243 } |
249 nParams ++; | 244 start_pos = m_dwCurPos; |
250 FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); | 245 } |
251 int buf_index = 0; | 246 while (1) { |
252 int buf_count = 0; | 247 end_pos = m_dwCurPos; |
253 while (1) { | 248 CFX_ByteStringC word = GetWord(); |
254 pBuf[buf_index++] = m_dwCurPos; | 249 if (word.IsEmpty()) { |
255 if (buf_index == nParams) { | 250 return FALSE; |
256 buf_index = 0; | 251 } |
257 } | 252 if (word == end_token) { |
258 buf_count ++; | 253 return TRUE; |
259 if (buf_count > nParams) { | 254 } |
260 buf_count = nParams; | 255 } |
261 } | 256 return FALSE; |
262 CFX_ByteStringC word = GetWord(); | 257 } |
263 if (word.IsEmpty()) { | 258 FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, |
264 FX_Free(pBuf); | 259 int nParams) { |
265 return FALSE; | 260 nParams++; |
266 } | 261 FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); |
267 if (word == token) { | 262 int buf_index = 0; |
268 if (buf_count < nParams) { | 263 int buf_count = 0; |
269 continue; | 264 while (1) { |
270 } | 265 pBuf[buf_index++] = m_dwCurPos; |
271 m_dwCurPos = pBuf[buf_index]; | 266 if (buf_index == nParams) { |
272 FX_Free(pBuf); | 267 buf_index = 0; |
273 return TRUE; | 268 } |
274 } | 269 buf_count++; |
275 } | 270 if (buf_count > nParams) { |
276 return FALSE; | 271 buf_count = nParams; |
277 } | 272 } |
278 static int _hex2dec(char ch) | 273 CFX_ByteStringC word = GetWord(); |
279 { | 274 if (word.IsEmpty()) { |
280 if (ch >= '0' && ch <= '9') { | 275 FX_Free(pBuf); |
281 return ch - '0'; | 276 return FALSE; |
282 } | 277 } |
283 if (ch >= 'a' && ch <= 'f') { | 278 if (word == token) { |
284 return ch - 'a' + 10; | 279 if (buf_count < nParams) { |
285 } | 280 continue; |
286 if (ch >= 'A' && ch <= 'F') { | 281 } |
287 return ch - 'A' + 10; | 282 m_dwCurPos = pBuf[buf_index]; |
288 } | 283 FX_Free(pBuf); |
| 284 return TRUE; |
| 285 } |
| 286 } |
| 287 return FALSE; |
| 288 } |
| 289 static int _hex2dec(char ch) { |
| 290 if (ch >= '0' && ch <= '9') { |
| 291 return ch - '0'; |
| 292 } |
| 293 if (ch >= 'a' && ch <= 'f') { |
| 294 return ch - 'a' + 10; |
| 295 } |
| 296 if (ch >= 'A' && ch <= 'F') { |
| 297 return ch - 'A' + 10; |
| 298 } |
| 299 return 0; |
| 300 } |
| 301 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) { |
| 302 int size = bstr.GetLength(); |
| 303 const FX_CHAR* pSrc = bstr.GetCStr(); |
| 304 if (FXSYS_memchr(pSrc, '#', size) == NULL) { |
| 305 return bstr; |
| 306 } |
| 307 CFX_ByteString result; |
| 308 FX_CHAR* pDestStart = result.GetBuffer(size); |
| 309 FX_CHAR* pDest = pDestStart; |
| 310 for (int i = 0; i < size; i++) { |
| 311 if (pSrc[i] == '#' && i < size - 2) { |
| 312 *pDest++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); |
| 313 i += 2; |
| 314 } else { |
| 315 *pDest++ = pSrc[i]; |
| 316 } |
| 317 } |
| 318 result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); |
| 319 return result; |
| 320 } |
| 321 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) { |
| 322 if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { |
| 323 return orig; |
| 324 } |
| 325 return PDF_NameDecode(CFX_ByteStringC(orig)); |
| 326 } |
| 327 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) { |
| 328 uint8_t* src_buf = (uint8_t*)orig.c_str(); |
| 329 int src_len = orig.GetLength(); |
| 330 int dest_len = 0; |
| 331 int i; |
| 332 for (i = 0; i < src_len; i++) { |
| 333 uint8_t ch = src_buf[i]; |
| 334 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || |
| 335 PDF_CharType[ch] == 'D') { |
| 336 dest_len += 3; |
| 337 } else { |
| 338 dest_len++; |
| 339 } |
| 340 } |
| 341 if (dest_len == src_len) { |
| 342 return orig; |
| 343 } |
| 344 CFX_ByteString res; |
| 345 FX_CHAR* dest_buf = res.GetBuffer(dest_len); |
| 346 dest_len = 0; |
| 347 for (i = 0; i < src_len; i++) { |
| 348 uint8_t ch = src_buf[i]; |
| 349 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || |
| 350 PDF_CharType[ch] == 'D') { |
| 351 dest_buf[dest_len++] = '#'; |
| 352 dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; |
| 353 dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; |
| 354 } else { |
| 355 dest_buf[dest_len++] = ch; |
| 356 } |
| 357 } |
| 358 dest_buf[dest_len] = 0; |
| 359 res.ReleaseBuffer(); |
| 360 return res; |
| 361 } |
| 362 CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { |
| 363 if (pObj == NULL) { |
| 364 buf << FX_BSTRC(" null"); |
| 365 return buf; |
| 366 } |
| 367 switch (pObj->GetType()) { |
| 368 case PDFOBJ_NULL: |
| 369 buf << FX_BSTRC(" null"); |
| 370 break; |
| 371 case PDFOBJ_BOOLEAN: |
| 372 case PDFOBJ_NUMBER: |
| 373 buf << " " << pObj->GetString(); |
| 374 break; |
| 375 case PDFOBJ_STRING: { |
| 376 CFX_ByteString str = pObj->GetString(); |
| 377 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); |
| 378 buf << PDF_EncodeString(str, bHex); |
| 379 break; |
| 380 } |
| 381 case PDFOBJ_NAME: { |
| 382 CFX_ByteString str = pObj->GetString(); |
| 383 buf << FX_BSTRC("/") << PDF_NameEncode(str); |
| 384 break; |
| 385 } |
| 386 case PDFOBJ_REFERENCE: { |
| 387 CPDF_Reference* p = (CPDF_Reference*)pObj; |
| 388 buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); |
| 389 break; |
| 390 } |
| 391 case PDFOBJ_ARRAY: { |
| 392 CPDF_Array* p = (CPDF_Array*)pObj; |
| 393 buf << FX_BSTRC("["); |
| 394 for (FX_DWORD i = 0; i < p->GetCount(); i++) { |
| 395 CPDF_Object* pElement = p->GetElement(i); |
| 396 if (pElement->GetObjNum()) { |
| 397 buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); |
| 398 } else { |
| 399 buf << pElement; |
| 400 } |
| 401 } |
| 402 buf << FX_BSTRC("]"); |
| 403 break; |
| 404 } |
| 405 case PDFOBJ_DICTIONARY: { |
| 406 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; |
| 407 buf << FX_BSTRC("<<"); |
| 408 FX_POSITION pos = p->GetStartPos(); |
| 409 while (pos) { |
| 410 CFX_ByteString key; |
| 411 CPDF_Object* pValue = p->GetNextElement(pos, key); |
| 412 buf << FX_BSTRC("/") << PDF_NameEncode(key); |
| 413 if (pValue->GetObjNum()) { |
| 414 buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); |
| 415 } else { |
| 416 buf << pValue; |
| 417 } |
| 418 } |
| 419 buf << FX_BSTRC(">>"); |
| 420 break; |
| 421 } |
| 422 case PDFOBJ_STREAM: { |
| 423 CPDF_Stream* p = (CPDF_Stream*)pObj; |
| 424 buf << p->GetDict() << FX_BSTRC("stream\r\n"); |
| 425 CPDF_StreamAcc acc; |
| 426 acc.LoadAllData(p, TRUE); |
| 427 buf.AppendBlock(acc.GetData(), acc.GetSize()); |
| 428 buf << FX_BSTRC("\r\nendstream"); |
| 429 break; |
| 430 } |
| 431 default: |
| 432 ASSERT(FALSE); |
| 433 break; |
| 434 } |
| 435 return buf; |
| 436 } |
| 437 FX_FLOAT PDF_ClipFloat(FX_FLOAT f) { |
| 438 if (f < 0) { |
289 return 0; | 439 return 0; |
290 } | 440 } |
291 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) | 441 if (f > 1.0f) { |
292 { | 442 return 1.0f; |
293 int size = bstr.GetLength(); | 443 } |
294 const FX_CHAR* pSrc = bstr.GetCStr(); | 444 return f; |
295 if (FXSYS_memchr(pSrc, '#', size) == NULL) { | 445 } |
296 return bstr; | 446 static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) { |
297 } | 447 CPDF_Array* pLimits = pNode->GetArray("Limits"); |
298 CFX_ByteString result; | 448 if (pLimits && |
299 FX_CHAR* pDestStart = result.GetBuffer(size); | 449 (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1))) { |
300 FX_CHAR* pDest = pDestStart; | |
301 for (int i = 0; i < size; i ++) { | |
302 if (pSrc[i] == '#' && i < size - 2) { | |
303 *pDest ++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); | |
304 i += 2; | |
305 } else { | |
306 *pDest ++ = pSrc[i]; | |
307 } | |
308 } | |
309 result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); | |
310 return result; | |
311 } | |
312 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) | |
313 { | |
314 if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { | |
315 return orig; | |
316 } | |
317 return PDF_NameDecode(CFX_ByteStringC(orig)); | |
318 } | |
319 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) | |
320 { | |
321 uint8_t* src_buf = (uint8_t*)orig.c_str(); | |
322 int src_len = orig.GetLength(); | |
323 int dest_len = 0; | |
324 int i; | |
325 for (i = 0; i < src_len; i ++) { | |
326 uint8_t ch = src_buf[i]; | |
327 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || | |
328 PDF_CharType[ch] == 'D') { | |
329 dest_len += 3; | |
330 } else { | |
331 dest_len ++; | |
332 } | |
333 } | |
334 if (dest_len == src_len) { | |
335 return orig; | |
336 } | |
337 CFX_ByteString res; | |
338 FX_CHAR* dest_buf = res.GetBuffer(dest_len); | |
339 dest_len = 0; | |
340 for (i = 0; i < src_len; i ++) { | |
341 uint8_t ch = src_buf[i]; | |
342 if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || | |
343 PDF_CharType[ch] == 'D') { | |
344 dest_buf[dest_len++] = '#'; | |
345 dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; | |
346 dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; | |
347 } else { | |
348 dest_buf[dest_len++] = ch; | |
349 } | |
350 } | |
351 dest_buf[dest_len] = 0; | |
352 res.ReleaseBuffer(); | |
353 return res; | |
354 } | |
355 CFX_ByteTextBuf& operator << (CFX_ByteTextBuf& buf, const CPDF_Object* pObj) | |
356 { | |
357 if (pObj == NULL) { | |
358 buf << FX_BSTRC(" null"); | |
359 return buf; | |
360 } | |
361 switch (pObj->GetType()) { | |
362 case PDFOBJ_NULL: | |
363 buf << FX_BSTRC(" null"); | |
364 break; | |
365 case PDFOBJ_BOOLEAN: | |
366 case PDFOBJ_NUMBER: | |
367 buf << " " << pObj->GetString(); | |
368 break; | |
369 case PDFOBJ_STRING: { | |
370 CFX_ByteString str = pObj->GetString(); | |
371 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); | |
372 buf << PDF_EncodeString(str, bHex); | |
373 break; | |
374 } | |
375 case PDFOBJ_NAME: { | |
376 CFX_ByteString str = pObj->GetString(); | |
377 buf << FX_BSTRC("/") << PDF_NameEncode(str); | |
378 break; | |
379 } | |
380 case PDFOBJ_REFERENCE: { | |
381 CPDF_Reference* p = (CPDF_Reference*)pObj; | |
382 buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); | |
383 break; | |
384 } | |
385 case PDFOBJ_ARRAY: { | |
386 CPDF_Array* p = (CPDF_Array*)pObj; | |
387 buf << FX_BSTRC("["); | |
388 for (FX_DWORD i = 0; i < p->GetCount(); i ++) { | |
389 CPDF_Object* pElement = p->GetElement(i); | |
390 if (pElement->GetObjNum()) { | |
391 buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); | |
392 } else { | |
393 buf << pElement; | |
394 } | |
395 } | |
396 buf << FX_BSTRC("]"); | |
397 break; | |
398 } | |
399 case PDFOBJ_DICTIONARY: { | |
400 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; | |
401 buf << FX_BSTRC("<<"); | |
402 FX_POSITION pos = p->GetStartPos(); | |
403 while (pos) { | |
404 CFX_ByteString key; | |
405 CPDF_Object* pValue = p->GetNextElement(pos, key); | |
406 buf << FX_BSTRC("/") << PDF_NameEncode(key); | |
407 if (pValue->GetObjNum()) { | |
408 buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); | |
409 } else { | |
410 buf << pValue; | |
411 } | |
412 } | |
413 buf << FX_BSTRC(">>"); | |
414 break; | |
415 } | |
416 case PDFOBJ_STREAM: { | |
417 CPDF_Stream* p = (CPDF_Stream*)pObj; | |
418 buf << p->GetDict() << FX_BSTRC("stream\r\n"); | |
419 CPDF_StreamAcc acc; | |
420 acc.LoadAllData(p, TRUE); | |
421 buf.AppendBlock(acc.GetData(), acc.GetSize()); | |
422 buf << FX_BSTRC("\r\nendstream"); | |
423 break; | |
424 } | |
425 default: | |
426 ASSERT(FALSE); | |
427 break; | |
428 } | |
429 return buf; | |
430 } | |
431 FX_FLOAT PDF_ClipFloat(FX_FLOAT f) | |
432 { | |
433 if (f < 0) { | |
434 return 0; | |
435 } | |
436 if (f > 1.0f) { | |
437 return 1.0f; | |
438 } | |
439 return f; | |
440 } | |
441 static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) | |
442 { | |
443 CPDF_Array* pLimits = pNode->GetArray("Limits"); | |
444 if (pLimits && (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1)
)) { | |
445 return NULL; | |
446 } | |
447 CPDF_Array* pNumbers = pNode->GetArray("Nums"); | |
448 if (pNumbers) { | |
449 FX_DWORD dwCount = pNumbers->GetCount() / 2; | |
450 for (FX_DWORD i = 0; i < dwCount; i ++) { | |
451 int index = pNumbers->GetInteger(i * 2); | |
452 if (num == index) { | |
453 return pNumbers->GetElementValue(i * 2 + 1); | |
454 } | |
455 if (index > num) { | |
456 break; | |
457 } | |
458 } | |
459 return NULL; | |
460 } | |
461 CPDF_Array* pKids = pNode->GetArray("Kids"); | |
462 if (pKids == NULL) { | |
463 return NULL; | |
464 } | |
465 for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { | |
466 CPDF_Dictionary* pKid = pKids->GetDict(i); | |
467 if (pKid == NULL) { | |
468 continue; | |
469 } | |
470 CPDF_Object* pFound = SearchNumberNode(pKid, num); | |
471 if (pFound) { | |
472 return pFound; | |
473 } | |
474 } | |
475 return NULL; | 450 return NULL; |
476 } | 451 } |
477 CPDF_Object* CPDF_NumberTree::LookupValue(int num) | 452 CPDF_Array* pNumbers = pNode->GetArray("Nums"); |
478 { | 453 if (pNumbers) { |
479 return SearchNumberNode(m_pRoot, num); | 454 FX_DWORD dwCount = pNumbers->GetCount() / 2; |
480 } | 455 for (FX_DWORD i = 0; i < dwCount; i++) { |
| 456 int index = pNumbers->GetInteger(i * 2); |
| 457 if (num == index) { |
| 458 return pNumbers->GetElementValue(i * 2 + 1); |
| 459 } |
| 460 if (index > num) { |
| 461 break; |
| 462 } |
| 463 } |
| 464 return NULL; |
| 465 } |
| 466 CPDF_Array* pKids = pNode->GetArray("Kids"); |
| 467 if (pKids == NULL) { |
| 468 return NULL; |
| 469 } |
| 470 for (FX_DWORD i = 0; i < pKids->GetCount(); i++) { |
| 471 CPDF_Dictionary* pKid = pKids->GetDict(i); |
| 472 if (pKid == NULL) { |
| 473 continue; |
| 474 } |
| 475 CPDF_Object* pFound = SearchNumberNode(pKid, num); |
| 476 if (pFound) { |
| 477 return pFound; |
| 478 } |
| 479 } |
| 480 return NULL; |
| 481 } |
| 482 CPDF_Object* CPDF_NumberTree::LookupValue(int num) { |
| 483 return SearchNumberNode(m_pRoot, num); |
| 484 } |
OLD | NEW |