1 //===---------------------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 
13 // This cross-project usage is fine as StringExtractor.h is entirely
14 // self-contained.
15 #include "lldb/Utility/StringExtractor.h"
16 
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 
28 class JSONValue
29 {
30 public:
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 
60 private:
61     const Kind m_kind;
62 };
63 
64 class JSONString : public JSONValue
65 {
66 public:
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 
90 private:
91 
92     static std::string
93     json_string_quote_metachars (const std::string&);
94 
95     std::string m_data;
96 };
97 
98 class JSONNumber : public JSONValue
99 {
100 public:
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 
160 private:
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 
176 class JSONTrue : public JSONValue
177 {
178 public:
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 
198 class JSONFalse : public JSONValue
199 {
200 public:
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 
220 class JSONNull : public JSONValue
221 {
222 public:
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 
242 class JSONObject : public JSONValue
243 {
244 public:
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 
291 private:
292     typedef std::map<std::string, JSONValue::SP> Map;
293     typedef Map::iterator Iterator;
294     Map m_elements;
295 };
296 
297 class JSONArray : public JSONValue
298 {
299 public:
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 
316 private:
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 
322 public:
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 
341 class JSONParser : public StringExtractor
342 {
343 public:
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 
374 protected:
375     JSONValue::SP
376     ParseJSONObject ();
377 
378     JSONValue::SP
379     ParseJSONArray ();
380 };
381 
382 #endif // utility_JSON_h_
383