Files
clang-p2996/lldb/tools/debugserver/source/JSON.h
Zachary Turner 44c35e80b1 Copy StringExtractor to StdStringExtractor.
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
2016-08-29 19:45:59 +00:00

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_