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 (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 | |