summaryrefslogtreecommitdiffstats
path: root/upstream/xmlserializer/XmlElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/xmlserializer/XmlElement.cpp')
-rw-r--r--upstream/xmlserializer/XmlElement.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/upstream/xmlserializer/XmlElement.cpp b/upstream/xmlserializer/XmlElement.cpp
new file mode 100644
index 0000000..902d0d9
--- /dev/null
+++ b/upstream/xmlserializer/XmlElement.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2011-2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "XmlElement.h"
+#include <libxml/tree.h>
+#include "convert.hpp"
+#include <stdlib.h>
+
+using std::string;
+
+CXmlElement::CXmlElement(_xmlNode *pXmlElement) : _pXmlElement(pXmlElement)
+{
+}
+
+CXmlElement::CXmlElement() : _pXmlElement(NULL)
+{
+}
+
+void CXmlElement::setXmlElement(_xmlNode *pXmlElement)
+{
+ _pXmlElement = pXmlElement;
+}
+
+string CXmlElement::getType() const
+{
+ return (const char *)_pXmlElement->name;
+}
+
+string CXmlElement::getPath() const
+{
+ string strPathElement = "/" + getType();
+
+ if (hasAttribute("Name")) {
+
+ strPathElement += "[@Name=" + getNameAttribute() + "]";
+ }
+
+ CXmlElement parentElement;
+
+ if (getParentElement(parentElement)) {
+
+ // Done
+ return parentElement.getPath() + strPathElement;
+ }
+ return strPathElement;
+}
+
+bool CXmlElement::hasAttribute(const string &strAttributeName) const
+{
+ return xmlHasProp(_pXmlElement, (const xmlChar *)strAttributeName.c_str()) != NULL;
+}
+
+template <>
+bool CXmlElement::getAttribute<std::string>(const string &name, string &value) const
+{
+ if (!hasAttribute(name)) {
+ return false;
+ }
+
+ string backup = value;
+ xmlChar *pucXmlValue = xmlGetProp((xmlNode *)_pXmlElement, (const xmlChar *)name.c_str());
+ if (pucXmlValue == NULL) {
+ value = backup;
+ return false;
+ }
+
+ value = (const char *)pucXmlValue;
+
+ xmlFree(pucXmlValue);
+
+ return true;
+}
+
+template <typename T>
+bool CXmlElement::getAttribute(const std::string &name, T &value) const
+{
+ std::string rawValue;
+ if (!getAttribute(name, rawValue)) {
+ return false;
+ }
+
+ T backup = value;
+ if (!convertTo<T>(rawValue, value)) {
+ value = backup;
+ return false;
+ }
+
+ return true;
+}
+
+string CXmlElement::getNameAttribute() const
+{
+ string attribute;
+ getAttribute("Name", attribute);
+ return attribute;
+}
+
+string CXmlElement::getTextContent() const
+{
+ xmlChar *pucXmlContent = xmlNodeGetContent(_pXmlElement);
+ if (pucXmlContent == NULL) {
+ return "";
+ }
+
+ string strContent((const char *)pucXmlContent);
+
+ xmlFree(pucXmlContent);
+
+ return strContent;
+}
+
+bool CXmlElement::getChildElement(const string &strType, CXmlElement &childElement) const
+{
+ CChildIterator childIterator(*this);
+
+ while (childIterator.next(childElement)) {
+
+ if (childElement.getType() == strType) {
+
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CXmlElement::getChildElement(const string &strType, const string &strNameAttribute,
+ CXmlElement &childElement) const
+{
+ CChildIterator childIterator(*this);
+
+ while (childIterator.next(childElement)) {
+
+ if ((childElement.getType() == strType) &&
+ (childElement.getNameAttribute() == strNameAttribute)) {
+
+ return true;
+ }
+ }
+ return false;
+}
+
+size_t CXmlElement::getNbChildElements() const
+{
+ CXmlElement childElement;
+ size_t uiNbChildren = 0;
+
+ CChildIterator childIterator(*this);
+
+ while (childIterator.next(childElement)) {
+
+ uiNbChildren++;
+ }
+ return uiNbChildren;
+}
+
+bool CXmlElement::getParentElement(CXmlElement &parentElement) const
+{
+ _xmlNode *pXmlNode = _pXmlElement->parent;
+
+ if (pXmlNode->type == XML_ELEMENT_NODE) {
+
+ parentElement.setXmlElement(pXmlNode);
+
+ return true;
+ }
+ return false;
+}
+
+template <>
+void CXmlElement::setAttribute<bool>(const string &name, const bool &value)
+{
+ setAttribute(name, value ? "true" : "false");
+}
+
+template <>
+void CXmlElement::setAttribute<std::string>(const string &name, const string &value)
+{
+ setAttribute(name, value.c_str());
+}
+
+// This method exists for 2 reasons:
+// - at link time, all calls to setAttribute(const string&, const char [N])
+// for any value of N will all resolve to this method; this prevents the
+// need for one template instance per value of N.
+// - the libxml2 API takes a C-style string anyway.
+void CXmlElement::setAttribute(const string &name, const char *value)
+{
+ xmlNewProp(_pXmlElement, BAD_CAST name.c_str(), BAD_CAST value);
+}
+
+template <typename T>
+void CXmlElement::setAttribute(const std::string &name, const T &value)
+{
+ setAttribute(name, std::to_string(value).c_str());
+}
+
+void CXmlElement::setNameAttribute(const string &strValue)
+{
+ setAttribute("Name", strValue);
+}
+
+void CXmlElement::setTextContent(const string &strContent)
+{
+ xmlAddChild(_pXmlElement, xmlNewText(BAD_CAST strContent.c_str()));
+}
+
+// Child creation
+void CXmlElement::createChild(CXmlElement &childElement, const string &strType)
+{
+#ifdef LIBXML_TREE_ENABLED
+ xmlNodePtr pChildNode = xmlNewChild(_pXmlElement, NULL, BAD_CAST strType.c_str(), NULL);
+
+ childElement.setXmlElement(pChildNode);
+#endif
+}
+
+// Child iteration
+CXmlElement::CChildIterator::CChildIterator(const CXmlElement &xmlElement)
+ : _pCurNode(xmlElement._pXmlElement->children)
+{
+}
+
+bool CXmlElement::CChildIterator::next(CXmlElement &xmlChildElement)
+{
+ while (_pCurNode) {
+
+ if (_pCurNode->type == XML_ELEMENT_NODE) {
+
+ xmlChildElement.setXmlElement(_pCurNode);
+
+ _pCurNode = _pCurNode->next;
+
+ return true;
+ }
+ _pCurNode = _pCurNode->next;
+ }
+
+ return false;
+}
+
+template bool CXmlElement::getAttribute(const std::string &name, std::string &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, bool &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, short &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, unsigned short &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, int &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, unsigned int &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, long &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, unsigned long &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, long long &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, unsigned long long &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, float &value) const;
+template bool CXmlElement::getAttribute(const std::string &name, double &value) const;
+
+template void CXmlElement::setAttribute(const std::string &name, const std::string &value);
+template void CXmlElement::setAttribute(const std::string &name, const bool &value);
+template void CXmlElement::setAttribute(const std::string &name, const short &value);
+template void CXmlElement::setAttribute(const std::string &name, const unsigned short &value);
+template void CXmlElement::setAttribute(const std::string &name, const int &value);
+template void CXmlElement::setAttribute(const std::string &name, const unsigned int &value);
+template void CXmlElement::setAttribute(const std::string &name, const long &value);
+template void CXmlElement::setAttribute(const std::string &name, const unsigned long &value);
+template void CXmlElement::setAttribute(const std::string &name, const long long &value);
+template void CXmlElement::setAttribute(const std::string &name, const unsigned long long &value);
+template void CXmlElement::setAttribute(const std::string &name, const float &value);
+template void CXmlElement::setAttribute(const std::string &name, const double &value);