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 utility_JSON_h_ 10 #define utility_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 33 JSONValue(Kind k) : m_kind(k) {} 34 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 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 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> 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 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 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 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 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 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 // ------------------------------------------------------------------------- 207 /// Return keyed value as bool 208 /// 209 /// @param[in] key 210 /// The value of the key to lookup 211 /// 212 /// @param[out] value 213 /// The value of the key as a bool. Undefined if the key doesn't 214 /// exist or if the key is not either true or false. 215 /// 216 /// @return 217 /// true if the key existed as was a bool value; false otherwise. 218 /// Note the return value is *not* the value of the bool, use 219 /// \b value for that. 220 // ------------------------------------------------------------------------- 221 bool GetObjectAsBool(const std::string &key, bool &value) const; 222 223 bool GetObjectAsString(const std::string &key, std::string &value) const; 224 225 ~JSONObject() override = default; 226 227 private: 228 typedef std::map<std::string, JSONValue::SP> Map; 229 typedef Map::iterator Iterator; 230 Map m_elements; 231 }; 232 233 class JSONArray : public JSONValue { 234 public: 235 JSONArray(); 236 237 JSONArray(const JSONArray &s) = delete; 238 JSONArray &operator=(const JSONArray &s) = delete; 239 240 void Write(std::ostream &s) override; 241 242 typedef std::shared_ptr<JSONArray> SP; 243 244 static bool classof(const JSONValue *V) { 245 return V->GetKind() == JSONValue::Kind::Array; 246 } 247 248 private: 249 typedef std::vector<JSONValue::SP> Vector; 250 typedef Vector::iterator Iterator; 251 typedef Vector::size_type Index; 252 typedef Vector::size_type Size; 253 254 public: 255 bool SetObject(Index i, JSONValue::SP value); 256 257 bool AppendObject(JSONValue::SP value); 258 259 JSONValue::SP GetObject(Index i); 260 261 Size GetNumElements(); 262 263 ~JSONArray() override = default; 264 265 Vector m_elements; 266 }; 267 268 class JSONParser : public StdStringExtractor { 269 public: 270 enum Token { 271 Invalid, 272 Status, 273 ObjectStart, 274 ObjectEnd, 275 ArrayStart, 276 ArrayEnd, 277 Comma, 278 Colon, 279 String, 280 Integer, 281 Float, 282 True, 283 False, 284 Null, 285 EndOfFile 286 }; 287 288 JSONParser(const char *cstr); 289 290 int GetEscapedChar(bool &was_escaped); 291 292 Token GetToken(std::string &value); 293 294 JSONValue::SP ParseJSONValue(); 295 296 protected: 297 JSONValue::SP ParseJSONObject(); 298 299 JSONValue::SP ParseJSONArray(); 300 }; 301 302 #endif // utility_JSON_h_ 303