blob: d3951776cac835002dd64fb470b8d3f551706796 [file] [log] [blame]
Todd Fiala75930012016-08-19 04:21:48 +00001//===---------------------JSON.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 utility_JSON_h_
11#define utility_JSON_h_
12
Zachary Turner44c35e82016-08-29 19:45:59 +000013// This cross-project usage is fine as StdStringExtractor.h is entirely
Todd Fiala75930012016-08-19 04:21:48 +000014// self-contained.
Zachary Turner44c35e82016-08-29 19:45:59 +000015#include "lldb/Utility/StdStringExtractor.h"
Todd Fiala75930012016-08-19 04:21:48 +000016
17// C includes
18#include <inttypes.h>
19#include <stdint.h>
20
21// C++ includes
22#include <map>
23#include <memory>
24#include <ostream>
25#include <string>
26#include <vector>
27
Kate Stoneb9c1b512016-09-06 20:57:50 +000028class JSONValue {
Todd Fiala75930012016-08-19 04:21:48 +000029public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000030 virtual void Write(std::ostream &s) = 0;
Todd Fiala75930012016-08-19 04:21:48 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 typedef std::shared_ptr<JSONValue> SP;
Todd Fiala75930012016-08-19 04:21:48 +000033
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 enum class Kind { String, Number, True, False, Null, Object, Array };
Todd Fiala75930012016-08-19 04:21:48 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 JSONValue(Kind k) : m_kind(k) {}
Todd Fiala75930012016-08-19 04:21:48 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038 Kind GetKind() const { return m_kind; }
Todd Fiala75930012016-08-19 04:21:48 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 virtual ~JSONValue() = default;
Todd Fiala75930012016-08-19 04:21:48 +000041
42private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 const Kind m_kind;
Todd Fiala75930012016-08-19 04:21:48 +000044};
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046class JSONString : public JSONValue {
Todd Fiala75930012016-08-19 04:21:48 +000047public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 JSONString();
49 JSONString(const char *s);
50 JSONString(const std::string &s);
Todd Fiala75930012016-08-19 04:21:48 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 JSONString(const JSONString &s) = delete;
53 JSONString &operator=(const JSONString &s) = delete;
Todd Fiala75930012016-08-19 04:21:48 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 void Write(std::ostream &s) override;
Todd Fiala75930012016-08-19 04:21:48 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 typedef std::shared_ptr<JSONString> SP;
Todd Fiala75930012016-08-19 04:21:48 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 std::string GetData() { return m_data; }
Todd Fiala75930012016-08-19 04:21:48 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 static bool classof(const JSONValue *V) {
62 return V->GetKind() == JSONValue::Kind::String;
63 }
Todd Fiala75930012016-08-19 04:21:48 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 ~JSONString() override = default;
Todd Fiala75930012016-08-19 04:21:48 +000066
Todd Fiala75930012016-08-19 04:21:48 +000067private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 static std::string json_string_quote_metachars(const std::string &);
69
70 std::string m_data;
Todd Fiala75930012016-08-19 04:21:48 +000071};
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073class JSONNumber : public JSONValue {
Todd Fiala75930012016-08-19 04:21:48 +000074public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 typedef std::shared_ptr<JSONNumber> SP;
76
77 // We cretae a constructor for all integer and floating point type with using
78 // templates and
79 // SFINAE to avoid having ambiguous overloads because of the implicit type
80 // promotion. If we
81 // would have constructors only with int64_t, uint64_t and double types then
82 // constructing a
83 // JSONNumber from an int32_t (or any other similar type) would fail to
84 // compile.
85
86 template <typename T, typename std::enable_if<
87 std::is_integral<T>::value &&
88 std::is_unsigned<T>::value>::type * = nullptr>
89 explicit JSONNumber(T u)
90 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
91 m_data.m_unsigned = u;
92 }
93
94 template <typename T,
95 typename std::enable_if<std::is_integral<T>::value &&
96 std::is_signed<T>::value>::type * = nullptr>
97 explicit JSONNumber(T s)
98 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
99 m_data.m_signed = s;
100 }
101
102 template <typename T, typename std::enable_if<
103 std::is_floating_point<T>::value>::type * = nullptr>
104 explicit JSONNumber(T d)
105 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
106 m_data.m_double = d;
107 }
108
109 ~JSONNumber() override = default;
110
111 JSONNumber(const JSONNumber &s) = delete;
112 JSONNumber &operator=(const JSONNumber &s) = delete;
113
114 void Write(std::ostream &s) override;
115
116 uint64_t GetAsUnsigned() const;
117
118 int64_t GetAsSigned() const;
119
120 double GetAsDouble() const;
121
122 static bool classof(const JSONValue *V) {
123 return V->GetKind() == JSONValue::Kind::Number;
124 }
125
Todd Fiala75930012016-08-19 04:21:48 +0000126private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
Todd Fiala75930012016-08-19 04:21:48 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 union {
130 uint64_t m_unsigned;
131 int64_t m_signed;
132 double m_double;
133 } m_data;
Todd Fiala75930012016-08-19 04:21:48 +0000134};
135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136class JSONTrue : public JSONValue {
Todd Fiala75930012016-08-19 04:21:48 +0000137public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 JSONTrue();
Todd Fiala75930012016-08-19 04:21:48 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 JSONTrue(const JSONTrue &s) = delete;
141 JSONTrue &operator=(const JSONTrue &s) = delete;
Todd Fiala75930012016-08-19 04:21:48 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 void Write(std::ostream &s) override;
Todd Fiala75930012016-08-19 04:21:48 +0000144
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 typedef std::shared_ptr<JSONTrue> SP;
Todd Fiala75930012016-08-19 04:21:48 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 static bool classof(const JSONValue *V) {
148 return V->GetKind() == JSONValue::Kind::True;
149 }
150
151 ~JSONTrue() override = default;
152};
153
154class JSONFalse : public JSONValue {
155public:
156 JSONFalse();
157
158 JSONFalse(const JSONFalse &s) = delete;
159 JSONFalse &operator=(const JSONFalse &s) = delete;
160
161 void Write(std::ostream &s) override;
162
163 typedef std::shared_ptr<JSONFalse> SP;
164
165 static bool classof(const JSONValue *V) {
166 return V->GetKind() == JSONValue::Kind::False;
167 }
168
169 ~JSONFalse() override = default;
170};
171
172class JSONNull : public JSONValue {
173public:
174 JSONNull();
175
176 JSONNull(const JSONNull &s) = delete;
177 JSONNull &operator=(const JSONNull &s) = delete;
178
179 void Write(std::ostream &s) override;
180
181 typedef std::shared_ptr<JSONNull> SP;
182
183 static bool classof(const JSONValue *V) {
184 return V->GetKind() == JSONValue::Kind::Null;
185 }
186
187 ~JSONNull() override = default;
188};
189
190class JSONObject : public JSONValue {
191public:
192 JSONObject();
193
194 JSONObject(const JSONObject &s) = delete;
195 JSONObject &operator=(const JSONObject &s) = delete;
196
197 void Write(std::ostream &s) override;
198
199 typedef std::shared_ptr<JSONObject> SP;
200
201 static bool classof(const JSONValue *V) {
202 return V->GetKind() == JSONValue::Kind::Object;
203 }
204
205 bool SetObject(const std::string &key, JSONValue::SP value);
206
207 JSONValue::SP GetObject(const std::string &key) const;
208
209 // -------------------------------------------------------------------------
210 /// Return keyed value as bool
211 ///
212 /// @param[in] key
213 /// The value of the key to lookup
214 ///
215 /// @param[out] value
216 /// The value of the key as a bool. Undefined if the key doesn't
217 /// exist or if the key is not either true or false.
218 ///
219 /// @return
220 /// true if the key existed as was a bool value; false otherwise.
221 /// Note the return value is *not* the value of the bool, use
222 /// \b value for that.
223 // -------------------------------------------------------------------------
224 bool GetObjectAsBool(const std::string &key, bool &value) const;
225
226 bool GetObjectAsString(const std::string &key, std::string &value) const;
227
228 ~JSONObject() override = default;
229
230private:
231 typedef std::map<std::string, JSONValue::SP> Map;
232 typedef Map::iterator Iterator;
233 Map m_elements;
234};
235
236class JSONArray : public JSONValue {
237public:
238 JSONArray();
239
240 JSONArray(const JSONArray &s) = delete;
241 JSONArray &operator=(const JSONArray &s) = delete;
242
243 void Write(std::ostream &s) override;
244
245 typedef std::shared_ptr<JSONArray> SP;
246
247 static bool classof(const JSONValue *V) {
248 return V->GetKind() == JSONValue::Kind::Array;
249 }
250
251private:
252 typedef std::vector<JSONValue::SP> Vector;
253 typedef Vector::iterator Iterator;
254 typedef Vector::size_type Index;
255 typedef Vector::size_type Size;
256
257public:
258 bool SetObject(Index i, JSONValue::SP value);
259
260 bool AppendObject(JSONValue::SP value);
261
262 JSONValue::SP GetObject(Index i);
263
264 Size GetNumElements();
265
266 ~JSONArray() override = default;
267
268 Vector m_elements;
269};
270
271class JSONParser : public StdStringExtractor {
272public:
273 enum Token {
274 Invalid,
275 Error,
276 ObjectStart,
277 ObjectEnd,
278 ArrayStart,
279 ArrayEnd,
280 Comma,
281 Colon,
282 String,
283 Integer,
284 Float,
285 True,
286 False,
287 Null,
288 EndOfFile
289 };
290
291 JSONParser(const char *cstr);
292
293 int GetEscapedChar(bool &was_escaped);
294
295 Token GetToken(std::string &value);
296
297 JSONValue::SP ParseJSONValue();
Todd Fiala75930012016-08-19 04:21:48 +0000298
299protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300 JSONValue::SP ParseJSONObject();
Todd Fiala75930012016-08-19 04:21:48 +0000301
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302 JSONValue::SP ParseJSONArray();
Todd Fiala75930012016-08-19 04:21:48 +0000303};
304
305#endif // utility_JSON_h_