1 | //===---------------------JSON.h --------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H |
10 | #define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H |
11 | |
12 | #include "StdStringExtractor.h" |
13 | |
14 | // C includes |
15 | #include <cinttypes> |
16 | #include <cstdint> |
17 | |
18 | // C++ includes |
19 | #include <map> |
20 | #include <memory> |
21 | #include <ostream> |
22 | #include <string> |
23 | #include <vector> |
24 | |
25 | class JSONValue { |
26 | public: |
27 | virtual void Write(std::ostream &s) = 0; |
28 | |
29 | typedef std::shared_ptr<JSONValue> SP; |
30 | |
31 | enum class Kind { String, Number, True, False, Null, Object, Array }; |
32 | |
33 | JSONValue(Kind k) : m_kind(k) {} |
34 | |
35 | Kind GetKind() const { return m_kind; } |
36 | |
37 | virtual ~JSONValue() = default; |
38 | |
39 | private: |
40 | const Kind m_kind; |
41 | }; |
42 | |
43 | class JSONString : public JSONValue { |
44 | public: |
45 | JSONString(); |
46 | JSONString(const char *s); |
47 | JSONString(const std::string &s); |
48 | |
49 | JSONString(const JSONString &s) = delete; |
50 | JSONString &operator=(const JSONString &s) = delete; |
51 | |
52 | void Write(std::ostream &s) override; |
53 | |
54 | typedef std::shared_ptr<JSONString> SP; |
55 | |
56 | std::string GetData() { return m_data; } |
57 | |
58 | static bool classof(const JSONValue *V) { |
59 | return V->GetKind() == JSONValue::Kind::String; |
60 | } |
61 | |
62 | ~JSONString() override = default; |
63 | |
64 | private: |
65 | static std::string json_string_quote_metachars(const std::string &); |
66 | |
67 | std::string m_data; |
68 | }; |
69 | |
70 | class JSONNumber : public JSONValue { |
71 | public: |
72 | typedef std::shared_ptr<JSONNumber> SP; |
73 | |
74 | // We create a constructor for all integer and floating point type with using |
75 | // templates and |
76 | // SFINAE to avoid having ambiguous overloads because of the implicit type |
77 | // promotion. If we |
78 | // would have constructors only with int64_t, uint64_t and double types then |
79 | // constructing a |
80 | // JSONNumber from an int32_t (or any other similar type) would fail to |
81 | // compile. |
82 | |
83 | template <typename T, typename std::enable_if< |
84 | std::is_integral<T>::value && |
85 | std::is_unsigned<T>::value>::type * = nullptr> |
86 | explicit JSONNumber(T u) |
87 | : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { |
88 | m_data.m_unsigned = u; |
89 | } |
90 | |
91 | template <typename T, |
92 | typename std::enable_if<std::is_integral<T>::value && |
93 | std::is_signed<T>::value>::type * = nullptr> |
94 | explicit JSONNumber(T s) |
95 | : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { |
96 | m_data.m_signed = s; |
97 | } |
98 | |
99 | template <typename T, typename std::enable_if< |
100 | std::is_floating_point<T>::value>::type * = nullptr> |
101 | explicit JSONNumber(T d) |
102 | : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { |
103 | m_data.m_double = d; |
104 | } |
105 | |
106 | ~JSONNumber() override = default; |
107 | |
108 | JSONNumber(const JSONNumber &s) = delete; |
109 | JSONNumber &operator=(const JSONNumber &s) = delete; |
110 | |
111 | void Write(std::ostream &s) override; |
112 | |
113 | uint64_t GetAsUnsigned() const; |
114 | |
115 | int64_t GetAsSigned() const; |
116 | |
117 | double GetAsDouble() const; |
118 | |
119 | static bool classof(const JSONValue *V) { |
120 | return V->GetKind() == JSONValue::Kind::Number; |
121 | } |
122 | |
123 | private: |
124 | enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; |
125 | |
126 | union { |
127 | uint64_t m_unsigned; |
128 | int64_t m_signed; |
129 | double m_double; |
130 | } m_data; |
131 | }; |
132 | |
133 | class JSONTrue : public JSONValue { |
134 | public: |
135 | JSONTrue(); |
136 | |
137 | JSONTrue(const JSONTrue &s) = delete; |
138 | JSONTrue &operator=(const JSONTrue &s) = delete; |
139 | |
140 | void Write(std::ostream &s) override; |
141 | |
142 | typedef std::shared_ptr<JSONTrue> SP; |
143 | |
144 | static bool classof(const JSONValue *V) { |
145 | return V->GetKind() == JSONValue::Kind::True; |
146 | } |
147 | |
148 | ~JSONTrue() override = default; |
149 | }; |
150 | |
151 | class JSONFalse : public JSONValue { |
152 | public: |
153 | JSONFalse(); |
154 | |
155 | JSONFalse(const JSONFalse &s) = delete; |
156 | JSONFalse &operator=(const JSONFalse &s) = delete; |
157 | |
158 | void Write(std::ostream &s) override; |
159 | |
160 | typedef std::shared_ptr<JSONFalse> SP; |
161 | |
162 | static bool classof(const JSONValue *V) { |
163 | return V->GetKind() == JSONValue::Kind::False; |
164 | } |
165 | |
166 | ~JSONFalse() override = default; |
167 | }; |
168 | |
169 | class JSONNull : public JSONValue { |
170 | public: |
171 | JSONNull(); |
172 | |
173 | JSONNull(const JSONNull &s) = delete; |
174 | JSONNull &operator=(const JSONNull &s) = delete; |
175 | |
176 | void Write(std::ostream &s) override; |
177 | |
178 | typedef std::shared_ptr<JSONNull> SP; |
179 | |
180 | static bool classof(const JSONValue *V) { |
181 | return V->GetKind() == JSONValue::Kind::Null; |
182 | } |
183 | |
184 | ~JSONNull() override = default; |
185 | }; |
186 | |
187 | class JSONObject : public JSONValue { |
188 | public: |
189 | JSONObject(); |
190 | |
191 | JSONObject(const JSONObject &s) = delete; |
192 | JSONObject &operator=(const JSONObject &s) = delete; |
193 | |
194 | void Write(std::ostream &s) override; |
195 | |
196 | typedef std::shared_ptr<JSONObject> SP; |
197 | |
198 | static bool classof(const JSONValue *V) { |
199 | return V->GetKind() == JSONValue::Kind::Object; |
200 | } |
201 | |
202 | bool SetObject(const std::string &key, JSONValue::SP value); |
203 | |
204 | JSONValue::SP GetObject(const std::string &key) const; |
205 | |
206 | /// Return keyed value as bool |
207 | /// |
208 | /// \param[in] key |
209 | /// The value of the key to lookup |
210 | /// |
211 | /// \param[out] value |
212 | /// The value of the key as a bool. Undefined if the key doesn't |
213 | /// exist or if the key is not either true or false. |
214 | /// |
215 | /// \return |
216 | /// true if the key existed as was a bool value; false otherwise. |
217 | /// Note the return value is *not* the value of the bool, use |
218 | /// \b value for that. |
219 | bool GetObjectAsBool(const std::string &key, bool &value) const; |
220 | |
221 | bool GetObjectAsString(const std::string &key, std::string &value) const; |
222 | |
223 | ~JSONObject() override = default; |
224 | |
225 | private: |
226 | typedef std::map<std::string, JSONValue::SP> Map; |
227 | typedef Map::iterator Iterator; |
228 | Map m_elements; |
229 | }; |
230 | |
231 | class JSONArray : public JSONValue { |
232 | public: |
233 | JSONArray(); |
234 | |
235 | JSONArray(const JSONArray &s) = delete; |
236 | JSONArray &operator=(const JSONArray &s) = delete; |
237 | |
238 | void Write(std::ostream &s) override; |
239 | |
240 | typedef std::shared_ptr<JSONArray> SP; |
241 | |
242 | static bool classof(const JSONValue *V) { |
243 | return V->GetKind() == JSONValue::Kind::Array; |
244 | } |
245 | |
246 | private: |
247 | typedef std::vector<JSONValue::SP> Vector; |
248 | typedef Vector::iterator Iterator; |
249 | typedef Vector::size_type Index; |
250 | typedef Vector::size_type Size; |
251 | |
252 | public: |
253 | bool SetObject(Index i, JSONValue::SP value); |
254 | |
255 | bool AppendObject(JSONValue::SP value); |
256 | |
257 | JSONValue::SP GetObject(Index i); |
258 | |
259 | Size GetNumElements(); |
260 | |
261 | ~JSONArray() override = default; |
262 | |
263 | Vector m_elements; |
264 | }; |
265 | |
266 | class JSONParser : public StdStringExtractor { |
267 | public: |
268 | enum Token { |
269 | Invalid, |
270 | Status, |
271 | ObjectStart, |
272 | ObjectEnd, |
273 | ArrayStart, |
274 | ArrayEnd, |
275 | Comma, |
276 | Colon, |
277 | String, |
278 | Integer, |
279 | Float, |
280 | True, |
281 | False, |
282 | Null, |
283 | EndOfFile |
284 | }; |
285 | |
286 | JSONParser(const char *cstr); |
287 | |
288 | int GetEscapedChar(bool &was_escaped); |
289 | |
290 | Token GetToken(std::string &value); |
291 | |
292 | JSONValue::SP ParseJSONValue(); |
293 | |
294 | protected: |
295 | JSONValue::SP ParseJSONValue(const std::string &value, const Token &token); |
296 | |
297 | JSONValue::SP ParseJSONObject(); |
298 | |
299 | JSONValue::SP ParseJSONArray(); |
300 | }; |
301 | |
302 | #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H |
303 | |