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