diff options
Diffstat (limited to 'xbmc/utils/XMLUtils.cpp')
-rw-r--r-- | xbmc/utils/XMLUtils.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/xbmc/utils/XMLUtils.cpp b/xbmc/utils/XMLUtils.cpp new file mode 100644 index 0000000..8e8603e --- /dev/null +++ b/xbmc/utils/XMLUtils.cpp @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "XMLUtils.h" + +#include "StringUtils.h" +#include "URL.h" +#include "XBDateTime.h" + +bool XMLUtils::GetHex(const TiXmlNode* pRootNode, const char* strTag, uint32_t& hexValue) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + return sscanf(pNode->FirstChild()->Value(), "%x", &hexValue) == 1; +} + + +bool XMLUtils::GetUInt(const TiXmlNode* pRootNode, const char* strTag, uint32_t& uintValue) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + uintValue = atol(pNode->FirstChild()->Value()); + return true; +} + +bool XMLUtils::GetUInt(const TiXmlNode* pRootNode, const char* strTag, uint32_t &value, const uint32_t min, const uint32_t max) +{ + if (GetUInt(pRootNode, strTag, value)) + { + if (value < min) value = min; + if (value > max) value = max; + return true; + } + return false; +} + +bool XMLUtils::GetLong(const TiXmlNode* pRootNode, const char* strTag, long& lLongValue) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + lLongValue = atol(pNode->FirstChild()->Value()); + return true; +} + +bool XMLUtils::GetInt(const TiXmlNode* pRootNode, const char* strTag, int& iIntValue) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + iIntValue = atoi(pNode->FirstChild()->Value()); + return true; +} + +bool XMLUtils::GetInt(const TiXmlNode* pRootNode, const char* strTag, int &value, const int min, const int max) +{ + if (GetInt(pRootNode, strTag, value)) + { + if (value < min) value = min; + if (value > max) value = max; + return true; + } + return false; +} + +bool XMLUtils::GetDouble(const TiXmlNode* root, const char* tag, double& value) +{ + const TiXmlNode* node = root->FirstChild(tag); + if (!node || !node->FirstChild()) return false; + value = atof(node->FirstChild()->Value()); + return true; +} + +bool XMLUtils::GetFloat(const TiXmlNode* pRootNode, const char* strTag, float& value) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + value = (float)atof(pNode->FirstChild()->Value()); + return true; +} + +bool XMLUtils::GetFloat(const TiXmlNode* pRootElement, const char *tagName, float& fValue, const float fMin, const float fMax) +{ + if (GetFloat(pRootElement, tagName, fValue)) + { // check range + if (fValue < fMin) fValue = fMin; + if (fValue > fMax) fValue = fMax; + return true; + } + return false; +} + +bool XMLUtils::GetBoolean(const TiXmlNode* pRootNode, const char* strTag, bool& bBoolValue) +{ + const TiXmlNode* pNode = pRootNode->FirstChild(strTag ); + if (!pNode || !pNode->FirstChild()) return false; + std::string strEnabled = pNode->FirstChild()->ValueStr(); + StringUtils::ToLower(strEnabled); + if (strEnabled == "off" || strEnabled == "no" || strEnabled == "disabled" || strEnabled == "false" || strEnabled == "0" ) + bBoolValue = false; + else + { + bBoolValue = true; + if (strEnabled != "on" && strEnabled != "yes" && strEnabled != "enabled" && strEnabled != "true") + return false; // invalid bool switch - it's probably some other string. + } + return true; +} + +bool XMLUtils::GetString(const TiXmlNode* pRootNode, const char* strTag, std::string& strStringValue) +{ + const TiXmlElement* pElement = pRootNode->FirstChildElement(strTag); + if (!pElement) return false; + + const char* encoded = pElement->Attribute("urlencoded"); + const TiXmlNode* pNode = pElement->FirstChild(); + if (pNode != NULL) + { + strStringValue = pNode->ValueStr(); + if (encoded && StringUtils::CompareNoCase(encoded, "yes") == 0) + strStringValue = CURL::Decode(strStringValue); + return true; + } + strStringValue.clear(); + return true; +} + +std::string XMLUtils::GetString(const TiXmlNode* pRootNode, const char* strTag) +{ + std::string temp; + GetString(pRootNode, strTag, temp); + return temp; +} + +bool XMLUtils::HasChild(const TiXmlNode* pRootNode, const char* strTag) +{ + const TiXmlElement* pElement = pRootNode->FirstChildElement(strTag); + if (!pElement) return false; + const TiXmlNode* pNode = pElement->FirstChild(); + return (pNode != NULL); +} + +bool XMLUtils::GetAdditiveString(const TiXmlNode* pRootNode, const char* strTag, + const std::string& strSeparator, std::string& strStringValue, + bool clear) +{ + std::string strTemp; + const TiXmlElement* node = pRootNode->FirstChildElement(strTag); + bool bResult=false; + if (node && node->FirstChild() && clear) + strStringValue.clear(); + while (node) + { + if (node->FirstChild()) + { + bResult = true; + strTemp = node->FirstChild()->Value(); + const char* clear=node->Attribute("clear"); + if (strStringValue.empty() || (clear && StringUtils::CompareNoCase(clear, "true") == 0)) + strStringValue = strTemp; + else + strStringValue += strSeparator+strTemp; + } + node = node->NextSiblingElement(strTag); + } + + return bResult; +} + +/*! + Parses the XML for multiple tags of the given name. + Does not clear the array to support chaining. +*/ +bool XMLUtils::GetStringArray(const TiXmlNode* pRootNode, const char* strTag, std::vector<std::string>& arrayValue, bool clear /* = false */, const std::string& separator /* = "" */) +{ + std::string strTemp; + const TiXmlElement* node = pRootNode->FirstChildElement(strTag); + bool bResult=false; + if (node && node->FirstChild() && clear) + arrayValue.clear(); + while (node) + { + if (node->FirstChild()) + { + bResult = true; + strTemp = node->FirstChild()->ValueStr(); + + const char* clearAttr = node->Attribute("clear"); + if (clearAttr && StringUtils::CompareNoCase(clearAttr, "true") == 0) + arrayValue.clear(); + + if (strTemp.empty()) + continue; + + if (separator.empty()) + arrayValue.push_back(strTemp); + else + { + std::vector<std::string> tempArray = StringUtils::Split(strTemp, separator); + arrayValue.insert(arrayValue.end(), tempArray.begin(), tempArray.end()); + } + } + node = node->NextSiblingElement(strTag); + } + + return bResult; +} + +bool XMLUtils::GetPath(const TiXmlNode* pRootNode, const char* strTag, std::string& strStringValue) +{ + const TiXmlElement* pElement = pRootNode->FirstChildElement(strTag); + if (!pElement) return false; + + const char* encoded = pElement->Attribute("urlencoded"); + const TiXmlNode* pNode = pElement->FirstChild(); + if (pNode != NULL) + { + strStringValue = pNode->Value(); + if (encoded && StringUtils::CompareNoCase(encoded, "yes") == 0) + strStringValue = CURL::Decode(strStringValue); + return true; + } + strStringValue.clear(); + return false; +} + +bool XMLUtils::GetDate(const TiXmlNode* pRootNode, const char* strTag, CDateTime& date) +{ + std::string strDate; + if (GetString(pRootNode, strTag, strDate) && !strDate.empty()) + { + date.SetFromDBDate(strDate); + return true; + } + + return false; +} + +bool XMLUtils::GetDateTime(const TiXmlNode* pRootNode, const char* strTag, CDateTime& dateTime) +{ + std::string strDateTime; + if (GetString(pRootNode, strTag, strDateTime) && !strDateTime.empty()) + { + dateTime.SetFromDBDateTime(strDateTime); + return true; + } + + return false; +} + +std::string XMLUtils::GetAttribute(const TiXmlElement *element, const char *tag) +{ + if (element) + { + const char *attribute = element->Attribute(tag); + if (attribute) + return attribute; + } + return ""; +} + +void XMLUtils::SetAdditiveString(TiXmlNode* pRootNode, const char *strTag, const std::string& strSeparator, const std::string& strValue) +{ + std::vector<std::string> list = StringUtils::Split(strValue, strSeparator); + for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i) + SetString(pRootNode, strTag, *i); +} + +void XMLUtils::SetStringArray(TiXmlNode* pRootNode, const char *strTag, const std::vector<std::string>& arrayValue) +{ + for (unsigned int i = 0; i < arrayValue.size(); i++) + SetString(pRootNode, strTag, arrayValue.at(i)); +} + +TiXmlNode* XMLUtils::SetString(TiXmlNode* pRootNode, const char *strTag, const std::string& strValue) +{ + TiXmlElement newElement(strTag); + TiXmlNode *pNewNode = pRootNode->InsertEndChild(newElement); + if (pNewNode) + { + TiXmlText value(strValue); + pNewNode->InsertEndChild(value); + } + return pNewNode; +} + +TiXmlNode* XMLUtils::SetInt(TiXmlNode* pRootNode, const char *strTag, int value) +{ + std::string strValue = std::to_string(value); + return SetString(pRootNode, strTag, strValue); +} + +void XMLUtils::SetLong(TiXmlNode* pRootNode, const char *strTag, long value) +{ + std::string strValue = std::to_string(value); + SetString(pRootNode, strTag, strValue); +} + +TiXmlNode* XMLUtils::SetFloat(TiXmlNode* pRootNode, const char *strTag, float value) +{ + std::string strValue = StringUtils::Format("{:f}", value); + return SetString(pRootNode, strTag, strValue); +} + +TiXmlNode* XMLUtils::SetDouble(TiXmlNode* pRootNode, const char* strTag, double value) +{ + std::string strValue = StringUtils::Format("{:f}", value); + return SetString(pRootNode, strTag, strValue); +} + +void XMLUtils::SetBoolean(TiXmlNode* pRootNode, const char *strTag, bool value) +{ + SetString(pRootNode, strTag, value ? "true" : "false"); +} + +void XMLUtils::SetHex(TiXmlNode* pRootNode, const char *strTag, uint32_t value) +{ + std::string strValue = StringUtils::Format("{:x}", value); + SetString(pRootNode, strTag, strValue); +} + +void XMLUtils::SetPath(TiXmlNode* pRootNode, const char *strTag, const std::string& strValue) +{ + TiXmlElement newElement(strTag); + newElement.SetAttribute("pathversion", path_version); + TiXmlNode *pNewNode = pRootNode->InsertEndChild(newElement); + if (pNewNode) + { + TiXmlText value(strValue); + pNewNode->InsertEndChild(value); + } +} + +void XMLUtils::SetDate(TiXmlNode* pRootNode, const char *strTag, const CDateTime& date) +{ + SetString(pRootNode, strTag, date.IsValid() ? date.GetAsDBDate() : ""); +} + +void XMLUtils::SetDateTime(TiXmlNode* pRootNode, const char *strTag, const CDateTime& dateTime) +{ + SetString(pRootNode, strTag, dateTime.IsValid() ? dateTime.GetAsDBDateTime() : ""); +} |