Take 2, with missing cmake line fixed. Build tested on Ubuntu 14.04 with clang-3.6. See docs/structured_data/StructuredDataPlugins.md for details. differential review: https://reviews.llvm.org/D22976 reviewers: clayborg, jingham llvm-svn: 279202
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 StringExtractor.h is entirely
|
|
// self-contained.
|
|
#include "lldb/Utility/StringExtractor.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 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 ();
|
|
};
|
|
|
|
#endif // utility_JSON_h_
|