2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "StringUtils.h"
13 #include "XBDateTime.h"
15 bool XMLUtils::GetHex(const TiXmlNode
* pRootNode
, const char* strTag
, uint32_t& hexValue
)
17 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
18 if (!pNode
|| !pNode
->FirstChild()) return false;
19 return sscanf(pNode
->FirstChild()->Value(), "%x", &hexValue
) == 1;
23 bool XMLUtils::GetUInt(const TiXmlNode
* pRootNode
, const char* strTag
, uint32_t& uintValue
)
25 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
26 if (!pNode
|| !pNode
->FirstChild()) return false;
27 uintValue
= atol(pNode
->FirstChild()->Value());
31 bool XMLUtils::GetUInt(const TiXmlNode
* pRootNode
, const char* strTag
, uint32_t &value
, const uint32_t min
, const uint32_t max
)
33 if (GetUInt(pRootNode
, strTag
, value
))
35 if (value
< min
) value
= min
;
36 if (value
> max
) value
= max
;
42 bool XMLUtils::GetLong(const TiXmlNode
* pRootNode
, const char* strTag
, long& lLongValue
)
44 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
45 if (!pNode
|| !pNode
->FirstChild()) return false;
46 lLongValue
= atol(pNode
->FirstChild()->Value());
50 bool XMLUtils::GetInt(const TiXmlNode
* pRootNode
, const char* strTag
, int& iIntValue
)
52 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
53 if (!pNode
|| !pNode
->FirstChild()) return false;
54 iIntValue
= atoi(pNode
->FirstChild()->Value());
58 bool XMLUtils::GetInt(const TiXmlNode
* pRootNode
, const char* strTag
, int &value
, const int min
, const int max
)
60 if (GetInt(pRootNode
, strTag
, value
))
62 if (value
< min
) value
= min
;
63 if (value
> max
) value
= max
;
69 bool XMLUtils::GetDouble(const TiXmlNode
* root
, const char* tag
, double& value
)
71 const TiXmlNode
* node
= root
->FirstChild(tag
);
72 if (!node
|| !node
->FirstChild()) return false;
73 value
= atof(node
->FirstChild()->Value());
77 bool XMLUtils::GetFloat(const TiXmlNode
* pRootNode
, const char* strTag
, float& value
)
79 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
80 if (!pNode
|| !pNode
->FirstChild()) return false;
81 value
= (float)atof(pNode
->FirstChild()->Value());
85 bool XMLUtils::GetFloat(const TiXmlNode
* pRootElement
, const char *tagName
, float& fValue
, const float fMin
, const float fMax
)
87 if (GetFloat(pRootElement
, tagName
, fValue
))
89 if (fValue
< fMin
) fValue
= fMin
;
90 if (fValue
> fMax
) fValue
= fMax
;
96 bool XMLUtils::GetBoolean(const TiXmlNode
* pRootNode
, const char* strTag
, bool& bBoolValue
)
98 const TiXmlNode
* pNode
= pRootNode
->FirstChild(strTag
);
99 if (!pNode
|| !pNode
->FirstChild()) return false;
100 std::string strEnabled
= pNode
->FirstChild()->ValueStr();
101 StringUtils::ToLower(strEnabled
);
102 if (strEnabled
== "off" || strEnabled
== "no" || strEnabled
== "disabled" || strEnabled
== "false" || strEnabled
== "0" )
107 if (strEnabled
!= "on" && strEnabled
!= "yes" && strEnabled
!= "enabled" && strEnabled
!= "true")
108 return false; // invalid bool switch - it's probably some other string.
113 bool XMLUtils::GetString(const TiXmlNode
* pRootNode
, const char* strTag
, std::string
& strStringValue
)
115 const TiXmlElement
* pElement
= pRootNode
->FirstChildElement(strTag
);
116 if (!pElement
) return false;
118 const char* encoded
= pElement
->Attribute("urlencoded");
119 const TiXmlNode
* pNode
= pElement
->FirstChild();
122 strStringValue
= pNode
->ValueStr();
123 if (encoded
&& StringUtils::CompareNoCase(encoded
, "yes") == 0)
124 strStringValue
= CURL::Decode(strStringValue
);
127 strStringValue
.clear();
131 std::string
XMLUtils::GetString(const TiXmlNode
* pRootNode
, const char* strTag
)
134 GetString(pRootNode
, strTag
, temp
);
138 bool XMLUtils::HasChild(const TiXmlNode
* pRootNode
, const char* strTag
)
140 const TiXmlElement
* pElement
= pRootNode
->FirstChildElement(strTag
);
141 if (!pElement
) return false;
142 const TiXmlNode
* pNode
= pElement
->FirstChild();
143 return (pNode
!= NULL
);
146 bool XMLUtils::GetAdditiveString(const TiXmlNode
* pRootNode
, const char* strTag
,
147 const std::string
& strSeparator
, std::string
& strStringValue
,
151 const TiXmlElement
* node
= pRootNode
->FirstChildElement(strTag
);
153 if (node
&& node
->FirstChild() && clear
)
154 strStringValue
.clear();
157 if (node
->FirstChild())
160 strTemp
= node
->FirstChild()->Value();
161 const char* clear
=node
->Attribute("clear");
162 if (strStringValue
.empty() || (clear
&& StringUtils::CompareNoCase(clear
, "true") == 0))
163 strStringValue
= strTemp
;
165 strStringValue
+= strSeparator
+strTemp
;
167 node
= node
->NextSiblingElement(strTag
);
174 Parses the XML for multiple tags of the given name.
175 Does not clear the array to support chaining.
177 bool XMLUtils::GetStringArray(const TiXmlNode
* pRootNode
, const char* strTag
, std::vector
<std::string
>& arrayValue
, bool clear
/* = false */, const std::string
& separator
/* = "" */)
180 const TiXmlElement
* node
= pRootNode
->FirstChildElement(strTag
);
182 if (node
&& node
->FirstChild() && clear
)
186 if (node
->FirstChild())
189 strTemp
= node
->FirstChild()->ValueStr();
191 const char* clearAttr
= node
->Attribute("clear");
192 if (clearAttr
&& StringUtils::CompareNoCase(clearAttr
, "true") == 0)
198 if (separator
.empty())
199 arrayValue
.push_back(strTemp
);
202 std::vector
<std::string
> tempArray
= StringUtils::Split(strTemp
, separator
);
203 arrayValue
.insert(arrayValue
.end(), tempArray
.begin(), tempArray
.end());
206 node
= node
->NextSiblingElement(strTag
);
212 bool XMLUtils::GetPath(const TiXmlNode
* pRootNode
, const char* strTag
, std::string
& strStringValue
)
214 const TiXmlElement
* pElement
= pRootNode
->FirstChildElement(strTag
);
215 if (!pElement
) return false;
217 const char* encoded
= pElement
->Attribute("urlencoded");
218 const TiXmlNode
* pNode
= pElement
->FirstChild();
221 strStringValue
= pNode
->Value();
222 if (encoded
&& StringUtils::CompareNoCase(encoded
, "yes") == 0)
223 strStringValue
= CURL::Decode(strStringValue
);
226 strStringValue
.clear();
230 bool XMLUtils::GetDate(const TiXmlNode
* pRootNode
, const char* strTag
, CDateTime
& date
)
233 if (GetString(pRootNode
, strTag
, strDate
) && !strDate
.empty())
235 date
.SetFromDBDate(strDate
);
242 bool XMLUtils::GetDateTime(const TiXmlNode
* pRootNode
, const char* strTag
, CDateTime
& dateTime
)
244 std::string strDateTime
;
245 if (GetString(pRootNode
, strTag
, strDateTime
) && !strDateTime
.empty())
247 dateTime
.SetFromDBDateTime(strDateTime
);
254 std::string
XMLUtils::GetAttribute(const TiXmlElement
*element
, const char *tag
)
258 const char *attribute
= element
->Attribute(tag
);
265 void XMLUtils::SetAdditiveString(TiXmlNode
* pRootNode
, const char *strTag
, const std::string
& strSeparator
, const std::string
& strValue
)
267 std::vector
<std::string
> list
= StringUtils::Split(strValue
, strSeparator
);
268 for (std::vector
<std::string
>::const_iterator i
= list
.begin(); i
!= list
.end(); ++i
)
269 SetString(pRootNode
, strTag
, *i
);
272 void XMLUtils::SetStringArray(TiXmlNode
* pRootNode
, const char *strTag
, const std::vector
<std::string
>& arrayValue
)
274 for (unsigned int i
= 0; i
< arrayValue
.size(); i
++)
275 SetString(pRootNode
, strTag
, arrayValue
.at(i
));
278 TiXmlNode
* XMLUtils::SetString(TiXmlNode
* pRootNode
, const char *strTag
, const std::string
& strValue
)
280 TiXmlElement
newElement(strTag
);
281 TiXmlNode
*pNewNode
= pRootNode
->InsertEndChild(newElement
);
284 TiXmlText
value(strValue
);
285 pNewNode
->InsertEndChild(value
);
290 TiXmlNode
* XMLUtils::SetInt(TiXmlNode
* pRootNode
, const char *strTag
, int value
)
292 std::string strValue
= std::to_string(value
);
293 return SetString(pRootNode
, strTag
, strValue
);
296 void XMLUtils::SetLong(TiXmlNode
* pRootNode
, const char *strTag
, long value
)
298 std::string strValue
= std::to_string(value
);
299 SetString(pRootNode
, strTag
, strValue
);
302 TiXmlNode
* XMLUtils::SetFloat(TiXmlNode
* pRootNode
, const char *strTag
, float value
)
304 std::string strValue
= StringUtils::Format("{:f}", value
);
305 return SetString(pRootNode
, strTag
, strValue
);
308 TiXmlNode
* XMLUtils::SetDouble(TiXmlNode
* pRootNode
, const char* strTag
, double value
)
310 std::string strValue
= StringUtils::Format("{:f}", value
);
311 return SetString(pRootNode
, strTag
, strValue
);
314 void XMLUtils::SetBoolean(TiXmlNode
* pRootNode
, const char *strTag
, bool value
)
316 SetString(pRootNode
, strTag
, value
? "true" : "false");
319 void XMLUtils::SetHex(TiXmlNode
* pRootNode
, const char *strTag
, uint32_t value
)
321 std::string strValue
= StringUtils::Format("{:x}", value
);
322 SetString(pRootNode
, strTag
, strValue
);
325 void XMLUtils::SetPath(TiXmlNode
* pRootNode
, const char *strTag
, const std::string
& strValue
)
327 TiXmlElement
newElement(strTag
);
328 newElement
.SetAttribute("pathversion", path_version
);
329 TiXmlNode
*pNewNode
= pRootNode
->InsertEndChild(newElement
);
332 TiXmlText
value(strValue
);
333 pNewNode
->InsertEndChild(value
);
337 void XMLUtils::SetDate(TiXmlNode
* pRootNode
, const char *strTag
, const CDateTime
& date
)
339 SetString(pRootNode
, strTag
, date
.IsValid() ? date
.GetAsDBDate() : "");
342 void XMLUtils::SetDateTime(TiXmlNode
* pRootNode
, const char *strTag
, const CDateTime
& dateTime
)
344 SetString(pRootNode
, strTag
, dateTime
.IsValid() ? dateTime
.GetAsDBDateTime() : "");