From 4a2aa1a90d89b88036b0bff432ffefa183ea80d0 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Tue, 19 Jan 2016 15:18:13 -0800 Subject: Resolve fde_xml.h header collision R=thestig@chromium.org Review URL: https://codereview.chromium.org/1581823002 . --- xfa/src/fdp/include/fde_xml.h | 8 +- xfa/src/fdp/src/xml/fde_xml.cpp | 2638 ----------------------------------- xfa/src/fdp/src/xml/fde_xml.h | 373 ----- xfa/src/fdp/src/xml/fde_xml_imp.cpp | 2637 ++++++++++++++++++++++++++++++++++ xfa/src/fdp/src/xml/fde_xml_imp.h | 375 +++++ 5 files changed, 3017 insertions(+), 3014 deletions(-) delete mode 100644 xfa/src/fdp/src/xml/fde_xml.cpp delete mode 100644 xfa/src/fdp/src/xml/fde_xml.h create mode 100644 xfa/src/fdp/src/xml/fde_xml_imp.cpp create mode 100644 xfa/src/fdp/src/xml/fde_xml_imp.h (limited to 'xfa/src') diff --git a/xfa/src/fdp/include/fde_xml.h b/xfa/src/fdp/include/fde_xml.h index 9fc80b789d..85793aae19 100644 --- a/xfa/src/fdp/include/fde_xml.h +++ b/xfa/src/fdp/include/fde_xml.h @@ -4,8 +4,9 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#ifndef _FDE_XML -#define _FDE_XML +#ifndef FDE_XML_H_ +#define FDE_XML_H_ + class IFDE_XMLNode; class IFDE_XMLInstruction; class IFDE_XMLDeclaration; @@ -228,4 +229,5 @@ class IFDE_XMLSyntaxParser { virtual void GetTextData(CFX_WideString& wsText) const = 0; virtual void GetTargetData(CFX_WideString& wsData) const = 0; }; -#endif + +#endif // FDE_XML_H_ diff --git a/xfa/src/fdp/src/xml/fde_xml.cpp b/xfa/src/fdp/src/xml/fde_xml.cpp deleted file mode 100644 index 8725cb7655..0000000000 --- a/xfa/src/fdp/src/xml/fde_xml.cpp +++ /dev/null @@ -1,2638 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include - -#include "xfa/src/foxitlib.h" -#include "fde_xml.h" -#ifdef __cplusplus -extern "C" { -#endif -#define FDE_XMLVALIDCHARRANGENUM 5 -static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { - {0x09, 0x09}, - {0x0A, 0x0A}, - {0x0D, 0x0D}, - {0x20, 0xD7FF}, - {0xE000, 0xFFFD}}; -FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { - int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; - while (iStart <= iEnd) { - iMid = (iStart + iEnd) / 2; - if (ch < g_XMLValidCharRange[iMid][0]) { - iEnd = iMid - 1; - } else if (ch > g_XMLValidCharRange[iMid][1]) { - iStart = iMid + 1; - } else { - return TRUE; - } - } - return FALSE; -} -FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch) { - return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09; -} -typedef struct _FDE_XMLNAMECHAR { - FX_WCHAR wStart; - FX_WCHAR wEnd; - FX_BOOL bStartChar; -} FDE_XMLNAMECHAR; -#define FDE_XMLNAMECHARSNUM 20 -static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = { - {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, - {L'A', L'Z', TRUE}, {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, - {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE}, {0xD8, 0xF6, TRUE}, - {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE}, - {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, - {0x2070, 0x218F, TRUE}, {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, - {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE}, -}; -FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar) { - int32_t iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid; - while (iStart <= iEnd) { - iMid = (iStart + iEnd) / 2; - if (ch < g_XMLNameChars[iMid].wStart) { - iEnd = iMid - 1; - } else if (ch > g_XMLNameChars[iMid].wEnd) { - iStart = iMid + 1; - } else { - if (bFirstChar) { - return g_XMLNameChars[iMid].bStartChar; - } - return TRUE; - } - } - return FALSE; -} -#ifdef __cplusplus -} -#endif -CFDE_XMLNode::CFDE_XMLNode() - : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} -CFDE_XMLNode::~CFDE_XMLNode() { - DeleteChildren(); -} -void CFDE_XMLNode::DeleteChildren() { - CFDE_XMLNode *pChild = m_pChild, *pTemp; - while (pChild != NULL) { - pTemp = pChild->m_pNext; - pChild->Release(); - pChild = pTemp; - } - m_pChild = NULL; -} -int32_t CFDE_XMLNode::CountChildNodes() const { - int32_t iCount = 0; - CFDE_XMLNode* pChild = m_pChild; - while (pChild != NULL) { - iCount++; - pChild = pChild->m_pNext; - } - return iCount; -} -CFDE_XMLNode* CFDE_XMLNode::GetChildNode(int32_t index) const { - CFDE_XMLNode* pChild = m_pChild; - while (pChild != NULL) { - if (index == 0) { - return pChild; - } - index--; - pChild = pChild->m_pNext; - } - return NULL; -} -int32_t CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode* pNode) const { - int32_t index = 0; - CFDE_XMLNode* pChild = m_pChild; - while (pChild != NULL) { - if (pChild == pNode) { - return index; - } - index++; - pChild = pChild->m_pNext; - } - return -1; -} -CFDE_XMLNode* CFDE_XMLNode::GetPath(const FX_WCHAR* pPath, - int32_t iLength, - FX_BOOL bQualifiedName) const { - FXSYS_assert(pPath != NULL); - if (iLength < 0) { - iLength = FXSYS_wcslen(pPath); - } - if (iLength == 0) { - return NULL; - } - CFX_WideString csPath; - const FX_WCHAR* pStart = pPath; - const FX_WCHAR* pEnd = pPath + iLength; - FX_WCHAR ch; - while (pStart < pEnd) { - ch = *pStart++; - if (ch == L'/') { - break; - } else { - csPath += ch; - } - } - iLength -= pStart - pPath; - CFDE_XMLNode* pFind = NULL; - if (csPath.GetLength() < 1) { - pFind = GetNodeItem(IFDE_XMLNode::Root); - } else if (csPath.Compare(L"..") == 0) { - pFind = m_pParent; - } else if (csPath.Compare(L".") == 0) { - pFind = (CFDE_XMLNode*)this; - } else { - CFX_WideString wsTag; - CFDE_XMLNode* pNode = m_pChild; - while (pNode != NULL) { - if (pNode->GetType() == FDE_XMLNODE_Element) { - if (bQualifiedName) { - ((CFDE_XMLElement*)pNode)->GetTagName(wsTag); - } else { - ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag); - } - if (wsTag.Compare(csPath) == 0) { - if (iLength < 1) { - pFind = pNode; - } else { - pFind = pNode->GetPath(pStart, iLength, bQualifiedName); - } - if (pFind != NULL) { - return pFind; - } - } - } - pNode = pNode->m_pNext; - } - } - if (pFind == NULL || iLength < 1) { - return pFind; - } - return pFind->GetPath(pStart, iLength, bQualifiedName); -} -int32_t CFDE_XMLNode::InsertChildNode(CFDE_XMLNode* pNode, int32_t index) { - FXSYS_assert(pNode != NULL); - pNode->m_pParent = this; - if (m_pChild == NULL) { - m_pChild = pNode; - pNode->m_pPrior = NULL; - pNode->m_pNext = NULL; - return 0; - } else if (index == 0) { - pNode->m_pNext = m_pChild; - pNode->m_pPrior = NULL; - m_pChild->m_pPrior = pNode; - m_pChild = pNode; - return 0; - } - int32_t iCount = 0; - CFDE_XMLNode* pFind = m_pChild; - while (++iCount != index && pFind->m_pNext != NULL) { - pFind = pFind->m_pNext; - } - pNode->m_pPrior = pFind; - pNode->m_pNext = pFind->m_pNext; - if (pFind->m_pNext != NULL) { - pFind->m_pNext->m_pPrior = pNode; - } - pFind->m_pNext = pNode; - return iCount; -} -void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode* pNode) { - FXSYS_assert(m_pChild != NULL && pNode != NULL); - if (m_pChild == pNode) { - m_pChild = pNode->m_pNext; - } else { - pNode->m_pPrior->m_pNext = pNode->m_pNext; - } - if (pNode->m_pNext != NULL) { - pNode->m_pNext->m_pPrior = pNode->m_pPrior; - } - pNode->m_pParent = NULL; - pNode->m_pNext = NULL; - pNode->m_pPrior = NULL; -} -CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const { - switch (eItem) { - case IFDE_XMLNode::Root: { - CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; - while (pParent->m_pParent != NULL) { - pParent = pParent->m_pParent; - } - return pParent; - } - case IFDE_XMLNode::Parent: - return m_pParent; - case IFDE_XMLNode::FirstSibling: { - CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; - while (pItem->m_pPrior != NULL) { - pItem = pItem->m_pPrior; - } - return pItem == (CFDE_XMLNode*)this ? NULL : pItem; - } - case IFDE_XMLNode::PriorSibling: - return m_pPrior; - case IFDE_XMLNode::NextSibling: - return m_pNext; - case IFDE_XMLNode::LastSibling: { - CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; - while (pItem->m_pNext != NULL) { - pItem = pItem->m_pNext; - } - return pItem == (CFDE_XMLNode*)this ? NULL : pItem; - } - case IFDE_XMLNode::FirstNeighbor: { - CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; - while (pParent->m_pParent != NULL) { - pParent = pParent->m_pParent; - } - return pParent == (CFDE_XMLNode*)this ? NULL : pParent; - } - case IFDE_XMLNode::PriorNeighbor: { - if (m_pPrior == NULL) { - return m_pParent; - } - CFDE_XMLNode* pItem = m_pPrior; - while (CFDE_XMLNode* pTemp = pItem->m_pChild) { - pItem = pTemp; - while ((pTemp = pItem->m_pNext) != NULL) { - pItem = pTemp; - } - } - return pItem; - } - case IFDE_XMLNode::NextNeighbor: { - if (m_pChild != NULL) { - return m_pChild; - } - if (m_pNext != NULL) { - return m_pNext; - } - CFDE_XMLNode* pItem = m_pParent; - while (pItem != NULL) { - if (pItem->m_pNext != NULL) { - return pItem->m_pNext; - } - pItem = pItem->m_pParent; - } - return NULL; - } - case IFDE_XMLNode::LastNeighbor: { - CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; - while (pItem->m_pParent != NULL) { - pItem = pItem->m_pParent; - } - while (TRUE) { - while (pItem->m_pNext != NULL) { - pItem = pItem->m_pNext; - } - if (pItem->m_pChild == NULL) { - break; - } - pItem = pItem->m_pChild; - } - return pItem == (CFDE_XMLNode*)this ? NULL : pItem; - } - case IFDE_XMLNode::FirstChild: - return m_pChild; - case IFDE_XMLNode::LastChild: { - if (m_pChild == NULL) { - return NULL; - } - CFDE_XMLNode* pChild = m_pChild; - while (pChild->m_pNext != NULL) { - pChild = pChild->m_pNext; - } - return pChild; - } - default: - break; - } - return NULL; -} -int32_t CFDE_XMLNode::GetNodeLevel() const { - int32_t iLevel = 0; - CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; - while ((pItem = pItem->m_pParent) != NULL) { - iLevel++; - } - return iLevel; -} -FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, - CFDE_XMLNode* pNode) { - FXSYS_assert(pNode != NULL); - switch (eItem) { - case IFDE_XMLNode::NextSibling: { - pNode->m_pParent = m_pParent; - pNode->m_pNext = m_pNext; - pNode->m_pPrior = this; - if (m_pNext) { - m_pNext->m_pPrior = pNode; - } - m_pNext = pNode; - return TRUE; - } - case IFDE_XMLNode::PriorSibling: { - pNode->m_pParent = m_pParent; - pNode->m_pNext = this; - pNode->m_pPrior = m_pPrior; - if (m_pPrior) { - m_pPrior->m_pNext = pNode; - } else if (m_pParent) { - m_pParent->m_pChild = pNode; - } - m_pPrior = pNode; - return TRUE; - } - default: - return FALSE; - } - return FALSE; -} -CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) { - CFDE_XMLNode* pNode = NULL; - switch (eItem) { - case IFDE_XMLNode::NextSibling: - if (m_pNext) { - pNode = m_pNext; - m_pNext = pNode->m_pNext; - if (m_pNext) { - m_pNext->m_pPrior = this; - } - pNode->m_pParent = NULL; - pNode->m_pNext = NULL; - pNode->m_pPrior = NULL; - } - break; - default: - break; - } - return pNode; -} -CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive) { - return NULL; -} -void CFDE_XMLNode::SaveXMLNode(IFX_Stream* pXMLStream) { - CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; - FXSYS_assert(pXMLStream != NULL && pNode != NULL); - switch (pNode->GetType()) { - case FDE_XMLNODE_Instruction: { - CFX_WideString ws; - CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; - if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { - ws = L"GetCodePage(); - if (wCodePage == FX_CODEPAGE_UTF16LE) { - ws += L"UTF-16"; - } else if (wCodePage == FX_CODEPAGE_UTF16BE) { - ws += L"UTF-16be"; - } else { - ws += L"UTF-8"; - } - ws += L"\"?>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } else { - ws.Format(L"m_wsTarget); - pXMLStream->WriteString(ws, ws.GetLength()); - CFX_WideStringArray& attributes = pInstruction->m_Attributes; - int32_t i, iCount = attributes.GetSize(); - CFX_WideString wsValue; - for (i = 0; i < iCount; i += 2) { - ws = L" "; - ws += attributes[i]; - ws += L"=\""; - wsValue = attributes[i + 1]; - wsValue.Replace(L"&", L"&"); - wsValue.Replace(L"<", L"<"); - wsValue.Replace(L">", L">"); - wsValue.Replace(L"\'", L"'"); - wsValue.Replace(L"\"", L"""); - ws += wsValue; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - CFX_WideStringArray& targetdata = pInstruction->m_TargetData; - iCount = targetdata.GetSize(); - for (i = 0; i < iCount; i++) { - ws = L" \""; - ws += targetdata[i]; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - ws = L"?>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } - } break; - case FDE_XMLNODE_Element: { - CFX_WideString ws; - ws = L"<"; - ws += ((CFDE_XMLElement*)pNode)->m_wsTag; - pXMLStream->WriteString(ws, ws.GetLength()); - CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; - int32_t iCount = attributes.GetSize(); - CFX_WideString wsValue; - for (int32_t i = 0; i < iCount; i += 2) { - ws = L" "; - ws += attributes[i]; - ws += L"=\""; - wsValue = attributes[i + 1]; - wsValue.Replace(L"&", L"&"); - wsValue.Replace(L"<", L"<"); - wsValue.Replace(L">", L">"); - wsValue.Replace(L"\'", L"'"); - wsValue.Replace(L"\"", L"""); - ws += wsValue; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - if (pNode->m_pChild == NULL) { - ws = L"\n/>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } else { - ws = L"\n>"; - pXMLStream->WriteString(ws, ws.GetLength()); - CFDE_XMLNode* pChild = pNode->m_pChild; - while (pChild != NULL) { - pChild->SaveXMLNode(pXMLStream); - pChild = pChild->m_pNext; - } - ws = L"m_wsTag; - ws += L"\n>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } - } break; - case FDE_XMLNODE_Text: { - CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; - ws.Replace(L"&", L"&"); - ws.Replace(L"<", L"<"); - ws.Replace(L">", L">"); - ws.Replace(L"\'", L"'"); - ws.Replace(L"\"", L"""); - pXMLStream->WriteString(ws, ws.GetLength()); - } break; - case FDE_XMLNODE_CharData: { - CFX_WideString ws = L"m_wsCharData; - ws += L"]]>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } break; - case FDE_XMLNODE_Unknown: - break; - default: - break; - } -} -void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) { - if (!m_pChild) { - return; - } - CFDE_XMLNode* pNext = m_pChild; - CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE); - pClone->InsertChildNode(pCloneNext); - pNext = pNext->m_pNext; - while (pNext) { - CFDE_XMLNode* pChild = pNext->Clone(TRUE); - pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild); - pCloneNext = pChild; - pNext = pNext->m_pNext; - } -} -IFDE_XMLInstruction* IFDE_XMLInstruction::Create( - const CFX_WideString& wsTarget) { - return (IFDE_XMLInstruction*)new CFDE_XMLInstruction(wsTarget); -} -CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) - : m_wsTarget(wsTarget) { - FXSYS_assert(m_wsTarget.GetLength() > 0); -} -CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive) { - CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget); - if (!pClone) { - return pClone; - } - pClone->m_Attributes.Copy(m_Attributes); - pClone->m_TargetData.Copy(m_TargetData); - if (bRecursive) { - CloneChildren(pClone); - } - return pClone; -} -int32_t CFDE_XMLInstruction::CountAttributes() const { - return m_Attributes.GetSize() / 2; -} -FX_BOOL CFDE_XMLInstruction::GetAttribute(int32_t index, - CFX_WideString& wsAttriName, - CFX_WideString& wsAttriValue) const { - int32_t iCount = m_Attributes.GetSize(); - FXSYS_assert(index > -1 && index < iCount / 2); - for (int32_t i = 0; i < iCount; i += 2) { - if (index == 0) { - wsAttriName = m_Attributes[i]; - wsAttriValue = m_Attributes[i + 1]; - return TRUE; - } - index--; - } - return FALSE; -} -FX_BOOL CFDE_XMLInstruction::HasAttribute(const FX_WCHAR* pwsAttriName) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return TRUE; - } - } - return FALSE; -} -void CFDE_XMLInstruction::GetString(const FX_WCHAR* pwsAttriName, - CFX_WideString& wsAttriValue, - const FX_WCHAR* pwsDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - wsAttriValue = m_Attributes[i + 1]; - return; - } - } - wsAttriValue = pwsDefValue; -} -void CFDE_XMLInstruction::SetString(const CFX_WideString& wsAttriName, - const CFX_WideString& wsAttriValue) { - FXSYS_assert(wsAttriName.GetLength() > 0); - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(wsAttriName) == 0) { - m_Attributes[i] = wsAttriName; - m_Attributes[i + 1] = wsAttriValue; - return; - } - } - m_Attributes.Add(wsAttriName); - m_Attributes.Add(wsAttriValue); -} -int32_t CFDE_XMLInstruction::GetInteger(const FX_WCHAR* pwsAttriName, - int32_t iDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); - } - } - return iDefValue; -} -void CFDE_XMLInstruction::SetInteger(const FX_WCHAR* pwsAttriName, - int32_t iAttriValue) { - CFX_WideString wsValue; - wsValue.Format(L"%d", iAttriValue); - SetString(pwsAttriName, wsValue); -} -FX_FLOAT CFDE_XMLInstruction::GetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); - } - } - return fDefValue; -} -void CFDE_XMLInstruction::SetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fAttriValue) { - CFX_WideString wsValue; - wsValue.Format(L"%f", fAttriValue); - SetString(pwsAttriName, wsValue); -} -void CFDE_XMLInstruction::RemoveAttribute(const FX_WCHAR* pwsAttriName) { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - m_Attributes.RemoveAt(i + 1); - m_Attributes.RemoveAt(i); - return; - } - } -} -int32_t CFDE_XMLInstruction::CountData() const { - return m_TargetData.GetSize(); -} -FX_BOOL CFDE_XMLInstruction::GetData(int32_t index, - CFX_WideString& wsData) const { - if (index < 0 || index >= m_TargetData.GetSize()) { - return FALSE; - } - wsData = m_TargetData[index]; - return TRUE; -} -void CFDE_XMLInstruction::AppendData(const CFX_WideString& wsData) { - m_TargetData.Add(wsData); -} -void CFDE_XMLInstruction::RemoveData(int32_t index) { - m_TargetData.RemoveAt(index); -} -IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString& wsTag) { - return (IFDE_XMLElement*)new CFDE_XMLElement(wsTag); -} -CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) - : CFDE_XMLNode(), m_wsTag(wsTag), m_Attributes() { - FXSYS_assert(m_wsTag.GetLength() > 0); -} -CFDE_XMLElement::~CFDE_XMLElement() { - m_Attributes.RemoveAll(); -} -CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive) { - CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag); - if (!pClone) { - return NULL; - } - pClone->m_Attributes.Copy(m_Attributes); - if (bRecursive) { - CloneChildren(pClone); - } else { - CFX_WideString wsText; - CFDE_XMLNode* pChild = m_pChild; - while (pChild != NULL) { - switch (pChild->GetType()) { - case FDE_XMLNODE_Text: - wsText += ((CFDE_XMLText*)pChild)->m_wsText; - break; - default: - break; - } - pChild = pChild->m_pNext; - } - pClone->SetTextData(wsText); - } - return pClone; -} -void CFDE_XMLElement::GetTagName(CFX_WideString& wsTag) const { - wsTag = m_wsTag; -} -void CFDE_XMLElement::GetLocalTagName(CFX_WideString& wsTag) const { - FX_STRSIZE iFind = m_wsTag.Find(L':', 0); - if (iFind < 0) { - wsTag = m_wsTag; - } else { - wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1); - } -} -void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString& wsPrefix) const { - FX_STRSIZE iFind = m_wsTag.Find(L':', 0); - if (iFind < 0) { - wsPrefix.Empty(); - } else { - wsPrefix = m_wsTag.Left(iFind); - } -} -void CFDE_XMLElement::GetNamespaceURI(CFX_WideString& wsNamespace) const { - CFX_WideString wsAttri(L"xmlns"), wsPrefix; - GetNamespacePrefix(wsPrefix); - if (wsPrefix.GetLength() > 0) { - wsAttri += L":"; - wsAttri += wsPrefix; - } - wsNamespace.Empty(); - CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; - while (pNode != NULL) { - if (pNode->GetType() != FDE_XMLNODE_Element) { - break; - } - CFDE_XMLElement* pElement = (CFDE_XMLElement*)pNode; - if (!pElement->HasAttribute(wsAttri)) { - pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent); - continue; - } - pElement->GetString(wsAttri, wsNamespace); - break; - } -} -int32_t CFDE_XMLElement::CountAttributes() const { - return m_Attributes.GetSize() / 2; -} -FX_BOOL CFDE_XMLElement::GetAttribute(int32_t index, - CFX_WideString& wsAttriName, - CFX_WideString& wsAttriValue) const { - int32_t iCount = m_Attributes.GetSize(); - FXSYS_assert(index > -1 && index < iCount / 2); - for (int32_t i = 0; i < iCount; i += 2) { - if (index == 0) { - wsAttriName = m_Attributes[i]; - wsAttriValue = m_Attributes[i + 1]; - return TRUE; - } - index--; - } - return FALSE; -} -FX_BOOL CFDE_XMLElement::HasAttribute(const FX_WCHAR* pwsAttriName) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return TRUE; - } - } - return FALSE; -} -void CFDE_XMLElement::GetString(const FX_WCHAR* pwsAttriName, - CFX_WideString& wsAttriValue, - const FX_WCHAR* pwsDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - wsAttriValue = m_Attributes[i + 1]; - return; - } - } - wsAttriValue = pwsDefValue; -} -void CFDE_XMLElement::SetString(const CFX_WideString& wsAttriName, - const CFX_WideString& wsAttriValue) { - FXSYS_assert(wsAttriName.GetLength() > 0); - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(wsAttriName) == 0) { - m_Attributes[i] = wsAttriName; - m_Attributes[i + 1] = wsAttriValue; - return; - } - } - m_Attributes.Add(wsAttriName); - m_Attributes.Add(wsAttriValue); -} -int32_t CFDE_XMLElement::GetInteger(const FX_WCHAR* pwsAttriName, - int32_t iDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); - } - } - return iDefValue; -} -void CFDE_XMLElement::SetInteger(const FX_WCHAR* pwsAttriName, - int32_t iAttriValue) { - CFX_WideString wsValue; - wsValue.Format(L"%d", iAttriValue); - SetString(pwsAttriName, wsValue); -} -FX_FLOAT CFDE_XMLElement::GetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fDefValue) const { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); - } - } - return fDefValue; -} -void CFDE_XMLElement::SetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fAttriValue) { - CFX_WideString wsValue; - wsValue.Format(L"%f", fAttriValue); - SetString(pwsAttriName, wsValue); -} -void CFDE_XMLElement::RemoveAttribute(const FX_WCHAR* pwsAttriName) { - int32_t iCount = m_Attributes.GetSize(); - for (int32_t i = 0; i < iCount; i += 2) { - if (m_Attributes[i].Compare(pwsAttriName) == 0) { - m_Attributes.RemoveAt(i + 1); - m_Attributes.RemoveAt(i); - return; - } - } -} -void CFDE_XMLElement::GetTextData(CFX_WideString& wsText) const { - CFX_WideTextBuf buffer; - CFDE_XMLNode* pChild = m_pChild; - while (pChild != NULL) { - switch (pChild->GetType()) { - case FDE_XMLNODE_Text: - buffer << ((CFDE_XMLText*)pChild)->m_wsText; - break; - case FDE_XMLNODE_CharData: - buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData; - break; - default: - break; - } - pChild = pChild->m_pNext; - } - wsText = buffer.GetWideString(); -} -void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { - if (wsText.GetLength() < 1) { - return; - } - InsertChildNode(new CFDE_XMLText(wsText)); -} -IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString& wsText) { - return (IFDE_XMLText*)new CFDE_XMLText(wsText); -} -CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) - : CFDE_XMLNode(), m_wsText(wsText) {} -CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive) { - CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText); - return pClone; -} -IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString& wsCData) { - return (IFDE_XMLCharData*)new CFDE_XMLCharData(wsCData); -} -CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) - : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} -CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive) { - CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData); - return pClone; -} -IFDE_XMLDoc* IFDE_XMLDoc::Create() { - return (IFDE_XMLDoc*)new CFDE_XMLDoc; -} -CFDE_XMLDoc::CFDE_XMLDoc() - : m_pRoot(NULL), m_pSyntaxParser(NULL), m_pXMLParser(NULL) { - Reset(TRUE); - CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); - m_pRoot->InsertChildNode(pXML); -} -CFDE_XMLDoc::~CFDE_XMLDoc() { - Reset(FALSE); -} -void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot) { - m_iStatus = 0; - m_pStream = NULL; - if (bInitRoot) { - if (m_pRoot == NULL) { - m_pRoot = new CFDE_XMLNode; - } else { - m_pRoot->DeleteChildren(); - } - } else { - if (m_pRoot != NULL) { - m_pRoot->Release(); - m_pRoot = NULL; - } - } - ReleaseParser(); -} -void CFDE_XMLDoc::ReleaseParser() { - if (m_pXMLParser != NULL) { - m_pXMLParser->Release(); - m_pXMLParser = NULL; - } - if (m_pSyntaxParser != NULL) { - m_pSyntaxParser->Release(); - m_pSyntaxParser = NULL; - } -} -FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream* pXMLStream, - int32_t iXMLPlaneSize, - int32_t iTextDataSize, - FDE_LPXMLREADERHANDLER pHandler) { - if (pXMLStream == NULL) { - return FALSE; - } - Reset(TRUE); - iXMLPlaneSize = iXMLPlaneSize / 1024; - if (iXMLPlaneSize < 1) { - iXMLPlaneSize = 1; - } - iXMLPlaneSize *= 1024; - if (iXMLPlaneSize < 4096) { - iXMLPlaneSize = 4096; - } - iTextDataSize = iTextDataSize / 128; - if (iTextDataSize < 1) { - iTextDataSize = 1; - } - iTextDataSize *= 128; - if (iTextDataSize < 128) { - iTextDataSize = 128; - } - m_pStream = pXMLStream; - FX_WORD wCodePage = m_pStream->GetCodePage(); - if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && - wCodePage != FX_CODEPAGE_UTF8) { - m_pStream->SetCodePage(FX_CODEPAGE_UTF8); - } - m_pSyntaxParser = IFDE_XMLSyntaxParser::Create(); - if (m_pSyntaxParser == NULL) { - return FALSE; - } - m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize); - if (pHandler == NULL) { - m_pXMLParser = new CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser); - } else { - m_pXMLParser = new CFDE_XMLSAXParser(pHandler, m_pSyntaxParser); - } - return TRUE; -} -FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser* pXMLParser) { - if (pXMLParser == NULL) { - return FALSE; - } - Reset(TRUE); - m_pXMLParser = pXMLParser; - return m_pXMLParser != NULL; -} -int32_t CFDE_XMLDoc::DoLoad(IFX_Pause* pPause) { - if (m_iStatus >= 100) { - return m_iStatus; - } - FXSYS_assert(m_pXMLParser != NULL); - return m_iStatus = m_pXMLParser->DoParser(pPause); -} -void CFDE_XMLDoc::CloseXML() { - ReleaseParser(); -} -void CFDE_XMLDoc::SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pINode) { - CFDE_XMLNode* pNode = (CFDE_XMLNode*)pINode; - FXSYS_assert(pXMLStream != NULL && pNode != NULL); - switch (pNode->GetType()) { - case FDE_XMLNODE_Instruction: { - CFX_WideString ws; - CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; - if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { - ws = L"GetCodePage(); - if (wCodePage == FX_CODEPAGE_UTF16LE) { - ws += L"UTF-16"; - } else if (wCodePage == FX_CODEPAGE_UTF16BE) { - ws += L"UTF-16be"; - } else { - ws += L"UTF-8"; - } - ws += L"\"?>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } else { - ws.Format(L"m_wsTarget); - pXMLStream->WriteString(ws, ws.GetLength()); - CFX_WideStringArray& attributes = pInstruction->m_Attributes; - int32_t i, iCount = attributes.GetSize(); - CFX_WideString wsValue; - for (i = 0; i < iCount; i += 2) { - ws = L" "; - ws += attributes[i]; - ws += L"=\""; - wsValue = attributes[i + 1]; - wsValue.Replace(L"&", L"&"); - wsValue.Replace(L"<", L"<"); - wsValue.Replace(L">", L">"); - wsValue.Replace(L"\'", L"'"); - wsValue.Replace(L"\"", L"""); - ws += wsValue; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - CFX_WideStringArray& targetdata = pInstruction->m_TargetData; - iCount = targetdata.GetSize(); - for (i = 0; i < iCount; i++) { - ws = L" \""; - ws += targetdata[i]; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - ws = L"?>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } - } break; - case FDE_XMLNODE_Element: { - CFX_WideString ws; - ws = L"<"; - ws += ((CFDE_XMLElement*)pNode)->m_wsTag; - pXMLStream->WriteString(ws, ws.GetLength()); - CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; - int32_t iCount = attributes.GetSize(); - CFX_WideString wsValue; - for (int32_t i = 0; i < iCount; i += 2) { - ws = L" "; - ws += attributes[i]; - ws += L"=\""; - wsValue = attributes[i + 1]; - wsValue.Replace(L"&", L"&"); - wsValue.Replace(L"<", L"<"); - wsValue.Replace(L">", L">"); - wsValue.Replace(L"\'", L"'"); - wsValue.Replace(L"\"", L"""); - ws += wsValue; - ws += L"\""; - pXMLStream->WriteString(ws, ws.GetLength()); - } - if (pNode->m_pChild == NULL) { - ws = L"\n/>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } else { - ws = L"\n>"; - pXMLStream->WriteString(ws, ws.GetLength()); - CFDE_XMLNode* pChild = pNode->m_pChild; - while (pChild != NULL) { - SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild); - pChild = pChild->m_pNext; - } - ws = L"m_wsTag; - ws += L"\n>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } - } break; - case FDE_XMLNODE_Text: { - CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; - ws.Replace(L"&", L"&"); - ws.Replace(L"<", L"<"); - ws.Replace(L">", L">"); - ws.Replace(L"\'", L"'"); - ws.Replace(L"\"", L"""); - pXMLStream->WriteString(ws, ws.GetLength()); - } break; - case FDE_XMLNODE_CharData: { - CFX_WideString ws = L"m_wsCharData; - ws += L"]]>"; - pXMLStream->WriteString(ws, ws.GetLength()); - } break; - case FDE_XMLNODE_Unknown: - break; - default: - break; - } -} -void CFDE_XMLDoc::SaveXML(IFX_Stream* pXMLStream, FX_BOOL bSaveBOM) { - if (pXMLStream == NULL || pXMLStream == m_pStream) { - m_pStream->Seek(FX_STREAMSEEK_Begin, 0); - pXMLStream = m_pStream; - } - FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0); - FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0); - FX_WORD wCodePage = pXMLStream->GetCodePage(); - if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && - wCodePage != FX_CODEPAGE_UTF8) { - wCodePage = FX_CODEPAGE_UTF8; - pXMLStream->SetCodePage(wCodePage); - } - if (bSaveBOM) { - pXMLStream->WriteString(L"\xFEFF", 1); - } - CFDE_XMLNode* pNode = m_pRoot->m_pChild; - while (pNode != NULL) { - SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode); - pNode = pNode->m_pNext; - } - if (pXMLStream == m_pStream) { - int32_t iPos = pXMLStream->GetPosition(); - pXMLStream->SetLength(iPos); - } -} -CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, - IFDE_XMLSyntaxParser* pParser) - : m_pParser(pParser), - m_pParent(pRoot), - m_pChild(NULL), - m_NodeStack(16), - m_ws1(), - m_ws2() { - m_NodeStack.Push(m_pParent); -} -CFDE_XMLDOMParser::~CFDE_XMLDOMParser() { - m_NodeStack.RemoveAll(); - m_ws1.Empty(); - m_ws2.Empty(); -} -int32_t CFDE_XMLDOMParser::DoParser(IFX_Pause* pPause) { - FX_DWORD dwRet; - int32_t iCount = 0; - while (TRUE) { - dwRet = m_pParser->DoSyntaxParse(); - switch (dwRet) { - case FDE_XMLSYNTAXSTATUS_InstructionOpen: - break; - case FDE_XMLSYNTAXSTATUS_InstructionClose: - if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_pChild = m_pParent; - break; - case FDE_XMLSYNTAXSTATUS_ElementOpen: - case FDE_XMLSYNTAXSTATUS_ElementBreak: - break; - case FDE_XMLSYNTAXSTATUS_ElementClose: - if (m_pChild->GetType() != FDE_XMLNODE_Element) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_pParser->GetTagName(m_ws1); - ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2); - if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_NodeStack.Pop(); - if (m_NodeStack.GetSize() < 1) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement(); - m_pChild = m_pParent; - iCount++; - break; - case FDE_XMLSYNTAXSTATUS_TargetName: - m_pParser->GetTargetName(m_ws1); - m_pChild = new CFDE_XMLInstruction(m_ws1); - m_pParent->InsertChildNode(m_pChild); - m_ws1.Empty(); - break; - case FDE_XMLSYNTAXSTATUS_TagName: - m_pParser->GetTagName(m_ws1); - m_pChild = new CFDE_XMLElement(m_ws1); - m_pParent->InsertChildNode(m_pChild); - m_NodeStack.Push(m_pChild); - m_pParent = m_pChild; - break; - case FDE_XMLSYNTAXSTATUS_AttriName: - m_pParser->GetAttributeName(m_ws1); - break; - case FDE_XMLSYNTAXSTATUS_AttriValue: - if (m_pChild == NULL) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_pParser->GetAttributeName(m_ws2); - if (m_pChild->GetType() == FDE_XMLNODE_Element) { - ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2); - } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) { - ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2); - } - m_ws1.Empty(); - break; - case FDE_XMLSYNTAXSTATUS_Text: - m_pParser->GetTextData(m_ws1); - m_pChild = new CFDE_XMLText(m_ws1); - m_pParent->InsertChildNode(m_pChild); - m_pChild = m_pParent; - break; - case FDE_XMLSYNTAXSTATUS_CData: - m_pParser->GetTextData(m_ws1); - m_pChild = new CFDE_XMLCharData(m_ws1); - m_pParent->InsertChildNode(m_pChild); - m_pChild = m_pParent; - break; - case FDE_XMLSYNTAXSTATUS_TargetData: - if (m_pChild == NULL || - m_pChild->GetType() != FDE_XMLNODE_Instruction) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - if (!m_ws1.IsEmpty()) { - ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); - } - m_pParser->GetTargetData(m_ws1); - ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); - m_ws1.Empty(); - break; - default: - break; - } - if (dwRet == FDE_XMLSYNTAXSTATUS_Error || - dwRet == FDE_XMLSYNTAXSTATUS_EOS) { - break; - } - if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { - break; - } - } - return m_pParser->GetStatus(); -} -CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, - IFDE_XMLSyntaxParser* pParser) - : m_pHandler(pHandler), - m_pParser(pParser), - m_TagStack(16), - m_pTagTop(NULL), - m_ws1(), - m_ws2() {} -CFDE_XMLSAXParser::~CFDE_XMLSAXParser() { - m_TagStack.RemoveAll(); - m_ws1.Empty(); - m_ws2.Empty(); -} -int32_t CFDE_XMLSAXParser::DoParser(IFX_Pause* pPause) { - FX_DWORD dwRet = 0; - int32_t iCount = 0; - while (TRUE) { - dwRet = m_pParser->DoSyntaxParse(); - switch (dwRet) { - case FDE_XMLSYNTAXSTATUS_ElementBreak: - if (m_pTagTop == NULL) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - if (m_pTagTop->eType == FDE_XMLNODE_Element) { - m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); - } - break; - case FDE_XMLSYNTAXSTATUS_ElementClose: - if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - m_pParser->GetTagName(m_ws1); - if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } else if (m_ws1.GetLength() == 0) { - m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); - } - m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName); - Pop(); - iCount++; - break; - case FDE_XMLSYNTAXSTATUS_TargetName: { - m_pParser->GetTargetName(m_ws1); - CFDE_XMLTAG xmlTag; - xmlTag.wsTagName = m_ws1; - xmlTag.eType = FDE_XMLNODE_Instruction; - Push(xmlTag); - m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, - m_pTagTop->wsTagName); - m_ws1.Empty(); - } break; - case FDE_XMLSYNTAXSTATUS_TagName: { - m_pParser->GetTargetName(m_ws1); - CFDE_XMLTAG xmlTag; - xmlTag.wsTagName = m_ws1; - xmlTag.eType = FDE_XMLNODE_Element; - Push(xmlTag); - m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, - m_pTagTop->wsTagName); - } break; - case FDE_XMLSYNTAXSTATUS_AttriName: - m_pParser->GetTargetName(m_ws1); - break; - case FDE_XMLSYNTAXSTATUS_AttriValue: - m_pParser->GetAttributeName(m_ws2); - if (m_pTagTop == NULL) { - dwRet = FDE_XMLSYNTAXSTATUS_Error; - break; - } - if (m_pTagTop->eType == FDE_XMLNODE_Element) { - m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2); - } - m_ws1.Empty(); - break; - case FDE_XMLSYNTAXSTATUS_CData: - m_pParser->GetTextData(m_ws1); - m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1); - break; - case FDE_XMLSYNTAXSTATUS_Text: - m_pParser->GetTextData(m_ws1); - m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1); - break; - case FDE_XMLSYNTAXSTATUS_TargetData: - m_pParser->GetTargetData(m_ws1); - m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1); - m_ws1.Empty(); - break; - default: - break; - } - if (dwRet == FDE_XMLSYNTAXSTATUS_Error || - dwRet == FDE_XMLSYNTAXSTATUS_EOS) { - break; - } - if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { - break; - } - } - return m_pParser->GetStatus(); -} -inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { - m_TagStack.Push(xmlTag); - m_pTagTop = m_TagStack.GetTopElement(); -} -inline void CFDE_XMLSAXParser::Pop() { - m_TagStack.Pop(); - m_pTagTop = m_TagStack.GetTopElement(); -} -#ifdef _FDE_BLOCK_BUFFER -CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) - : m_iDataLength(0), - m_iBufferSize(0), - m_iAllocStep(iAllocStep), - m_iStartPosition(0) { -} -CFDE_BlockBuffer::~CFDE_BlockBuffer() { - ClearBuffer(); -} -FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { - iIndexInBlock = 0; - if (!m_BlockArray.GetSize()) { - return nullptr; - } - int32_t iRealIndex = m_iStartPosition + m_iDataLength; - if (iRealIndex == m_iBufferSize) { - FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); - m_BlockArray.Add(pBlock); - m_iBufferSize += m_iAllocStep; - return pBlock; - } - iIndexInBlock = iRealIndex % m_iAllocStep; - return (FX_WCHAR*)m_BlockArray[iRealIndex / m_iAllocStep]; -} -FX_BOOL CFDE_BlockBuffer::InitBuffer(int32_t iBufferSize) { - ClearBuffer(); - int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1; - for (int32_t i = 0; i < iNumOfBlock; i++) { - m_BlockArray.Add(FX_Alloc(FX_WCHAR, m_iAllocStep)); - } - m_iBufferSize = iNumOfBlock * m_iAllocStep; - return TRUE; -} -void CFDE_BlockBuffer::SetTextChar(int32_t iIndex, FX_WCHAR ch) { - if (iIndex < 0) { - return; - } - int32_t iRealIndex = m_iStartPosition + iIndex; - int32_t iBlockIndex = iRealIndex / m_iAllocStep; - int32_t iInnerIndex = iRealIndex % m_iAllocStep; - int32_t iBlockSize = m_BlockArray.GetSize(); - if (iBlockIndex >= iBlockSize) { - int32_t iNewBlocks = iBlockIndex - iBlockSize + 1; - do { - FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); - m_BlockArray.Add(pBlock); - m_iBufferSize += m_iAllocStep; - } while (--iNewBlocks); - } - FX_WCHAR* pTextData = (FX_WCHAR*)m_BlockArray[iBlockIndex]; - *(pTextData + iInnerIndex) = ch; - if (m_iDataLength <= iIndex) { - m_iDataLength = iIndex + 1; - } -} -int32_t CFDE_BlockBuffer::DeleteTextChars(int32_t iCount, FX_BOOL bDirection) { - if (iCount <= 0) { - return m_iDataLength; - } - if (iCount >= m_iDataLength) { - Reset(FALSE); - return 0; - } - if (bDirection) { - m_iStartPosition += iCount; - m_iDataLength -= iCount; - } else { - m_iDataLength -= iCount; - } - return m_iDataLength; -} -void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, - int32_t iStart, - int32_t iLength) const { - wsTextData.Empty(); - int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition; - if (iStart < 0 || iStart > iMaybeDataLength) { - return; - } - if (iLength == -1 || iLength > iMaybeDataLength) { - iLength = iMaybeDataLength; - } - if (iLength <= 0) { - return; - } - FX_WCHAR* pBuf = wsTextData.GetBuffer(iLength); - if (!pBuf) { - return; - } - int32_t iStartBlockIndex = 0; - int32_t iStartInnerIndex = 0; - TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex); - int32_t iEndBlockIndex = 0; - int32_t iEndInnerIndex = 0; - TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex); - int32_t iPointer = 0; - for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) { - int32_t iBufferPointer = 0; - int32_t iCopyLength = m_iAllocStep; - if (i == iStartBlockIndex) { - iCopyLength -= iStartInnerIndex; - iBufferPointer = iStartInnerIndex; - } - if (i == iEndBlockIndex) { - iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex); - } - FX_WCHAR* pBlockBuf = (FX_WCHAR*)m_BlockArray[i]; - FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, - iCopyLength * sizeof(FX_WCHAR)); - iPointer += iCopyLength; - } - wsTextData.ReleaseBuffer(iLength); -} -void CFDE_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex, - int32_t& iBlockIndex, - int32_t& iInnerIndex) const { - FXSYS_assert(iIndex >= 0); - int32_t iRealIndex = m_iStartPosition + iIndex; - iBlockIndex = iRealIndex / m_iAllocStep; - iInnerIndex = iRealIndex % m_iAllocStep; -} -void CFDE_BlockBuffer::ClearBuffer() { - m_iBufferSize = 0; - int32_t iSize = m_BlockArray.GetSize(); - for (int32_t i = 0; i < iSize; i++) { - FX_Free(m_BlockArray[i]); - m_BlockArray[i] = NULL; - } - m_BlockArray.RemoveAll(); -} -#endif -IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { - return new CFDE_XMLSyntaxParser; -} -#ifdef _FDE_BLOCK_BUFFER -CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() - : m_pStream(nullptr), - m_iXMLPlaneSize(-1), - m_iCurrentPos(0), - m_iCurrentNodeNum(-1), - m_iLastNodeNum(-1), - m_iParsedChars(0), - m_iParsedBytes(0), - m_pBuffer(nullptr), - m_iBufferChars(0), - m_bEOS(FALSE), - m_pStart(nullptr), - m_pEnd(nullptr), - m_XMLNodeStack(16), - m_iAllocStep(m_BlockBuffer.GetAllocStep()), - m_iDataLength(m_BlockBuffer.GetDataLengthRef()), - m_pCurrentBlock(nullptr), - m_iIndexInBlock(0), - m_iTextDataLength(0), - m_dwStatus(FDE_XMLSYNTAXSTATUS_None), - m_dwMode(FDE_XMLSYNTAXMODE_Text), - m_wQuotationMark(0), - m_iEntityStart(-1), - m_SkipStack(16) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; -} -void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, - int32_t iXMLPlaneSize, - int32_t iTextDataSize) { - FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); - FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0); - int32_t iStreamLength = pStream->GetLength(); - FXSYS_assert(iStreamLength > 0); - m_pStream = pStream; - m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); - uint8_t bom[4]; - m_iCurrentPos = m_pStream->GetBOM(bom); - FXSYS_assert(m_pBuffer == NULL); - m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); - m_pStart = m_pEnd = m_pBuffer; - FXSYS_assert(!m_BlockBuffer.IsInitialized()); - m_BlockBuffer.InitBuffer(); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_iParsedBytes = m_iParsedChars = 0; - m_iBufferChars = 0; -} -FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { - if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || - m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { - return m_dwStatus; - } - FXSYS_assert(m_pStream && m_pBuffer && m_BlockBuffer.IsInitialized()); - int32_t iStreamLength = m_pStream->GetLength(); - int32_t iPos; - FX_WCHAR ch; - FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; - while (TRUE) { - if (m_pStart >= m_pEnd) { - if (m_bEOS || m_iCurrentPos >= iStreamLength) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; - return m_dwStatus; - } - m_iParsedChars += (m_pEnd - m_pBuffer); - m_iParsedBytes = m_iCurrentPos; - m_pStream->Lock(); - if (m_pStream->GetPosition() != m_iCurrentPos) { - m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); - } - m_iBufferChars = - m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); - iPos = m_pStream->GetPosition(); - m_pStream->Unlock(); - if (m_iBufferChars < 1) { - m_iCurrentPos = iStreamLength; - m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; - return m_dwStatus; - } - m_iCurrentPos = iPos; - m_pStart = m_pBuffer; - m_pEnd = m_pBuffer + m_iBufferChars; - } - while (m_pStart < m_pEnd) { - ch = *m_pStart; - switch (m_dwMode) { - case FDE_XMLSYNTAXMODE_Text: - if (ch == L'<') { - if (m_iDataLength > 0) { - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_iEntityStart = -1; - dwStatus = FDE_XMLSYNTAXSTATUS_Text; - } else { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_Node; - } - } else { - ParseTextChar(ch); - } - break; - case FDE_XMLSYNTAXMODE_Node: - if (ch == L'!') { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; - } else if (ch == L'/') { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; - } else if (ch == L'?') { - m_iLastNodeNum++; - m_iCurrentNodeNum = m_iLastNodeNum; - m_CurNode.iNodeNum = m_iLastNodeNum; - m_CurNode.eNodeType = FDE_XMLNODE_Instruction; - m_XMLNodeStack.Push(m_CurNode); - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_Target; - dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; - } else { - m_iLastNodeNum++; - m_iCurrentNodeNum = m_iLastNodeNum; - m_CurNode.iNodeNum = m_iLastNodeNum; - m_CurNode.eNodeType = FDE_XMLNODE_Element; - m_XMLNodeStack.Push(m_CurNode); - m_dwMode = FDE_XMLSYNTAXMODE_Tag; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; - } - break; - case FDE_XMLSYNTAXMODE_Target: - case FDE_XMLSYNTAXMODE_Tag: - if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { - if (m_iDataLength < 1) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { - dwStatus = FDE_XMLSYNTAXSTATUS_TagName; - } else { - dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; - } - m_dwMode = FDE_XMLSYNTAXMODE_AttriName; - } - } else { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriName: - if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { - if (m_iDataLength < 1) { - if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { - if (ch == L'>' || ch == L'/') { - m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; - break; - } - } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - if (ch == L'?') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; - m_pStart++; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - } - break; - } - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - break; - } - } - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; - dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; - } - } else { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriEqualSign: - if (FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (ch != L'=') { - if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - break; - } - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriQuotation: - if (FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (ch != L'\"' && ch != L'\'') { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_wQuotationMark = ch; - m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriValue: - if (ch == m_wQuotationMark) { - if (m_iEntityStart > -1) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_iTextDataLength = m_iDataLength; - m_wQuotationMark = 0; - m_BlockBuffer.Reset(); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_AttriName; - dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; - } else { - ParseTextChar(ch); - } - break; - case FDE_XMLSYNTAXMODE_CloseInstruction: - if (ch != L'>') { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - } else if (m_iDataLength > 0) { - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - } else { - m_pStart++; - FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_XMLNodeStack.Pop(); - pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; - } else { - m_CurNode = *pXMLNode; - } - m_iCurrentNodeNum = m_CurNode.iNodeNum; - m_BlockBuffer.Reset(); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; - } - break; - case FDE_XMLSYNTAXMODE_BreakElement: - if (ch == L'>') { - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; - } else if (ch == L'/') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; - } else { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_CloseElement: - if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { - if (ch == L'>') { - FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_XMLNodeStack.Pop(); - pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; - } else { - m_CurNode = *pXMLNode; - } - m_iCurrentNodeNum = m_CurNode.iNodeNum; - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; - } else if (!FDE_IsXMLWhiteSpace(ch)) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - } else { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: - if (ch == '-') { - m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; - m_SkipChar = L'>'; - m_SkipStack.Push(L'>'); - } - break; - case FDE_XMLSYNTAXMODE_SkipDeclNode: - if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { - m_pStart++; - if (ch != m_SkipChar) { - break; - } - m_SkipStack.Pop(); - FX_DWORD* pDWord = m_SkipStack.GetTopElement(); - if (pDWord == NULL) { - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } else { - m_SkipChar = (FX_WCHAR)*pDWord; - } - } else { - switch (ch) { - case L'<': - m_SkipChar = L'>'; - m_SkipStack.Push(L'>'); - break; - case L'[': - m_SkipChar = L']'; - m_SkipStack.Push(L']'); - break; - case L'(': - m_SkipChar = L')'; - m_SkipStack.Push(L')'); - break; - case L'\'': - m_SkipChar = L'\''; - m_SkipStack.Push(L'\''); - break; - case L'\"': - m_SkipChar = L'\"'; - m_SkipStack.Push(L'\"'); - break; - default: - if (ch == m_SkipChar) { - m_SkipStack.Pop(); - FX_DWORD* pDWord = m_SkipStack.GetTopElement(); - if (pDWord == NULL) { - if (m_iDataLength >= 9) { - CFX_WideString wsHeader; - m_BlockBuffer.GetTextData(wsHeader, 0, 7); - if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) { - CFX_WideString wsTailer; - m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, - 2); - if (wsTailer.Equal(FX_WSTRC(L"]]"))) { - m_BlockBuffer.DeleteTextChars(7, TRUE); - m_BlockBuffer.DeleteTextChars(2, FALSE); - dwStatus = FDE_XMLSYNTAXSTATUS_CData; - } - } - } - m_iTextDataLength = m_iDataLength; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } else { - m_SkipChar = (FX_WCHAR)*pDWord; - } - } - break; - } - if (m_SkipStack.GetSize() > 0) { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - } - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_SkipComment: - if (ch == L'-') { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = L'-'; - m_iDataLength++; - } else if (ch == L'>') { - if (m_iDataLength > 1) { - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } - } else { - m_BlockBuffer.Reset(); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_TargetData: - if (FDE_IsXMLWhiteSpace(ch)) { - if (m_iDataLength < 1) { - m_pStart++; - break; - } else if (m_wQuotationMark == 0) { - m_iTextDataLength = m_iDataLength; - m_wQuotationMark = 0; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_pStart++; - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - break; - } - } - if (ch == '?') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; - m_pStart++; - } else if (ch == '\"') { - if (m_wQuotationMark == 0) { - m_wQuotationMark = ch; - m_pStart++; - } else if (ch == m_wQuotationMark) { - m_iTextDataLength = m_iDataLength; - m_wQuotationMark = 0; - m_BlockBuffer.Reset(); - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_pStart++; - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - } else { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - } else { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = - m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return FDE_XMLSYNTAXSTATUS_Error; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - m_pStart++; - } - break; - default: - break; - } - if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { - return dwStatus; - } - } - } - return 0; -} -#else -CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() - : m_pStream(NULL), - m_iXMLPlaneSize(-1), - m_iTextDataSize(256), - m_iCurrentPos(0), - m_iCurrentNodeNum(-1), - m_iLastNodeNum(-1), - m_iParsedChars(0), - m_iParsedBytes(0), - m_pBuffer(NULL), - m_iBufferChars(0), - m_bEOS(FALSE), - m_pStart(NULL), - m_pEnd(NULL), - m_XMLNodeStack(16), - m_pwsTextData(NULL), - m_iDataPos(0), - m_dwStatus(FDE_XMLSYNTAXSTATUS_None), - m_dwMode(FDE_XMLSYNTAXMODE_Text), - m_wQuotationMark(0), - m_iTextDataLength(0), - m_iEntityStart(-1), - m_SkipStack(16) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; -} -void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, - int32_t iXMLPlaneSize, - int32_t iTextDataSize) { - FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); - FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0); - int32_t iStreamLength = pStream->GetLength(); - FXSYS_assert(iStreamLength > 0); - m_pStream = pStream; - m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); - m_iTextDataSize = iTextDataSize; - uint8_t bom[4]; - m_iCurrentPos = m_pStream->GetBOM(bom); - FXSYS_assert(m_pBuffer == NULL); - m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); - m_pStart = m_pEnd = m_pBuffer; - FXSYS_assert(m_pwsTextData == NULL); - m_pwsTextData = FX_Alloc(FX_WCHAR, m_iTextDataSize); - m_iParsedBytes = 0; - m_iParsedChars = 0; - m_iBufferChars = 0; -} -FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { - if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || - m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { - return m_dwStatus; - } - FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL); - int32_t iStreamLength = m_pStream->GetLength(); - int32_t iPos; - FX_WCHAR ch; - FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; - while (TRUE) { - if (m_pStart >= m_pEnd) { - if (m_bEOS || m_iCurrentPos >= iStreamLength) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; - return m_dwStatus; - } - m_iParsedChars += (m_pEnd - m_pBuffer); - m_iParsedBytes = m_iCurrentPos; - m_pStream->Lock(); - if (m_pStream->GetPosition() != m_iCurrentPos) { - m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); - } - m_iBufferChars = - m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); - iPos = m_pStream->GetPosition(); - m_pStream->Unlock(); - if (m_iBufferChars < 1) { - m_iCurrentPos = iStreamLength; - m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; - return m_dwStatus; - } - m_iCurrentPos = iPos; - m_pStart = m_pBuffer; - m_pEnd = m_pBuffer + m_iBufferChars; - } - while (m_pStart < m_pEnd) { - ch = *m_pStart; - switch (m_dwMode) { - case FDE_XMLSYNTAXMODE_Text: - if (ch == L'<') { - if (m_iDataPos > 0) { - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - m_iEntityStart = -1; - dwStatus = FDE_XMLSYNTAXSTATUS_Text; - } else { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_Node; - } - } else { - ParseTextChar(ch); - } - break; - case FDE_XMLSYNTAXMODE_Node: - if (ch == L'!') { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; - } else if (ch == L'/') { - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; - } else if (ch == L'?') { - m_iLastNodeNum++; - m_iCurrentNodeNum = m_iLastNodeNum; - m_CurNode.iNodeNum = m_iLastNodeNum; - m_CurNode.eNodeType = FDE_XMLNODE_Instruction; - m_XMLNodeStack.Push(m_CurNode); - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_Target; - dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; - } else { - m_iLastNodeNum++; - m_iCurrentNodeNum = m_iLastNodeNum; - m_CurNode.iNodeNum = m_iLastNodeNum; - m_CurNode.eNodeType = FDE_XMLNODE_Element; - m_XMLNodeStack.Push(m_CurNode); - m_dwMode = FDE_XMLSYNTAXMODE_Tag; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; - } - break; - case FDE_XMLSYNTAXMODE_Target: - case FDE_XMLSYNTAXMODE_Tag: - if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { - if (m_iDataPos < 1) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { - dwStatus = FDE_XMLSYNTAXSTATUS_TagName; - } else { - dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; - } - m_dwMode = FDE_XMLSYNTAXMODE_AttriName; - } - } else { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriName: - if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { - if (m_iDataPos < 1) { - if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { - if (ch == L'>' || ch == L'/') { - m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; - break; - } - } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - if (ch == L'?') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; - m_pStart++; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - } - break; - } - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - break; - } - } - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; - dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; - } - } else { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriEqualSign: - if (FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (ch != L'=') { - if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - break; - } - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriQuotation: - if (FDE_IsXMLWhiteSpace(ch)) { - m_pStart++; - break; - } - if (ch != L'\"' && ch != L'\'') { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } else { - m_wQuotationMark = ch; - m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_AttriValue: - if (ch == m_wQuotationMark) { - if (m_iEntityStart > -1) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_iTextDataLength = m_iDataPos; - m_wQuotationMark = 0; - m_iDataPos = 0; - m_pStart++; - m_dwMode = FDE_XMLSYNTAXMODE_AttriName; - dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; - } else { - ParseTextChar(ch); - } - break; - case FDE_XMLSYNTAXMODE_CloseInstruction: - if (ch != L'>') { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - m_dwMode = FDE_XMLSYNTAXMODE_TargetData; - } else if (m_iDataPos > 0) { - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - } else { - m_pStart++; - FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_XMLNodeStack.Pop(); - pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; - } else { - m_CurNode = *pXMLNode; - } - m_iCurrentNodeNum = m_CurNode.iNodeNum; - m_iDataPos = 0; - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; - } - break; - case FDE_XMLSYNTAXMODE_BreakElement: - if (ch == L'>') { - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; - } else if (ch == L'/') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; - } else { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_CloseElement: - if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { - if (ch == L'>') { - FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - m_XMLNodeStack.Pop(); - pXMLNode = m_XMLNodeStack.GetTopElement(); - if (pXMLNode == NULL) { - m_CurNode.iNodeNum = -1; - m_CurNode.eNodeType = FDE_XMLNODE_Unknown; - } else { - m_CurNode = *pXMLNode; - } - m_iCurrentNodeNum = m_CurNode.iNodeNum; - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - m_dwMode = FDE_XMLSYNTAXMODE_Text; - dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; - } else if (!FDE_IsXMLWhiteSpace(ch)) { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - } else { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: - if (ch == '-') { - m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; - } else { - m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; - m_SkipChar = L'>'; - m_SkipStack.Push(L'>'); - } - break; - case FDE_XMLSYNTAXMODE_SkipDeclNode: - if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { - m_pStart++; - if (ch != m_SkipChar) { - break; - } - m_SkipStack.Pop(); - FX_DWORD* pDWord = m_SkipStack.GetTopElement(); - if (pDWord == NULL) { - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } else { - m_SkipChar = (FX_WCHAR)*pDWord; - } - } else { - switch (ch) { - case L'<': - m_SkipChar = L'>'; - m_SkipStack.Push(L'>'); - break; - case L'[': - m_SkipChar = L']'; - m_SkipStack.Push(L']'); - break; - case L'(': - m_SkipChar = L')'; - m_SkipStack.Push(L')'); - break; - case L'\'': - m_SkipChar = L'\''; - m_SkipStack.Push(L'\''); - break; - case L'\"': - m_SkipChar = L'\"'; - m_SkipStack.Push(L'\"'); - break; - default: - if (ch == m_SkipChar) { - m_SkipStack.Pop(); - FX_DWORD* pDWord = m_SkipStack.GetTopElement(); - if (pDWord == NULL) { - m_iTextDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_iTextDataLength >= 9 && - FXSYS_memcmp(m_pwsTextData, L"[CDATA[", - 7 * sizeof(FX_WCHAR)) == 0 && - FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, - L"]]", 2 * sizeof(FX_WCHAR)) == 0) { - m_iTextDataLength -= 9; - FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, - m_iTextDataLength * sizeof(FX_WCHAR)); - dwStatus = FDE_XMLSYNTAXSTATUS_CData; - } - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } else { - m_SkipChar = (FX_WCHAR)*pDWord; - } - } - break; - } - if (m_SkipStack.GetSize() > 0) { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - } - m_pStart++; - } - break; - case FDE_XMLSYNTAXMODE_SkipComment: - if (ch == L'-') { - m_iDataPos++; - } else if (ch == L'>') { - if (m_iDataPos > 1) { - m_iDataPos = 0; - m_dwMode = FDE_XMLSYNTAXMODE_Text; - } - } else { - m_iDataPos = 0; - } - m_pStart++; - break; - case FDE_XMLSYNTAXMODE_TargetData: - if (FDE_IsXMLWhiteSpace(ch)) { - if (m_iDataPos < 1) { - m_pStart++; - break; - } else if (m_wQuotationMark == 0) { - m_iTextDataLength = m_iDataPos; - m_wQuotationMark = 0; - m_iDataPos = 0; - m_pStart++; - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - break; - } - } - if (ch == '?') { - m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; - m_pStart++; - } else if (ch == '\"') { - if (m_wQuotationMark == 0) { - m_wQuotationMark = ch; - m_pStart++; - } else if (ch == m_wQuotationMark) { - m_iTextDataLength = m_iDataPos; - m_wQuotationMark = 0; - m_iDataPos = 0; - m_pStart++; - dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; - } else { - m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; - return m_dwStatus; - } - } else { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos++] = ch; - m_pStart++; - } - break; - default: - break; - } - if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { - return dwStatus; - } - } - } - return 0; -} -#endif -CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { -#ifdef _FDE_BLOCK_BUFFER - if (m_pCurrentBlock) { - m_pCurrentBlock = NULL; - } -#else - FX_Free(m_pwsTextData); -#endif - FX_Free(m_pBuffer); -} -int32_t CFDE_XMLSyntaxParser::GetStatus() const { - if (m_pStream == NULL) { - return -1; - } - int32_t iStreamLength = m_pStream->GetLength(); - if (iStreamLength < 1) { - return 100; - } - if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { - return -1; - } - if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { - return 100; - } - return m_iParsedBytes * 100 / iStreamLength; -} -static int32_t FX_GetUTF8EncodeLength(const FX_WCHAR* pSrc, int32_t iSrcLen) { - FX_DWORD unicode = 0; - int32_t iDstNum = 0; - while (iSrcLen-- > 0) { - unicode = *pSrc++; - int nbytes = 0; - if ((FX_DWORD)unicode < 0x80) { - nbytes = 1; - } else if ((FX_DWORD)unicode < 0x800) { - nbytes = 2; - } else if ((FX_DWORD)unicode < 0x10000) { - nbytes = 3; - } else if ((FX_DWORD)unicode < 0x200000) { - nbytes = 4; - } else if ((FX_DWORD)unicode < 0x4000000) { - nbytes = 5; - } else { - nbytes = 6; - } - iDstNum += nbytes; - } - return iDstNum; -} -FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { - if (m_pStream == NULL) { - return 0; - } - int32_t nSrcLen = m_pStart - m_pBuffer; - int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); - return m_iParsedBytes + nDstLen; -} -#ifdef _FDE_BLOCK_BUFFER -void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { - if (m_iIndexInBlock == m_iAllocStep) { - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - if (!m_pCurrentBlock) { - return; - } - } - m_pCurrentBlock[m_iIndexInBlock++] = ch; - m_iDataLength++; - if (m_iEntityStart > -1 && ch == L';') { - CFX_WideString csEntity; - m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, - (m_iDataLength - 1) - m_iEntityStart - 1); - int32_t iLen = csEntity.GetLength(); - if (iLen > 0) { - if (csEntity[0] == L'#') { - ch = 0; - FX_WCHAR w; - if (iLen > 1 && csEntity[1] == L'x') { - for (int32_t i = 2; i < iLen; i++) { - w = csEntity[i]; - if (w >= L'0' && w <= L'9') { - ch = (ch << 4) + w - L'0'; - } else if (w >= L'A' && w <= L'F') { - ch = (ch << 4) + w - 55; - } else if (w >= L'a' && w <= L'f') { - ch = (ch << 4) + w - 87; - } else { - break; - } - } - } else { - for (int32_t i = 1; i < iLen; i++) { - w = csEntity[i]; - if (w < L'0' || w > L'9') { - break; - } - ch = ch * 10 + w - L'0'; - } - } - if (ch != 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, ch); - m_iEntityStart++; - } - } else { - if (csEntity.Compare(L"amp") == 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, L'&'); - m_iEntityStart++; - } else if (csEntity.Compare(L"lt") == 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, L'<'); - m_iEntityStart++; - } else if (csEntity.Compare(L"gt") == 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, L'>'); - m_iEntityStart++; - } else if (csEntity.Compare(L"apos") == 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, L'\''); - m_iEntityStart++; - } else if (csEntity.Compare(L"quot") == 0) { - m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"'); - m_iEntityStart++; - } - } - } - m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); - m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); - m_iEntityStart = -1; - } else { - if (m_iEntityStart < 0 && ch == L'&') { - m_iEntityStart = m_iDataLength - 1; - } - } - m_pStart++; -} -#else -void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { - if (m_iDataPos >= m_iTextDataSize) { - ReallocTextDataBuffer(); - } - m_pwsTextData[m_iDataPos] = ch; - if (m_iEntityStart > -1 && ch == L';') { - CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, - m_iDataPos - m_iEntityStart - 1); - int32_t iLen = csEntity.GetLength(); - if (iLen > 0) { - if (csEntity[0] == L'#') { - ch = 0; - FX_WCHAR w; - if (iLen > 1 && csEntity[1] == L'x') { - for (int32_t i = 2; i < iLen; i++) { - w = csEntity[i]; - if (w >= L'0' && w <= L'9') { - ch = (ch << 4) + w - L'0'; - } else if (w >= L'A' && w <= L'F') { - ch = (ch << 4) + w - 55; - } else if (w >= L'a' && w <= L'f') { - ch = (ch << 4) + w - 87; - } else { - break; - } - } - } else { - for (int32_t i = 1; i < iLen; i++) { - w = csEntity[i]; - if (w < L'0' || w > L'9') { - break; - } - ch = ch * 10 + w - L'0'; - } - } - if (ch != 0) { - m_pwsTextData[m_iEntityStart++] = ch; - } - } else { - if (csEntity.Compare(L"amp") == 0) { - m_pwsTextData[m_iEntityStart++] = L'&'; - } else if (csEntity.Compare(L"lt") == 0) { - m_pwsTextData[m_iEntityStart++] = L'<'; - } else if (csEntity.Compare(L"gt") == 0) { - m_pwsTextData[m_iEntityStart++] = L'>'; - } else if (csEntity.Compare(L"apos") == 0) { - m_pwsTextData[m_iEntityStart++] = L'\''; - } else if (csEntity.Compare(L"quot") == 0) { - m_pwsTextData[m_iEntityStart++] = L'\"'; - } - } - } - m_iDataPos = m_iEntityStart; - m_iEntityStart = -1; - } else { - if (m_iEntityStart < 0 && ch == L'&') { - m_iEntityStart = m_iDataPos; - } - m_iDataPos++; - } - m_pStart++; -} -void CFDE_XMLSyntaxParser::ReallocTextDataBuffer() { - FXSYS_assert(m_pwsTextData != NULL); - if (m_iTextDataSize <= 1024 * 1024) { - m_iTextDataSize *= 2; - } else { - m_iTextDataSize += 1024 * 1024; - } - m_pwsTextData = FX_Realloc(FX_WCHAR, m_pwsTextData, m_iTextDataSize); -} -void CFDE_XMLSyntaxParser::GetData(CFX_WideString& wsData) const { - FX_WCHAR* pBuf = wsData.GetBuffer(m_iTextDataLength); - FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR)); - wsData.ReleaseBuffer(m_iTextDataLength); -} -#endif diff --git a/xfa/src/fdp/src/xml/fde_xml.h b/xfa/src/fdp/src/xml/fde_xml.h deleted file mode 100644 index fb5ea6f44b..0000000000 --- a/xfa/src/fdp/src/xml/fde_xml.h +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef _FDE_XML_IMP -#define _FDE_XML_IMP -#define _FDE_BLOCK_BUFFER -#ifdef _FDE_BLOCK_BUFFER -class CFDE_BlockBuffer; -#endif -class CFDE_XMLNode; -class CFDE_XMLInstruction; -class CFDE_XMLElement; -class CFDE_XMLText; -class CFDE_XMLDoc; -class IFDE_XMLParser; -class CFDE_XMLDOMParser; -class CFDE_XMLSAXParser; -class CFDE_XMLSyntaxParser; -class CFDE_XMLNode : public CFX_Target { - public: - CFDE_XMLNode(); - virtual void Release() { delete this; } - virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Unknown; } - virtual int32_t CountChildNodes() const; - virtual CFDE_XMLNode* GetChildNode(int32_t index) const; - virtual int32_t GetChildNodeIndex(CFDE_XMLNode* pNode) const; - virtual CFDE_XMLNode* GetPath(const FX_WCHAR* pPath, - int32_t iLength = -1, - FX_BOOL bQualifiedName = TRUE) const; - virtual int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1); - virtual void RemoveChildNode(CFDE_XMLNode* pNode); - virtual void DeleteChildren(); - virtual CFDE_XMLNode* GetNodeItem(IFDE_XMLNode::NodeItem eItem) const; - virtual int32_t GetNodeLevel() const; - virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, - CFDE_XMLNode* pNode); - virtual CFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem); - virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); - virtual void SaveXMLNode(IFX_Stream* pXMLStream); - - public: - ~CFDE_XMLNode(); - void CloneChildren(CFDE_XMLNode* pClone); - CFDE_XMLNode* m_pParent; - CFDE_XMLNode* m_pChild; - CFDE_XMLNode* m_pPrior; - CFDE_XMLNode* m_pNext; -}; -class CFDE_XMLInstruction : public CFDE_XMLNode { - public: - CFDE_XMLInstruction(const CFX_WideString& wsTarget); - virtual void Release() { delete this; } - virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Instruction; } - virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); - virtual void GetTargetName(CFX_WideString& wsTarget) const { - wsTarget = m_wsTarget; - } - virtual int32_t CountAttributes() const; - virtual FX_BOOL GetAttribute(int32_t index, - CFX_WideString& wsAttriName, - CFX_WideString& wsAttriValue) const; - virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const; - virtual void GetString(const FX_WCHAR* pwsAttriName, - CFX_WideString& wsAttriValue, - const FX_WCHAR* pwsDefValue = NULL) const; - virtual void SetString(const CFX_WideString& wsAttriName, - const CFX_WideString& wsAttriValue); - virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName, - int32_t iDefValue = 0) const; - virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue); - virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fDefValue = 0) const; - virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue); - virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName); - virtual int32_t CountData() const; - virtual FX_BOOL GetData(int32_t index, CFX_WideString& wsData) const; - virtual void AppendData(const CFX_WideString& wsData); - virtual void RemoveData(int32_t index); - - public: - ~CFDE_XMLInstruction() {} - CFX_WideString m_wsTarget; - CFX_WideStringArray m_Attributes; - CFX_WideStringArray m_TargetData; -}; -class CFDE_XMLElement : public CFDE_XMLNode { - public: - CFDE_XMLElement(const CFX_WideString& wsTag); - virtual void Release() { delete this; } - virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Element; } - virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); - virtual void GetTagName(CFX_WideString& wsTag) const; - virtual void GetLocalTagName(CFX_WideString& wsTag) const; - virtual void GetNamespacePrefix(CFX_WideString& wsPrefix) const; - virtual void GetNamespaceURI(CFX_WideString& wsNamespace) const; - virtual int32_t CountAttributes() const; - virtual FX_BOOL GetAttribute(int32_t index, - CFX_WideString& wsAttriName, - CFX_WideString& wsAttriValue) const; - virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const; - virtual void GetString(const FX_WCHAR* pwsAttriName, - CFX_WideString& wsAttriValue, - const FX_WCHAR* pwsDefValue = NULL) const; - virtual void SetString(const CFX_WideString& wsAttriName, - const CFX_WideString& wsAttriValue); - virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName, - int32_t iDefValue = 0) const; - virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue); - virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, - FX_FLOAT fDefValue = 0) const; - virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue); - virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName); - virtual void GetTextData(CFX_WideString& wsText) const; - virtual void SetTextData(const CFX_WideString& wsText); - - public: - ~CFDE_XMLElement(); - CFX_WideString m_wsTag; - CFX_WideStringArray m_Attributes; -}; -class CFDE_XMLText : public CFDE_XMLNode { - public: - CFDE_XMLText(const CFX_WideString& wsText); - virtual void Release() { delete this; } - virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Text; } - virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); - virtual void GetText(CFX_WideString& wsText) const { wsText = m_wsText; } - virtual void SetText(const CFX_WideString& wsText) { m_wsText = wsText; } - - public: - ~CFDE_XMLText() {} - CFX_WideString m_wsText; -}; -class CFDE_XMLDeclaration : public CFDE_XMLNode { - public: - CFDE_XMLDeclaration() : CFDE_XMLNode() {} -}; -class CFDE_XMLCharData : public CFDE_XMLDeclaration { - public: - CFDE_XMLCharData(const CFX_WideString& wsCData); - - virtual void Release() { delete this; } - virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_CharData; } - virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); - virtual void GetCharData(CFX_WideString& wsCharData) const { - wsCharData = m_wsCharData; - } - virtual void SetCharData(const CFX_WideString& wsCData) { - m_wsCharData = wsCData; - } - - public: - ~CFDE_XMLCharData() {} - - CFX_WideString m_wsCharData; -}; -class CFDE_XMLDoc : public CFX_Target { - public: - CFDE_XMLDoc(); - ~CFDE_XMLDoc(); - virtual void Release() { delete this; } - virtual FX_BOOL LoadXML(IFX_Stream* pXMLStream, - int32_t iXMLPlaneSize = 8192, - int32_t iTextDataSize = 256, - FDE_LPXMLREADERHANDLER pHandler = NULL); - virtual FX_BOOL LoadXML(IFDE_XMLParser* pXMLParser); - virtual int32_t DoLoad(IFX_Pause* pPause = NULL); - virtual void CloseXML(); - virtual CFDE_XMLNode* GetRoot() const { return m_pRoot; } - virtual void SaveXML(IFX_Stream* pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE); - virtual void SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pNode); - - protected: - IFX_Stream* m_pStream; - int32_t m_iStatus; - CFDE_XMLNode* m_pRoot; - IFDE_XMLSyntaxParser* m_pSyntaxParser; - IFDE_XMLParser* m_pXMLParser; - void Reset(FX_BOOL bInitRoot); - void ReleaseParser(); -}; -typedef CFX_StackTemplate CFDE_XMLDOMNodeStack; -class CFDE_XMLDOMParser : public IFDE_XMLParser, public CFX_Target { - public: - CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, IFDE_XMLSyntaxParser* pParser); - ~CFDE_XMLDOMParser(); - - virtual void Release() { delete this; } - virtual int32_t DoParser(IFX_Pause* pPause); - - private: - IFDE_XMLSyntaxParser* m_pParser; - CFDE_XMLNode* m_pParent; - CFDE_XMLNode* m_pChild; - CFDE_XMLDOMNodeStack m_NodeStack; - CFX_WideString m_ws1; - CFX_WideString m_ws2; -}; -class CFDE_XMLTAG : public CFX_Target { - public: - CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {} - CFDE_XMLTAG(const CFDE_XMLTAG& src) - : wsTagName(src.wsTagName), eType(src.eType) {} - CFX_WideString wsTagName; - FDE_XMLNODETYPE eType; -}; -typedef CFX_ObjectStackTemplate CFDE_XMLTagStack; -class CFDE_XMLSAXParser : public IFDE_XMLParser, public CFX_Target { - public: - CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, - IFDE_XMLSyntaxParser* pParser); - ~CFDE_XMLSAXParser(); - - virtual void Release() { delete this; } - virtual int32_t DoParser(IFX_Pause* pPause); - - private: - void Push(const CFDE_XMLTAG& xmlTag); - void Pop(); - FDE_LPXMLREADERHANDLER m_pHandler; - IFDE_XMLSyntaxParser* m_pParser; - CFDE_XMLTagStack m_TagStack; - CFDE_XMLTAG* m_pTagTop; - CFX_WideString m_ws1; - CFX_WideString m_ws2; -}; -#ifdef _FDE_BLOCK_BUFFER -class CFDE_BlockBuffer : public CFX_Target { - public: - CFDE_BlockBuffer(int32_t iAllocStep = 1024 * 1024); - ~CFDE_BlockBuffer(); - - FX_BOOL InitBuffer(int32_t iBufferSize = 1024 * 1024); - FX_BOOL IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; } - void ReleaseBuffer() { delete this; } - FX_WCHAR* GetAvailableBlock(int32_t& iIndexInBlock); - inline int32_t GetAllocStep() const { return m_iAllocStep; } - inline int32_t& GetDataLengthRef() { return m_iDataLength; } - inline void Reset(FX_BOOL bReserveData = TRUE) { - if (!bReserveData) { - m_iStartPosition = 0; - } - m_iDataLength = 0; - } - void SetTextChar(int32_t iIndex, FX_WCHAR ch); - int32_t DeleteTextChars(int32_t iCount, FX_BOOL bDirection = TRUE); - void GetTextData(CFX_WideString& wsTextData, - int32_t iStart = 0, - int32_t iLength = -1) const; - - protected: - inline void TextDataIndex2BufIndex(const int32_t iIndex, - int32_t& iBlockIndex, - int32_t& iInnerIndex) const; - void ClearBuffer(); - CFX_PtrArray m_BlockArray; - int32_t m_iDataLength; - int32_t m_iBufferSize; - int32_t m_iAllocStep; - int32_t m_iStartPosition; -}; -#endif -#define FDE_XMLSYNTAXMODE_Text 0 -#define FDE_XMLSYNTAXMODE_Node 1 -#define FDE_XMLSYNTAXMODE_Target 2 -#define FDE_XMLSYNTAXMODE_Tag 3 -#define FDE_XMLSYNTAXMODE_AttriName 4 -#define FDE_XMLSYNTAXMODE_AttriEqualSign 5 -#define FDE_XMLSYNTAXMODE_AttriQuotation 6 -#define FDE_XMLSYNTAXMODE_AttriValue 7 -#define FDE_XMLSYNTAXMODE_Entity 8 -#define FDE_XMLSYNTAXMODE_EntityDecimal 9 -#define FDE_XMLSYNTAXMODE_EntityHex 10 -#define FDE_XMLSYNTAXMODE_CloseInstruction 11 -#define FDE_XMLSYNTAXMODE_BreakElement 12 -#define FDE_XMLSYNTAXMODE_CloseElement 13 -#define FDE_XMLSYNTAXMODE_SkipDeclNode 14 -#define FDE_XMLSYNTAXMODE_DeclCharData 15 -#define FDE_XMLSYNTAXMODE_SkipComment 16 -#define FDE_XMLSYNTAXMODE_SkipCommentOrDecl 17 -#define FDE_XMLSYNTAXMODE_TargetData 18 -class CFDE_XMLSyntaxParser : public IFDE_XMLSyntaxParser, public CFX_Target { - public: - CFDE_XMLSyntaxParser(); - ~CFDE_XMLSyntaxParser(); - virtual void Release() { delete this; } - virtual void Init(IFX_Stream* pStream, - int32_t iXMLPlaneSize, - int32_t iTextDataSize = 256); - virtual FX_DWORD DoSyntaxParse(); - virtual int32_t GetStatus() const; - virtual int32_t GetCurrentPos() const { - return m_iParsedChars + (m_pStart - m_pBuffer); - } - virtual FX_FILESIZE GetCurrentBinaryPos() const; - virtual int32_t GetCurrentNodeNumber() const { return m_iCurrentNodeNum; } - virtual int32_t GetLastNodeNumber() const { return m_iLastNodeNum; } -#ifdef _FDE_BLOCK_BUFFER - virtual void GetTargetName(CFX_WideString& wsTarget) const { - m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength); - } - virtual void GetTagName(CFX_WideString& wsTag) const { - m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength); - } - virtual void GetAttributeName(CFX_WideString& wsAttriName) const { - m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength); - } - virtual void GetAttributeValue(CFX_WideString& wsAttriValue) const { - m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength); - } - virtual void GetTextData(CFX_WideString& wsText) const { - m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength); - } - virtual void GetTargetData(CFX_WideString& wsData) const { - m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength); - } -#else - virtual void GetTargetName(CFX_WideString& wsTarget) const { - GetData(wsTarget); - } - virtual void GetTagName(CFX_WideString& wsTag) const { GetData(wsTag); } - virtual void GetAttributeName(CFX_WideString& wsAttriName) const { - GetData(wsAttriName); - } - virtual void GetAttributeValue(CFX_WideString& wsAttriValue) const { - GetData(wsAttriValue); - } - virtual void GetTextData(CFX_WideString& wsText) const { GetData(wsText); } - virtual void GetTargetData(CFX_WideString& wsData) const { GetData(wsData); } -#endif - protected: - IFX_Stream* m_pStream; - int32_t m_iXMLPlaneSize; - int32_t m_iCurrentPos; - int32_t m_iCurrentNodeNum; - int32_t m_iLastNodeNum; - int32_t m_iParsedChars; - int32_t m_iParsedBytes; - FX_WCHAR* m_pBuffer; - int32_t m_iBufferChars; - FX_BOOL m_bEOS; - FX_WCHAR* m_pStart; - FX_WCHAR* m_pEnd; - FDE_XMLNODE m_CurNode; - CFDE_XMLNodeStack m_XMLNodeStack; -#ifdef _FDE_BLOCK_BUFFER - CFDE_BlockBuffer m_BlockBuffer; - int32_t m_iAllocStep; - int32_t& m_iDataLength; - FX_WCHAR* m_pCurrentBlock; - int32_t m_iIndexInBlock; -#else - int32_t m_iTextDataSize; - FX_WCHAR* m_pwsTextData; - int32_t m_iDataPos; -#endif - int32_t m_iTextDataLength; - FX_DWORD m_dwStatus; - FX_DWORD m_dwMode; - FX_WCHAR m_wQuotationMark; - int32_t m_iEntityStart; - CFX_DWordStack m_SkipStack; - FX_WCHAR m_SkipChar; - inline void ParseTextChar(FX_WCHAR ch); -#ifndef _FDE_BLOCK_BUFFER - void ReallocTextDataBuffer(); - void GetData(CFX_WideString& wsData) const; -#endif -}; -#endif diff --git a/xfa/src/fdp/src/xml/fde_xml_imp.cpp b/xfa/src/fdp/src/xml/fde_xml_imp.cpp new file mode 100644 index 0000000000..6961aba6f8 --- /dev/null +++ b/xfa/src/fdp/src/xml/fde_xml_imp.cpp @@ -0,0 +1,2637 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include + +#include "xfa/src/foxitlib.h" +#include "fde_xml_imp.h" +#ifdef __cplusplus +extern "C" { +#endif +#define FDE_XMLVALIDCHARRANGENUM 5 +static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { + {0x09, 0x09}, + {0x0A, 0x0A}, + {0x0D, 0x0D}, + {0x20, 0xD7FF}, + {0xE000, 0xFFFD}}; +FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { + int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; + while (iStart <= iEnd) { + iMid = (iStart + iEnd) / 2; + if (ch < g_XMLValidCharRange[iMid][0]) { + iEnd = iMid - 1; + } else if (ch > g_XMLValidCharRange[iMid][1]) { + iStart = iMid + 1; + } else { + return TRUE; + } + } + return FALSE; +} +FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch) { + return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09; +} +typedef struct _FDE_XMLNAMECHAR { + FX_WCHAR wStart; + FX_WCHAR wEnd; + FX_BOOL bStartChar; +} FDE_XMLNAMECHAR; +#define FDE_XMLNAMECHARSNUM 20 +static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = { + {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, + {L'A', L'Z', TRUE}, {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, + {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE}, {0xD8, 0xF6, TRUE}, + {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE}, + {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, + {0x2070, 0x218F, TRUE}, {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, + {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE}, +}; +FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar) { + int32_t iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid; + while (iStart <= iEnd) { + iMid = (iStart + iEnd) / 2; + if (ch < g_XMLNameChars[iMid].wStart) { + iEnd = iMid - 1; + } else if (ch > g_XMLNameChars[iMid].wEnd) { + iStart = iMid + 1; + } else { + if (bFirstChar) { + return g_XMLNameChars[iMid].bStartChar; + } + return TRUE; + } + } + return FALSE; +} +#ifdef __cplusplus +} +#endif +CFDE_XMLNode::CFDE_XMLNode() + : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} +CFDE_XMLNode::~CFDE_XMLNode() { + DeleteChildren(); +} +void CFDE_XMLNode::DeleteChildren() { + CFDE_XMLNode *pChild = m_pChild, *pTemp; + while (pChild != NULL) { + pTemp = pChild->m_pNext; + pChild->Release(); + pChild = pTemp; + } + m_pChild = NULL; +} +int32_t CFDE_XMLNode::CountChildNodes() const { + int32_t iCount = 0; + CFDE_XMLNode* pChild = m_pChild; + while (pChild != NULL) { + iCount++; + pChild = pChild->m_pNext; + } + return iCount; +} +CFDE_XMLNode* CFDE_XMLNode::GetChildNode(int32_t index) const { + CFDE_XMLNode* pChild = m_pChild; + while (pChild != NULL) { + if (index == 0) { + return pChild; + } + index--; + pChild = pChild->m_pNext; + } + return NULL; +} +int32_t CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode* pNode) const { + int32_t index = 0; + CFDE_XMLNode* pChild = m_pChild; + while (pChild != NULL) { + if (pChild == pNode) { + return index; + } + index++; + pChild = pChild->m_pNext; + } + return -1; +} +CFDE_XMLNode* CFDE_XMLNode::GetPath(const FX_WCHAR* pPath, + int32_t iLength, + FX_BOOL bQualifiedName) const { + FXSYS_assert(pPath != NULL); + if (iLength < 0) { + iLength = FXSYS_wcslen(pPath); + } + if (iLength == 0) { + return NULL; + } + CFX_WideString csPath; + const FX_WCHAR* pStart = pPath; + const FX_WCHAR* pEnd = pPath + iLength; + FX_WCHAR ch; + while (pStart < pEnd) { + ch = *pStart++; + if (ch == L'/') { + break; + } else { + csPath += ch; + } + } + iLength -= pStart - pPath; + CFDE_XMLNode* pFind = NULL; + if (csPath.GetLength() < 1) { + pFind = GetNodeItem(IFDE_XMLNode::Root); + } else if (csPath.Compare(L"..") == 0) { + pFind = m_pParent; + } else if (csPath.Compare(L".") == 0) { + pFind = (CFDE_XMLNode*)this; + } else { + CFX_WideString wsTag; + CFDE_XMLNode* pNode = m_pChild; + while (pNode != NULL) { + if (pNode->GetType() == FDE_XMLNODE_Element) { + if (bQualifiedName) { + ((CFDE_XMLElement*)pNode)->GetTagName(wsTag); + } else { + ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag); + } + if (wsTag.Compare(csPath) == 0) { + if (iLength < 1) { + pFind = pNode; + } else { + pFind = pNode->GetPath(pStart, iLength, bQualifiedName); + } + if (pFind != NULL) { + return pFind; + } + } + } + pNode = pNode->m_pNext; + } + } + if (pFind == NULL || iLength < 1) { + return pFind; + } + return pFind->GetPath(pStart, iLength, bQualifiedName); +} +int32_t CFDE_XMLNode::InsertChildNode(CFDE_XMLNode* pNode, int32_t index) { + FXSYS_assert(pNode != NULL); + pNode->m_pParent = this; + if (m_pChild == NULL) { + m_pChild = pNode; + pNode->m_pPrior = NULL; + pNode->m_pNext = NULL; + return 0; + } else if (index == 0) { + pNode->m_pNext = m_pChild; + pNode->m_pPrior = NULL; + m_pChild->m_pPrior = pNode; + m_pChild = pNode; + return 0; + } + int32_t iCount = 0; + CFDE_XMLNode* pFind = m_pChild; + while (++iCount != index && pFind->m_pNext != NULL) { + pFind = pFind->m_pNext; + } + pNode->m_pPrior = pFind; + pNode->m_pNext = pFind->m_pNext; + if (pFind->m_pNext != NULL) { + pFind->m_pNext->m_pPrior = pNode; + } + pFind->m_pNext = pNode; + return iCount; +} +void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode* pNode) { + FXSYS_assert(m_pChild != NULL && pNode != NULL); + if (m_pChild == pNode) { + m_pChild = pNode->m_pNext; + } else { + pNode->m_pPrior->m_pNext = pNode->m_pNext; + } + if (pNode->m_pNext != NULL) { + pNode->m_pNext->m_pPrior = pNode->m_pPrior; + } + pNode->m_pParent = NULL; + pNode->m_pNext = NULL; + pNode->m_pPrior = NULL; +} +CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const { + switch (eItem) { + case IFDE_XMLNode::Root: { + CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; + while (pParent->m_pParent != NULL) { + pParent = pParent->m_pParent; + } + return pParent; + } + case IFDE_XMLNode::Parent: + return m_pParent; + case IFDE_XMLNode::FirstSibling: { + CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; + while (pItem->m_pPrior != NULL) { + pItem = pItem->m_pPrior; + } + return pItem == (CFDE_XMLNode*)this ? NULL : pItem; + } + case IFDE_XMLNode::PriorSibling: + return m_pPrior; + case IFDE_XMLNode::NextSibling: + return m_pNext; + case IFDE_XMLNode::LastSibling: { + CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; + while (pItem->m_pNext != NULL) { + pItem = pItem->m_pNext; + } + return pItem == (CFDE_XMLNode*)this ? NULL : pItem; + } + case IFDE_XMLNode::FirstNeighbor: { + CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; + while (pParent->m_pParent != NULL) { + pParent = pParent->m_pParent; + } + return pParent == (CFDE_XMLNode*)this ? NULL : pParent; + } + case IFDE_XMLNode::PriorNeighbor: { + if (m_pPrior == NULL) { + return m_pParent; + } + CFDE_XMLNode* pItem = m_pPrior; + while (CFDE_XMLNode* pTemp = pItem->m_pChild) { + pItem = pTemp; + while ((pTemp = pItem->m_pNext) != NULL) { + pItem = pTemp; + } + } + return pItem; + } + case IFDE_XMLNode::NextNeighbor: { + if (m_pChild != NULL) { + return m_pChild; + } + if (m_pNext != NULL) { + return m_pNext; + } + CFDE_XMLNode* pItem = m_pParent; + while (pItem != NULL) { + if (pItem->m_pNext != NULL) { + return pItem->m_pNext; + } + pItem = pItem->m_pParent; + } + return NULL; + } + case IFDE_XMLNode::LastNeighbor: { + CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; + while (pItem->m_pParent != NULL) { + pItem = pItem->m_pParent; + } + while (TRUE) { + while (pItem->m_pNext != NULL) { + pItem = pItem->m_pNext; + } + if (pItem->m_pChild == NULL) { + break; + } + pItem = pItem->m_pChild; + } + return pItem == (CFDE_XMLNode*)this ? NULL : pItem; + } + case IFDE_XMLNode::FirstChild: + return m_pChild; + case IFDE_XMLNode::LastChild: { + if (m_pChild == NULL) { + return NULL; + } + CFDE_XMLNode* pChild = m_pChild; + while (pChild->m_pNext != NULL) { + pChild = pChild->m_pNext; + } + return pChild; + } + default: + break; + } + return NULL; +} +int32_t CFDE_XMLNode::GetNodeLevel() const { + int32_t iLevel = 0; + CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; + while ((pItem = pItem->m_pParent) != NULL) { + iLevel++; + } + return iLevel; +} +FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, + CFDE_XMLNode* pNode) { + FXSYS_assert(pNode != NULL); + switch (eItem) { + case IFDE_XMLNode::NextSibling: { + pNode->m_pParent = m_pParent; + pNode->m_pNext = m_pNext; + pNode->m_pPrior = this; + if (m_pNext) { + m_pNext->m_pPrior = pNode; + } + m_pNext = pNode; + return TRUE; + } + case IFDE_XMLNode::PriorSibling: { + pNode->m_pParent = m_pParent; + pNode->m_pNext = this; + pNode->m_pPrior = m_pPrior; + if (m_pPrior) { + m_pPrior->m_pNext = pNode; + } else if (m_pParent) { + m_pParent->m_pChild = pNode; + } + m_pPrior = pNode; + return TRUE; + } + default: + return FALSE; + } + return FALSE; +} +CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) { + CFDE_XMLNode* pNode = NULL; + switch (eItem) { + case IFDE_XMLNode::NextSibling: + if (m_pNext) { + pNode = m_pNext; + m_pNext = pNode->m_pNext; + if (m_pNext) { + m_pNext->m_pPrior = this; + } + pNode->m_pParent = NULL; + pNode->m_pNext = NULL; + pNode->m_pPrior = NULL; + } + break; + default: + break; + } + return pNode; +} +CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive) { + return NULL; +} +void CFDE_XMLNode::SaveXMLNode(IFX_Stream* pXMLStream) { + CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; + FXSYS_assert(pXMLStream != NULL && pNode != NULL); + switch (pNode->GetType()) { + case FDE_XMLNODE_Instruction: { + CFX_WideString ws; + CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; + if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { + ws = L"GetCodePage(); + if (wCodePage == FX_CODEPAGE_UTF16LE) { + ws += L"UTF-16"; + } else if (wCodePage == FX_CODEPAGE_UTF16BE) { + ws += L"UTF-16be"; + } else { + ws += L"UTF-8"; + } + ws += L"\"?>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } else { + ws.Format(L"m_wsTarget); + pXMLStream->WriteString(ws, ws.GetLength()); + CFX_WideStringArray& attributes = pInstruction->m_Attributes; + int32_t i, iCount = attributes.GetSize(); + CFX_WideString wsValue; + for (i = 0; i < iCount; i += 2) { + ws = L" "; + ws += attributes[i]; + ws += L"=\""; + wsValue = attributes[i + 1]; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + CFX_WideStringArray& targetdata = pInstruction->m_TargetData; + iCount = targetdata.GetSize(); + for (i = 0; i < iCount; i++) { + ws = L" \""; + ws += targetdata[i]; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + ws = L"?>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } + } break; + case FDE_XMLNODE_Element: { + CFX_WideString ws; + ws = L"<"; + ws += ((CFDE_XMLElement*)pNode)->m_wsTag; + pXMLStream->WriteString(ws, ws.GetLength()); + CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; + int32_t iCount = attributes.GetSize(); + CFX_WideString wsValue; + for (int32_t i = 0; i < iCount; i += 2) { + ws = L" "; + ws += attributes[i]; + ws += L"=\""; + wsValue = attributes[i + 1]; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + if (pNode->m_pChild == NULL) { + ws = L"\n/>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } else { + ws = L"\n>"; + pXMLStream->WriteString(ws, ws.GetLength()); + CFDE_XMLNode* pChild = pNode->m_pChild; + while (pChild != NULL) { + pChild->SaveXMLNode(pXMLStream); + pChild = pChild->m_pNext; + } + ws = L"m_wsTag; + ws += L"\n>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } + } break; + case FDE_XMLNODE_Text: { + CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; + ws.Replace(L"&", L"&"); + ws.Replace(L"<", L"<"); + ws.Replace(L">", L">"); + ws.Replace(L"\'", L"'"); + ws.Replace(L"\"", L"""); + pXMLStream->WriteString(ws, ws.GetLength()); + } break; + case FDE_XMLNODE_CharData: { + CFX_WideString ws = L"m_wsCharData; + ws += L"]]>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } break; + case FDE_XMLNODE_Unknown: + break; + default: + break; + } +} +void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) { + if (!m_pChild) { + return; + } + CFDE_XMLNode* pNext = m_pChild; + CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE); + pClone->InsertChildNode(pCloneNext); + pNext = pNext->m_pNext; + while (pNext) { + CFDE_XMLNode* pChild = pNext->Clone(TRUE); + pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild); + pCloneNext = pChild; + pNext = pNext->m_pNext; + } +} +IFDE_XMLInstruction* IFDE_XMLInstruction::Create( + const CFX_WideString& wsTarget) { + return (IFDE_XMLInstruction*)new CFDE_XMLInstruction(wsTarget); +} +CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) + : m_wsTarget(wsTarget) { + FXSYS_assert(m_wsTarget.GetLength() > 0); +} +CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive) { + CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget); + if (!pClone) { + return pClone; + } + pClone->m_Attributes.Copy(m_Attributes); + pClone->m_TargetData.Copy(m_TargetData); + if (bRecursive) { + CloneChildren(pClone); + } + return pClone; +} +int32_t CFDE_XMLInstruction::CountAttributes() const { + return m_Attributes.GetSize() / 2; +} +FX_BOOL CFDE_XMLInstruction::GetAttribute(int32_t index, + CFX_WideString& wsAttriName, + CFX_WideString& wsAttriValue) const { + int32_t iCount = m_Attributes.GetSize(); + FXSYS_assert(index > -1 && index < iCount / 2); + for (int32_t i = 0; i < iCount; i += 2) { + if (index == 0) { + wsAttriName = m_Attributes[i]; + wsAttriValue = m_Attributes[i + 1]; + return TRUE; + } + index--; + } + return FALSE; +} +FX_BOOL CFDE_XMLInstruction::HasAttribute(const FX_WCHAR* pwsAttriName) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return TRUE; + } + } + return FALSE; +} +void CFDE_XMLInstruction::GetString(const FX_WCHAR* pwsAttriName, + CFX_WideString& wsAttriValue, + const FX_WCHAR* pwsDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + wsAttriValue = m_Attributes[i + 1]; + return; + } + } + wsAttriValue = pwsDefValue; +} +void CFDE_XMLInstruction::SetString(const CFX_WideString& wsAttriName, + const CFX_WideString& wsAttriValue) { + FXSYS_assert(wsAttriName.GetLength() > 0); + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(wsAttriName) == 0) { + m_Attributes[i] = wsAttriName; + m_Attributes[i + 1] = wsAttriValue; + return; + } + } + m_Attributes.Add(wsAttriName); + m_Attributes.Add(wsAttriValue); +} +int32_t CFDE_XMLInstruction::GetInteger(const FX_WCHAR* pwsAttriName, + int32_t iDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); + } + } + return iDefValue; +} +void CFDE_XMLInstruction::SetInteger(const FX_WCHAR* pwsAttriName, + int32_t iAttriValue) { + CFX_WideString wsValue; + wsValue.Format(L"%d", iAttriValue); + SetString(pwsAttriName, wsValue); +} +FX_FLOAT CFDE_XMLInstruction::GetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); + } + } + return fDefValue; +} +void CFDE_XMLInstruction::SetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fAttriValue) { + CFX_WideString wsValue; + wsValue.Format(L"%f", fAttriValue); + SetString(pwsAttriName, wsValue); +} +void CFDE_XMLInstruction::RemoveAttribute(const FX_WCHAR* pwsAttriName) { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + m_Attributes.RemoveAt(i + 1); + m_Attributes.RemoveAt(i); + return; + } + } +} +int32_t CFDE_XMLInstruction::CountData() const { + return m_TargetData.GetSize(); +} +FX_BOOL CFDE_XMLInstruction::GetData(int32_t index, + CFX_WideString& wsData) const { + if (index < 0 || index >= m_TargetData.GetSize()) { + return FALSE; + } + wsData = m_TargetData[index]; + return TRUE; +} +void CFDE_XMLInstruction::AppendData(const CFX_WideString& wsData) { + m_TargetData.Add(wsData); +} +void CFDE_XMLInstruction::RemoveData(int32_t index) { + m_TargetData.RemoveAt(index); +} +IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString& wsTag) { + return (IFDE_XMLElement*)new CFDE_XMLElement(wsTag); +} +CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) + : CFDE_XMLNode(), m_wsTag(wsTag), m_Attributes() { + FXSYS_assert(m_wsTag.GetLength() > 0); +} +CFDE_XMLElement::~CFDE_XMLElement() { + m_Attributes.RemoveAll(); +} +CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive) { + CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag); + if (!pClone) { + return NULL; + } + pClone->m_Attributes.Copy(m_Attributes); + if (bRecursive) { + CloneChildren(pClone); + } else { + CFX_WideString wsText; + CFDE_XMLNode* pChild = m_pChild; + while (pChild != NULL) { + switch (pChild->GetType()) { + case FDE_XMLNODE_Text: + wsText += ((CFDE_XMLText*)pChild)->m_wsText; + break; + default: + break; + } + pChild = pChild->m_pNext; + } + pClone->SetTextData(wsText); + } + return pClone; +} +void CFDE_XMLElement::GetTagName(CFX_WideString& wsTag) const { + wsTag = m_wsTag; +} +void CFDE_XMLElement::GetLocalTagName(CFX_WideString& wsTag) const { + FX_STRSIZE iFind = m_wsTag.Find(L':', 0); + if (iFind < 0) { + wsTag = m_wsTag; + } else { + wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1); + } +} +void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString& wsPrefix) const { + FX_STRSIZE iFind = m_wsTag.Find(L':', 0); + if (iFind < 0) { + wsPrefix.Empty(); + } else { + wsPrefix = m_wsTag.Left(iFind); + } +} +void CFDE_XMLElement::GetNamespaceURI(CFX_WideString& wsNamespace) const { + CFX_WideString wsAttri(L"xmlns"), wsPrefix; + GetNamespacePrefix(wsPrefix); + if (wsPrefix.GetLength() > 0) { + wsAttri += L":"; + wsAttri += wsPrefix; + } + wsNamespace.Empty(); + CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; + while (pNode != NULL) { + if (pNode->GetType() != FDE_XMLNODE_Element) { + break; + } + CFDE_XMLElement* pElement = (CFDE_XMLElement*)pNode; + if (!pElement->HasAttribute(wsAttri)) { + pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent); + continue; + } + pElement->GetString(wsAttri, wsNamespace); + break; + } +} +int32_t CFDE_XMLElement::CountAttributes() const { + return m_Attributes.GetSize() / 2; +} +FX_BOOL CFDE_XMLElement::GetAttribute(int32_t index, + CFX_WideString& wsAttriName, + CFX_WideString& wsAttriValue) const { + int32_t iCount = m_Attributes.GetSize(); + FXSYS_assert(index > -1 && index < iCount / 2); + for (int32_t i = 0; i < iCount; i += 2) { + if (index == 0) { + wsAttriName = m_Attributes[i]; + wsAttriValue = m_Attributes[i + 1]; + return TRUE; + } + index--; + } + return FALSE; +} +FX_BOOL CFDE_XMLElement::HasAttribute(const FX_WCHAR* pwsAttriName) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return TRUE; + } + } + return FALSE; +} +void CFDE_XMLElement::GetString(const FX_WCHAR* pwsAttriName, + CFX_WideString& wsAttriValue, + const FX_WCHAR* pwsDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + wsAttriValue = m_Attributes[i + 1]; + return; + } + } + wsAttriValue = pwsDefValue; +} +void CFDE_XMLElement::SetString(const CFX_WideString& wsAttriName, + const CFX_WideString& wsAttriValue) { + FXSYS_assert(wsAttriName.GetLength() > 0); + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(wsAttriName) == 0) { + m_Attributes[i] = wsAttriName; + m_Attributes[i + 1] = wsAttriValue; + return; + } + } + m_Attributes.Add(wsAttriName); + m_Attributes.Add(wsAttriValue); +} +int32_t CFDE_XMLElement::GetInteger(const FX_WCHAR* pwsAttriName, + int32_t iDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); + } + } + return iDefValue; +} +void CFDE_XMLElement::SetInteger(const FX_WCHAR* pwsAttriName, + int32_t iAttriValue) { + CFX_WideString wsValue; + wsValue.Format(L"%d", iAttriValue); + SetString(pwsAttriName, wsValue); +} +FX_FLOAT CFDE_XMLElement::GetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fDefValue) const { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); + } + } + return fDefValue; +} +void CFDE_XMLElement::SetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fAttriValue) { + CFX_WideString wsValue; + wsValue.Format(L"%f", fAttriValue); + SetString(pwsAttriName, wsValue); +} +void CFDE_XMLElement::RemoveAttribute(const FX_WCHAR* pwsAttriName) { + int32_t iCount = m_Attributes.GetSize(); + for (int32_t i = 0; i < iCount; i += 2) { + if (m_Attributes[i].Compare(pwsAttriName) == 0) { + m_Attributes.RemoveAt(i + 1); + m_Attributes.RemoveAt(i); + return; + } + } +} +void CFDE_XMLElement::GetTextData(CFX_WideString& wsText) const { + CFX_WideTextBuf buffer; + CFDE_XMLNode* pChild = m_pChild; + while (pChild != NULL) { + switch (pChild->GetType()) { + case FDE_XMLNODE_Text: + buffer << ((CFDE_XMLText*)pChild)->m_wsText; + break; + case FDE_XMLNODE_CharData: + buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData; + break; + default: + break; + } + pChild = pChild->m_pNext; + } + wsText = buffer.GetWideString(); +} +void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { + if (wsText.GetLength() < 1) { + return; + } + InsertChildNode(new CFDE_XMLText(wsText)); +} +IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString& wsText) { + return (IFDE_XMLText*)new CFDE_XMLText(wsText); +} +CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) + : CFDE_XMLNode(), m_wsText(wsText) {} +CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive) { + CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText); + return pClone; +} +IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString& wsCData) { + return (IFDE_XMLCharData*)new CFDE_XMLCharData(wsCData); +} +CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) + : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} +CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive) { + CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData); + return pClone; +} +IFDE_XMLDoc* IFDE_XMLDoc::Create() { + return (IFDE_XMLDoc*)new CFDE_XMLDoc; +} +CFDE_XMLDoc::CFDE_XMLDoc() + : m_pRoot(NULL), m_pSyntaxParser(NULL), m_pXMLParser(NULL) { + Reset(TRUE); + CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); + m_pRoot->InsertChildNode(pXML); +} +CFDE_XMLDoc::~CFDE_XMLDoc() { + Reset(FALSE); +} +void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot) { + m_iStatus = 0; + m_pStream = NULL; + if (bInitRoot) { + if (m_pRoot == NULL) { + m_pRoot = new CFDE_XMLNode; + } else { + m_pRoot->DeleteChildren(); + } + } else { + if (m_pRoot != NULL) { + m_pRoot->Release(); + m_pRoot = NULL; + } + } + ReleaseParser(); +} +void CFDE_XMLDoc::ReleaseParser() { + if (m_pXMLParser != NULL) { + m_pXMLParser->Release(); + m_pXMLParser = NULL; + } + if (m_pSyntaxParser != NULL) { + m_pSyntaxParser->Release(); + m_pSyntaxParser = NULL; + } +} +FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream* pXMLStream, + int32_t iXMLPlaneSize, + int32_t iTextDataSize, + FDE_LPXMLREADERHANDLER pHandler) { + if (pXMLStream == NULL) { + return FALSE; + } + Reset(TRUE); + iXMLPlaneSize = iXMLPlaneSize / 1024; + if (iXMLPlaneSize < 1) { + iXMLPlaneSize = 1; + } + iXMLPlaneSize *= 1024; + if (iXMLPlaneSize < 4096) { + iXMLPlaneSize = 4096; + } + iTextDataSize = iTextDataSize / 128; + if (iTextDataSize < 1) { + iTextDataSize = 1; + } + iTextDataSize *= 128; + if (iTextDataSize < 128) { + iTextDataSize = 128; + } + m_pStream = pXMLStream; + FX_WORD wCodePage = m_pStream->GetCodePage(); + if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && + wCodePage != FX_CODEPAGE_UTF8) { + m_pStream->SetCodePage(FX_CODEPAGE_UTF8); + } + m_pSyntaxParser = IFDE_XMLSyntaxParser::Create(); + if (m_pSyntaxParser == NULL) { + return FALSE; + } + m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize); + if (pHandler == NULL) { + m_pXMLParser = new CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser); + } else { + m_pXMLParser = new CFDE_XMLSAXParser(pHandler, m_pSyntaxParser); + } + return TRUE; +} +FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser* pXMLParser) { + if (pXMLParser == NULL) { + return FALSE; + } + Reset(TRUE); + m_pXMLParser = pXMLParser; + return m_pXMLParser != NULL; +} +int32_t CFDE_XMLDoc::DoLoad(IFX_Pause* pPause) { + if (m_iStatus >= 100) { + return m_iStatus; + } + FXSYS_assert(m_pXMLParser != NULL); + return m_iStatus = m_pXMLParser->DoParser(pPause); +} +void CFDE_XMLDoc::CloseXML() { + ReleaseParser(); +} +void CFDE_XMLDoc::SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pINode) { + CFDE_XMLNode* pNode = (CFDE_XMLNode*)pINode; + FXSYS_assert(pXMLStream != NULL && pNode != NULL); + switch (pNode->GetType()) { + case FDE_XMLNODE_Instruction: { + CFX_WideString ws; + CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; + if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { + ws = L"GetCodePage(); + if (wCodePage == FX_CODEPAGE_UTF16LE) { + ws += L"UTF-16"; + } else if (wCodePage == FX_CODEPAGE_UTF16BE) { + ws += L"UTF-16be"; + } else { + ws += L"UTF-8"; + } + ws += L"\"?>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } else { + ws.Format(L"m_wsTarget); + pXMLStream->WriteString(ws, ws.GetLength()); + CFX_WideStringArray& attributes = pInstruction->m_Attributes; + int32_t i, iCount = attributes.GetSize(); + CFX_WideString wsValue; + for (i = 0; i < iCount; i += 2) { + ws = L" "; + ws += attributes[i]; + ws += L"=\""; + wsValue = attributes[i + 1]; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + CFX_WideStringArray& targetdata = pInstruction->m_TargetData; + iCount = targetdata.GetSize(); + for (i = 0; i < iCount; i++) { + ws = L" \""; + ws += targetdata[i]; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + ws = L"?>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } + } break; + case FDE_XMLNODE_Element: { + CFX_WideString ws; + ws = L"<"; + ws += ((CFDE_XMLElement*)pNode)->m_wsTag; + pXMLStream->WriteString(ws, ws.GetLength()); + CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; + int32_t iCount = attributes.GetSize(); + CFX_WideString wsValue; + for (int32_t i = 0; i < iCount; i += 2) { + ws = L" "; + ws += attributes[i]; + ws += L"=\""; + wsValue = attributes[i + 1]; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws, ws.GetLength()); + } + if (pNode->m_pChild == NULL) { + ws = L"\n/>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } else { + ws = L"\n>"; + pXMLStream->WriteString(ws, ws.GetLength()); + CFDE_XMLNode* pChild = pNode->m_pChild; + while (pChild != NULL) { + SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild); + pChild = pChild->m_pNext; + } + ws = L"m_wsTag; + ws += L"\n>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } + } break; + case FDE_XMLNODE_Text: { + CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; + ws.Replace(L"&", L"&"); + ws.Replace(L"<", L"<"); + ws.Replace(L">", L">"); + ws.Replace(L"\'", L"'"); + ws.Replace(L"\"", L"""); + pXMLStream->WriteString(ws, ws.GetLength()); + } break; + case FDE_XMLNODE_CharData: { + CFX_WideString ws = L"m_wsCharData; + ws += L"]]>"; + pXMLStream->WriteString(ws, ws.GetLength()); + } break; + case FDE_XMLNODE_Unknown: + break; + default: + break; + } +} +void CFDE_XMLDoc::SaveXML(IFX_Stream* pXMLStream, FX_BOOL bSaveBOM) { + if (pXMLStream == NULL || pXMLStream == m_pStream) { + m_pStream->Seek(FX_STREAMSEEK_Begin, 0); + pXMLStream = m_pStream; + } + FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0); + FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0); + FX_WORD wCodePage = pXMLStream->GetCodePage(); + if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && + wCodePage != FX_CODEPAGE_UTF8) { + wCodePage = FX_CODEPAGE_UTF8; + pXMLStream->SetCodePage(wCodePage); + } + if (bSaveBOM) { + pXMLStream->WriteString(L"\xFEFF", 1); + } + CFDE_XMLNode* pNode = m_pRoot->m_pChild; + while (pNode != NULL) { + SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode); + pNode = pNode->m_pNext; + } + if (pXMLStream == m_pStream) { + int32_t iPos = pXMLStream->GetPosition(); + pXMLStream->SetLength(iPos); + } +} +CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, + IFDE_XMLSyntaxParser* pParser) + : m_pParser(pParser), + m_pParent(pRoot), + m_pChild(NULL), + m_NodeStack(16), + m_ws1(), + m_ws2() { + m_NodeStack.Push(m_pParent); +} +CFDE_XMLDOMParser::~CFDE_XMLDOMParser() { + m_NodeStack.RemoveAll(); + m_ws1.Empty(); + m_ws2.Empty(); +} +int32_t CFDE_XMLDOMParser::DoParser(IFX_Pause* pPause) { + FX_DWORD dwRet; + int32_t iCount = 0; + while (TRUE) { + dwRet = m_pParser->DoSyntaxParse(); + switch (dwRet) { + case FDE_XMLSYNTAXSTATUS_InstructionOpen: + break; + case FDE_XMLSYNTAXSTATUS_InstructionClose: + if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_pChild = m_pParent; + break; + case FDE_XMLSYNTAXSTATUS_ElementOpen: + case FDE_XMLSYNTAXSTATUS_ElementBreak: + break; + case FDE_XMLSYNTAXSTATUS_ElementClose: + if (m_pChild->GetType() != FDE_XMLNODE_Element) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_pParser->GetTagName(m_ws1); + ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2); + if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_NodeStack.Pop(); + if (m_NodeStack.GetSize() < 1) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement(); + m_pChild = m_pParent; + iCount++; + break; + case FDE_XMLSYNTAXSTATUS_TargetName: + m_pParser->GetTargetName(m_ws1); + m_pChild = new CFDE_XMLInstruction(m_ws1); + m_pParent->InsertChildNode(m_pChild); + m_ws1.Empty(); + break; + case FDE_XMLSYNTAXSTATUS_TagName: + m_pParser->GetTagName(m_ws1); + m_pChild = new CFDE_XMLElement(m_ws1); + m_pParent->InsertChildNode(m_pChild); + m_NodeStack.Push(m_pChild); + m_pParent = m_pChild; + break; + case FDE_XMLSYNTAXSTATUS_AttriName: + m_pParser->GetAttributeName(m_ws1); + break; + case FDE_XMLSYNTAXSTATUS_AttriValue: + if (m_pChild == NULL) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_pParser->GetAttributeName(m_ws2); + if (m_pChild->GetType() == FDE_XMLNODE_Element) { + ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2); + } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) { + ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2); + } + m_ws1.Empty(); + break; + case FDE_XMLSYNTAXSTATUS_Text: + m_pParser->GetTextData(m_ws1); + m_pChild = new CFDE_XMLText(m_ws1); + m_pParent->InsertChildNode(m_pChild); + m_pChild = m_pParent; + break; + case FDE_XMLSYNTAXSTATUS_CData: + m_pParser->GetTextData(m_ws1); + m_pChild = new CFDE_XMLCharData(m_ws1); + m_pParent->InsertChildNode(m_pChild); + m_pChild = m_pParent; + break; + case FDE_XMLSYNTAXSTATUS_TargetData: + if (m_pChild == NULL || + m_pChild->GetType() != FDE_XMLNODE_Instruction) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + if (!m_ws1.IsEmpty()) { + ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); + } + m_pParser->GetTargetData(m_ws1); + ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); + m_ws1.Empty(); + break; + default: + break; + } + if (dwRet == FDE_XMLSYNTAXSTATUS_Error || + dwRet == FDE_XMLSYNTAXSTATUS_EOS) { + break; + } + if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { + break; + } + } + return m_pParser->GetStatus(); +} +CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, + IFDE_XMLSyntaxParser* pParser) + : m_pHandler(pHandler), + m_pParser(pParser), + m_TagStack(16), + m_pTagTop(NULL), + m_ws1(), + m_ws2() {} +CFDE_XMLSAXParser::~CFDE_XMLSAXParser() { + m_TagStack.RemoveAll(); + m_ws1.Empty(); + m_ws2.Empty(); +} +int32_t CFDE_XMLSAXParser::DoParser(IFX_Pause* pPause) { + FX_DWORD dwRet = 0; + int32_t iCount = 0; + while (TRUE) { + dwRet = m_pParser->DoSyntaxParse(); + switch (dwRet) { + case FDE_XMLSYNTAXSTATUS_ElementBreak: + if (m_pTagTop == NULL) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + if (m_pTagTop->eType == FDE_XMLNODE_Element) { + m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); + } + break; + case FDE_XMLSYNTAXSTATUS_ElementClose: + if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + m_pParser->GetTagName(m_ws1); + if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } else if (m_ws1.GetLength() == 0) { + m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); + } + m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName); + Pop(); + iCount++; + break; + case FDE_XMLSYNTAXSTATUS_TargetName: { + m_pParser->GetTargetName(m_ws1); + CFDE_XMLTAG xmlTag; + xmlTag.wsTagName = m_ws1; + xmlTag.eType = FDE_XMLNODE_Instruction; + Push(xmlTag); + m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, + m_pTagTop->wsTagName); + m_ws1.Empty(); + } break; + case FDE_XMLSYNTAXSTATUS_TagName: { + m_pParser->GetTargetName(m_ws1); + CFDE_XMLTAG xmlTag; + xmlTag.wsTagName = m_ws1; + xmlTag.eType = FDE_XMLNODE_Element; + Push(xmlTag); + m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, + m_pTagTop->wsTagName); + } break; + case FDE_XMLSYNTAXSTATUS_AttriName: + m_pParser->GetTargetName(m_ws1); + break; + case FDE_XMLSYNTAXSTATUS_AttriValue: + m_pParser->GetAttributeName(m_ws2); + if (m_pTagTop == NULL) { + dwRet = FDE_XMLSYNTAXSTATUS_Error; + break; + } + if (m_pTagTop->eType == FDE_XMLNODE_Element) { + m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2); + } + m_ws1.Empty(); + break; + case FDE_XMLSYNTAXSTATUS_CData: + m_pParser->GetTextData(m_ws1); + m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1); + break; + case FDE_XMLSYNTAXSTATUS_Text: + m_pParser->GetTextData(m_ws1); + m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1); + break; + case FDE_XMLSYNTAXSTATUS_TargetData: + m_pParser->GetTargetData(m_ws1); + m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1); + m_ws1.Empty(); + break; + default: + break; + } + if (dwRet == FDE_XMLSYNTAXSTATUS_Error || + dwRet == FDE_XMLSYNTAXSTATUS_EOS) { + break; + } + if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { + break; + } + } + return m_pParser->GetStatus(); +} +inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { + m_TagStack.Push(xmlTag); + m_pTagTop = m_TagStack.GetTopElement(); +} +inline void CFDE_XMLSAXParser::Pop() { + m_TagStack.Pop(); + m_pTagTop = m_TagStack.GetTopElement(); +} +#ifdef _FDE_BLOCK_BUFFER +CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) + : m_iDataLength(0), + m_iBufferSize(0), + m_iAllocStep(iAllocStep), + m_iStartPosition(0) {} +CFDE_BlockBuffer::~CFDE_BlockBuffer() { + ClearBuffer(); +} +FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { + iIndexInBlock = 0; + if (!m_BlockArray.GetSize()) { + return nullptr; + } + int32_t iRealIndex = m_iStartPosition + m_iDataLength; + if (iRealIndex == m_iBufferSize) { + FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); + m_BlockArray.Add(pBlock); + m_iBufferSize += m_iAllocStep; + return pBlock; + } + iIndexInBlock = iRealIndex % m_iAllocStep; + return (FX_WCHAR*)m_BlockArray[iRealIndex / m_iAllocStep]; +} +FX_BOOL CFDE_BlockBuffer::InitBuffer(int32_t iBufferSize) { + ClearBuffer(); + int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1; + for (int32_t i = 0; i < iNumOfBlock; i++) { + m_BlockArray.Add(FX_Alloc(FX_WCHAR, m_iAllocStep)); + } + m_iBufferSize = iNumOfBlock * m_iAllocStep; + return TRUE; +} +void CFDE_BlockBuffer::SetTextChar(int32_t iIndex, FX_WCHAR ch) { + if (iIndex < 0) { + return; + } + int32_t iRealIndex = m_iStartPosition + iIndex; + int32_t iBlockIndex = iRealIndex / m_iAllocStep; + int32_t iInnerIndex = iRealIndex % m_iAllocStep; + int32_t iBlockSize = m_BlockArray.GetSize(); + if (iBlockIndex >= iBlockSize) { + int32_t iNewBlocks = iBlockIndex - iBlockSize + 1; + do { + FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); + m_BlockArray.Add(pBlock); + m_iBufferSize += m_iAllocStep; + } while (--iNewBlocks); + } + FX_WCHAR* pTextData = (FX_WCHAR*)m_BlockArray[iBlockIndex]; + *(pTextData + iInnerIndex) = ch; + if (m_iDataLength <= iIndex) { + m_iDataLength = iIndex + 1; + } +} +int32_t CFDE_BlockBuffer::DeleteTextChars(int32_t iCount, FX_BOOL bDirection) { + if (iCount <= 0) { + return m_iDataLength; + } + if (iCount >= m_iDataLength) { + Reset(FALSE); + return 0; + } + if (bDirection) { + m_iStartPosition += iCount; + m_iDataLength -= iCount; + } else { + m_iDataLength -= iCount; + } + return m_iDataLength; +} +void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, + int32_t iStart, + int32_t iLength) const { + wsTextData.Empty(); + int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition; + if (iStart < 0 || iStart > iMaybeDataLength) { + return; + } + if (iLength == -1 || iLength > iMaybeDataLength) { + iLength = iMaybeDataLength; + } + if (iLength <= 0) { + return; + } + FX_WCHAR* pBuf = wsTextData.GetBuffer(iLength); + if (!pBuf) { + return; + } + int32_t iStartBlockIndex = 0; + int32_t iStartInnerIndex = 0; + TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex); + int32_t iEndBlockIndex = 0; + int32_t iEndInnerIndex = 0; + TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex); + int32_t iPointer = 0; + for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) { + int32_t iBufferPointer = 0; + int32_t iCopyLength = m_iAllocStep; + if (i == iStartBlockIndex) { + iCopyLength -= iStartInnerIndex; + iBufferPointer = iStartInnerIndex; + } + if (i == iEndBlockIndex) { + iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex); + } + FX_WCHAR* pBlockBuf = (FX_WCHAR*)m_BlockArray[i]; + FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, + iCopyLength * sizeof(FX_WCHAR)); + iPointer += iCopyLength; + } + wsTextData.ReleaseBuffer(iLength); +} +void CFDE_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex, + int32_t& iBlockIndex, + int32_t& iInnerIndex) const { + FXSYS_assert(iIndex >= 0); + int32_t iRealIndex = m_iStartPosition + iIndex; + iBlockIndex = iRealIndex / m_iAllocStep; + iInnerIndex = iRealIndex % m_iAllocStep; +} +void CFDE_BlockBuffer::ClearBuffer() { + m_iBufferSize = 0; + int32_t iSize = m_BlockArray.GetSize(); + for (int32_t i = 0; i < iSize; i++) { + FX_Free(m_BlockArray[i]); + m_BlockArray[i] = NULL; + } + m_BlockArray.RemoveAll(); +} +#endif +IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { + return new CFDE_XMLSyntaxParser; +} +#ifdef _FDE_BLOCK_BUFFER +CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() + : m_pStream(nullptr), + m_iXMLPlaneSize(-1), + m_iCurrentPos(0), + m_iCurrentNodeNum(-1), + m_iLastNodeNum(-1), + m_iParsedChars(0), + m_iParsedBytes(0), + m_pBuffer(nullptr), + m_iBufferChars(0), + m_bEOS(FALSE), + m_pStart(nullptr), + m_pEnd(nullptr), + m_XMLNodeStack(16), + m_iAllocStep(m_BlockBuffer.GetAllocStep()), + m_iDataLength(m_BlockBuffer.GetDataLengthRef()), + m_pCurrentBlock(nullptr), + m_iIndexInBlock(0), + m_iTextDataLength(0), + m_dwStatus(FDE_XMLSYNTAXSTATUS_None), + m_dwMode(FDE_XMLSYNTAXMODE_Text), + m_wQuotationMark(0), + m_iEntityStart(-1), + m_SkipStack(16) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; +} +void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, + int32_t iXMLPlaneSize, + int32_t iTextDataSize) { + FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); + FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0); + int32_t iStreamLength = pStream->GetLength(); + FXSYS_assert(iStreamLength > 0); + m_pStream = pStream; + m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); + uint8_t bom[4]; + m_iCurrentPos = m_pStream->GetBOM(bom); + FXSYS_assert(m_pBuffer == NULL); + m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); + m_pStart = m_pEnd = m_pBuffer; + FXSYS_assert(!m_BlockBuffer.IsInitialized()); + m_BlockBuffer.InitBuffer(); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_iParsedBytes = m_iParsedChars = 0; + m_iBufferChars = 0; +} +FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { + if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || + m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { + return m_dwStatus; + } + FXSYS_assert(m_pStream && m_pBuffer && m_BlockBuffer.IsInitialized()); + int32_t iStreamLength = m_pStream->GetLength(); + int32_t iPos; + FX_WCHAR ch; + FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; + while (TRUE) { + if (m_pStart >= m_pEnd) { + if (m_bEOS || m_iCurrentPos >= iStreamLength) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; + return m_dwStatus; + } + m_iParsedChars += (m_pEnd - m_pBuffer); + m_iParsedBytes = m_iCurrentPos; + m_pStream->Lock(); + if (m_pStream->GetPosition() != m_iCurrentPos) { + m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); + } + m_iBufferChars = + m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); + iPos = m_pStream->GetPosition(); + m_pStream->Unlock(); + if (m_iBufferChars < 1) { + m_iCurrentPos = iStreamLength; + m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; + return m_dwStatus; + } + m_iCurrentPos = iPos; + m_pStart = m_pBuffer; + m_pEnd = m_pBuffer + m_iBufferChars; + } + while (m_pStart < m_pEnd) { + ch = *m_pStart; + switch (m_dwMode) { + case FDE_XMLSYNTAXMODE_Text: + if (ch == L'<') { + if (m_iDataLength > 0) { + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_iEntityStart = -1; + dwStatus = FDE_XMLSYNTAXSTATUS_Text; + } else { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_Node; + } + } else { + ParseTextChar(ch); + } + break; + case FDE_XMLSYNTAXMODE_Node: + if (ch == L'!') { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; + } else if (ch == L'/') { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; + } else if (ch == L'?') { + m_iLastNodeNum++; + m_iCurrentNodeNum = m_iLastNodeNum; + m_CurNode.iNodeNum = m_iLastNodeNum; + m_CurNode.eNodeType = FDE_XMLNODE_Instruction; + m_XMLNodeStack.Push(m_CurNode); + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_Target; + dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; + } else { + m_iLastNodeNum++; + m_iCurrentNodeNum = m_iLastNodeNum; + m_CurNode.iNodeNum = m_iLastNodeNum; + m_CurNode.eNodeType = FDE_XMLNODE_Element; + m_XMLNodeStack.Push(m_CurNode); + m_dwMode = FDE_XMLSYNTAXMODE_Tag; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; + } + break; + case FDE_XMLSYNTAXMODE_Target: + case FDE_XMLSYNTAXMODE_Tag: + if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { + if (m_iDataLength < 1) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { + dwStatus = FDE_XMLSYNTAXSTATUS_TagName; + } else { + dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; + } + m_dwMode = FDE_XMLSYNTAXMODE_AttriName; + } + } else { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriName: + if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { + if (m_iDataLength < 1) { + if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { + if (ch == L'>' || ch == L'/') { + m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; + break; + } + } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + if (ch == L'?') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; + m_pStart++; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + } + break; + } + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + break; + } + } + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; + dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; + } + } else { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriEqualSign: + if (FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (ch != L'=') { + if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + break; + } + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriQuotation: + if (FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (ch != L'\"' && ch != L'\'') { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_wQuotationMark = ch; + m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriValue: + if (ch == m_wQuotationMark) { + if (m_iEntityStart > -1) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_iTextDataLength = m_iDataLength; + m_wQuotationMark = 0; + m_BlockBuffer.Reset(); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_AttriName; + dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; + } else { + ParseTextChar(ch); + } + break; + case FDE_XMLSYNTAXMODE_CloseInstruction: + if (ch != L'>') { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + } else if (m_iDataLength > 0) { + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + } else { + m_pStart++; + FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_XMLNodeStack.Pop(); + pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; + } else { + m_CurNode = *pXMLNode; + } + m_iCurrentNodeNum = m_CurNode.iNodeNum; + m_BlockBuffer.Reset(); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; + } + break; + case FDE_XMLSYNTAXMODE_BreakElement: + if (ch == L'>') { + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; + } else if (ch == L'/') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; + } else { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_CloseElement: + if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { + if (ch == L'>') { + FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_XMLNodeStack.Pop(); + pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; + } else { + m_CurNode = *pXMLNode; + } + m_iCurrentNodeNum = m_CurNode.iNodeNum; + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; + } else if (!FDE_IsXMLWhiteSpace(ch)) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + } else { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: + if (ch == '-') { + m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; + m_SkipChar = L'>'; + m_SkipStack.Push(L'>'); + } + break; + case FDE_XMLSYNTAXMODE_SkipDeclNode: + if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { + m_pStart++; + if (ch != m_SkipChar) { + break; + } + m_SkipStack.Pop(); + FX_DWORD* pDWord = m_SkipStack.GetTopElement(); + if (pDWord == NULL) { + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } else { + m_SkipChar = (FX_WCHAR)*pDWord; + } + } else { + switch (ch) { + case L'<': + m_SkipChar = L'>'; + m_SkipStack.Push(L'>'); + break; + case L'[': + m_SkipChar = L']'; + m_SkipStack.Push(L']'); + break; + case L'(': + m_SkipChar = L')'; + m_SkipStack.Push(L')'); + break; + case L'\'': + m_SkipChar = L'\''; + m_SkipStack.Push(L'\''); + break; + case L'\"': + m_SkipChar = L'\"'; + m_SkipStack.Push(L'\"'); + break; + default: + if (ch == m_SkipChar) { + m_SkipStack.Pop(); + FX_DWORD* pDWord = m_SkipStack.GetTopElement(); + if (pDWord == NULL) { + if (m_iDataLength >= 9) { + CFX_WideString wsHeader; + m_BlockBuffer.GetTextData(wsHeader, 0, 7); + if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) { + CFX_WideString wsTailer; + m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, + 2); + if (wsTailer.Equal(FX_WSTRC(L"]]"))) { + m_BlockBuffer.DeleteTextChars(7, TRUE); + m_BlockBuffer.DeleteTextChars(2, FALSE); + dwStatus = FDE_XMLSYNTAXSTATUS_CData; + } + } + } + m_iTextDataLength = m_iDataLength; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } else { + m_SkipChar = (FX_WCHAR)*pDWord; + } + } + break; + } + if (m_SkipStack.GetSize() > 0) { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + } + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_SkipComment: + if (ch == L'-') { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = L'-'; + m_iDataLength++; + } else if (ch == L'>') { + if (m_iDataLength > 1) { + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } + } else { + m_BlockBuffer.Reset(); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_TargetData: + if (FDE_IsXMLWhiteSpace(ch)) { + if (m_iDataLength < 1) { + m_pStart++; + break; + } else if (m_wQuotationMark == 0) { + m_iTextDataLength = m_iDataLength; + m_wQuotationMark = 0; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_pStart++; + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + break; + } + } + if (ch == '?') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; + m_pStart++; + } else if (ch == '\"') { + if (m_wQuotationMark == 0) { + m_wQuotationMark = ch; + m_pStart++; + } else if (ch == m_wQuotationMark) { + m_iTextDataLength = m_iDataLength; + m_wQuotationMark = 0; + m_BlockBuffer.Reset(); + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_pStart++; + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + } else { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + } else { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = + m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return FDE_XMLSYNTAXSTATUS_Error; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + m_pStart++; + } + break; + default: + break; + } + if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { + return dwStatus; + } + } + } + return 0; +} +#else +CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() + : m_pStream(NULL), + m_iXMLPlaneSize(-1), + m_iTextDataSize(256), + m_iCurrentPos(0), + m_iCurrentNodeNum(-1), + m_iLastNodeNum(-1), + m_iParsedChars(0), + m_iParsedBytes(0), + m_pBuffer(NULL), + m_iBufferChars(0), + m_bEOS(FALSE), + m_pStart(NULL), + m_pEnd(NULL), + m_XMLNodeStack(16), + m_pwsTextData(NULL), + m_iDataPos(0), + m_dwStatus(FDE_XMLSYNTAXSTATUS_None), + m_dwMode(FDE_XMLSYNTAXMODE_Text), + m_wQuotationMark(0), + m_iTextDataLength(0), + m_iEntityStart(-1), + m_SkipStack(16) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; +} +void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, + int32_t iXMLPlaneSize, + int32_t iTextDataSize) { + FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); + FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0); + int32_t iStreamLength = pStream->GetLength(); + FXSYS_assert(iStreamLength > 0); + m_pStream = pStream; + m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); + m_iTextDataSize = iTextDataSize; + uint8_t bom[4]; + m_iCurrentPos = m_pStream->GetBOM(bom); + FXSYS_assert(m_pBuffer == NULL); + m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); + m_pStart = m_pEnd = m_pBuffer; + FXSYS_assert(m_pwsTextData == NULL); + m_pwsTextData = FX_Alloc(FX_WCHAR, m_iTextDataSize); + m_iParsedBytes = 0; + m_iParsedChars = 0; + m_iBufferChars = 0; +} +FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { + if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || + m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { + return m_dwStatus; + } + FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL); + int32_t iStreamLength = m_pStream->GetLength(); + int32_t iPos; + FX_WCHAR ch; + FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; + while (TRUE) { + if (m_pStart >= m_pEnd) { + if (m_bEOS || m_iCurrentPos >= iStreamLength) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; + return m_dwStatus; + } + m_iParsedChars += (m_pEnd - m_pBuffer); + m_iParsedBytes = m_iCurrentPos; + m_pStream->Lock(); + if (m_pStream->GetPosition() != m_iCurrentPos) { + m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); + } + m_iBufferChars = + m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); + iPos = m_pStream->GetPosition(); + m_pStream->Unlock(); + if (m_iBufferChars < 1) { + m_iCurrentPos = iStreamLength; + m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; + return m_dwStatus; + } + m_iCurrentPos = iPos; + m_pStart = m_pBuffer; + m_pEnd = m_pBuffer + m_iBufferChars; + } + while (m_pStart < m_pEnd) { + ch = *m_pStart; + switch (m_dwMode) { + case FDE_XMLSYNTAXMODE_Text: + if (ch == L'<') { + if (m_iDataPos > 0) { + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + m_iEntityStart = -1; + dwStatus = FDE_XMLSYNTAXSTATUS_Text; + } else { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_Node; + } + } else { + ParseTextChar(ch); + } + break; + case FDE_XMLSYNTAXMODE_Node: + if (ch == L'!') { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; + } else if (ch == L'/') { + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; + } else if (ch == L'?') { + m_iLastNodeNum++; + m_iCurrentNodeNum = m_iLastNodeNum; + m_CurNode.iNodeNum = m_iLastNodeNum; + m_CurNode.eNodeType = FDE_XMLNODE_Instruction; + m_XMLNodeStack.Push(m_CurNode); + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_Target; + dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; + } else { + m_iLastNodeNum++; + m_iCurrentNodeNum = m_iLastNodeNum; + m_CurNode.iNodeNum = m_iLastNodeNum; + m_CurNode.eNodeType = FDE_XMLNODE_Element; + m_XMLNodeStack.Push(m_CurNode); + m_dwMode = FDE_XMLSYNTAXMODE_Tag; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; + } + break; + case FDE_XMLSYNTAXMODE_Target: + case FDE_XMLSYNTAXMODE_Tag: + if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { + if (m_iDataPos < 1) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { + dwStatus = FDE_XMLSYNTAXSTATUS_TagName; + } else { + dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; + } + m_dwMode = FDE_XMLSYNTAXMODE_AttriName; + } + } else { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriName: + if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { + if (m_iDataPos < 1) { + if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { + if (ch == L'>' || ch == L'/') { + m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; + break; + } + } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + if (ch == L'?') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; + m_pStart++; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + } + break; + } + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + break; + } + } + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; + dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; + } + } else { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriEqualSign: + if (FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (ch != L'=') { + if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + break; + } + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriQuotation: + if (FDE_IsXMLWhiteSpace(ch)) { + m_pStart++; + break; + } + if (ch != L'\"' && ch != L'\'') { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } else { + m_wQuotationMark = ch; + m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_AttriValue: + if (ch == m_wQuotationMark) { + if (m_iEntityStart > -1) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_iTextDataLength = m_iDataPos; + m_wQuotationMark = 0; + m_iDataPos = 0; + m_pStart++; + m_dwMode = FDE_XMLSYNTAXMODE_AttriName; + dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; + } else { + ParseTextChar(ch); + } + break; + case FDE_XMLSYNTAXMODE_CloseInstruction: + if (ch != L'>') { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + m_dwMode = FDE_XMLSYNTAXMODE_TargetData; + } else if (m_iDataPos > 0) { + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + } else { + m_pStart++; + FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_XMLNodeStack.Pop(); + pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; + } else { + m_CurNode = *pXMLNode; + } + m_iCurrentNodeNum = m_CurNode.iNodeNum; + m_iDataPos = 0; + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; + } + break; + case FDE_XMLSYNTAXMODE_BreakElement: + if (ch == L'>') { + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; + } else if (ch == L'/') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; + } else { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_CloseElement: + if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { + if (ch == L'>') { + FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + m_XMLNodeStack.Pop(); + pXMLNode = m_XMLNodeStack.GetTopElement(); + if (pXMLNode == NULL) { + m_CurNode.iNodeNum = -1; + m_CurNode.eNodeType = FDE_XMLNODE_Unknown; + } else { + m_CurNode = *pXMLNode; + } + m_iCurrentNodeNum = m_CurNode.iNodeNum; + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + m_dwMode = FDE_XMLSYNTAXMODE_Text; + dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; + } else if (!FDE_IsXMLWhiteSpace(ch)) { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + } else { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: + if (ch == '-') { + m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; + } else { + m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; + m_SkipChar = L'>'; + m_SkipStack.Push(L'>'); + } + break; + case FDE_XMLSYNTAXMODE_SkipDeclNode: + if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { + m_pStart++; + if (ch != m_SkipChar) { + break; + } + m_SkipStack.Pop(); + FX_DWORD* pDWord = m_SkipStack.GetTopElement(); + if (pDWord == NULL) { + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } else { + m_SkipChar = (FX_WCHAR)*pDWord; + } + } else { + switch (ch) { + case L'<': + m_SkipChar = L'>'; + m_SkipStack.Push(L'>'); + break; + case L'[': + m_SkipChar = L']'; + m_SkipStack.Push(L']'); + break; + case L'(': + m_SkipChar = L')'; + m_SkipStack.Push(L')'); + break; + case L'\'': + m_SkipChar = L'\''; + m_SkipStack.Push(L'\''); + break; + case L'\"': + m_SkipChar = L'\"'; + m_SkipStack.Push(L'\"'); + break; + default: + if (ch == m_SkipChar) { + m_SkipStack.Pop(); + FX_DWORD* pDWord = m_SkipStack.GetTopElement(); + if (pDWord == NULL) { + m_iTextDataLength = m_iDataPos; + m_iDataPos = 0; + if (m_iTextDataLength >= 9 && + FXSYS_memcmp(m_pwsTextData, L"[CDATA[", + 7 * sizeof(FX_WCHAR)) == 0 && + FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, + L"]]", 2 * sizeof(FX_WCHAR)) == 0) { + m_iTextDataLength -= 9; + FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, + m_iTextDataLength * sizeof(FX_WCHAR)); + dwStatus = FDE_XMLSYNTAXSTATUS_CData; + } + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } else { + m_SkipChar = (FX_WCHAR)*pDWord; + } + } + break; + } + if (m_SkipStack.GetSize() > 0) { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + } + m_pStart++; + } + break; + case FDE_XMLSYNTAXMODE_SkipComment: + if (ch == L'-') { + m_iDataPos++; + } else if (ch == L'>') { + if (m_iDataPos > 1) { + m_iDataPos = 0; + m_dwMode = FDE_XMLSYNTAXMODE_Text; + } + } else { + m_iDataPos = 0; + } + m_pStart++; + break; + case FDE_XMLSYNTAXMODE_TargetData: + if (FDE_IsXMLWhiteSpace(ch)) { + if (m_iDataPos < 1) { + m_pStart++; + break; + } else if (m_wQuotationMark == 0) { + m_iTextDataLength = m_iDataPos; + m_wQuotationMark = 0; + m_iDataPos = 0; + m_pStart++; + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + break; + } + } + if (ch == '?') { + m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; + m_pStart++; + } else if (ch == '\"') { + if (m_wQuotationMark == 0) { + m_wQuotationMark = ch; + m_pStart++; + } else if (ch == m_wQuotationMark) { + m_iTextDataLength = m_iDataPos; + m_wQuotationMark = 0; + m_iDataPos = 0; + m_pStart++; + dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; + } else { + m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; + return m_dwStatus; + } + } else { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos++] = ch; + m_pStart++; + } + break; + default: + break; + } + if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { + return dwStatus; + } + } + } + return 0; +} +#endif +CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { +#ifdef _FDE_BLOCK_BUFFER + if (m_pCurrentBlock) { + m_pCurrentBlock = NULL; + } +#else + FX_Free(m_pwsTextData); +#endif + FX_Free(m_pBuffer); +} +int32_t CFDE_XMLSyntaxParser::GetStatus() const { + if (m_pStream == NULL) { + return -1; + } + int32_t iStreamLength = m_pStream->GetLength(); + if (iStreamLength < 1) { + return 100; + } + if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { + return -1; + } + if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { + return 100; + } + return m_iParsedBytes * 100 / iStreamLength; +} +static int32_t FX_GetUTF8EncodeLength(const FX_WCHAR* pSrc, int32_t iSrcLen) { + FX_DWORD unicode = 0; + int32_t iDstNum = 0; + while (iSrcLen-- > 0) { + unicode = *pSrc++; + int nbytes = 0; + if ((FX_DWORD)unicode < 0x80) { + nbytes = 1; + } else if ((FX_DWORD)unicode < 0x800) { + nbytes = 2; + } else if ((FX_DWORD)unicode < 0x10000) { + nbytes = 3; + } else if ((FX_DWORD)unicode < 0x200000) { + nbytes = 4; + } else if ((FX_DWORD)unicode < 0x4000000) { + nbytes = 5; + } else { + nbytes = 6; + } + iDstNum += nbytes; + } + return iDstNum; +} +FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { + if (m_pStream == NULL) { + return 0; + } + int32_t nSrcLen = m_pStart - m_pBuffer; + int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); + return m_iParsedBytes + nDstLen; +} +#ifdef _FDE_BLOCK_BUFFER +void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { + if (m_iIndexInBlock == m_iAllocStep) { + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + if (!m_pCurrentBlock) { + return; + } + } + m_pCurrentBlock[m_iIndexInBlock++] = ch; + m_iDataLength++; + if (m_iEntityStart > -1 && ch == L';') { + CFX_WideString csEntity; + m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, + (m_iDataLength - 1) - m_iEntityStart - 1); + int32_t iLen = csEntity.GetLength(); + if (iLen > 0) { + if (csEntity[0] == L'#') { + ch = 0; + FX_WCHAR w; + if (iLen > 1 && csEntity[1] == L'x') { + for (int32_t i = 2; i < iLen; i++) { + w = csEntity[i]; + if (w >= L'0' && w <= L'9') { + ch = (ch << 4) + w - L'0'; + } else if (w >= L'A' && w <= L'F') { + ch = (ch << 4) + w - 55; + } else if (w >= L'a' && w <= L'f') { + ch = (ch << 4) + w - 87; + } else { + break; + } + } + } else { + for (int32_t i = 1; i < iLen; i++) { + w = csEntity[i]; + if (w < L'0' || w > L'9') { + break; + } + ch = ch * 10 + w - L'0'; + } + } + if (ch != 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, ch); + m_iEntityStart++; + } + } else { + if (csEntity.Compare(L"amp") == 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, L'&'); + m_iEntityStart++; + } else if (csEntity.Compare(L"lt") == 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, L'<'); + m_iEntityStart++; + } else if (csEntity.Compare(L"gt") == 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, L'>'); + m_iEntityStart++; + } else if (csEntity.Compare(L"apos") == 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, L'\''); + m_iEntityStart++; + } else if (csEntity.Compare(L"quot") == 0) { + m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"'); + m_iEntityStart++; + } + } + } + m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); + m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); + m_iEntityStart = -1; + } else { + if (m_iEntityStart < 0 && ch == L'&') { + m_iEntityStart = m_iDataLength - 1; + } + } + m_pStart++; +} +#else +void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { + if (m_iDataPos >= m_iTextDataSize) { + ReallocTextDataBuffer(); + } + m_pwsTextData[m_iDataPos] = ch; + if (m_iEntityStart > -1 && ch == L';') { + CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, + m_iDataPos - m_iEntityStart - 1); + int32_t iLen = csEntity.GetLength(); + if (iLen > 0) { + if (csEntity[0] == L'#') { + ch = 0; + FX_WCHAR w; + if (iLen > 1 && csEntity[1] == L'x') { + for (int32_t i = 2; i < iLen; i++) { + w = csEntity[i]; + if (w >= L'0' && w <= L'9') { + ch = (ch << 4) + w - L'0'; + } else if (w >= L'A' && w <= L'F') { + ch = (ch << 4) + w - 55; + } else if (w >= L'a' && w <= L'f') { + ch = (ch << 4) + w - 87; + } else { + break; + } + } + } else { + for (int32_t i = 1; i < iLen; i++) { + w = csEntity[i]; + if (w < L'0' || w > L'9') { + break; + } + ch = ch * 10 + w - L'0'; + } + } + if (ch != 0) { + m_pwsTextData[m_iEntityStart++] = ch; + } + } else { + if (csEntity.Compare(L"amp") == 0) { + m_pwsTextData[m_iEntityStart++] = L'&'; + } else if (csEntity.Compare(L"lt") == 0) { + m_pwsTextData[m_iEntityStart++] = L'<'; + } else if (csEntity.Compare(L"gt") == 0) { + m_pwsTextData[m_iEntityStart++] = L'>'; + } else if (csEntity.Compare(L"apos") == 0) { + m_pwsTextData[m_iEntityStart++] = L'\''; + } else if (csEntity.Compare(L"quot") == 0) { + m_pwsTextData[m_iEntityStart++] = L'\"'; + } + } + } + m_iDataPos = m_iEntityStart; + m_iEntityStart = -1; + } else { + if (m_iEntityStart < 0 && ch == L'&') { + m_iEntityStart = m_iDataPos; + } + m_iDataPos++; + } + m_pStart++; +} +void CFDE_XMLSyntaxParser::ReallocTextDataBuffer() { + FXSYS_assert(m_pwsTextData != NULL); + if (m_iTextDataSize <= 1024 * 1024) { + m_iTextDataSize *= 2; + } else { + m_iTextDataSize += 1024 * 1024; + } + m_pwsTextData = FX_Realloc(FX_WCHAR, m_pwsTextData, m_iTextDataSize); +} +void CFDE_XMLSyntaxParser::GetData(CFX_WideString& wsData) const { + FX_WCHAR* pBuf = wsData.GetBuffer(m_iTextDataLength); + FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR)); + wsData.ReleaseBuffer(m_iTextDataLength); +} +#endif diff --git a/xfa/src/fdp/src/xml/fde_xml_imp.h b/xfa/src/fdp/src/xml/fde_xml_imp.h new file mode 100644 index 0000000000..1a8097008e --- /dev/null +++ b/xfa/src/fdp/src/xml/fde_xml_imp.h @@ -0,0 +1,375 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FDE_XML_IMP_H_ +#define FDE_XML_IMP_H_ + +#define _FDE_BLOCK_BUFFER +#ifdef _FDE_BLOCK_BUFFER +class CFDE_BlockBuffer; +#endif +class CFDE_XMLNode; +class CFDE_XMLInstruction; +class CFDE_XMLElement; +class CFDE_XMLText; +class CFDE_XMLDoc; +class IFDE_XMLParser; +class CFDE_XMLDOMParser; +class CFDE_XMLSAXParser; +class CFDE_XMLSyntaxParser; +class CFDE_XMLNode : public CFX_Target { + public: + CFDE_XMLNode(); + virtual void Release() { delete this; } + virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Unknown; } + virtual int32_t CountChildNodes() const; + virtual CFDE_XMLNode* GetChildNode(int32_t index) const; + virtual int32_t GetChildNodeIndex(CFDE_XMLNode* pNode) const; + virtual CFDE_XMLNode* GetPath(const FX_WCHAR* pPath, + int32_t iLength = -1, + FX_BOOL bQualifiedName = TRUE) const; + virtual int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1); + virtual void RemoveChildNode(CFDE_XMLNode* pNode); + virtual void DeleteChildren(); + virtual CFDE_XMLNode* GetNodeItem(IFDE_XMLNode::NodeItem eItem) const; + virtual int32_t GetNodeLevel() const; + virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, + CFDE_XMLNode* pNode); + virtual CFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem); + virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); + virtual void SaveXMLNode(IFX_Stream* pXMLStream); + + public: + ~CFDE_XMLNode(); + void CloneChildren(CFDE_XMLNode* pClone); + CFDE_XMLNode* m_pParent; + CFDE_XMLNode* m_pChild; + CFDE_XMLNode* m_pPrior; + CFDE_XMLNode* m_pNext; +}; +class CFDE_XMLInstruction : public CFDE_XMLNode { + public: + CFDE_XMLInstruction(const CFX_WideString& wsTarget); + virtual void Release() { delete this; } + virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Instruction; } + virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); + virtual void GetTargetName(CFX_WideString& wsTarget) const { + wsTarget = m_wsTarget; + } + virtual int32_t CountAttributes() const; + virtual FX_BOOL GetAttribute(int32_t index, + CFX_WideString& wsAttriName, + CFX_WideString& wsAttriValue) const; + virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const; + virtual void GetString(const FX_WCHAR* pwsAttriName, + CFX_WideString& wsAttriValue, + const FX_WCHAR* pwsDefValue = NULL) const; + virtual void SetString(const CFX_WideString& wsAttriName, + const CFX_WideString& wsAttriValue); + virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName, + int32_t iDefValue = 0) const; + virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue); + virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fDefValue = 0) const; + virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue); + virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName); + virtual int32_t CountData() const; + virtual FX_BOOL GetData(int32_t index, CFX_WideString& wsData) const; + virtual void AppendData(const CFX_WideString& wsData); + virtual void RemoveData(int32_t index); + + public: + ~CFDE_XMLInstruction() {} + CFX_WideString m_wsTarget; + CFX_WideStringArray m_Attributes; + CFX_WideStringArray m_TargetData; +}; +class CFDE_XMLElement : public CFDE_XMLNode { + public: + CFDE_XMLElement(const CFX_WideString& wsTag); + virtual void Release() { delete this; } + virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Element; } + virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); + virtual void GetTagName(CFX_WideString& wsTag) const; + virtual void GetLocalTagName(CFX_WideString& wsTag) const; + virtual void GetNamespacePrefix(CFX_WideString& wsPrefix) const; + virtual void GetNamespaceURI(CFX_WideString& wsNamespace) const; + virtual int32_t CountAttributes() const; + virtual FX_BOOL GetAttribute(int32_t index, + CFX_WideString& wsAttriName, + CFX_WideString& wsAttriValue) const; + virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const; + virtual void GetString(const FX_WCHAR* pwsAttriName, + CFX_WideString& wsAttriValue, + const FX_WCHAR* pwsDefValue = NULL) const; + virtual void SetString(const CFX_WideString& wsAttriName, + const CFX_WideString& wsAttriValue); + virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName, + int32_t iDefValue = 0) const; + virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue); + virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, + FX_FLOAT fDefValue = 0) const; + virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue); + virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName); + virtual void GetTextData(CFX_WideString& wsText) const; + virtual void SetTextData(const CFX_WideString& wsText); + + public: + ~CFDE_XMLElement(); + CFX_WideString m_wsTag; + CFX_WideStringArray m_Attributes; +}; +class CFDE_XMLText : public CFDE_XMLNode { + public: + CFDE_XMLText(const CFX_WideString& wsText); + virtual void Release() { delete this; } + virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Text; } + virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); + virtual void GetText(CFX_WideString& wsText) const { wsText = m_wsText; } + virtual void SetText(const CFX_WideString& wsText) { m_wsText = wsText; } + + public: + ~CFDE_XMLText() {} + CFX_WideString m_wsText; +}; +class CFDE_XMLDeclaration : public CFDE_XMLNode { + public: + CFDE_XMLDeclaration() : CFDE_XMLNode() {} +}; +class CFDE_XMLCharData : public CFDE_XMLDeclaration { + public: + CFDE_XMLCharData(const CFX_WideString& wsCData); + + virtual void Release() { delete this; } + virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_CharData; } + virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive); + virtual void GetCharData(CFX_WideString& wsCharData) const { + wsCharData = m_wsCharData; + } + virtual void SetCharData(const CFX_WideString& wsCData) { + m_wsCharData = wsCData; + } + + public: + ~CFDE_XMLCharData() {} + + CFX_WideString m_wsCharData; +}; +class CFDE_XMLDoc : public CFX_Target { + public: + CFDE_XMLDoc(); + ~CFDE_XMLDoc(); + virtual void Release() { delete this; } + virtual FX_BOOL LoadXML(IFX_Stream* pXMLStream, + int32_t iXMLPlaneSize = 8192, + int32_t iTextDataSize = 256, + FDE_LPXMLREADERHANDLER pHandler = NULL); + virtual FX_BOOL LoadXML(IFDE_XMLParser* pXMLParser); + virtual int32_t DoLoad(IFX_Pause* pPause = NULL); + virtual void CloseXML(); + virtual CFDE_XMLNode* GetRoot() const { return m_pRoot; } + virtual void SaveXML(IFX_Stream* pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE); + virtual void SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pNode); + + protected: + IFX_Stream* m_pStream; + int32_t m_iStatus; + CFDE_XMLNode* m_pRoot; + IFDE_XMLSyntaxParser* m_pSyntaxParser; + IFDE_XMLParser* m_pXMLParser; + void Reset(FX_BOOL bInitRoot); + void ReleaseParser(); +}; +typedef CFX_StackTemplate CFDE_XMLDOMNodeStack; +class CFDE_XMLDOMParser : public IFDE_XMLParser, public CFX_Target { + public: + CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, IFDE_XMLSyntaxParser* pParser); + ~CFDE_XMLDOMParser(); + + virtual void Release() { delete this; } + virtual int32_t DoParser(IFX_Pause* pPause); + + private: + IFDE_XMLSyntaxParser* m_pParser; + CFDE_XMLNode* m_pParent; + CFDE_XMLNode* m_pChild; + CFDE_XMLDOMNodeStack m_NodeStack; + CFX_WideString m_ws1; + CFX_WideString m_ws2; +}; +class CFDE_XMLTAG : public CFX_Target { + public: + CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {} + CFDE_XMLTAG(const CFDE_XMLTAG& src) + : wsTagName(src.wsTagName), eType(src.eType) {} + CFX_WideString wsTagName; + FDE_XMLNODETYPE eType; +}; +typedef CFX_ObjectStackTemplate CFDE_XMLTagStack; +class CFDE_XMLSAXParser : public IFDE_XMLParser, public CFX_Target { + public: + CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, + IFDE_XMLSyntaxParser* pParser); + ~CFDE_XMLSAXParser(); + + virtual void Release() { delete this; } + virtual int32_t DoParser(IFX_Pause* pPause); + + private: + void Push(const CFDE_XMLTAG& xmlTag); + void Pop(); + FDE_LPXMLREADERHANDLER m_pHandler; + IFDE_XMLSyntaxParser* m_pParser; + CFDE_XMLTagStack m_TagStack; + CFDE_XMLTAG* m_pTagTop; + CFX_WideString m_ws1; + CFX_WideString m_ws2; +}; +#ifdef _FDE_BLOCK_BUFFER +class CFDE_BlockBuffer : public CFX_Target { + public: + CFDE_BlockBuffer(int32_t iAllocStep = 1024 * 1024); + ~CFDE_BlockBuffer(); + + FX_BOOL InitBuffer(int32_t iBufferSize = 1024 * 1024); + FX_BOOL IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; } + void ReleaseBuffer() { delete this; } + FX_WCHAR* GetAvailableBlock(int32_t& iIndexInBlock); + inline int32_t GetAllocStep() const { return m_iAllocStep; } + inline int32_t& GetDataLengthRef() { return m_iDataLength; } + inline void Reset(FX_BOOL bReserveData = TRUE) { + if (!bReserveData) { + m_iStartPosition = 0; + } + m_iDataLength = 0; + } + void SetTextChar(int32_t iIndex, FX_WCHAR ch); + int32_t DeleteTextChars(int32_t iCount, FX_BOOL bDirection = TRUE); + void GetTextData(CFX_WideString& wsTextData, + int32_t iStart = 0, + int32_t iLength = -1) const; + + protected: + inline void TextDataIndex2BufIndex(const int32_t iIndex, + int32_t& iBlockIndex, + int32_t& iInnerIndex) const; + void ClearBuffer(); + CFX_PtrArray m_BlockArray; + int32_t m_iDataLength; + int32_t m_iBufferSize; + int32_t m_iAllocStep; + int32_t m_iStartPosition; +}; +#endif +#define FDE_XMLSYNTAXMODE_Text 0 +#define FDE_XMLSYNTAXMODE_Node 1 +#define FDE_XMLSYNTAXMODE_Target 2 +#define FDE_XMLSYNTAXMODE_Tag 3 +#define FDE_XMLSYNTAXMODE_AttriName 4 +#define FDE_XMLSYNTAXMODE_AttriEqualSign 5 +#define FDE_XMLSYNTAXMODE_AttriQuotation 6 +#define FDE_XMLSYNTAXMODE_AttriValue 7 +#define FDE_XMLSYNTAXMODE_Entity 8 +#define FDE_XMLSYNTAXMODE_EntityDecimal 9 +#define FDE_XMLSYNTAXMODE_EntityHex 10 +#define FDE_XMLSYNTAXMODE_CloseInstruction 11 +#define FDE_XMLSYNTAXMODE_BreakElement 12 +#define FDE_XMLSYNTAXMODE_CloseElement 13 +#define FDE_XMLSYNTAXMODE_SkipDeclNode 14 +#define FDE_XMLSYNTAXMODE_DeclCharData 15 +#define FDE_XMLSYNTAXMODE_SkipComment 16 +#define FDE_XMLSYNTAXMODE_SkipCommentOrDecl 17 +#define FDE_XMLSYNTAXMODE_TargetData 18 +class CFDE_XMLSyntaxParser : public IFDE_XMLSyntaxParser, public CFX_Target { + public: + CFDE_XMLSyntaxParser(); + ~CFDE_XMLSyntaxParser(); + virtual void Release() { delete this; } + virtual void Init(IFX_Stream* pStream, + int32_t iXMLPlaneSize, + int32_t iTextDataSize = 256); + virtual FX_DWORD DoSyntaxParse(); + virtual int32_t GetStatus() const; + virtual int32_t GetCurrentPos() const { + return m_iParsedChars + (m_pStart - m_pBuffer); + } + virtual FX_FILESIZE GetCurrentBinaryPos() const; + virtual int32_t GetCurrentNodeNumber() const { return m_iCurrentNodeNum; } + virtual int32_t GetLastNodeNumber() const { return m_iLastNodeNum; } +#ifdef _FDE_BLOCK_BUFFER + virtual void GetTargetName(CFX_WideString& wsTarget) const { + m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength); + } + virtual void GetTagName(CFX_WideString& wsTag) const { + m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength); + } + virtual void GetAttributeName(CFX_WideString& wsAttriName) const { + m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength); + } + virtual void GetAttributeValue(CFX_WideString& wsAttriValue) const { + m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength); + } + virtual void GetTextData(CFX_WideString& wsText) const { + m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength); + } + virtual void GetTargetData(CFX_WideString& wsData) const { + m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength); + } +#else + virtual void GetTargetName(CFX_WideString& wsTarget) const { + GetData(wsTarget); + } + virtual void GetTagName(CFX_WideString& wsTag) const { GetData(wsTag); } + virtual void GetAttributeName(CFX_WideString& wsAttriName) const { + GetData(wsAttriName); + } + virtual void GetAttributeValue(CFX_WideString& wsAttriValue) const { + GetData(wsAttriValue); + } + virtual void GetTextData(CFX_WideString& wsText) const { GetData(wsText); } + virtual void GetTargetData(CFX_WideString& wsData) const { GetData(wsData); } +#endif + protected: + IFX_Stream* m_pStream; + int32_t m_iXMLPlaneSize; + int32_t m_iCurrentPos; + int32_t m_iCurrentNodeNum; + int32_t m_iLastNodeNum; + int32_t m_iParsedChars; + int32_t m_iParsedBytes; + FX_WCHAR* m_pBuffer; + int32_t m_iBufferChars; + FX_BOOL m_bEOS; + FX_WCHAR* m_pStart; + FX_WCHAR* m_pEnd; + FDE_XMLNODE m_CurNode; + CFDE_XMLNodeStack m_XMLNodeStack; +#ifdef _FDE_BLOCK_BUFFER + CFDE_BlockBuffer m_BlockBuffer; + int32_t m_iAllocStep; + int32_t& m_iDataLength; + FX_WCHAR* m_pCurrentBlock; + int32_t m_iIndexInBlock; +#else + int32_t m_iTextDataSize; + FX_WCHAR* m_pwsTextData; + int32_t m_iDataPos; +#endif + int32_t m_iTextDataLength; + FX_DWORD m_dwStatus; + FX_DWORD m_dwMode; + FX_WCHAR m_wQuotationMark; + int32_t m_iEntityStart; + CFX_DWordStack m_SkipStack; + FX_WCHAR m_SkipChar; + inline void ParseTextChar(FX_WCHAR ch); +#ifndef _FDE_BLOCK_BUFFER + void ReallocTextDataBuffer(); + void GetData(CFX_WideString& wsData) const; +#endif +}; + +#endif // FDE_XML_IMP_H_ -- cgit v1.2.3