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 <inttypes.h> 16 #include <stdint.h> 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 JSONValue(Kind k)33 JSONValue(Kind k) : m_kind(k) {} 34 GetKind()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 GetData()56 std::string GetData() { return m_data; } 57 classof(const JSONValue * V)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 cretae 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> JSONNumber(T u)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> JSONNumber(T s)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> JSONNumber(T d)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 classof(const JSONValue * V)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 classof(const JSONValue * V)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 classof(const JSONValue * V)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 classof(const JSONValue * V)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 classof(const JSONValue * V)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 classof(const JSONValue * V)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