diff options
Diffstat (limited to 'source/Host/common/XML.cpp')
-rw-r--r-- | source/Host/common/XML.cpp | 944 |
1 files changed, 392 insertions, 552 deletions
diff --git a/source/Host/common/XML.cpp b/source/Host/common/XML.cpp index dc9cb0bc5a33..c637d938dffa 100644 --- a/source/Host/common/XML.cpp +++ b/source/Host/common/XML.cpp @@ -7,685 +7,525 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> /* atof */ +#include <stdlib.h> /* atof */ -#include "lldb/Host/XML.h" #include "lldb/Host/StringConvert.h" +#include "lldb/Host/XML.h" using namespace lldb; using namespace lldb_private; +#pragma mark-- XMLDocument -#pragma mark -- XMLDocument - -XMLDocument::XMLDocument () : - m_document (nullptr) -{ -} +XMLDocument::XMLDocument() : m_document(nullptr) {} -XMLDocument::~XMLDocument () -{ - Clear(); -} +XMLDocument::~XMLDocument() { Clear(); } -void -XMLDocument::Clear() -{ -#if defined( LIBXML2_DEFINED ) - if (m_document) - { - xmlDocPtr doc = m_document; - m_document = nullptr; - xmlFreeDoc(doc); - } +void XMLDocument::Clear() { +#if defined(LIBXML2_DEFINED) + if (m_document) { + xmlDocPtr doc = m_document; + m_document = nullptr; + xmlFreeDoc(doc); + } #endif } -bool -XMLDocument::IsValid() const -{ - return m_document != nullptr; -} +bool XMLDocument::IsValid() const { return m_document != nullptr; } -void -XMLDocument::ErrorCallback (void *ctx, const char *format, ...) -{ - XMLDocument *document = (XMLDocument *)ctx; - va_list args; - va_start (args, format); - document->m_errors.PrintfVarArg(format, args); - document->m_errors.EOL(); - va_end (args); +void XMLDocument::ErrorCallback(void *ctx, const char *format, ...) { + XMLDocument *document = (XMLDocument *)ctx; + va_list args; + va_start(args, format); + document->m_errors.PrintfVarArg(format, args); + document->m_errors.EOL(); + va_end(args); } -bool -XMLDocument::ParseFile (const char *path) -{ -#if defined( LIBXML2_DEFINED ) - Clear(); - xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback ); - m_document = xmlParseFile(path); - xmlSetGenericErrorFunc(nullptr, nullptr); +bool XMLDocument::ParseFile(const char *path) { +#if defined(LIBXML2_DEFINED) + Clear(); + xmlSetGenericErrorFunc((void *)this, XMLDocument::ErrorCallback); + m_document = xmlParseFile(path); + xmlSetGenericErrorFunc(nullptr, nullptr); #endif - return IsValid(); + return IsValid(); } -bool -XMLDocument::ParseMemory (const char *xml, size_t xml_length, const char *url) -{ -#if defined( LIBXML2_DEFINED ) - Clear(); - xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback ); - m_document = xmlReadMemory(xml, (int)xml_length, url, nullptr, 0); - xmlSetGenericErrorFunc(nullptr, nullptr); +bool XMLDocument::ParseMemory(const char *xml, size_t xml_length, + const char *url) { +#if defined(LIBXML2_DEFINED) + Clear(); + xmlSetGenericErrorFunc((void *)this, XMLDocument::ErrorCallback); + m_document = xmlReadMemory(xml, (int)xml_length, url, nullptr, 0); + xmlSetGenericErrorFunc(nullptr, nullptr); #endif - return IsValid(); - -} - -XMLNode -XMLDocument::GetRootElement(const char *required_name) -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - XMLNode root_node(xmlDocGetRootElement(m_document)); - if (required_name) - { - llvm::StringRef actual_name = root_node.GetName(); - if (actual_name == required_name) - return root_node; - } - else - { - return root_node; - } + return IsValid(); +} + +XMLNode XMLDocument::GetRootElement(const char *required_name) { +#if defined(LIBXML2_DEFINED) + if (IsValid()) { + XMLNode root_node(xmlDocGetRootElement(m_document)); + if (required_name) { + llvm::StringRef actual_name = root_node.GetName(); + if (actual_name == required_name) + return root_node; + } else { + return root_node; } + } #endif - return XMLNode(); + return XMLNode(); } -const std::string & -XMLDocument::GetErrors() const -{ - return m_errors.GetString(); -} +llvm::StringRef XMLDocument::GetErrors() const { return m_errors.GetString(); } -bool -XMLDocument::XMLEnabled () -{ -#if defined( LIBXML2_DEFINED ) - return true; +bool XMLDocument::XMLEnabled() { +#if defined(LIBXML2_DEFINED) + return true; #else - return false; + return false; #endif } -#pragma mark -- XMLNode +#pragma mark-- XMLNode -XMLNode::XMLNode() : - m_node(nullptr) -{ -} +XMLNode::XMLNode() : m_node(nullptr) {} -XMLNode::XMLNode(XMLNodeImpl node) : - m_node(node) -{ -} +XMLNode::XMLNode(XMLNodeImpl node) : m_node(node) {} -XMLNode::~XMLNode() -{ - -} +XMLNode::~XMLNode() {} -void -XMLNode::Clear() -{ - m_node = nullptr; -} +void XMLNode::Clear() { m_node = nullptr; } -XMLNode -XMLNode::GetParent() const -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - return XMLNode(m_node->parent); - else - return XMLNode(); -#else +XMLNode XMLNode::GetParent() const { +#if defined(LIBXML2_DEFINED) + if (IsValid()) + return XMLNode(m_node->parent); + else return XMLNode(); +#else + return XMLNode(); #endif - } -XMLNode -XMLNode::GetSibling() const -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - return XMLNode(m_node->next); - else - return XMLNode(); -#else +XMLNode XMLNode::GetSibling() const { +#if defined(LIBXML2_DEFINED) + if (IsValid()) + return XMLNode(m_node->next); + else return XMLNode(); +#else + return XMLNode(); #endif - } -XMLNode -XMLNode::GetChild () const -{ -#if defined( LIBXML2_DEFINED ) +XMLNode XMLNode::GetChild() const { +#if defined(LIBXML2_DEFINED) - if (IsValid()) - return XMLNode(m_node->children); - else - return XMLNode(); -#else + if (IsValid()) + return XMLNode(m_node->children); + else return XMLNode(); +#else + return XMLNode(); #endif - } -llvm::StringRef -XMLNode::GetAttributeValue(const char *name, const char *fail_value) const -{ - const char *attr_value = NULL; -#if defined( LIBXML2_DEFINED ) +llvm::StringRef XMLNode::GetAttributeValue(const char *name, + const char *fail_value) const { + const char *attr_value = NULL; +#if defined(LIBXML2_DEFINED) - if (IsValid()) - attr_value = (const char *)xmlGetProp(m_node, (const xmlChar *)name); - else - attr_value = fail_value; -#else + if (IsValid()) + attr_value = (const char *)xmlGetProp(m_node, (const xmlChar *)name); + else attr_value = fail_value; +#else + attr_value = fail_value; #endif - if (attr_value) - return llvm::StringRef(attr_value); - else - return llvm::StringRef(); + if (attr_value) + return llvm::StringRef(attr_value); + else + return llvm::StringRef(); } - - - -void -XMLNode::ForEachChildNode (NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - GetChild().ForEachSiblingNode(callback); +void XMLNode::ForEachChildNode(NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) + if (IsValid()) + GetChild().ForEachSiblingNode(callback); #endif } -void -XMLNode::ForEachChildElement (NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - XMLNode child = GetChild(); - if (child) - child.ForEachSiblingElement(callback); +void XMLNode::ForEachChildElement(NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) + XMLNode child = GetChild(); + if (child) + child.ForEachSiblingElement(callback); #endif } -void -XMLNode::ForEachChildElementWithName (const char *name, NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - XMLNode child = GetChild(); - if (child) - child.ForEachSiblingElementWithName(name, callback); +void XMLNode::ForEachChildElementWithName(const char *name, + NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) + XMLNode child = GetChild(); + if (child) + child.ForEachSiblingElementWithName(name, callback); #endif } -void -XMLNode::ForEachAttribute (AttributeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - for (xmlAttrPtr attr = m_node->properties; attr != nullptr; attr=attr->next) - { - // check if name matches - if (attr->name) - { - // check child is a text node - xmlNodePtr child = attr->children; - if (child->type == XML_TEXT_NODE) - { - llvm::StringRef attr_value; - if (child->content) - attr_value = llvm::StringRef((const char *)child->content); - if (callback(llvm::StringRef((const char *)attr->name), attr_value) == false) - return; - } - } +void XMLNode::ForEachAttribute(AttributeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) + + if (IsValid()) { + for (xmlAttrPtr attr = m_node->properties; attr != nullptr; + attr = attr->next) { + // check if name matches + if (attr->name) { + // check child is a text node + xmlNodePtr child = attr->children; + if (child->type == XML_TEXT_NODE) { + llvm::StringRef attr_value; + if (child->content) + attr_value = llvm::StringRef((const char *)child->content); + if (callback(llvm::StringRef((const char *)attr->name), attr_value) == + false) + return; } + } } + } #endif } +void XMLNode::ForEachSiblingNode(NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) -void -XMLNode::ForEachSiblingNode (NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - // iterate through all siblings - for (xmlNodePtr node = m_node; node; node=node->next) - { - if (callback(XMLNode(node)) == false) - return; - } + if (IsValid()) { + // iterate through all siblings + for (xmlNodePtr node = m_node; node; node = node->next) { + if (callback(XMLNode(node)) == false) + return; } + } #endif } -void -XMLNode::ForEachSiblingElement (NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - // iterate through all siblings - for (xmlNodePtr node = m_node; node; node=node->next) - { - // we are looking for element nodes only - if (node->type != XML_ELEMENT_NODE) - continue; - - if (callback(XMLNode(node)) == false) - return; - } - } -#endif -} +void XMLNode::ForEachSiblingElement(NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) -void -XMLNode::ForEachSiblingElementWithName (const char *name, NodeCallback const &callback) const -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - // iterate through all siblings - for (xmlNodePtr node = m_node; node; node=node->next) - { - // we are looking for element nodes only - if (node->type != XML_ELEMENT_NODE) - continue; - - // If name is nullptr, we take all nodes of type "t", else - // just the ones whose name matches - if (name) - { - if (strcmp((const char *)node->name, name) != 0) - continue; // Name mismatch, ignore this one - } - else - { - if (node->name) - continue; // nullptr name specified and this element has a name, ignore this one - } - - if (callback(XMLNode(node)) == false) - return; - } - } -#endif -} + if (IsValid()) { + // iterate through all siblings + for (xmlNodePtr node = m_node; node; node = node->next) { + // we are looking for element nodes only + if (node->type != XML_ELEMENT_NODE) + continue; -llvm::StringRef -XMLNode::GetName() const -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - if (m_node->name) - return llvm::StringRef((const char *)m_node->name); + if (callback(XMLNode(node)) == false) + return; } + } #endif - return llvm::StringRef(); } -bool -XMLNode::GetElementText (std::string &text) const -{ - text.clear(); -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - bool success = false; - if (m_node->type == XML_ELEMENT_NODE) - { - // check child is a text node - for (xmlNodePtr node = m_node->children; - node != nullptr; - node = node->next) - { - if (node->type == XML_TEXT_NODE) - { - text.append((const char *)node->content); - success = true; - } - } - } - return success; +void XMLNode::ForEachSiblingElementWithName( + const char *name, NodeCallback const &callback) const { +#if defined(LIBXML2_DEFINED) + + if (IsValid()) { + // iterate through all siblings + for (xmlNodePtr node = m_node; node; node = node->next) { + // we are looking for element nodes only + if (node->type != XML_ELEMENT_NODE) + continue; + + // If name is nullptr, we take all nodes of type "t", else + // just the ones whose name matches + if (name) { + if (strcmp((const char *)node->name, name) != 0) + continue; // Name mismatch, ignore this one + } else { + if (node->name) + continue; // nullptr name specified and this element has a name, + // ignore this one + } + + if (callback(XMLNode(node)) == false) + return; } + } #endif - return false; } - -bool -XMLNode::GetElementTextAsUnsigned (uint64_t &value, uint64_t fail_value, int base) const -{ - bool success = false; -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - std::string text; - if (GetElementText(text)) - value = StringConvert::ToUInt64(text.c_str(), fail_value, base, &success); - } +llvm::StringRef XMLNode::GetName() const { +#if defined(LIBXML2_DEFINED) + if (IsValid()) { + if (m_node->name) + return llvm::StringRef((const char *)m_node->name); + } #endif - if (!success) - value = fail_value; - return success; + return llvm::StringRef(); } -bool -XMLNode::GetElementTextAsFloat (double &value, double fail_value) const -{ +bool XMLNode::GetElementText(std::string &text) const { + text.clear(); +#if defined(LIBXML2_DEFINED) + if (IsValid()) { bool success = false; -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - std::string text; - if (GetElementText(text)) - { - value = atof(text.c_str()); - success = true; + if (m_node->type == XML_ELEMENT_NODE) { + // check child is a text node + for (xmlNodePtr node = m_node->children; node != nullptr; + node = node->next) { + if (node->type == XML_TEXT_NODE) { + text.append((const char *)node->content); + success = true; } + } } -#endif - if (!success) - value = fail_value; return success; + } +#endif + return false; +} + +bool XMLNode::GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value, + int base) const { + bool success = false; +#if defined(LIBXML2_DEFINED) + if (IsValid()) { + std::string text; + if (GetElementText(text)) + value = StringConvert::ToUInt64(text.c_str(), fail_value, base, &success); + } +#endif + if (!success) + value = fail_value; + return success; +} + +bool XMLNode::GetElementTextAsFloat(double &value, double fail_value) const { + bool success = false; +#if defined(LIBXML2_DEFINED) + if (IsValid()) { + std::string text; + if (GetElementText(text)) { + value = atof(text.c_str()); + success = true; + } + } +#endif + if (!success) + value = fail_value; + return success; } +bool XMLNode::NameIs(const char *name) const { +#if defined(LIBXML2_DEFINED) - -bool -XMLNode::NameIs (const char *name) const -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - // In case we are looking for a nullptr name or an exact pointer match - if (m_node->name == (const xmlChar *)name) - return true; - if (m_node->name) - return strcmp((const char *)m_node->name, name) == 0; - } + if (IsValid()) { + // In case we are looking for a nullptr name or an exact pointer match + if (m_node->name == (const xmlChar *)name) + return true; + if (m_node->name) + return strcmp((const char *)m_node->name, name) == 0; + } #endif - return false; + return false; } -XMLNode -XMLNode::FindFirstChildElementWithName (const char *name) const -{ - XMLNode result_node; +XMLNode XMLNode::FindFirstChildElementWithName(const char *name) const { + XMLNode result_node; -#if defined( LIBXML2_DEFINED ) - ForEachChildElementWithName(name, [&result_node, name](const XMLNode& node) -> bool { +#if defined(LIBXML2_DEFINED) + ForEachChildElementWithName( + name, [&result_node, name](const XMLNode &node) -> bool { result_node = node; // Stop iterating, we found the node we wanted return false; - }); + }); #endif - return result_node; + return result_node; } -bool -XMLNode::IsValid() const -{ - return m_node != nullptr; -} +bool XMLNode::IsValid() const { return m_node != nullptr; } -bool -XMLNode::IsElement () const -{ -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - return m_node->type == XML_ELEMENT_NODE; +bool XMLNode::IsElement() const { +#if defined(LIBXML2_DEFINED) + if (IsValid()) + return m_node->type == XML_ELEMENT_NODE; #endif - return false; -} - - -XMLNode -XMLNode::GetElementForPath (const NamePath &path) -{ -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - if (path.empty()) - return *this; - else - { - XMLNode node = FindFirstChildElementWithName(path[0].c_str()); - const size_t n = path.size(); - for (size_t i=1; node && i<n; ++i) - node = node.FindFirstChildElementWithName(path[i].c_str()); - return node; - } + return false; +} + +XMLNode XMLNode::GetElementForPath(const NamePath &path) { +#if defined(LIBXML2_DEFINED) + + if (IsValid()) { + if (path.empty()) + return *this; + else { + XMLNode node = FindFirstChildElementWithName(path[0].c_str()); + const size_t n = path.size(); + for (size_t i = 1; node && i < n; ++i) + node = node.FindFirstChildElementWithName(path[i].c_str()); + return node; } + } #endif - return XMLNode(); + return XMLNode(); } +#pragma mark-- ApplePropertyList -#pragma mark -- ApplePropertyList - -ApplePropertyList::ApplePropertyList() : - m_xml_doc(), - m_dict_node() -{ - -} +ApplePropertyList::ApplePropertyList() : m_xml_doc(), m_dict_node() {} -ApplePropertyList::ApplePropertyList (const char *path) : - m_xml_doc(), - m_dict_node() -{ - ParseFile(path); +ApplePropertyList::ApplePropertyList(const char *path) + : m_xml_doc(), m_dict_node() { + ParseFile(path); } -ApplePropertyList::~ApplePropertyList() -{ -} +ApplePropertyList::~ApplePropertyList() {} -const std::string & -ApplePropertyList::GetErrors() const -{ - return m_xml_doc.GetErrors(); +llvm::StringRef ApplePropertyList::GetErrors() const { + return m_xml_doc.GetErrors(); } - -bool -ApplePropertyList::ParseFile (const char *path) -{ - if (m_xml_doc.ParseFile(path)) - { - XMLNode plist = m_xml_doc.GetRootElement("plist"); - if (plist) - { - plist.ForEachChildElementWithName("dict", [this](const XMLNode &dict) -> bool { - this->m_dict_node = dict; - return false; // Stop iterating - }); - return (bool)m_dict_node; - } +bool ApplePropertyList::ParseFile(const char *path) { + if (m_xml_doc.ParseFile(path)) { + XMLNode plist = m_xml_doc.GetRootElement("plist"); + if (plist) { + plist.ForEachChildElementWithName("dict", + [this](const XMLNode &dict) -> bool { + this->m_dict_node = dict; + return false; // Stop iterating + }); + return (bool)m_dict_node; } - return false; -} - -bool -ApplePropertyList::IsValid() const -{ - return (bool)m_dict_node; -} - -bool -ApplePropertyList::GetValueAsString (const char *key, std::string &value) const -{ - XMLNode value_node = GetValueNode (key); - if (value_node) - return ApplePropertyList::ExtractStringFromValueNode(value_node, value); - return false; -} - -XMLNode -ApplePropertyList::GetValueNode (const char *key) const -{ - XMLNode value_node; -#if defined( LIBXML2_DEFINED ) - - if (IsValid()) - { - m_dict_node.ForEachChildElementWithName("key", [key, &value_node](const XMLNode &key_node) -> bool { - std::string key_name; - if (key_node.GetElementText(key_name)) - { - if (key_name.compare(key) == 0) - { - value_node = key_node.GetSibling(); - while (value_node && !value_node.IsElement()) - value_node = value_node.GetSibling(); - return false; // Stop iterating - } + } + return false; +} + +bool ApplePropertyList::IsValid() const { return (bool)m_dict_node; } + +bool ApplePropertyList::GetValueAsString(const char *key, + std::string &value) const { + XMLNode value_node = GetValueNode(key); + if (value_node) + return ApplePropertyList::ExtractStringFromValueNode(value_node, value); + return false; +} + +XMLNode ApplePropertyList::GetValueNode(const char *key) const { + XMLNode value_node; +#if defined(LIBXML2_DEFINED) + + if (IsValid()) { + m_dict_node.ForEachChildElementWithName( + "key", [key, &value_node](const XMLNode &key_node) -> bool { + std::string key_name; + if (key_node.GetElementText(key_name)) { + if (key_name.compare(key) == 0) { + value_node = key_node.GetSibling(); + while (value_node && !value_node.IsElement()) + value_node = value_node.GetSibling(); + return false; // Stop iterating } - return true; // Keep iterating + } + return true; // Keep iterating }); - } + } #endif - return value_node; -} - -bool -ApplePropertyList::ExtractStringFromValueNode (const XMLNode &node, std::string &value) -{ - value.clear(); -#if defined( LIBXML2_DEFINED ) - if (node.IsValid()) - { - llvm::StringRef element_name = node.GetName(); - if (element_name == "true" || element_name == "false") - { - // The text value _is_ the element name itself... - value = element_name.str(); - return true; - } - else if (element_name == "dict" || element_name == "array") - return false; // dictionaries and arrays have no text value, so we fail - else - return node.GetElementText(value); - } + return value_node; +} + +bool ApplePropertyList::ExtractStringFromValueNode(const XMLNode &node, + std::string &value) { + value.clear(); +#if defined(LIBXML2_DEFINED) + if (node.IsValid()) { + llvm::StringRef element_name = node.GetName(); + if (element_name == "true" || element_name == "false") { + // The text value _is_ the element name itself... + value = element_name.str(); + return true; + } else if (element_name == "dict" || element_name == "array") + return false; // dictionaries and arrays have no text value, so we fail + else + return node.GetElementText(value); + } #endif - return false; + return false; } -#if defined( LIBXML2_DEFINED ) +#if defined(LIBXML2_DEFINED) namespace { - StructuredData::ObjectSP - CreatePlistValue (XMLNode node) - { - llvm::StringRef element_name = node.GetName(); - if (element_name == "array") - { - std::shared_ptr<StructuredData::Array> array_sp(new StructuredData::Array()); - node.ForEachChildElement([&array_sp](const XMLNode &node) -> bool { - array_sp->AddItem(CreatePlistValue(node)); - return true; // Keep iterating through all child elements of the array - }); - return array_sp; - } - else if (element_name == "dict") - { - XMLNode key_node; - std::shared_ptr<StructuredData::Dictionary> dict_sp(new StructuredData::Dictionary()); - node.ForEachChildElement([&key_node, &dict_sp](const XMLNode &node) -> bool { - if (node.NameIs("key")) - { - // This is a "key" element node - key_node = node; - } - else - { - // This is a value node - if (key_node) - { - std::string key_name; - key_node.GetElementText(key_name); - dict_sp->AddItem(key_name, CreatePlistValue(node)); - key_node.Clear(); - } - } - return true; // Keep iterating through all child elements of the dictionary - }); - return dict_sp; - } - else if (element_name == "real") - { - double value = 0.0; - node.GetElementTextAsFloat(value); - return StructuredData::ObjectSP(new StructuredData::Float(value)); - } - else if (element_name == "integer") - { - uint64_t value = 0; - node.GetElementTextAsUnsigned(value, 0, 0); - return StructuredData::ObjectSP(new StructuredData::Integer(value)); - } - else if ((element_name == "string") || (element_name == "data") || (element_name == "date")) - { - std::string text; - node.GetElementText(text); - return StructuredData::ObjectSP(new StructuredData::String(std::move(text))); - } - else if (element_name == "true") - { - return StructuredData::ObjectSP(new StructuredData::Boolean(true)); - } - else if (element_name == "false") - { - return StructuredData::ObjectSP(new StructuredData::Boolean(false)); - } - return StructuredData::ObjectSP(new StructuredData::Null()); - } +StructuredData::ObjectSP CreatePlistValue(XMLNode node) { + llvm::StringRef element_name = node.GetName(); + if (element_name == "array") { + std::shared_ptr<StructuredData::Array> array_sp( + new StructuredData::Array()); + node.ForEachChildElement([&array_sp](const XMLNode &node) -> bool { + array_sp->AddItem(CreatePlistValue(node)); + return true; // Keep iterating through all child elements of the array + }); + return array_sp; + } else if (element_name == "dict") { + XMLNode key_node; + std::shared_ptr<StructuredData::Dictionary> dict_sp( + new StructuredData::Dictionary()); + node.ForEachChildElement( + [&key_node, &dict_sp](const XMLNode &node) -> bool { + if (node.NameIs("key")) { + // This is a "key" element node + key_node = node; + } else { + // This is a value node + if (key_node) { + std::string key_name; + key_node.GetElementText(key_name); + dict_sp->AddItem(key_name, CreatePlistValue(node)); + key_node.Clear(); + } + } + return true; // Keep iterating through all child elements of the + // dictionary + }); + return dict_sp; + } else if (element_name == "real") { + double value = 0.0; + node.GetElementTextAsFloat(value); + return StructuredData::ObjectSP(new StructuredData::Float(value)); + } else if (element_name == "integer") { + uint64_t value = 0; + node.GetElementTextAsUnsigned(value, 0, 0); + return StructuredData::ObjectSP(new StructuredData::Integer(value)); + } else if ((element_name == "string") || (element_name == "data") || + (element_name == "date")) { + std::string text; + node.GetElementText(text); + return StructuredData::ObjectSP( + new StructuredData::String(std::move(text))); + } else if (element_name == "true") { + return StructuredData::ObjectSP(new StructuredData::Boolean(true)); + } else if (element_name == "false") { + return StructuredData::ObjectSP(new StructuredData::Boolean(false)); + } + return StructuredData::ObjectSP(new StructuredData::Null()); +} } #endif -StructuredData::ObjectSP -ApplePropertyList::GetStructuredData() -{ - StructuredData::ObjectSP root_sp; -#if defined( LIBXML2_DEFINED ) - if (IsValid()) - { - return CreatePlistValue(m_dict_node); - } +StructuredData::ObjectSP ApplePropertyList::GetStructuredData() { + StructuredData::ObjectSP root_sp; +#if defined(LIBXML2_DEFINED) + if (IsValid()) { + return CreatePlistValue(m_dict_node); + } #endif - return root_sp; + return root_sp; } |