diff options
-rw-r--r-- | core/include/fxcrt/fx_xml.h | 40 | ||||
-rw-r--r-- | core/src/fxcrt/fx_xml_parser.cpp | 95 |
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; } |