diff options
author | George Hazan <ghazan@miranda.im> | 2019-02-14 14:01:44 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-02-14 14:01:44 +0300 |
commit | 8368f365becd8668dbce2e40cecc7ba4f882f41b (patch) | |
tree | d446e441cf00d86f5cfb59ac5fd91cad6c0d37c8 | |
parent | 2a704d136a65cc39ead589a6bbbc99b28a4bab82 (diff) |
XML iterators, first version
-rw-r--r-- | include/m_xml.h | 128 | ||||
-rw-r--r-- | plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp | 23 | ||||
-rw-r--r-- | plugins/CurrencyRates/src/DBUtils.cpp | 2 | ||||
-rw-r--r-- | plugins/CurrencyRates/src/ImportExport.cpp | 20 |
4 files changed, 148 insertions, 25 deletions
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 @@ -45,6 +45,134 @@ 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
DECLARE_HANDLE(HXML);
diff --git a/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp b/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp index 41e9b00c88..dda1e9cc18 100644 --- a/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp +++ b/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp @@ -20,7 +20,7 @@ bool parse_currencyrate(const TiXmlNode *pTop, CCurrencyRatesProviderBase::CCurr { tstring sSymbol, sDescription, sID; - for (auto *pNode = pTop->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pTop)) { const char *sName = pNode->Value(); if (!mir_strcmpi(sName, "symbol")) { sSymbol = GetNodeText(pNode); @@ -47,7 +47,7 @@ bool parse_section(const TiXmlNode *pTop, CCurrencyRatesProviderBase::CCurrencyR CCurrencyRatesProviderBase::CCurrencyRateSection::TCurrencyRates aCurrencyRates; tstring sSectionName; - for (auto *pNode = pTop->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pTop)) { const char *sName = pNode->Value(); if (!mir_strcmpi(sName, "section")) { CCurrencyRatesProviderBase::CCurrencyRateSection qs1; @@ -72,21 +72,16 @@ bool parse_section(const TiXmlNode *pTop, CCurrencyRatesProviderBase::CCurrencyR const TiXmlNode* find_provider(const TiXmlNode *pRoot) { - const TiXmlNode *pProvider = nullptr; - - for (auto *pNode = pRoot->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pRoot)) { const char *sName = pNode->Value(); - if (!mir_strcmpi(sName, "Provider")) { - pProvider = pNode; - break; - } + if (!mir_strcmpi(sName, "Provider")) + return pNode; - pProvider = find_provider(pNode); - if (pProvider) - break; + if (auto *pProvider = find_provider(pNode)) + return pProvider; } - return pProvider; + return nullptr; } CCurrencyRatesProviderBase::CXMLFileInfo parse_ini_file(const tstring &rsXMLFile, bool &rbSucceded) @@ -99,7 +94,7 @@ CCurrencyRatesProviderBase::CXMLFileInfo parse_ini_file(const tstring &rsXMLFile const TiXmlNode *pProvider = find_provider(&doc); if (pProvider) { rbSucceded = true; - for (auto *pNode = pProvider->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pProvider)) { const char *sName = pNode->Value(); if (!mir_strcmpi(sName, "section")) { CCurrencyRatesProviderBase::CCurrencyRateSection qs; diff --git a/plugins/CurrencyRates/src/DBUtils.cpp b/plugins/CurrencyRates/src/DBUtils.cpp index 53e1f211b3..571bad0bfb 100644 --- a/plugins/CurrencyRates/src/DBUtils.cpp +++ b/plugins/CurrencyRates/src/DBUtils.cpp @@ -4,7 +4,7 @@ std::wstring GetNodeText(const TiXmlElement *pNode) { auto *pszText = pNode->GetText(); if (pszText) - return Utf2T(pszText); + return Utf2T(pszText).get(); return std::wstring(); } diff --git a/plugins/CurrencyRates/src/ImportExport.cpp b/plugins/CurrencyRates/src/ImportExport.cpp index 3087670e18..47bb3e1b40 100644 --- a/plugins/CurrencyRates/src/ImportExport.cpp +++ b/plugins/CurrencyRates/src/ImportExport.cpp @@ -253,7 +253,7 @@ bool handle_module(MCONTACT hContact, const TiXmlElement *pXmlModule) DBCONTACTWRITESETTING dbs; dbs.szModule = szModuleName; - for (auto *pSetting = pXmlModule->FirstChildElement(g_szXmlSetting); pSetting != nullptr; pSetting = pSetting->NextSiblingElement(g_szXmlSetting)) { + for (auto *pSetting : TiXmlFilter(pXmlModule, g_szXmlSetting)) { auto *pNode = pSetting->FirstChildElement(g_szXmlName); if (pNode == nullptr) continue; @@ -342,7 +342,7 @@ size_t count_contacts(const TiXmlNode *pXmlRoot, bool bInContactsGroup) { size_t cContacts = 0; - for (auto *pNode = pXmlRoot->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pXmlRoot)) { const char *sName = pNode->Name(); if (false == bInContactsGroup) { if (!mir_strcmpi(g_szXmlContacts, sName)) @@ -378,7 +378,7 @@ struct CContactState const TiXmlNode* find_currencyrates_module(const TiXmlNode *pXmlContact) { - for (auto *pNode = pXmlContact->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) + for (auto *pNode : TiXmlEnum(pXmlContact)) if ((!mir_strcmpi(g_szXmlModule, pNode->Name())) && (!mir_strcmpi(CURRENCYRATES_MODULE_NAME, pNode->GetText()))) return pNode; @@ -391,7 +391,7 @@ TNameValue parse_setting_node(const TiXmlNode *pXmlSetting) assert(pXmlSetting); const char *sName, *sValue; - for (auto *pNode = pXmlSetting->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pXmlSetting)) { if (!mir_strcmpi(g_szXmlName, pNode->Name())) sName = pNode->GetText(); else if (!mir_strcmpi(g_szXmlValue, pNode->Name())) @@ -403,7 +403,7 @@ TNameValue parse_setting_node(const TiXmlNode *pXmlSetting) CCurrencyRatesProviders::TCurrencyRatesProviderPtr find_provider(const TiXmlNode *pXmlCurrencyRatesModule) { - for (auto *pNode = pXmlCurrencyRatesModule->FirstChildElement(g_szXmlSetting); pNode != nullptr; pNode = pNode->NextSiblingElement(g_szXmlSetting)) { + for (auto *pNode : TiXmlFilter(pXmlCurrencyRatesModule, g_szXmlSetting)) { TNameValue Item = parse_setting_node(pNode); if ((!mir_strcmpi(DB_STR_CURRENCYRATE_PROVIDER, Item.first)) && Item.second) return CModuleInfo::GetCurrencyRateProvidersPtr()->FindProvider(Utf2T(Item.second).get()); @@ -429,7 +429,7 @@ bool get_contact_state(const TiXmlNode *pXmlContact, CContactState& cst) { const char *sFromID = nullptr, *sToID = nullptr; - for (auto *pNode = m_pXmlCurrencyRates->FirstChildElement(g_szXmlSetting); pNode != nullptr; pNode = pNode->NextSiblingElement(g_szXmlSetting)) { + for (auto *pNode : TiXmlFilter(m_pXmlCurrencyRates, g_szXmlSetting)) { TNameValue Item = parse_setting_node(pNode); if (!mir_strcmpi(Item.first, DB_STR_FROM_ID)) sFromID = Item.second; @@ -443,7 +443,7 @@ bool get_contact_state(const TiXmlNode *pXmlContact, CContactState& cst) tstring GetXMLNodeValue(const char* pszXMLNodeName) const { - for (auto *pNode = m_pXmlCurrencyRates->FirstChildElement(g_szXmlSetting); pNode != nullptr; pNode = pNode->NextSiblingElement(g_szXmlSetting)) { + for (auto *pNode : TiXmlFilter(m_pXmlCurrencyRates, g_szXmlSetting)) { TNameValue Item = parse_setting_node(pNode); if (!mir_strcmpi(Item.first, pszXMLNodeName)) return Utf2T(Item.second).get(); @@ -489,7 +489,7 @@ bool import_contact(const TiXmlNode *pXmlContact, CImportContext &impctx) if (!cst.m_hContact) return false; - for (auto *pNode = pXmlContact->FirstChildElement(g_szXmlModule); pNode != nullptr; pNode = pNode->NextSiblingElement(g_szXmlModule)) + for (auto *pNode : TiXmlFilter(pXmlContact, g_szXmlModule)) if (!handle_module(cst.m_hContact, pNode)) return false; @@ -503,7 +503,7 @@ bool import_contact(const TiXmlNode *pXmlContact, CImportContext &impctx) size_t import_contacts(const TiXmlNode *pXmlContacts, CImportContext &impctx) { size_t cContacts = 0; - for (auto *pNode = pXmlContacts->FirstChildElement(g_szXmlContact); pNode != nullptr; pNode = pNode->NextSiblingElement(g_szXmlContact)) + for (auto *pNode : TiXmlFilter(pXmlContacts, g_szXmlContact)) if (import_contact(pNode, impctx)) ++cContacts; @@ -513,7 +513,7 @@ size_t import_contacts(const TiXmlNode *pXmlContacts, CImportContext &impctx) size_t handle_contacts_node(const TiXmlNode *pXmlRoot, CImportContext& impctx) { size_t cContacts = 0; - for (auto *pNode = pXmlRoot->FirstChildElement(); pNode != nullptr; pNode = pNode->NextSiblingElement()) { + for (auto *pNode : TiXmlEnum(pXmlRoot)) { if (!mir_strcmpi(g_szXmlContacts, pNode->Name())) cContacts += import_contacts(pNode, impctx); else |