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