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