aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Host/XML.h
blob: 4113b3318dd0d06ea3a09d9316a781801912fbe4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//===-- XML.h ---------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_XML_h_
#define liblldb_XML_h_

// C Includes
#if defined(LIBXML2_DEFINED)
#include <libxml/xmlreader.h>
#endif

// C++ Includes
#include <functional>
#include <string>
#include <vector>

// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"

// Project includes
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

#if defined(LIBXML2_DEFINED)
typedef xmlNodePtr XMLNodeImpl;
typedef xmlDocPtr XMLDocumentImpl;
#else
typedef void *XMLNodeImpl;
typedef void *XMLDocumentImpl;
#endif

class XMLNode;

typedef std::vector<std::string> NamePath;
typedef std::function<bool(const XMLNode &node)> NodeCallback;
typedef std::function<bool(const llvm::StringRef &name,
                           const llvm::StringRef &value)>
    AttributeCallback;

class XMLNode {
public:
  XMLNode();

  XMLNode(XMLNodeImpl node);

  ~XMLNode();

  explicit operator bool() const { return IsValid(); }

  void Clear();

  bool IsValid() const;

  bool IsElement() const;

  llvm::StringRef GetName() const;

  bool GetElementText(std::string &text) const;

  bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value = 0,
                                int base = 0) const;

  bool GetElementTextAsFloat(double &value, double fail_value = 0.0) const;

  bool NameIs(const char *name) const;

  XMLNode GetParent() const;

  XMLNode GetSibling() const;

  XMLNode GetChild() const;

  llvm::StringRef GetAttributeValue(const char *name,
                                    const char *fail_value = nullptr) const;

  XMLNode FindFirstChildElementWithName(const char *name) const;

  XMLNode GetElementForPath(const NamePath &path);

  //----------------------------------------------------------------------
  // Iterate through all sibling nodes of any type
  //----------------------------------------------------------------------
  void ForEachSiblingNode(NodeCallback const &callback) const;

  //----------------------------------------------------------------------
  // Iterate through only the sibling nodes that are elements
  //----------------------------------------------------------------------
  void ForEachSiblingElement(NodeCallback const &callback) const;

  //----------------------------------------------------------------------
  // Iterate through only the sibling nodes that are elements and whose
  // name matches \a name.
  //----------------------------------------------------------------------
  void ForEachSiblingElementWithName(const char *name,
                                     NodeCallback const &callback) const;

  void ForEachChildNode(NodeCallback const &callback) const;

  void ForEachChildElement(NodeCallback const &callback) const;

  void ForEachChildElementWithName(const char *name,
                                   NodeCallback const &callback) const;

  void ForEachAttribute(AttributeCallback const &callback) const;

protected:
  XMLNodeImpl m_node;
};

class XMLDocument {
public:
  XMLDocument();

  ~XMLDocument();

  explicit operator bool() const { return IsValid(); }

  bool IsValid() const;

  void Clear();

  bool ParseFile(const char *path);

  bool ParseMemory(const char *xml, size_t xml_length,
                   const char *url = "untitled.xml");

  //----------------------------------------------------------------------
  // If \a name is nullptr, just get the root element node, else only return
  // a value XMLNode if the name of the root element matches \a name.
  //----------------------------------------------------------------------
  XMLNode GetRootElement(const char *required_name = nullptr);

  llvm::StringRef GetErrors() const;

  static void ErrorCallback(void *ctx, const char *format, ...);

  static bool XMLEnabled();

protected:
  XMLDocumentImpl m_document;
  StreamString m_errors;
};

class ApplePropertyList {
public:
  ApplePropertyList();

  ApplePropertyList(const char *path);

  ~ApplePropertyList();

  bool ParseFile(const char *path);

  llvm::StringRef GetErrors() const;

  explicit operator bool() const { return IsValid(); }

  bool IsValid() const;

  XMLNode GetValueNode(const char *key) const;

  bool GetValueAsString(const char *key, std::string &value) const;

  StructuredData::ObjectSP GetStructuredData();

protected:
  // Using a node returned from GetValueNode() extract its value as a
  // string (if possible). Array and dictionary nodes will return false
  // as they have no string value. Boolean nodes will return true and
  // \a value will be "true" or "false" as the string value comes from
  // the element name itself. All other nodes will return the text
  // content of the XMLNode.
  static bool ExtractStringFromValueNode(const XMLNode &node,
                                         std::string &value);

  XMLDocument m_xml_doc;
  XMLNode m_dict_node;
};

} // namespace lldb_private

#endif // liblldb_XML_h_