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 // This cross-project usage is fine as StdStringExtractor.h is entirely 14 // self-contained. 15 #include "lldb/Utility/StdStringExtractor.h" 16 17 // C includes 18 #include <inttypes.h> 19 #include <stdint.h> 20 21 // C++ includes 22 #include <map> 23 #include <memory> 24 #include <ostream> 25 #include <string> 26 #include <vector> 27 28 class JSONValue { 29 public: 30 virtual void Write(std::ostream &s) = 0; 31 32 typedef std::shared_ptr<JSONValue> SP; 33 34 enum class Kind { String, Number, True, False, Null, Object, Array }; 35 36 JSONValue(Kind k) : m_kind(k) {} 37 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(std::ostream &s) override; 56 57 typedef std::shared_ptr<JSONString> SP; 58 59 std::string GetData() { return m_data; } 60 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 83 // JSONNumber from an int32_t (or any other similar type) would fail to 84 // compile. 85 86 template <typename T, typename std::enable_if< 87 std::is_integral<T>::value && 88 std::is_unsigned<T>::value>::type * = nullptr> 89 explicit JSONNumber(T u) 90 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { 91 m_data.m_unsigned = u; 92 } 93 94 template <typename T, 95 typename std::enable_if<std::is_integral<T>::value && 96 std::is_signed<T>::value>::type * = nullptr> 97 explicit JSONNumber(T s) 98 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { 99 m_data.m_signed = s; 100 } 101 102 template <typename T, typename std::enable_if< 103 std::is_floating_point<T>::value>::type * = nullptr> 104 explicit JSONNumber(T d) 105 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { 106 m_data.m_double = d; 107 } 108 109 ~JSONNumber() override = default; 110 111 JSONNumber(const JSONNumber &s) = delete; 112 JSONNumber &operator=(const JSONNumber &s) = delete; 113 114 void Write(std::ostream &s) override; 115 116 uint64_t GetAsUnsigned() const; 117 118 int64_t GetAsSigned() const; 119 120 double GetAsDouble() const; 121 122 static bool classof(const JSONValue *V) { 123 return V->GetKind() == JSONValue::Kind::Number; 124 } 125 126 private: 127 enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; 128 129 union { 130 uint64_t m_unsigned; 131 int64_t m_signed; 132 double m_double; 133 } m_data; 134 }; 135 136 class JSONTrue : public JSONValue { 137 public: 138 JSONTrue(); 139 140 JSONTrue(const JSONTrue &s) = delete; 141 JSONTrue &operator=(const JSONTrue &s) = delete; 142 143 void Write(std::ostream &s) override; 144 145 typedef std::shared_ptr<JSONTrue> SP; 146 147 static bool classof(const JSONValue *V) { 148 return V->GetKind() == JSONValue::Kind::True; 149 } 150 151 ~JSONTrue() override = default; 152 }; 153 154 class JSONFalse : public JSONValue { 155 public: 156 JSONFalse(); 157 158 JSONFalse(const JSONFalse &s) = delete; 159 JSONFalse &operator=(const JSONFalse &s) = delete; 160 161 void Write(std::ostream &s) override; 162 163 typedef std::shared_ptr<JSONFalse> SP; 164 165 static bool classof(const JSONValue *V) { 166 return V->GetKind() == JSONValue::Kind::False; 167 } 168 169 ~JSONFalse() override = default; 170 }; 171 172 class JSONNull : public JSONValue { 173 public: 174 JSONNull(); 175 176 JSONNull(const JSONNull &s) = delete; 177 JSONNull &operator=(const JSONNull &s) = delete; 178 179 void Write(std::ostream &s) override; 180 181 typedef std::shared_ptr<JSONNull> SP; 182 183 static bool classof(const JSONValue *V) { 184 return V->GetKind() == JSONValue::Kind::Null; 185 } 186 187 ~JSONNull() override = default; 188 }; 189 190 class JSONObject : public JSONValue { 191 public: 192 JSONObject(); 193 194 JSONObject(const JSONObject &s) = delete; 195 JSONObject &operator=(const JSONObject &s) = delete; 196 197 void Write(std::ostream &s) override; 198 199 typedef std::shared_ptr<JSONObject> SP; 200 201 static bool classof(const JSONValue *V) { 202 return V->GetKind() == JSONValue::Kind::Object; 203 } 204 205 bool SetObject(const std::string &key, JSONValue::SP value); 206 207 JSONValue::SP GetObject(const std::string &key) const; 208 209 // ------------------------------------------------------------------------- 210 /// Return keyed value as bool 211 /// 212 /// @param[in] key 213 /// The value of the key to lookup 214 /// 215 /// @param[out] value 216 /// The value of the key as a bool. Undefined if the key doesn't 217 /// exist or if the key is not either true or false. 218 /// 219 /// @return 220 /// true if the key existed as was a bool value; false otherwise. 221 /// Note the return value is *not* the value of the bool, use 222 /// \b value for that. 223 // ------------------------------------------------------------------------- 224 bool GetObjectAsBool(const std::string &key, bool &value) const; 225 226 bool GetObjectAsString(const std::string &key, std::string &value) const; 227 228 ~JSONObject() override = default; 229 230 private: 231 typedef std::map<std::string, JSONValue::SP> Map; 232 typedef Map::iterator Iterator; 233 Map m_elements; 234 }; 235 236 class JSONArray : public JSONValue { 237 public: 238 JSONArray(); 239 240 JSONArray(const JSONArray &s) = delete; 241 JSONArray &operator=(const JSONArray &s) = delete; 242 243 void Write(std::ostream &s) override; 244 245 typedef std::shared_ptr<JSONArray> SP; 246 247 static bool classof(const JSONValue *V) { 248 return V->GetKind() == JSONValue::Kind::Array; 249 } 250 251 private: 252 typedef std::vector<JSONValue::SP> Vector; 253 typedef Vector::iterator Iterator; 254 typedef Vector::size_type Index; 255 typedef Vector::size_type Size; 256 257 public: 258 bool SetObject(Index i, JSONValue::SP value); 259 260 bool AppendObject(JSONValue::SP value); 261 262 JSONValue::SP GetObject(Index i); 263 264 Size GetNumElements(); 265 266 ~JSONArray() override = default; 267 268 Vector m_elements; 269 }; 270 271 class JSONParser : public StdStringExtractor { 272 public: 273 enum Token { 274 Invalid, 275 Error, 276 ObjectStart, 277 ObjectEnd, 278 ArrayStart, 279 ArrayEnd, 280 Comma, 281 Colon, 282 String, 283 Integer, 284 Float, 285 True, 286 False, 287 Null, 288 EndOfFile 289 }; 290 291 JSONParser(const char *cstr); 292 293 int GetEscapedChar(bool &was_escaped); 294 295 Token GetToken(std::string &value); 296 297 JSONValue::SP ParseJSONValue(); 298 299 protected: 300 JSONValue::SP ParseJSONObject(); 301 302 JSONValue::SP ParseJSONArray(); 303 }; 304 305 #endif // utility_JSON_h_ 306