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