//===---------------------JSON.h --------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef utility_JSON_h_ #define utility_JSON_h_ #include "lldb/Core/Stream.h" #include "lldb/Utility/StringExtractor.h" #include #include #include #include #include #include #include "llvm/Support/Casting.h" namespace lldb_private { class JSONValue { public: virtual void Write (Stream& s) = 0; typedef std::shared_ptr SP; enum class Kind { String, Number, True, False, Null, Object, Array }; JSONValue (Kind k) : m_kind(k) {} Kind GetKind() const { return m_kind; } virtual ~JSONValue () = default; private: const Kind m_kind; }; class JSONString : public JSONValue { public: JSONString (); JSONString (const char* s); JSONString (const std::string& s); JSONString (const JSONString& s) = delete; JSONString& operator = (const JSONString& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; std::string GetData () { return m_data; } static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::String; } ~JSONString() override = default; private: static std::string json_string_quote_metachars (const std::string&); std::string m_data; }; class JSONNumber : public JSONValue { public: typedef std::shared_ptr SP; // We cretae a constructor for all integer and floating point type with using templates and // SFINAE to avoid having ambiguous overloads because of the implicit type promotion. If we // would have constructors only with int64_t, uint64_t and double types then constructing a // JSONNumber from an int32_t (or any other similar type) would fail to compile. template ::value && std::is_unsigned::value>::type* = nullptr> explicit JSONNumber (T u) : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { m_data.m_unsigned = u; } template ::value && std::is_signed::value>::type* = nullptr> explicit JSONNumber (T s) : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { m_data.m_signed = s; } template ::value>::type* = nullptr> explicit JSONNumber (T d) : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { m_data.m_double = d; } ~JSONNumber() override = default; JSONNumber (const JSONNumber& s) = delete; JSONNumber& operator = (const JSONNumber& s) = delete; void Write(Stream& s) override; uint64_t GetAsUnsigned() const; int64_t GetAsSigned() const; double GetAsDouble() const; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::Number; } private: enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; union { uint64_t m_unsigned; int64_t m_signed; double m_double; } m_data; }; class JSONTrue : public JSONValue { public: JSONTrue (); JSONTrue (const JSONTrue& s) = delete; JSONTrue& operator = (const JSONTrue& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::True; } ~JSONTrue() override = default; }; class JSONFalse : public JSONValue { public: JSONFalse (); JSONFalse (const JSONFalse& s) = delete; JSONFalse& operator = (const JSONFalse& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::False; } ~JSONFalse() override = default; }; class JSONNull : public JSONValue { public: JSONNull (); JSONNull (const JSONNull& s) = delete; JSONNull& operator = (const JSONNull& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::Null; } ~JSONNull() override = default; }; class JSONObject : public JSONValue { public: JSONObject (); JSONObject (const JSONObject& s) = delete; JSONObject& operator = (const JSONObject& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::Object; } bool SetObject (const std::string& key, JSONValue::SP value); JSONValue::SP GetObject (const std::string& key); ~JSONObject() override = default; private: typedef std::map Map; typedef Map::iterator Iterator; Map m_elements; }; class JSONArray : public JSONValue { public: JSONArray (); JSONArray (const JSONArray& s) = delete; JSONArray& operator = (const JSONArray& s) = delete; void Write(Stream& s) override; typedef std::shared_ptr SP; static bool classof(const JSONValue *V) { return V->GetKind() == JSONValue::Kind::Array; } private: typedef std::vector Vector; typedef Vector::iterator Iterator; typedef Vector::size_type Index; typedef Vector::size_type Size; public: bool SetObject (Index i, JSONValue::SP value); bool AppendObject (JSONValue::SP value); JSONValue::SP GetObject (Index i); Size GetNumElements (); ~JSONArray() override = default; Vector m_elements; }; class JSONParser : public StringExtractor { public: enum Token { Invalid, Error, ObjectStart, ObjectEnd, ArrayStart, ArrayEnd, Comma, Colon, String, Integer, Float, True, False, Null, EndOfFile }; JSONParser (const char *cstr); int GetEscapedChar (bool &was_escaped); Token GetToken (std::string &value); JSONValue::SP ParseJSONValue (); protected: JSONValue::SP ParseJSONObject (); JSONValue::SP ParseJSONArray (); }; } // namespace lldb_private #endif // utility_JSON_h_