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/foxitlib.h" 10 #include "fde_xml.h" 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 #define FDE_XMLVALIDCHARRANGENUM 5 15 static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { 16 {0x09, 0x09}, 17 {0x0A, 0x0A}, 18 {0x0D, 0x0D}, 19 {0x20, 0xD7FF}, 20 {0xE000, 0xFFFD}}; 21 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { 22 int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; 23 while (iStart <= iEnd) { 24 iMid = (iStart + iEnd) / 2; 25 if (ch < g_XMLValidCharRange[iMid][0]) { 26 iEnd = iMid - 1; 27 } else if (ch > g_XMLValidCharRange[iMid][1]) { 28 iStart = iMid + 1; 29 } else { 30 return TRUE; 31 } 32 } 33 return FALSE; 34 } 35 FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch) { 36 return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09; 37 } 38 typedef struct _FDE_XMLNAMECHAR { 39 FX_WCHAR wStart; 40 FX_WCHAR wEnd; 41 FX_BOOL bStartChar; 42 } FDE_XMLNAMECHAR; 43 #define FDE_XMLNAMECHARSNUM 20 44 static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = { 45 {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, 46 {L'A', L'Z', TRUE}, {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, 47 {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE}, {0xD8, 0xF6, TRUE}, 48 {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE}, 49 {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, 50 {0x2070, 0x218F, TRUE}, {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, 51 {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE}, 52 }; 53 FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar) { 54 int32_t iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid; 55 while (iStart <= iEnd) { 56 iMid = (iStart + iEnd) / 2; 57 if (ch < g_XMLNameChars[iMid].wStart) { 58 iEnd = iMid - 1; 59 } else if (ch > g_XMLNameChars[iMid].wEnd) { 60 iStart = iMid + 1; 61 } else { 62 if (bFirstChar) { 63 return g_XMLNameChars[iMid].bStartChar; 64 } 65 return TRUE; 66 } 67 } 68 return FALSE; 69 } 70 #ifdef __cplusplus 71 } 72 #endif 73 CFDE_XMLNode::CFDE_XMLNode() 74 : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} 75 CFDE_XMLNode::~CFDE_XMLNode() { 76 DeleteChildren(); 77 } 78 void CFDE_XMLNode::DeleteChildren() { 79 CFDE_XMLNode *pChild = m_pChild, *pTemp; 80 while (pChild != NULL) { 81 pTemp = pChild->m_pNext; 82 pChild->Release(); 83 pChild = pTemp; 84 } 85 m_pChild = NULL; 86 } 87 int32_t CFDE_XMLNode::CountChildNodes() const { 88 int32_t iCount = 0; 89 CFDE_XMLNode* pChild = m_pChild; 90 while (pChild != NULL) { 91 iCount++; 92 pChild = pChild->m_pNext; 93 } 94 return iCount; 95 } 96 CFDE_XMLNode* CFDE_XMLNode::GetChildNode(int32_t index) const { 97 CFDE_XMLNode* pChild = m_pChild; 98 while (pChild != NULL) { 99 if (index == 0) { 100 return pChild; 101 } 102 index--; 103 pChild = pChild->m_pNext; 104 } 105 return NULL; 106 } 107 int32_t CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode* pNode) const { 108 int32_t index = 0; 109 CFDE_XMLNode* pChild = m_pChild; 110 while (pChild != NULL) { 111 if (pChild == pNode) { 112 return index; 113 } 114 index++; 115 pChild = pChild->m_pNext; 116 } 117 return -1; 118 } 119 CFDE_XMLNode* CFDE_XMLNode::GetPath(const FX_WCHAR* pPath, 120 int32_t iLength, 121 FX_BOOL bQualifiedName) const { 122 FXSYS_assert(pPath != NULL); 123 if (iLength < 0) { 124 iLength = FXSYS_wcslen(pPath); 125 } 126 if (iLength == 0) { 127 return NULL; 128 } 129 CFX_WideString csPath; 130 const FX_WCHAR* pStart = pPath; 131 const FX_WCHAR* pEnd = pPath + iLength; 132 FX_WCHAR ch; 133 while (pStart < pEnd) { 134 ch = *pStart++; 135 if (ch == L'/') { 136 break; 137 } else { 138 csPath += ch; 139 } 140 } 141 iLength -= pStart - pPath; 142 CFDE_XMLNode* pFind = NULL; 143 if (csPath.GetLength() < 1) { 144 pFind = GetNodeItem(IFDE_XMLNode::Root); 145 } else if (csPath.Compare(L"..") == 0) { 146 pFind = m_pParent; 147 } else if (csPath.Compare(L".") == 0) { 148 pFind = (CFDE_XMLNode*)this; 149 } else { 150 CFX_WideString wsTag; 151 CFDE_XMLNode* pNode = m_pChild; 152 while (pNode != NULL) { 153 if (pNode->GetType() == FDE_XMLNODE_Element) { 154 if (bQualifiedName) { 155 ((CFDE_XMLElement*)pNode)->GetTagName(wsTag); 156 } else { 157 ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag); 158 } 159 if (wsTag.Compare(csPath) == 0) { 160 if (iLength < 1) { 161 pFind = pNode; 162 } else { 163 pFind = pNode->GetPath(pStart, iLength, bQualifiedName); 164 } 165 if (pFind != NULL) { 166 return pFind; 167 } 168 } 169 } 170 pNode = pNode->m_pNext; 171 } 172 } 173 if (pFind == NULL || iLength < 1) { 174 return pFind; 175 } 176 return pFind->GetPath(pStart, iLength, bQualifiedName); 177 } 178 int32_t CFDE_XMLNode::InsertChildNode(CFDE_XMLNode* pNode, int32_t index) { 179 FXSYS_assert(pNode != NULL); 180 pNode->m_pParent = this; 181 if (m_pChild == NULL) { 182 m_pChild = pNode; 183 pNode->m_pPrior = NULL; 184 pNode->m_pNext = NULL; 185 return 0; 186 } else if (index == 0) { 187 pNode->m_pNext = m_pChild; 188 pNode->m_pPrior = NULL; 189 m_pChild->m_pPrior = pNode; 190 m_pChild = pNode; 191 return 0; 192 } 193 int32_t iCount = 0; 194 CFDE_XMLNode* pFind = m_pChild; 195 while (++iCount != index && pFind->m_pNext != NULL) { 196 pFind = pFind->m_pNext; 197 } 198 pNode->m_pPrior = pFind; 199 pNode->m_pNext = pFind->m_pNext; 200 if (pFind->m_pNext != NULL) { 201 pFind->m_pNext->m_pPrior = pNode; 202 } 203 pFind->m_pNext = pNode; 204 return iCount; 205 } 206 void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode* pNode) { 207 FXSYS_assert(m_pChild != NULL && pNode != NULL); 208 if (m_pChild == pNode) { 209 m_pChild = pNode->m_pNext; 210 } else { 211 pNode->m_pPrior->m_pNext = pNode->m_pNext; 212 } 213 if (pNode->m_pNext != NULL) { 214 pNode->m_pNext->m_pPrior = pNode->m_pPrior; 215 } 216 pNode->m_pParent = NULL; 217 pNode->m_pNext = NULL; 218 pNode->m_pPrior = NULL; 219 } 220 CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const { 221 switch (eItem) { 222 case IFDE_XMLNode::Root: { 223 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; 224 while (pParent->m_pParent != NULL) { 225 pParent = pParent->m_pParent; 226 } 227 return pParent; 228 } 229 case IFDE_XMLNode::Parent: 230 return m_pParent; 231 case IFDE_XMLNode::FirstSibling: { 232 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; 233 while (pItem->m_pPrior != NULL) { 234 pItem = pItem->m_pPrior; 235 } 236 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; 237 } 238 case IFDE_XMLNode::PriorSibling: 239 return m_pPrior; 240 case IFDE_XMLNode::NextSibling: 241 return m_pNext; 242 case IFDE_XMLNode::LastSibling: { 243 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; 244 while (pItem->m_pNext != NULL) { 245 pItem = pItem->m_pNext; 246 } 247 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; 248 } 249 case IFDE_XMLNode::FirstNeighbor: { 250 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; 251 while (pParent->m_pParent != NULL) { 252 pParent = pParent->m_pParent; 253 } 254 return pParent == (CFDE_XMLNode*)this ? NULL : pParent; 255 } 256 case IFDE_XMLNode::PriorNeighbor: { 257 if (m_pPrior == NULL) { 258 return m_pParent; 259 } 260 CFDE_XMLNode* pItem = m_pPrior; 261 while (CFDE_XMLNode* pTemp = pItem->m_pChild) { 262 pItem = pTemp; 263 while ((pTemp = pItem->m_pNext) != NULL) { 264 pItem = pTemp; 265 } 266 } 267 return pItem; 268 } 269 case IFDE_XMLNode::NextNeighbor: { 270 if (m_pChild != NULL) { 271 return m_pChild; 272 } 273 if (m_pNext != NULL) { 274 return m_pNext; 275 } 276 CFDE_XMLNode* pItem = m_pParent; 277 while (pItem != NULL) { 278 if (pItem->m_pNext != NULL) { 279 return pItem->m_pNext; 280 } 281 pItem = pItem->m_pParent; 282 } 283 return NULL; 284 } 285 case IFDE_XMLNode::LastNeighbor: { 286 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; 287 while (pItem->m_pParent != NULL) { 288 pItem = pItem->m_pParent; 289 } 290 while (TRUE) { 291 while (pItem->m_pNext != NULL) { 292 pItem = pItem->m_pNext; 293 } 294 if (pItem->m_pChild == NULL) { 295 break; 296 } 297 pItem = pItem->m_pChild; 298 } 299 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; 300 } 301 case IFDE_XMLNode::FirstChild: 302 return m_pChild; 303 case IFDE_XMLNode::LastChild: { 304 if (m_pChild == NULL) { 305 return NULL; 306 } 307 CFDE_XMLNode* pChild = m_pChild; 308 while (pChild->m_pNext != NULL) { 309 pChild = pChild->m_pNext; 310 } 311 return pChild; 312 } 313 default: 314 break; 315 } 316 return NULL; 317 } 318 int32_t CFDE_XMLNode::GetNodeLevel() const { 319 int32_t iLevel = 0; 320 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; 321 while ((pItem = pItem->m_pParent) != NULL) { 322 iLevel++; 323 } 324 return iLevel; 325 } 326 FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, 327 CFDE_XMLNode* pNode) { 328 FXSYS_assert(pNode != NULL); 329 switch (eItem) { 330 case IFDE_XMLNode::NextSibling: { 331 pNode->m_pParent = m_pParent; 332 pNode->m_pNext = m_pNext; 333 pNode->m_pPrior = this; 334 if (m_pNext) { 335 m_pNext->m_pPrior = pNode; 336 } 337 m_pNext = pNode; 338 return TRUE; 339 } 340 case IFDE_XMLNode::PriorSibling: { 341 pNode->m_pParent = m_pParent; 342 pNode->m_pNext = this; 343 pNode->m_pPrior = m_pPrior; 344 if (m_pPrior) { 345 m_pPrior->m_pNext = pNode; 346 } else if (m_pParent) { 347 m_pParent->m_pChild = pNode; 348 } 349 m_pPrior = pNode; 350 return TRUE; 351 } 352 default: 353 return FALSE; 354 } 355 return FALSE; 356 } 357 CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) { 358 CFDE_XMLNode* pNode = NULL; 359 switch (eItem) { 360 case IFDE_XMLNode::NextSibling: 361 if (m_pNext) { 362 pNode = m_pNext; 363 m_pNext = pNode->m_pNext; 364 if (m_pNext) { 365 m_pNext->m_pPrior = this; 366 } 367 pNode->m_pParent = NULL; 368 pNode->m_pNext = NULL; 369 pNode->m_pPrior = NULL; 370 } 371 break; 372 default: 373 break; 374 } 375 return pNode; 376 } 377 CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive) { 378 return NULL; 379 } 380 void CFDE_XMLNode::SaveXMLNode(IFX_Stream* pXMLStream) { 381 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; 382 FXSYS_assert(pXMLStream != NULL && pNode != NULL); 383 switch (pNode->GetType()) { 384 case FDE_XMLNODE_Instruction: { 385 CFX_WideString ws; 386 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; 387 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { 388 ws = L"<?xml version=\"1.0\" encoding=\""; 389 FX_WORD wCodePage = pXMLStream->GetCodePage(); 390 if (wCodePage == FX_CODEPAGE_UTF16LE) { 391 ws += L"UTF-16"; 392 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { 393 ws += L"UTF-16be"; 394 } else { 395 ws += L"UTF-8"; 396 } 397 ws += L"\"?>"; 398 pXMLStream->WriteString(ws, ws.GetLength()); 399 } else { 400 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); 401 pXMLStream->WriteString(ws, ws.GetLength()); 402 CFX_WideStringArray& attributes = pInstruction->m_Attributes; 403 int32_t i, iCount = attributes.GetSize(); 404 CFX_WideString wsValue; 405 for (i = 0; i < iCount; i += 2) { 406 ws = L" "; 407 ws += attributes[i]; 408 ws += L"=\""; 409 wsValue = attributes[i + 1]; 410 wsValue.Replace(L"&", L"&"); 411 wsValue.Replace(L"<", L"<"); 412 wsValue.Replace(L">", L">"); 413 wsValue.Replace(L"\'", L"'"); 414 wsValue.Replace(L"\"", L"""); 415 ws += wsValue; 416 ws += L"\""; 417 pXMLStream->WriteString(ws, ws.GetLength()); 418 } 419 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; 420 iCount = targetdata.GetSize(); 421 for (i = 0; i < iCount; i++) { 422 ws = L" \""; 423 ws += targetdata[i]; 424 ws += L"\""; 425 pXMLStream->WriteString(ws, ws.GetLength()); 426 } 427 ws = L"?>"; 428 pXMLStream->WriteString(ws, ws.GetLength()); 429 } 430 } break; 431 case FDE_XMLNODE_Element: { 432 CFX_WideString ws; 433 ws = L"<"; 434 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; 435 pXMLStream->WriteString(ws, ws.GetLength()); 436 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; 437 int32_t iCount = attributes.GetSize(); 438 CFX_WideString wsValue; 439 for (int32_t i = 0; i < iCount; i += 2) { 440 ws = L" "; 441 ws += attributes[i]; 442 ws += L"=\""; 443 wsValue = attributes[i + 1]; 444 wsValue.Replace(L"&", L"&"); 445 wsValue.Replace(L"<", L"<"); 446 wsValue.Replace(L">", L">"); 447 wsValue.Replace(L"\'", L"'"); 448 wsValue.Replace(L"\"", L"""); 449 ws += wsValue; 450 ws += L"\""; 451 pXMLStream->WriteString(ws, ws.GetLength()); 452 } 453 if (pNode->m_pChild == NULL) { 454 ws = L"\n/>"; 455 pXMLStream->WriteString(ws, ws.GetLength()); 456 } else { 457 ws = L"\n>"; 458 pXMLStream->WriteString(ws, ws.GetLength()); 459 CFDE_XMLNode* pChild = pNode->m_pChild; 460 while (pChild != NULL) { 461 pChild->SaveXMLNode(pXMLStream); 462 pChild = pChild->m_pNext; 463 } 464 ws = L"</"; 465 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; 466 ws += L"\n>"; 467 pXMLStream->WriteString(ws, ws.GetLength()); 468 } 469 } break; 470 case FDE_XMLNODE_Text: { 471 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; 472 ws.Replace(L"&", L"&"); 473 ws.Replace(L"<", L"<"); 474 ws.Replace(L">", L">"); 475 ws.Replace(L"\'", L"'"); 476 ws.Replace(L"\"", L"""); 477 pXMLStream->WriteString(ws, ws.GetLength()); 478 } break; 479 case FDE_XMLNODE_CharData: { 480 CFX_WideString ws = L"<![CDATA["; 481 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; 482 ws += L"]]>"; 483 pXMLStream->WriteString(ws, ws.GetLength()); 484 } break; 485 case FDE_XMLNODE_Unknown: 486 break; 487 default: 488 break; 489 } 490 } 491 void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) { 492 if (!m_pChild) { 493 return; 494 } 495 CFDE_XMLNode* pNext = m_pChild; 496 CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE); 497 pClone->InsertChildNode(pCloneNext); 498 pNext = pNext->m_pNext; 499 while (pNext) { 500 CFDE_XMLNode* pChild = pNext->Clone(TRUE); 501 pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild); 502 pCloneNext = pChild; 503 pNext = pNext->m_pNext; 504 } 505 } 506 IFDE_XMLInstruction* IFDE_XMLInstruction::Create( 507 const CFX_WideString& wsTarget) { 508 return (IFDE_XMLInstruction*)new CFDE_XMLInstruction(wsTarget); 509 } 510 CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) 511 : m_wsTarget(wsTarget) { 512 FXSYS_assert(m_wsTarget.GetLength() > 0); 513 } 514 CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive) { 515 CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget); 516 if (!pClone) { 517 return pClone; 518 } 519 pClone->m_Attributes.Copy(m_Attributes); 520 pClone->m_TargetData.Copy(m_TargetData); 521 if (bRecursive) { 522 CloneChildren(pClone); 523 } 524 return pClone; 525 } 526 int32_t CFDE_XMLInstruction::CountAttributes() const { 527 return m_Attributes.GetSize() / 2; 528 } 529 FX_BOOL CFDE_XMLInstruction::GetAttribute(int32_t index, 530 CFX_WideString& wsAttriName, 531 CFX_WideString& wsAttriValue) const { 532 int32_t iCount = m_Attributes.GetSize(); 533 FXSYS_assert(index > -1 && index < iCount / 2); 534 for (int32_t i = 0; i < iCount; i += 2) { 535 if (index == 0) { 536 wsAttriName = m_Attributes[i]; 537 wsAttriValue = m_Attributes[i + 1]; 538 return TRUE; 539 } 540 index--; 541 } 542 return FALSE; 543 } 544 FX_BOOL CFDE_XMLInstruction::HasAttribute(const FX_WCHAR* pwsAttriName) const { 545 int32_t iCount = m_Attributes.GetSize(); 546 for (int32_t i = 0; i < iCount; i += 2) { 547 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 548 return TRUE; 549 } 550 } 551 return FALSE; 552 } 553 void CFDE_XMLInstruction::GetString(const FX_WCHAR* pwsAttriName, 554 CFX_WideString& wsAttriValue, 555 const FX_WCHAR* pwsDefValue) const { 556 int32_t iCount = m_Attributes.GetSize(); 557 for (int32_t i = 0; i < iCount; i += 2) { 558 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 559 wsAttriValue = m_Attributes[i + 1]; 560 return; 561 } 562 } 563 wsAttriValue = pwsDefValue; 564 } 565 void CFDE_XMLInstruction::SetString(const CFX_WideString& wsAttriName, 566 const CFX_WideString& wsAttriValue) { 567 FXSYS_assert(wsAttriName.GetLength() > 0); 568 int32_t iCount = m_Attributes.GetSize(); 569 for (int32_t i = 0; i < iCount; i += 2) { 570 if (m_Attributes[i].Compare(wsAttriName) == 0) { 571 m_Attributes[i] = wsAttriName; 572 m_Attributes[i + 1] = wsAttriValue; 573 return; 574 } 575 } 576 m_Attributes.Add(wsAttriName); 577 m_Attributes.Add(wsAttriValue); 578 } 579 int32_t CFDE_XMLInstruction::GetInteger(const FX_WCHAR* pwsAttriName, 580 int32_t iDefValue) const { 581 int32_t iCount = m_Attributes.GetSize(); 582 for (int32_t i = 0; i < iCount; i += 2) { 583 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 584 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); 585 } 586 } 587 return iDefValue; 588 } 589 void CFDE_XMLInstruction::SetInteger(const FX_WCHAR* pwsAttriName, 590 int32_t iAttriValue) { 591 CFX_WideString wsValue; 592 wsValue.Format(L"%d", iAttriValue); 593 SetString(pwsAttriName, wsValue); 594 } 595 FX_FLOAT CFDE_XMLInstruction::GetFloat(const FX_WCHAR* pwsAttriName, 596 FX_FLOAT fDefValue) const { 597 int32_t iCount = m_Attributes.GetSize(); 598 for (int32_t i = 0; i < iCount; i += 2) { 599 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 600 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); 601 } 602 } 603 return fDefValue; 604 } 605 void CFDE_XMLInstruction::SetFloat(const FX_WCHAR* pwsAttriName, 606 FX_FLOAT fAttriValue) { 607 CFX_WideString wsValue; 608 wsValue.Format(L"%f", fAttriValue); 609 SetString(pwsAttriName, wsValue); 610 } 611 void CFDE_XMLInstruction::RemoveAttribute(const FX_WCHAR* pwsAttriName) { 612 int32_t iCount = m_Attributes.GetSize(); 613 for (int32_t i = 0; i < iCount; i += 2) { 614 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 615 m_Attributes.RemoveAt(i + 1); 616 m_Attributes.RemoveAt(i); 617 return; 618 } 619 } 620 } 621 int32_t CFDE_XMLInstruction::CountData() const { 622 return m_TargetData.GetSize(); 623 } 624 FX_BOOL CFDE_XMLInstruction::GetData(int32_t index, 625 CFX_WideString& wsData) const { 626 if (index < 0 || index >= m_TargetData.GetSize()) { 627 return FALSE; 628 } 629 wsData = m_TargetData[index]; 630 return TRUE; 631 } 632 void CFDE_XMLInstruction::AppendData(const CFX_WideString& wsData) { 633 m_TargetData.Add(wsData); 634 } 635 void CFDE_XMLInstruction::RemoveData(int32_t index) { 636 m_TargetData.RemoveAt(index); 637 } 638 IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString& wsTag) { 639 return (IFDE_XMLElement*)new CFDE_XMLElement(wsTag); 640 } 641 CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) 642 : CFDE_XMLNode(), m_wsTag(wsTag), m_Attributes() { 643 FXSYS_assert(m_wsTag.GetLength() > 0); 644 } 645 CFDE_XMLElement::~CFDE_XMLElement() { 646 m_Attributes.RemoveAll(); 647 } 648 CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive) { 649 CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag); 650 if (!pClone) { 651 return NULL; 652 } 653 pClone->m_Attributes.Copy(m_Attributes); 654 if (bRecursive) { 655 CloneChildren(pClone); 656 } else { 657 CFX_WideString wsText; 658 CFDE_XMLNode* pChild = m_pChild; 659 while (pChild != NULL) { 660 switch (pChild->GetType()) { 661 case FDE_XMLNODE_Text: 662 wsText += ((CFDE_XMLText*)pChild)->m_wsText; 663 break; 664 default: 665 break; 666 } 667 pChild = pChild->m_pNext; 668 } 669 pClone->SetTextData(wsText); 670 } 671 return pClone; 672 } 673 void CFDE_XMLElement::GetTagName(CFX_WideString& wsTag) const { 674 wsTag = m_wsTag; 675 } 676 void CFDE_XMLElement::GetLocalTagName(CFX_WideString& wsTag) const { 677 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); 678 if (iFind < 0) { 679 wsTag = m_wsTag; 680 } else { 681 wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1); 682 } 683 } 684 void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString& wsPrefix) const { 685 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); 686 if (iFind < 0) { 687 wsPrefix.Empty(); 688 } else { 689 wsPrefix = m_wsTag.Left(iFind); 690 } 691 } 692 void CFDE_XMLElement::GetNamespaceURI(CFX_WideString& wsNamespace) const { 693 CFX_WideString wsAttri(L"xmlns"), wsPrefix; 694 GetNamespacePrefix(wsPrefix); 695 if (wsPrefix.GetLength() > 0) { 696 wsAttri += L":"; 697 wsAttri += wsPrefix; 698 } 699 wsNamespace.Empty(); 700 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; 701 while (pNode != NULL) { 702 if (pNode->GetType() != FDE_XMLNODE_Element) { 703 break; 704 } 705 CFDE_XMLElement* pElement = (CFDE_XMLElement*)pNode; 706 if (!pElement->HasAttribute(wsAttri)) { 707 pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent); 708 continue; 709 } 710 pElement->GetString(wsAttri, wsNamespace); 711 break; 712 } 713 } 714 int32_t CFDE_XMLElement::CountAttributes() const { 715 return m_Attributes.GetSize() / 2; 716 } 717 FX_BOOL CFDE_XMLElement::GetAttribute(int32_t index, 718 CFX_WideString& wsAttriName, 719 CFX_WideString& wsAttriValue) const { 720 int32_t iCount = m_Attributes.GetSize(); 721 FXSYS_assert(index > -1 && index < iCount / 2); 722 for (int32_t i = 0; i < iCount; i += 2) { 723 if (index == 0) { 724 wsAttriName = m_Attributes[i]; 725 wsAttriValue = m_Attributes[i + 1]; 726 return TRUE; 727 } 728 index--; 729 } 730 return FALSE; 731 } 732 FX_BOOL CFDE_XMLElement::HasAttribute(const FX_WCHAR* pwsAttriName) const { 733 int32_t iCount = m_Attributes.GetSize(); 734 for (int32_t i = 0; i < iCount; i += 2) { 735 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 736 return TRUE; 737 } 738 } 739 return FALSE; 740 } 741 void CFDE_XMLElement::GetString(const FX_WCHAR* pwsAttriName, 742 CFX_WideString& wsAttriValue, 743 const FX_WCHAR* pwsDefValue) const { 744 int32_t iCount = m_Attributes.GetSize(); 745 for (int32_t i = 0; i < iCount; i += 2) { 746 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 747 wsAttriValue = m_Attributes[i + 1]; 748 return; 749 } 750 } 751 wsAttriValue = pwsDefValue; 752 } 753 void CFDE_XMLElement::SetString(const CFX_WideString& wsAttriName, 754 const CFX_WideString& wsAttriValue) { 755 FXSYS_assert(wsAttriName.GetLength() > 0); 756 int32_t iCount = m_Attributes.GetSize(); 757 for (int32_t i = 0; i < iCount; i += 2) { 758 if (m_Attributes[i].Compare(wsAttriName) == 0) { 759 m_Attributes[i] = wsAttriName; 760 m_Attributes[i + 1] = wsAttriValue; 761 return; 762 } 763 } 764 m_Attributes.Add(wsAttriName); 765 m_Attributes.Add(wsAttriValue); 766 } 767 int32_t CFDE_XMLElement::GetInteger(const FX_WCHAR* pwsAttriName, 768 int32_t iDefValue) const { 769 int32_t iCount = m_Attributes.GetSize(); 770 for (int32_t i = 0; i < iCount; i += 2) { 771 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 772 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); 773 } 774 } 775 return iDefValue; 776 } 777 void CFDE_XMLElement::SetInteger(const FX_WCHAR* pwsAttriName, 778 int32_t iAttriValue) { 779 CFX_WideString wsValue; 780 wsValue.Format(L"%d", iAttriValue); 781 SetString(pwsAttriName, wsValue); 782 } 783 FX_FLOAT CFDE_XMLElement::GetFloat(const FX_WCHAR* pwsAttriName, 784 FX_FLOAT fDefValue) const { 785 int32_t iCount = m_Attributes.GetSize(); 786 for (int32_t i = 0; i < iCount; i += 2) { 787 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 788 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); 789 } 790 } 791 return fDefValue; 792 } 793 void CFDE_XMLElement::SetFloat(const FX_WCHAR* pwsAttriName, 794 FX_FLOAT fAttriValue) { 795 CFX_WideString wsValue; 796 wsValue.Format(L"%f", fAttriValue); 797 SetString(pwsAttriName, wsValue); 798 } 799 void CFDE_XMLElement::RemoveAttribute(const FX_WCHAR* pwsAttriName) { 800 int32_t iCount = m_Attributes.GetSize(); 801 for (int32_t i = 0; i < iCount; i += 2) { 802 if (m_Attributes[i].Compare(pwsAttriName) == 0) { 803 m_Attributes.RemoveAt(i + 1); 804 m_Attributes.RemoveAt(i); 805 return; 806 } 807 } 808 } 809 void CFDE_XMLElement::GetTextData(CFX_WideString& wsText) const { 810 CFX_WideTextBuf buffer; 811 CFDE_XMLNode* pChild = m_pChild; 812 while (pChild != NULL) { 813 switch (pChild->GetType()) { 814 case FDE_XMLNODE_Text: 815 buffer << ((CFDE_XMLText*)pChild)->m_wsText; 816 break; 817 case FDE_XMLNODE_CharData: 818 buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData; 819 break; 820 default: 821 break; 822 } 823 pChild = pChild->m_pNext; 824 } 825 wsText = buffer.GetWideString(); 826 } 827 void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { 828 if (wsText.GetLength() < 1) { 829 return; 830 } 831 InsertChildNode(new CFDE_XMLText(wsText)); 832 } 833 IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString& wsText) { 834 return (IFDE_XMLText*)new CFDE_XMLText(wsText); 835 } 836 CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) 837 : CFDE_XMLNode(), m_wsText(wsText) {} 838 CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive) { 839 CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText); 840 return pClone; 841 } 842 IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString& wsCData) { 843 return (IFDE_XMLCharData*)new CFDE_XMLCharData(wsCData); 844 } 845 CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) 846 : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} 847 CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive) { 848 CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData); 849 return pClone; 850 } 851 IFDE_XMLDoc* IFDE_XMLDoc::Create() { 852 return (IFDE_XMLDoc*)new CFDE_XMLDoc; 853 } 854 CFDE_XMLDoc::CFDE_XMLDoc() 855 : m_pRoot(NULL), m_pSyntaxParser(NULL), m_pXMLParser(NULL) { 856 Reset(TRUE); 857 CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); 858 m_pRoot->InsertChildNode(pXML); 859 } 860 CFDE_XMLDoc::~CFDE_XMLDoc() { 861 Reset(FALSE); 862 } 863 void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot) { 864 m_iStatus = 0; 865 m_pStream = NULL; 866 if (bInitRoot) { 867 if (m_pRoot == NULL) { 868 m_pRoot = new CFDE_XMLNode; 869 } else { 870 m_pRoot->DeleteChildren(); 871 } 872 } else { 873 if (m_pRoot != NULL) { 874 m_pRoot->Release(); 875 m_pRoot = NULL; 876 } 877 } 878 ReleaseParser(); 879 } 880 void CFDE_XMLDoc::ReleaseParser() { 881 if (m_pXMLParser != NULL) { 882 m_pXMLParser->Release(); 883 m_pXMLParser = NULL; 884 } 885 if (m_pSyntaxParser != NULL) { 886 m_pSyntaxParser->Release(); 887 m_pSyntaxParser = NULL; 888 } 889 } 890 FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream* pXMLStream, 891 int32_t iXMLPlaneSize, 892 int32_t iTextDataSize, 893 FDE_LPXMLREADERHANDLER pHandler) { 894 if (pXMLStream == NULL) { 895 return FALSE; 896 } 897 Reset(TRUE); 898 iXMLPlaneSize = iXMLPlaneSize / 1024; 899 if (iXMLPlaneSize < 1) { 900 iXMLPlaneSize = 1; 901 } 902 iXMLPlaneSize *= 1024; 903 if (iXMLPlaneSize < 4096) { 904 iXMLPlaneSize = 4096; 905 } 906 iTextDataSize = iTextDataSize / 128; 907 if (iTextDataSize < 1) { 908 iTextDataSize = 1; 909 } 910 iTextDataSize *= 128; 911 if (iTextDataSize < 128) { 912 iTextDataSize = 128; 913 } 914 m_pStream = pXMLStream; 915 FX_WORD wCodePage = m_pStream->GetCodePage(); 916 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && 917 wCodePage != FX_CODEPAGE_UTF8) { 918 m_pStream->SetCodePage(FX_CODEPAGE_UTF8); 919 } 920 m_pSyntaxParser = IFDE_XMLSyntaxParser::Create(); 921 if (m_pSyntaxParser == NULL) { 922 return FALSE; 923 } 924 m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize); 925 if (pHandler == NULL) { 926 m_pXMLParser = new CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser); 927 } else { 928 m_pXMLParser = new CFDE_XMLSAXParser(pHandler, m_pSyntaxParser); 929 } 930 return TRUE; 931 } 932 FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser* pXMLParser) { 933 if (pXMLParser == NULL) { 934 return FALSE; 935 } 936 Reset(TRUE); 937 m_pXMLParser = pXMLParser; 938 return m_pXMLParser != NULL; 939 } 940 int32_t CFDE_XMLDoc::DoLoad(IFX_Pause* pPause) { 941 if (m_iStatus >= 100) { 942 return m_iStatus; 943 } 944 FXSYS_assert(m_pXMLParser != NULL); 945 return m_iStatus = m_pXMLParser->DoParser(pPause); 946 } 947 void CFDE_XMLDoc::CloseXML() { 948 ReleaseParser(); 949 } 950 void CFDE_XMLDoc::SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pINode) { 951 CFDE_XMLNode* pNode = (CFDE_XMLNode*)pINode; 952 FXSYS_assert(pXMLStream != NULL && pNode != NULL); 953 switch (pNode->GetType()) { 954 case FDE_XMLNODE_Instruction: { 955 CFX_WideString ws; 956 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; 957 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { 958 ws = L"<?xml version=\"1.0\" encoding=\""; 959 FX_WORD wCodePage = pXMLStream->GetCodePage(); 960 if (wCodePage == FX_CODEPAGE_UTF16LE) { 961 ws += L"UTF-16"; 962 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { 963 ws += L"UTF-16be"; 964 } else { 965 ws += L"UTF-8"; 966 } 967 ws += L"\"?>"; 968 pXMLStream->WriteString(ws, ws.GetLength()); 969 } else { 970 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); 971 pXMLStream->WriteString(ws, ws.GetLength()); 972 CFX_WideStringArray& attributes = pInstruction->m_Attributes; 973 int32_t i, iCount = attributes.GetSize(); 974 CFX_WideString wsValue; 975 for (i = 0; i < iCount; i += 2) { 976 ws = L" "; 977 ws += attributes[i]; 978 ws += L"=\""; 979 wsValue = attributes[i + 1]; 980 wsValue.Replace(L"&", L"&"); 981 wsValue.Replace(L"<", L"<"); 982 wsValue.Replace(L">", L">"); 983 wsValue.Replace(L"\'", L"'"); 984 wsValue.Replace(L"\"", L"""); 985 ws += wsValue; 986 ws += L"\""; 987 pXMLStream->WriteString(ws, ws.GetLength()); 988 } 989 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; 990 iCount = targetdata.GetSize(); 991 for (i = 0; i < iCount; i++) { 992 ws = L" \""; 993 ws += targetdata[i]; 994 ws += L"\""; 995 pXMLStream->WriteString(ws, ws.GetLength()); 996 } 997 ws = L"?>"; 998 pXMLStream->WriteString(ws, ws.GetLength()); 999 } 1000 } break; 1001 case FDE_XMLNODE_Element: { 1002 CFX_WideString ws; 1003 ws = L"<"; 1004 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; 1005 pXMLStream->WriteString(ws, ws.GetLength()); 1006 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; 1007 int32_t iCount = attributes.GetSize(); 1008 CFX_WideString wsValue; 1009 for (int32_t i = 0; i < iCount; i += 2) { 1010 ws = L" "; 1011 ws += attributes[i]; 1012 ws += L"=\""; 1013 wsValue = attributes[i + 1]; 1014 wsValue.Replace(L"&", L"&"); 1015 wsValue.Replace(L"<", L"<"); 1016 wsValue.Replace(L">", L">"); 1017 wsValue.Replace(L"\'", L"'"); 1018 wsValue.Replace(L"\"", L"""); 1019 ws += wsValue; 1020 ws += L"\""; 1021 pXMLStream->WriteString(ws, ws.GetLength()); 1022 } 1023 if (pNode->m_pChild == NULL) { 1024 ws = L"\n/>"; 1025 pXMLStream->WriteString(ws, ws.GetLength()); 1026 } else { 1027 ws = L"\n>"; 1028 pXMLStream->WriteString(ws, ws.GetLength()); 1029 CFDE_XMLNode* pChild = pNode->m_pChild; 1030 while (pChild != NULL) { 1031 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild); 1032 pChild = pChild->m_pNext; 1033 } 1034 ws = L"</"; 1035 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; 1036 ws += L"\n>"; 1037 pXMLStream->WriteString(ws, ws.GetLength()); 1038 } 1039 } break; 1040 case FDE_XMLNODE_Text: { 1041 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; 1042 ws.Replace(L"&", L"&"); 1043 ws.Replace(L"<", L"<"); 1044 ws.Replace(L">", L">"); 1045 ws.Replace(L"\'", L"'"); 1046 ws.Replace(L"\"", L"""); 1047 pXMLStream->WriteString(ws, ws.GetLength()); 1048 } break; 1049 case FDE_XMLNODE_CharData: { 1050 CFX_WideString ws = L"<![CDATA["; 1051 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; 1052 ws += L"]]>"; 1053 pXMLStream->WriteString(ws, ws.GetLength()); 1054 } break; 1055 case FDE_XMLNODE_Unknown: 1056 break; 1057 default: 1058 break; 1059 } 1060 } 1061 void CFDE_XMLDoc::SaveXML(IFX_Stream* pXMLStream, FX_BOOL bSaveBOM) { 1062 if (pXMLStream == NULL || pXMLStream == m_pStream) { 1063 m_pStream->Seek(FX_STREAMSEEK_Begin, 0); 1064 pXMLStream = m_pStream; 1065 } 1066 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0); 1067 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0); 1068 FX_WORD wCodePage = pXMLStream->GetCodePage(); 1069 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && 1070 wCodePage != FX_CODEPAGE_UTF8) { 1071 wCodePage = FX_CODEPAGE_UTF8; 1072 pXMLStream->SetCodePage(wCodePage); 1073 } 1074 if (bSaveBOM) { 1075 pXMLStream->WriteString(L"\xFEFF", 1); 1076 } 1077 CFDE_XMLNode* pNode = m_pRoot->m_pChild; 1078 while (pNode != NULL) { 1079 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode); 1080 pNode = pNode->m_pNext; 1081 } 1082 if (pXMLStream == m_pStream) { 1083 int32_t iPos = pXMLStream->GetPosition(); 1084 pXMLStream->SetLength(iPos); 1085 } 1086 } 1087 CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, 1088 IFDE_XMLSyntaxParser* pParser) 1089 : m_pParser(pParser), 1090 m_pParent(pRoot), 1091 m_pChild(NULL), 1092 m_NodeStack(16), 1093 m_ws1(), 1094 m_ws2() { 1095 m_NodeStack.Push(m_pParent); 1096 } 1097 CFDE_XMLDOMParser::~CFDE_XMLDOMParser() { 1098 m_NodeStack.RemoveAll(); 1099 m_ws1.Empty(); 1100 m_ws2.Empty(); 1101 } 1102 int32_t CFDE_XMLDOMParser::DoParser(IFX_Pause* pPause) { 1103 FX_DWORD dwRet; 1104 int32_t iCount = 0; 1105 while (TRUE) { 1106 dwRet = m_pParser->DoSyntaxParse(); 1107 switch (dwRet) { 1108 case FDE_XMLSYNTAXSTATUS_InstructionOpen: 1109 break; 1110 case FDE_XMLSYNTAXSTATUS_InstructionClose: 1111 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { 1112 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1113 break; 1114 } 1115 m_pChild = m_pParent; 1116 break; 1117 case FDE_XMLSYNTAXSTATUS_ElementOpen: 1118 case FDE_XMLSYNTAXSTATUS_ElementBreak: 1119 break; 1120 case FDE_XMLSYNTAXSTATUS_ElementClose: 1121 if (m_pChild->GetType() != FDE_XMLNODE_Element) { 1122 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1123 break; 1124 } 1125 m_pParser->GetTagName(m_ws1); 1126 ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2); 1127 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) { 1128 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1129 break; 1130 } 1131 m_NodeStack.Pop(); 1132 if (m_NodeStack.GetSize() < 1) { 1133 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1134 break; 1135 } 1136 m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement(); 1137 m_pChild = m_pParent; 1138 iCount++; 1139 break; 1140 case FDE_XMLSYNTAXSTATUS_TargetName: 1141 m_pParser->GetTargetName(m_ws1); 1142 m_pChild = new CFDE_XMLInstruction(m_ws1); 1143 m_pParent->InsertChildNode(m_pChild); 1144 m_ws1.Empty(); 1145 break; 1146 case FDE_XMLSYNTAXSTATUS_TagName: 1147 m_pParser->GetTagName(m_ws1); 1148 m_pChild = new CFDE_XMLElement(m_ws1); 1149 m_pParent->InsertChildNode(m_pChild); 1150 m_NodeStack.Push(m_pChild); 1151 m_pParent = m_pChild; 1152 break; 1153 case FDE_XMLSYNTAXSTATUS_AttriName: 1154 m_pParser->GetAttributeName(m_ws1); 1155 break; 1156 case FDE_XMLSYNTAXSTATUS_AttriValue: 1157 if (m_pChild == NULL) { 1158 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1159 break; 1160 } 1161 m_pParser->GetAttributeName(m_ws2); 1162 if (m_pChild->GetType() == FDE_XMLNODE_Element) { 1163 ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2); 1164 } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) { 1165 ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2); 1166 } 1167 m_ws1.Empty(); 1168 break; 1169 case FDE_XMLSYNTAXSTATUS_Text: 1170 m_pParser->GetTextData(m_ws1); 1171 m_pChild = new CFDE_XMLText(m_ws1); 1172 m_pParent->InsertChildNode(m_pChild); 1173 m_pChild = m_pParent; 1174 break; 1175 case FDE_XMLSYNTAXSTATUS_CData: 1176 m_pParser->GetTextData(m_ws1); 1177 m_pChild = new CFDE_XMLCharData(m_ws1); 1178 m_pParent->InsertChildNode(m_pChild); 1179 m_pChild = m_pParent; 1180 break; 1181 case FDE_XMLSYNTAXSTATUS_TargetData: 1182 if (m_pChild == NULL || 1183 m_pChild->GetType() != FDE_XMLNODE_Instruction) { 1184 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1185 break; 1186 } 1187 if (!m_ws1.IsEmpty()) { 1188 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); 1189 } 1190 m_pParser->GetTargetData(m_ws1); 1191 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); 1192 m_ws1.Empty(); 1193 break; 1194 default: 1195 break; 1196 } 1197 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || 1198 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { 1199 break; 1200 } 1201 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { 1202 break; 1203 } 1204 } 1205 return m_pParser->GetStatus(); 1206 } 1207 CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, 1208 IFDE_XMLSyntaxParser* pParser) 1209 : m_pHandler(pHandler), 1210 m_pParser(pParser), 1211 m_TagStack(16), 1212 m_pTagTop(NULL), 1213 m_ws1(), 1214 m_ws2() {} 1215 CFDE_XMLSAXParser::~CFDE_XMLSAXParser() { 1216 m_TagStack.RemoveAll(); 1217 m_ws1.Empty(); 1218 m_ws2.Empty(); 1219 } 1220 int32_t CFDE_XMLSAXParser::DoParser(IFX_Pause* pPause) { 1221 FX_DWORD dwRet = 0; 1222 int32_t iCount = 0; 1223 while (TRUE) { 1224 dwRet = m_pParser->DoSyntaxParse(); 1225 switch (dwRet) { 1226 case FDE_XMLSYNTAXSTATUS_ElementBreak: 1227 if (m_pTagTop == NULL) { 1228 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1229 break; 1230 } 1231 if (m_pTagTop->eType == FDE_XMLNODE_Element) { 1232 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); 1233 } 1234 break; 1235 case FDE_XMLSYNTAXSTATUS_ElementClose: 1236 if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) { 1237 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1238 break; 1239 } 1240 m_pParser->GetTagName(m_ws1); 1241 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) { 1242 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1243 break; 1244 } else if (m_ws1.GetLength() == 0) { 1245 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); 1246 } 1247 m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName); 1248 Pop(); 1249 iCount++; 1250 break; 1251 case FDE_XMLSYNTAXSTATUS_TargetName: { 1252 m_pParser->GetTargetName(m_ws1); 1253 CFDE_XMLTAG xmlTag; 1254 xmlTag.wsTagName = m_ws1; 1255 xmlTag.eType = FDE_XMLNODE_Instruction; 1256 Push(xmlTag); 1257 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, 1258 m_pTagTop->wsTagName); 1259 m_ws1.Empty(); 1260 } break; 1261 case FDE_XMLSYNTAXSTATUS_TagName: { 1262 m_pParser->GetTargetName(m_ws1); 1263 CFDE_XMLTAG xmlTag; 1264 xmlTag.wsTagName = m_ws1; 1265 xmlTag.eType = FDE_XMLNODE_Element; 1266 Push(xmlTag); 1267 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, 1268 m_pTagTop->wsTagName); 1269 } break; 1270 case FDE_XMLSYNTAXSTATUS_AttriName: 1271 m_pParser->GetTargetName(m_ws1); 1272 break; 1273 case FDE_XMLSYNTAXSTATUS_AttriValue: 1274 m_pParser->GetAttributeName(m_ws2); 1275 if (m_pTagTop == NULL) { 1276 dwRet = FDE_XMLSYNTAXSTATUS_Error; 1277 break; 1278 } 1279 if (m_pTagTop->eType == FDE_XMLNODE_Element) { 1280 m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2); 1281 } 1282 m_ws1.Empty(); 1283 break; 1284 case FDE_XMLSYNTAXSTATUS_CData: 1285 m_pParser->GetTextData(m_ws1); 1286 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1); 1287 break; 1288 case FDE_XMLSYNTAXSTATUS_Text: 1289 m_pParser->GetTextData(m_ws1); 1290 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1); 1291 break; 1292 case FDE_XMLSYNTAXSTATUS_TargetData: 1293 m_pParser->GetTargetData(m_ws1); 1294 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1); 1295 m_ws1.Empty(); 1296 break; 1297 default: 1298 break; 1299 } 1300 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || 1301 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { 1302 break; 1303 } 1304 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { 1305 break; 1306 } 1307 } 1308 return m_pParser->GetStatus(); 1309 } 1310 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { 1311 m_TagStack.Push(xmlTag); 1312 m_pTagTop = m_TagStack.GetTopElement(); 1313 } 1314 inline void CFDE_XMLSAXParser::Pop() { 1315 m_TagStack.Pop(); 1316 m_pTagTop = m_TagStack.GetTopElement(); 1317 } 1318 #ifdef _FDE_BLOCK_BUFFER 1319 CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) 1320 : m_iDataLength(0), 1321 m_iBufferSize(0), 1322 m_iAllocStep(iAllocStep), 1323 m_iStartPosition(0) { 1324 } 1325 CFDE_BlockBuffer::~CFDE_BlockBuffer() { 1326 ClearBuffer(); 1327 } 1328 FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { 1329 iIndexInBlock = 0; 1330 if (!m_BlockArray.GetSize()) { 1331 return nullptr; 1332 } 1333 int32_t iRealIndex = m_iStartPosition + m_iDataLength; 1334 if (iRealIndex == m_iBufferSize) { 1335 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); 1336 m_BlockArray.Add(pBlock); 1337 m_iBufferSize += m_iAllocStep; 1338 return pBlock; 1339 } 1340 iIndexInBlock = iRealIndex % m_iAllocStep; 1341 return (FX_WCHAR*)m_BlockArray[iRealIndex / m_iAllocStep]; 1342 } 1343 FX_BOOL CFDE_BlockBuffer::InitBuffer(int32_t iBufferSize) { 1344 ClearBuffer(); 1345 int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1; 1346 for (int32_t i = 0; i < iNumOfBlock; i++) { 1347 m_BlockArray.Add(FX_Alloc(FX_WCHAR, m_iAllocStep)); 1348 } 1349 m_iBufferSize = iNumOfBlock * m_iAllocStep; 1350 return TRUE; 1351 } 1352 void CFDE_BlockBuffer::SetTextChar(int32_t iIndex, FX_WCHAR ch) { 1353 if (iIndex < 0) { 1354 return; 1355 } 1356 int32_t iRealIndex = m_iStartPosition + iIndex; 1357 int32_t iBlockIndex = iRealIndex / m_iAllocStep; 1358 int32_t iInnerIndex = iRealIndex % m_iAllocStep; 1359 int32_t iBlockSize = m_BlockArray.GetSize(); 1360 if (iBlockIndex >= iBlockSize) { 1361 int32_t iNewBlocks = iBlockIndex - iBlockSize + 1; 1362 do { 1363 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); 1364 m_BlockArray.Add(pBlock); 1365 m_iBufferSize += m_iAllocStep; 1366 } while (--iNewBlocks); 1367 } 1368 FX_WCHAR* pTextData = (FX_WCHAR*)m_BlockArray[iBlockIndex]; 1369 *(pTextData + iInnerIndex) = ch; 1370 if (m_iDataLength <= iIndex) { 1371 m_iDataLength = iIndex + 1; 1372 } 1373 } 1374 int32_t CFDE_BlockBuffer::DeleteTextChars(int32_t iCount, FX_BOOL bDirection) { 1375 if (iCount <= 0) { 1376 return m_iDataLength; 1377 } 1378 if (iCount >= m_iDataLength) { 1379 Reset(FALSE); 1380 return 0; 1381 } 1382 if (bDirection) { 1383 m_iStartPosition += iCount; 1384 m_iDataLength -= iCount; 1385 } else { 1386 m_iDataLength -= iCount; 1387 } 1388 return m_iDataLength; 1389 } 1390 void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, 1391 int32_t iStart, 1392 int32_t iLength) const { 1393 wsTextData.Empty(); 1394 int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition; 1395 if (iStart < 0 || iStart > iMaybeDataLength) { 1396 return; 1397 } 1398 if (iLength == -1 || iLength > iMaybeDataLength) { 1399 iLength = iMaybeDataLength; 1400 } 1401 if (iLength <= 0) { 1402 return; 1403 } 1404 FX_WCHAR* pBuf = wsTextData.GetBuffer(iLength); 1405 if (!pBuf) { 1406 return; 1407 } 1408 int32_t iStartBlockIndex = 0; 1409 int32_t iStartInnerIndex = 0; 1410 TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex); 1411 int32_t iEndBlockIndex = 0; 1412 int32_t iEndInnerIndex = 0; 1413 TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex); 1414 int32_t iPointer = 0; 1415 for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) { 1416 int32_t iBufferPointer = 0; 1417 int32_t iCopyLength = m_iAllocStep; 1418 if (i == iStartBlockIndex) { 1419 iCopyLength -= iStartInnerIndex; 1420 iBufferPointer = iStartInnerIndex; 1421 } 1422 if (i == iEndBlockIndex) { 1423 iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex); 1424 } 1425 FX_WCHAR* pBlockBuf = (FX_WCHAR*)m_BlockArray[i]; 1426 FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, 1427 iCopyLength * sizeof(FX_WCHAR)); 1428 iPointer += iCopyLength; 1429 } 1430 wsTextData.ReleaseBuffer(iLength); 1431 } 1432 void CFDE_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex, 1433 int32_t& iBlockIndex, 1434 int32_t& iInnerIndex) const { 1435 FXSYS_assert(iIndex >= 0); 1436 int32_t iRealIndex = m_iStartPosition + iIndex; 1437 iBlockIndex = iRealIndex / m_iAllocStep; 1438 iInnerIndex = iRealIndex % m_iAllocStep; 1439 } 1440 void CFDE_BlockBuffer::ClearBuffer() { 1441 m_iBufferSize = 0; 1442 int32_t iSize = m_BlockArray.GetSize(); 1443 for (int32_t i = 0; i < iSize; i++) { 1444 FX_Free(m_BlockArray[i]); 1445 m_BlockArray[i] = NULL; 1446 } 1447 m_BlockArray.RemoveAll(); 1448 } 1449 #endif 1450 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { 1451 return new CFDE_XMLSyntaxParser; 1452 } 1453 #ifdef _FDE_BLOCK_BUFFER 1454 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() 1455 : m_pStream(nullptr), 1456 m_iXMLPlaneSize(-1), 1457 m_iCurrentPos(0), 1458 m_iCurrentNodeNum(-1), 1459 m_iLastNodeNum(-1), 1460 m_iParsedChars(0), 1461 m_iParsedBytes(0), 1462 m_pBuffer(nullptr), 1463 m_iBufferChars(0), 1464 m_bEOS(FALSE), 1465 m_pStart(nullptr), 1466 m_pEnd(nullptr), 1467 m_XMLNodeStack(16), 1468 m_iAllocStep(m_BlockBuffer.GetAllocStep()), 1469 m_iDataLength(m_BlockBuffer.GetDataLengthRef()), 1470 m_pCurrentBlock(nullptr), 1471 m_iIndexInBlock(0), 1472 m_iTextDataLength(0), 1473 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), 1474 m_dwMode(FDE_XMLSYNTAXMODE_Text), 1475 m_wQuotationMark(0), 1476 m_iEntityStart(-1), 1477 m_SkipStack(16) { 1478 m_CurNode.iNodeNum = -1; 1479 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 1480 } 1481 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, 1482 int32_t iXMLPlaneSize, 1483 int32_t iTextDataSize) { 1484 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); 1485 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0); 1486 int32_t iStreamLength = pStream->GetLength(); 1487 FXSYS_assert(iStreamLength > 0); 1488 m_pStream = pStream; 1489 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); 1490 uint8_t bom[4]; 1491 m_iCurrentPos = m_pStream->GetBOM(bom); 1492 FXSYS_assert(m_pBuffer == NULL); 1493 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); 1494 m_pStart = m_pEnd = m_pBuffer; 1495 FXSYS_assert(!m_BlockBuffer.IsInitialized()); 1496 m_BlockBuffer.InitBuffer(); 1497 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1498 m_iParsedBytes = m_iParsedChars = 0; 1499 m_iBufferChars = 0; 1500 } 1501 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { 1502 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || 1503 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { 1504 return m_dwStatus; 1505 } 1506 FXSYS_assert(m_pStream && m_pBuffer && m_BlockBuffer.IsInitialized()); 1507 int32_t iStreamLength = m_pStream->GetLength(); 1508 int32_t iPos; 1509 FX_WCHAR ch; 1510 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; 1511 while (TRUE) { 1512 if (m_pStart >= m_pEnd) { 1513 if (m_bEOS || m_iCurrentPos >= iStreamLength) { 1514 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; 1515 return m_dwStatus; 1516 } 1517 m_iParsedChars += (m_pEnd - m_pBuffer); 1518 m_iParsedBytes = m_iCurrentPos; 1519 m_pStream->Lock(); 1520 if (m_pStream->GetPosition() != m_iCurrentPos) { 1521 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); 1522 } 1523 m_iBufferChars = 1524 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); 1525 iPos = m_pStream->GetPosition(); 1526 m_pStream->Unlock(); 1527 if (m_iBufferChars < 1) { 1528 m_iCurrentPos = iStreamLength; 1529 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; 1530 return m_dwStatus; 1531 } 1532 m_iCurrentPos = iPos; 1533 m_pStart = m_pBuffer; 1534 m_pEnd = m_pBuffer + m_iBufferChars; 1535 } 1536 while (m_pStart < m_pEnd) { 1537 ch = *m_pStart; 1538 switch (m_dwMode) { 1539 case FDE_XMLSYNTAXMODE_Text: 1540 if (ch == L'<') { 1541 if (m_iDataLength > 0) { 1542 m_iTextDataLength = m_iDataLength; 1543 m_BlockBuffer.Reset(); 1544 m_pCurrentBlock = 1545 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1546 m_iEntityStart = -1; 1547 dwStatus = FDE_XMLSYNTAXSTATUS_Text; 1548 } else { 1549 m_pStart++; 1550 m_dwMode = FDE_XMLSYNTAXMODE_Node; 1551 } 1552 } else { 1553 ParseTextChar(ch); 1554 } 1555 break; 1556 case FDE_XMLSYNTAXMODE_Node: 1557 if (ch == L'!') { 1558 m_pStart++; 1559 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; 1560 } else if (ch == L'/') { 1561 m_pStart++; 1562 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; 1563 } else if (ch == L'?') { 1564 m_iLastNodeNum++; 1565 m_iCurrentNodeNum = m_iLastNodeNum; 1566 m_CurNode.iNodeNum = m_iLastNodeNum; 1567 m_CurNode.eNodeType = FDE_XMLNODE_Instruction; 1568 m_XMLNodeStack.Push(m_CurNode); 1569 m_pStart++; 1570 m_dwMode = FDE_XMLSYNTAXMODE_Target; 1571 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; 1572 } else { 1573 m_iLastNodeNum++; 1574 m_iCurrentNodeNum = m_iLastNodeNum; 1575 m_CurNode.iNodeNum = m_iLastNodeNum; 1576 m_CurNode.eNodeType = FDE_XMLNODE_Element; 1577 m_XMLNodeStack.Push(m_CurNode); 1578 m_dwMode = FDE_XMLSYNTAXMODE_Tag; 1579 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; 1580 } 1581 break; 1582 case FDE_XMLSYNTAXMODE_Target: 1583 case FDE_XMLSYNTAXMODE_Tag: 1584 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { 1585 if (m_iDataLength < 1) { 1586 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1587 return m_dwStatus; 1588 } else { 1589 m_iTextDataLength = m_iDataLength; 1590 m_BlockBuffer.Reset(); 1591 m_pCurrentBlock = 1592 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1593 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { 1594 dwStatus = FDE_XMLSYNTAXSTATUS_TagName; 1595 } else { 1596 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; 1597 } 1598 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; 1599 } 1600 } else { 1601 if (m_iIndexInBlock == m_iAllocStep) { 1602 m_pCurrentBlock = 1603 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1604 if (!m_pCurrentBlock) { 1605 return FDE_XMLSYNTAXSTATUS_Error; 1606 } 1607 } 1608 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1609 m_iDataLength++; 1610 m_pStart++; 1611 } 1612 break; 1613 case FDE_XMLSYNTAXMODE_AttriName: 1614 if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) { 1615 m_pStart++; 1616 break; 1617 } 1618 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { 1619 if (m_iDataLength < 1) { 1620 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { 1621 if (ch == L'>' || ch == L'/') { 1622 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; 1623 break; 1624 } 1625 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 1626 if (ch == L'?') { 1627 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; 1628 m_pStart++; 1629 } else { 1630 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 1631 } 1632 break; 1633 } 1634 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1635 return m_dwStatus; 1636 } else { 1637 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 1638 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { 1639 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 1640 break; 1641 } 1642 } 1643 m_iTextDataLength = m_iDataLength; 1644 m_BlockBuffer.Reset(); 1645 m_pCurrentBlock = 1646 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1647 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; 1648 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; 1649 } 1650 } else { 1651 if (m_iIndexInBlock == m_iAllocStep) { 1652 m_pCurrentBlock = 1653 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1654 if (!m_pCurrentBlock) { 1655 return FDE_XMLSYNTAXSTATUS_Error; 1656 } 1657 } 1658 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1659 m_iDataLength++; 1660 m_pStart++; 1661 } 1662 break; 1663 case FDE_XMLSYNTAXMODE_AttriEqualSign: 1664 if (FDE_IsXMLWhiteSpace(ch)) { 1665 m_pStart++; 1666 break; 1667 } 1668 if (ch != L'=') { 1669 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 1670 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 1671 break; 1672 } 1673 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1674 return m_dwStatus; 1675 } else { 1676 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; 1677 m_pStart++; 1678 } 1679 break; 1680 case FDE_XMLSYNTAXMODE_AttriQuotation: 1681 if (FDE_IsXMLWhiteSpace(ch)) { 1682 m_pStart++; 1683 break; 1684 } 1685 if (ch != L'\"' && ch != L'\'') { 1686 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1687 return m_dwStatus; 1688 } else { 1689 m_wQuotationMark = ch; 1690 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; 1691 m_pStart++; 1692 } 1693 break; 1694 case FDE_XMLSYNTAXMODE_AttriValue: 1695 if (ch == m_wQuotationMark) { 1696 if (m_iEntityStart > -1) { 1697 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1698 return m_dwStatus; 1699 } 1700 m_iTextDataLength = m_iDataLength; 1701 m_wQuotationMark = 0; 1702 m_BlockBuffer.Reset(); 1703 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1704 m_pStart++; 1705 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; 1706 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; 1707 } else { 1708 ParseTextChar(ch); 1709 } 1710 break; 1711 case FDE_XMLSYNTAXMODE_CloseInstruction: 1712 if (ch != L'>') { 1713 if (m_iIndexInBlock == m_iAllocStep) { 1714 m_pCurrentBlock = 1715 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1716 if (!m_pCurrentBlock) { 1717 return FDE_XMLSYNTAXSTATUS_Error; 1718 } 1719 } 1720 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1721 m_iDataLength++; 1722 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 1723 } else if (m_iDataLength > 0) { 1724 m_iTextDataLength = m_iDataLength; 1725 m_BlockBuffer.Reset(); 1726 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1727 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 1728 } else { 1729 m_pStart++; 1730 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); 1731 if (pXMLNode == NULL) { 1732 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1733 return m_dwStatus; 1734 } 1735 m_XMLNodeStack.Pop(); 1736 pXMLNode = m_XMLNodeStack.GetTopElement(); 1737 if (pXMLNode == NULL) { 1738 m_CurNode.iNodeNum = -1; 1739 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 1740 } else { 1741 m_CurNode = *pXMLNode; 1742 } 1743 m_iCurrentNodeNum = m_CurNode.iNodeNum; 1744 m_BlockBuffer.Reset(); 1745 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1746 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1747 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; 1748 } 1749 break; 1750 case FDE_XMLSYNTAXMODE_BreakElement: 1751 if (ch == L'>') { 1752 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1753 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; 1754 } else if (ch == L'/') { 1755 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; 1756 } else { 1757 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1758 return m_dwStatus; 1759 } 1760 m_pStart++; 1761 break; 1762 case FDE_XMLSYNTAXMODE_CloseElement: 1763 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { 1764 if (ch == L'>') { 1765 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); 1766 if (pXMLNode == NULL) { 1767 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1768 return m_dwStatus; 1769 } 1770 m_XMLNodeStack.Pop(); 1771 pXMLNode = m_XMLNodeStack.GetTopElement(); 1772 if (pXMLNode == NULL) { 1773 m_CurNode.iNodeNum = -1; 1774 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 1775 } else { 1776 m_CurNode = *pXMLNode; 1777 } 1778 m_iCurrentNodeNum = m_CurNode.iNodeNum; 1779 m_iTextDataLength = m_iDataLength; 1780 m_BlockBuffer.Reset(); 1781 m_pCurrentBlock = 1782 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1783 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1784 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; 1785 } else if (!FDE_IsXMLWhiteSpace(ch)) { 1786 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1787 return m_dwStatus; 1788 } 1789 } else { 1790 if (m_iIndexInBlock == m_iAllocStep) { 1791 m_pCurrentBlock = 1792 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1793 if (!m_pCurrentBlock) { 1794 return FDE_XMLSYNTAXSTATUS_Error; 1795 } 1796 } 1797 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1798 m_iDataLength++; 1799 } 1800 m_pStart++; 1801 break; 1802 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: 1803 if (ch == '-') { 1804 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; 1805 } else { 1806 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; 1807 m_SkipChar = L'>'; 1808 m_SkipStack.Push(L'>'); 1809 } 1810 break; 1811 case FDE_XMLSYNTAXMODE_SkipDeclNode: 1812 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { 1813 m_pStart++; 1814 if (ch != m_SkipChar) { 1815 break; 1816 } 1817 m_SkipStack.Pop(); 1818 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); 1819 if (pDWord == NULL) { 1820 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1821 } else { 1822 m_SkipChar = (FX_WCHAR)*pDWord; 1823 } 1824 } else { 1825 switch (ch) { 1826 case L'<': 1827 m_SkipChar = L'>'; 1828 m_SkipStack.Push(L'>'); 1829 break; 1830 case L'[': 1831 m_SkipChar = L']'; 1832 m_SkipStack.Push(L']'); 1833 break; 1834 case L'(': 1835 m_SkipChar = L')'; 1836 m_SkipStack.Push(L')'); 1837 break; 1838 case L'\'': 1839 m_SkipChar = L'\''; 1840 m_SkipStack.Push(L'\''); 1841 break; 1842 case L'\"': 1843 m_SkipChar = L'\"'; 1844 m_SkipStack.Push(L'\"'); 1845 break; 1846 default: 1847 if (ch == m_SkipChar) { 1848 m_SkipStack.Pop(); 1849 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); 1850 if (pDWord == NULL) { 1851 if (m_iDataLength >= 9) { 1852 CFX_WideString wsHeader; 1853 m_BlockBuffer.GetTextData(wsHeader, 0, 7); 1854 if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) { 1855 CFX_WideString wsTailer; 1856 m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, 1857 2); 1858 if (wsTailer.Equal(FX_WSTRC(L"]]"))) { 1859 m_BlockBuffer.DeleteTextChars(7, TRUE); 1860 m_BlockBuffer.DeleteTextChars(2, FALSE); 1861 dwStatus = FDE_XMLSYNTAXSTATUS_CData; 1862 } 1863 } 1864 } 1865 m_iTextDataLength = m_iDataLength; 1866 m_BlockBuffer.Reset(); 1867 m_pCurrentBlock = 1868 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1869 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1870 } else { 1871 m_SkipChar = (FX_WCHAR)*pDWord; 1872 } 1873 } 1874 break; 1875 } 1876 if (m_SkipStack.GetSize() > 0) { 1877 if (m_iIndexInBlock == m_iAllocStep) { 1878 m_pCurrentBlock = 1879 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1880 if (!m_pCurrentBlock) { 1881 return FDE_XMLSYNTAXSTATUS_Error; 1882 } 1883 } 1884 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1885 m_iDataLength++; 1886 } 1887 m_pStart++; 1888 } 1889 break; 1890 case FDE_XMLSYNTAXMODE_SkipComment: 1891 if (ch == L'-') { 1892 if (m_iIndexInBlock == m_iAllocStep) { 1893 m_pCurrentBlock = 1894 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1895 if (!m_pCurrentBlock) { 1896 return FDE_XMLSYNTAXSTATUS_Error; 1897 } 1898 } 1899 m_pCurrentBlock[m_iIndexInBlock++] = L'-'; 1900 m_iDataLength++; 1901 } else if (ch == L'>') { 1902 if (m_iDataLength > 1) { 1903 m_BlockBuffer.Reset(); 1904 m_pCurrentBlock = 1905 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1906 m_dwMode = FDE_XMLSYNTAXMODE_Text; 1907 } 1908 } else { 1909 m_BlockBuffer.Reset(); 1910 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1911 } 1912 m_pStart++; 1913 break; 1914 case FDE_XMLSYNTAXMODE_TargetData: 1915 if (FDE_IsXMLWhiteSpace(ch)) { 1916 if (m_iDataLength < 1) { 1917 m_pStart++; 1918 break; 1919 } else if (m_wQuotationMark == 0) { 1920 m_iTextDataLength = m_iDataLength; 1921 m_wQuotationMark = 0; 1922 m_BlockBuffer.Reset(); 1923 m_pCurrentBlock = 1924 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1925 m_pStart++; 1926 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 1927 break; 1928 } 1929 } 1930 if (ch == '?') { 1931 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; 1932 m_pStart++; 1933 } else if (ch == '\"') { 1934 if (m_wQuotationMark == 0) { 1935 m_wQuotationMark = ch; 1936 m_pStart++; 1937 } else if (ch == m_wQuotationMark) { 1938 m_iTextDataLength = m_iDataLength; 1939 m_wQuotationMark = 0; 1940 m_BlockBuffer.Reset(); 1941 m_pCurrentBlock = 1942 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1943 m_pStart++; 1944 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 1945 } else { 1946 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 1947 return m_dwStatus; 1948 } 1949 } else { 1950 if (m_iIndexInBlock == m_iAllocStep) { 1951 m_pCurrentBlock = 1952 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 1953 if (!m_pCurrentBlock) { 1954 return FDE_XMLSYNTAXSTATUS_Error; 1955 } 1956 } 1957 m_pCurrentBlock[m_iIndexInBlock++] = ch; 1958 m_iDataLength++; 1959 m_pStart++; 1960 } 1961 break; 1962 default: 1963 break; 1964 } 1965 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { 1966 return dwStatus; 1967 } 1968 } 1969 } 1970 return 0; 1971 } 1972 #else 1973 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() 1974 : m_pStream(NULL), 1975 m_iXMLPlaneSize(-1), 1976 m_iTextDataSize(256), 1977 m_iCurrentPos(0), 1978 m_iCurrentNodeNum(-1), 1979 m_iLastNodeNum(-1), 1980 m_iParsedChars(0), 1981 m_iParsedBytes(0), 1982 m_pBuffer(NULL), 1983 m_iBufferChars(0), 1984 m_bEOS(FALSE), 1985 m_pStart(NULL), 1986 m_pEnd(NULL), 1987 m_XMLNodeStack(16), 1988 m_pwsTextData(NULL), 1989 m_iDataPos(0), 1990 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), 1991 m_dwMode(FDE_XMLSYNTAXMODE_Text), 1992 m_wQuotationMark(0), 1993 m_iTextDataLength(0), 1994 m_iEntityStart(-1), 1995 m_SkipStack(16) { 1996 m_CurNode.iNodeNum = -1; 1997 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 1998 } 1999 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, 2000 int32_t iXMLPlaneSize, 2001 int32_t iTextDataSize) { 2002 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); 2003 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0); 2004 int32_t iStreamLength = pStream->GetLength(); 2005 FXSYS_assert(iStreamLength > 0); 2006 m_pStream = pStream; 2007 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); 2008 m_iTextDataSize = iTextDataSize; 2009 uint8_t bom[4]; 2010 m_iCurrentPos = m_pStream->GetBOM(bom); 2011 FXSYS_assert(m_pBuffer == NULL); 2012 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); 2013 m_pStart = m_pEnd = m_pBuffer; 2014 FXSYS_assert(m_pwsTextData == NULL); 2015 m_pwsTextData = FX_Alloc(FX_WCHAR, m_iTextDataSize); 2016 m_iParsedBytes = 0; 2017 m_iParsedChars = 0; 2018 m_iBufferChars = 0; 2019 } 2020 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { 2021 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || 2022 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { 2023 return m_dwStatus; 2024 } 2025 FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL); 2026 int32_t iStreamLength = m_pStream->GetLength(); 2027 int32_t iPos; 2028 FX_WCHAR ch; 2029 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; 2030 while (TRUE) { 2031 if (m_pStart >= m_pEnd) { 2032 if (m_bEOS || m_iCurrentPos >= iStreamLength) { 2033 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; 2034 return m_dwStatus; 2035 } 2036 m_iParsedChars += (m_pEnd - m_pBuffer); 2037 m_iParsedBytes = m_iCurrentPos; 2038 m_pStream->Lock(); 2039 if (m_pStream->GetPosition() != m_iCurrentPos) { 2040 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); 2041 } 2042 m_iBufferChars = 2043 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); 2044 iPos = m_pStream->GetPosition(); 2045 m_pStream->Unlock(); 2046 if (m_iBufferChars < 1) { 2047 m_iCurrentPos = iStreamLength; 2048 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; 2049 return m_dwStatus; 2050 } 2051 m_iCurrentPos = iPos; 2052 m_pStart = m_pBuffer; 2053 m_pEnd = m_pBuffer + m_iBufferChars; 2054 } 2055 while (m_pStart < m_pEnd) { 2056 ch = *m_pStart; 2057 switch (m_dwMode) { 2058 case FDE_XMLSYNTAXMODE_Text: 2059 if (ch == L'<') { 2060 if (m_iDataPos > 0) { 2061 m_iTextDataLength = m_iDataPos; 2062 m_iDataPos = 0; 2063 m_iEntityStart = -1; 2064 dwStatus = FDE_XMLSYNTAXSTATUS_Text; 2065 } else { 2066 m_pStart++; 2067 m_dwMode = FDE_XMLSYNTAXMODE_Node; 2068 } 2069 } else { 2070 ParseTextChar(ch); 2071 } 2072 break; 2073 case FDE_XMLSYNTAXMODE_Node: 2074 if (ch == L'!') { 2075 m_pStart++; 2076 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; 2077 } else if (ch == L'/') { 2078 m_pStart++; 2079 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; 2080 } else if (ch == L'?') { 2081 m_iLastNodeNum++; 2082 m_iCurrentNodeNum = m_iLastNodeNum; 2083 m_CurNode.iNodeNum = m_iLastNodeNum; 2084 m_CurNode.eNodeType = FDE_XMLNODE_Instruction; 2085 m_XMLNodeStack.Push(m_CurNode); 2086 m_pStart++; 2087 m_dwMode = FDE_XMLSYNTAXMODE_Target; 2088 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; 2089 } else { 2090 m_iLastNodeNum++; 2091 m_iCurrentNodeNum = m_iLastNodeNum; 2092 m_CurNode.iNodeNum = m_iLastNodeNum; 2093 m_CurNode.eNodeType = FDE_XMLNODE_Element; 2094 m_XMLNodeStack.Push(m_CurNode); 2095 m_dwMode = FDE_XMLSYNTAXMODE_Tag; 2096 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; 2097 } 2098 break; 2099 case FDE_XMLSYNTAXMODE_Target: 2100 case FDE_XMLSYNTAXMODE_Tag: 2101 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { 2102 if (m_iDataPos < 1) { 2103 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2104 return m_dwStatus; 2105 } else { 2106 m_iTextDataLength = m_iDataPos; 2107 m_iDataPos = 0; 2108 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { 2109 dwStatus = FDE_XMLSYNTAXSTATUS_TagName; 2110 } else { 2111 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; 2112 } 2113 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; 2114 } 2115 } else { 2116 if (m_iDataPos >= m_iTextDataSize) { 2117 ReallocTextDataBuffer(); 2118 } 2119 m_pwsTextData[m_iDataPos++] = ch; 2120 m_pStart++; 2121 } 2122 break; 2123 case FDE_XMLSYNTAXMODE_AttriName: 2124 if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) { 2125 m_pStart++; 2126 break; 2127 } 2128 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { 2129 if (m_iDataPos < 1) { 2130 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { 2131 if (ch == L'>' || ch == L'/') { 2132 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; 2133 break; 2134 } 2135 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 2136 if (ch == L'?') { 2137 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; 2138 m_pStart++; 2139 } else { 2140 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 2141 } 2142 break; 2143 } 2144 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2145 return m_dwStatus; 2146 } else { 2147 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 2148 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { 2149 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 2150 break; 2151 } 2152 } 2153 m_iTextDataLength = m_iDataPos; 2154 m_iDataPos = 0; 2155 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; 2156 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; 2157 } 2158 } else { 2159 if (m_iDataPos >= m_iTextDataSize) { 2160 ReallocTextDataBuffer(); 2161 } 2162 m_pwsTextData[m_iDataPos++] = ch; 2163 m_pStart++; 2164 } 2165 break; 2166 case FDE_XMLSYNTAXMODE_AttriEqualSign: 2167 if (FDE_IsXMLWhiteSpace(ch)) { 2168 m_pStart++; 2169 break; 2170 } 2171 if (ch != L'=') { 2172 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { 2173 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 2174 break; 2175 } 2176 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2177 return m_dwStatus; 2178 } else { 2179 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; 2180 m_pStart++; 2181 } 2182 break; 2183 case FDE_XMLSYNTAXMODE_AttriQuotation: 2184 if (FDE_IsXMLWhiteSpace(ch)) { 2185 m_pStart++; 2186 break; 2187 } 2188 if (ch != L'\"' && ch != L'\'') { 2189 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2190 return m_dwStatus; 2191 } else { 2192 m_wQuotationMark = ch; 2193 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; 2194 m_pStart++; 2195 } 2196 break; 2197 case FDE_XMLSYNTAXMODE_AttriValue: 2198 if (ch == m_wQuotationMark) { 2199 if (m_iEntityStart > -1) { 2200 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2201 return m_dwStatus; 2202 } 2203 m_iTextDataLength = m_iDataPos; 2204 m_wQuotationMark = 0; 2205 m_iDataPos = 0; 2206 m_pStart++; 2207 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; 2208 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; 2209 } else { 2210 ParseTextChar(ch); 2211 } 2212 break; 2213 case FDE_XMLSYNTAXMODE_CloseInstruction: 2214 if (ch != L'>') { 2215 if (m_iDataPos >= m_iTextDataSize) { 2216 ReallocTextDataBuffer(); 2217 } 2218 m_pwsTextData[m_iDataPos++] = ch; 2219 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; 2220 } else if (m_iDataPos > 0) { 2221 m_iTextDataLength = m_iDataPos; 2222 m_iDataPos = 0; 2223 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 2224 } else { 2225 m_pStart++; 2226 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); 2227 if (pXMLNode == NULL) { 2228 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2229 return m_dwStatus; 2230 } 2231 m_XMLNodeStack.Pop(); 2232 pXMLNode = m_XMLNodeStack.GetTopElement(); 2233 if (pXMLNode == NULL) { 2234 m_CurNode.iNodeNum = -1; 2235 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 2236 } else { 2237 m_CurNode = *pXMLNode; 2238 } 2239 m_iCurrentNodeNum = m_CurNode.iNodeNum; 2240 m_iDataPos = 0; 2241 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2242 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; 2243 } 2244 break; 2245 case FDE_XMLSYNTAXMODE_BreakElement: 2246 if (ch == L'>') { 2247 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2248 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; 2249 } else if (ch == L'/') { 2250 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; 2251 } else { 2252 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2253 return m_dwStatus; 2254 } 2255 m_pStart++; 2256 break; 2257 case FDE_XMLSYNTAXMODE_CloseElement: 2258 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { 2259 if (ch == L'>') { 2260 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); 2261 if (pXMLNode == NULL) { 2262 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2263 return m_dwStatus; 2264 } 2265 m_XMLNodeStack.Pop(); 2266 pXMLNode = m_XMLNodeStack.GetTopElement(); 2267 if (pXMLNode == NULL) { 2268 m_CurNode.iNodeNum = -1; 2269 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; 2270 } else { 2271 m_CurNode = *pXMLNode; 2272 } 2273 m_iCurrentNodeNum = m_CurNode.iNodeNum; 2274 m_iTextDataLength = m_iDataPos; 2275 m_iDataPos = 0; 2276 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2277 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; 2278 } else if (!FDE_IsXMLWhiteSpace(ch)) { 2279 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2280 return m_dwStatus; 2281 } 2282 } else { 2283 if (m_iDataPos >= m_iTextDataSize) { 2284 ReallocTextDataBuffer(); 2285 } 2286 m_pwsTextData[m_iDataPos++] = ch; 2287 } 2288 m_pStart++; 2289 break; 2290 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: 2291 if (ch == '-') { 2292 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; 2293 } else { 2294 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; 2295 m_SkipChar = L'>'; 2296 m_SkipStack.Push(L'>'); 2297 } 2298 break; 2299 case FDE_XMLSYNTAXMODE_SkipDeclNode: 2300 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { 2301 m_pStart++; 2302 if (ch != m_SkipChar) { 2303 break; 2304 } 2305 m_SkipStack.Pop(); 2306 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); 2307 if (pDWord == NULL) { 2308 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2309 } else { 2310 m_SkipChar = (FX_WCHAR)*pDWord; 2311 } 2312 } else { 2313 switch (ch) { 2314 case L'<': 2315 m_SkipChar = L'>'; 2316 m_SkipStack.Push(L'>'); 2317 break; 2318 case L'[': 2319 m_SkipChar = L']'; 2320 m_SkipStack.Push(L']'); 2321 break; 2322 case L'(': 2323 m_SkipChar = L')'; 2324 m_SkipStack.Push(L')'); 2325 break; 2326 case L'\'': 2327 m_SkipChar = L'\''; 2328 m_SkipStack.Push(L'\''); 2329 break; 2330 case L'\"': 2331 m_SkipChar = L'\"'; 2332 m_SkipStack.Push(L'\"'); 2333 break; 2334 default: 2335 if (ch == m_SkipChar) { 2336 m_SkipStack.Pop(); 2337 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); 2338 if (pDWord == NULL) { 2339 m_iTextDataLength = m_iDataPos; 2340 m_iDataPos = 0; 2341 if (m_iTextDataLength >= 9 && 2342 FXSYS_memcmp(m_pwsTextData, L"[CDATA[", 2343 7 * sizeof(FX_WCHAR)) == 0 && 2344 FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, 2345 L"]]", 2 * sizeof(FX_WCHAR)) == 0) { 2346 m_iTextDataLength -= 9; 2347 FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, 2348 m_iTextDataLength * sizeof(FX_WCHAR)); 2349 dwStatus = FDE_XMLSYNTAXSTATUS_CData; 2350 } 2351 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2352 } else { 2353 m_SkipChar = (FX_WCHAR)*pDWord; 2354 } 2355 } 2356 break; 2357 } 2358 if (m_SkipStack.GetSize() > 0) { 2359 if (m_iDataPos >= m_iTextDataSize) { 2360 ReallocTextDataBuffer(); 2361 } 2362 m_pwsTextData[m_iDataPos++] = ch; 2363 } 2364 m_pStart++; 2365 } 2366 break; 2367 case FDE_XMLSYNTAXMODE_SkipComment: 2368 if (ch == L'-') { 2369 m_iDataPos++; 2370 } else if (ch == L'>') { 2371 if (m_iDataPos > 1) { 2372 m_iDataPos = 0; 2373 m_dwMode = FDE_XMLSYNTAXMODE_Text; 2374 } 2375 } else { 2376 m_iDataPos = 0; 2377 } 2378 m_pStart++; 2379 break; 2380 case FDE_XMLSYNTAXMODE_TargetData: 2381 if (FDE_IsXMLWhiteSpace(ch)) { 2382 if (m_iDataPos < 1) { 2383 m_pStart++; 2384 break; 2385 } else if (m_wQuotationMark == 0) { 2386 m_iTextDataLength = m_iDataPos; 2387 m_wQuotationMark = 0; 2388 m_iDataPos = 0; 2389 m_pStart++; 2390 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 2391 break; 2392 } 2393 } 2394 if (ch == '?') { 2395 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; 2396 m_pStart++; 2397 } else if (ch == '\"') { 2398 if (m_wQuotationMark == 0) { 2399 m_wQuotationMark = ch; 2400 m_pStart++; 2401 } else if (ch == m_wQuotationMark) { 2402 m_iTextDataLength = m_iDataPos; 2403 m_wQuotationMark = 0; 2404 m_iDataPos = 0; 2405 m_pStart++; 2406 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; 2407 } else { 2408 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; 2409 return m_dwStatus; 2410 } 2411 } else { 2412 if (m_iDataPos >= m_iTextDataSize) { 2413 ReallocTextDataBuffer(); 2414 } 2415 m_pwsTextData[m_iDataPos++] = ch; 2416 m_pStart++; 2417 } 2418 break; 2419 default: 2420 break; 2421 } 2422 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { 2423 return dwStatus; 2424 } 2425 } 2426 } 2427 return 0; 2428 } 2429 #endif 2430 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { 2431 #ifdef _FDE_BLOCK_BUFFER 2432 if (m_pCurrentBlock) { 2433 m_pCurrentBlock = NULL; 2434 } 2435 #else 2436 FX_Free(m_pwsTextData); 2437 #endif 2438 FX_Free(m_pBuffer); 2439 } 2440 int32_t CFDE_XMLSyntaxParser::GetStatus() const { 2441 if (m_pStream == NULL) { 2442 return -1; 2443 } 2444 int32_t iStreamLength = m_pStream->GetLength(); 2445 if (iStreamLength < 1) { 2446 return 100; 2447 } 2448 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { 2449 return -1; 2450 } 2451 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { 2452 return 100; 2453 } 2454 return m_iParsedBytes * 100 / iStreamLength; 2455 } 2456 static int32_t FX_GetUTF8EncodeLength(const FX_WCHAR* pSrc, int32_t iSrcLen) { 2457 FX_DWORD unicode = 0; 2458 int32_t iDstNum = 0; 2459 while (iSrcLen-- > 0) { 2460 unicode = *pSrc++; 2461 int nbytes = 0; 2462 if ((FX_DWORD)unicode < 0x80) { 2463 nbytes = 1; 2464 } else if ((FX_DWORD)unicode < 0x800) { 2465 nbytes = 2; 2466 } else if ((FX_DWORD)unicode < 0x10000) { 2467 nbytes = 3; 2468 } else if ((FX_DWORD)unicode < 0x200000) { 2469 nbytes = 4; 2470 } else if ((FX_DWORD)unicode < 0x4000000) { 2471 nbytes = 5; 2472 } else { 2473 nbytes = 6; 2474 } 2475 iDstNum += nbytes; 2476 } 2477 return iDstNum; 2478 } 2479 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { 2480 if (m_pStream == NULL) { 2481 return 0; 2482 } 2483 int32_t nSrcLen = m_pStart - m_pBuffer; 2484 int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); 2485 return m_iParsedBytes + nDstLen; 2486 } 2487 #ifdef _FDE_BLOCK_BUFFER 2488 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { 2489 if (m_iIndexInBlock == m_iAllocStep) { 2490 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 2491 if (!m_pCurrentBlock) { 2492 return; 2493 } 2494 } 2495 m_pCurrentBlock[m_iIndexInBlock++] = ch; 2496 m_iDataLength++; 2497 if (m_iEntityStart > -1 && ch == L';') { 2498 CFX_WideString csEntity; 2499 m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, 2500 (m_iDataLength - 1) - m_iEntityStart - 1); 2501 int32_t iLen = csEntity.GetLength(); 2502 if (iLen > 0) { 2503 if (csEntity[0] == L'#') { 2504 ch = 0; 2505 FX_WCHAR w; 2506 if (iLen > 1 && csEntity[1] == L'x') { 2507 for (int32_t i = 2; i < iLen; i++) { 2508 w = csEntity[i]; 2509 if (w >= L'0' && w <= L'9') { 2510 ch = (ch << 4) + w - L'0'; 2511 } else if (w >= L'A' && w <= L'F') { 2512 ch = (ch << 4) + w - 55; 2513 } else if (w >= L'a' && w <= L'f') { 2514 ch = (ch << 4) + w - 87; 2515 } else { 2516 break; 2517 } 2518 } 2519 } else { 2520 for (int32_t i = 1; i < iLen; i++) { 2521 w = csEntity[i]; 2522 if (w < L'0' || w > L'9') { 2523 break; 2524 } 2525 ch = ch * 10 + w - L'0'; 2526 } 2527 } 2528 if (ch != 0) { 2529 m_BlockBuffer.SetTextChar(m_iEntityStart, ch); 2530 m_iEntityStart++; 2531 } 2532 } else { 2533 if (csEntity.Compare(L"amp") == 0) { 2534 m_BlockBuffer.SetTextChar(m_iEntityStart, L'&'); 2535 m_iEntityStart++; 2536 } else if (csEntity.Compare(L"lt") == 0) { 2537 m_BlockBuffer.SetTextChar(m_iEntityStart, L'<'); 2538 m_iEntityStart++; 2539 } else if (csEntity.Compare(L"gt") == 0) { 2540 m_BlockBuffer.SetTextChar(m_iEntityStart, L'>'); 2541 m_iEntityStart++; 2542 } else if (csEntity.Compare(L"apos") == 0) { 2543 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\''); 2544 m_iEntityStart++; 2545 } else if (csEntity.Compare(L"quot") == 0) { 2546 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"'); 2547 m_iEntityStart++; 2548 } 2549 } 2550 } 2551 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); 2552 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); 2553 m_iEntityStart = -1; 2554 } else { 2555 if (m_iEntityStart < 0 && ch == L'&') { 2556 m_iEntityStart = m_iDataLength - 1; 2557 } 2558 } 2559 m_pStart++; 2560 } 2561 #else 2562 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { 2563 if (m_iDataPos >= m_iTextDataSize) { 2564 ReallocTextDataBuffer(); 2565 } 2566 m_pwsTextData[m_iDataPos] = ch; 2567 if (m_iEntityStart > -1 && ch == L';') { 2568 CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, 2569 m_iDataPos - m_iEntityStart - 1); 2570 int32_t iLen = csEntity.GetLength(); 2571 if (iLen > 0) { 2572 if (csEntity[0] == L'#') { 2573 ch = 0; 2574 FX_WCHAR w; 2575 if (iLen > 1 && csEntity[1] == L'x') { 2576 for (int32_t i = 2; i < iLen; i++) { 2577 w = csEntity[i]; 2578 if (w >= L'0' && w <= L'9') { 2579 ch = (ch << 4) + w - L'0'; 2580 } else if (w >= L'A' && w <= L'F') { 2581 ch = (ch << 4) + w - 55; 2582 } else if (w >= L'a' && w <= L'f') { 2583 ch = (ch << 4) + w - 87; 2584 } else { 2585 break; 2586 } 2587 } 2588 } else { 2589 for (int32_t i = 1; i < iLen; i++) { 2590 w = csEntity[i]; 2591 if (w < L'0' || w > L'9') { 2592 break; 2593 } 2594 ch = ch * 10 + w - L'0'; 2595 } 2596 } 2597 if (ch != 0) { 2598 m_pwsTextData[m_iEntityStart++] = ch; 2599 } 2600 } else { 2601 if (csEntity.Compare(L"amp") == 0) { 2602 m_pwsTextData[m_iEntityStart++] = L'&'; 2603 } else if (csEntity.Compare(L"lt") == 0) { 2604 m_pwsTextData[m_iEntityStart++] = L'<'; 2605 } else if (csEntity.Compare(L"gt") == 0) { 2606 m_pwsTextData[m_iEntityStart++] = L'>'; 2607 } else if (csEntity.Compare(L"apos") == 0) { 2608 m_pwsTextData[m_iEntityStart++] = L'\''; 2609 } else if (csEntity.Compare(L"quot") == 0) { 2610 m_pwsTextData[m_iEntityStart++] = L'\"'; 2611 } 2612 } 2613 } 2614 m_iDataPos = m_iEntityStart; 2615 m_iEntityStart = -1; 2616 } else { 2617 if (m_iEntityStart < 0 && ch == L'&') { 2618 m_iEntityStart = m_iDataPos; 2619 } 2620 m_iDataPos++; 2621 } 2622 m_pStart++; 2623 } 2624 void CFDE_XMLSyntaxParser::ReallocTextDataBuffer() { 2625 FXSYS_assert(m_pwsTextData != NULL); 2626 if (m_iTextDataSize <= 1024 * 1024) { 2627 m_iTextDataSize *= 2; 2628 } else { 2629 m_iTextDataSize += 1024 * 1024; 2630 } 2631 m_pwsTextData = FX_Realloc(FX_WCHAR, m_pwsTextData, m_iTextDataSize); 2632 } 2633 void CFDE_XMLSyntaxParser::GetData(CFX_WideString& wsData) const { 2634 FX_WCHAR* pBuf = wsData.GetBuffer(m_iTextDataLength); 2635 FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR)); 2636 wsData.ReleaseBuffer(m_iTextDataLength); 2637 } 2638 #endif 2639