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
25class JSONValue {
26public:
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
39private:
40 const Kind m_kind;
41};
42
43class JSONString : public JSONValue {
44public:
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
64private:
65 static std::string json_string_quote_metachars(const std::string &);
66
67 std::string m_data;
68};
69
70class JSONNumber : public JSONValue {
71public:
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
123private:
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
133class JSONTrue : public JSONValue {
134public:
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
151class JSONFalse : public JSONValue {
152public:
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
169class JSONNull : public JSONValue {
170public:
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
187class JSONObject : public JSONValue {
188public:
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
225private:
226 typedef std::map<std::string, JSONValue::SP> Map;
227 typedef Map::iterator Iterator;
228 Map m_elements;
229};
230
231class JSONArray : public JSONValue {
232public:
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
246private:
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
252public:
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
266class JSONParser : public StdStringExtractor {
267public:
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
294protected:
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

source code of lldb/tools/debugserver/source/JSON.h