1061da546Spatrick //===---------------------JSON.h --------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 10dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 11061da546Spatrick 12061da546Spatrick #include "StdStringExtractor.h" 13061da546Spatrick 14061da546Spatrick // C includes 15be691f3bSpatrick #include <cinttypes> 16be691f3bSpatrick #include <cstdint> 17061da546Spatrick 18061da546Spatrick // C++ includes 19061da546Spatrick #include <map> 20061da546Spatrick #include <memory> 21061da546Spatrick #include <ostream> 22061da546Spatrick #include <string> 23061da546Spatrick #include <vector> 24061da546Spatrick 25061da546Spatrick class JSONValue { 26061da546Spatrick public: 27061da546Spatrick virtual void Write(std::ostream &s) = 0; 28061da546Spatrick 29061da546Spatrick typedef std::shared_ptr<JSONValue> SP; 30061da546Spatrick 31061da546Spatrick enum class Kind { String, Number, True, False, Null, Object, Array }; 32061da546Spatrick JSONValue(Kind k)33061da546Spatrick JSONValue(Kind k) : m_kind(k) {} 34061da546Spatrick GetKind()35061da546Spatrick Kind GetKind() const { return m_kind; } 36061da546Spatrick 37061da546Spatrick virtual ~JSONValue() = default; 38061da546Spatrick 39061da546Spatrick private: 40061da546Spatrick const Kind m_kind; 41061da546Spatrick }; 42061da546Spatrick 43061da546Spatrick class JSONString : public JSONValue { 44061da546Spatrick public: 45061da546Spatrick JSONString(); 46061da546Spatrick JSONString(const char *s); 47061da546Spatrick JSONString(const std::string &s); 48061da546Spatrick 49061da546Spatrick JSONString(const JSONString &s) = delete; 50061da546Spatrick JSONString &operator=(const JSONString &s) = delete; 51061da546Spatrick 52061da546Spatrick void Write(std::ostream &s) override; 53061da546Spatrick 54061da546Spatrick typedef std::shared_ptr<JSONString> SP; 55061da546Spatrick GetData()56061da546Spatrick std::string GetData() { return m_data; } 57061da546Spatrick classof(const JSONValue * V)58061da546Spatrick static bool classof(const JSONValue *V) { 59061da546Spatrick return V->GetKind() == JSONValue::Kind::String; 60061da546Spatrick } 61061da546Spatrick 62061da546Spatrick ~JSONString() override = default; 63061da546Spatrick 64061da546Spatrick private: 65061da546Spatrick static std::string json_string_quote_metachars(const std::string &); 66061da546Spatrick 67061da546Spatrick std::string m_data; 68061da546Spatrick }; 69061da546Spatrick 70061da546Spatrick class JSONNumber : public JSONValue { 71061da546Spatrick public: 72061da546Spatrick typedef std::shared_ptr<JSONNumber> SP; 73061da546Spatrick 74*f6aab3d8Srobert // We create a constructor for all integer and floating point type with using 75061da546Spatrick // templates and 76061da546Spatrick // SFINAE to avoid having ambiguous overloads because of the implicit type 77061da546Spatrick // promotion. If we 78061da546Spatrick // would have constructors only with int64_t, uint64_t and double types then 79061da546Spatrick // constructing a 80061da546Spatrick // JSONNumber from an int32_t (or any other similar type) would fail to 81061da546Spatrick // compile. 82061da546Spatrick 83061da546Spatrick template <typename T, typename std::enable_if< 84061da546Spatrick std::is_integral<T>::value && 85061da546Spatrick std::is_unsigned<T>::value>::type * = nullptr> JSONNumber(T u)86061da546Spatrick explicit JSONNumber(T u) 87061da546Spatrick : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { 88061da546Spatrick m_data.m_unsigned = u; 89061da546Spatrick } 90061da546Spatrick 91061da546Spatrick template <typename T, 92061da546Spatrick typename std::enable_if<std::is_integral<T>::value && 93061da546Spatrick std::is_signed<T>::value>::type * = nullptr> JSONNumber(T s)94061da546Spatrick explicit JSONNumber(T s) 95061da546Spatrick : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { 96061da546Spatrick m_data.m_signed = s; 97061da546Spatrick } 98061da546Spatrick 99061da546Spatrick template <typename T, typename std::enable_if< 100061da546Spatrick std::is_floating_point<T>::value>::type * = nullptr> JSONNumber(T d)101061da546Spatrick explicit JSONNumber(T d) 102061da546Spatrick : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { 103061da546Spatrick m_data.m_double = d; 104061da546Spatrick } 105061da546Spatrick 106061da546Spatrick ~JSONNumber() override = default; 107061da546Spatrick 108061da546Spatrick JSONNumber(const JSONNumber &s) = delete; 109061da546Spatrick JSONNumber &operator=(const JSONNumber &s) = delete; 110061da546Spatrick 111061da546Spatrick void Write(std::ostream &s) override; 112061da546Spatrick 113061da546Spatrick uint64_t GetAsUnsigned() const; 114061da546Spatrick 115061da546Spatrick int64_t GetAsSigned() const; 116061da546Spatrick 117061da546Spatrick double GetAsDouble() const; 118061da546Spatrick classof(const JSONValue * V)119061da546Spatrick static bool classof(const JSONValue *V) { 120061da546Spatrick return V->GetKind() == JSONValue::Kind::Number; 121061da546Spatrick } 122061da546Spatrick 123061da546Spatrick private: 124061da546Spatrick enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; 125061da546Spatrick 126061da546Spatrick union { 127061da546Spatrick uint64_t m_unsigned; 128061da546Spatrick int64_t m_signed; 129061da546Spatrick double m_double; 130061da546Spatrick } m_data; 131061da546Spatrick }; 132061da546Spatrick 133061da546Spatrick class JSONTrue : public JSONValue { 134061da546Spatrick public: 135061da546Spatrick JSONTrue(); 136061da546Spatrick 137061da546Spatrick JSONTrue(const JSONTrue &s) = delete; 138061da546Spatrick JSONTrue &operator=(const JSONTrue &s) = delete; 139061da546Spatrick 140061da546Spatrick void Write(std::ostream &s) override; 141061da546Spatrick 142061da546Spatrick typedef std::shared_ptr<JSONTrue> SP; 143061da546Spatrick classof(const JSONValue * V)144061da546Spatrick static bool classof(const JSONValue *V) { 145061da546Spatrick return V->GetKind() == JSONValue::Kind::True; 146061da546Spatrick } 147061da546Spatrick 148061da546Spatrick ~JSONTrue() override = default; 149061da546Spatrick }; 150061da546Spatrick 151061da546Spatrick class JSONFalse : public JSONValue { 152061da546Spatrick public: 153061da546Spatrick JSONFalse(); 154061da546Spatrick 155061da546Spatrick JSONFalse(const JSONFalse &s) = delete; 156061da546Spatrick JSONFalse &operator=(const JSONFalse &s) = delete; 157061da546Spatrick 158061da546Spatrick void Write(std::ostream &s) override; 159061da546Spatrick 160061da546Spatrick typedef std::shared_ptr<JSONFalse> SP; 161061da546Spatrick classof(const JSONValue * V)162061da546Spatrick static bool classof(const JSONValue *V) { 163061da546Spatrick return V->GetKind() == JSONValue::Kind::False; 164061da546Spatrick } 165061da546Spatrick 166061da546Spatrick ~JSONFalse() override = default; 167061da546Spatrick }; 168061da546Spatrick 169061da546Spatrick class JSONNull : public JSONValue { 170061da546Spatrick public: 171061da546Spatrick JSONNull(); 172061da546Spatrick 173061da546Spatrick JSONNull(const JSONNull &s) = delete; 174061da546Spatrick JSONNull &operator=(const JSONNull &s) = delete; 175061da546Spatrick 176061da546Spatrick void Write(std::ostream &s) override; 177061da546Spatrick 178061da546Spatrick typedef std::shared_ptr<JSONNull> SP; 179061da546Spatrick classof(const JSONValue * V)180061da546Spatrick static bool classof(const JSONValue *V) { 181061da546Spatrick return V->GetKind() == JSONValue::Kind::Null; 182061da546Spatrick } 183061da546Spatrick 184061da546Spatrick ~JSONNull() override = default; 185061da546Spatrick }; 186061da546Spatrick 187061da546Spatrick class JSONObject : public JSONValue { 188061da546Spatrick public: 189061da546Spatrick JSONObject(); 190061da546Spatrick 191061da546Spatrick JSONObject(const JSONObject &s) = delete; 192061da546Spatrick JSONObject &operator=(const JSONObject &s) = delete; 193061da546Spatrick 194061da546Spatrick void Write(std::ostream &s) override; 195061da546Spatrick 196061da546Spatrick typedef std::shared_ptr<JSONObject> SP; 197061da546Spatrick classof(const JSONValue * V)198061da546Spatrick static bool classof(const JSONValue *V) { 199061da546Spatrick return V->GetKind() == JSONValue::Kind::Object; 200061da546Spatrick } 201061da546Spatrick 202061da546Spatrick bool SetObject(const std::string &key, JSONValue::SP value); 203061da546Spatrick 204061da546Spatrick JSONValue::SP GetObject(const std::string &key) const; 205061da546Spatrick 206061da546Spatrick /// Return keyed value as bool 207061da546Spatrick /// 208061da546Spatrick /// \param[in] key 209061da546Spatrick /// The value of the key to lookup 210061da546Spatrick /// 211061da546Spatrick /// \param[out] value 212061da546Spatrick /// The value of the key as a bool. Undefined if the key doesn't 213061da546Spatrick /// exist or if the key is not either true or false. 214061da546Spatrick /// 215061da546Spatrick /// \return 216061da546Spatrick /// true if the key existed as was a bool value; false otherwise. 217061da546Spatrick /// Note the return value is *not* the value of the bool, use 218061da546Spatrick /// \b value for that. 219061da546Spatrick bool GetObjectAsBool(const std::string &key, bool &value) const; 220061da546Spatrick 221061da546Spatrick bool GetObjectAsString(const std::string &key, std::string &value) const; 222061da546Spatrick 223061da546Spatrick ~JSONObject() override = default; 224061da546Spatrick 225061da546Spatrick private: 226061da546Spatrick typedef std::map<std::string, JSONValue::SP> Map; 227061da546Spatrick typedef Map::iterator Iterator; 228061da546Spatrick Map m_elements; 229061da546Spatrick }; 230061da546Spatrick 231061da546Spatrick class JSONArray : public JSONValue { 232061da546Spatrick public: 233061da546Spatrick JSONArray(); 234061da546Spatrick 235061da546Spatrick JSONArray(const JSONArray &s) = delete; 236061da546Spatrick JSONArray &operator=(const JSONArray &s) = delete; 237061da546Spatrick 238061da546Spatrick void Write(std::ostream &s) override; 239061da546Spatrick 240061da546Spatrick typedef std::shared_ptr<JSONArray> SP; 241061da546Spatrick classof(const JSONValue * V)242061da546Spatrick static bool classof(const JSONValue *V) { 243061da546Spatrick return V->GetKind() == JSONValue::Kind::Array; 244061da546Spatrick } 245061da546Spatrick 246061da546Spatrick private: 247061da546Spatrick typedef std::vector<JSONValue::SP> Vector; 248061da546Spatrick typedef Vector::iterator Iterator; 249061da546Spatrick typedef Vector::size_type Index; 250061da546Spatrick typedef Vector::size_type Size; 251061da546Spatrick 252061da546Spatrick public: 253061da546Spatrick bool SetObject(Index i, JSONValue::SP value); 254061da546Spatrick 255061da546Spatrick bool AppendObject(JSONValue::SP value); 256061da546Spatrick 257061da546Spatrick JSONValue::SP GetObject(Index i); 258061da546Spatrick 259061da546Spatrick Size GetNumElements(); 260061da546Spatrick 261061da546Spatrick ~JSONArray() override = default; 262061da546Spatrick 263061da546Spatrick Vector m_elements; 264061da546Spatrick }; 265061da546Spatrick 266061da546Spatrick class JSONParser : public StdStringExtractor { 267061da546Spatrick public: 268061da546Spatrick enum Token { 269061da546Spatrick Invalid, 270061da546Spatrick Status, 271061da546Spatrick ObjectStart, 272061da546Spatrick ObjectEnd, 273061da546Spatrick ArrayStart, 274061da546Spatrick ArrayEnd, 275061da546Spatrick Comma, 276061da546Spatrick Colon, 277061da546Spatrick String, 278061da546Spatrick Integer, 279061da546Spatrick Float, 280061da546Spatrick True, 281061da546Spatrick False, 282061da546Spatrick Null, 283061da546Spatrick EndOfFile 284061da546Spatrick }; 285061da546Spatrick 286061da546Spatrick JSONParser(const char *cstr); 287061da546Spatrick 288061da546Spatrick int GetEscapedChar(bool &was_escaped); 289061da546Spatrick 290061da546Spatrick Token GetToken(std::string &value); 291061da546Spatrick 292061da546Spatrick JSONValue::SP ParseJSONValue(); 293061da546Spatrick 294061da546Spatrick protected: 295061da546Spatrick JSONValue::SP ParseJSONValue(const std::string &value, const Token &token); 296061da546Spatrick 297061da546Spatrick JSONValue::SP ParseJSONObject(); 298061da546Spatrick 299061da546Spatrick JSONValue::SP ParseJSONArray(); 300061da546Spatrick }; 301061da546Spatrick 302dda28197Spatrick #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 303