summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/include/fxcrt/fx_xml.h40
-rw-r--r--core/src/fxcrt/fx_xml_parser.cpp95
2 files changed, 55 insertions, 80 deletions
diff --git a/core/include/fxcrt/fx_xml.h b/core/include/fxcrt/fx_xml.h
index eaf872c164..e1255c1f30 100644
--- a/core/include/fxcrt/fx_xml.h
+++ b/core/include/fxcrt/fx_xml.h
@@ -7,7 +7,9 @@
#ifndef CORE_INCLUDE_FXCRT_FX_XML_H_
#define CORE_INCLUDE_FXCRT_FX_XML_H_
-#include "fx_basic.h"
+#include <vector>
+
+#include "core/include/fxcrt/fx_basic.h"
class CXML_AttrItem {
public:
@@ -15,6 +17,7 @@ class CXML_AttrItem {
CFX_ByteString m_AttrName;
CFX_WideString m_Value;
};
+
class CXML_AttrMap {
public:
CXML_AttrMap() { m_pMap = NULL; }
@@ -30,6 +33,7 @@ class CXML_AttrMap {
CXML_AttrItem& GetAt(int index) const;
CFX_ObjectArray<CXML_AttrItem>* m_pMap;
};
+
class CXML_Content {
public:
CXML_Content() : m_bCDATA(FALSE), m_Content() {}
@@ -40,8 +44,11 @@ class CXML_Content {
FX_BOOL m_bCDATA;
CFX_WideString m_Content;
};
+
class CXML_Element {
public:
+ enum ChildType { Invalid, Element, Content };
+
static CXML_Element* Parse(const void* pBuffer,
size_t size,
FX_BOOL bSaveSpaceChars = FALSE,
@@ -52,31 +59,23 @@ class CXML_Element {
static CXML_Element* Parse(IFX_BufferRead* pBuffer,
FX_BOOL bSaveSpaceChars = FALSE,
FX_FILESIZE* pParsedSize = NULL);
+
CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagName);
CXML_Element(const CFX_ByteStringC& qTagName);
CXML_Element();
-
~CXML_Element();
void Empty();
-
CFX_ByteString GetTagName(FX_BOOL bQualified = FALSE) const;
-
CFX_ByteString GetNamespace(FX_BOOL bQualified = FALSE) const;
-
CFX_ByteString GetNamespaceURI(const CFX_ByteStringC& qName) const;
-
CXML_Element* GetParent() const { return m_pParent; }
-
FX_DWORD CountAttrs() const { return m_AttrMap.GetSize(); }
-
void GetAttrByIndex(int index,
CFX_ByteString& space,
CFX_ByteString& name,
CFX_WideString& value) const;
-
FX_BOOL HasAttr(const CFX_ByteStringC& qName) const;
-
FX_BOOL GetAttrValue(const CFX_ByteStringC& name,
CFX_WideString& attribute) const;
CFX_WideString GetAttrValue(const CFX_ByteStringC& name) const {
@@ -129,16 +128,10 @@ class CXML_Element {
return attr;
}
- FX_DWORD CountChildren() const;
-
- enum ChildType { Invalid, Element, Content };
-
+ FX_DWORD CountChildren() const { return m_Children.size(); }
ChildType GetChildType(FX_DWORD index) const;
-
CFX_WideString GetContent(FX_DWORD index) const;
-
CXML_Element* GetElement(FX_DWORD index) const;
-
CXML_Element* GetElement(const CFX_ByteStringC& space,
const CFX_ByteStringC& tag) const {
return GetElement(space, tag, 0);
@@ -146,29 +139,28 @@ class CXML_Element {
FX_DWORD CountElements(const CFX_ByteStringC& space,
const CFX_ByteStringC& tag) const;
-
CXML_Element* GetElement(const CFX_ByteStringC& space,
const CFX_ByteStringC& tag,
int index) const;
FX_DWORD FindElement(CXML_Element* pChild) const;
-
void SetTag(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname);
-
void SetTag(const CFX_ByteStringC& qTagName);
-
void RemoveChildren();
-
void RemoveChild(FX_DWORD index);
protected:
+ struct ChildRecord {
+ ChildType type;
+ void* child; // CXML_Element and CXML_Content lack a common ancestor.
+ };
+
CXML_Element* m_pParent;
CFX_ByteString m_QSpaceName;
CFX_ByteString m_TagName;
-
CXML_AttrMap m_AttrMap;
+ std::vector<ChildRecord> m_Children;
- CFX_PtrArray m_Children;
friend class CXML_Parser;
friend class CXML_Composer;
};
diff --git a/core/src/fxcrt/fx_xml_parser.cpp b/core/src/fxcrt/fx_xml_parser.cpp
index 0b71836ef9..fb8b1db39a 100644
--- a/core/src/fxcrt/fx_xml_parser.cpp
+++ b/core/src/fxcrt/fx_xml_parser.cpp
@@ -467,8 +467,8 @@ CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent,
break;
}
pSubElement->m_pParent = pElement;
- pElement->m_Children.Add((void*)CXML_Element::Element);
- pElement->m_Children.Add(pSubElement);
+ pElement->m_Children.push_back(
+ {CXML_Element::Element, pSubElement});
SkipWhiteSpaces();
}
break;
@@ -514,8 +514,7 @@ void CXML_Parser::InsertContentSegment(FX_BOOL bCDATA,
}
CXML_Content* pContent = new CXML_Content;
pContent->Set(bCDATA, content);
- pElement->m_Children.Add((void*)CXML_Element::Content);
- pElement->m_Children.Add(pContent);
+ pElement->m_Children.push_back({CXML_Element::Content, pContent});
}
static CXML_Element* XML_ContinueParse(CXML_Parser& parser,
FX_BOOL bSaveSpaceChars,
@@ -573,18 +572,16 @@ void CXML_Element::Empty() {
RemoveChildren();
}
void CXML_Element::RemoveChildren() {
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i);
- if (type == Content) {
- CXML_Content* content = (CXML_Content*)m_Children.GetAt(i + 1);
- delete content;
- } else if (type == Element) {
- CXML_Element* child = (CXML_Element*)m_Children.GetAt(i + 1);
+ for (const ChildRecord& record : m_Children) {
+ if (record.type == Content) {
+ delete static_cast<CXML_Content*>(record.child);
+ } else if (record.type == Element) {
+ CXML_Element* child = static_cast<CXML_Element*>(record.child);
child->RemoveChildren();
delete child;
}
}
- m_Children.RemoveAll();
+ m_Children.clear();
}
CFX_ByteString CXML_Element::GetTagName(FX_BOOL bQualified) const {
if (!bQualified || m_QSpaceName.IsEmpty()) {
@@ -688,45 +685,32 @@ FX_BOOL CXML_Element::GetAttrFloat(const CFX_ByteStringC& space,
}
return FALSE;
}
-FX_DWORD CXML_Element::CountChildren() const {
- return m_Children.GetSize() / 2;
-}
CXML_Element::ChildType CXML_Element::GetChildType(FX_DWORD index) const {
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize()) {
- return Invalid;
- }
- return (ChildType)(uintptr_t)m_Children.GetAt(index);
+ return index < m_Children.size() ? m_Children[index].type : Invalid;
}
CFX_WideString CXML_Element::GetContent(FX_DWORD index) const {
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize() ||
- (ChildType)(uintptr_t)m_Children.GetAt(index) != Content) {
- return CFX_WideString();
- }
- CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1);
- if (pContent) {
- return pContent->m_Content;
+ if (index < m_Children.size() && m_Children[index].type == Content) {
+ CXML_Content* pContent =
+ static_cast<CXML_Content*>(m_Children[index].child);
+ if (pContent)
+ return pContent->m_Content;
}
return CFX_WideString();
}
CXML_Element* CXML_Element::GetElement(FX_DWORD index) const {
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize() ||
- (ChildType)(uintptr_t)m_Children.GetAt(index) != Element) {
- return NULL;
+ if (index < m_Children.size() && m_Children[index].type == Element) {
+ return static_cast<CXML_Element*>(m_Children[index].child);
}
- return (CXML_Element*)m_Children.GetAt(index + 1);
+ return nullptr;
}
FX_DWORD CXML_Element::CountElements(const CFX_ByteStringC& space,
const CFX_ByteStringC& tag) const {
int count = 0;
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i);
- if (type != Element) {
+ for (const ChildRecord& record : m_Children) {
+ if (record.type != Element)
continue;
- }
- CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1);
+
+ CXML_Element* pKid = static_cast<CXML_Element*>(record.child);
if ((space.IsEmpty() || pKid->m_QSpaceName == space) &&
pKid->m_TagName == tag) {
count++;
@@ -737,31 +721,30 @@ FX_DWORD CXML_Element::CountElements(const CFX_ByteStringC& space,
CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space,
const CFX_ByteStringC& tag,
int index) const {
- if (index < 0) {
- return NULL;
- }
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i);
- if (type != Element) {
- continue;
- }
- CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1);
- if ((!space.IsEmpty() && pKid->m_QSpaceName != space) ||
- pKid->m_TagName != tag) {
+ if (index < 0)
+ return nullptr;
+
+ for (const ChildRecord& record : m_Children) {
+ if (record.type != Element)
continue;
- }
- if (index-- == 0) {
- return pKid;
+
+ CXML_Element* pKid = static_cast<CXML_Element*>(record.child);
+ if ((space.IsEmpty() || pKid->m_QSpaceName == space) &&
+ pKid->m_TagName == tag) {
+ if (index-- == 0)
+ return pKid;
}
}
return NULL;
}
FX_DWORD CXML_Element::FindElement(CXML_Element* pChild) const {
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- if ((ChildType)(uintptr_t)m_Children.GetAt(i) == Element &&
- (CXML_Element*)m_Children.GetAt(i + 1) == pChild) {
- return (FX_DWORD)(i >> 1);
+ int index = 0;
+ for (const ChildRecord& record : m_Children) {
+ if (record.type == Element &&
+ static_cast<CXML_Element*>(record.child) == pChild) {
+ return index;
}
+ ++index;
}
return (FX_DWORD)-1;
}