xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/JSON.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===---------------------JSON.h --------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H
10dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H
11061da546Spatrick 
12061da546Spatrick #include "StdStringExtractor.h"
13061da546Spatrick 
14061da546Spatrick // C includes
15be691f3bSpatrick #include <cinttypes>
16be691f3bSpatrick #include <cstdint>
17061da546Spatrick 
18061da546Spatrick // C++ includes
19061da546Spatrick #include <map>
20061da546Spatrick #include <memory>
21061da546Spatrick #include <ostream>
22061da546Spatrick #include <string>
23061da546Spatrick #include <vector>
24061da546Spatrick 
25061da546Spatrick class JSONValue {
26061da546Spatrick public:
27061da546Spatrick   virtual void Write(std::ostream &s) = 0;
28061da546Spatrick 
29061da546Spatrick   typedef std::shared_ptr<JSONValue> SP;
30061da546Spatrick 
31061da546Spatrick   enum class Kind { String, Number, True, False, Null, Object, Array };
32061da546Spatrick 
JSONValue(Kind k)33061da546Spatrick   JSONValue(Kind k) : m_kind(k) {}
34061da546Spatrick 
GetKind()35061da546Spatrick   Kind GetKind() const { return m_kind; }
36061da546Spatrick 
37061da546Spatrick   virtual ~JSONValue() = default;
38061da546Spatrick 
39061da546Spatrick private:
40061da546Spatrick   const Kind m_kind;
41061da546Spatrick };
42061da546Spatrick 
43061da546Spatrick class JSONString : public JSONValue {
44061da546Spatrick public:
45061da546Spatrick   JSONString();
46061da546Spatrick   JSONString(const char *s);
47061da546Spatrick   JSONString(const std::string &s);
48061da546Spatrick 
49061da546Spatrick   JSONString(const JSONString &s) = delete;
50061da546Spatrick   JSONString &operator=(const JSONString &s) = delete;
51061da546Spatrick 
52061da546Spatrick   void Write(std::ostream &s) override;
53061da546Spatrick 
54061da546Spatrick   typedef std::shared_ptr<JSONString> SP;
55061da546Spatrick 
GetData()56061da546Spatrick   std::string GetData() { return m_data; }
57061da546Spatrick 
classof(const JSONValue * V)58061da546Spatrick   static bool classof(const JSONValue *V) {
59061da546Spatrick     return V->GetKind() == JSONValue::Kind::String;
60061da546Spatrick   }
61061da546Spatrick 
62061da546Spatrick   ~JSONString() override = default;
63061da546Spatrick 
64061da546Spatrick private:
65061da546Spatrick   static std::string json_string_quote_metachars(const std::string &);
66061da546Spatrick 
67061da546Spatrick   std::string m_data;
68061da546Spatrick };
69061da546Spatrick 
70061da546Spatrick class JSONNumber : public JSONValue {
71061da546Spatrick public:
72061da546Spatrick   typedef std::shared_ptr<JSONNumber> SP;
73061da546Spatrick 
74*f6aab3d8Srobert   // We create a constructor for all integer and floating point type with using
75061da546Spatrick   // templates and
76061da546Spatrick   // SFINAE to avoid having ambiguous overloads because of the implicit type
77061da546Spatrick   // promotion. If we
78061da546Spatrick   // would have constructors only with int64_t, uint64_t and double types then
79061da546Spatrick   // constructing a
80061da546Spatrick   // JSONNumber from an int32_t (or any other similar type) would fail to
81061da546Spatrick   // compile.
82061da546Spatrick 
83061da546Spatrick   template <typename T, typename std::enable_if<
84061da546Spatrick                             std::is_integral<T>::value &&
85061da546Spatrick                             std::is_unsigned<T>::value>::type * = nullptr>
JSONNumber(T u)86061da546Spatrick   explicit JSONNumber(T u)
87061da546Spatrick       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
88061da546Spatrick     m_data.m_unsigned = u;
89061da546Spatrick   }
90061da546Spatrick 
91061da546Spatrick   template <typename T,
92061da546Spatrick             typename std::enable_if<std::is_integral<T>::value &&
93061da546Spatrick                                     std::is_signed<T>::value>::type * = nullptr>
JSONNumber(T s)94061da546Spatrick   explicit JSONNumber(T s)
95061da546Spatrick       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
96061da546Spatrick     m_data.m_signed = s;
97061da546Spatrick   }
98061da546Spatrick 
99061da546Spatrick   template <typename T, typename std::enable_if<
100061da546Spatrick                             std::is_floating_point<T>::value>::type * = nullptr>
JSONNumber(T d)101061da546Spatrick   explicit JSONNumber(T d)
102061da546Spatrick       : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
103061da546Spatrick     m_data.m_double = d;
104061da546Spatrick   }
105061da546Spatrick 
106061da546Spatrick   ~JSONNumber() override = default;
107061da546Spatrick 
108061da546Spatrick   JSONNumber(const JSONNumber &s) = delete;
109061da546Spatrick   JSONNumber &operator=(const JSONNumber &s) = delete;
110061da546Spatrick 
111061da546Spatrick   void Write(std::ostream &s) override;
112061da546Spatrick 
113061da546Spatrick   uint64_t GetAsUnsigned() const;
114061da546Spatrick 
115061da546Spatrick   int64_t GetAsSigned() const;
116061da546Spatrick 
117061da546Spatrick   double GetAsDouble() const;
118061da546Spatrick 
classof(const JSONValue * V)119061da546Spatrick   static bool classof(const JSONValue *V) {
120061da546Spatrick     return V->GetKind() == JSONValue::Kind::Number;
121061da546Spatrick   }
122061da546Spatrick 
123061da546Spatrick private:
124061da546Spatrick   enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
125061da546Spatrick 
126061da546Spatrick   union {
127061da546Spatrick     uint64_t m_unsigned;
128061da546Spatrick     int64_t m_signed;
129061da546Spatrick     double m_double;
130061da546Spatrick   } m_data;
131061da546Spatrick };
132061da546Spatrick 
133061da546Spatrick class JSONTrue : public JSONValue {
134061da546Spatrick public:
135061da546Spatrick   JSONTrue();
136061da546Spatrick 
137061da546Spatrick   JSONTrue(const JSONTrue &s) = delete;
138061da546Spatrick   JSONTrue &operator=(const JSONTrue &s) = delete;
139061da546Spatrick 
140061da546Spatrick   void Write(std::ostream &s) override;
141061da546Spatrick 
142061da546Spatrick   typedef std::shared_ptr<JSONTrue> SP;
143061da546Spatrick 
classof(const JSONValue * V)144061da546Spatrick   static bool classof(const JSONValue *V) {
145061da546Spatrick     return V->GetKind() == JSONValue::Kind::True;
146061da546Spatrick   }
147061da546Spatrick 
148061da546Spatrick   ~JSONTrue() override = default;
149061da546Spatrick };
150061da546Spatrick 
151061da546Spatrick class JSONFalse : public JSONValue {
152061da546Spatrick public:
153061da546Spatrick   JSONFalse();
154061da546Spatrick 
155061da546Spatrick   JSONFalse(const JSONFalse &s) = delete;
156061da546Spatrick   JSONFalse &operator=(const JSONFalse &s) = delete;
157061da546Spatrick 
158061da546Spatrick   void Write(std::ostream &s) override;
159061da546Spatrick 
160061da546Spatrick   typedef std::shared_ptr<JSONFalse> SP;
161061da546Spatrick 
classof(const JSONValue * V)162061da546Spatrick   static bool classof(const JSONValue *V) {
163061da546Spatrick     return V->GetKind() == JSONValue::Kind::False;
164061da546Spatrick   }
165061da546Spatrick 
166061da546Spatrick   ~JSONFalse() override = default;
167061da546Spatrick };
168061da546Spatrick 
169061da546Spatrick class JSONNull : public JSONValue {
170061da546Spatrick public:
171061da546Spatrick   JSONNull();
172061da546Spatrick 
173061da546Spatrick   JSONNull(const JSONNull &s) = delete;
174061da546Spatrick   JSONNull &operator=(const JSONNull &s) = delete;
175061da546Spatrick 
176061da546Spatrick   void Write(std::ostream &s) override;
177061da546Spatrick 
178061da546Spatrick   typedef std::shared_ptr<JSONNull> SP;
179061da546Spatrick 
classof(const JSONValue * V)180061da546Spatrick   static bool classof(const JSONValue *V) {
181061da546Spatrick     return V->GetKind() == JSONValue::Kind::Null;
182061da546Spatrick   }
183061da546Spatrick 
184061da546Spatrick   ~JSONNull() override = default;
185061da546Spatrick };
186061da546Spatrick 
187061da546Spatrick class JSONObject : public JSONValue {
188061da546Spatrick public:
189061da546Spatrick   JSONObject();
190061da546Spatrick 
191061da546Spatrick   JSONObject(const JSONObject &s) = delete;
192061da546Spatrick   JSONObject &operator=(const JSONObject &s) = delete;
193061da546Spatrick 
194061da546Spatrick   void Write(std::ostream &s) override;
195061da546Spatrick 
196061da546Spatrick   typedef std::shared_ptr<JSONObject> SP;
197061da546Spatrick 
classof(const JSONValue * V)198061da546Spatrick   static bool classof(const JSONValue *V) {
199061da546Spatrick     return V->GetKind() == JSONValue::Kind::Object;
200061da546Spatrick   }
201061da546Spatrick 
202061da546Spatrick   bool SetObject(const std::string &key, JSONValue::SP value);
203061da546Spatrick 
204061da546Spatrick   JSONValue::SP GetObject(const std::string &key) const;
205061da546Spatrick 
206061da546Spatrick   /// Return keyed value as bool
207061da546Spatrick   ///
208061da546Spatrick   /// \param[in] key
209061da546Spatrick   ///     The value of the key to lookup
210061da546Spatrick   ///
211061da546Spatrick   /// \param[out] value
212061da546Spatrick   ///     The value of the key as a bool.  Undefined if the key doesn't
213061da546Spatrick   ///     exist or if the key is not either true or false.
214061da546Spatrick   ///
215061da546Spatrick   /// \return
216061da546Spatrick   ///     true if the key existed as was a bool value; false otherwise.
217061da546Spatrick   ///     Note the return value is *not* the value of the bool, use
218061da546Spatrick   ///     \b value for that.
219061da546Spatrick   bool GetObjectAsBool(const std::string &key, bool &value) const;
220061da546Spatrick 
221061da546Spatrick   bool GetObjectAsString(const std::string &key, std::string &value) const;
222061da546Spatrick 
223061da546Spatrick   ~JSONObject() override = default;
224061da546Spatrick 
225061da546Spatrick private:
226061da546Spatrick   typedef std::map<std::string, JSONValue::SP> Map;
227061da546Spatrick   typedef Map::iterator Iterator;
228061da546Spatrick   Map m_elements;
229061da546Spatrick };
230061da546Spatrick 
231061da546Spatrick class JSONArray : public JSONValue {
232061da546Spatrick public:
233061da546Spatrick   JSONArray();
234061da546Spatrick 
235061da546Spatrick   JSONArray(const JSONArray &s) = delete;
236061da546Spatrick   JSONArray &operator=(const JSONArray &s) = delete;
237061da546Spatrick 
238061da546Spatrick   void Write(std::ostream &s) override;
239061da546Spatrick 
240061da546Spatrick   typedef std::shared_ptr<JSONArray> SP;
241061da546Spatrick 
classof(const JSONValue * V)242061da546Spatrick   static bool classof(const JSONValue *V) {
243061da546Spatrick     return V->GetKind() == JSONValue::Kind::Array;
244061da546Spatrick   }
245061da546Spatrick 
246061da546Spatrick private:
247061da546Spatrick   typedef std::vector<JSONValue::SP> Vector;
248061da546Spatrick   typedef Vector::iterator Iterator;
249061da546Spatrick   typedef Vector::size_type Index;
250061da546Spatrick   typedef Vector::size_type Size;
251061da546Spatrick 
252061da546Spatrick public:
253061da546Spatrick   bool SetObject(Index i, JSONValue::SP value);
254061da546Spatrick 
255061da546Spatrick   bool AppendObject(JSONValue::SP value);
256061da546Spatrick 
257061da546Spatrick   JSONValue::SP GetObject(Index i);
258061da546Spatrick 
259061da546Spatrick   Size GetNumElements();
260061da546Spatrick 
261061da546Spatrick   ~JSONArray() override = default;
262061da546Spatrick 
263061da546Spatrick   Vector m_elements;
264061da546Spatrick };
265061da546Spatrick 
266061da546Spatrick class JSONParser : public StdStringExtractor {
267061da546Spatrick public:
268061da546Spatrick   enum Token {
269061da546Spatrick     Invalid,
270061da546Spatrick     Status,
271061da546Spatrick     ObjectStart,
272061da546Spatrick     ObjectEnd,
273061da546Spatrick     ArrayStart,
274061da546Spatrick     ArrayEnd,
275061da546Spatrick     Comma,
276061da546Spatrick     Colon,
277061da546Spatrick     String,
278061da546Spatrick     Integer,
279061da546Spatrick     Float,
280061da546Spatrick     True,
281061da546Spatrick     False,
282061da546Spatrick     Null,
283061da546Spatrick     EndOfFile
284061da546Spatrick   };
285061da546Spatrick 
286061da546Spatrick   JSONParser(const char *cstr);
287061da546Spatrick 
288061da546Spatrick   int GetEscapedChar(bool &was_escaped);
289061da546Spatrick 
290061da546Spatrick   Token GetToken(std::string &value);
291061da546Spatrick 
292061da546Spatrick   JSONValue::SP ParseJSONValue();
293061da546Spatrick 
294061da546Spatrick protected:
295061da546Spatrick   JSONValue::SP ParseJSONValue(const std::string &value, const Token &token);
296061da546Spatrick 
297061da546Spatrick   JSONValue::SP ParseJSONObject();
298061da546Spatrick 
299061da546Spatrick   JSONValue::SP ParseJSONArray();
300061da546Spatrick };
301061da546Spatrick 
302dda28197Spatrick #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H
303