OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
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 "xfa/fgas/xml/fgas_sax.h" | |
8 | |
9 #include <algorithm> | |
10 | |
11 #include "xfa/fxfa/include/xfa_checksum.h" | |
12 | |
13 namespace { | |
14 | |
15 const uint32_t kSaxFileBufSize = 32768; | |
16 | |
17 } // namespace | |
18 | |
19 CFX_SAXFile::CFX_SAXFile() | |
20 : m_pFile(NULL), | |
21 m_dwStart(0), | |
22 m_dwEnd(0), | |
23 m_dwCur(0), | |
24 m_pBuf(NULL), | |
25 m_dwBufSize(0), | |
26 m_dwBufIndex(0) {} | |
27 FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead* pFile, | |
28 uint32_t dwStart, | |
29 uint32_t dwLen) { | |
30 ASSERT(m_pFile == NULL && pFile != NULL); | |
31 uint32_t dwSize = pFile->GetSize(); | |
32 if (dwStart >= dwSize) { | |
33 return FALSE; | |
34 } | |
35 if (dwLen == static_cast<uint32_t>(-1) || dwStart + dwLen > dwSize) { | |
36 dwLen = dwSize - dwStart; | |
37 } | |
38 if (dwLen == 0) { | |
39 return FALSE; | |
40 } | |
41 m_dwBufSize = std::min(dwLen, kSaxFileBufSize); | |
42 m_pBuf = FX_Alloc(uint8_t, m_dwBufSize); | |
43 if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) { | |
44 return FALSE; | |
45 } | |
46 m_dwStart = dwStart; | |
47 m_dwEnd = dwStart + dwLen; | |
48 m_dwCur = dwStart; | |
49 m_pFile = pFile; | |
50 m_dwBufIndex = 0; | |
51 return TRUE; | |
52 } | |
53 FX_BOOL CFX_SAXFile::ReadNextBlock() { | |
54 ASSERT(m_pFile != NULL); | |
55 uint32_t dwSize = m_dwEnd - m_dwCur; | |
56 if (dwSize == 0) { | |
57 return FALSE; | |
58 } | |
59 m_dwBufSize = std::min(dwSize, kSaxFileBufSize); | |
60 if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) { | |
61 return FALSE; | |
62 } | |
63 m_dwBufIndex = 0; | |
64 return TRUE; | |
65 } | |
66 void CFX_SAXFile::Reset() { | |
67 if (m_pBuf) { | |
68 FX_Free(m_pBuf); | |
69 m_pBuf = NULL; | |
70 } | |
71 m_pFile = NULL; | |
72 } | |
73 CFX_SAXReader::CFX_SAXReader() | |
74 : m_File(), | |
75 m_pHandler(nullptr), | |
76 m_iState(-1), | |
77 m_pRoot(nullptr), | |
78 m_pCurItem(nullptr), | |
79 m_dwItemID(0), | |
80 m_iDataSize(256), | |
81 m_iNameSize(256), | |
82 m_dwParseMode(0), | |
83 m_pCommentContext(nullptr) { | |
84 m_pszData = FX_Alloc(uint8_t, m_iDataSize); | |
85 m_pszName = FX_Alloc(uint8_t, m_iNameSize); | |
86 } | |
87 CFX_SAXReader::~CFX_SAXReader() { | |
88 Reset(); | |
89 if (m_pszData) { | |
90 FX_Free(m_pszData); | |
91 m_pszData = NULL; | |
92 } | |
93 if (m_pszName) { | |
94 FX_Free(m_pszName); | |
95 m_pszName = NULL; | |
96 } | |
97 } | |
98 void CFX_SAXReader::Reset() { | |
99 m_File.Reset(); | |
100 CFX_SAXItem* pItem = m_pRoot; | |
101 while (pItem) { | |
102 CFX_SAXItem* pNext = pItem->m_pNext; | |
103 delete pItem; | |
104 pItem = pNext; | |
105 } | |
106 m_pRoot = NULL; | |
107 m_pCurItem = NULL; | |
108 m_dwItemID = 0; | |
109 m_SkipStack.RemoveAll(); | |
110 m_SkipChar = 0; | |
111 m_iDataLength = 0; | |
112 m_iEntityStart = -1; | |
113 m_iNameLength = 0; | |
114 m_iDataPos = 0; | |
115 if (m_pCommentContext) { | |
116 delete m_pCommentContext; | |
117 m_pCommentContext = NULL; | |
118 } | |
119 } | |
120 inline void CFX_SAXReader::Push() { | |
121 CFX_SAXItem* pNew = new CFX_SAXItem; | |
122 pNew->m_dwID = ++m_dwItemID; | |
123 pNew->m_bSkip = m_pCurItem->m_bSkip; | |
124 pNew->m_pPrev = m_pCurItem; | |
125 m_pCurItem->m_pNext = pNew; | |
126 m_pCurItem = pNew; | |
127 } | |
128 inline void CFX_SAXReader::Pop() { | |
129 if (!m_pCurItem) { | |
130 return; | |
131 } | |
132 CFX_SAXItem* pPrev = m_pCurItem->m_pPrev; | |
133 pPrev->m_pNext = NULL; | |
134 delete m_pCurItem; | |
135 m_pCurItem = pPrev; | |
136 } | |
137 inline void CFX_SAXReader::AppendData(uint8_t ch) { | |
138 ReallocDataBuffer(); | |
139 m_pszData[m_iDataPos++] = ch; | |
140 } | |
141 inline void CFX_SAXReader::AppendName(uint8_t ch) { | |
142 ReallocNameBuffer(); | |
143 m_pszName[m_iDataPos++] = ch; | |
144 } | |
145 void CFX_SAXReader::ReallocDataBuffer() { | |
146 if (m_iDataPos < m_iDataSize) { | |
147 return; | |
148 } | |
149 if (m_iDataSize <= 1024 * 1024) { | |
150 m_iDataSize *= 2; | |
151 } else { | |
152 m_iDataSize += 1024 * 1024; | |
153 } | |
154 m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize); | |
155 } | |
156 void CFX_SAXReader::ReallocNameBuffer() { | |
157 if (m_iDataPos < m_iNameSize) { | |
158 return; | |
159 } | |
160 if (m_iNameSize <= 1024 * 1024) { | |
161 m_iNameSize *= 2; | |
162 } else { | |
163 m_iNameSize += 1024 * 1024; | |
164 } | |
165 m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize); | |
166 } | |
167 inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) { | |
168 return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21; | |
169 } | |
170 int32_t CFX_SAXReader::StartParse(IFX_FileRead* pFile, | |
171 uint32_t dwStart, | |
172 uint32_t dwLen, | |
173 uint32_t dwParseMode) { | |
174 m_iState = -1; | |
175 Reset(); | |
176 if (!m_File.StartFile(pFile, dwStart, dwLen)) { | |
177 return -1; | |
178 } | |
179 m_iState = 0; | |
180 m_eMode = FX_SAXMODE_Text; | |
181 m_ePrevMode = FX_SAXMODE_Text; | |
182 m_bCharData = FALSE; | |
183 m_dwDataOffset = 0; | |
184 m_pRoot = m_pCurItem = new CFX_SAXItem; | |
185 m_pCurItem->m_dwID = ++m_dwItemID; | |
186 m_dwParseMode = dwParseMode; | |
187 return 0; | |
188 } | |
189 typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)(); | |
190 static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = { | |
191 &CFX_SAXReader::ParseText, | |
192 &CFX_SAXReader::ParseNodeStart, | |
193 &CFX_SAXReader::ParseDeclOrComment, | |
194 &CFX_SAXReader::ParseDeclNode, | |
195 &CFX_SAXReader::ParseComment, | |
196 &CFX_SAXReader::ParseCommentContent, | |
197 &CFX_SAXReader::ParseTagName, | |
198 &CFX_SAXReader::ParseTagAttributeName, | |
199 &CFX_SAXReader::ParseTagAttributeEqual, | |
200 &CFX_SAXReader::ParseTagAttributeValue, | |
201 &CFX_SAXReader::ParseMaybeClose, | |
202 &CFX_SAXReader::ParseTagClose, | |
203 &CFX_SAXReader::ParseTagEnd, | |
204 &CFX_SAXReader::ParseTargetData, | |
205 }; | |
206 int32_t CFX_SAXReader::ContinueParse(IFX_Pause* pPause) { | |
207 if (m_iState < 0 || m_iState > 99) { | |
208 return m_iState; | |
209 } | |
210 while (m_File.m_dwCur < m_File.m_dwEnd) { | |
211 uint32_t& index = m_File.m_dwBufIndex; | |
212 uint32_t size = m_File.m_dwBufSize; | |
213 const uint8_t* pBuf = m_File.m_pBuf; | |
214 while (index < size) { | |
215 m_CurByte = pBuf[index]; | |
216 (this->*g_FX_SAXReader_LPFParse[m_eMode])(); | |
217 index++; | |
218 } | |
219 m_File.m_dwCur += index; | |
220 m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 / | |
221 (m_File.m_dwEnd - m_File.m_dwStart); | |
222 if (m_File.m_dwCur >= m_File.m_dwEnd) { | |
223 break; | |
224 } | |
225 if (!m_File.ReadNextBlock()) { | |
226 m_iState = -2; | |
227 break; | |
228 } | |
229 m_dwDataOffset = 0; | |
230 if (pPause && pPause->NeedToPauseNow()) { | |
231 break; | |
232 } | |
233 } | |
234 return m_iState; | |
235 } | |
236 void CFX_SAXReader::ParseChar(uint8_t ch) { | |
237 ReallocDataBuffer(); | |
238 m_pszData[m_iDataPos] = ch; | |
239 if (m_iEntityStart > -1 && ch == ';') { | |
240 int32_t iSaveEntityStart = m_iEntityStart; | |
241 CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1, | |
242 m_iDataPos - m_iEntityStart - 1); | |
243 int32_t iLen = csEntity.GetLength(); | |
244 if (iLen > 0) { | |
245 if (csEntity[0] == '#') { | |
246 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) { | |
247 ch = 0; | |
248 uint8_t w; | |
249 if (iLen > 1 && csEntity[1] == 'x') { | |
250 for (int32_t i = 2; i < iLen; i++) { | |
251 w = csEntity[i]; | |
252 if (w >= '0' && w <= '9') { | |
253 ch = (ch << 4) + w - '0'; | |
254 } else if (w >= 'A' && w <= 'F') { | |
255 ch = (ch << 4) + w - 55; | |
256 } else if (w >= 'a' && w <= 'f') { | |
257 ch = (ch << 4) + w - 87; | |
258 } else { | |
259 break; | |
260 } | |
261 } | |
262 } else { | |
263 for (int32_t i = 1; i < iLen; i++) { | |
264 w = csEntity[i]; | |
265 if (w < '0' || w > '9') { | |
266 break; | |
267 } | |
268 ch = ch * 10 + w - '0'; | |
269 } | |
270 } | |
271 if (ch != 0) { | |
272 m_pszData[m_iEntityStart++] = ch; | |
273 } | |
274 } | |
275 } else { | |
276 if (csEntity.Compare("amp") == 0) { | |
277 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) { | |
278 m_pszData[m_iEntityStart++] = '&'; | |
279 } | |
280 } else if (csEntity.Compare("lt") == 0) { | |
281 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) { | |
282 m_pszData[m_iEntityStart++] = '<'; | |
283 } | |
284 } else if (csEntity.Compare("gt") == 0) { | |
285 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) { | |
286 m_pszData[m_iEntityStart++] = '>'; | |
287 } | |
288 } else if (csEntity.Compare("apos") == 0) { | |
289 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) { | |
290 m_pszData[m_iEntityStart++] = '\''; | |
291 } | |
292 } else if (csEntity.Compare("quot") == 0) { | |
293 if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) { | |
294 m_pszData[m_iEntityStart++] = '\"'; | |
295 } | |
296 } | |
297 } | |
298 } | |
299 if (iSaveEntityStart != m_iEntityStart) { | |
300 m_iDataPos = m_iEntityStart; | |
301 m_iEntityStart = -1; | |
302 } else { | |
303 m_iDataPos++; | |
304 m_iEntityStart = -1; | |
305 } | |
306 } else { | |
307 if (m_iEntityStart < 0 && ch == '&') { | |
308 m_iEntityStart = m_iDataPos; | |
309 } | |
310 m_iDataPos++; | |
311 } | |
312 } | |
313 void CFX_SAXReader::ParseText() { | |
314 if (m_CurByte == '<') { | |
315 if (m_iDataPos > 0) { | |
316 m_iDataLength = m_iDataPos; | |
317 m_iDataPos = 0; | |
318 if (m_pHandler) { | |
319 NotifyData(); | |
320 } | |
321 } | |
322 Push(); | |
323 m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; | |
324 m_eMode = FX_SAXMODE_NodeStart; | |
325 return; | |
326 } | |
327 if (m_iDataPos < 1 && SkipSpace(m_CurByte)) { | |
328 return; | |
329 } | |
330 ParseChar(m_CurByte); | |
331 } | |
332 void CFX_SAXReader::ParseNodeStart() { | |
333 if (m_CurByte == '?') { | |
334 m_pCurItem->m_eNode = FX_SAXNODE_Instruction; | |
335 m_eMode = FX_SAXMODE_TagName; | |
336 return; | |
337 } | |
338 if (m_CurByte == '!') { | |
339 m_eMode = FX_SAXMODE_DeclOrComment; | |
340 return; | |
341 } | |
342 if (m_CurByte == '/') { | |
343 m_eMode = FX_SAXMODE_TagEnd; | |
344 return; | |
345 } | |
346 if (m_CurByte == '>') { | |
347 Pop(); | |
348 m_eMode = FX_SAXMODE_Text; | |
349 return; | |
350 } | |
351 if (m_CurByte > 0x20) { | |
352 m_dwDataOffset = m_File.m_dwBufIndex; | |
353 m_pCurItem->m_eNode = FX_SAXNODE_Tag; | |
354 m_eMode = FX_SAXMODE_TagName; | |
355 AppendData(m_CurByte); | |
356 } | |
357 } | |
358 void CFX_SAXReader::ParseDeclOrComment() { | |
359 if (m_CurByte == '-') { | |
360 m_eMode = FX_SAXMODE_Comment; | |
361 m_pCurItem->m_eNode = FX_SAXNODE_Comment; | |
362 if (m_pCommentContext == NULL) { | |
363 m_pCommentContext = new CFX_SAXCommentContext; | |
364 } | |
365 m_pCommentContext->m_iHeaderCount = 1; | |
366 m_pCommentContext->m_iTailCount = 0; | |
367 } else { | |
368 m_eMode = FX_SAXMODE_DeclNode; | |
369 m_dwDataOffset = m_File.m_dwBufIndex; | |
370 m_SkipChar = '>'; | |
371 m_SkipStack.Add('>'); | |
372 SkipNode(); | |
373 } | |
374 } | |
375 void CFX_SAXReader::ParseComment() { | |
376 m_pCommentContext->m_iHeaderCount = 2; | |
377 m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; | |
378 m_eMode = FX_SAXMODE_CommentContent; | |
379 } | |
380 void CFX_SAXReader::ParseCommentContent() { | |
381 if (m_CurByte == '-') { | |
382 m_pCommentContext->m_iTailCount++; | |
383 } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) { | |
384 m_iDataLength = m_iDataPos; | |
385 m_iDataPos = 0; | |
386 if (m_pHandler) { | |
387 NotifyTargetData(); | |
388 } | |
389 Pop(); | |
390 m_eMode = FX_SAXMODE_Text; | |
391 } else { | |
392 while (m_pCommentContext->m_iTailCount > 0) { | |
393 AppendData('-'); | |
394 m_pCommentContext->m_iTailCount--; | |
395 } | |
396 AppendData(m_CurByte); | |
397 } | |
398 } | |
399 void CFX_SAXReader::ParseDeclNode() { | |
400 SkipNode(); | |
401 } | |
402 void CFX_SAXReader::ParseTagName() { | |
403 if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' || | |
404 m_CurByte == '?') { | |
405 m_iDataLength = m_iDataPos; | |
406 m_iDataPos = 0; | |
407 if (m_pHandler) { | |
408 NotifyEnter(); | |
409 } | |
410 if (m_CurByte < 0x21) { | |
411 m_eMode = FX_SAXMODE_TagAttributeName; | |
412 } else if (m_CurByte == '/' || m_CurByte == '?') { | |
413 m_ePrevMode = m_eMode; | |
414 m_eMode = FX_SAXMODE_TagMaybeClose; | |
415 } else { | |
416 if (m_pHandler) { | |
417 NotifyBreak(); | |
418 } | |
419 m_eMode = FX_SAXMODE_Text; | |
420 } | |
421 } else { | |
422 AppendData(m_CurByte); | |
423 } | |
424 } | |
425 void CFX_SAXReader::ParseTagAttributeName() { | |
426 if (m_CurByte < 0x21 || m_CurByte == '=') { | |
427 if (m_iDataPos < 1 && m_CurByte < 0x21) { | |
428 return; | |
429 } | |
430 m_iNameLength = m_iDataPos; | |
431 m_iDataPos = 0; | |
432 m_SkipChar = 0; | |
433 m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue | |
434 : FX_SAXMODE_TagAttributeEqual; | |
435 return; | |
436 } | |
437 if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') { | |
438 if (m_CurByte == '/' || m_CurByte == '?') { | |
439 m_ePrevMode = m_eMode; | |
440 m_eMode = FX_SAXMODE_TagMaybeClose; | |
441 } else { | |
442 if (m_pHandler) { | |
443 NotifyBreak(); | |
444 } | |
445 m_eMode = FX_SAXMODE_Text; | |
446 } | |
447 return; | |
448 } | |
449 if (m_iDataPos < 1) { | |
450 m_dwDataOffset = m_File.m_dwBufIndex; | |
451 } | |
452 AppendName(m_CurByte); | |
453 } | |
454 void CFX_SAXReader::ParseTagAttributeEqual() { | |
455 if (m_CurByte == '=') { | |
456 m_SkipChar = 0; | |
457 m_eMode = FX_SAXMODE_TagAttributeValue; | |
458 return; | |
459 } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
460 m_iDataPos = m_iNameLength; | |
461 AppendName(0x20); | |
462 m_eMode = FX_SAXMODE_TargetData; | |
463 ParseTargetData(); | |
464 } | |
465 } | |
466 void CFX_SAXReader::ParseTagAttributeValue() { | |
467 if (m_SkipChar) { | |
468 if (m_SkipChar == m_CurByte) { | |
469 { | |
470 m_iDataLength = m_iDataPos; | |
471 m_iDataPos = 0; | |
472 if (m_pHandler) { | |
473 NotifyAttribute(); | |
474 } | |
475 } | |
476 m_SkipChar = 0; | |
477 m_eMode = FX_SAXMODE_TagAttributeName; | |
478 return; | |
479 } | |
480 ParseChar(m_CurByte); | |
481 return; | |
482 } | |
483 if (m_CurByte < 0x21) { | |
484 return; | |
485 } | |
486 if (m_iDataPos < 1) { | |
487 if (m_CurByte == '\'' || m_CurByte == '\"') { | |
488 m_SkipChar = m_CurByte; | |
489 } | |
490 } | |
491 } | |
492 void CFX_SAXReader::ParseMaybeClose() { | |
493 if (m_CurByte == '>') { | |
494 if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
495 m_iNameLength = m_iDataPos; | |
496 m_iDataPos = 0; | |
497 if (m_pHandler) { | |
498 NotifyTargetData(); | |
499 } | |
500 } | |
501 ParseTagClose(); | |
502 m_eMode = FX_SAXMODE_Text; | |
503 } else if (m_ePrevMode == FX_SAXMODE_TagName) { | |
504 AppendData('/'); | |
505 m_eMode = FX_SAXMODE_TagName; | |
506 m_ePrevMode = FX_SAXMODE_Text; | |
507 ParseTagName(); | |
508 } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) { | |
509 AppendName('/'); | |
510 m_eMode = FX_SAXMODE_TagAttributeName; | |
511 m_ePrevMode = FX_SAXMODE_Text; | |
512 ParseTagAttributeName(); | |
513 } else if (m_ePrevMode == FX_SAXMODE_TargetData) { | |
514 AppendName('?'); | |
515 m_eMode = FX_SAXMODE_TargetData; | |
516 m_ePrevMode = FX_SAXMODE_Text; | |
517 ParseTargetData(); | |
518 } | |
519 } | |
520 void CFX_SAXReader::ParseTagClose() { | |
521 m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; | |
522 if (m_pHandler) { | |
523 NotifyClose(); | |
524 } | |
525 Pop(); | |
526 } | |
527 void CFX_SAXReader::ParseTagEnd() { | |
528 if (m_CurByte < 0x21) { | |
529 return; | |
530 } | |
531 if (m_CurByte == '>') { | |
532 Pop(); | |
533 m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; | |
534 m_iDataLength = m_iDataPos; | |
535 m_iDataPos = 0; | |
536 if (m_pHandler) { | |
537 NotifyEnd(); | |
538 } | |
539 Pop(); | |
540 m_eMode = FX_SAXMODE_Text; | |
541 } else { | |
542 ParseChar(m_CurByte); | |
543 } | |
544 } | |
545 void CFX_SAXReader::ParseTargetData() { | |
546 if (m_CurByte == '?') { | |
547 m_ePrevMode = m_eMode; | |
548 m_eMode = FX_SAXMODE_TagMaybeClose; | |
549 } else { | |
550 AppendName(m_CurByte); | |
551 } | |
552 } | |
553 void CFX_SAXReader::SkipNode() { | |
554 int32_t iLen = m_SkipStack.GetSize(); | |
555 if (m_SkipChar == '\'' || m_SkipChar == '\"') { | |
556 if (m_CurByte != m_SkipChar) { | |
557 return; | |
558 } | |
559 iLen--; | |
560 ASSERT(iLen > -1); | |
561 m_SkipStack.RemoveAt(iLen, 1); | |
562 m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0; | |
563 return; | |
564 } | |
565 switch (m_CurByte) { | |
566 case '<': | |
567 m_SkipChar = '>'; | |
568 m_SkipStack.Add('>'); | |
569 break; | |
570 case '[': | |
571 m_SkipChar = ']'; | |
572 m_SkipStack.Add(']'); | |
573 break; | |
574 case '(': | |
575 m_SkipChar = ')'; | |
576 m_SkipStack.Add(')'); | |
577 break; | |
578 case '\'': | |
579 m_SkipChar = '\''; | |
580 m_SkipStack.Add('\''); | |
581 break; | |
582 case '\"': | |
583 m_SkipChar = '\"'; | |
584 m_SkipStack.Add('\"'); | |
585 break; | |
586 default: | |
587 if (m_CurByte == m_SkipChar) { | |
588 iLen--; | |
589 m_SkipStack.RemoveAt(iLen, 1); | |
590 m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0; | |
591 if (iLen == 0 && m_CurByte == '>') { | |
592 m_iDataLength = m_iDataPos; | |
593 m_iDataPos = 0; | |
594 if (m_iDataLength >= 9 && | |
595 FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 && | |
596 FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]", | |
597 2 * sizeof(uint8_t)) == 0) { | |
598 Pop(); | |
599 m_iDataLength -= 9; | |
600 m_dwDataOffset += 7; | |
601 FXSYS_memmove(m_pszData, m_pszData + 7, | |
602 m_iDataLength * sizeof(uint8_t)); | |
603 m_bCharData = TRUE; | |
604 if (m_pHandler) { | |
605 NotifyData(); | |
606 } | |
607 m_bCharData = FALSE; | |
608 } else { | |
609 Pop(); | |
610 } | |
611 m_eMode = FX_SAXMODE_Text; | |
612 } | |
613 } | |
614 break; | |
615 } | |
616 if (iLen > 0) { | |
617 ParseChar(m_CurByte); | |
618 } | |
619 } | |
620 | |
621 void CFX_SAXReader::NotifyData() { | |
622 if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) | |
623 m_pHandler->OnTagData(m_pCurItem->m_pNode, | |
624 m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text, | |
625 CFX_ByteStringC(m_pszData, m_iDataLength), | |
626 m_File.m_dwCur + m_dwDataOffset); | |
627 } | |
628 | |
629 void CFX_SAXReader::NotifyEnter() { | |
630 if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || | |
631 m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
632 m_pCurItem->m_pNode = | |
633 m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength), | |
634 m_pCurItem->m_eNode, m_dwNodePos); | |
635 } | |
636 } | |
637 | |
638 void CFX_SAXReader::NotifyAttribute() { | |
639 if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || | |
640 m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
641 m_pHandler->OnTagAttribute(m_pCurItem->m_pNode, | |
642 CFX_ByteStringC(m_pszName, m_iNameLength), | |
643 CFX_ByteStringC(m_pszData, m_iDataLength)); | |
644 } | |
645 } | |
646 | |
647 void CFX_SAXReader::NotifyBreak() { | |
648 if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) | |
649 m_pHandler->OnTagBreak(m_pCurItem->m_pNode); | |
650 } | |
651 | |
652 void CFX_SAXReader::NotifyClose() { | |
653 if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || | |
654 m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
655 m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos); | |
656 } | |
657 } | |
658 | |
659 void CFX_SAXReader::NotifyEnd() { | |
660 if (m_pCurItem->m_eNode != FX_SAXNODE_Tag) | |
661 return; | |
662 | |
663 m_pHandler->OnTagEnd(m_pCurItem->m_pNode, | |
664 CFX_ByteStringC(m_pszData, m_iDataLength), m_dwNodePos); | |
665 } | |
666 | |
667 void CFX_SAXReader::NotifyTargetData() { | |
668 if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) { | |
669 m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode, | |
670 CFX_ByteStringC(m_pszName, m_iNameLength), | |
671 m_dwNodePos); | |
672 } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) { | |
673 m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode, | |
674 CFX_ByteStringC(m_pszData, m_iDataLength), | |
675 m_dwNodePos); | |
676 } | |
677 } | |
678 | |
679 void CFX_SAXReader::SkipCurrentNode() { | |
680 if (!m_pCurItem) | |
681 return; | |
682 | |
683 m_pCurItem->m_bSkip = TRUE; | |
684 } | |
685 | |
686 void CFX_SAXReader::SetHandler(CXFA_SAXReaderHandler* pHandler) { | |
687 m_pHandler = pHandler; | |
688 } | |
OLD | NEW |