1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
7 #include "../../../foxitlib.h"
\r
12 #define FDE_XMLVALIDCHARRANGENUM 5
\r
13 static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = {{0x09, 0x09}, {0x0A, 0x0A}, {0x0D, 0x0D}, {0x20, 0xD7FF}, {0xE000, 0xFFFD}};
\r
14 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch)
\r
16 FX_INT32 iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid;
\r
17 while (iStart <= iEnd) {
\r
18 iMid = (iStart + iEnd) / 2;
\r
19 if (ch < g_XMLValidCharRange[iMid][0]) {
\r
21 } else if (ch > g_XMLValidCharRange[iMid][1]) {
\r
29 FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch)
\r
31 return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09;
\r
33 typedef struct _FDE_XMLNAMECHAR {
\r
38 #define FDE_XMLNAMECHARSNUM 20
\r
39 static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = {
\r
40 {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, {L'A', L'Z', TRUE},
\r
41 {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE},
\r
42 {0xD8, 0xF6, TRUE}, {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE},
\r
43 {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, {0x2070, 0x218F, TRUE},
\r
44 {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE},
\r
46 FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar)
\r
48 FX_INT32 iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid;
\r
49 while (iStart <= iEnd) {
\r
50 iMid = (iStart + iEnd) / 2;
\r
51 if (ch < g_XMLNameChars[iMid].wStart) {
\r
53 } else if (ch > g_XMLNameChars[iMid].wEnd) {
\r
57 return g_XMLNameChars[iMid].bStartChar;
\r
67 CFDE_XMLNode::CFDE_XMLNode()
\r
74 CFDE_XMLNode::~CFDE_XMLNode()
\r
78 void CFDE_XMLNode::DeleteChildren()
\r
80 CFDE_XMLNode *pChild = m_pChild, *pTemp;
\r
81 while (pChild != NULL) {
\r
82 pTemp = pChild->m_pNext;
\r
88 FX_INT32 CFDE_XMLNode::CountChildNodes() const
\r
90 FX_INT32 iCount = 0;
\r
91 CFDE_XMLNode *pChild = m_pChild;
\r
92 while (pChild != NULL) {
\r
94 pChild = pChild->m_pNext;
\r
98 CFDE_XMLNode* CFDE_XMLNode::GetChildNode(FX_INT32 index) const
\r
100 CFDE_XMLNode *pChild = m_pChild;
\r
101 while (pChild != NULL) {
\r
106 pChild = pChild->m_pNext;
\r
110 FX_INT32 CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode *pNode) const
\r
112 FX_INT32 index = 0;
\r
113 CFDE_XMLNode *pChild = m_pChild;
\r
114 while (pChild != NULL) {
\r
115 if (pChild == pNode) {
\r
119 pChild = pChild->m_pNext;
\r
123 CFDE_XMLNode* CFDE_XMLNode::GetPath(FX_LPCWSTR pPath, FX_INT32 iLength, FX_BOOL bQualifiedName) const
\r
125 FXSYS_assert(pPath != NULL);
\r
127 iLength = FXSYS_wcslen(pPath);
\r
129 if (iLength == 0) {
\r
132 CFX_WideString csPath;
\r
133 FX_LPCWSTR pStart = pPath, pEnd = pPath + iLength;
\r
135 while (pStart < pEnd) {
\r
143 iLength -= pStart - pPath;
\r
144 CFDE_XMLNode *pFind = NULL;
\r
145 if (csPath.GetLength() < 1) {
\r
146 pFind = GetNodeItem(IFDE_XMLNode::Root);
\r
147 } else if (csPath.Compare(L"..") == 0) {
\r
149 } else if (csPath.Compare(L".") == 0) {
\r
150 pFind = (CFDE_XMLNode*)this;
\r
152 CFX_WideString wsTag;
\r
153 CFDE_XMLNode *pNode = m_pChild;
\r
154 while (pNode != NULL) {
\r
155 if (pNode->GetType() == FDE_XMLNODE_Element) {
\r
156 if (bQualifiedName) {
\r
157 ((CFDE_XMLElement*)pNode)->GetTagName(wsTag);
\r
159 ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag);
\r
161 if (wsTag.Compare(csPath) == 0) {
\r
165 pFind = pNode->GetPath(pStart, iLength, bQualifiedName);
\r
167 if (pFind != NULL) {
\r
172 pNode = pNode->m_pNext;
\r
175 if (pFind == NULL || iLength < 1) {
\r
178 return pFind->GetPath(pStart, iLength, bQualifiedName);
\r
180 FX_INT32 CFDE_XMLNode::InsertChildNode(CFDE_XMLNode *pNode, FX_INT32 index)
\r
182 FXSYS_assert(pNode != NULL);
\r
183 pNode->m_pParent = this;
\r
184 if (m_pChild == NULL) {
\r
186 pNode->m_pPrior = NULL;
\r
187 pNode->m_pNext = NULL;
\r
189 } else if (index == 0) {
\r
190 pNode->m_pNext = m_pChild;
\r
191 pNode->m_pPrior = NULL;
\r
192 m_pChild->m_pPrior = pNode;
\r
196 FX_INT32 iCount = 0;
\r
197 CFDE_XMLNode *pFind = m_pChild;
\r
198 while (++iCount != index && pFind->m_pNext != NULL) {
\r
199 pFind = pFind->m_pNext;
\r
201 pNode->m_pPrior = pFind;
\r
202 pNode->m_pNext = pFind->m_pNext;
\r
203 if (pFind->m_pNext != NULL) {
\r
204 pFind->m_pNext->m_pPrior = pNode;
\r
206 pFind->m_pNext = pNode;
\r
209 void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode *pNode)
\r
211 FXSYS_assert(m_pChild != NULL && pNode != NULL);
\r
212 if (m_pChild == pNode) {
\r
213 m_pChild = pNode->m_pNext;
\r
215 pNode->m_pPrior->m_pNext = pNode->m_pNext;
\r
217 if (pNode->m_pNext != NULL) {
\r
218 pNode->m_pNext->m_pPrior = pNode->m_pPrior;
\r
220 pNode->m_pParent = NULL;
\r
221 pNode->m_pNext = NULL;
\r
222 pNode->m_pPrior = NULL;
\r
224 CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const
\r
227 case IFDE_XMLNode::Root: {
\r
228 CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
\r
229 while (pParent->m_pParent != NULL) {
\r
230 pParent = pParent->m_pParent;
\r
234 case IFDE_XMLNode::Parent:
\r
236 case IFDE_XMLNode::FirstSibling: {
\r
237 CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
\r
238 while (pItem->m_pPrior != NULL) {
\r
239 pItem = pItem->m_pPrior;
\r
241 return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
\r
243 case IFDE_XMLNode::PriorSibling:
\r
245 case IFDE_XMLNode::NextSibling:
\r
247 case IFDE_XMLNode::LastSibling: {
\r
248 CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
\r
249 while (pItem->m_pNext != NULL) {
\r
250 pItem = pItem->m_pNext;
\r
252 return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
\r
254 case IFDE_XMLNode::FirstNeighbor: {
\r
255 CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
\r
256 while (pParent->m_pParent != NULL) {
\r
257 pParent = pParent->m_pParent;
\r
259 return pParent == (CFDE_XMLNode*)this ? NULL : pParent;
\r
261 case IFDE_XMLNode::PriorNeighbor: {
\r
262 if (m_pPrior == NULL) {
\r
265 CFDE_XMLNode *pItem = m_pPrior;
\r
266 while (CFDE_XMLNode *pTemp = pItem->m_pChild) {
\r
268 while ((pTemp = pItem->m_pNext) != NULL) {
\r
274 case IFDE_XMLNode::NextNeighbor: {
\r
275 if (m_pChild != NULL) {
\r
278 if (m_pNext != NULL) {
\r
281 CFDE_XMLNode *pItem = m_pParent;
\r
282 while (pItem != NULL) {
\r
283 if (pItem->m_pNext != NULL) {
\r
284 return pItem->m_pNext;
\r
286 pItem = pItem->m_pParent;
\r
290 case IFDE_XMLNode::LastNeighbor: {
\r
291 CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
\r
292 while (pItem->m_pParent != NULL) {
\r
293 pItem = pItem->m_pParent;
\r
296 while (pItem->m_pNext != NULL) {
\r
297 pItem = pItem->m_pNext;
\r
299 if (pItem->m_pChild == NULL) {
\r
302 pItem = pItem->m_pChild;
\r
304 return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
\r
306 case IFDE_XMLNode::FirstChild:
\r
308 case IFDE_XMLNode::LastChild: {
\r
309 if (m_pChild == NULL) {
\r
312 CFDE_XMLNode *pChild = m_pChild;
\r
313 while (pChild->m_pNext != NULL) {
\r
314 pChild = pChild->m_pNext;
\r
323 FX_INT32 CFDE_XMLNode::GetNodeLevel() const
\r
325 FX_INT32 iLevel = 0;
\r
326 CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
\r
327 while ((pItem = pItem->m_pParent) != NULL) {
\r
332 FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, CFDE_XMLNode *pNode)
\r
334 FXSYS_assert(pNode != NULL);
\r
336 case IFDE_XMLNode::NextSibling: {
\r
337 pNode->m_pParent = m_pParent;
\r
338 pNode->m_pNext = m_pNext;
\r
339 pNode->m_pPrior = this;
\r
341 m_pNext->m_pPrior = pNode;
\r
346 case IFDE_XMLNode::PriorSibling: {
\r
347 pNode->m_pParent = m_pParent;
\r
348 pNode->m_pNext = this;
\r
349 pNode->m_pPrior = m_pPrior;
\r
351 m_pPrior->m_pNext = pNode;
\r
352 } else if (m_pParent) {
\r
353 m_pParent->m_pChild = pNode;
\r
363 CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem)
\r
365 CFDE_XMLNode* pNode = NULL;
\r
367 case IFDE_XMLNode::NextSibling:
\r
370 m_pNext = pNode->m_pNext;
\r
372 m_pNext->m_pPrior = this;
\r
374 pNode->m_pParent = NULL;
\r
375 pNode->m_pNext = NULL;
\r
376 pNode->m_pPrior = NULL;
\r
384 CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive)
\r
388 void CFDE_XMLNode::SaveXMLNode(IFX_Stream *pXMLStream)
\r
390 CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
\r
391 FXSYS_assert(pXMLStream != NULL && pNode != NULL);
\r
392 switch (pNode->GetType()) {
\r
393 case FDE_XMLNODE_Instruction: {
\r
395 CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
\r
396 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
\r
397 ws = L"<?xml version=\"1.0\" encoding=\"";
\r
398 FX_WORD wCodePage = pXMLStream->GetCodePage();
\r
399 if (wCodePage == FX_CODEPAGE_UTF16LE) {
\r
401 } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
\r
407 pXMLStream->WriteString(ws, ws.GetLength());
\r
409 ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
\r
410 pXMLStream->WriteString(ws, ws.GetLength());
\r
411 CFX_WideStringArray &attributes = pInstruction->m_Attributes;
\r
412 FX_INT32 i, iCount = attributes.GetSize();
\r
413 CFX_WideString wsValue;
\r
414 for (i = 0; i < iCount; i += 2) {
\r
416 ws += attributes[i];
\r
418 wsValue = attributes[i + 1];
\r
419 wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
420 wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
421 wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
422 wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
423 wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
426 pXMLStream->WriteString(ws, ws.GetLength());
\r
428 CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
\r
429 iCount = targetdata.GetSize();
\r
430 for (i = 0; i < iCount; i++) {
\r
432 ws += targetdata[i];
\r
434 pXMLStream->WriteString(ws, ws.GetLength());
\r
437 pXMLStream->WriteString(ws, ws.GetLength());
\r
441 case FDE_XMLNODE_Element: {
\r
444 ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
\r
445 pXMLStream->WriteString(ws, ws.GetLength());
\r
446 CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
\r
447 FX_INT32 iCount = attributes.GetSize();
\r
448 CFX_WideString wsValue;
\r
449 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
451 ws += attributes[i];
\r
453 wsValue = attributes[i + 1];
\r
454 wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
455 wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
456 wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
457 wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
458 wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
461 pXMLStream->WriteString(ws, ws.GetLength());
\r
463 if (pNode->m_pChild == NULL) {
\r
465 pXMLStream->WriteString(ws, ws.GetLength());
\r
468 pXMLStream->WriteString(ws, ws.GetLength());
\r
469 CFDE_XMLNode *pChild = pNode->m_pChild;
\r
470 while (pChild != NULL) {
\r
471 pChild->SaveXMLNode(pXMLStream);
\r
472 pChild = pChild->m_pNext;
\r
475 ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
\r
477 pXMLStream->WriteString(ws, ws.GetLength());
\r
481 case FDE_XMLNODE_Text: {
\r
482 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
\r
483 ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
484 ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
485 ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
486 ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
487 ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
488 pXMLStream->WriteString(ws, ws.GetLength());
\r
491 case FDE_XMLNODE_CharData: {
\r
492 CFX_WideString ws = L"<![CDATA[";
\r
493 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
\r
495 pXMLStream->WriteString(ws, ws.GetLength());
\r
498 case FDE_XMLNODE_Unknown:
\r
504 void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone)
\r
509 CFDE_XMLNode* pNext = m_pChild;
\r
510 CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE);
\r
511 pClone->InsertChildNode(pCloneNext);
\r
512 pNext = pNext->m_pNext;
\r
514 CFDE_XMLNode* pChild = pNext->Clone(TRUE);
\r
515 pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild);
\r
516 pCloneNext = pChild;
\r
517 pNext = pNext->m_pNext;
\r
520 IFDE_XMLInstruction* IFDE_XMLInstruction::Create(const CFX_WideString &wsTarget)
\r
522 return (IFDE_XMLInstruction*)FDE_New CFDE_XMLInstruction(wsTarget);
\r
524 CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString &wsTarget)
\r
526 , m_wsTarget(wsTarget)
\r
530 FXSYS_assert(m_wsTarget.GetLength() > 0);
\r
532 CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive)
\r
534 CFDE_XMLInstruction* pClone = FDE_New CFDE_XMLInstruction(m_wsTarget);
\r
538 pClone->m_Attributes.Copy(m_Attributes);
\r
539 pClone->m_TargetData.Copy(m_TargetData);
\r
541 CloneChildren(pClone);
\r
545 FX_INT32 CFDE_XMLInstruction::CountAttributes() const
\r
547 return m_Attributes.GetSize() / 2;
\r
549 FX_BOOL CFDE_XMLInstruction::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
\r
551 FX_INT32 iCount = m_Attributes.GetSize();
\r
552 FXSYS_assert(index > -1 && index < iCount / 2);
\r
553 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
555 wsAttriName = m_Attributes[i];
\r
556 wsAttriValue = m_Attributes[i + 1];
\r
563 FX_BOOL CFDE_XMLInstruction::HasAttribute(FX_LPCWSTR pwsAttriName) const
\r
565 FX_INT32 iCount = m_Attributes.GetSize();
\r
566 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
567 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
573 void CFDE_XMLInstruction::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
\r
575 FX_INT32 iCount = m_Attributes.GetSize();
\r
576 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
577 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
578 wsAttriValue = m_Attributes[i + 1];
\r
582 wsAttriValue = pwsDefValue;
\r
584 void CFDE_XMLInstruction::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
\r
586 FXSYS_assert(wsAttriName.GetLength() > 0);
\r
587 FX_INT32 iCount = m_Attributes.GetSize();
\r
588 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
589 if (m_Attributes[i].Compare(wsAttriName) == 0) {
\r
590 m_Attributes[i] = wsAttriName;
\r
591 m_Attributes[i + 1] = wsAttriValue;
\r
595 m_Attributes.Add(wsAttriName);
\r
596 m_Attributes.Add(wsAttriValue);
\r
598 FX_INT32 CFDE_XMLInstruction::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
\r
600 FX_INT32 iCount = m_Attributes.GetSize();
\r
601 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
602 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
603 return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
\r
608 void CFDE_XMLInstruction::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
\r
610 CFX_WideString wsValue;
\r
611 wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
\r
612 SetString(pwsAttriName, wsValue);
\r
614 FX_FLOAT CFDE_XMLInstruction::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
\r
616 FX_INT32 iCount = m_Attributes.GetSize();
\r
617 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
618 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
619 return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
\r
624 void CFDE_XMLInstruction::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
\r
626 CFX_WideString wsValue;
\r
627 wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
\r
628 SetString(pwsAttriName, wsValue);
\r
630 void CFDE_XMLInstruction::RemoveAttribute(FX_LPCWSTR pwsAttriName)
\r
632 FX_INT32 iCount = m_Attributes.GetSize();
\r
633 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
634 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
635 m_Attributes.RemoveAt(i + 1);
\r
636 m_Attributes.RemoveAt(i);
\r
641 FX_INT32 CFDE_XMLInstruction::CountData() const
\r
643 return m_TargetData.GetSize();
\r
645 FX_BOOL CFDE_XMLInstruction::GetData(FX_INT32 index, CFX_WideString &wsData) const
\r
647 if (index < 0 || index >= m_TargetData.GetSize()) {
\r
650 wsData = m_TargetData[index];
\r
653 void CFDE_XMLInstruction::AppendData(const CFX_WideString &wsData)
\r
655 m_TargetData.Add(wsData);
\r
657 void CFDE_XMLInstruction::RemoveData(FX_INT32 index)
\r
659 m_TargetData.RemoveAt(index);
\r
661 IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString &wsTag)
\r
663 return (IFDE_XMLElement*)FDE_New CFDE_XMLElement(wsTag);
\r
665 CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString &wsTag)
\r
670 FXSYS_assert(m_wsTag.GetLength() > 0);
\r
672 CFDE_XMLElement::~CFDE_XMLElement()
\r
674 m_Attributes.RemoveAll();
\r
676 CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive)
\r
678 CFDE_XMLElement* pClone = FDE_New CFDE_XMLElement(m_wsTag);
\r
682 pClone->m_Attributes.Copy(m_Attributes);
\r
684 CloneChildren(pClone);
\r
686 CFX_WideString wsText;
\r
687 CFDE_XMLNode *pChild = m_pChild;
\r
688 while (pChild != NULL) {
\r
689 switch (pChild->GetType()) {
\r
690 case FDE_XMLNODE_Text:
\r
691 wsText += ((CFDE_XMLText*)pChild)->m_wsText;
\r
696 pChild = pChild->m_pNext;
\r
698 pClone->SetTextData(wsText);
\r
702 void CFDE_XMLElement::GetTagName(CFX_WideString &wsTag) const
\r
706 void CFDE_XMLElement::GetLocalTagName(CFX_WideString &wsTag) const
\r
708 FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
\r
712 wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1);
\r
715 void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString &wsPrefix) const
\r
717 FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
\r
721 wsPrefix = m_wsTag.Left(iFind);
\r
724 void CFDE_XMLElement::GetNamespaceURI(CFX_WideString &wsNamespace) const
\r
726 CFX_WideString wsAttri(L"xmlns"), wsPrefix;
\r
727 GetNamespacePrefix(wsPrefix);
\r
728 if (wsPrefix.GetLength() > 0) {
\r
730 wsAttri += wsPrefix;
\r
732 wsNamespace.Empty();
\r
733 CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
\r
734 while (pNode != NULL) {
\r
735 if (pNode->GetType() != FDE_XMLNODE_Element) {
\r
738 CFDE_XMLElement *pElement = (CFDE_XMLElement*)pNode;
\r
739 if (!pElement->HasAttribute(wsAttri)) {
\r
740 pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent);
\r
743 pElement->GetString(wsAttri, wsNamespace);
\r
747 FX_INT32 CFDE_XMLElement::CountAttributes() const
\r
749 return m_Attributes.GetSize() / 2;
\r
751 FX_BOOL CFDE_XMLElement::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
\r
753 FX_INT32 iCount = m_Attributes.GetSize();
\r
754 FXSYS_assert(index > -1 && index < iCount / 2);
\r
755 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
757 wsAttriName = m_Attributes[i];
\r
758 wsAttriValue = m_Attributes[i + 1];
\r
765 FX_BOOL CFDE_XMLElement::HasAttribute(FX_LPCWSTR pwsAttriName) const
\r
767 FX_INT32 iCount = m_Attributes.GetSize();
\r
768 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
769 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
775 void CFDE_XMLElement::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
\r
777 FX_INT32 iCount = m_Attributes.GetSize();
\r
778 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
779 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
780 wsAttriValue = m_Attributes[i + 1];
\r
784 wsAttriValue = pwsDefValue;
\r
786 void CFDE_XMLElement::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
\r
788 FXSYS_assert(wsAttriName.GetLength() > 0);
\r
789 FX_INT32 iCount = m_Attributes.GetSize();
\r
790 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
791 if (m_Attributes[i].Compare(wsAttriName) == 0) {
\r
792 m_Attributes[i] = wsAttriName;
\r
793 m_Attributes[i + 1] = wsAttriValue;
\r
797 m_Attributes.Add(wsAttriName);
\r
798 m_Attributes.Add(wsAttriValue);
\r
800 FX_INT32 CFDE_XMLElement::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
\r
802 FX_INT32 iCount = m_Attributes.GetSize();
\r
803 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
804 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
805 return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
\r
810 void CFDE_XMLElement::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
\r
812 CFX_WideString wsValue;
\r
813 wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
\r
814 SetString(pwsAttriName, wsValue);
\r
816 FX_FLOAT CFDE_XMLElement::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
\r
818 FX_INT32 iCount = m_Attributes.GetSize();
\r
819 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
820 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
821 return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
\r
826 void CFDE_XMLElement::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
\r
828 CFX_WideString wsValue;
\r
829 wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
\r
830 SetString(pwsAttriName, wsValue);
\r
832 void CFDE_XMLElement::RemoveAttribute(FX_LPCWSTR pwsAttriName)
\r
834 FX_INT32 iCount = m_Attributes.GetSize();
\r
835 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
836 if (m_Attributes[i].Compare(pwsAttriName) == 0) {
\r
837 m_Attributes.RemoveAt(i + 1);
\r
838 m_Attributes.RemoveAt(i);
\r
843 void CFDE_XMLElement::GetTextData(CFX_WideString &wsText) const
\r
845 CFX_WideTextBuf buffer;
\r
846 CFDE_XMLNode *pChild = m_pChild;
\r
847 while (pChild != NULL) {
\r
848 switch (pChild->GetType()) {
\r
849 case FDE_XMLNODE_Text:
\r
850 buffer << ((CFDE_XMLText*)pChild)->m_wsText;
\r
852 case FDE_XMLNODE_CharData:
\r
853 buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData;
\r
858 pChild = pChild->m_pNext;
\r
860 wsText = buffer.GetWideString();
\r
862 void CFDE_XMLElement::SetTextData(const CFX_WideString &wsText)
\r
864 if (wsText.GetLength() < 1) {
\r
867 InsertChildNode(FDE_New CFDE_XMLText(wsText));
\r
869 IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString &wsText)
\r
871 return (IFDE_XMLText*)FDE_New CFDE_XMLText(wsText);
\r
873 CFDE_XMLText::CFDE_XMLText(const CFX_WideString &wsText)
\r
878 CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive)
\r
880 CFDE_XMLText* pClone = FDE_New CFDE_XMLText(m_wsText);
\r
883 IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString &wsCData)
\r
885 return (IFDE_XMLCharData*)FDE_New CFDE_XMLCharData(wsCData);
\r
887 CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString &wsCData)
\r
888 : CFDE_XMLDeclaration()
\r
889 , m_wsCharData(wsCData)
\r
892 CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive)
\r
894 CFDE_XMLCharData* pClone = FDE_New CFDE_XMLCharData(m_wsCharData);
\r
897 IFDE_XMLDoc* IFDE_XMLDoc::Create()
\r
899 return (IFDE_XMLDoc*)FDE_New CFDE_XMLDoc;
\r
901 CFDE_XMLDoc::CFDE_XMLDoc()
\r
903 , m_pSyntaxParser(NULL)
\r
904 , m_pXMLParser(NULL)
\r
907 CFDE_XMLInstruction *pXML = FDE_New CFDE_XMLInstruction((FX_LPCWSTR)L"xml");
\r
908 m_pRoot->InsertChildNode(pXML);
\r
910 CFDE_XMLDoc::~CFDE_XMLDoc()
\r
914 void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot)
\r
919 if (m_pRoot == NULL) {
\r
920 m_pRoot = FDE_New CFDE_XMLNode;
\r
922 m_pRoot->DeleteChildren();
\r
925 if (m_pRoot != NULL) {
\r
926 m_pRoot->Release();
\r
932 void CFDE_XMLDoc::ReleaseParser()
\r
934 if (m_pXMLParser != NULL) {
\r
935 m_pXMLParser->Release();
\r
936 m_pXMLParser = NULL;
\r
938 if (m_pSyntaxParser != NULL) {
\r
939 m_pSyntaxParser->Release();
\r
940 m_pSyntaxParser = NULL;
\r
943 FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize , FX_INT32 iTextDataSize , FDE_LPXMLREADERHANDLER pHandler )
\r
945 if (pXMLStream == NULL) {
\r
949 iXMLPlaneSize = iXMLPlaneSize / 1024;
\r
950 if (iXMLPlaneSize < 1) {
\r
953 iXMLPlaneSize *= 1024;
\r
954 if (iXMLPlaneSize < 4096) {
\r
955 iXMLPlaneSize = 4096;
\r
957 iTextDataSize = iTextDataSize / 128;
\r
958 if (iTextDataSize < 1) {
\r
961 iTextDataSize *= 128;
\r
962 if (iTextDataSize < 128) {
\r
963 iTextDataSize = 128;
\r
965 m_pStream = pXMLStream;
\r
966 FX_WORD wCodePage = m_pStream->GetCodePage();
\r
967 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
\r
968 m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
\r
970 m_pSyntaxParser = IFDE_XMLSyntaxParser::Create();
\r
971 if (m_pSyntaxParser == NULL) {
\r
974 m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize);
\r
975 if (pHandler == NULL) {
\r
976 m_pXMLParser = FDE_New CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser);
\r
978 m_pXMLParser = FDE_New CFDE_XMLSAXParser(pHandler, m_pSyntaxParser);
\r
980 return m_pXMLParser != NULL;
\r
982 FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser *pXMLParser)
\r
984 if (pXMLParser == NULL) {
\r
988 m_pXMLParser = pXMLParser;
\r
989 return m_pXMLParser != NULL;
\r
991 FX_INT32 CFDE_XMLDoc::DoLoad(IFX_Pause *pPause)
\r
993 if (m_iStatus >= 100) {
\r
996 FXSYS_assert(m_pXMLParser != NULL);
\r
997 return m_iStatus = m_pXMLParser->DoParser(pPause);
\r
999 void CFDE_XMLDoc::CloseXML()
\r
1003 void CFDE_XMLDoc::SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pINode)
\r
1005 CFDE_XMLNode *pNode = (CFDE_XMLNode*)pINode;
\r
1006 FXSYS_assert(pXMLStream != NULL && pNode != NULL);
\r
1007 switch (pNode->GetType()) {
\r
1008 case FDE_XMLNODE_Instruction: {
\r
1009 CFX_WideString ws;
\r
1010 CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
\r
1011 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
\r
1012 ws = L"<?xml version=\"1.0\" encoding=\"";
\r
1013 FX_WORD wCodePage = pXMLStream->GetCodePage();
\r
1014 if (wCodePage == FX_CODEPAGE_UTF16LE) {
\r
1016 } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
\r
1017 ws += L"UTF-16be";
\r
1022 pXMLStream->WriteString(ws, ws.GetLength());
\r
1024 ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
\r
1025 pXMLStream->WriteString(ws, ws.GetLength());
\r
1026 CFX_WideStringArray &attributes = pInstruction->m_Attributes;
\r
1027 FX_INT32 i, iCount = attributes.GetSize();
\r
1028 CFX_WideString wsValue;
\r
1029 for (i = 0; i < iCount; i += 2) {
\r
1031 ws += attributes[i];
\r
1033 wsValue = attributes[i + 1];
\r
1034 wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
1035 wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
1036 wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
1037 wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
1038 wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
1041 pXMLStream->WriteString(ws, ws.GetLength());
\r
1043 CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
\r
1044 iCount = targetdata.GetSize();
\r
1045 for (i = 0; i < iCount; i++) {
\r
1047 ws += targetdata[i];
\r
1049 pXMLStream->WriteString(ws, ws.GetLength());
\r
1052 pXMLStream->WriteString(ws, ws.GetLength());
\r
1056 case FDE_XMLNODE_Element: {
\r
1057 CFX_WideString ws;
\r
1059 ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
\r
1060 pXMLStream->WriteString(ws, ws.GetLength());
\r
1061 CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
\r
1062 FX_INT32 iCount = attributes.GetSize();
\r
1063 CFX_WideString wsValue;
\r
1064 for (FX_INT32 i = 0; i < iCount; i += 2) {
\r
1066 ws += attributes[i];
\r
1068 wsValue = attributes[i + 1];
\r
1069 wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
1070 wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
1071 wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
1072 wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
1073 wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
1076 pXMLStream->WriteString(ws, ws.GetLength());
\r
1078 if (pNode->m_pChild == NULL) {
\r
1080 pXMLStream->WriteString(ws, ws.GetLength());
\r
1083 pXMLStream->WriteString(ws, ws.GetLength());
\r
1084 CFDE_XMLNode *pChild = pNode->m_pChild;
\r
1085 while (pChild != NULL) {
\r
1086 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild);
\r
1087 pChild = pChild->m_pNext;
\r
1090 ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
\r
1092 pXMLStream->WriteString(ws, ws.GetLength());
\r
1096 case FDE_XMLNODE_Text: {
\r
1097 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
\r
1098 ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&");
\r
1099 ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"<");
\r
1100 ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L">");
\r
1101 ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"'");
\r
1102 ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L""");
\r
1103 pXMLStream->WriteString(ws, ws.GetLength());
\r
1106 case FDE_XMLNODE_CharData: {
\r
1107 CFX_WideString ws = L"<![CDATA[";
\r
1108 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
\r
1110 pXMLStream->WriteString(ws, ws.GetLength());
\r
1113 case FDE_XMLNODE_Unknown:
\r
1119 void CFDE_XMLDoc::SaveXML(IFX_Stream *pXMLStream, FX_BOOL bSaveBOM)
\r
1121 if (pXMLStream == NULL || pXMLStream == m_pStream) {
\r
1122 m_pStream->Seek(FX_STREAMSEEK_Begin, 0);
\r
1123 pXMLStream = m_pStream;
\r
1125 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0);
\r
1126 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0);
\r
1127 FX_WORD wCodePage = pXMLStream->GetCodePage();
\r
1128 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
\r
1129 wCodePage = FX_CODEPAGE_UTF8;
\r
1130 pXMLStream->SetCodePage(wCodePage);
\r
1133 pXMLStream->WriteString((FX_LPCWSTR)L"\xFEFF", 1);
\r
1135 CFDE_XMLNode *pNode = m_pRoot->m_pChild;
\r
1136 while (pNode != NULL) {
\r
1137 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode);
\r
1138 pNode = pNode->m_pNext;
\r
1140 if (pXMLStream == m_pStream) {
\r
1141 FX_INT32 iPos = pXMLStream->GetPosition();
\r
1142 pXMLStream->SetLength(iPos);
\r
1145 CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode *pRoot, IFDE_XMLSyntaxParser *pParser)
\r
1147 , m_pParser(pParser)
\r
1148 , m_pParent(pRoot)
\r
1154 m_NodeStack.Push(m_pParent);
\r
1156 CFDE_XMLDOMParser::~CFDE_XMLDOMParser()
\r
1158 m_NodeStack.RemoveAll();
\r
1162 FX_INT32 CFDE_XMLDOMParser::DoParser(IFX_Pause *pPause)
\r
1165 FX_INT32 iCount = 0;
\r
1167 dwRet = m_pParser->DoSyntaxParse();
\r
1169 case FDE_XMLSYNTAXSTATUS_InstructionOpen:
\r
1171 case FDE_XMLSYNTAXSTATUS_InstructionClose:
\r
1172 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
\r
1173 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1176 m_pChild = m_pParent;
\r
1178 case FDE_XMLSYNTAXSTATUS_ElementOpen:
\r
1179 case FDE_XMLSYNTAXSTATUS_ElementBreak:
\r
1181 case FDE_XMLSYNTAXSTATUS_ElementClose:
\r
1182 if (m_pChild->GetType() != FDE_XMLNODE_Element) {
\r
1183 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1186 m_pParser->GetTagName(m_ws1);
\r
1187 ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2);
\r
1188 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) {
\r
1189 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1192 m_NodeStack.Pop();
\r
1193 if (m_NodeStack.GetSize() < 1) {
\r
1194 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1197 m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement();
\r
1198 m_pChild = m_pParent;
\r
1201 case FDE_XMLSYNTAXSTATUS_TargetName:
\r
1202 m_pParser->GetTargetName(m_ws1);
\r
1203 m_pChild = FDE_New CFDE_XMLInstruction(m_ws1);
\r
1204 m_pParent->InsertChildNode(m_pChild);
\r
1207 case FDE_XMLSYNTAXSTATUS_TagName:
\r
1208 m_pParser->GetTagName(m_ws1);
\r
1209 m_pChild = FDE_New CFDE_XMLElement(m_ws1);
\r
1210 m_pParent->InsertChildNode(m_pChild);
\r
1211 m_NodeStack.Push(m_pChild);
\r
1212 m_pParent = m_pChild;
\r
1214 case FDE_XMLSYNTAXSTATUS_AttriName:
\r
1215 m_pParser->GetAttributeName(m_ws1);
\r
1217 case FDE_XMLSYNTAXSTATUS_AttriValue:
\r
1218 if (m_pChild == NULL) {
\r
1219 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1222 m_pParser->GetAttributeName(m_ws2);
\r
1223 if (m_pChild->GetType() == FDE_XMLNODE_Element) {
\r
1224 ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2);
\r
1225 } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) {
\r
1226 ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2);
\r
1230 case FDE_XMLSYNTAXSTATUS_Text:
\r
1231 m_pParser->GetTextData(m_ws1);
\r
1232 m_pChild = FDE_New CFDE_XMLText(m_ws1);
\r
1233 m_pParent->InsertChildNode(m_pChild);
\r
1234 m_pChild = m_pParent;
\r
1236 case FDE_XMLSYNTAXSTATUS_CData:
\r
1237 m_pParser->GetTextData(m_ws1);
\r
1238 m_pChild = FDE_New CFDE_XMLCharData(m_ws1);
\r
1239 m_pParent->InsertChildNode(m_pChild);
\r
1240 m_pChild = m_pParent;
\r
1242 case FDE_XMLSYNTAXSTATUS_TargetData:
\r
1243 if (m_pChild == NULL || m_pChild->GetType() != FDE_XMLNODE_Instruction) {
\r
1244 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1247 if (!m_ws1.IsEmpty()) {
\r
1248 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
\r
1250 m_pParser->GetTargetData(m_ws1);
\r
1251 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
\r
1257 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
\r
1260 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
\r
1264 return m_pParser->GetStatus();
\r
1266 CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, IFDE_XMLSyntaxParser *pParser)
\r
1267 : m_pHandler(pHandler)
\r
1268 , m_pParser(pParser)
\r
1275 CFDE_XMLSAXParser::~CFDE_XMLSAXParser()
\r
1277 m_TagStack.RemoveAll();
\r
1281 FX_INT32 CFDE_XMLSAXParser::DoParser(IFX_Pause *pPause)
\r
1283 FX_DWORD dwRet = 0;
\r
1284 FX_INT32 iCount = 0;
\r
1286 dwRet = m_pParser->DoSyntaxParse();
\r
1288 case FDE_XMLSYNTAXSTATUS_ElementBreak:
\r
1289 if (m_pTagTop == NULL) {
\r
1290 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1293 if (m_pTagTop->eType == FDE_XMLNODE_Element) {
\r
1294 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
\r
1297 case FDE_XMLSYNTAXSTATUS_ElementClose:
\r
1298 if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) {
\r
1299 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1302 m_pParser->GetTagName(m_ws1);
\r
1303 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) {
\r
1304 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1306 } else if (m_ws1.GetLength() == 0) {
\r
1307 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
\r
1309 m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName);
\r
1313 case FDE_XMLSYNTAXSTATUS_TargetName: {
\r
1314 m_pParser->GetTargetName(m_ws1);
\r
1315 CFDE_XMLTAG xmlTag;
\r
1316 xmlTag.wsTagName = m_ws1;
\r
1317 xmlTag.eType = FDE_XMLNODE_Instruction;
\r
1319 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, m_pTagTop->wsTagName);
\r
1323 case FDE_XMLSYNTAXSTATUS_TagName: {
\r
1324 m_pParser->GetTargetName(m_ws1);
\r
1325 CFDE_XMLTAG xmlTag;
\r
1326 xmlTag.wsTagName = m_ws1;
\r
1327 xmlTag.eType = FDE_XMLNODE_Element;
\r
1329 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, m_pTagTop->wsTagName);
\r
1332 case FDE_XMLSYNTAXSTATUS_AttriName:
\r
1333 m_pParser->GetTargetName(m_ws1);
\r
1335 case FDE_XMLSYNTAXSTATUS_AttriValue:
\r
1336 m_pParser->GetAttributeName(m_ws2);
\r
1337 if (m_pTagTop == NULL) {
\r
1338 dwRet = FDE_XMLSYNTAXSTATUS_Error;
\r
1341 if (m_pTagTop->eType == FDE_XMLNODE_Element) {
\r
1342 m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2);
\r
1346 case FDE_XMLSYNTAXSTATUS_CData:
\r
1347 m_pParser->GetTextData(m_ws1);
\r
1348 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1);
\r
1350 case FDE_XMLSYNTAXSTATUS_Text:
\r
1351 m_pParser->GetTextData(m_ws1);
\r
1352 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1);
\r
1354 case FDE_XMLSYNTAXSTATUS_TargetData:
\r
1355 m_pParser->GetTargetData(m_ws1);
\r
1356 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1);
\r
1362 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
\r
1365 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
\r
1369 return m_pParser->GetStatus();
\r
1371 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG &xmlTag)
\r
1373 m_TagStack.Push(xmlTag);
\r
1374 m_pTagTop = m_TagStack.GetTopElement();
\r
1376 inline void CFDE_XMLSAXParser::Pop()
\r
1379 m_pTagTop = m_TagStack.GetTopElement();
\r
1381 #ifdef _FDE_BLOCK_BUFFER
\r
1382 CFDE_BlockBuffer::CFDE_BlockBuffer(FX_INT32 iAllocStep)
\r
1383 : m_iAllocStep(iAllocStep),
\r
1384 m_iStartPosition(0),
\r
1389 CFDE_BlockBuffer::~CFDE_BlockBuffer()
\r
1393 FX_LPWSTR CFDE_BlockBuffer::GetAvailableBlock(FX_INT32& iIndexInBlock)
\r
1395 iIndexInBlock = 0;
\r
1396 FX_INT32 iBlockNum = m_BlockArray.GetSize();
\r
1397 if (iBlockNum == 0) {
\r
1400 FX_INT32 iRealIndex = m_iStartPosition + m_iDataLength;
\r
1401 FX_LPWSTR pDataBlock = NULL;
\r
1402 if(iRealIndex == m_iBufferSize) {
\r
1403 FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
\r
1405 m_BlockArray.Add(pBlock);
\r
1406 m_iBufferSize += m_iAllocStep;
\r
1408 iIndexInBlock = 0;
\r
1409 pDataBlock = pBlock;
\r
1411 FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
\r
1412 FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
\r
1413 iIndexInBlock = iInnerIndex;
\r
1414 pDataBlock = (FX_LPWSTR)m_BlockArray[iBlockIndex];
\r
1416 return pDataBlock;
\r
1418 FX_BOOL CFDE_BlockBuffer::InitBuffer(FX_INT32 iBufferSize)
\r
1421 FX_INT32 iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1;
\r
1422 for (FX_INT32 i = 0; i < iNumOfBlock; i++) {
\r
1423 FX_LPWSTR pBlockBuffer = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
\r
1424 if (pBlockBuffer == NULL) {
\r
1428 m_BlockArray.Add(pBlockBuffer);
\r
1430 m_iBufferSize = iNumOfBlock * m_iAllocStep;
\r
1433 void CFDE_BlockBuffer::SetTextChar(FX_INT32 iIndex, FX_WCHAR ch)
\r
1438 FX_INT32 iRealIndex = m_iStartPosition + iIndex;
\r
1439 FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
\r
1440 FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
\r
1441 FX_INT32 iBlockSize = m_BlockArray.GetSize();
\r
1442 if (iBlockIndex >= iBlockSize) {
\r
1443 FX_INT32 iNewBlocks = iBlockIndex - iBlockSize + 1;
\r
1445 FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
\r
1449 m_BlockArray.Add(pBlock);
\r
1450 m_iBufferSize += m_iAllocStep;
\r
1451 } while (--iNewBlocks);
\r
1453 FX_LPWSTR pTextData = (FX_LPWSTR)m_BlockArray[iBlockIndex];
\r
1454 *(pTextData + iInnerIndex) = ch;
\r
1455 if (m_iDataLength <= iIndex) {
\r
1456 m_iDataLength = iIndex + 1;
\r
1459 FX_INT32 CFDE_BlockBuffer::DeleteTextChars(FX_INT32 iCount, FX_BOOL bDirection )
\r
1461 if (iCount <= 0) {
\r
1462 return m_iDataLength;
\r
1464 if (iCount >= m_iDataLength) {
\r
1469 m_iStartPosition += iCount;
\r
1470 m_iDataLength -= iCount;
\r
1472 m_iDataLength -= iCount;
\r
1474 return m_iDataLength;
\r
1476 void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, FX_INT32 iStart, FX_INT32 iLength) const
\r
1478 wsTextData.Empty();
\r
1479 FX_INT32 iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition;
\r
1480 if (iStart < 0 || iStart > iMaybeDataLength) {
\r
1483 if (iLength == -1 || iLength > iMaybeDataLength) {
\r
1484 iLength = iMaybeDataLength;
\r
1486 if (iLength <= 0) {
\r
1489 FX_LPWSTR pBuf = wsTextData.GetBuffer(iLength);
\r
1493 FX_INT32 iStartBlockIndex = 0;
\r
1494 FX_INT32 iStartInnerIndex = 0;
\r
1495 TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex);
\r
1496 FX_INT32 iEndBlockIndex = 0;
\r
1497 FX_INT32 iEndInnerIndex = 0;
\r
1498 TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex);
\r
1499 FX_INT32 iPointer = 0;
\r
1500 for (FX_INT32 i = iStartBlockIndex; i <= iEndBlockIndex; i++) {
\r
1501 FX_INT32 iBufferPointer = 0;
\r
1502 FX_INT32 iCopyLength = m_iAllocStep;
\r
1503 if (i == iStartBlockIndex) {
\r
1504 iCopyLength -= iStartInnerIndex;
\r
1505 iBufferPointer = iStartInnerIndex;
\r
1507 if (i == iEndBlockIndex) {
\r
1508 iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex);
\r
1510 FX_LPWSTR pBlockBuf = (FX_LPWSTR)m_BlockArray[i];
\r
1511 FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, iCopyLength * sizeof(FX_WCHAR));
\r
1512 iPointer += iCopyLength;
\r
1514 wsTextData.ReleaseBuffer(iLength);
\r
1516 void CFDE_BlockBuffer::TextDataIndex2BufIndex(const FX_INT32 iIndex, FX_INT32& iBlockIndex, FX_INT32& iInnerIndex) const
\r
1518 FXSYS_assert(iIndex >= 0);
\r
1519 FX_INT32 iRealIndex = m_iStartPosition + iIndex;
\r
1520 iBlockIndex = iRealIndex / m_iAllocStep;
\r
1521 iInnerIndex = iRealIndex % m_iAllocStep;
\r
1523 void CFDE_BlockBuffer::ClearBuffer()
\r
1525 m_iBufferSize = 0;
\r
1526 FX_INT32 iSize = m_BlockArray.GetSize();
\r
1527 for (FX_INT32 i = 0; i < iSize; i++) {
\r
1528 FDE_Free(m_BlockArray[i]);
\r
1529 m_BlockArray[i] = NULL;
\r
1531 m_BlockArray.RemoveAll();
\r
1534 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create()
\r
1536 return FDE_New CFDE_XMLSyntaxParser;
\r
1538 #ifdef _FDE_BLOCK_BUFFER
\r
1539 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
\r
1541 , m_iXMLPlaneSize(-1)
\r
1542 , m_iCurrentPos(0)
\r
1543 , m_iCurrentNodeNum(-1)
\r
1544 , m_iLastNodeNum(-1)
\r
1545 , m_iParsedChars(0)
\r
1546 , m_iParsedBytes(0)
\r
1548 , m_iBufferChars(0)
\r
1552 , m_XMLNodeStack(16)
\r
1553 , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
\r
1554 , m_dwMode(FDE_XMLSYNTAXMODE_Text)
\r
1555 , m_wQuotationMark(0)
\r
1557 , m_pCurrentBlock(NULL)
\r
1558 , m_iIndexInBlock(0)
\r
1559 , m_iDataLength(m_BlockBuffer.GetDataLengthRef())
\r
1560 , m_iAllocStep(m_BlockBuffer.GetAllocStep())
\r
1561 , m_iTextDataLength(0)
\r
1562 , m_iEntityStart(-1)
\r
1565 m_CurNode.iNodeNum = -1;
\r
1566 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
1568 void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
\r
1570 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
\r
1571 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0);
\r
1572 FX_INT32 iStreamLength = pStream->GetLength();
\r
1573 FXSYS_assert(iStreamLength > 0);
\r
1574 m_pStream = pStream;
\r
1575 m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
\r
1577 m_iCurrentPos = m_pStream->GetBOM(bom);
\r
1578 FXSYS_assert(m_pBuffer == NULL);
\r
1579 m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
\r
1580 m_pStart = m_pEnd = m_pBuffer;
\r
1581 FXSYS_assert(!m_BlockBuffer.IsInitialized());
\r
1582 m_BlockBuffer.InitBuffer();
\r
1583 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1584 m_iParsedBytes = m_iParsedChars = 0;
\r
1585 m_iBufferChars = 0;
\r
1587 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
\r
1589 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
\r
1590 return m_dwStatus;
\r
1592 FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_BlockBuffer.IsInitialized());
\r
1593 FX_INT32 iStreamLength = m_pStream->GetLength();
\r
1596 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
\r
1598 if (m_pStart >= m_pEnd) {
\r
1599 if (m_bEOS || m_iCurrentPos >= iStreamLength) {
\r
1600 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
\r
1601 return m_dwStatus;
\r
1603 m_iParsedChars += (m_pEnd - m_pBuffer);
\r
1604 m_iParsedBytes = m_iCurrentPos;
\r
1605 m_pStream->Lock();
\r
1606 if (m_pStream->GetPosition() != m_iCurrentPos) {
\r
1607 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
\r
1609 m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
\r
1610 iPos = m_pStream->GetPosition();
\r
1611 m_pStream->Unlock();
\r
1612 if (m_iBufferChars < 1) {
\r
1613 m_iCurrentPos = iStreamLength;
\r
1614 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
\r
1615 return m_dwStatus;
\r
1617 m_iCurrentPos = iPos;
\r
1618 m_pStart = m_pBuffer;
\r
1619 m_pEnd = m_pBuffer + m_iBufferChars;
\r
1621 while (m_pStart < m_pEnd) {
\r
1623 switch (m_dwMode) {
\r
1624 case FDE_XMLSYNTAXMODE_Text:
\r
1626 if (m_iDataLength > 0) {
\r
1627 m_iTextDataLength = m_iDataLength;
\r
1628 m_BlockBuffer.Reset();
\r
1629 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1630 m_iEntityStart = -1;
\r
1631 dwStatus = FDE_XMLSYNTAXSTATUS_Text;
\r
1634 m_dwMode = FDE_XMLSYNTAXMODE_Node;
\r
1637 ParseTextChar(ch);
\r
1640 case FDE_XMLSYNTAXMODE_Node:
\r
1643 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
\r
1644 } else if (ch == L'/') {
\r
1646 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
\r
1647 } else if (ch == L'?') {
\r
1648 m_iLastNodeNum ++;
\r
1649 m_iCurrentNodeNum = m_iLastNodeNum;
\r
1650 m_CurNode.iNodeNum = m_iLastNodeNum;
\r
1651 m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
\r
1652 m_XMLNodeStack.Push(m_CurNode);
\r
1654 m_dwMode = FDE_XMLSYNTAXMODE_Target;
\r
1655 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
\r
1657 m_iLastNodeNum ++;
\r
1658 m_iCurrentNodeNum = m_iLastNodeNum;
\r
1659 m_CurNode.iNodeNum = m_iLastNodeNum;
\r
1660 m_CurNode.eNodeType = FDE_XMLNODE_Element;
\r
1661 m_XMLNodeStack.Push(m_CurNode);
\r
1662 m_dwMode = FDE_XMLSYNTAXMODE_Tag;
\r
1663 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
\r
1666 case FDE_XMLSYNTAXMODE_Target:
\r
1667 case FDE_XMLSYNTAXMODE_Tag:
\r
1668 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
\r
1669 if (m_iDataLength < 1) {
\r
1670 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1671 return m_dwStatus;
\r
1673 m_iTextDataLength = m_iDataLength;
\r
1674 m_BlockBuffer.Reset();
\r
1675 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1676 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
\r
1677 dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
\r
1679 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
\r
1681 m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
\r
1684 if (m_iIndexInBlock == m_iAllocStep) {
\r
1685 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1686 if (!m_pCurrentBlock) {
\r
1687 return FDE_XMLSYNTAXSTATUS_Error;
\r
1690 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
1695 case FDE_XMLSYNTAXMODE_AttriName:
\r
1696 if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) {
\r
1700 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
\r
1701 if (m_iDataLength < 1) {
\r
1702 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
\r
1703 if (ch == L'>' || ch == L'/') {
\r
1704 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
\r
1707 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
1709 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
\r
1712 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
1716 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1717 return m_dwStatus;
\r
1719 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
1720 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
\r
1721 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
1725 m_iTextDataLength = m_iDataLength;
\r
1726 m_BlockBuffer.Reset();
\r
1727 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1728 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
\r
1729 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
\r
1732 if (m_iIndexInBlock == m_iAllocStep) {
\r
1733 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1734 if (!m_pCurrentBlock) {
\r
1735 return FDE_XMLSYNTAXSTATUS_Error;
\r
1738 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
1743 case FDE_XMLSYNTAXMODE_AttriEqualSign:
\r
1744 if (FDE_IsXMLWhiteSpace(ch)) {
\r
1749 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
1750 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
1753 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1754 return m_dwStatus;
\r
1756 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
\r
1760 case FDE_XMLSYNTAXMODE_AttriQuotation:
\r
1761 if (FDE_IsXMLWhiteSpace(ch)) {
\r
1765 if (ch != L'\"' && ch != L'\'') {
\r
1766 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1767 return m_dwStatus;
\r
1769 m_wQuotationMark = ch;
\r
1770 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
\r
1774 case FDE_XMLSYNTAXMODE_AttriValue:
\r
1775 if (ch == m_wQuotationMark) {
\r
1776 if (m_iEntityStart > -1) {
\r
1777 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1778 return m_dwStatus;
\r
1780 m_iTextDataLength = m_iDataLength;
\r
1781 m_wQuotationMark = 0;
\r
1782 m_BlockBuffer.Reset();
\r
1783 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1785 m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
\r
1786 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
\r
1788 ParseTextChar(ch);
\r
1791 case FDE_XMLSYNTAXMODE_CloseInstruction:
\r
1793 if (m_iIndexInBlock == m_iAllocStep) {
\r
1794 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1795 if (!m_pCurrentBlock) {
\r
1796 return FDE_XMLSYNTAXSTATUS_Error;
\r
1799 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
1801 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
1802 } else if (m_iDataLength > 0) {
\r
1803 m_iTextDataLength = m_iDataLength;
\r
1804 m_BlockBuffer.Reset();
\r
1805 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1806 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
1809 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
\r
1810 if (pXMLNode == NULL) {
\r
1811 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1812 return m_dwStatus;
\r
1814 m_XMLNodeStack.Pop();
\r
1815 pXMLNode = m_XMLNodeStack.GetTopElement();
\r
1816 if (pXMLNode == NULL) {
\r
1817 m_CurNode.iNodeNum = -1;
\r
1818 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
1820 m_CurNode = *pXMLNode;
\r
1822 m_iCurrentNodeNum = m_CurNode.iNodeNum;
\r
1823 m_BlockBuffer.Reset();
\r
1824 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1825 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1826 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
\r
1829 case FDE_XMLSYNTAXMODE_BreakElement:
\r
1831 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1832 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
\r
1833 } else if (ch == L'/') {
\r
1834 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
\r
1836 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1837 return m_dwStatus;
\r
1841 case FDE_XMLSYNTAXMODE_CloseElement:
\r
1842 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
\r
1844 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
\r
1845 if (pXMLNode == NULL) {
\r
1846 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1847 return m_dwStatus;
\r
1849 m_XMLNodeStack.Pop();
\r
1850 pXMLNode = m_XMLNodeStack.GetTopElement();
\r
1851 if (pXMLNode == NULL) {
\r
1852 m_CurNode.iNodeNum = -1;
\r
1853 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
1855 m_CurNode = *pXMLNode;
\r
1857 m_iCurrentNodeNum = m_CurNode.iNodeNum;
\r
1858 m_iTextDataLength = m_iDataLength;
\r
1859 m_BlockBuffer.Reset();
\r
1860 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1861 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1862 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
\r
1863 } else if (!FDE_IsXMLWhiteSpace(ch)) {
\r
1864 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
1865 return m_dwStatus;
\r
1868 if (m_iIndexInBlock == m_iAllocStep) {
\r
1869 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1870 if (!m_pCurrentBlock) {
\r
1871 return FDE_XMLSYNTAXSTATUS_Error;
\r
1874 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
1879 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
\r
1881 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
\r
1883 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
\r
1884 m_SkipChar = L'>';
\r
1885 m_SkipStack.Push(L'>');
\r
1888 case FDE_XMLSYNTAXMODE_SkipDeclNode:
\r
1889 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
\r
1891 if (ch != m_SkipChar) {
\r
1894 m_SkipStack.Pop();
\r
1895 FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
\r
1896 if (pDWord == NULL) {
\r
1897 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1899 m_SkipChar = (FX_WCHAR) * pDWord;
\r
1904 m_SkipChar = L'>';
\r
1905 m_SkipStack.Push(L'>');
\r
1908 m_SkipChar = L']';
\r
1909 m_SkipStack.Push(L']');
\r
1912 m_SkipChar = L')';
\r
1913 m_SkipStack.Push(L')');
\r
1916 m_SkipChar = L'\'';
\r
1917 m_SkipStack.Push(L'\'');
\r
1920 m_SkipChar = L'\"';
\r
1921 m_SkipStack.Push(L'\"');
\r
1924 if (ch == m_SkipChar) {
\r
1925 m_SkipStack.Pop();
\r
1926 FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
\r
1927 if (pDWord == NULL) {
\r
1928 if (m_iDataLength >= 9) {
\r
1929 CFX_WideString wsHeader;
\r
1930 m_BlockBuffer.GetTextData(wsHeader, 0, 7);
\r
1931 if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) {
\r
1932 CFX_WideString wsTailer;
\r
1933 m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, 2);
\r
1934 if (wsTailer.Equal(FX_WSTRC(L"]]"))) {
\r
1935 m_BlockBuffer.DeleteTextChars(7, TRUE);
\r
1936 m_BlockBuffer.DeleteTextChars(2, FALSE);
\r
1937 dwStatus = FDE_XMLSYNTAXSTATUS_CData;
\r
1941 m_iTextDataLength = m_iDataLength;
\r
1942 m_BlockBuffer.Reset();
\r
1943 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1944 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1946 m_SkipChar = (FX_WCHAR) * pDWord;
\r
1951 if (m_SkipStack.GetSize() > 0) {
\r
1952 if (m_iIndexInBlock == m_iAllocStep) {
\r
1953 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1954 if (!m_pCurrentBlock) {
\r
1955 return FDE_XMLSYNTAXSTATUS_Error;
\r
1958 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
1964 case FDE_XMLSYNTAXMODE_SkipComment:
\r
1966 if (m_iIndexInBlock == m_iAllocStep) {
\r
1967 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1968 if (!m_pCurrentBlock) {
\r
1969 return FDE_XMLSYNTAXSTATUS_Error;
\r
1972 m_pCurrentBlock[m_iIndexInBlock++] = L'-';
\r
1974 } else if (ch == L'>') {
\r
1975 if (m_iDataLength > 1) {
\r
1976 m_BlockBuffer.Reset();
\r
1977 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1978 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
1981 m_BlockBuffer.Reset();
\r
1982 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1986 case FDE_XMLSYNTAXMODE_TargetData:
\r
1987 if (FDE_IsXMLWhiteSpace(ch)) {
\r
1988 if (m_iDataLength < 1) {
\r
1991 } else if (m_wQuotationMark == 0) {
\r
1992 m_iTextDataLength = m_iDataLength;
\r
1993 m_wQuotationMark = 0;
\r
1994 m_BlockBuffer.Reset();
\r
1995 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
1997 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
2002 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
\r
2004 } else if (ch == '\"') {
\r
2005 if (m_wQuotationMark == 0) {
\r
2006 m_wQuotationMark = ch;
\r
2008 } else if (ch == m_wQuotationMark) {
\r
2009 m_iTextDataLength = m_iDataLength;
\r
2010 m_wQuotationMark = 0;
\r
2011 m_BlockBuffer.Reset();
\r
2012 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
2014 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
2016 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2017 return m_dwStatus;
\r
2020 if (m_iIndexInBlock == m_iAllocStep) {
\r
2021 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
2022 if (!m_pCurrentBlock) {
\r
2023 return FDE_XMLSYNTAXSTATUS_Error;
\r
2026 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
2034 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
\r
2042 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
\r
2044 , m_iXMLPlaneSize(-1)
\r
2045 , m_iTextDataSize(256)
\r
2046 , m_iCurrentPos(0)
\r
2047 , m_iCurrentNodeNum(-1)
\r
2048 , m_iLastNodeNum(-1)
\r
2049 , m_iParsedChars(0)
\r
2050 , m_iParsedBytes(0)
\r
2052 , m_iBufferChars(0)
\r
2056 , m_XMLNodeStack(16)
\r
2057 , m_pwsTextData(NULL)
\r
2059 , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
\r
2060 , m_dwMode(FDE_XMLSYNTAXMODE_Text)
\r
2061 , m_wQuotationMark(0)
\r
2062 , m_iTextDataLength(0)
\r
2063 , m_iEntityStart(-1)
\r
2066 m_CurNode.iNodeNum = -1;
\r
2067 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
2069 void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
\r
2071 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
\r
2072 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0);
\r
2073 FX_INT32 iStreamLength = pStream->GetLength();
\r
2074 FXSYS_assert(iStreamLength > 0);
\r
2075 m_pStream = pStream;
\r
2076 m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
\r
2077 m_iTextDataSize = iTextDataSize;
\r
2079 m_iCurrentPos = m_pStream->GetBOM(bom);
\r
2080 FXSYS_assert(m_pBuffer == NULL);
\r
2081 m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
\r
2082 m_pStart = m_pEnd = m_pBuffer;
\r
2083 FXSYS_assert(m_pwsTextData == NULL);
\r
2084 m_pwsTextData = (FX_LPWSTR)FDE_Alloc(m_iTextDataSize * sizeof(FX_WCHAR));
\r
2085 m_iParsedBytes = m_iParsedChars = 0;
\r
2086 m_iBufferChars = 0;
\r
2088 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
\r
2090 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
\r
2091 return m_dwStatus;
\r
2093 FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL);
\r
2094 FX_INT32 iStreamLength = m_pStream->GetLength();
\r
2097 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
\r
2099 if (m_pStart >= m_pEnd) {
\r
2100 if (m_bEOS || m_iCurrentPos >= iStreamLength) {
\r
2101 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
\r
2102 return m_dwStatus;
\r
2104 m_iParsedChars += (m_pEnd - m_pBuffer);
\r
2105 m_iParsedBytes = m_iCurrentPos;
\r
2106 m_pStream->Lock();
\r
2107 if (m_pStream->GetPosition() != m_iCurrentPos) {
\r
2108 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
\r
2110 m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
\r
2111 iPos = m_pStream->GetPosition();
\r
2112 m_pStream->Unlock();
\r
2113 if (m_iBufferChars < 1) {
\r
2114 m_iCurrentPos = iStreamLength;
\r
2115 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
\r
2116 return m_dwStatus;
\r
2118 m_iCurrentPos = iPos;
\r
2119 m_pStart = m_pBuffer;
\r
2120 m_pEnd = m_pBuffer + m_iBufferChars;
\r
2122 while (m_pStart < m_pEnd) {
\r
2124 switch (m_dwMode) {
\r
2125 case FDE_XMLSYNTAXMODE_Text:
\r
2127 if (m_iDataPos > 0) {
\r
2128 m_iTextDataLength = m_iDataPos;
\r
2130 m_iEntityStart = -1;
\r
2131 dwStatus = FDE_XMLSYNTAXSTATUS_Text;
\r
2134 m_dwMode = FDE_XMLSYNTAXMODE_Node;
\r
2137 ParseTextChar(ch);
\r
2140 case FDE_XMLSYNTAXMODE_Node:
\r
2143 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
\r
2144 } else if (ch == L'/') {
\r
2146 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
\r
2147 } else if (ch == L'?') {
\r
2148 m_iLastNodeNum ++;
\r
2149 m_iCurrentNodeNum = m_iLastNodeNum;
\r
2150 m_CurNode.iNodeNum = m_iLastNodeNum;
\r
2151 m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
\r
2152 m_XMLNodeStack.Push(m_CurNode);
\r
2154 m_dwMode = FDE_XMLSYNTAXMODE_Target;
\r
2155 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
\r
2157 m_iLastNodeNum ++;
\r
2158 m_iCurrentNodeNum = m_iLastNodeNum;
\r
2159 m_CurNode.iNodeNum = m_iLastNodeNum;
\r
2160 m_CurNode.eNodeType = FDE_XMLNODE_Element;
\r
2161 m_XMLNodeStack.Push(m_CurNode);
\r
2162 m_dwMode = FDE_XMLSYNTAXMODE_Tag;
\r
2163 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
\r
2166 case FDE_XMLSYNTAXMODE_Target:
\r
2167 case FDE_XMLSYNTAXMODE_Tag:
\r
2168 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
\r
2169 if (m_iDataPos < 1) {
\r
2170 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2171 return m_dwStatus;
\r
2173 m_iTextDataLength = m_iDataPos;
\r
2175 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
\r
2176 dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
\r
2178 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
\r
2180 m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
\r
2183 if (m_iDataPos >= m_iTextDataSize) {
\r
2184 ReallocTextDataBuffer();
\r
2186 m_pwsTextData[m_iDataPos ++] = ch;
\r
2190 case FDE_XMLSYNTAXMODE_AttriName:
\r
2191 if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) {
\r
2195 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
\r
2196 if (m_iDataPos < 1) {
\r
2197 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
\r
2198 if (ch == L'>' || ch == L'/') {
\r
2199 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
\r
2202 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
2204 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
\r
2207 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
2211 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2212 return m_dwStatus;
\r
2214 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
2215 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
\r
2216 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
2220 m_iTextDataLength = m_iDataPos;
\r
2222 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
\r
2223 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
\r
2226 if (m_iDataPos >= m_iTextDataSize) {
\r
2227 ReallocTextDataBuffer();
\r
2229 m_pwsTextData[m_iDataPos ++] = ch;
\r
2233 case FDE_XMLSYNTAXMODE_AttriEqualSign:
\r
2234 if (FDE_IsXMLWhiteSpace(ch)) {
\r
2239 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
\r
2240 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
2243 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2244 return m_dwStatus;
\r
2246 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
\r
2250 case FDE_XMLSYNTAXMODE_AttriQuotation:
\r
2251 if (FDE_IsXMLWhiteSpace(ch)) {
\r
2255 if (ch != L'\"' && ch != L'\'') {
\r
2256 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2257 return m_dwStatus;
\r
2259 m_wQuotationMark = ch;
\r
2260 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
\r
2264 case FDE_XMLSYNTAXMODE_AttriValue:
\r
2265 if (ch == m_wQuotationMark) {
\r
2266 if (m_iEntityStart > -1) {
\r
2267 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2268 return m_dwStatus;
\r
2270 m_iTextDataLength = m_iDataPos;
\r
2271 m_wQuotationMark = 0;
\r
2274 m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
\r
2275 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
\r
2277 ParseTextChar(ch);
\r
2280 case FDE_XMLSYNTAXMODE_CloseInstruction:
\r
2282 if (m_iDataPos >= m_iTextDataSize) {
\r
2283 ReallocTextDataBuffer();
\r
2285 m_pwsTextData[m_iDataPos ++] = ch;
\r
2286 m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
\r
2287 } else if (m_iDataPos > 0) {
\r
2288 m_iTextDataLength = m_iDataPos;
\r
2290 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
2293 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
\r
2294 if (pXMLNode == NULL) {
\r
2295 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2296 return m_dwStatus;
\r
2298 m_XMLNodeStack.Pop();
\r
2299 pXMLNode = m_XMLNodeStack.GetTopElement();
\r
2300 if (pXMLNode == NULL) {
\r
2301 m_CurNode.iNodeNum = -1;
\r
2302 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
2304 m_CurNode = *pXMLNode;
\r
2306 m_iCurrentNodeNum = m_CurNode.iNodeNum;
\r
2308 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2309 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
\r
2312 case FDE_XMLSYNTAXMODE_BreakElement:
\r
2314 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2315 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
\r
2316 } else if (ch == L'/') {
\r
2317 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
\r
2319 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2320 return m_dwStatus;
\r
2324 case FDE_XMLSYNTAXMODE_CloseElement:
\r
2325 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
\r
2327 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
\r
2328 if (pXMLNode == NULL) {
\r
2329 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2330 return m_dwStatus;
\r
2332 m_XMLNodeStack.Pop();
\r
2333 pXMLNode = m_XMLNodeStack.GetTopElement();
\r
2334 if (pXMLNode == NULL) {
\r
2335 m_CurNode.iNodeNum = -1;
\r
2336 m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
\r
2338 m_CurNode = *pXMLNode;
\r
2340 m_iCurrentNodeNum = m_CurNode.iNodeNum;
\r
2341 m_iTextDataLength = m_iDataPos;
\r
2343 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2344 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
\r
2345 } else if (!FDE_IsXMLWhiteSpace(ch)) {
\r
2346 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2347 return m_dwStatus;
\r
2350 if (m_iDataPos >= m_iTextDataSize) {
\r
2351 ReallocTextDataBuffer();
\r
2353 m_pwsTextData[m_iDataPos ++] = ch;
\r
2357 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
\r
2359 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
\r
2361 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
\r
2362 m_SkipChar = L'>';
\r
2363 m_SkipStack.Push(L'>');
\r
2366 case FDE_XMLSYNTAXMODE_SkipDeclNode:
\r
2367 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
\r
2369 if (ch != m_SkipChar) {
\r
2372 m_SkipStack.Pop();
\r
2373 FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
\r
2374 if (pDWord == NULL) {
\r
2375 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2377 m_SkipChar = (FX_WCHAR) * pDWord;
\r
2382 m_SkipChar = L'>';
\r
2383 m_SkipStack.Push(L'>');
\r
2386 m_SkipChar = L']';
\r
2387 m_SkipStack.Push(L']');
\r
2390 m_SkipChar = L')';
\r
2391 m_SkipStack.Push(L')');
\r
2394 m_SkipChar = L'\'';
\r
2395 m_SkipStack.Push(L'\'');
\r
2398 m_SkipChar = L'\"';
\r
2399 m_SkipStack.Push(L'\"');
\r
2402 if (ch == m_SkipChar) {
\r
2403 m_SkipStack.Pop();
\r
2404 FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
\r
2405 if (pDWord == NULL) {
\r
2406 m_iTextDataLength = m_iDataPos;
\r
2408 if (m_iTextDataLength >= 9
\r
2409 && FXSYS_memcmp(m_pwsTextData, L"[CDATA[", 7 * sizeof(FX_WCHAR)) == 0
\r
2410 && FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, L"]]", 2 * sizeof(FX_WCHAR)) == 0) {
\r
2411 m_iTextDataLength -= 9;
\r
2412 FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, m_iTextDataLength * sizeof(FX_WCHAR));
\r
2413 dwStatus = FDE_XMLSYNTAXSTATUS_CData;
\r
2415 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2417 m_SkipChar = (FX_WCHAR) * pDWord;
\r
2422 if (m_SkipStack.GetSize() > 0) {
\r
2423 if (m_iDataPos >= m_iTextDataSize) {
\r
2424 ReallocTextDataBuffer();
\r
2426 m_pwsTextData[m_iDataPos ++] = ch;
\r
2431 case FDE_XMLSYNTAXMODE_SkipComment:
\r
2434 } else if (ch == L'>') {
\r
2435 if (m_iDataPos > 1) {
\r
2437 m_dwMode = FDE_XMLSYNTAXMODE_Text;
\r
2444 case FDE_XMLSYNTAXMODE_TargetData:
\r
2445 if (FDE_IsXMLWhiteSpace(ch)) {
\r
2446 if (m_iDataPos < 1) {
\r
2449 } else if (m_wQuotationMark == 0) {
\r
2450 m_iTextDataLength = m_iDataPos;
\r
2451 m_wQuotationMark = 0;
\r
2454 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
2459 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
\r
2461 } else if (ch == '\"') {
\r
2462 if (m_wQuotationMark == 0) {
\r
2463 m_wQuotationMark = ch;
\r
2465 } else if (ch == m_wQuotationMark) {
\r
2466 m_iTextDataLength = m_iDataPos;
\r
2467 m_wQuotationMark = 0;
\r
2470 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
\r
2472 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
\r
2473 return m_dwStatus;
\r
2476 if (m_iDataPos >= m_iTextDataSize) {
\r
2477 ReallocTextDataBuffer();
\r
2479 m_pwsTextData[m_iDataPos ++] = ch;
\r
2486 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
\r
2494 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser()
\r
2496 #ifdef _FDE_BLOCK_BUFFER
\r
2497 if (m_pCurrentBlock) {
\r
2498 m_pCurrentBlock = NULL;
\r
2501 if (m_pwsTextData != NULL) {
\r
2502 FDE_Free(m_pwsTextData);
\r
2505 if (m_pBuffer != NULL) {
\r
2506 FDE_Free(m_pBuffer);
\r
2509 FX_INT32 CFDE_XMLSyntaxParser::GetStatus() const
\r
2511 if (m_pStream == NULL) {
\r
2514 FX_INT32 iStreamLength = m_pStream->GetLength();
\r
2515 if (iStreamLength < 1) {
\r
2518 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) {
\r
2521 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
\r
2524 return m_iParsedBytes * 100 / iStreamLength;
\r
2526 static FX_INT32 FX_GetUTF8EncodeLength(FX_LPCWSTR pSrc, FX_INT32 iSrcLen)
\r
2528 FX_DWORD unicode = 0;
\r
2529 FX_INT32 iDstNum = 0;
\r
2530 while (iSrcLen -- > 0) {
\r
2531 unicode = *pSrc ++;
\r
2533 if ((FX_DWORD)unicode < 0x80) {
\r
2535 } else if ((FX_DWORD)unicode < 0x800) {
\r
2537 } else if ((FX_DWORD)unicode < 0x10000) {
\r
2539 } else if ((FX_DWORD)unicode < 0x200000) {
\r
2541 } else if ((FX_DWORD)unicode < 0x4000000) {
\r
2546 iDstNum += nbytes;
\r
2550 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const
\r
2552 if (m_pStream == NULL) {
\r
2555 FX_INT32 nSrcLen = m_pStart - m_pBuffer;
\r
2556 FX_INT32 nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen);
\r
2557 return m_iParsedBytes + nDstLen;
\r
2559 #ifdef _FDE_BLOCK_BUFFER
\r
2560 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
\r
2562 if (m_iIndexInBlock == m_iAllocStep) {
\r
2563 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
2564 if (!m_pCurrentBlock) {
\r
2568 m_pCurrentBlock[m_iIndexInBlock++] = ch;
\r
2570 if (m_iEntityStart > -1 && ch == L';') {
\r
2571 CFX_WideString csEntity;
\r
2572 m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, (m_iDataLength - 1) - m_iEntityStart - 1);
\r
2573 FX_INT32 iLen = csEntity.GetLength();
\r
2575 if (csEntity[0] == L'#') {
\r
2578 if (iLen > 1 && csEntity[1] == L'x') {
\r
2579 for (FX_INT32 i = 2; i < iLen; i ++) {
\r
2581 if (w >= L'0' && w <= L'9') {
\r
2582 ch = (ch << 4) + w - L'0';
\r
2583 } else if (w >= L'A' && w <= L'F') {
\r
2584 ch = (ch << 4) + w - 55;
\r
2585 } else if (w >= L'a' && w <= L'f') {
\r
2586 ch = (ch << 4) + w - 87;
\r
2592 for (FX_INT32 i = 1; i < iLen; i ++) {
\r
2594 if (w < L'0' || w > L'9') {
\r
2597 ch = ch * 10 + w - L'0';
\r
2601 m_BlockBuffer.SetTextChar(m_iEntityStart, ch);
\r
2602 m_iEntityStart ++;
\r
2605 if (csEntity.Compare(L"amp") == 0) {
\r
2606 m_BlockBuffer.SetTextChar(m_iEntityStart, L'&');
\r
2607 m_iEntityStart ++;
\r
2608 } else if (csEntity.Compare(L"lt") == 0) {
\r
2609 m_BlockBuffer.SetTextChar(m_iEntityStart, L'<');
\r
2610 m_iEntityStart ++;
\r
2611 } else if (csEntity.Compare(L"gt") == 0) {
\r
2612 m_BlockBuffer.SetTextChar(m_iEntityStart, L'>');
\r
2613 m_iEntityStart ++;
\r
2614 } else if (csEntity.Compare(L"apos") == 0) {
\r
2615 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\'');
\r
2616 m_iEntityStart ++;
\r
2617 } else if (csEntity.Compare(L"quot") == 0) {
\r
2618 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"');
\r
2619 m_iEntityStart ++;
\r
2623 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE);
\r
2624 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
\r
2625 m_iEntityStart = -1;
\r
2627 if (m_iEntityStart < 0 && ch == L'&') {
\r
2628 m_iEntityStart = m_iDataLength - 1;
\r
2634 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
\r
2636 if (m_iDataPos >= m_iTextDataSize) {
\r
2637 ReallocTextDataBuffer();
\r
2639 m_pwsTextData[m_iDataPos] = ch;
\r
2640 if (m_iEntityStart > -1 && ch == L';') {
\r
2641 CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, m_iDataPos - m_iEntityStart - 1);
\r
2642 FX_INT32 iLen = csEntity.GetLength();
\r
2644 if (csEntity[0] == L'#') {
\r
2647 if (iLen > 1 && csEntity[1] == L'x') {
\r
2648 for (FX_INT32 i = 2; i < iLen; i ++) {
\r
2650 if (w >= L'0' && w <= L'9') {
\r
2651 ch = (ch << 4) + w - L'0';
\r
2652 } else if (w >= L'A' && w <= L'F') {
\r
2653 ch = (ch << 4) + w - 55;
\r
2654 } else if (w >= L'a' && w <= L'f') {
\r
2655 ch = (ch << 4) + w - 87;
\r
2661 for (FX_INT32 i = 1; i < iLen; i ++) {
\r
2663 if (w < L'0' || w > L'9') {
\r
2666 ch = ch * 10 + w - L'0';
\r
2670 m_pwsTextData[m_iEntityStart ++] = ch;
\r
2673 if (csEntity.Compare(L"amp") == 0) {
\r
2674 m_pwsTextData[m_iEntityStart ++] = L'&';
\r
2675 } else if (csEntity.Compare(L"lt") == 0) {
\r
2676 m_pwsTextData[m_iEntityStart ++] = L'<';
\r
2677 } else if (csEntity.Compare(L"gt") == 0) {
\r
2678 m_pwsTextData[m_iEntityStart ++] = L'>';
\r
2679 } else if (csEntity.Compare(L"apos") == 0) {
\r
2680 m_pwsTextData[m_iEntityStart ++] = L'\'';
\r
2681 } else if (csEntity.Compare(L"quot") == 0) {
\r
2682 m_pwsTextData[m_iEntityStart ++] = L'\"';
\r
2686 m_iDataPos = m_iEntityStart;
\r
2687 m_iEntityStart = -1;
\r
2689 if (m_iEntityStart < 0 && ch == L'&') {
\r
2690 m_iEntityStart = m_iDataPos;
\r
2696 void CFDE_XMLSyntaxParser::ReallocTextDataBuffer()
\r
2698 FXSYS_assert(m_pwsTextData != NULL);
\r
2699 if (m_iTextDataSize <= 1024 * 1024) {
\r
2700 m_iTextDataSize *= 2;
\r
2702 m_iTextDataSize += 1024 * 1024;
\r
2704 m_pwsTextData = (FX_LPWSTR)FDE_Realloc(m_pwsTextData, m_iTextDataSize * sizeof(FX_WCHAR));
\r
2706 void CFDE_XMLSyntaxParser::GetData(CFX_WideString &wsData) const
\r
2708 FX_LPWSTR pBuf = wsData.GetBuffer(m_iTextDataLength);
\r
2709 FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR));
\r
2710 wsData.ReleaseBuffer(m_iTextDataLength);
\r