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 18 IFX_SAXReader* FX_SAXReader_Create() { 19 return new CFX_SAXReader; 20 } 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) {} 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 } 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 } 68 void CFX_SAXFile::Reset() { 69 if (m_pBuf) { 70 FX_Free(m_pBuf); 71 m_pBuf = NULL; 72 } 73 m_pFile = NULL; 74 } 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 } 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 } 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 } 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 } 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 } 139 inline void CFX_SAXReader::AppendData(uint8_t ch) { 140 ReallocDataBuffer(); 141 m_pszData[m_iDataPos++] = ch; 142 } 143 inline void CFX_SAXReader::AppendName(uint8_t ch) { 144 ReallocNameBuffer(); 145 m_pszName[m_iDataPos++] = ch; 146 } 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 } 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 } 169 inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) { 170 return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21; 171 } 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 }; 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 } 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 } 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 } 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 } 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 } 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 } 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 } 401 void CFX_SAXReader::ParseDeclNode() { 402 SkipNode(); 403 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 681 void CFX_SAXReader::SkipCurrentNode() { 682 if (!m_pCurItem) { 683 return; 684 } 685 m_pCurItem->m_bSkip = TRUE; 686 } 687 void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler* pHandler) { 688 m_pHandler = pHandler; 689 } 690