1 //===-- XML.h ---------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_HOST_XML_H 10 #define LLDB_HOST_XML_H 11 12 #include "lldb/Host/Config.h" 13 14 #if LLDB_ENABLE_LIBXML2 15 #include <libxml/xmlreader.h> 16 #endif 17 18 #include <functional> 19 #include <string> 20 #include <vector> 21 22 #include "llvm/ADT/StringRef.h" 23 24 #include "lldb/Utility/StreamString.h" 25 #include "lldb/Utility/StructuredData.h" 26 #include "lldb/lldb-private.h" 27 28 namespace lldb_private { 29 30 #if LLDB_ENABLE_LIBXML2 31 typedef xmlNodePtr XMLNodeImpl; 32 typedef xmlDocPtr XMLDocumentImpl; 33 #else 34 typedef void *XMLNodeImpl; 35 typedef void *XMLDocumentImpl; 36 #endif 37 38 class XMLNode; 39 40 typedef std::vector<std::string> NamePath; 41 typedef std::function<bool(const XMLNode &node)> NodeCallback; 42 typedef std::function<bool(const llvm::StringRef &name, 43 const llvm::StringRef &value)> 44 AttributeCallback; 45 46 class XMLNode { 47 public: 48 XMLNode(); 49 50 XMLNode(XMLNodeImpl node); 51 52 ~XMLNode(); 53 54 explicit operator bool() const { return IsValid(); } 55 56 void Clear(); 57 58 bool IsValid() const; 59 60 bool IsElement() const; 61 62 llvm::StringRef GetName() const; 63 64 bool GetElementText(std::string &text) const; 65 66 bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value = 0, 67 int base = 0) const; 68 69 bool GetElementTextAsFloat(double &value, double fail_value = 0.0) const; 70 71 bool NameIs(const char *name) const; 72 73 XMLNode GetParent() const; 74 75 XMLNode GetSibling() const; 76 77 XMLNode GetChild() const; 78 79 llvm::StringRef GetAttributeValue(const char *name, 80 const char *fail_value = nullptr) const; 81 82 bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, 83 uint64_t fail_value = 0, int base = 0) const; 84 85 XMLNode FindFirstChildElementWithName(const char *name) const; 86 87 XMLNode GetElementForPath(const NamePath &path); 88 89 // Iterate through all sibling nodes of any type 90 void ForEachSiblingNode(NodeCallback const &callback) const; 91 92 // Iterate through only the sibling nodes that are elements 93 void ForEachSiblingElement(NodeCallback const &callback) const; 94 95 // Iterate through only the sibling nodes that are elements and whose name 96 // matches \a name. 97 void ForEachSiblingElementWithName(const char *name, 98 NodeCallback const &callback) const; 99 100 void ForEachChildNode(NodeCallback const &callback) const; 101 102 void ForEachChildElement(NodeCallback const &callback) const; 103 104 void ForEachChildElementWithName(const char *name, 105 NodeCallback const &callback) const; 106 107 void ForEachAttribute(AttributeCallback const &callback) const; 108 109 protected: 110 XMLNodeImpl m_node = nullptr; 111 }; 112 113 class XMLDocument { 114 public: 115 XMLDocument(); 116 117 ~XMLDocument(); 118 119 explicit operator bool() const { return IsValid(); } 120 121 bool IsValid() const; 122 123 void Clear(); 124 125 bool ParseFile(const char *path); 126 127 bool ParseMemory(const char *xml, size_t xml_length, 128 const char *url = "untitled.xml"); 129 130 // If \a name is nullptr, just get the root element node, else only return a 131 // value XMLNode if the name of the root element matches \a name. 132 XMLNode GetRootElement(const char *required_name = nullptr); 133 134 llvm::StringRef GetErrors() const; 135 136 static void ErrorCallback(void *ctx, const char *format, ...); 137 138 static bool XMLEnabled(); 139 140 protected: 141 XMLDocumentImpl m_document = nullptr; 142 StreamString m_errors; 143 }; 144 145 class ApplePropertyList { 146 public: 147 ApplePropertyList(); 148 149 ApplePropertyList(const char *path); 150 151 ~ApplePropertyList(); 152 153 bool ParseFile(const char *path); 154 155 llvm::StringRef GetErrors() const; 156 157 explicit operator bool() const { return IsValid(); } 158 159 bool IsValid() const; 160 161 XMLNode GetValueNode(const char *key) const; 162 163 bool GetValueAsString(const char *key, std::string &value) const; 164 165 StructuredData::ObjectSP GetStructuredData(); 166 167 protected: 168 // Using a node returned from GetValueNode() extract its value as a string 169 // (if possible). Array and dictionary nodes will return false as they have 170 // no string value. Boolean nodes will return true and \a value will be 171 // "true" or "false" as the string value comes from the element name itself. 172 // All other nodes will return the text content of the XMLNode. 173 static bool ExtractStringFromValueNode(const XMLNode &node, 174 std::string &value); 175 176 XMLDocument m_xml_doc; 177 XMLNode m_dict_node; 178 }; 179 180 } // namespace lldb_private 181 182 #endif // LLDB_HOST_XML_H 183