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
28namespace lldb_private {
29
30#if LLDB_ENABLE_LIBXML2
31typedef xmlNodePtr XMLNodeImpl;
32typedef xmlDocPtr XMLDocumentImpl;
33#else
34typedef void *XMLNodeImpl;
35typedef void *XMLDocumentImpl;
36#endif
37
38class XMLNode;
39
40typedef std::vector<std::string> NamePath;
41typedef std::function<bool(const XMLNode &node)> NodeCallback;
42typedef std::function<bool(const llvm::StringRef &name,
43                           const llvm::StringRef &value)>
44    AttributeCallback;
45
46class XMLNode {
47public:
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  llvm::StringRef 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
109protected:
110  XMLNodeImpl m_node;
111};
112
113class XMLDocument {
114public:
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
140protected:
141  XMLDocumentImpl m_document;
142  StreamString m_errors;
143};
144
145class ApplePropertyList {
146public:
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
167protected:
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