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 #include "lldb/Utility/StringExtractor.h"
14 
15 #include <map>
16 #include <memory>
17 #include <string>
18 #include <type_traits>
19 #include <vector>
20 
21 #include <stdint.h>
22 
23 namespace lldb_private {
24 class Stream;
25 }
26 namespace lldb_private {
27 
28 class JSONValue {
29 public:
30   virtual void Write(Stream &s) = 0;
31 
32   typedef std::shared_ptr<JSONValue> SP;
33 
34   enum class Kind { String, Number, True, False, Null, Object, Array };
35 
JSONValue(Kind k)36   JSONValue(Kind k) : m_kind(k) {}
37 
GetKind()38   Kind GetKind() const { return m_kind; }
39 
40   virtual ~JSONValue() = default;
41 
42 private:
43   const Kind m_kind;
44 };
45 
46 class JSONString : public JSONValue {
47 public:
48   JSONString();
49   JSONString(const char *s);
50   JSONString(const std::string &s);
51 
52   JSONString(const JSONString &s) = delete;
53   JSONString &operator=(const JSONString &s) = delete;
54 
55   void Write(Stream &s) override;
56 
57   typedef std::shared_ptr<JSONString> SP;
58 
GetData()59   std::string GetData() { return m_data; }
60 
classof(const JSONValue * V)61   static bool classof(const JSONValue *V) {
62     return V->GetKind() == JSONValue::Kind::String;
63   }
64 
65   ~JSONString() override = default;
66 
67 private:
68   static std::string json_string_quote_metachars(const std::string &);
69 
70   std::string m_data;
71 };
72 
73 class JSONNumber : public JSONValue {
74 public:
75   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 JSONNumber from an int32_t (or any other similar type)
83   // would fail to compile.
84 
85   template <typename T, typename std::enable_if<
86                             std::is_integral<T>::value &&
87                             std::is_unsigned<T>::value>::type * = nullptr>
JSONNumber(T u)88   explicit JSONNumber(T u)
89       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
90     m_data.m_unsigned = u;
91   }
92 
93   template <typename T,
94             typename std::enable_if<std::is_integral<T>::value &&
95                                     std::is_signed<T>::value>::type * = nullptr>
JSONNumber(T s)96   explicit JSONNumber(T s)
97       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
98     m_data.m_signed = s;
99   }
100 
101   template <typename T, typename std::enable_if<
102                             std::is_floating_point<T>::value>::type * = nullptr>
JSONNumber(T d)103   explicit JSONNumber(T d)
104       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
105     m_data.m_double = d;
106   }
107 
108   ~JSONNumber() override = default;
109 
110   JSONNumber(const JSONNumber &s) = delete;
111   JSONNumber &operator=(const JSONNumber &s) = delete;
112 
113   void Write(Stream &s) override;
114 
115   uint64_t GetAsUnsigned() const;
116 
117   int64_t GetAsSigned() const;
118 
119   double GetAsDouble() const;
120 
classof(const JSONValue * V)121   static bool classof(const JSONValue *V) {
122     return V->GetKind() == JSONValue::Kind::Number;
123   }
124 
125 private:
126   enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
127 
128   union {
129     uint64_t m_unsigned;
130     int64_t m_signed;
131     double m_double;
132   } m_data;
133 };
134 
135 class JSONTrue : public JSONValue {
136 public:
137   JSONTrue();
138 
139   JSONTrue(const JSONTrue &s) = delete;
140   JSONTrue &operator=(const JSONTrue &s) = delete;
141 
142   void Write(Stream &s) override;
143 
144   typedef std::shared_ptr<JSONTrue> SP;
145 
classof(const JSONValue * V)146   static bool classof(const JSONValue *V) {
147     return V->GetKind() == JSONValue::Kind::True;
148   }
149 
150   ~JSONTrue() override = default;
151 };
152 
153 class JSONFalse : public JSONValue {
154 public:
155   JSONFalse();
156 
157   JSONFalse(const JSONFalse &s) = delete;
158   JSONFalse &operator=(const JSONFalse &s) = delete;
159 
160   void Write(Stream &s) override;
161 
162   typedef std::shared_ptr<JSONFalse> SP;
163 
classof(const JSONValue * V)164   static bool classof(const JSONValue *V) {
165     return V->GetKind() == JSONValue::Kind::False;
166   }
167 
168   ~JSONFalse() override = default;
169 };
170 
171 class JSONNull : public JSONValue {
172 public:
173   JSONNull();
174 
175   JSONNull(const JSONNull &s) = delete;
176   JSONNull &operator=(const JSONNull &s) = delete;
177 
178   void Write(Stream &s) override;
179 
180   typedef std::shared_ptr<JSONNull> SP;
181 
classof(const JSONValue * V)182   static bool classof(const JSONValue *V) {
183     return V->GetKind() == JSONValue::Kind::Null;
184   }
185 
186   ~JSONNull() override = default;
187 };
188 
189 class JSONObject : public JSONValue {
190 public:
191   JSONObject();
192 
193   JSONObject(const JSONObject &s) = delete;
194   JSONObject &operator=(const JSONObject &s) = delete;
195 
196   void Write(Stream &s) override;
197 
198   typedef std::shared_ptr<JSONObject> SP;
199 
classof(const JSONValue * V)200   static bool classof(const JSONValue *V) {
201     return V->GetKind() == JSONValue::Kind::Object;
202   }
203 
204   bool SetObject(const std::string &key, JSONValue::SP value);
205 
206   JSONValue::SP GetObject(const std::string &key);
207 
208   ~JSONObject() override = default;
209 
210 private:
211   typedef std::map<std::string, JSONValue::SP> Map;
212   typedef Map::iterator Iterator;
213   Map m_elements;
214 };
215 
216 class JSONArray : public JSONValue {
217 public:
218   JSONArray();
219 
220   JSONArray(const JSONArray &s) = delete;
221   JSONArray &operator=(const JSONArray &s) = delete;
222 
223   void Write(Stream &s) override;
224 
225   typedef std::shared_ptr<JSONArray> SP;
226 
classof(const JSONValue * V)227   static bool classof(const JSONValue *V) {
228     return V->GetKind() == JSONValue::Kind::Array;
229   }
230 
231 private:
232   typedef std::vector<JSONValue::SP> Vector;
233   typedef Vector::iterator Iterator;
234   typedef Vector::size_type Index;
235   typedef Vector::size_type Size;
236 
237 public:
238   bool SetObject(Index i, JSONValue::SP value);
239 
240   bool AppendObject(JSONValue::SP value);
241 
242   JSONValue::SP GetObject(Index i);
243 
244   Size GetNumElements();
245 
246   ~JSONArray() override = default;
247 
248   Vector m_elements;
249 };
250 
251 class JSONParser : public StringExtractor {
252 public:
253   enum Token {
254     Invalid,
255     Status,
256     ObjectStart,
257     ObjectEnd,
258     ArrayStart,
259     ArrayEnd,
260     Comma,
261     Colon,
262     String,
263     Integer,
264     Float,
265     True,
266     False,
267     Null,
268     EndOfFile
269   };
270 
271   JSONParser(llvm::StringRef data);
272 
273   int GetEscapedChar(bool &was_escaped);
274 
275   Token GetToken(std::string &value);
276 
277   JSONValue::SP ParseJSONValue();
278 
279 protected:
280   JSONValue::SP ParseJSONObject();
281 
282   JSONValue::SP ParseJSONArray();
283 };
284 } // namespace lldb_private
285 
286 #endif // utility_JSON_h_
287