10b57cec5SDimitry Andric //===-- XML.h ---------------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_HOST_XML_H 105ffd83dbSDimitry Andric #define LLDB_HOST_XML_H 110b57cec5SDimitry Andric 12480093f4SDimitry Andric #include "lldb/Host/Config.h" 13480093f4SDimitry Andric 14480093f4SDimitry Andric #if LLDB_ENABLE_LIBXML2 150b57cec5SDimitry Andric #include <libxml/xmlreader.h> 160b57cec5SDimitry Andric #endif 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include <functional> 190b57cec5SDimitry Andric #include <string> 200b57cec5SDimitry Andric #include <vector> 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 250b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h" 260b57cec5SDimitry Andric #include "lldb/lldb-private.h" 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace lldb_private { 290b57cec5SDimitry Andric 30480093f4SDimitry Andric #if LLDB_ENABLE_LIBXML2 310b57cec5SDimitry Andric typedef xmlNodePtr XMLNodeImpl; 320b57cec5SDimitry Andric typedef xmlDocPtr XMLDocumentImpl; 330b57cec5SDimitry Andric #else 340b57cec5SDimitry Andric typedef void *XMLNodeImpl; 350b57cec5SDimitry Andric typedef void *XMLDocumentImpl; 360b57cec5SDimitry Andric #endif 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric class XMLNode; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric typedef std::vector<std::string> NamePath; 410b57cec5SDimitry Andric typedef std::function<bool(const XMLNode &node)> NodeCallback; 420b57cec5SDimitry Andric typedef std::function<bool(const llvm::StringRef &name, 430b57cec5SDimitry Andric const llvm::StringRef &value)> 440b57cec5SDimitry Andric AttributeCallback; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric class XMLNode { 470b57cec5SDimitry Andric public: 480b57cec5SDimitry Andric XMLNode(); 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric XMLNode(XMLNodeImpl node); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric ~XMLNode(); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric explicit operator bool() const { return IsValid(); } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric void Clear(); 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric bool IsValid() const; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric bool IsElement() const; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric llvm::StringRef GetName() const; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric bool GetElementText(std::string &text) const; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value = 0, 670b57cec5SDimitry Andric int base = 0) const; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric bool GetElementTextAsFloat(double &value, double fail_value = 0.0) const; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric bool NameIs(const char *name) const; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric XMLNode GetParent() const; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric XMLNode GetSibling() const; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric XMLNode GetChild() const; 780b57cec5SDimitry Andric 79*04eeddc0SDimitry Andric std::string GetAttributeValue(const char *name, 800b57cec5SDimitry Andric const char *fail_value = nullptr) const; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, 830b57cec5SDimitry Andric uint64_t fail_value = 0, int base = 0) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric XMLNode FindFirstChildElementWithName(const char *name) const; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric XMLNode GetElementForPath(const NamePath &path); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // Iterate through all sibling nodes of any type 900b57cec5SDimitry Andric void ForEachSiblingNode(NodeCallback const &callback) const; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // Iterate through only the sibling nodes that are elements 930b57cec5SDimitry Andric void ForEachSiblingElement(NodeCallback const &callback) const; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // Iterate through only the sibling nodes that are elements and whose name 960b57cec5SDimitry Andric // matches \a name. 970b57cec5SDimitry Andric void ForEachSiblingElementWithName(const char *name, 980b57cec5SDimitry Andric NodeCallback const &callback) const; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric void ForEachChildNode(NodeCallback const &callback) const; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric void ForEachChildElement(NodeCallback const &callback) const; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric void ForEachChildElementWithName(const char *name, 1050b57cec5SDimitry Andric NodeCallback const &callback) const; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric void ForEachAttribute(AttributeCallback const &callback) const; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric protected: 110fe6060f1SDimitry Andric XMLNodeImpl m_node = nullptr; 1110b57cec5SDimitry Andric }; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric class XMLDocument { 1140b57cec5SDimitry Andric public: 1150b57cec5SDimitry Andric XMLDocument(); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric ~XMLDocument(); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric explicit operator bool() const { return IsValid(); } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric bool IsValid() const; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric void Clear(); 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric bool ParseFile(const char *path); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool ParseMemory(const char *xml, size_t xml_length, 1280b57cec5SDimitry Andric const char *url = "untitled.xml"); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // If \a name is nullptr, just get the root element node, else only return a 1310b57cec5SDimitry Andric // value XMLNode if the name of the root element matches \a name. 1320b57cec5SDimitry Andric XMLNode GetRootElement(const char *required_name = nullptr); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric llvm::StringRef GetErrors() const; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric static void ErrorCallback(void *ctx, const char *format, ...); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric static bool XMLEnabled(); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric protected: 141fe6060f1SDimitry Andric XMLDocumentImpl m_document = nullptr; 1420b57cec5SDimitry Andric StreamString m_errors; 1430b57cec5SDimitry Andric }; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric class ApplePropertyList { 1460b57cec5SDimitry Andric public: 1470b57cec5SDimitry Andric ApplePropertyList(); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric ApplePropertyList(const char *path); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric ~ApplePropertyList(); 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric bool ParseFile(const char *path); 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric llvm::StringRef GetErrors() const; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric explicit operator bool() const { return IsValid(); } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric bool IsValid() const; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric XMLNode GetValueNode(const char *key) const; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric bool GetValueAsString(const char *key, std::string &value) const; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric StructuredData::ObjectSP GetStructuredData(); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric protected: 1680b57cec5SDimitry Andric // Using a node returned from GetValueNode() extract its value as a string 1690b57cec5SDimitry Andric // (if possible). Array and dictionary nodes will return false as they have 1700b57cec5SDimitry Andric // no string value. Boolean nodes will return true and \a value will be 1710b57cec5SDimitry Andric // "true" or "false" as the string value comes from the element name itself. 1720b57cec5SDimitry Andric // All other nodes will return the text content of the XMLNode. 1730b57cec5SDimitry Andric static bool ExtractStringFromValueNode(const XMLNode &node, 1740b57cec5SDimitry Andric std::string &value); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric XMLDocument m_xml_doc; 1770b57cec5SDimitry Andric XMLNode m_dict_node; 1780b57cec5SDimitry Andric }; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric } // namespace lldb_private 1810b57cec5SDimitry Andric 1825ffd83dbSDimitry Andric #endif // LLDB_HOST_XML_H 183