| 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 |