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