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