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