I have some improvements to make to StringExtractor that require using LLVM. debugserver can't take a dependency on LLVM but uses this file, so I'm forking it off into StdStringExtractor and StringExtractor, so that StringExtractor can take advantage of some performance improvements and readability improvements that LLVM can provide. llvm-svn: 279997
383 lines
8.0 KiB
C++
383 lines
8.0 KiB
C++
//===---------------------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_
|
|
|
|
// This cross-project usage is fine as StdStringExtractor.h is entirely
|
|
// self-contained.
|
|
#include "lldb/Utility/StdStringExtractor.h"
|
|
|
|
// C includes
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
|
|
// C++ includes
|
|
#include <map>
|
|
#include <memory>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
class JSONValue
|
|
{
|
|
public:
|
|
virtual void
|
|
Write (std::ostream& s) = 0;
|
|
|
|
typedef std::shared_ptr<JSONValue> 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONString> 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<JSONNumber> 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 <typename T,
|
|
typename std::enable_if<std::is_integral<T>::value &&
|
|
std::is_unsigned<T>::value>::type* = nullptr>
|
|
explicit JSONNumber (T u) :
|
|
JSONValue(JSONValue::Kind::Number),
|
|
m_data_type(DataType::Unsigned)
|
|
{
|
|
m_data.m_unsigned = u;
|
|
}
|
|
|
|
template <typename T,
|
|
typename std::enable_if<std::is_integral<T>::value &&
|
|
std::is_signed<T>::value>::type* = nullptr>
|
|
explicit JSONNumber (T s) :
|
|
JSONValue(JSONValue::Kind::Number),
|
|
m_data_type(DataType::Signed)
|
|
{
|
|
m_data.m_signed = s;
|
|
}
|
|
|
|
template <typename T,
|
|
typename std::enable_if<std::is_floating_point<T>::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(std::ostream& 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONTrue> 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONFalse> 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONNull> 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONObject> 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) const;
|
|
|
|
// -------------------------------------------------------------------------
|
|
/// Return keyed value as bool
|
|
///
|
|
/// @param[in] key
|
|
/// The value of the key to lookup
|
|
///
|
|
/// @param[out] value
|
|
/// The value of the key as a bool. Undefined if the key doesn't
|
|
/// exist or if the key is not either true or false.
|
|
///
|
|
/// @return
|
|
/// true if the key existed as was a bool value; false otherwise.
|
|
/// Note the return value is *not* the value of the bool, use
|
|
/// \b value for that.
|
|
// -------------------------------------------------------------------------
|
|
bool
|
|
GetObjectAsBool (const std::string& key, bool& value) const;
|
|
|
|
bool
|
|
GetObjectAsString (const std::string& key, std::string& value) const;
|
|
|
|
~JSONObject() override = default;
|
|
|
|
private:
|
|
typedef std::map<std::string, JSONValue::SP> 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(std::ostream& s) override;
|
|
|
|
typedef std::shared_ptr<JSONArray> SP;
|
|
|
|
static bool classof(const JSONValue *V)
|
|
{
|
|
return V->GetKind() == JSONValue::Kind::Array;
|
|
}
|
|
|
|
private:
|
|
typedef std::vector<JSONValue::SP> 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 StdStringExtractor
|
|
{
|
|
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 ();
|
|
};
|
|
|
|
#endif // utility_JSON_h_
|