From 8368f365becd8668dbce2e40cecc7ba4f882f41b Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 14 Feb 2019 14:01:44 +0300 Subject: XML iterators, first version --- include/m_xml.h | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) (limited to 'include') diff --git a/include/m_xml.h b/include/m_xml.h index 1c8dffc1f5..ee50229082 100644 --- a/include/m_xml.h +++ b/include/m_xml.h @@ -44,6 +44,134 @@ typedef tinyxml2::XMLText TiXmlText; typedef tinyxml2::XMLElement TiXmlElement; typedef tinyxml2::XMLDocument TiXmlDocument; +///////////////////////////////////////////////////////////////////////////////////////// +// simple element iterator +// +// allows traversing subnodes in a cycle like +// for (auto *pNode : TiXmlEnum(pRoot)) { + +class TiXmlIterator +{ + const TiXmlElement *m_pCurr; + +public: + TiXmlIterator(const TiXmlElement *pNode) : + m_pCurr(pNode) + { + } + + TiXmlIterator& operator=(const TiXmlElement *pNode) + { + m_pCurr = pNode; + return *this; + } + + // Prefix ++ overload + TiXmlIterator& operator++() + { + if (m_pCurr) + m_pCurr = m_pCurr->NextSiblingElement(); + return *this; + } + + const TiXmlElement* operator*() + { + return m_pCurr; + } + + bool operator!=(const TiXmlIterator &iterator) + { + return m_pCurr != iterator.m_pCurr; + } +}; + +class TiXmlEnum +{ + const TiXmlElement *m_pFirst; + +public: + TiXmlEnum(const TiXmlNode *pNode) + { + m_pFirst = (pNode) ? pNode->FirstChildElement() : nullptr; + } + + TiXmlIterator begin() + { + return TiXmlIterator(m_pFirst); + } + + TiXmlIterator end() + { + return TiXmlIterator(nullptr); + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// filtered element iterator +// +// allows traversing subnodes of the specified name in a cycle like +// for (auto *pNode : TiXmlFilter(pRoot, "element")) { + +class TiXmlFilterIterator +{ + const TiXmlElement *m_pCurr; + const char *m_pszFilter; + +public: + TiXmlFilterIterator(const TiXmlElement *pNode, const char *pszNodeName) : + m_pszFilter(pszNodeName), + m_pCurr(pNode) + { + } + + TiXmlFilterIterator& operator=(const TiXmlElement *pNode) + { + m_pCurr = pNode; + return *this; + } + + // Prefix ++ overload + TiXmlFilterIterator& operator++() + { + if (m_pCurr) + m_pCurr = m_pCurr->NextSiblingElement(m_pszFilter); + return *this; + } + + const TiXmlElement* operator*() + { + return m_pCurr; + } + + bool operator!=(const TiXmlFilterIterator &iterator) + { + return m_pCurr != iterator.m_pCurr; + } +}; + +class TiXmlFilter +{ + const TiXmlElement *m_pFirst; + const char *m_pszFilter; + +public: + TiXmlFilter(const TiXmlNode *pNode, const char *pszNodeName) : + m_pszFilter(pszNodeName) + { + m_pFirst = (pNode) ? pNode->FirstChildElement() : nullptr; + } + + TiXmlFilterIterator begin() + { + return TiXmlFilterIterator(m_pFirst, m_pszFilter); + } + + TiXmlFilterIterator end() + { + return TiXmlFilterIterator(nullptr, nullptr); + } +}; + ///////////////////////////////////////////////////////////////////////////////////////// // old API to be removed once -- cgit v1.2.3