xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Host/XML.h (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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    std::string 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