blob: e24f928bcf74e805a3f080d59eece56faea2cc53 [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
28class JSONValue
29{
30public:
31 virtual void
32 Write (std::ostream& s) = 0;
33
34 typedef std::shared_ptr<JSONValue> SP;
35
36 enum class Kind
37 {
38 String,
39 Number,
40 True,
41 False,
42 Null,
43 Object,
44 Array
45 };
46
47 JSONValue (Kind k) :
48 m_kind(k)
49 {}
50
51 Kind
52 GetKind() const
53 {
54 return m_kind;
55 }
56
57 virtual
58 ~JSONValue () = default;
59
60private:
61 const Kind m_kind;
62};
63
64class JSONString : public JSONValue
65{
66public:
67 JSONString ();
68 JSONString (const char* s);
69 JSONString (const std::string& s);
70
71 JSONString (const JSONString& s) = delete;
72 JSONString&
73 operator = (const JSONString& s) = delete;
74
75 void
76 Write(std::ostream& s) override;
77
78 typedef std::shared_ptr<JSONString> SP;
79
80 std::string
81 GetData () { return m_data; }
82
83 static bool classof(const JSONValue *V)
84 {
85 return V->GetKind() == JSONValue::Kind::String;
86 }
87
88 ~JSONString() override = default;
89
90private:
91
92 static std::string
93 json_string_quote_metachars (const std::string&);
94
95 std::string m_data;
96};
97
98class JSONNumber : public JSONValue
99{
100public:
101 typedef std::shared_ptr<JSONNumber> SP;
102
103 // We cretae a constructor for all integer and floating point type with using templates and
104 // SFINAE to avoid having ambiguous overloads because of the implicit type promotion. If we
105 // would have constructors only with int64_t, uint64_t and double types then constructing a
106 // JSONNumber from an int32_t (or any other similar type) would fail to compile.
107
108 template <typename T,
109 typename std::enable_if<std::is_integral<T>::value &&
110 std::is_unsigned<T>::value>::type* = nullptr>
111 explicit JSONNumber (T u) :
112 JSONValue(JSONValue::Kind::Number),
113 m_data_type(DataType::Unsigned)
114 {
115 m_data.m_unsigned = u;
116 }
117
118 template <typename T,
119 typename std::enable_if<std::is_integral<T>::value &&
120 std::is_signed<T>::value>::type* = nullptr>
121 explicit JSONNumber (T s) :
122 JSONValue(JSONValue::Kind::Number),
123 m_data_type(DataType::Signed)
124 {
125 m_data.m_signed = s;
126 }
127
128 template <typename T,
129 typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
130 explicit JSONNumber (T d) :
131 JSONValue(JSONValue::Kind::Number),
132 m_data_type(DataType::Double)
133 {
134 m_data.m_double = d;
135 }
136
137 ~JSONNumber() override = default;
138
139 JSONNumber (const JSONNumber& s) = delete;
140 JSONNumber&
141 operator = (const JSONNumber& s) = delete;
142
143 void
144 Write(std::ostream& s) override;
145
146 uint64_t
147 GetAsUnsigned() const;
148
149 int64_t
150 GetAsSigned() const;
151
152 double
153 GetAsDouble() const;
154
155 static bool classof(const JSONValue *V)
156 {
157 return V->GetKind() == JSONValue::Kind::Number;
158 }
159
160private:
161 enum class DataType : uint8_t
162 {
163 Unsigned,
164 Signed,
165 Double
166 } m_data_type;
167
168 union
169 {
170 uint64_t m_unsigned;
171 int64_t m_signed;
172 double m_double;
173 } m_data;
174};
175
176class JSONTrue : public JSONValue
177{
178public:
179 JSONTrue ();
180
181 JSONTrue (const JSONTrue& s) = delete;
182 JSONTrue&
183 operator = (const JSONTrue& s) = delete;
184
185 void
186 Write(std::ostream& s) override;
187
188 typedef std::shared_ptr<JSONTrue> SP;
189
190 static bool classof(const JSONValue *V)
191 {
192 return V->GetKind() == JSONValue::Kind::True;
193 }
194
195 ~JSONTrue() override = default;
196};
197
198class JSONFalse : public JSONValue
199{
200public:
201 JSONFalse ();
202
203 JSONFalse (const JSONFalse& s) = delete;
204 JSONFalse&
205 operator = (const JSONFalse& s) = delete;
206
207 void
208 Write(std::ostream& s) override;
209
210 typedef std::shared_ptr<JSONFalse> SP;
211
212 static bool classof(const JSONValue *V)
213 {
214 return V->GetKind() == JSONValue::Kind::False;
215 }
216
217 ~JSONFalse() override = default;
218};
219
220class JSONNull : public JSONValue
221{
222public:
223 JSONNull ();
224
225 JSONNull (const JSONNull& s) = delete;
226 JSONNull&
227 operator = (const JSONNull& s) = delete;
228
229 void
230 Write(std::ostream& s) override;
231
232 typedef std::shared_ptr<JSONNull> SP;
233
234 static bool classof(const JSONValue *V)
235 {
236 return V->GetKind() == JSONValue::Kind::Null;
237 }
238
239 ~JSONNull() override = default;
240};
241
242class JSONObject : public JSONValue
243{
244public:
245 JSONObject ();
246
247 JSONObject (const JSONObject& s) = delete;
248 JSONObject&
249 operator = (const JSONObject& s) = delete;
250
251 void
252 Write(std::ostream& s) override;
253
254 typedef std::shared_ptr<JSONObject> SP;
255
256 static bool classof(const JSONValue *V)
257 {
258 return V->GetKind() == JSONValue::Kind::Object;
259 }
260
261 bool
262 SetObject (const std::string& key,
263 JSONValue::SP value);
264
265 JSONValue::SP
266 GetObject (const std::string& key) const;
267
268 // -------------------------------------------------------------------------
269 /// Return keyed value as bool
270 ///
271 /// @param[in] key
272 /// The value of the key to lookup
273 ///
274 /// @param[out] value
275 /// The value of the key as a bool. Undefined if the key doesn't
276 /// exist or if the key is not either true or false.
277 ///
278 /// @return
279 /// true if the key existed as was a bool value; false otherwise.
280 /// Note the return value is *not* the value of the bool, use
281 /// \b value for that.
282 // -------------------------------------------------------------------------
283 bool
284 GetObjectAsBool (const std::string& key, bool& value) const;
285
286 bool
287 GetObjectAsString (const std::string& key, std::string& value) const;
288
289 ~JSONObject() override = default;
290
291private:
292 typedef std::map<std::string, JSONValue::SP> Map;
293 typedef Map::iterator Iterator;
294 Map m_elements;
295};
296
297class JSONArray : public JSONValue
298{
299public:
300 JSONArray ();
301
302 JSONArray (const JSONArray& s) = delete;
303 JSONArray&
304 operator = (const JSONArray& s) = delete;
305
306 void
307 Write(std::ostream& s) override;
308
309 typedef std::shared_ptr<JSONArray> SP;
310
311 static bool classof(const JSONValue *V)
312 {
313 return V->GetKind() == JSONValue::Kind::Array;
314 }
315
316private:
317 typedef std::vector<JSONValue::SP> Vector;
318 typedef Vector::iterator Iterator;
319 typedef Vector::size_type Index;
320 typedef Vector::size_type Size;
321
322public:
323 bool
324 SetObject (Index i,
325 JSONValue::SP value);
326
327 bool
328 AppendObject (JSONValue::SP value);
329
330 JSONValue::SP
331 GetObject (Index i);
332
333 Size
334 GetNumElements ();
335
336 ~JSONArray() override = default;
337
338 Vector m_elements;
339};
340
Zachary Turner44c35e82016-08-29 19:45:59 +0000341class JSONParser : public StdStringExtractor
Todd Fiala75930012016-08-19 04:21:48 +0000342{
343public:
344 enum Token
345 {
346 Invalid,
347 Error,
348 ObjectStart,
349 ObjectEnd,
350 ArrayStart,
351 ArrayEnd,
352 Comma,
353 Colon,
354 String,
355 Integer,
356 Float,
357 True,
358 False,
359 Null,
360 EndOfFile
361 };
362
363 JSONParser (const char *cstr);
364
365 int
366 GetEscapedChar (bool &was_escaped);
367
368 Token
369 GetToken (std::string &value);
370
371 JSONValue::SP
372 ParseJSONValue ();
373
374protected:
375 JSONValue::SP
376 ParseJSONObject ();
377
378 JSONValue::SP
379 ParseJSONArray ();
380};
381
382#endif // utility_JSON_h_