* Add valijson sources

* Add valijson to cgmanifest
This commit is contained in:
Eddy Ashton 2019-06-04 13:49:22 +01:00 коммит произвёл GitHub
Родитель 1eda2341cc
Коммит 817f586cc6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
39 изменённых файлов: 14247 добавлений и 0 удалений

476
3rdparty/valijson/adapters/adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,476 @@
#pragma once
#ifndef __VALIJSON_ADAPTERS_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_ADAPTER_HPP
#include <functional>
namespace valijson {
namespace adapters {
class FrozenValue;
/**
* @brief An interface that encapsulates access to the JSON values provided
* by a JSON parser implementation.
*
* This interface allows JSON processing code to be parser-agnostic. It provides
* functions to access the plain old datatypes (PODs) that are described in the
* JSON specification, and callback-based access to the contents of arrays and
* objects.
*
* The interface also defines a set of functions that allow for type-casting and
* type-comparison based on value rather than on type.
*/
class Adapter
{
public:
/// Typedef for callback function supplied to applyToArray.
typedef std::function<bool (const Adapter &)>
ArrayValueCallback;
/// Typedef for callback function supplied to applyToObject.
typedef std::function<bool (const std::string &, const Adapter &)>
ObjectMemberCallback;
/**
* @brief Virtual destructor defined to ensure deletion via base-class
* pointers is safe.
*/
virtual ~Adapter() { };
/**
* @brief Apply a callback function to each value in an array.
*
* The callback function is invoked for each element in the array, until
* it has been applied to all values, or it returns false.
*
* @param fn Callback function to invoke
*
* @returns true if Adapter contains an array and all values are equal,
* false otherwise.
*/
virtual bool applyToArray(ArrayValueCallback fn) const = 0;
/**
* @brief Apply a callback function to each member in an object.
*
* The callback function shall be invoked for each member in the object,
* until it has been applied to all values, or it returns false.
*
* @param fn Callback function to invoke
*
* @returns true if Adapter contains an object, and callback function
* returns true for each member in the object, false otherwise.
*/
virtual bool applyToObject(ObjectMemberCallback fn) const = 0;
/**
* @brief Return the boolean representation of the contained value.
*
* This function shall return a boolean value if the Adapter contains either
* an actual boolean value, or one of the strings 'true' or 'false'.
* The string comparison is case sensitive.
*
* An exception shall be thrown if the value cannot be cast to a boolean.
*
* @returns Boolean representation of contained value.
*/
virtual bool asBool() const = 0;
/**
* @brief Retrieve the boolean representation of the contained value.
*
* This function shall retrieve a boolean value if the Adapter contains
* either an actual boolean value, or one of the strings 'true' or 'false'.
* The string comparison is case sensitive.
*
* The retrieved value is returned via reference.
*
* @param result reference to a bool to set with retrieved value.
*
* @returns true if the value could be retrieved, false otherwise
*/
virtual bool asBool(bool &result) const = 0;
/**
* @brief Return the double representation of the contained value.
*
* This function shall return a double value if the Adapter contains either
* an actual double, an integer, or a string that contains a valid
* representation of a numeric value (according to the C++ Std Library).
*
* An exception shall be thrown if the value cannot be cast to a double.
*
* @returns Double representation of contained value.
*/
virtual double asDouble() const = 0;
/**
* @brief Retrieve the double representation of the contained value.
*
* This function shall retrieve a double value if the Adapter contains either
* an actual double, an integer, or a string that contains a valid
* representation of a numeric value (according to the C++ Std Library).
*
* The retrieved value is returned via reference.
*
* @param result reference to a double to set with retrieved value.
*
* @returns true if the value could be retrieved, false otherwise
*/
virtual bool asDouble(double &result) const = 0;
/**
* @brief Return the int64_t representation of the contained value.
*
* This function shall return an int64_t value if the Adapter contains either
* an actual integer, or a string that contains a valid representation of an
* integer value (according to the C++ Std Library).
*
* An exception shall be thrown if the value cannot be cast to an int64_t.
*
* @returns int64_t representation of contained value.
*/
virtual int64_t asInteger() const = 0;
/**
* @brief Retrieve the int64_t representation of the contained value.
*
* This function shall retrieve an int64_t value if the Adapter contains
* either an actual integer, or a string that contains a valid
* representation of an integer value (according to the C++ Std Library).
*
* The retrieved value is returned via reference.
*
* @param result reference to a int64_t to set with retrieved value.
*
* @returns true if the value could be retrieved, false otherwise
*/
virtual bool asInteger(int64_t &result) const = 0;
/**
* @brief Return the string representation of the contained value.
*
* This function shall return a string value if the Adapter contains either
* an actual string, a literal value of another POD type, an empty array,
* an empty object, or null.
*
* An exception shall be thrown if the value cannot be cast to a string.
*
* @returns string representation of contained value.
*/
virtual std::string asString() const = 0;
/**
* @brief Retrieve the string representation of the contained value.
*
* This function shall retrieve a string value if the Adapter contains either
* an actual string, a literal value of another POD type, an empty array,
* an empty object, or null.
*
* The retrieved value is returned via reference.
*
* @param result reference to a string to set with retrieved value.
*
* @returns true if the value could be retrieved, false otherwise
*/
virtual bool asString(std::string &result) const = 0;
/**
* @brief Compare the value held by this Adapter instance with the value
* held by another Adapter instance.
*
* @param other the other adapter instance
* @param strict flag to use strict type comparison
*
* @returns true if values are equal, false otherwise
*/
virtual bool equalTo(const Adapter &other, bool strict) const = 0;
/**
* @brief Create a new FrozenValue instance that is equivalent to the
* value contained by the Adapter.
*
* @returns pointer to a new FrozenValue instance, belonging to the caller.
*/
virtual FrozenValue* freeze() const = 0;
/**
* @brief Return the number of elements in the array.
*
* Throws an exception if the value is not an array.
*
* @return number of elements if value is an array
*/
virtual size_t getArraySize() const = 0;
/**
* @brief Retrieve the number of elements in the array.
*
* This function shall return true or false to indicate whether or not the
* result value was set. If the contained value is not an array, the
* result value shall not be set. This applies even if the value could be
* cast to an empty array. The calling code is expected to handles those
* cases manually.
*
* @param result reference to size_t variable to set with result.
*
* @return true if value retrieved successfully, false otherwise.
*/
virtual bool getArraySize(size_t &result) const = 0;
/**
* @brief Return the contained boolean value.
*
* This function shall throw an exception if the contained value is not a
* boolean.
*
* @returns contained boolean value.
*/
virtual bool getBool() const = 0;
/**
* @brief Retrieve the contained boolean value.
*
* This function shall retrieve the boolean value contained by this Adapter,
* and store it in the result variable that was passed by reference.
*
* @param result reference to boolean variable to set with result.
*
* @returns true if the value was retrieved, false otherwise.
*/
virtual bool getBool(bool &result) const = 0;
/**
* @brief Return the contained double value.
*
* This function shall throw an exception if the contained value is not a
* double.
*
* @returns contained double value.
*/
virtual double getDouble() const = 0;
/**
* @brief Retrieve the contained double value.
*
* This function shall retrieve the double value contained by this Adapter,
* and store it in the result variable that was passed by reference.
*
* @param result reference to double variable to set with result.
*
* @returns true if the value was retrieved, false otherwise.
*/
virtual bool getDouble(double &result) const = 0;
/**
* @brief Return the contained integer value.
*
* This function shall throw an exception if the contained value is not a
* integer.
*
* @returns contained integer value.
*/
virtual int64_t getInteger() const = 0;
/**
* @brief Retrieve the contained integer value.
*
* This function shall retrieve the integer value contained by this Adapter,
* and store it in the result variable that was passed by reference.
*
* @param result reference to integer variable to set with result.
*
* @returns true if the value was retrieved, false otherwise.
*/
virtual bool getInteger(int64_t &result) const = 0;
/**
* @brief Return the contained numeric value as a double.
*
* This function shall throw an exception if the contained value is not a
* integer or a double.
*
* @returns contained double or integral value.
*/
virtual double getNumber() const = 0;
/**
* @brief Retrieve the contained numeric value as a double.
*
* This function shall retrieve the double or integral value contained by
* this Adapter, and store it in the result variable that was passed by
* reference.
*
* @param result reference to double variable to set with result.
*
* @returns true if the value was retrieved, false otherwise.
*/
virtual bool getNumber(double &result) const = 0;
/**
* @brief Return the number of members in the object.
*
* Throws an exception if the value is not an object.
*
* @return number of members if value is an object
*/
virtual size_t getObjectSize() const = 0;
/**
* @brief Retrieve the number of members in the object.
*
* This function shall return true or false to indicate whether or not the
* result value was set. If the contained value is not an object, the
* result value shall not be set. This applies even if the value could be
* cast to an empty object. The calling code is expected to handles those
* cases manually.
*
* @param result reference to size_t variable to set with result.
*
* @return true if value retrieved successfully, false otherwise.
*/
virtual bool getObjectSize(size_t &result) const = 0;
/**
* @brief Return the contained string value.
*
* This function shall throw an exception if the contained value is not a
* string - even if the value could be cast to a string. The asString()
* function should be used when casting is allowed.
*
* @returns string contained by this Adapter
*/
virtual std::string getString() const = 0;
/**
* @brief Retrieve the contained string value.
*
* This function shall retrieve the string value contained by this Adapter,
* and store it in result variable that is passed by reference.
*
* @param result reference to string to set with result
*
* @returns true if string was retrieved, false otherwise
*/
virtual bool getString(std::string &result) const = 0;
/**
* @brief Returns whether or not this Adapter supports strict types.
*
* This function shall return true if the Adapter implementation supports
* strict types, or false if the Adapter fails to store any part of the
* type information supported by the Adapter interface.
*
* For example, the PropertyTreeAdapter implementation stores POD values as
* strings, effectively discarding any other type information. If you were
* to call isDouble() on a double stored by this Adapter, the result would
* be false. The maybeDouble(), asDouble() and various related functions
* are provided to perform type checking based on value rather than on type.
*
* The BasicAdapter template class provides implementations for the type-
* casting functions so that Adapter implementations are semantically
* equivalent in their type-casting behaviour.
*
* @returns true if Adapter supports strict types, false otherwise
*/
virtual bool hasStrictTypes() const = 0;
/// Returns true if the contained value is definitely an array.
virtual bool isArray() const = 0;
/// Returns true if the contained value is definitely a boolean.
virtual bool isBool() const = 0;
/// Returns true if the contained value is definitely a double.
virtual bool isDouble() const = 0;
/// Returns true if the contained value is definitely an integer.
virtual bool isInteger() const = 0;
/// Returns true if the contained value is definitely a null.
virtual bool isNull() const = 0;
/// Returns true if the contained value is either a double or an integer.
virtual bool isNumber() const = 0;
/// Returns true if the contained value is definitely an object.
virtual bool isObject() const = 0;
/// Returns true if the contained value is definitely a string.
virtual bool isString() const = 0;
/**
* @brief Returns true if the contained value can be cast to an array.
*
* @returns true if the contained value is an array, an empty string, or an
* empty object.
*/
virtual bool maybeArray() const = 0;
/**
* @brief Returns true if the contained value can be cast to a boolean.
*
* @returns true if the contained value is a boolean, or one of the strings
* 'true' or 'false'. Note that numeric values are not to be cast
* to boolean values.
*/
virtual bool maybeBool() const = 0;
/**
* @brief Returns true if the contained value can be cast to a double.
*
* @returns true if the contained value is a double, an integer, or a string
* containing a double or integral value.
*/
virtual bool maybeDouble() const = 0;
/**
* @brief Returns true if the contained value can be cast to an integer.
*
* @returns true if the contained value is an integer, or a string
* containing an integral value.
*/
virtual bool maybeInteger() const = 0;
/**
* @brief Returns true if the contained value can be cast to a null.
*
* @returns true if the contained value is null or an empty string.
*/
virtual bool maybeNull() const = 0;
/**
* @brief Returns true if the contained value can be cast to an object.
*
* @returns true if the contained value is an object, an empty array or
* an empty string.
*/
virtual bool maybeObject() const = 0;
/**
* @brief Returns true if the contained value can be cast to a string.
*
* @returns true if the contained value is a non-null POD type, an empty
* array, or an empty object.
*/
virtual bool maybeString() const = 0;
};
/**
* @brief Template struct that should be specialised for each concrete Adapter
* class.
*
* @deprecated This is a bit of a hack, and I'd like to remove it.
*/
template<typename T>
struct AdapterTraits
{
};
} // namespace adapters
} // namespace valijson
#endif

868
3rdparty/valijson/adapters/basic_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,868 @@
#pragma once
#ifndef __VALIJSON_ADAPTERS_BASIC_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_BASIC_ADAPTER_HPP
#include <stdint.h>
#include <sstream>
#include <valijson/adapters/adapter.hpp>
#include <valijson/internal/optional.hpp>
namespace valijson {
namespace adapters {
/**
* @brief A helper for the array and object member iterators.
*
* See http://www.stlsoft.org/doc-1.9/group__group____pattern____dereference__proxy.html
* for motivation
*
* @tparam Value Name of the value type
*/
template<class Value>
struct DerefProxy
{
explicit DerefProxy(const Value& x)
: m_ref(x) { }
Value* operator->()
{
return std::addressof(m_ref);
}
operator Value*()
{
return std::addressof(m_ref);
}
private:
Value m_ref;
};
/**
* @brief Template class that implements the expected semantics of an Adapter.
*
* Implementing all of the type-casting functionality for each Adapter is error
* prone and tedious, so this template class aims to minimise the duplication
* of code between various Adapter implementations. This template doesn't quite
* succeed in removing all duplication, but it has greatly simplified the
* implementation of a new Adapter by encapsulating the type-casting semantics
* and a lot of the trivial functionality associated with the Adapter interface.
*
* By inheriting from this template class, Adapter implementations will inherit
* the exception throwing behaviour that is expected by other parts of the
* Valijson library.
*
* @tparam AdapterType Self-referential name of the Adapter being
* specialised.
* @tparam ArrayType Name of the type that will be returned by the
* getArray() function. Instances of this type should
* provide begin(), end() and size() functions so
* that it is possible to iterate over the values in
* the array.
* @tparam ObjectMemberType Name of the type exposed when iterating over the
* contents of an object returned by getObject().
* @tparam ObjectType Name of the type that will be returned by the
* getObject() function. Instances of this type
* should provide begin(), end(), find() and size()
* functions so that it is possible to iterate over
* the members of the object.
* @tparam ValueType Name of the type that provides a consistent
* interface to a JSON value for a parser. For
* example, this type should provide the getDouble()
* and isDouble() functions. But it does not need to
* know how to cast values from one type to another -
* that functionality is provided by this template
* class.
*/
template<
typename AdapterType,
typename ArrayType,
typename ObjectMemberType,
typename ObjectType,
typename ValueType>
class BasicAdapter: public Adapter
{
protected:
/**
* @brief Functor for comparing two arrays.
*
* This functor is used to compare the elements in an array of the type
* ArrayType with individual values provided as generic Adapter objects.
* Comparison is performed by the () operator.
*
* The functor works by maintaining an iterator for the current position
* in an array. Each time the () operator is called, the value at this
* position is compared with the value passed as an argument to ().
* Immediately after the comparison, the iterator will be incremented.
*
* This functor is designed to be passed to the applyToArray() function
* of an Adapter object.
*/
class ArrayComparisonFunctor
{
public:
/**
* @brief Construct an ArrayComparisonFunctor for an array.
*
* @param array Array to compare values against
* @param strict Flag to use strict type comparison
*/
ArrayComparisonFunctor(const ArrayType &array, bool strict)
: itr(array.begin()),
end(array.end()),
strict(strict) { }
/**
* @brief Compare a value against the current element in the array.
*
* @param adapter Value to be compared with current element
*
* @returns true if values are equal, false otherwise.
*/
bool operator()(const Adapter &adapter)
{
if (itr == end) {
return false;
}
return AdapterType(*itr++).equalTo(adapter, strict);
}
private:
/// Iterator for current element in the array
typename ArrayType::const_iterator itr;
/// Iterator for one-past the last element of the array
typename ArrayType::const_iterator end;
/// Flag to use strict type comparison
const bool strict;
};
/**
* @brief Functor for comparing two objects
*
* This functor is used to compare the members of an object of the type
* ObjectType with key-value pairs belonging to another object.
*
* The functor works by maintaining a reference to an object provided via
* the constructor. When time the () operator is called with a key-value
* pair as arguments, the function will attempt to find the key in the
* base object. If found, the associated value will be compared with the
* value provided to the () operator.
*
* This functor is designed to be passed to the applyToObject() function
* of an Adapter object.
*/
class ObjectComparisonFunctor
{
public:
/**
* @brief Construct a new ObjectComparisonFunctor for an object.
*
* @param object object to use as comparison baseline
* @param strict flag to use strict type-checking
*/
ObjectComparisonFunctor(
const ObjectType &object, bool strict)
: object(object),
strict(strict) { }
/**
* @brief Find a key in the object and compare its value.
*
* @param key Key to find
* @param value Value to be compared against
*
* @returns true if key is found and values are equal, false otherwise.
*/
bool operator()(const std::string &key, const Adapter &value)
{
const typename ObjectType::const_iterator itr = object.find(key);
if (itr == object.end()) {
return false;
}
return (*itr).second.equalTo(value, strict);
}
private:
/// Object to be used as a comparison baseline
const ObjectType &object;
/// Flag to use strict type-checking
bool strict;
};
public:
/// Alias for ArrayType template parameter
typedef ArrayType Array;
/// Alias for ObjectMemberType template parameter
typedef ObjectMemberType ObjectMember;
/// Alias for ObjectType template parameter
typedef ObjectType Object;
/**
* @brief Construct an Adapter using the default value.
*
* This constructor relies on the default constructor of the ValueType
* class provided as a template argument.
*/
BasicAdapter() { }
/**
* @brief Construct an Adapter using a specified ValueType object.
*
* This constructor relies on the copy constructor of the ValueType
* class provided as template argument.
*/
BasicAdapter(const ValueType &value)
: value(value) { }
virtual bool applyToArray(ArrayValueCallback fn) const
{
if (!maybeArray()) {
return false;
}
// Due to the fact that the only way a value can be 'maybe an array' is
// if it is an empty string or empty object, we only need to go to
// effort of constructing an ArrayType instance if the value is
// definitely an array.
if (value.isArray()) {
const opt::optional<Array> array = value.getArrayOptional();
for (const AdapterType element : *array) {
if (!fn(element)) {
return false;
}
}
}
return true;
}
virtual bool applyToObject(ObjectMemberCallback fn) const
{
if (!maybeObject()) {
return false;
}
if (value.isObject()) {
const opt::optional<Object> object = value.getObjectOptional();
for (const ObjectMemberType member : *object) {
if (!fn(member.first, AdapterType(member.second))) {
return false;
}
}
}
return true;
}
/**
* @brief Return an ArrayType instance containing an array representation
* of the value held by this Adapter.
*
* This is a convenience function that is not actually declared in the
* Adapter interface, but allows for useful techniques such as procedural
* iteration over the elements in an array. The ArrayType instance that is
* returned by this function is compatible with the BOOST_FOREACH macro.
*
* If the contained value is either an empty object, or an empty string,
* then this function will cast the value to an empty array.
*
* @returns ArrayType instance containing an array representation of the
* value held by this Adapter.
*/
ArrayType asArray() const
{
if (value.isArray()) {
return *value.getArrayOptional();
} else if (value.isObject()) {
size_t objectSize;
if (value.getObjectSize(objectSize) && objectSize == 0) {
return ArrayType();
}
} else if (value.isString()) {
std::string stringValue;
if (value.getString(stringValue) && stringValue.empty()) {
return ArrayType();
}
}
throw std::runtime_error("JSON value cannot be cast to an array.");
}
virtual bool asBool() const
{
bool result;
if (asBool(result)) {
return result;
}
throw std::runtime_error("JSON value cannot be cast to a boolean.");
}
virtual bool asBool(bool &result) const
{
if (value.isBool()) {
return value.getBool(result);
} else if (value.isString()) {
std::string s;
if (value.getString(s)) {
if (s.compare("true") == 0) {
result = true;
return true;
} else if (s.compare("false") == 0) {
result = false;
return true;
}
}
}
return false;
}
virtual double asDouble() const
{
double result;
if (asDouble(result)) {
return result;
}
throw std::runtime_error("JSON value cannot be cast to a double.");
}
virtual bool asDouble(double &result) const
{
if (value.isDouble()) {
return value.getDouble(result);
} else if (value.isInteger()) {
int64_t i;
if (value.getInteger(i)) {
result = double(i);
return true;
}
} else if (value.isString()) {
std::string s;
if (value.getString(s)) {
const char *b = s.c_str();
char *e = NULL;
double x = strtod(b, &e);
if (e == b || e != b + s.length()) {
return false;
}
result = x;
return true;
}
}
return false;
}
virtual int64_t asInteger() const
{
int64_t result;
if (asInteger(result)) {
return result;
}
throw std::runtime_error("JSON value cannot be cast as an integer.");
}
virtual bool asInteger(int64_t &result) const
{
if (value.isInteger()) {
return value.getInteger(result);
} else if (value.isString()) {
std::string s;
if (value.getString(s)) {
std::istringstream i(s);
int64_t x;
char c;
if (!(!(i >> x) || i.get(c))) {
result = x;
return true;
}
}
}
return false;
}
/**
* @brief Return an ObjectType instance containing an array representation
* of the value held by this Adapter.
*
* This is a convenience function that is not actually declared in the
* Adapter interface, but allows for useful techniques such as procedural
* iteration over the members of the object. The ObjectType instance that is
* returned by this function is compatible with the BOOST_FOREACH macro.
*
* @returns ObjectType instance containing an object representation of the
* value held by this Adapter.
*/
ObjectType asObject() const
{
if (value.isObject()) {
return *value.getObjectOptional();
} else if (value.isArray()) {
size_t arraySize;
if (value.getArraySize(arraySize) && arraySize == 0) {
return ObjectType();
}
} else if (value.isString()) {
std::string stringValue;
if (value.getString(stringValue) && stringValue.empty()) {
return ObjectType();
}
}
throw std::runtime_error("JSON value cannot be cast to an object.");
}
virtual std::string asString() const
{
std::string result;
if (asString(result)) {
return result;
}
throw std::runtime_error("JSON value cannot be cast to a string.");
}
virtual bool asString(std::string &result) const
{
if (value.isString()) {
return value.getString(result);
} else if (value.isNull()) {
result.clear();
return true;
} else if (value.isArray()) {
size_t arraySize;
if (value.getArraySize(arraySize) && arraySize == 0) {
result.clear();
return true;
}
} else if (value.isObject()) {
size_t objectSize;
if (value.getObjectSize(objectSize) && objectSize == 0) {
result.clear();
return true;
}
} else if (value.isBool()) {
bool boolValue;
if (value.getBool(boolValue)) {
result = boolValue ? "true" : "false";
return true;
}
} else if (value.isInteger()) {
int64_t integerValue;
if (value.getInteger(integerValue)) {
result = std::to_string(integerValue);
return true;
}
} else if (value.isDouble()) {
double doubleValue;
if (value.getDouble(doubleValue)) {
result = std::to_string(doubleValue);
return true;
}
}
return false;
}
virtual bool equalTo(const Adapter &other, bool strict) const
{
if (isNull() || (!strict && maybeNull())) {
return other.isNull() || (!strict && other.maybeNull());
} else if (isBool() || (!strict && maybeBool())) {
return (other.isBool() || (!strict && other.maybeBool())) &&
other.asBool() == asBool();
} else if (isNumber() && strict) {
return other.isNumber() && other.getNumber() == getNumber();
} else if (!strict && maybeDouble()) {
return (other.maybeDouble() &&
other.asDouble() == asDouble());
} else if (!strict && maybeInteger()) {
return (other.maybeInteger() &&
other.asInteger() == asInteger());
} else if (isString() || (!strict && maybeString())) {
return (other.isString() || (!strict && other.maybeString())) &&
other.asString() == asString();
} else if (isArray()) {
if (other.isArray() && getArraySize() == other.getArraySize()) {
const opt::optional<ArrayType> array = value.getArrayOptional();
if (array) {
ArrayComparisonFunctor fn(*array, strict);
return other.applyToArray(fn);
}
} else if (!strict && other.maybeArray() && getArraySize() == 0) {
return true;
}
} else if (isObject()) {
if (other.isObject() && other.getObjectSize() == getObjectSize()) {
const opt::optional<ObjectType> object = value.getObjectOptional();
if (object) {
ObjectComparisonFunctor fn(*object, strict);
return other.applyToObject(fn);
}
} else if (!strict && other.maybeObject() && getObjectSize() == 0) {
return true;
}
}
return false;
}
/**
* @brief Return an ArrayType instance representing the array contained
* by this Adapter instance.
*
* This is a convenience function that is not actually declared in the
* Adapter interface, but allows for useful techniques such as procedural
* iteration over the elements in an array. The ArrayType instance that is
* returned by this function is compatible with the BOOST_FOREACH macro.
*
* If the contained is not an array, this function will throw an exception.
*
* @returns ArrayType instance containing an array representation of the
* value held by this Adapter.
*/
ArrayType getArray() const
{
opt::optional<ArrayType> arrayValue = value.getArrayOptional();
if (arrayValue) {
return *arrayValue;
}
throw std::runtime_error("JSON value is not an array.");
}
virtual size_t getArraySize() const
{
size_t result;
if (value.getArraySize(result)) {
return result;
}
throw std::runtime_error("JSON value is not an array.");
}
virtual bool getArraySize(size_t &result) const
{
return value.getArraySize(result);
}
virtual bool getBool() const
{
bool result;
if (getBool(result)) {
return result;
}
throw std::runtime_error("JSON value is not a boolean.");
}
virtual bool getBool(bool &result) const
{
return value.getBool(result);
}
virtual double getDouble() const
{
double result;
if (getDouble(result)) {
return result;
}
throw std::runtime_error("JSON value is not a double.");
}
virtual bool getDouble(double &result) const
{
return value.getDouble(result);
}
virtual int64_t getInteger() const
{
int64_t result;
if (getInteger(result)) {
return result;
}
throw std::runtime_error("JSON value is not an integer.");
}
virtual bool getInteger(int64_t &result) const
{
return value.getInteger(result);
}
virtual double getNumber() const
{
double result;
if (getNumber(result)) {
return result;
}
throw std::runtime_error("JSON value is not a number.");
}
virtual bool getNumber(double &result) const
{
if (isDouble()) {
return getDouble(result);
} else if (isInteger()) {
int64_t integerResult;
if (getInteger(integerResult)) {
result = static_cast<double>(integerResult);
return true;
}
}
return false;
}
/**
* @brief Return an ObjectType instance representing the object contained
* by this Adapter instance.
*
* This is a convenience function that is not actually declared in the
* Adapter interface, but allows for useful techniques such as procedural
* iteration over the members of an object. The ObjectType instance that is
* returned by this function is compatible with the BOOST_FOREACH macro.
*
* If the contained is not an object, this function will throw an exception.
*
* @returns ObjectType instance containing an array representation of the
* value held by this Adapter.
*/
ObjectType getObject() const
{
opt::optional<ObjectType> objectValue = value.getObjectOptional();
if (objectValue) {
return *objectValue;
}
throw std::runtime_error("JSON value is not an object.");
}
virtual size_t getObjectSize() const
{
size_t result;
if (getObjectSize(result)) {
return result;
}
throw std::runtime_error("JSON value is not an object.");
}
virtual bool getObjectSize(size_t &result) const
{
return value.getObjectSize(result);
}
virtual std::string getString() const
{
std::string result;
if (getString(result)) {
return result;
}
throw std::runtime_error("JSON value is not a string.");
}
virtual bool getString(std::string &result) const
{
return value.getString(result);
}
virtual FrozenValue * freeze() const
{
return value.freeze();
}
virtual bool hasStrictTypes() const
{
return ValueType::hasStrictTypes();
}
virtual bool isArray() const
{
return value.isArray();
}
virtual bool isBool() const
{
return value.isBool();
}
virtual bool isDouble() const
{
return value.isDouble();
}
virtual bool isInteger() const
{
return value.isInteger();
}
virtual bool isNull() const
{
return value.isNull();
}
virtual bool isNumber() const
{
return value.isInteger() || value.isDouble();
}
virtual bool isObject() const
{
return value.isObject();
}
virtual bool isString() const
{
return value.isString();
}
virtual bool maybeArray() const
{
if (value.isArray()) {
return true;
} else if (value.isObject()) {
size_t objectSize;
if (value.getObjectSize(objectSize) && objectSize == 0) {
return true;
}
}
return false;
}
virtual bool maybeBool() const
{
if (value.isBool()) {
return true;
} else if (value.isString()) {
std::string stringValue;
if (value.getString(stringValue)) {
if (stringValue.compare("true") == 0 || stringValue.compare("false") == 0) {
return true;
}
}
}
return false;
}
virtual bool maybeDouble() const
{
if (value.isNumber()) {
return true;
} else if (value.isString()) {
std::string s;
if (value.getString(s)) {
const char *b = s.c_str();
char *e = NULL;
strtod(b, &e);
return e != b && e == b + s.length();
}
}
return false;
}
virtual bool maybeInteger() const
{
if (value.isInteger()) {
return true;
} else if (value.isString()) {
std::string s;
if (value.getString(s)) {
std::istringstream i(s);
int64_t x;
char c;
if (!(i >> x) || i.get(c)) {
return false;
}
return true;
}
}
return false;
}
virtual bool maybeNull() const
{
if (value.isNull()) {
return true;
} else if (value.isString()) {
std::string stringValue;
if (value.getString(stringValue)) {
if (stringValue.empty()) {
return true;
}
}
}
return false;
}
virtual bool maybeObject() const
{
if (value.isObject()) {
return true;
} else if (value.isArray()) {
size_t arraySize;
if (value.getArraySize(arraySize) && arraySize == 0) {
return true;
}
}
return false;
}
virtual bool maybeString() const
{
if (value.isString() || value.isBool() || value.isInteger() ||
value.isDouble()) {
return true;
} else if (value.isObject()) {
size_t objectSize;
if (value.getObjectSize(objectSize) && objectSize == 0) {
return true;
}
} else if (value.isArray()) {
size_t arraySize;
if (value.getArraySize(arraySize) && arraySize == 0) {
return true;
}
}
return false;
}
private:
const ValueType value;
};
} // namespace adapters
} // namespace valijson
#endif

56
3rdparty/valijson/adapters/frozen_value.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,56 @@
#pragma once
#ifndef __VALIJSON_ADAPTERS_FROZEN_VALUE_HPP
#define __VALIJSON_ADAPTERS_FROZEN_VALUE_HPP
#include <valijson/adapters/adapter.hpp>
namespace valijson {
namespace adapters {
/**
* @brief An interface that provides minimal access to a stored JSON value.
*
* The main reason that this interface exists is to support the 'enum'
* constraint. Each Adapter type is expected to provide an implementation of
* this interface. That class should be able to maintain its own copy of a
* JSON value, independent of the original document.
*
* This interface currently provides just the clone and equalTo functions, but
* could be expanded to include other functions declared in the Adapter
* interface.
*
* @todo it would be nice to better integrate this with the Adapter interface
*/
class FrozenValue
{
public:
/**
* @brief Virtual destructor defined to ensure deletion via base-class
* pointers is safe.
*/
virtual ~FrozenValue() { }
/**
* @brief Clone the stored value and return a pointer to a new FrozenValue
* object containing the value.
*/
virtual FrozenValue *clone() const = 0;
/**
* @brief Return true if the stored value is equal to the value contained
* by an Adapter instance.
*
* @param adapter Adapter to compare value against
* @param strict Flag to use strict type comparison
*
* @returns true if values are equal, false otherwise
*/
virtual bool equalTo(const Adapter &adapter, bool strict) const = 0;
};
} // namespace adapters
} // namespace valijson
#endif

713
3rdparty/valijson/adapters/json11_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,713 @@
/**
* @file
*
* @brief Adapter implementation for the json11 parser library.
*
* Include this file in your program to enable support for json11.
*
* This file defines the following classes (not in this order):
* - Json11Adapter
* - Json11Array
* - Json11ArrayValueIterator
* - Json11FrozenValue
* - Json11Object
* - Json11ObjectMember
* - Json11ObjectMemberIterator
* - Json11Value
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is Json11Adapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_JSON11_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_JSON11_ADAPTER_HPP
#include <string>
#include <json11.hpp>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class Json11Adapter;
class Json11ArrayValueIterator;
class Json11ObjectMemberIterator;
typedef std::pair<std::string, Json11Adapter> Json11ObjectMember;
/**
* @brief Light weight wrapper for a Json11 array value.
*
* This class is light weight wrapper for a Json11 array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* Json11 value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class Json11Array
{
public:
typedef Json11ArrayValueIterator const_iterator;
typedef Json11ArrayValueIterator iterator;
/// Construct a Json11Array referencing an empty array.
Json11Array()
: value(emptyArray()) { }
/**
* @brief Construct a Json11Array referencing a specific Json11
* value.
*
* @param value reference to a Json11 value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
Json11Array(const json11::Json &value)
: value(value)
{
if (!value.is_array()) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying Json11 implementation.
*/
Json11ArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying Json11 implementation.
*/
Json11ArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return value.array_items().size();
}
private:
/**
* @brief Return a reference to a Json11 value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const json11::Json & emptyArray()
{
static const json11::Json array((json11::Json::array()));
return array;
}
/// Reference to the contained value
const json11::Json &value;
};
/**
* @brief Light weight wrapper for a Json11 object.
*
* This class is light weight wrapper for a Json11 object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* Json11 value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class Json11Object
{
public:
typedef Json11ObjectMemberIterator const_iterator;
typedef Json11ObjectMemberIterator iterator;
/// Construct a Json11Object referencing an empty object singleton.
Json11Object()
: value(emptyObject()) { }
/**
* @brief Construct a Json11Object referencing a specific Json11
* value.
*
* @param value reference to a Json11 value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
Json11Object(const json11::Json &value)
: value(value)
{
if (!value.is_object()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying Json11 implementation.
*/
Json11ObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying Json11 implementation.
*/
Json11ObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param propertyName property name to search for
*/
Json11ObjectMemberIterator find(const std::string &propertyName) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return value.object_items().size();
}
private:
/**
* @brief Return a reference to a Json11 value that is empty object.
*
* Note that the value returned by this function is a singleton.
*/
static const json11::Json & emptyObject()
{
static const json11::Json object((json11::Json::object()));
return object;
}
/// Reference to the contained object
const json11::Json &value;
};
/**
* @brief Stores an independent copy of a Json11 value.
*
* This class allows a Json11 value to be stored independent of its original
* document. Json11 makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class Json11FrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a Json11 value
*
* @param source the Json11 value to be copied
*/
explicit Json11FrozenValue(const json11::Json &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new Json11FrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored Json11 value
json11::Json value;
};
/**
* @brief Light weight wrapper for a Json11 value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a Json11 value. This class is responsible
* for the mechanics of actually reading a Json11 value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class Json11Value
{
public:
/// Construct a wrapper for the empty object singleton
Json11Value()
: value(emptyObject()) { }
/// Construct a wrapper for a specific Json11 value
Json11Value(const json11::Json &value)
: value(value) { }
/**
* @brief Create a new Json11FrozenValue instance that contains the
* value referenced by this Json11Value instance.
*
* @returns pointer to a new Json11FrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new Json11FrozenValue(value);
}
/**
* @brief Optionally return a Json11Array instance.
*
* If the referenced Json11 value is an array, this function will return
* a std::optional containing a Json11Array instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<Json11Array> getArrayOptional() const
{
if (value.is_array()) {
return opt::make_optional(Json11Array(value));
}
return opt::optional<Json11Array>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced Json11 value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.is_array()) {
result = value.array_items().size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.is_bool()) {
result = value.bool_value();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.is_number()) {
result = value.number_value();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if(isInteger()) {
result = value.int_value();
return true;
}
return false;
}
/**
* @brief Optionally return a Json11Object instance.
*
* If the referenced Json11 value is an object, this function will return a
* std::optional containing a Json11Object instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<Json11Object> getObjectOptional() const
{
if (value.is_object()) {
return opt::make_optional(Json11Object(value));
}
return opt::optional<Json11Object>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced Json11 value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.is_object()) {
result = value.object_items().size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.is_string()) {
result = value.string_value();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.is_array();
}
bool isBool() const
{
return value.is_bool();
}
bool isDouble() const
{
return value.is_number();
}
bool isInteger() const
{
return value.is_number()
&& value.int_value() == value.number_value();
}
bool isNull() const
{
return value.is_null();
}
bool isNumber() const
{
return value.is_number();
}
bool isObject() const
{
return value.is_object();
}
bool isString() const
{
return value.is_string();
}
private:
/// Return a reference to an empty object singleton
static const json11::Json & emptyObject()
{
static const json11::Json object((json11::Json::object()));
return object;
}
/// Reference to the contained Json11 value.
const json11::Json &value;
};
/**
* @brief An implementation of the Adapter interface supporting Json11.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class Json11Adapter:
public BasicAdapter<Json11Adapter,
Json11Array,
Json11ObjectMember,
Json11Object,
Json11Value>
{
public:
/// Construct a Json11Adapter that contains an empty object
Json11Adapter()
: BasicAdapter() { }
/// Construct a Json11Adapter containing a specific Json11 value
Json11Adapter(const json11::Json &value)
: BasicAdapter(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* Json11Adapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template.
*
* @see Json11Array
*/
class Json11ArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
Json11Adapter> // value type
{
public:
/**
* @brief Construct a new Json11ArrayValueIterator using an existing
* Json11 iterator.
*
* @param itr Json11 iterator to store
*/
Json11ArrayValueIterator(
const json11::Json::array::const_iterator &itr)
: itr(itr) { }
/// Returns a Json11Adapter that contains the value of the current
/// element.
Json11Adapter operator*() const
{
return Json11Adapter(*itr);
}
DerefProxy<Json11Adapter> operator->() const
{
return DerefProxy<Json11Adapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const Json11ArrayValueIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const Json11ArrayValueIterator &other) const
{
return !(itr == other.itr);
}
const Json11ArrayValueIterator& operator++()
{
itr++;
return *this;
}
Json11ArrayValueIterator operator++(int)
{
Json11ArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const Json11ArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
private:
json11::Json::array::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of Json11ObjectMember representing one of the members of the object. It
* has been implemented using the boost iterator_facade template.
*
* @see Json11Object
* @see Json11ObjectMember
*/
class Json11ObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
Json11ObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a Json11 iterator.
*
* @param itr Json11 iterator to store
*/
Json11ObjectMemberIterator(
const json11::Json::object::const_iterator &itr)
: itr(itr) { }
/**
* @brief Returns a Json11ObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
Json11ObjectMember operator*() const
{
return Json11ObjectMember(itr->first, itr->second);
}
DerefProxy<Json11ObjectMember> operator->() const
{
return DerefProxy<Json11ObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const Json11ObjectMemberIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const Json11ObjectMemberIterator &other) const
{
return !(itr == other.itr);
}
const Json11ObjectMemberIterator& operator++()
{
itr++;
return *this;
}
Json11ObjectMemberIterator operator++(int)
{
Json11ObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const Json11ObjectMemberIterator& operator--()
{
itr--;
return *this;
}
private:
/// Iternal copy of the original Json11 iterator
json11::Json::object::const_iterator itr;
};
/// Specialisation of the AdapterTraits template struct for Json11Adapter.
template<>
struct AdapterTraits<valijson::adapters::Json11Adapter>
{
typedef json11::Json DocumentType;
static std::string adapterName()
{
return "Json11Adapter";
}
};
inline bool Json11FrozenValue::equalTo(const Adapter &other, bool strict) const
{
return Json11Adapter(value).equalTo(other, strict);
}
inline Json11ArrayValueIterator Json11Array::begin() const
{
return value.array_items().begin();
}
inline Json11ArrayValueIterator Json11Array::end() const
{
return value.array_items().end();
}
inline Json11ObjectMemberIterator Json11Object::begin() const
{
return value.object_items().begin();
}
inline Json11ObjectMemberIterator Json11Object::end() const
{
return value.object_items().end();
}
inline Json11ObjectMemberIterator Json11Object::find(
const std::string &propertyName) const
{
return value.object_items().find(propertyName);
}
} // namespace adapters
} // namespace valijson
#endif

724
3rdparty/valijson/adapters/jsoncpp_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,724 @@
/**
* @file
*
* @brief Adapter implementation for the JsonCpp parser library.
*
* Include this file in your program to enable support for JsonCpp.
*
* This file defines the following classes (not in this order):
* - JsonCppAdapter
* - JsonCppArray
* - JsonCppArrayValueIterator
* - JsonCppFrozenValue
* - JsonCppObject
* - JsonCppObjectMember
* - JsonCppObjectMemberIterator
* - JsonCppValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is JsonCppAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_JSONCPP_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_JSONCPP_ADAPTER_HPP
#include <stdint.h>
#include <string>
#include <iterator>
#include <json/json.h>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class JsonCppAdapter;
class JsonCppArrayValueIterator;
class JsonCppObjectMemberIterator;
typedef std::pair<std::string, JsonCppAdapter> JsonCppObjectMember;
/**
* @brief Light weight wrapper for a JsonCpp array value.
*
* This class is light weight wrapper for a JsonCpp array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* JsonCpp value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class JsonCppArray
{
public:
typedef JsonCppArrayValueIterator const_iterator;
typedef JsonCppArrayValueIterator iterator;
/// Construct a JsonCppArray referencing an empty array.
JsonCppArray()
: value(emptyArray()) { }
/**
* @brief Construct a JsonCppArray referencing a specific JsonCpp value.
*
* @param value reference to a JsonCpp value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
JsonCppArray(const Json::Value &value)
: value(value)
{
if (!value.isArray()) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying JsonCpp implementation.
*/
JsonCppArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying JsonCpp implementation.
*/
JsonCppArrayValueIterator end() const;
/// Return the number of elements in the array.
size_t size() const
{
return value.size();
}
private:
/**
* @brief Return a reference to a JsonCpp value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const Json::Value & emptyArray()
{
static const Json::Value array(Json::arrayValue);
return array;
}
/// Reference to the contained array
const Json::Value &value;
};
/**
* @brief Light weight wrapper for a JsonCpp object.
*
* This class is light weight wrapper for a JsonCpp object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* JsonCpp object, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class JsonCppObject
{
public:
typedef JsonCppObjectMemberIterator const_iterator;
typedef JsonCppObjectMemberIterator iterator;
/// Construct a JsonCppObject referencing an empty object singleton.
JsonCppObject()
: value(emptyObject()) { }
/**
* @brief Construct a JsonCppObject referencing a specific JsonCpp value.
*
* @param value reference to a JsonCpp value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
JsonCppObject(const Json::Value &value)
: value(value)
{
if (!value.isObject()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying JsonCpp implementation.
*/
JsonCppObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying JsonCpp implementation.
*/
JsonCppObjectMemberIterator end() const;
/**
* @brief Return an iterator for a member/property with the given name
*
* @param propertyName Property name
*
* @returns a valid iterator if found, or an invalid iterator if not found
*/
JsonCppObjectMemberIterator find(const std::string &propertyName) const;
/// Return the number of members in the object
size_t size() const
{
return value.size();
}
private:
/// Return a reference to an empty JsonCpp object
static const Json::Value & emptyObject()
{
static const Json::Value object(Json::objectValue);
return object;
}
/// Reference to the contained object
const Json::Value &value;
};
/**
* @brief Stores an independent copy of a JsonCpp value.
*
* This class allows a JsonCpp value to be stored independent of its original
* document. JsonCpp makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class JsonCppFrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a JsonCpp value
*
* @param source the JsonCpp value to be copied
*/
explicit JsonCppFrozenValue(const Json::Value &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new JsonCppFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored JsonCpp value
Json::Value value;
};
/**
* @brief Light weight wrapper for a JsonCpp value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a JsonCpp value. This class is responsible
* for the mechanics of actually reading a JsonCpp value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class JsonCppValue
{
public:
/// Construct a wrapper for the empty object singleton
JsonCppValue()
: value(emptyObject()) { }
/// Construct a wrapper for a specific JsonCpp value
JsonCppValue(const Json::Value &value)
: value(value) { }
/**
* @brief Create a new JsonCppFrozenValue instance that contains the
* value referenced by this JsonCppValue instance.
*
* @returns pointer to a new JsonCppFrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new JsonCppFrozenValue(value);
}
/**
* @brief Optionally return a JsonCppArray instance.
*
* If the referenced JsonCpp value is an array, this function will return a
* std::optional containing a JsonCppArray instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<JsonCppArray> getArrayOptional() const
{
if (value.isArray()) {
return opt::make_optional(JsonCppArray(value));
}
return opt::optional<JsonCppArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced JsonCpp value is an array, this function will retrieve
* the number of elements in the array and store it in the output variable
* provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.isArray()) {
result = value.size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.isBool()) {
result = value.asBool();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.isDouble()) {
result = value.asDouble();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if (value.isIntegral()) {
result = static_cast<int64_t>(value.asInt());
return true;
}
return false;
}
/**
* @brief Optionally return a JsonCppObject instance.
*
* If the referenced JsonCpp value is an object, this function will return a
* std::optional containing a JsonCppObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<JsonCppObject> getObjectOptional() const
{
if (value.isObject()) {
return opt::make_optional(JsonCppObject(value));
}
return opt::optional<JsonCppObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced JsonCpp value is an object, this function will retrieve
* the number of members in the object and store it in the output variable
* provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.isObject()) {
result = value.size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.isString()) {
result = value.asString();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.isArray() && !value.isNull();
}
bool isBool() const
{
return value.isBool();
}
bool isDouble() const
{
return value.isDouble();
}
bool isInteger() const
{
return value.isIntegral() && !value.isBool();
}
bool isNull() const
{
return value.isNull();
}
bool isNumber() const
{
return value.isNumeric() && !value.isBool();
}
bool isObject() const
{
return value.isObject() && !value.isNull();
}
bool isString() const
{
return value.isString();
}
private:
/// Return a reference to an empty object singleton.
static const Json::Value &emptyObject()
{
static Json::Value object(Json::objectValue);
return object;
}
/// Reference to the contained JsonCpp value
const Json::Value &value;
};
/**
* @brief An implementation of the Adapter interface supporting JsonCpp.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class JsonCppAdapter:
public BasicAdapter<JsonCppAdapter,
JsonCppArray,
JsonCppObjectMember,
JsonCppObject,
JsonCppValue>
{
public:
/// Construct a JsonCppAdapter that contains an empty object
JsonCppAdapter()
: BasicAdapter() { }
/// Construct a JsonCppAdapter containing a specific JsonCpp value
JsonCppAdapter(const Json::Value &value)
: BasicAdapter(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* JsonCppAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template.
*
* @see JsonCppArray
*/
class JsonCppArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
JsonCppAdapter> // value type
{
public:
/**
* @brief Construct a new JsonCppArrayValueIterator using an existing
* JsonCpp iterator.
*
* @param itr JsonCpp iterator to store
*/
JsonCppArrayValueIterator(const Json::Value::const_iterator &itr)
: itr(itr) { }
/// Returns a JsonCppAdapter that contains the value of the current element.
JsonCppAdapter operator*() const
{
return JsonCppAdapter(*itr);
}
DerefProxy<JsonCppAdapter> operator->() const
{
return DerefProxy<JsonCppAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param rhs iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const JsonCppArrayValueIterator &rhs) const
{
return itr == rhs.itr;
}
bool operator!=(const JsonCppArrayValueIterator &rhs) const
{
return !(itr == rhs.itr);
}
JsonCppArrayValueIterator& operator++()
{
itr++;
return *this;
}
JsonCppArrayValueIterator operator++(int)
{
JsonCppArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
JsonCppArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
if (n > 0) {
while (n-- > 0) {
itr++;
}
} else {
while (n++ < 0) {
itr--;
}
}
}
private:
Json::Value::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of JsonCppObjectMember representing one of the members of the object. It has
* been implemented using the boost iterator_facade template.
*
* @see JsonCppObject
* @see JsonCppObjectMember
*/
class JsonCppObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
JsonCppObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a JsonCpp iterator.
*
* @param itr JsonCpp iterator to store
*/
JsonCppObjectMemberIterator(const Json::ValueConstIterator &itr)
: itr(itr) { }
/**
* @brief Returns a JsonCppObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
JsonCppObjectMember operator*() const
{
return JsonCppObjectMember(itr.key().asString(), *itr);
}
DerefProxy<JsonCppObjectMember> operator->() const
{
return DerefProxy<JsonCppObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param rhs Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const JsonCppObjectMemberIterator &rhs) const
{
return itr == rhs.itr;
}
bool operator!=(const JsonCppObjectMemberIterator &rhs) const
{
return !(itr == rhs.itr);
}
const JsonCppObjectMemberIterator& operator++()
{
itr++;
return *this;
}
JsonCppObjectMemberIterator operator++(int)
{
JsonCppObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
JsonCppObjectMemberIterator operator--()
{
itr--;
return *this;
}
private:
/// Iternal copy of the original JsonCpp iterator
Json::ValueConstIterator itr;
};
/// Specialisation of the AdapterTraits template struct for JsonCppAdapter.
template<>
struct AdapterTraits<valijson::adapters::JsonCppAdapter>
{
typedef Json::Value DocumentType;
static std::string adapterName()
{
return "JsonCppAdapter";
}
};
inline bool JsonCppFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return JsonCppAdapter(value).equalTo(other, strict);
}
inline JsonCppArrayValueIterator JsonCppArray::begin() const
{
return value.begin();
}
inline JsonCppArrayValueIterator JsonCppArray::end() const
{
return value.end();
}
inline JsonCppObjectMemberIterator JsonCppObject::begin() const
{
return value.begin();
}
inline JsonCppObjectMemberIterator JsonCppObject::end() const
{
return value.end();
}
inline JsonCppObjectMemberIterator JsonCppObject::find(
const std::string &propertyName) const
{
if (value.isMember(propertyName)) {
Json::ValueConstIterator itr;
for ( itr = value.begin(); itr != value.end(); ++itr) {
if (itr.key() == propertyName) {
return itr;
}
}
}
return value.end();
}
} // namespace adapters
} // namespace valijson
#endif

712
3rdparty/valijson/adapters/nlohmann_json_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,712 @@
/**
* @file
*
* @brief Adapter implementation for the nlohmann json parser library.
*
* Include this file in your program to enable support for nlohmann json.
*
* This file defines the following classes (not in this order):
* - NlohmannJsonAdapter
* - NlohmannJsonArray
* - NlohmannJsonValueIterator
* - NlohmannJsonFrozenValue
* - NlohmannJsonObject
* - NlohmannJsonObjectMember
* - NlohmannJsonObjectMemberIterator
* - NlohmannJsonValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is NlohmannJsonAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_NLOHMANN_JSON_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_NLOHMANN_JSON_ADAPTER_HPP
#include <string>
#include <nlohmann/json.hpp>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class NlohmannJsonAdapter;
class NlohmannJsonArrayValueIterator;
class NlohmannJsonObjectMemberIterator;
typedef std::pair<std::string, NlohmannJsonAdapter> NlohmannJsonObjectMember;
/**
* @brief Light weight wrapper for a NlohmannJson array value.
*
* This class is light weight wrapper for a NlohmannJson array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* NlohmannJson value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class NlohmannJsonArray
{
public:
typedef NlohmannJsonArrayValueIterator const_iterator;
typedef NlohmannJsonArrayValueIterator iterator;
/// Construct a NlohmannJsonArray referencing an empty array.
NlohmannJsonArray()
: value(emptyArray()) { }
/**
* @brief Construct a NlohmannJsonArray referencing a specific NlohmannJson
* value.
*
* @param value reference to a NlohmannJson value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
NlohmannJsonArray(const nlohmann::json &value)
: value(value)
{
if (!value.is_array()) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying NlohmannJson implementation.
*/
NlohmannJsonArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying NlohmannJson implementation.
*/
NlohmannJsonArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return value.size();
}
private:
/**
* @brief Return a reference to a NlohmannJson value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const nlohmann::json & emptyArray()
{
static const nlohmann::json array = nlohmann::json::array();
return array;
}
/// Reference to the contained value
const nlohmann::json &value;
};
/**
* @brief Light weight wrapper for a NlohmannJson object.
*
* This class is light weight wrapper for a NlohmannJson object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* NlohmannJson value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class NlohmannJsonObject
{
public:
typedef NlohmannJsonObjectMemberIterator const_iterator;
typedef NlohmannJsonObjectMemberIterator iterator;
/// Construct a NlohmannJsonObject referencing an empty object singleton.
NlohmannJsonObject()
: value(emptyObject()) { }
/**
* @brief Construct a NlohmannJsonObject referencing a specific NlohmannJson
* value.
*
* @param value reference to a NlohmannJson value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
NlohmannJsonObject(const nlohmann::json &value)
: value(value)
{
if (!value.is_object()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying NlohmannJson implementation.
*/
NlohmannJsonObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying NlohmannJson implementation.
*/
NlohmannJsonObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param propertyName property name to search for
*/
NlohmannJsonObjectMemberIterator find(const std::string &propertyName) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return value.size();
}
private:
/**
* @brief Return a reference to a NlohmannJson value that is empty object.
*
* Note that the value returned by this function is a singleton.
*/
static const nlohmann::json & emptyObject()
{
static const nlohmann::json object = nlohmann::json::object();
return object;
}
/// Reference to the contained object
const nlohmann::json &value;
};
/**
* @brief Stores an independent copy of a NlohmannJson value.
*
* This class allows a NlohmannJson value to be stored independent of its original
* document. NlohmannJson makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class NlohmannJsonFrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a NlohmannJson value
*
* @param source the NlohmannJson value to be copied
*/
explicit NlohmannJsonFrozenValue(const nlohmann::json &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new NlohmannJsonFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored NlohmannJson value
nlohmann::json value;
};
/**
* @brief Light weight wrapper for a NlohmannJson value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a NlohmannJson value. This class is responsible
* for the mechanics of actually reading a NlohmannJson value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class NlohmannJsonValue
{
public:
/// Construct a wrapper for the empty object singleton
NlohmannJsonValue()
: value(emptyObject()) { }
/// Construct a wrapper for a specific NlohmannJson value
NlohmannJsonValue(const nlohmann::json &value)
: value(value) { }
/**
* @brief Create a new NlohmannJsonFrozenValue instance that contains the
* value referenced by this NlohmannJsonValue instance.
*
* @returns pointer to a new NlohmannJsonFrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new NlohmannJsonFrozenValue(value);
}
/**
* @brief Optionally return a NlohmannJsonArray instance.
*
* If the referenced NlohmannJson value is an array, this function will return
* a std::optional containing a NlohmannJsonArray instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<NlohmannJsonArray> getArrayOptional() const
{
if (value.is_array()) {
return opt::make_optional(NlohmannJsonArray(value));
}
return opt::optional<NlohmannJsonArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced NlohmannJson value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.is_array()) {
result = value.size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.is_boolean()) {
result = value.get<bool>();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.is_number_float()) {
result = value.get<double>();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if(value.is_number_integer()) {
result = value.get<int64_t>();
return true;
}
return false;
}
/**
* @brief Optionally return a NlohmannJsonObject instance.
*
* If the referenced NlohmannJson value is an object, this function will return a
* std::optional containing a NlohmannJsonObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<NlohmannJsonObject> getObjectOptional() const
{
if (value.is_object()) {
return opt::make_optional(NlohmannJsonObject(value));
}
return opt::optional<NlohmannJsonObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced NlohmannJson value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.is_object()) {
result = value.size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.is_string()) {
result = value.get<std::string>();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.is_array();
}
bool isBool() const
{
return value.is_boolean();
}
bool isDouble() const
{
return value.is_number_float();
}
bool isInteger() const
{
return value.is_number_integer();
}
bool isNull() const
{
return value.is_null();
}
bool isNumber() const
{
return value.is_number();
}
bool isObject() const
{
return value.is_object();
}
bool isString() const
{
return value.is_string();
}
private:
/// Return a reference to an empty object singleton
static const nlohmann::json & emptyObject()
{
static const nlohmann::json object = nlohmann::json::object();
return object;
}
/// Reference to the contained NlohmannJson value.
const nlohmann::json &value;
};
/**
* @brief An implementation of the Adapter interface supporting NlohmannJson.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class NlohmannJsonAdapter:
public BasicAdapter<NlohmannJsonAdapter,
NlohmannJsonArray,
NlohmannJsonObjectMember,
NlohmannJsonObject,
NlohmannJsonValue>
{
public:
/// Construct a NlohmannJsonAdapter that contains an empty object
NlohmannJsonAdapter()
: BasicAdapter() { }
/// Construct a NlohmannJsonAdapter containing a specific Nlohmann Json object
NlohmannJsonAdapter(const nlohmann::json &value)
: BasicAdapter(NlohmannJsonValue{value}) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* NlohmannJsonAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template.
*
* @see NlohmannJsonArray
*/
class NlohmannJsonArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
NlohmannJsonAdapter> // value type
{
public:
/**
* @brief Construct a new NlohmannJsonArrayValueIterator using an existing
* NlohmannJson iterator.
*
* @param itr NlohmannJson iterator to store
*/
NlohmannJsonArrayValueIterator(const nlohmann::json::const_iterator &itr)
: itr(itr) { }
/// Returns a NlohmannJsonAdapter that contains the value of the current
/// element.
NlohmannJsonAdapter operator*() const
{
return NlohmannJsonAdapter(*itr);
}
DerefProxy<NlohmannJsonAdapter> operator->() const
{
return DerefProxy<NlohmannJsonAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const NlohmannJsonArrayValueIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const NlohmannJsonArrayValueIterator &other) const
{
return !(itr == other.itr);
}
const NlohmannJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
NlohmannJsonArrayValueIterator operator++(int)
{
NlohmannJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const NlohmannJsonArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
private:
nlohmann::json::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of NlohmannJsonObjectMember representing one of the members of the object. It
* has been implemented using the boost iterator_facade template.
*
* @see NlohmannJsonObject
* @see NlohmannJsonObjectMember
*/
class NlohmannJsonObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
NlohmannJsonObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a NlohmannJson iterator.
*
* @param itr NlohmannJson iterator to store
*/
NlohmannJsonObjectMemberIterator(const nlohmann::json::const_iterator &itr)
: itr(itr) { }
/**
* @brief Returns a NlohmannJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
NlohmannJsonObjectMember operator*() const
{
return NlohmannJsonObjectMember(itr.key(), itr.value());
}
DerefProxy<NlohmannJsonObjectMember> operator->() const
{
return DerefProxy<NlohmannJsonObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const NlohmannJsonObjectMemberIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const NlohmannJsonObjectMemberIterator &other) const
{
return !(itr == other.itr);
}
const NlohmannJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
NlohmannJsonObjectMemberIterator operator++(int)
{
NlohmannJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const NlohmannJsonObjectMemberIterator& operator--()
{
itr--;
return *this;
}
private:
/// Iternal copy of the original NlohmannJson iterator
nlohmann::json::const_iterator itr;
};
/// Specialisation of the AdapterTraits template struct for NlohmannJsonAdapter.
template<>
struct AdapterTraits<valijson::adapters::NlohmannJsonAdapter>
{
typedef nlohmann::json DocumentType;
static std::string adapterName()
{
return "NlohmannJsonAdapter";
}
};
inline bool NlohmannJsonFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return NlohmannJsonAdapter(value).equalTo(other, strict);
}
inline NlohmannJsonArrayValueIterator NlohmannJsonArray::begin() const
{
return value.begin();
}
inline NlohmannJsonArrayValueIterator NlohmannJsonArray::end() const
{
return value.end();
}
inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::begin() const
{
return value.begin();
}
inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::end() const
{
return value.end();
}
inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::find(
const std::string &propertyName) const
{
return value.find(propertyName);
}
} // namespace adapters
} // namespace valijson
#endif

727
3rdparty/valijson/adapters/picojson_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,727 @@
/**
* @file
*
* @brief Adapter implementation for the PicoJson parser library.
*
* Include this file in your program to enable support for PicoJson.
*
* This file defines the following classes (not in this order):
* - PicoJsonAdapter
* - PicoJsonArray
* - PicoJsonArrayValueIterator
* - PicoJsonFrozenValue
* - PicoJsonObject
* - PicoJsonObjectMember
* - PicoJsonObjectMemberIterator
* - PicoJsonValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is PicoJsonAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP
#include <string>
#include <picojson.h>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class PicoJsonAdapter;
class PicoJsonArrayValueIterator;
class PicoJsonObjectMemberIterator;
typedef std::pair<std::string, PicoJsonAdapter> PicoJsonObjectMember;
/**
* @brief Light weight wrapper for a PicoJson array value.
*
* This class is light weight wrapper for a PicoJson array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* PicoJson value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class PicoJsonArray
{
public:
typedef PicoJsonArrayValueIterator const_iterator;
typedef PicoJsonArrayValueIterator iterator;
/// Construct a PicoJsonArray referencing an empty array.
PicoJsonArray()
: value(emptyArray()) { }
/**
* @brief Construct a PicoJsonArray referencing a specific PicoJson
* value.
*
* @param value reference to a PicoJson value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
explicit PicoJsonArray(const picojson::value &value)
: value(value)
{
if (!value.is<picojson::array>()) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying PicoJson implementation.
*/
PicoJsonArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying PicoJson implementation.
*/
PicoJsonArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
const picojson::array &array = value.get<picojson::array>();
return array.size();
}
private:
/**
* @brief Return a reference to a PicoJson value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const picojson::value & emptyArray()
{
static const picojson::value array(picojson::array_type, false);
return array;
}
/// Reference to the contained value
const picojson::value &value;
};
/**
* @brief Light weight wrapper for a PicoJson object.
*
* This class is light weight wrapper for a PicoJson object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* PicoJson value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class PicoJsonObject
{
public:
typedef PicoJsonObjectMemberIterator const_iterator;
typedef PicoJsonObjectMemberIterator iterator;
/// Construct a PicoJsonObject referencing an empty object singleton.
PicoJsonObject()
: value(emptyObject()) { }
/**
* @brief Construct a PicoJsonObject referencing a specific PicoJson
* value.
*
* @param value reference to a PicoJson value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
PicoJsonObject(const picojson::value &value)
: value(value)
{
if (!value.is<picojson::object>()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying PicoJson implementation.
*/
PicoJsonObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying PicoJson implementation.
*/
PicoJsonObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param propertyName property name to search for
*/
PicoJsonObjectMemberIterator find(const std::string &propertyName) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
const picojson::object &object = value.get<picojson::object>();
return object.size();
}
private:
/**
* @brief Return a reference to a PicoJson value that is empty object.
*
* Note that the value returned by this function is a singleton.
*/
static const picojson::value & emptyObject()
{
static const picojson::value object(picojson::object_type, false);
return object;
}
/// Reference to the contained object
const picojson::value &value;
};
/**
* @brief Stores an independent copy of a PicoJson value.
*
* This class allows a PicoJson value to be stored independent of its original
* document. PicoJson makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class PicoJsonFrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a PicoJson value
*
* @param source the PicoJson value to be copied
*/
explicit PicoJsonFrozenValue(const picojson::value &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new PicoJsonFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored PicoJson value
picojson::value value;
};
/**
* @brief Light weight wrapper for a PicoJson value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a PicoJson value. This class is responsible
* for the mechanics of actually reading a PicoJson value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class PicoJsonValue
{
public:
/// Construct a wrapper for the empty object singleton
PicoJsonValue()
: value(emptyObject()) { }
/// Construct a wrapper for a specific PicoJson value
PicoJsonValue(const picojson::value &value)
: value(value) { }
/**
* @brief Create a new PicoJsonFrozenValue instance that contains the
* value referenced by this PicoJsonValue instance.
*
* @returns pointer to a new PicoJsonFrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new PicoJsonFrozenValue(value);
}
/**
* @brief Optionally return a PicoJsonArray instance.
*
* If the referenced PicoJson value is an array, this function will return
* a std::optional containing a PicoJsonArray instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PicoJsonArray> getArrayOptional() const
{
if (value.is<picojson::array>()) {
return opt::make_optional(PicoJsonArray(value));
}
return opt::optional<PicoJsonArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced PicoJson value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.is<picojson::array>()) {
const picojson::array& array = value.get<picojson::array>();
result = array.size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.is<bool>()) {
result = value.get<bool>();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.is<double>()) {
result = value.get<double>();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if (value.is<int64_t>()) {
result = value.get<int64_t>();
return true;
}
return false;
}
/**
* @brief Optionally return a PicoJsonObject instance.
*
* If the referenced PicoJson value is an object, this function will return a
* std::optional containing a PicoJsonObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PicoJsonObject> getObjectOptional() const
{
if (value.is<picojson::object>()) {
return opt::make_optional(PicoJsonObject(value));
}
return opt::optional<PicoJsonObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced PicoJson value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.is<picojson::object>()) {
const picojson::object &object = value.get<picojson::object>();
result = object.size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.is<std::string>()) {
result = value.get<std::string>();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.is<picojson::array>();
}
bool isBool() const
{
return value.is<bool>();
}
bool isDouble() const
{
if (value.is<int64_t>()) {
return false;
}
return value.is<double>();
}
bool isInteger() const
{
return value.is<int64_t>();
}
bool isNull() const
{
return value.is<picojson::null>();
}
bool isNumber() const
{
return value.is<double>();
}
bool isObject() const
{
return value.is<picojson::object>();
}
bool isString() const
{
return value.is<std::string>();
}
private:
/// Return a reference to an empty object singleton
static const picojson::value & emptyObject()
{
static const picojson::value object(picojson::object_type, false);
return object;
}
/// Reference to the contained PicoJson value.
const picojson::value &value;
};
/**
* @brief An implementation of the Adapter interface supporting PicoJson.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class PicoJsonAdapter:
public BasicAdapter<PicoJsonAdapter,
PicoJsonArray,
PicoJsonObjectMember,
PicoJsonObject,
PicoJsonValue>
{
public:
/// Construct a PicoJsonAdapter that contains an empty object
PicoJsonAdapter()
: BasicAdapter() { }
/// Construct a PicoJsonAdapter containing a specific PicoJson value
PicoJsonAdapter(const picojson::value &value)
: BasicAdapter(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* PicoJsonAdapter representing a value stored in the array. It has been
* implemented using the std::iterator template.
*
* @see PicoJsonArray
*/
class PicoJsonArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PicoJsonAdapter> // value type
{
public:
/**
* @brief Construct a new PicoJsonArrayValueIterator using an existing
* PicoJson iterator.
*
* @param itr PicoJson iterator to store
*/
PicoJsonArrayValueIterator(
const picojson::array::const_iterator &itr)
: itr(itr) { }
/// Returns a PicoJsonAdapter that contains the value of the current
/// element.
PicoJsonAdapter operator*() const
{
return PicoJsonAdapter(*itr);
}
DerefProxy<PicoJsonAdapter> operator->() const
{
return DerefProxy<PicoJsonAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const PicoJsonArrayValueIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const PicoJsonArrayValueIterator &other) const
{
return !(itr == other.itr);
}
const PicoJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
PicoJsonArrayValueIterator operator++(int)
{
PicoJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PicoJsonArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
private:
picojson::array::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of PicoJsonObjectMember representing one of the members of the object. It
* has been implemented using the boost iterator_facade template.
*
* @see PicoJsonObject
* @see PicoJsonObjectMember
*/
class PicoJsonObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PicoJsonObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a PicoJson iterator.
*
* @param itr PicoJson iterator to store
*/
PicoJsonObjectMemberIterator(
const picojson::object::const_iterator &itr)
: itr(itr) { }
/**
* @brief Returns a PicoJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
PicoJsonObjectMember operator*() const
{
return PicoJsonObjectMember(itr->first, itr->second);
}
DerefProxy<PicoJsonObjectMember> operator->() const
{
return DerefProxy<PicoJsonObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const PicoJsonObjectMemberIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const PicoJsonObjectMemberIterator &other) const
{
return !(itr == other.itr);
}
const PicoJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
PicoJsonObjectMemberIterator operator++(int)
{
PicoJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PicoJsonObjectMemberIterator& operator--(int)
{
itr--;
return *this;
}
private:
/// Iternal copy of the original PicoJson iterator
picojson::object::const_iterator itr;
};
/// Specialisation of the AdapterTraits template struct for PicoJsonAdapter.
template<>
struct AdapterTraits<valijson::adapters::PicoJsonAdapter>
{
typedef picojson::value DocumentType;
static std::string adapterName()
{
return "PicoJsonAdapter";
}
};
inline bool PicoJsonFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return PicoJsonAdapter(value).equalTo(other, strict);
}
inline PicoJsonArrayValueIterator PicoJsonArray::begin() const
{
const picojson::array &array = value.get<picojson::array>();
return array.begin();
}
inline PicoJsonArrayValueIterator PicoJsonArray::end() const
{
const picojson::array &array = value.get<picojson::array>();
return array.end();
}
inline PicoJsonObjectMemberIterator PicoJsonObject::begin() const
{
const picojson::object &object = value.get<picojson::object>();
return object.begin();
}
inline PicoJsonObjectMemberIterator PicoJsonObject::end() const
{
const picojson::object &object = value.get<picojson::object>();
return object.end();
}
inline PicoJsonObjectMemberIterator PicoJsonObject::find(
const std::string &propertyName) const
{
const picojson::object &object = value.get<picojson::object>();
return object.find(propertyName);
}
} // namespace adapters
} // namespace valijson
#endif

728
3rdparty/valijson/adapters/poco_json_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,728 @@
/**
* @file
*
* @brief Adapter implementation for the Poco json parser library.
*
* Include this file in your program to enable support for Poco json.
*
* This file defines the following classes (not in this order):
* - PocoJsonAdapter
* - PocoJsonArray
* - PocoJsonValueIterator
* - PocoJsonFrozenValue
* - PocoJsonObject
* - PocoJsonObjectMember
* - PocoJsonObjectMemberIterator
* - PocoJsonValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is PocoJsonAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_POCO_JSON_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_POCO_JSON_ADAPTER_HPP
#include <string>
#include <Poco/JSON/Object.h>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson
{
namespace adapters
{
class PocoJsonAdapter;
class PocoJsonArrayValueIterator;
class PocoJsonObjectMemberIterator;
typedef std::pair<std::string, PocoJsonAdapter> PocoJsonObjectMember;
/**
* @brief Light weight wrapper for a PocoJson array value.
*
* This class is light weight wrapper for a PocoJson array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* PocoJson value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class PocoJsonArray
{
public:
typedef PocoJsonArrayValueIterator const_iterator;
typedef PocoJsonArrayValueIterator iterator;
/// Construct a PocoJsonArray referencing an empty array.
PocoJsonArray()
: value(emptyArray())
{ }
/**
* @brief Construct a PocoJsonArray referencing a specific PocoJson
* value.
*
* @param value reference to a PocoJson value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
PocoJsonArray(const Poco::Dynamic::Var &value)
: value(value)
{
if (value.type() != typeid(Poco::JSON::Array::Ptr)) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying PocoJson implementation.
*/
PocoJsonArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying PocoJson implementation.
*/
PocoJsonArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return value.extract<Poco::JSON::Array::Ptr>()->size();
}
private:
/**
* @brief Return a PocoJson value that is an empty array.
*/
static Poco::Dynamic::Var emptyArray()
{
Poco::Dynamic::Var array = Poco::JSON::Array::Ptr();
return array;
}
/// Contained value
Poco::Dynamic::Var value;
};
/**
* @brief Light weight wrapper for a PocoJson object.
*
* This class is light weight wrapper for a PocoJson object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* PocoJson value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class PocoJsonObject
{
public:
typedef PocoJsonObjectMemberIterator const_iterator;
typedef PocoJsonObjectMemberIterator iterator;
/// Construct a PocoJsonObject an empty object.
PocoJsonObject()
: value(emptyObject())
{ }
/**
* @brief Construct a PocoJsonObject referencing a specific PocoJson
* value.
*
* @param value reference to a PocoJson value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
PocoJsonObject(const Poco::Dynamic::Var &value)
: value(value)
{
if (value.type() != typeid(Poco::JSON::Object::Ptr)) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying PocoJson implementation.
*/
PocoJsonObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying PocoJson implementation.
*/
PocoJsonObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param propertyName property name to search for
*/
PocoJsonObjectMemberIterator find(const std::string &propertyName) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return value.extract<Poco::JSON::Object::Ptr>()->size();
}
private:
/**
* @brief Return a PocoJson value that is empty object.
*/
static Poco::Dynamic::Var emptyObject()
{
Poco::Dynamic::Var object = Poco::JSON::Object::Ptr();
return object;
}
/// Contained value
Poco::Dynamic::Var value;
};
/**
* @brief Stores an independent copy of a PocoJson value.
*
* This class allows a PocoJson value to be stored independent of its original
* document. PocoJson makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class PocoJsonFrozenValue : public FrozenValue
{
public:
/**
* @brief Make a copy of a PocoJson value
*
* @param source the PocoJson value to be copied
*/
explicit PocoJsonFrozenValue(const Poco::Dynamic::Var &source)
: value(source)
{ }
virtual FrozenValue * clone() const
{
return new PocoJsonFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored PocoJson value
Poco::Dynamic::Var value;
};
/**
* @brief Light weight wrapper for a PocoJson value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a PocoJson value. This class is responsible
* for the mechanics of actually reading a PocoJson value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class PocoJsonValue
{
public:
/// Construct a wrapper for the empty object
PocoJsonValue()
: value(emptyObject())
{ }
/// Construct a wrapper for a specific PocoJson value
PocoJsonValue(const Poco::Dynamic::Var& value)
: value(value)
{ }
/**
* @brief Create a new PocoJsonFrozenValue instance that contains the
* value referenced by this PocoJsonValue instance.
*
* @returns pointer to a new PocoJsonFrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new PocoJsonFrozenValue(value);
}
/**
* @brief Optionally return a PocoJsonArray instance.
*
* If the referenced PocoJson value is an array, this function will return
* a std::optional containing a PocoJsonArray instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PocoJsonArray> getArrayOptional() const
{
if (value.type() == typeid(Poco::JSON::Array::Ptr)) {
return opt::make_optional(PocoJsonArray(value));
}
return opt::optional<PocoJsonArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced PocoJson value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.type() == typeid(Poco::JSON::Array::Ptr)) {
result = value.extract<Poco::JSON::Array::Ptr>()->size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.isBoolean()) {
result = value.convert<bool>();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.isNumeric() && !value.isInteger()) {
result = value.convert<double>();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if (value.isInteger()) {
result = value.convert<int>();
return true;
}
return false;
}
/**
* @brief Optionally return a PocoJsonObject instance.
*
* If the referenced PocoJson value is an object, this function will return a
* std::optional containing a PocoJsonObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PocoJsonObject> getObjectOptional() const
{
if (value.type() == typeid(Poco::JSON::Object::Ptr)) {
return opt::make_optional(PocoJsonObject(value));
}
return opt::optional<PocoJsonObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced PocoJson value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.type() == typeid(Poco::JSON::Object::Ptr)) {
result = value.extract<Poco::JSON::Object::Ptr>()->size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.isString()) {
result = value.convert<std::string>();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.type() == typeid(Poco::JSON::Array::Ptr);
}
bool isBool() const
{
return value.isBoolean();
}
bool isDouble() const
{
return value.isNumeric() && !value.isInteger();
}
bool isInteger() const
{
return !isBool() && value.isInteger();
}
bool isNull() const
{
return value.isEmpty();
}
bool isNumber() const
{
return value.isNumeric();
}
bool isObject() const
{
return value.type() == typeid(Poco::JSON::Object::Ptr);
}
bool isString() const
{
return value.isString();
}
private:
/// Return an empty object
static Poco::Dynamic::Var emptyObject()
{
Poco::Dynamic::Var object = Poco::JSON::Object::Ptr();
return object;
}
/// Contained value
Poco::Dynamic::Var value;
};
/**
* @brief An implementation of the Adapter interface supporting PocoJson.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class PocoJsonAdapter :
public BasicAdapter<PocoJsonAdapter,
PocoJsonArray,
PocoJsonObjectMember,
PocoJsonObject,
PocoJsonValue>
{
public:
/// Construct a PocoJsonAdapter that contains an empty object
PocoJsonAdapter()
: BasicAdapter()
{ }
/// Construct a PocoJsonAdapter containing a specific Poco Json object
PocoJsonAdapter(const Poco::Dynamic::Var &value)
: BasicAdapter(PocoJsonValue {value})
{ }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* PocoJsonAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template.
*
* @see PocoJsonArray
*/
class PocoJsonArrayValueIterator :
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PocoJsonAdapter> // value type
{
public:
/**
* @brief Construct a new PocoJsonArrayValueIterator using an existing
* PocoJson iterator.
*
* @param itr PocoJson iterator to store
*/
PocoJsonArrayValueIterator(const Poco::JSON::Array::ConstIterator &itr)
: itr(itr)
{ }
/// Returns a PocoJsonAdapter that contains the value of the current
/// element.
PocoJsonAdapter operator*() const
{
return PocoJsonAdapter(*itr);
}
DerefProxy<PocoJsonAdapter> operator->() const
{
return DerefProxy<PocoJsonAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const PocoJsonArrayValueIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const PocoJsonArrayValueIterator &other) const
{
return !(itr == other.itr);
}
const PocoJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
PocoJsonArrayValueIterator operator++(int)
{
PocoJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PocoJsonArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
private:
Poco::JSON::Array::ConstIterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of PocoJsonObjectMember representing one of the members of the object. It
* has been implemented using the boost iterator_facade template.
*
* @see PocoJsonObject
* @see PocoJsonObjectMember
*/
class PocoJsonObjectMemberIterator :
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PocoJsonObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a PocoJson iterator.
*
* @param itr PocoJson iterator to store
*/
PocoJsonObjectMemberIterator(const Poco::JSON::Object::ConstIterator &itr)
: itr(itr)
{ }
/**
* @brief Returns a PocoJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
PocoJsonObjectMember operator*() const
{
return PocoJsonObjectMember(itr->first, itr->second);
}
DerefProxy<PocoJsonObjectMember> operator->() const
{
return DerefProxy<PocoJsonObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const PocoJsonObjectMemberIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const PocoJsonObjectMemberIterator &other) const
{
return !(itr == other.itr);
}
const PocoJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
PocoJsonObjectMemberIterator operator++(int)
{
PocoJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PocoJsonObjectMemberIterator& operator--()
{
itr--;
return *this;
}
private:
/// Iternal copy of the original PocoJson iterator
Poco::JSON::Object::ConstIterator itr;
};
/// Specialisation of the AdapterTraits template struct for PocoJsonAdapter.
template<>
struct AdapterTraits<valijson::adapters::PocoJsonAdapter>
{
typedef Poco::Dynamic::Var DocumentType;
static std::string adapterName()
{
return "PocoJsonAdapter";
}
};
inline PocoJsonArrayValueIterator PocoJsonArray::begin() const
{
return value.extract<Poco::JSON::Array::Ptr>()->begin();
}
inline PocoJsonArrayValueIterator PocoJsonArray::end() const
{
return value.extract<Poco::JSON::Array::Ptr>()->end();
}
inline PocoJsonObjectMemberIterator PocoJsonObject::begin() const
{
return value.extract<Poco::JSON::Object::Ptr>()->begin();
}
inline PocoJsonObjectMemberIterator PocoJsonObject::end() const
{
return value.extract<Poco::JSON::Object::Ptr>()->end();
}
inline PocoJsonObjectMemberIterator PocoJsonObject::find(
const std::string &propertyName) const
{
auto& ptr = value.extract<Poco::JSON::Object::Ptr>();
auto it = std::find_if(ptr->begin(), ptr->end(),
[&propertyName](const Poco::JSON::Object::ValueType& p)
{
return p.first == propertyName;
});
return it;
}
inline bool PocoJsonFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return PocoJsonAdapter(value).equalTo(other, strict);
}
} // namespace adapters
} // namespace valijson
#endif // __VALIJSON_ADAPTERS_POCO_JSON_ADAPTER_HPP

757
3rdparty/valijson/adapters/property_tree_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,757 @@
/**
* @file
*
* @brief Adapter implementation for the Boost property tree library.
*
* Include this file in your program to enable support for boost property trees.
*
* This file defines the following classes (not in this order):
* - PropertyTreeAdapter
* - PropertyTreeArray
* - PropertyTreeArrayValueIterator
* - PropertyTreeFrozenValue
* - PropertyTreeObject
* - PropertyTreeObjectMember
* - PropertyTreeObjectMemberIterator
* - PropertyTreeValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is PropertyTreeAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_PROPERTY_TREE_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_PROPERTY_TREE_ADAPTER_HPP
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class PropertyTreeAdapter;
class PropertyTreeArrayValueIterator;
class PropertyTreeObjectMemberIterator;
typedef std::pair<std::string, PropertyTreeAdapter> PropertyTreeObjectMember;
/**
* @brief Light weight wrapper for a Boost property tree that contains
* array-like data.
*
* This class is light weight wrapper for a Boost property tree. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to a Boost property
* tree that is assumed to contain unnamed key-value pairs. There is very little
* associated with copy construction and passing by value.
*/
class PropertyTreeArray
{
public:
typedef PropertyTreeArrayValueIterator const_iterator;
typedef PropertyTreeArrayValueIterator iterator;
/// Construct a PropertyTreeArra7 referencing an empty property tree
/// singleton.
PropertyTreeArray()
: array(emptyTree()) { }
/**
* @brief Construct PropertyTreeArray referencing a specific Boost
* property tree.
*
* @param array reference to a property tree containing an array
*
* It is assumed that this value contains array-like data, but this is not
* checked due to runtime cost.
*/
explicit PropertyTreeArray(const boost::property_tree::ptree &array)
: array(array) { }
/// Return an iterator for the first element in the array.
PropertyTreeArrayValueIterator begin() const;
/// Return an iterator for one-past the last element of the array.
PropertyTreeArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return array.size();
}
private:
/**
* @brief Return a reference to a property tree that looks like an
* empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const boost::property_tree::ptree & emptyTree()
{
static const boost::property_tree::ptree tree;
return tree;
}
/// Reference to the contained value
const boost::property_tree::ptree &array;
};
/**
* @brief Light weight wrapper for a Boost property tree that contains
* object-like data.
*
* This class is light weight wrapper for a Boost property tree. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* property tree value, assumed to be object-like, so there is very little
* overhead associated with copy construction and passing by value.
*/
class PropertyTreeObject
{
public:
typedef PropertyTreeObjectMemberIterator const_iterator;
typedef PropertyTreeObjectMemberIterator iterator;
/// Construct a PropertyTreeObject referencing an empty property tree.
PropertyTreeObject()
: object(emptyTree()) { }
/**
* @brief Construct a PropertyTreeObject referencing a specific property
* tree.
*
* @param object reference to a property tree containing an object
*
* Note that the value of the property tree is not checked, due to the
* runtime cost of doing so.
*/
PropertyTreeObject(const boost::property_tree::ptree &object)
: object(object) { }
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying property tree
* implementation.
*/
PropertyTreeObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the pointer value returned by the underlying property tree
* implementation.
*/
PropertyTreeObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param property property name to search for
*/
PropertyTreeObjectMemberIterator find(const std::string &property) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return object.size();
}
private:
/**
* @brief Return a reference to an empty property tree.
*
* Note that the value returned by this function is a singleton.
*/
static const boost::property_tree::ptree & emptyTree()
{
static const boost::property_tree::ptree tree;
return tree;
}
/// Reference to the contained object
const boost::property_tree::ptree &object;
};
/**
* @brief Stores an independent copy of a Boost property tree.
*
* This class allows a property tree value to be stored independent of its
* original 'document'. Boost property trees make this easy to do, as they do
* not perform any custom memory management.
*
* @see FrozenValue
*/
class PropertyTreeFrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a Boost property tree POD value
*
* @param source string containing the POD vlaue
*/
explicit PropertyTreeFrozenValue(
const boost::property_tree::ptree::data_type &source)
: value(source) { }
/**
* @brief Make a copy of a Boost property tree object or array value
*
* @param source the property tree to be copied
*/
explicit PropertyTreeFrozenValue(
const boost::property_tree::ptree &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new PropertyTreeFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored value
boost::property_tree::ptree value;
};
/**
* @brief Light weight wrapper for a Boost property tree.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a Boost property tree value. This class
* is responsible for the mechanics of actually reading a property tree, whereas
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class PropertyTreeValue
{
public:
/// Construct a wrapper for an empty property tree
PropertyTreeValue()
: object(emptyTree()) { }
/**
* @brief Construct a PropertyTreeValue from a tree object
*
* This function will determine whether the tree object represents an array
* or an object by scanning the key names for any non-empty strings. In the
* case of an empty tree object, it is not possible to determine whether it
* is an array or an object, so it will be treated as an array by default.
* Empty arrays are considered equal to empty objects when compared using
* non-strict type comparison. Empty strings will also be stored as empty
* arrays.
*
* @param tree Tree object to be wrapped
*/
PropertyTreeValue(const boost::property_tree::ptree &tree)
{
if (tree.data().empty()) { // No string content
if (tree.size() == 0) { // No children
array.emplace(tree); // Treat as empty array
} else {
bool isArray = true;
boost::property_tree::ptree::const_iterator itr;
for (itr = tree.begin(); itr != tree.end(); itr++) {
if (!itr->first.empty()) {
isArray = false;
break;
}
}
if (isArray) {
array.emplace(tree);
} else {
object.emplace(tree);
}
}
} else {
value = tree.data();
}
}
/**
* @brief Create a new PropertyTreeFrozenValue instance that contains the
* value referenced by this PropertyTreeValue instance.
*
* @returns pointer to a new PropertyTreeFrozenValue instance, belonging to
* the caller.
*/
FrozenValue* freeze() const
{
if (array) {
return new PropertyTreeFrozenValue(*array);
} else if (object) {
return new PropertyTreeFrozenValue(*object);
} else {
return new PropertyTreeFrozenValue(*value);
}
}
/**
* @brief Return an instance of PropertyTreeArrayAdapter.
*
* If the referenced property tree value is an array, this function will
* return a std::optional containing a PropertyTreeArray instance
* referencing the array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PropertyTreeArray> getArrayOptional() const
{
if (array) {
return opt::make_optional(PropertyTreeArray(*array));
}
return opt::optional<PropertyTreeArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced property tree value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (array) {
result = array->size();
return true;
}
return false;
}
bool getBool(bool &) const
{
return false;
}
bool getDouble(double &) const
{
return false;
}
bool getInteger(int64_t &) const
{
return false;
}
/**
* @brief Optionally return a PropertyTreeObject instance.
*
* If the referenced property tree is an object, this function will return a
* std::optional containing a PropertyTreeObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<PropertyTreeObject> getObjectOptional() const
{
if (object) {
return opt::make_optional(PropertyTreeObject(*object));
}
return opt::optional<PropertyTreeObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced property tree value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (object) {
result = object->size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value) {
result = *value;
return true;
}
return false;
}
static bool hasStrictTypes()
{
return false;
}
bool isArray() const
{
return static_cast<bool>(array);
}
bool isBool() const
{
return false;
}
bool isDouble() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isNull() const
{
return false;
}
bool isNumber() const
{
return false;
}
bool isObject() const
{
return static_cast<bool>(object);
}
bool isString() const
{
return static_cast<bool>(value);
}
private:
static const boost::property_tree::ptree & emptyTree()
{
static const boost::property_tree::ptree tree;
return tree;
}
/// Reference used if the value is known to be an array
opt::optional<const boost::property_tree::ptree &> array;
/// Reference used if the value is known to be an object
opt::optional<const boost::property_tree::ptree &> object;
/// Reference used if the value is known to be a POD type
opt::optional<std::string> value;
};
/**
* @brief An implementation of the Adapter interface supporting the Boost
* property tree library.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class PropertyTreeAdapter:
public BasicAdapter<PropertyTreeAdapter,
PropertyTreeArray,
PropertyTreeObjectMember,
PropertyTreeObject,
PropertyTreeValue>
{
public:
/// Construct a PropertyTreeAdapter for an empty property tree
PropertyTreeAdapter()
: BasicAdapter() { }
/// Construct a PropertyTreeAdapter using a specific property tree
PropertyTreeAdapter(const boost::property_tree::ptree &value)
: BasicAdapter(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* PropertyTreeAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template.
*
* @see PropertyTreeArray
*/
class PropertyTreeArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PropertyTreeAdapter> // value type
{
public:
/**
* @brief Construct a new PropertyTreeArrayValueIterator using an existing
* property tree iterator.
*
* @param itr property tree iterator to store
*/
PropertyTreeArrayValueIterator(
const boost::property_tree::ptree::const_iterator &itr)
: itr(itr) { }
/// Returns a PropertyTreeAdapter that contains the value of the current
/// element.
PropertyTreeAdapter operator*() const
{
return PropertyTreeAdapter(itr->second);
}
DerefProxy<PropertyTreeAdapter> operator->() const
{
return DerefProxy<PropertyTreeAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param rhs iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const PropertyTreeArrayValueIterator &rhs) const
{
return itr == rhs.itr;
}
bool operator!=(const PropertyTreeArrayValueIterator &rhs) const
{
return !(itr == rhs.itr);
}
const PropertyTreeArrayValueIterator& operator++()
{
itr++;
return *this;
}
PropertyTreeArrayValueIterator operator++(int)
{
PropertyTreeArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PropertyTreeArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
if (n > 0) {
while (n-- > 0) {
itr++;
}
} else {
while (n++ < 0) {
itr--;
}
}
}
private:
boost::property_tree::ptree::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of PropertyTreeObjectMember representing one of the members of the object.
* It has been implemented using the boost iterator_facade template.
*
* @see PropertyTreeObject
* @see PropertyTreeObjectMember
*/
class PropertyTreeObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
PropertyTreeObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a PropertyTree iterator.
*
* @param itr PropertyTree iterator to store
*/
PropertyTreeObjectMemberIterator(
boost::property_tree::ptree::const_assoc_iterator itr)
: itr(itr) { }
/**
* @brief Returns a PropertyTreeObjectMember that contains the key and
* value belonging to the object member identified by the iterator.
*/
PropertyTreeObjectMember operator*() const
{
return PropertyTreeObjectMember(itr->first, itr->second);
}
DerefProxy<PropertyTreeObjectMember> operator->() const
{
return DerefProxy<PropertyTreeObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param rhs Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const PropertyTreeObjectMemberIterator &rhs) const
{
return itr == rhs.itr;
}
bool operator!=(const PropertyTreeObjectMemberIterator &rhs) const
{
return !(itr == rhs.itr);
}
const PropertyTreeObjectMemberIterator& operator++()
{
itr++;
return *this;
}
PropertyTreeObjectMemberIterator operator++(int)
{
PropertyTreeObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PropertyTreeObjectMemberIterator& operator--()
{
itr--;
return *this;
}
private:
boost::property_tree::ptree::const_assoc_iterator itr;
};
/// Specialisation of the AdapterTraits template struct for PropertyTreeAdapter.
template<>
struct AdapterTraits<valijson::adapters::PropertyTreeAdapter>
{
typedef boost::property_tree::ptree DocumentType;
static std::string adapterName()
{
return "PropertyTreeAdapter";
}
};
inline bool PropertyTreeFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return PropertyTreeAdapter(value).equalTo(other, strict);
}
inline PropertyTreeArrayValueIterator PropertyTreeArray::begin() const
{
return array.begin();
}
inline PropertyTreeArrayValueIterator PropertyTreeArray::end() const
{
return array.end();
}
inline PropertyTreeObjectMemberIterator PropertyTreeObject::begin() const
{
return object.ordered_begin();
}
inline PropertyTreeObjectMemberIterator PropertyTreeObject::end() const
{
return object.not_found();
}
inline PropertyTreeObjectMemberIterator PropertyTreeObject::find(
const std::string &propertyName) const
{
const boost::property_tree::ptree::const_assoc_iterator
itr = object.find(propertyName);
if (itr != object.not_found()) {
return itr;
}
return object.not_found();
}
} // namespace adapters
} // namespace valijson
#endif

725
3rdparty/valijson/adapters/qtjson_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,725 @@
/**
* @file
*
* @brief Adapter implementation for the QtJson parser library.
*
* Include this file in your program to enable support for QtJson.
*
* This file defines the following classes (not in this order):
* - QtJsonAdapter
* - QtJsonArray
* - QtJsonArrayValueIterator
* - QtJsonFrozenValue
* - QtJsonObject
* - QtJsonObjectMember
* - QtJsonObjectMemberIterator
* - QtJsonValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is QtJsonAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_QTJSON_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_QTJSON_ADAPTER_HPP
#include <string>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
class QtJsonAdapter;
class QtJsonArrayValueIterator;
class QtJsonObjectMemberIterator;
typedef std::pair<std::string, QtJsonAdapter> QtJsonObjectMember;
/**
* @brief Light weight wrapper for a QtJson array value.
*
* This class is light weight wrapper for a QtJson array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* QtJson value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
class QtJsonArray
{
public:
typedef QtJsonArrayValueIterator const_iterator;
typedef QtJsonArrayValueIterator iterator;
/// Construct a QtJsonArray referencing an empty array.
QtJsonArray()
: value(emptyArray())
{
}
/**
* @brief Construct a QtJsonArray referencing a specific QtJson
* value.
*
* @param value reference to a QtJson value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
explicit QtJsonArray(const QJsonValue &value)
: value(value.toArray())
{
if (!value.isArray()) {
throw std::runtime_error("Value is not an array.");
}
}
/**
* @brief Return an iterator for the first element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying QtJson implementation.
*/
QtJsonArrayValueIterator begin() const;
/**
* @brief Return an iterator for one-past the last element of the array.
*
* The iterator return by this function is effectively the iterator
* returned by the underlying QtJson implementation.
*/
QtJsonArrayValueIterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return value.size();
}
private:
/**
* @brief Return a reference to a QtJson value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const QJsonArray emptyArray()
{
static const QJsonArray array;
return array;
}
/// Reference to the contained value
const QJsonArray value;
};
/**
* @brief Light weight wrapper for a QtJson object.
*
* This class is light weight wrapper for a QtJson object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* QtJson value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
class QtJsonObject
{
public:
typedef QtJsonObjectMemberIterator const_iterator;
typedef QtJsonObjectMemberIterator iterator;
/// Construct a QtJsonObject referencing an empty object singleton.
QtJsonObject()
: value(emptyObject())
{
}
/**
* @brief Construct a QtJsonObject referencing a specific QtJson
* value.
*
* @param value reference to a QtJson value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
QtJsonObject(const QJsonValue &value)
: value(value.toObject())
{
if (!value.isObject()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying QtJson implementation.
*/
QtJsonObjectMemberIterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the iterator value returned by the underlying QtJson implementation.
*/
QtJsonObjectMemberIterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param propertyName property name to search for
*/
QtJsonObjectMemberIterator find(const std::string &propertyName) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return value.size();
}
private:
/**
* @brief Return a reference to a QtJson value that is empty object.
*
* Note that the value returned by this function is a singleton.
*/
static const QJsonObject emptyObject()
{
static const QJsonObject object;
return object;
}
/// Reference to the contained object
const QJsonObject value;
};
/**
* @brief Stores an independent copy of a QtJson value.
*
* This class allows a QtJson value to be stored independent of its original
* document. QtJson makes this easy to do, as it does not perform any
* custom memory management.
*
* @see FrozenValue
*/
class QtJsonFrozenValue: public FrozenValue
{
public:
/**
* @brief Make a copy of a QtJson value
*
* @param source the QtJson value to be copied
*/
explicit QtJsonFrozenValue(const QJsonValue &source)
: value(source) { }
virtual FrozenValue * clone() const
{
return new QtJsonFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/// Stored QtJson value
QJsonValue value;
};
/**
* @brief Light weight wrapper for a QtJson value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a QtJson value. This class is responsible
* for the mechanics of actually reading a QtJson value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
class QtJsonValue
{
public:
/// Construct a wrapper for the empty object singleton
QtJsonValue()
: value(emptyObject()) { }
/// Construct a wrapper for a specific QtJson value
QtJsonValue(const QJsonValue &value)
: value(value) { }
/**
* @brief Create a new QtJsonFrozenValue instance that contains the
* value referenced by this QtJsonValue instance.
*
* @returns pointer to a new QtJsonFrozenValue instance, belonging to the
* caller.
*/
FrozenValue * freeze() const
{
return new QtJsonFrozenValue(value);
}
/**
* @brief Optionally return a QtJsonArray instance.
*
* If the referenced QtJson value is an array, this function will return
* a std::optional containing a QtJsonArray instance referencing the
* array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<QtJsonArray> getArrayOptional() const
{
if (value.isArray()) {
return opt::make_optional(QtJsonArray(value));
}
return opt::optional<QtJsonArray>();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced QtJson value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.isArray()) {
const QJsonArray array = value.toArray();
result = array.size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.isBool()) {
result = value.toBool();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.isDouble()) {
result = value.toDouble();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if (value.isDouble()) {
result = value.toInt();
return true;
}
return false;
}
/**
* @brief Optionally return a QtJsonObject instance.
*
* If the referenced QtJson value is an object, this function will return a
* std::optional containing a QtJsonObject instance referencing the
* object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<QtJsonObject> getObjectOptional() const
{
if (value.isObject()) {
return opt::make_optional(QtJsonObject(value));
}
return opt::optional<QtJsonObject>();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced QtJson value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.isObject()) {
const QJsonObject &object = value.toObject();
result = object.size();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.isString()) {
result = value.toString().toStdString();
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.isArray();
}
bool isBool() const
{
return value.isBool();
}
bool isDouble() const
{
return value.isDouble();
}
bool isInteger() const
{
//toInt returns the default value (0, 1) if the value is not a whole number
return value.isDouble() && (value.toInt(0) == value.toInt(1));
}
bool isNull() const
{
return value.isNull();
}
bool isNumber() const
{
return value.isDouble();
}
bool isObject() const
{
return value.isObject();
}
bool isString() const
{
return value.isString();
}
private:
/// Return a reference to an empty object singleton
static const QJsonValue emptyObject()
{
static const QJsonValue object;
return object;
}
/// Reference to the contained QtJson value.
const QJsonValue value;
};
/**
* @brief An implementation of the Adapter interface supporting QtJson.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
class QtJsonAdapter:
public BasicAdapter<QtJsonAdapter,
QtJsonArray,
QtJsonObjectMember,
QtJsonObject,
QtJsonValue>
{
public:
/// Construct a QtJsonAdapter that contains an empty object
QtJsonAdapter()
: BasicAdapter() { }
/// Construct a QtJsonAdapter containing a specific QtJson value
QtJsonAdapter(const QJsonValue &value)
: BasicAdapter(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* QtJsonAdapter representing a value stored in the array. It has been
* implemented using the std::iterator template.
*
* @see QtJsonArray
*/
class QtJsonArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
QtJsonAdapter> // value type
{
public:
/**
* @brief Construct a new QtJsonArrayValueIterator using an existing
* QtJson iterator.
*
* @param itr QtJson iterator to store
*/
QtJsonArrayValueIterator(
const QJsonArray::const_iterator &itr)
: itr(itr) { }
/// Returns a QtJsonAdapter that contains the value of the current
/// element.
QtJsonAdapter operator*() const
{
return QtJsonAdapter(*itr);
}
DerefProxy<QtJsonAdapter> operator->() const
{
return DerefProxy<QtJsonAdapter>(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const QtJsonArrayValueIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const QtJsonArrayValueIterator &other) const
{
return !(itr == other.itr);
}
const QtJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
QtJsonArrayValueIterator operator++(int)
{
QtJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const QtJsonArrayValueIterator& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
private:
QJsonArray::const_iterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of QtJsonObjectMember representing one of the members of the object. It
* has been implemented using the boost iterator_facade template.
*
* @see QtJsonObject
* @see QtJsonObjectMember
*/
class QtJsonObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
QtJsonObjectMember> // value type
{
public:
/**
* @brief Construct an iterator from a QtJson iterator.
*
* @param itr QtJson iterator to store
*/
QtJsonObjectMemberIterator(
const QJsonObject::const_iterator &itr)
: itr(itr) { }
/**
* @brief Returns a QtJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator.
*/
QtJsonObjectMember operator*() const
{
std::string key = itr.key().toStdString();
return QtJsonObjectMember(key, itr.value());
}
DerefProxy<QtJsonObjectMember> operator->() const
{
return DerefProxy<QtJsonObjectMember>(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const QtJsonObjectMemberIterator &other) const
{
return itr == other.itr;
}
bool operator!=(const QtJsonObjectMemberIterator &other) const
{
return !(itr == other.itr);
}
const QtJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
QtJsonObjectMemberIterator operator++(int)
{
QtJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const QtJsonObjectMemberIterator& operator--(int)
{
itr--;
return *this;
}
private:
/// Iternal copy of the original QtJson iterator
QJsonObject::const_iterator itr;
};
/// Specialisation of the AdapterTraits template struct for QtJsonAdapter.
template<>
struct AdapterTraits<valijson::adapters::QtJsonAdapter>
{
typedef QJsonValue DocumentType;
static std::string adapterName()
{
return "QtJsonAdapter";
}
};
inline bool QtJsonFrozenValue::equalTo(const Adapter &other, bool strict) const
{
return QtJsonAdapter(value).equalTo(other, strict);
}
inline QtJsonArrayValueIterator QtJsonArray::begin() const
{
return value.begin();
}
inline QtJsonArrayValueIterator QtJsonArray::end() const
{
return value.end();
}
inline QtJsonObjectMemberIterator QtJsonObject::begin() const
{
return value.begin();
}
inline QtJsonObjectMemberIterator QtJsonObject::end() const
{
return value.end();
}
inline QtJsonObjectMemberIterator QtJsonObject::find(
const std::string &propertyName) const
{
return value.find(QString::fromStdString(propertyName));
}
} // namespace adapters
} // namespace valijson
#endif

933
3rdparty/valijson/adapters/rapidjson_adapter.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,933 @@
/**
* @file
*
* @brief Adapter implementation for the RapidJson parser library.
*
* Include this file in your program to enable support for RapidJson.
*
* This file defines the following template classes (not in this order):
* - GenericRapidJsonAdapter
* - GenericRapidJsonArray
* - GenericRapidJsonArrayValueIterator
* - GenericRapidJsonFrozenValue
* - GenericRapidJsonObject
* - GenericRapidJsonObjectMember
* - GenericRapidJsonObjectMemberIterator
* - GenericRapidJsonValue
*
* All of these classes share a template argument called 'ValueType', which can
* be used to choose the underlying the RapidJson value type that is used. This
* allows different RapidJson encodings and allocators to be used.
*
* This file also defines the following typedefs, which use RapidJson's default
* ValueType:
* - RapidJsonAdapter
* - RapidJsonArray
* - RapidJsonArrayValueIterator
* - RapidJsonFrozenValue
* - RapidJsonObject
* - RapidJsonObjectMember
* - RapidJsonObjectMemberIterator
* - RapidJsonValue
*
* Due to the dependencies that exist between these classes, the ordering of
* class declarations and definitions may be a bit confusing. The best place to
* start is RapidJsonAdapter. This class definition is actually very small,
* since most of the functionality is inherited from the BasicAdapter class.
* Most of the classes in this file are provided as template arguments to the
* inherited BasicAdapter class.
*/
#pragma once
#ifndef __VALIJSON_ADAPTERS_RAPIDJSON_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_RAPIDJSON_ADAPTER_HPP
#include <string>
#include <iterator>
#include <rapidjson/document.h>
#include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp>
#include <valijson/adapters/frozen_value.hpp>
namespace valijson {
namespace adapters {
template<class ValueType = rapidjson::Value>
class GenericRapidJsonAdapter;
template<class ValueType = rapidjson::Value>
class GenericRapidJsonArrayValueIterator;
template<class ValueType = rapidjson::Value>
class GenericRapidJsonObjectMemberIterator;
/// Container for a property name and an associated RapidJson value
template<class ValueType = rapidjson::Value>
class GenericRapidJsonObjectMember :
public std::pair<std::string, GenericRapidJsonAdapter<ValueType> >
{
private:
typedef std::pair<std::string, GenericRapidJsonAdapter<ValueType> > Super;
public:
GenericRapidJsonObjectMember(
const std::string &name,
const GenericRapidJsonAdapter<ValueType> &value)
: Super(name, value) { }
};
/**
* @brief Light weight wrapper for a RapidJson array value.
*
* This class is light weight wrapper for a RapidJson array. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to an underlying
* RapidJson value, assumed to be an array, so there is very little overhead
* associated with copy construction and passing by value.
*/
template<class ValueType = rapidjson::Value>
class GenericRapidJsonArray
{
public:
typedef GenericRapidJsonArrayValueIterator<ValueType> const_iterator;
typedef GenericRapidJsonArrayValueIterator<ValueType> iterator;
/// Construct a RapidJsonArray referencing an empty array singleton.
GenericRapidJsonArray()
: value(emptyArray()) { }
/**
* @brief Construct a RapidJsonArray referencing a specific RapidJson
* value.
*
* @param value reference to a RapidJson value
*
* Note that this constructor will throw an exception if the value is not
* an array.
*/
GenericRapidJsonArray(const ValueType &value)
: value(value)
{
if (!value.IsArray()) {
throw std::runtime_error("Value is not an array.");
}
}
/// Return an iterator for the first element in the array.
iterator begin() const;
/// Return an iterator for one-past the last element of the array.
iterator end() const;
/// Return the number of elements in the array
size_t size() const
{
return value.Size();
}
private:
/**
* @brief Return a reference to a RapidJson value that is an empty array.
*
* Note that the value returned by this function is a singleton.
*/
static const ValueType & emptyArray()
{
static const ValueType array(rapidjson::kArrayType);
return array;
}
/// Reference to the contained value
const ValueType &value;
};
/**
* @brief Light weight wrapper for a RapidJson object.
*
* This class is light weight wrapper for a RapidJson object. It provides a
* minimum set of container functions and typedefs that allow it to be used as
* an iterable container.
*
* An instance of this class contains a single reference to the underlying
* RapidJson value, assumed to be an object, so there is very little overhead
* associated with copy construction and passing by value.
*/
template <class ValueType = rapidjson::Value>
class GenericRapidJsonObject
{
public:
typedef GenericRapidJsonObjectMemberIterator<ValueType> const_iterator;
typedef GenericRapidJsonObjectMemberIterator<ValueType> iterator;
/// Construct a GenericRapidJsonObject referencing an empty object singleton.
GenericRapidJsonObject()
: value(emptyObject()) { }
/**
* @brief Construct a GenericRapidJsonObject referencing a specific
* RapidJson value.
*
* @param value reference to a RapidJson value
*
* Note that this constructor will throw an exception if the value is not
* an object.
*/
GenericRapidJsonObject(const ValueType &value)
: value(value)
{
if (!value.IsObject()) {
throw std::runtime_error("Value is not an object.");
}
}
/**
* @brief Return an iterator for this first object member
*
* The iterator return by this function is effectively a wrapper around
* the pointer value returned by the underlying RapidJson implementation.
*/
iterator begin() const;
/**
* @brief Return an iterator for an invalid object member that indicates
* the end of the collection.
*
* The iterator return by this function is effectively a wrapper around
* the pointer value returned by the underlying RapidJson implementation.
*/
iterator end() const;
/**
* @brief Return an iterator for the object member with the specified
* property name.
*
* If an object member with the specified name does not exist, the iterator
* returned will be the same as the iterator returned by the end() function.
*
* @param property property name to search for
*/
iterator find(const std::string &property) const;
/// Returns the number of members belonging to this object.
size_t size() const
{
return value.MemberEnd() - value.MemberBegin();
}
private:
/**
* @brief Return a reference to a RapidJson value that is empty object.
*
* Note that the value returned by this function is a singleton.
*/
static const ValueType & emptyObject()
{
static ValueType object(rapidjson::kObjectType);
return object;
}
/// Reference to the contained object
const ValueType &value;
};
/**
* @brief Stores an independent copy of a RapidJson value.
*
* This class allows a RapidJson value to be stored independent of its original
* document. RapidJson makes this a bit harder than usual, because RapidJson
* values are associated with a custom memory allocator. As such, RapidJson
* values have to be copied recursively, referencing a custom allocator held
* by this class.
*
* @see FrozenValue
*/
template<class ValueType = rapidjson::Value>
class GenericRapidJsonFrozenValue: public FrozenValue
{
public:
explicit GenericRapidJsonFrozenValue(const char *str)
{
value.SetString(str, allocator);
}
explicit GenericRapidJsonFrozenValue(const std::string &str)
{
value.SetString(str.c_str(), (unsigned int)str.length(), allocator);
}
/**
* @brief Make a copy of a RapidJson value
*
* @param source the RapidJson value to be copied
*/
explicit GenericRapidJsonFrozenValue(const ValueType &source)
{
if (!copy(source, value, allocator)) {
throw std::runtime_error("Failed to copy ValueType");
}
}
virtual FrozenValue * clone() const
{
return new GenericRapidJsonFrozenValue(value);
}
virtual bool equalTo(const Adapter &other, bool strict) const;
private:
/**
* @brief Recursively copy a RapidJson value using a separate allocator
*
* @param source value to copy from
* @param dest value to copy into
* @param allocator reference to an allocator held by this class
*
* @tparam Allocator type of RapidJson Allocator to be used
*
* @returns true if copied successfully, false otherwise.
*/
template<typename Allocator>
static bool copy(const ValueType &source,
ValueType &dest,
Allocator &allocator)
{
switch (source.GetType()) {
case rapidjson::kNullType:
dest.SetNull();
return true;
case rapidjson::kFalseType:
dest.SetBool(false);
return true;
case rapidjson::kTrueType:
dest.SetBool(true);
return true;
case rapidjson::kObjectType:
dest.SetObject();
for (typename ValueType::ConstMemberIterator itr = source.MemberBegin();
itr != source.MemberEnd(); ++itr) {
ValueType name(itr->name.GetString(), itr->name.GetStringLength(), allocator);
ValueType value;
copy(itr->value, value, allocator);
dest.AddMember(name, value, allocator);
}
return true;
case rapidjson::kArrayType:
dest.SetArray();
for (typename ValueType::ConstValueIterator itr = source.Begin(); itr != source.End(); ++itr) {
ValueType value;
copy(*itr, value, allocator);
dest.PushBack(value, allocator);
}
return true;
case rapidjson::kStringType:
dest.SetString(source.GetString(), source.GetStringLength(), allocator);
return true;
case rapidjson::kNumberType:
if (source.IsInt()) {
dest.SetInt(source.GetInt());
} else if (source.IsUint()) {
dest.SetUint(source.GetUint());
} else if (source.IsInt64()) {
dest.SetInt64(source.GetInt64());
} else if (source.IsUint64()) {
dest.SetUint64(source.GetUint64());
} else {
dest.SetDouble(source.GetDouble());
}
return true;
default:
break;
}
return false;
}
/// Local memory allocator for RapidJson value
typename ValueType::AllocatorType allocator;
/// Local RapidJson value
ValueType value;
};
/**
* @brief Light weight wrapper for a RapidJson value.
*
* This class is passed as an argument to the BasicAdapter template class,
* and is used to provide access to a RapidJson value. This class is responsible
* for the mechanics of actually reading a RapidJson value, whereas the
* BasicAdapter class is responsible for the semantics of type comparisons
* and conversions.
*
* The functions that need to be provided by this class are defined implicitly
* by the implementation of the BasicAdapter template class.
*
* @see BasicAdapter
*/
template<class ValueType = rapidjson::Value>
class GenericRapidJsonValue
{
public:
/// Construct a wrapper for the empty object singleton
GenericRapidJsonValue()
: value(emptyObject()) { }
/// Construct a wrapper for a specific RapidJson value
GenericRapidJsonValue(const ValueType &value)
: value(value) { }
/**
* @brief Create a new GenericRapidJsonFrozenValue instance that contains
* the value referenced by this GenericRapidJsonValue instance.
*
* @returns pointer to a new GenericRapidJsonFrozenValue instance, belonging
* to the caller.
*/
FrozenValue * freeze() const
{
return new GenericRapidJsonFrozenValue<ValueType>(value);
}
/**
* @brief Optionally return a GenericRapidJsonArray instance.
*
* If the referenced RapidJson value is an array, this function will return
* a std::optional containing a GenericRapidJsonArray instance referencing
* the array.
*
* Otherwise it will return an empty optional.
*/
opt::optional<GenericRapidJsonArray<ValueType> > getArrayOptional() const
{
if (value.IsArray()) {
return opt::make_optional(GenericRapidJsonArray<ValueType>(value));
}
return opt::optional<GenericRapidJsonArray<ValueType> >();
}
/**
* @brief Retrieve the number of elements in the array
*
* If the referenced RapidJson value is an array, this function will
* retrieve the number of elements in the array and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of elements was retrieved, false otherwise.
*/
bool getArraySize(size_t &result) const
{
if (value.IsArray()) {
result = value.Size();
return true;
}
return false;
}
bool getBool(bool &result) const
{
if (value.IsBool()) {
result = value.GetBool();
return true;
}
return false;
}
bool getDouble(double &result) const
{
if (value.IsDouble()) {
result = value.GetDouble();
return true;
}
return false;
}
bool getInteger(int64_t &result) const
{
if (value.IsInt()) {
result = value.GetInt();
return true;
} else if (value.IsInt64()) {
result = value.GetInt64();
return true;
} else if (value.IsUint()) {
result = static_cast<int64_t>(value.GetUint());
return true;
} else if (value.IsUint64()) {
result = static_cast<int64_t>(value.GetUint64());
return true;
}
return false;
}
/**
* @brief Optionally return a GenericRapidJsonObject instance.
*
* If the referenced RapidJson value is an object, this function will return
* a std::optional containing a GenericRapidJsonObject instance
* referencing the object.
*
* Otherwise it will return an empty optional.
*/
opt::optional<GenericRapidJsonObject<ValueType> > getObjectOptional() const
{
if (value.IsObject()) {
return opt::make_optional(GenericRapidJsonObject<ValueType>(value));
}
return opt::optional<GenericRapidJsonObject<ValueType> >();
}
/**
* @brief Retrieve the number of members in the object
*
* If the referenced RapidJson value is an object, this function will
* retrieve the number of members in the object and store it in the output
* variable provided.
*
* @param result reference to size_t to set with result
*
* @returns true if the number of members was retrieved, false otherwise.
*/
bool getObjectSize(size_t &result) const
{
if (value.IsObject()) {
result = value.MemberEnd() - value.MemberBegin();
return true;
}
return false;
}
bool getString(std::string &result) const
{
if (value.IsString()) {
result.assign(value.GetString(), value.GetStringLength());
return true;
}
return false;
}
static bool hasStrictTypes()
{
return true;
}
bool isArray() const
{
return value.IsArray();
}
bool isBool() const
{
return value.IsBool();
}
bool isDouble() const
{
return value.IsDouble();
}
bool isInteger() const
{
return value.IsInt() || value.IsInt64() || value.IsUint() ||
value.IsUint64();
}
bool isNull() const
{
return value.IsNull();
}
bool isNumber() const
{
return value.IsNumber();
}
bool isObject() const
{
return value.IsObject();
}
bool isString() const
{
return value.IsString();
}
private:
/// Return a reference to an empty object singleton
static const ValueType & emptyObject()
{
static const ValueType object(rapidjson::kObjectType);
return object;
}
/// Reference to the contained RapidJson value.
const ValueType &value;
};
/**
* @brief An implementation of the Adapter interface supporting RapidJson.
*
* This class is defined in terms of the BasicAdapter template class, which
* helps to ensure that all of the Adapter implementations behave consistently.
*
* @see Adapter
* @see BasicAdapter
*/
template<class ValueType>
class GenericRapidJsonAdapter:
public BasicAdapter<GenericRapidJsonAdapter<ValueType>,
GenericRapidJsonArray<ValueType>,
GenericRapidJsonObjectMember<ValueType>,
GenericRapidJsonObject<ValueType>,
GenericRapidJsonValue<ValueType> >
{
public:
/// Construct a RapidJsonAdapter that contains an empty object
GenericRapidJsonAdapter()
: BasicAdapter<GenericRapidJsonAdapter<ValueType>,
GenericRapidJsonArray<ValueType>,
GenericRapidJsonObjectMember<ValueType>,
GenericRapidJsonObject<ValueType>,
GenericRapidJsonValue<ValueType> >() { }
/// Construct a RapidJsonAdapter containing a specific RapidJson value
GenericRapidJsonAdapter(const ValueType &value)
: BasicAdapter<GenericRapidJsonAdapter<ValueType>,
GenericRapidJsonArray<ValueType>,
GenericRapidJsonObjectMember<ValueType>,
GenericRapidJsonObject<ValueType>,
GenericRapidJsonValue<ValueType> >(value) { }
};
/**
* @brief Class for iterating over values held in a JSON array.
*
* This class provides a JSON array iterator that dereferences as an instance of
* RapidJsonAdapter representing a value stored in the array. It has been
* implemented using the std::iterator template.
*
* @see RapidJsonArray
*/
template<class ValueType>
class GenericRapidJsonArrayValueIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
GenericRapidJsonAdapter<ValueType> > // value type
{
public:
/**
* @brief Construct a new GenericRapidJsonArrayValueIterator using an
* existing RapidJson iterator.
*
* @param itr RapidJson iterator to store
*/
GenericRapidJsonArrayValueIterator(
const typename ValueType::ConstValueIterator &itr)
: itr(itr) { }
/// Returns a GenericRapidJsonAdapter that contains the value of the current
/// element.
GenericRapidJsonAdapter<ValueType> operator*() const
{
return GenericRapidJsonAdapter<ValueType>(*itr);
}
/// Returns a proxy for the value of the current element
DerefProxy<GenericRapidJsonAdapter<ValueType> > operator->() const
{
return DerefProxy<GenericRapidJsonAdapter<ValueType> >(**this);
}
/**
* @brief Compare this iterator against another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other iterator to compare against
*
* @returns true if the iterators are equal, false otherwise.
*/
bool operator==(const GenericRapidJsonArrayValueIterator<ValueType> &other) const
{
return itr == other.itr;
}
bool operator!=(const GenericRapidJsonArrayValueIterator<ValueType>& other) const
{
return !(itr == other.itr);
}
GenericRapidJsonArrayValueIterator<ValueType>& operator++()
{
itr++;
return *this;
}
GenericRapidJsonArrayValueIterator<ValueType> operator++(int) {
GenericRapidJsonArrayValueIterator<ValueType> iterator_pre(itr);
++(*this);
return iterator_pre;
}
GenericRapidJsonArrayValueIterator<ValueType>& operator--()
{
itr--;
return *this;
}
void advance(std::ptrdiff_t n)
{
itr += n;
}
std::ptrdiff_t difference(const GenericRapidJsonArrayValueIterator<ValueType> &other)
{
return std::distance(itr, other.itr);
}
private:
typename ValueType::ConstValueIterator itr;
};
/**
* @brief Class for iterating over the members belonging to a JSON object.
*
* This class provides a JSON object iterator that dereferences as an instance
* of GenericRapidJsonObjectMember representing one of the members of the
* object. It has been implemented using the std::iterator template.
*
* @see GenericRapidJsonObject
* @see GenericRapidJsonObjectMember
*/
template<class ValueType>
class GenericRapidJsonObjectMemberIterator:
public std::iterator<
std::bidirectional_iterator_tag, // bi-directional iterator
GenericRapidJsonObjectMember<ValueType> > // value type
{
public:
/**
* @brief Construct an iterator from a RapidJson iterator.
*
* @param itr RapidJson iterator to store
*/
GenericRapidJsonObjectMemberIterator(
const typename ValueType::ConstMemberIterator &itr)
: itr(itr) { }
/**
* @brief Returns a GenericRapidJsonObjectMember that contains the key and
* value belonging to the object member identified by the iterator.
*/
GenericRapidJsonObjectMember<ValueType> operator*() const
{
return GenericRapidJsonObjectMember<ValueType>(
std::string(itr->name.GetString(), itr->name.GetStringLength()),
itr->value);
}
/// Returns a proxy for the value of the current element
DerefProxy<GenericRapidJsonObjectMember<ValueType> > operator->() const
{
return DerefProxy<GenericRapidJsonObjectMember<ValueType> >(**this);
}
/**
* @brief Compare this iterator with another iterator.
*
* Note that this directly compares the iterators, not the underlying
* values, and assumes that two identical iterators will point to the same
* underlying object.
*
* @param other Iterator to compare with
*
* @returns true if the underlying iterators are equal, false otherwise
*/
bool operator==(const GenericRapidJsonObjectMemberIterator<ValueType> &other) const
{
return itr == other.itr;
}
bool operator!=(const GenericRapidJsonObjectMemberIterator<ValueType> &other) const
{
return !(itr == other.itr);
}
GenericRapidJsonObjectMemberIterator<ValueType>& operator++()
{
itr++;
return *this;
}
GenericRapidJsonObjectMemberIterator<ValueType> operator++(int)
{
GenericRapidJsonObjectMemberIterator<ValueType> iterator_pre(itr);
++(*this);
return iterator_pre;
}
GenericRapidJsonObjectMemberIterator<ValueType>& operator--()
{
itr--;
return *this;
}
std::ptrdiff_t difference(const GenericRapidJsonObjectMemberIterator &other)
{
return std::distance(itr, other.itr);
}
private:
/// Iternal copy of the original RapidJson iterator
typename ValueType::ConstMemberIterator itr;
};
template<class ValueType>
inline bool GenericRapidJsonFrozenValue<ValueType>::equalTo(
const Adapter &other, bool strict) const
{
return GenericRapidJsonAdapter<ValueType>(value).equalTo(other, strict);
}
template<class ValueType>
inline typename GenericRapidJsonArray<ValueType>::iterator
GenericRapidJsonArray<ValueType>::begin() const
{
return value.Begin();
}
template<class ValueType>
inline typename GenericRapidJsonArray<ValueType>::iterator
GenericRapidJsonArray<ValueType>::end() const
{
return value.End();
}
template<class ValueType>
inline typename GenericRapidJsonObject<ValueType>::iterator
GenericRapidJsonObject<ValueType>::begin() const
{
return value.MemberBegin();
}
template<class ValueType>
inline typename GenericRapidJsonObject<ValueType>::iterator
GenericRapidJsonObject<ValueType>::end() const
{
return value.MemberEnd();
}
template<class ValueType>
inline typename GenericRapidJsonObject<ValueType>::iterator
GenericRapidJsonObject<ValueType>::find(
const std::string &propertyName) const
{
// Hack to support older versions of rapidjson where pointers are used as
// the built in iterator type. In those versions, the FindMember function
// would return a null pointer when the requested member could not be
// found. After calling FindMember on an empty object, we compare the
// result against what we would expect if a non-null-pointer iterator was
// returned.
const ValueType empty(rapidjson::kObjectType);
const typename ValueType::ConstMemberIterator maybeEnd = empty.FindMember("");
if (maybeEnd != empty.MemberBegin() + 1) {
// In addition to the pointer-based iterator issue, RapidJson's internal
// string comparison code seemed to rely on the query string being
// initialised to a length greater than or equal to that of the
// properties being compared. We get around this by implementing our
// own linear scan.
const size_t propertyNameLength = propertyName.length();
for (typename ValueType::ConstMemberIterator itr = value.MemberBegin();
itr != value.MemberEnd(); ++itr) {
const size_t memberNameLength = itr->name.GetStringLength();
if (memberNameLength == propertyNameLength &&
strncmp(itr->name.GetString(), propertyName.c_str(),
itr->name.GetStringLength()) == 0) {
return itr;
}
}
return value.MemberEnd();
}
return value.FindMember(propertyName.c_str()); // Times are good.
}
typedef GenericRapidJsonAdapter<> RapidJsonAdapter;
typedef GenericRapidJsonArray<> RapidJsonArray;
typedef GenericRapidJsonArrayValueIterator<> RapidJsonArrayValue;
typedef GenericRapidJsonFrozenValue<> RapidJsonFrozenValue;
typedef GenericRapidJsonObject<> RapidJsonObject;
typedef GenericRapidJsonObjectMember<> RapidJsonObjectMember;
typedef GenericRapidJsonObjectMemberIterator<> RapidJsonObjectMemberIterator;
typedef GenericRapidJsonValue<> RapidJsonValue;
/**
* @brief Specialisation of the AdapterTraits template struct for a
* RapidJsonAdapter that uses a pool allocator
*/
template<>
struct AdapterTraits<valijson::adapters::RapidJsonAdapter>
{
typedef rapidjson::Document DocumentType;
static std::string adapterName()
{
return "RapidJsonAdapter";
}
};
typedef rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator>
RapidJsonCrt;
/**
* @brief Specialisation of the AdapterTraits template struct for a
* RapidJsonAdapter that uses the default CRT allocator
*/
template<>
struct AdapterTraits<valijson::adapters::GenericRapidJsonAdapter<RapidJsonCrt> >
{
typedef rapidjson::GenericDocument<rapidjson::UTF8<>,
rapidjson::CrtAllocator> DocumentType;
static std::string adapterName()
{
return "GenericRapidJsonAdapter (using CrtAllocator)";
}
};
} // namespace adapters
} // namespace valijson
#endif

25
3rdparty/valijson/constraint_builder.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,25 @@
#pragma once
#ifndef __VALIJSON_CONSTRAINT_BUILDER_HPP
#define __VALIJSON_CONSTRAINT_BUILDER_HPP
namespace valijson {
namespace adapters {
class Adapter;
}
namespace constraints {
struct Constraint;
}
class ConstraintBuilder
{
public:
virtual ~ConstraintBuilder() {}
virtual constraints::Constraint * make(const adapters::Adapter &) const = 0;
};
} // namespace valijson
#endif

69
3rdparty/valijson/constraints/basic_constraint.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,69 @@
#pragma once
#ifndef __VALIJSON_CONSTRAINTS_BASIC_CONSTRAINT_HPP
#define __VALIJSON_CONSTRAINTS_BASIC_CONSTRAINT_HPP
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
#include <valijson/internal/custom_allocator.hpp>
namespace valijson {
namespace constraints {
/**
* @brief Template class that implements the accept() and clone() functions of
* the Constraint interface.
*
* @tparam ConstraintType name of the concrete constraint type, which must
* provide a copy constructor.
*/
template<typename ConstraintType>
struct BasicConstraint: Constraint
{
typedef internal::CustomAllocator<void *> Allocator;
typedef std::basic_string<char, std::char_traits<char>,
internal::CustomAllocator<char> > String;
BasicConstraint()
: allocator() { }
BasicConstraint(Allocator::CustomAlloc allocFn, Allocator::CustomFree freeFn)
: allocator(allocFn, freeFn) { }
BasicConstraint(const BasicConstraint &other)
: allocator(other.allocator) { }
virtual ~BasicConstraint<ConstraintType>() { }
virtual bool accept(ConstraintVisitor &visitor) const
{
return visitor.visit(*static_cast<const ConstraintType*>(this));
}
virtual Constraint * clone(CustomAlloc allocFn, CustomFree freeFn) const
{
void *ptr = allocFn(sizeof(ConstraintType));
if (!ptr) {
throw std::runtime_error(
"Failed to allocate memory for cloned constraint");
}
try {
return new (ptr) ConstraintType(
*static_cast<const ConstraintType*>(this));
} catch (...) {
freeFn(ptr);
throw;
}
}
protected:
Allocator allocator;
};
} // namespace constraints
} // namespace valijson
#endif

1097
3rdparty/valijson/constraints/concrete_constraints.hpp поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

54
3rdparty/valijson/constraints/constraint.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,54 @@
#pragma once
#ifndef __VALIJSON_CONSTRAINTS_CONSTRAINT_HPP
#define __VALIJSON_CONSTRAINTS_CONSTRAINT_HPP
namespace valijson {
namespace constraints {
class ConstraintVisitor;
/**
* @brief Interface that must be implemented by concrete constraint types.
*
* @todo Consider using something like the boost::cloneable concept here.
*/
struct Constraint
{
/// Typedef for custom new-/malloc-like function
typedef void * (*CustomAlloc)(size_t size);
/// Typedef for custom free-like function
typedef void (*CustomFree)(void *);
/**
* @brief Virtual destructor.
*/
virtual ~Constraint() { }
/**
* @brief Perform an action on the constraint using the visitor pattern.
*
* Note that Constraints cannot be modified by visitors.
*
* @param visitor Reference to a ConstraintVisitor object.
*
* @returns the boolean value returned by one of the visitor's visit
* functions.
*/
virtual bool accept(ConstraintVisitor &visitor) const = 0;
/**
* @brief Make a copy of a constraint.
*
* Note that this should be a deep copy of the constraint.
*
* @returns an owning-pointer to the new constraint.
*/
virtual Constraint * clone(CustomAlloc, CustomFree) const = 0;
};
} // namespace constraints
} // namespace valijson
#endif

96
3rdparty/valijson/constraints/constraint_visitor.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,96 @@
#pragma once
#ifndef __VALIJSON_CONSTRAINTS_CONSTRAINT_VISITOR_HPP
#define __VALIJSON_CONSTRAINTS_CONSTRAINT_VISITOR_HPP
namespace valijson {
namespace constraints {
class AllOfConstraint;
class AnyOfConstraint;
class DependenciesConstraint;
class EnumConstraint;
class LinearItemsConstraint;
class MaxItemsConstraint;
class MaximumConstraint;
class MaxLengthConstraint;
class MaxPropertiesConstraint;
class MinItemsConstraint;
class MinimumConstraint;
class MinLengthConstraint;
class MinPropertiesConstraint;
class MultipleOfDoubleConstraint;
class MultipleOfIntConstraint;
class NotConstraint;
class OneOfConstraint;
class PatternConstraint;
class PolyConstraint;
class PropertiesConstraint;
class RequiredConstraint;
class SingularItemsConstraint;
class TypeConstraint;
class UniqueItemsConstraint;
/// Interface to allow usage of the visitor pattern with Constraints
class ConstraintVisitor
{
protected:
virtual ~ConstraintVisitor() {}
// Shorten type names for derived classes outside of this namespace
typedef constraints::AllOfConstraint AllOfConstraint;
typedef constraints::AnyOfConstraint AnyOfConstraint;
typedef constraints::DependenciesConstraint DependenciesConstraint;
typedef constraints::EnumConstraint EnumConstraint;
typedef constraints::LinearItemsConstraint LinearItemsConstraint;
typedef constraints::MaximumConstraint MaximumConstraint;
typedef constraints::MaxItemsConstraint MaxItemsConstraint;
typedef constraints::MaxLengthConstraint MaxLengthConstraint;
typedef constraints::MaxPropertiesConstraint MaxPropertiesConstraint;
typedef constraints::MinimumConstraint MinimumConstraint;
typedef constraints::MinItemsConstraint MinItemsConstraint;
typedef constraints::MinLengthConstraint MinLengthConstraint;
typedef constraints::MinPropertiesConstraint MinPropertiesConstraint;
typedef constraints::MultipleOfDoubleConstraint MultipleOfDoubleConstraint;
typedef constraints::MultipleOfIntConstraint MultipleOfIntConstraint;
typedef constraints::NotConstraint NotConstraint;
typedef constraints::OneOfConstraint OneOfConstraint;
typedef constraints::PatternConstraint PatternConstraint;
typedef constraints::PolyConstraint PolyConstraint;
typedef constraints::PropertiesConstraint PropertiesConstraint;
typedef constraints::RequiredConstraint RequiredConstraint;
typedef constraints::SingularItemsConstraint SingularItemsConstraint;
typedef constraints::TypeConstraint TypeConstraint;
typedef constraints::UniqueItemsConstraint UniqueItemsConstraint;
public:
virtual bool visit(const AllOfConstraint &) = 0;
virtual bool visit(const AnyOfConstraint &) = 0;
virtual bool visit(const DependenciesConstraint &) = 0;
virtual bool visit(const EnumConstraint &) = 0;
virtual bool visit(const LinearItemsConstraint &) = 0;
virtual bool visit(const MaximumConstraint &) = 0;
virtual bool visit(const MaxItemsConstraint &) = 0;
virtual bool visit(const MaxLengthConstraint &) = 0;
virtual bool visit(const MaxPropertiesConstraint &) = 0;
virtual bool visit(const MinimumConstraint &) = 0;
virtual bool visit(const MinItemsConstraint &) = 0;
virtual bool visit(const MinLengthConstraint &) = 0;
virtual bool visit(const MinPropertiesConstraint &) = 0;
virtual bool visit(const MultipleOfDoubleConstraint &) = 0;
virtual bool visit(const MultipleOfIntConstraint &) = 0;
virtual bool visit(const NotConstraint &) = 0;
virtual bool visit(const OneOfConstraint &) = 0;
virtual bool visit(const PatternConstraint &) = 0;
virtual bool visit(const PolyConstraint &) = 0;
virtual bool visit(const PropertiesConstraint &) = 0;
virtual bool visit(const RequiredConstraint &) = 0;
virtual bool visit(const SingularItemsConstraint &) = 0;
virtual bool visit(const TypeConstraint &) = 0;
virtual bool visit(const UniqueItemsConstraint &) = 0;
};
} // namespace constraints
} // namespace valijson
#endif

110
3rdparty/valijson/internal/custom_allocator.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,110 @@
#ifndef __VALIJSON_CUSTOM_ALLOCATOR_HPP
#define __VALIJSON_CUSTOM_ALLOCATOR_HPP
namespace valijson {
namespace internal {
template<class T>
class CustomAllocator
{
public:
/// Typedef for custom new-/malloc-like function
typedef void * (*CustomAlloc)(size_t size);
/// Typedef for custom free-like function
typedef void (*CustomFree)(void *);
// Standard allocator typedefs
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<typename U>
struct rebind
{
typedef CustomAllocator<U> other;
};
CustomAllocator()
: allocFn(::operator new),
freeFn(::operator delete) { }
CustomAllocator(CustomAlloc allocFn, CustomFree freeFn)
: allocFn(allocFn),
freeFn(freeFn) { }
CustomAllocator(const CustomAllocator &other)
: allocFn(other.allocFn),
freeFn(other.freeFn) { }
template<typename U>
CustomAllocator(CustomAllocator<U> const &other)
: allocFn(other.allocFn),
freeFn(other.freeFn) { }
CustomAllocator & operator=(const CustomAllocator &other)
{
allocFn = other.allocFn;
freeFn = other.freeFn;
return *this;
}
pointer address(reference r)
{
return &r;
}
const_pointer address(const_reference r)
{
return &r;
}
pointer allocate(size_type cnt, const void * = 0)
{
return reinterpret_cast<pointer>(allocFn(cnt * sizeof(T)));
}
void deallocate(pointer p, size_type)
{
freeFn(p);
}
size_type max_size() const
{
return std::numeric_limits<size_type>::max() / sizeof(T);
}
void construct(pointer p, const T& t)
{
new(p) T(t);
}
void destroy(pointer p)
{
p->~T();
}
bool operator==(const CustomAllocator &other) const
{
return other.allocFn == allocFn && other.freeFn == freeFn;
}
bool operator!=(const CustomAllocator &other) const
{
return !operator==(other);
}
CustomAlloc allocFn;
CustomFree freeFn;
};
} // end namespace internal
} // end namespace valijson
#endif

33
3rdparty/valijson/internal/debug.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,33 @@
#ifndef __VALIJSON_DEBUG_HPP
#define __VALIJSON_DEBUG_HPP
#include <string>
namespace valijson {
namespace internal {
template<typename AdapterType>
std::string nodeTypeAsString(const AdapterType &node) {
if (node.isArray()) {
return "array";
} else if (node.isObject()) {
return "object";
} else if (node.isString()) {
return "string";
} else if (node.isNull()) {
return "null";
} else if (node.isInteger()) {
return "integer";
} else if (node.isDouble()) {
return "double";
} else if (node.isBool()) {
return "bool";
}
return "unknown";
}
} // end namespace internal
} // end namespace valijson
#endif

257
3rdparty/valijson/internal/json_pointer.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,257 @@
#pragma once
#ifndef __VALIJSON_INTERNAL_JSON_POINTER_HPP
#define __VALIJSON_INTERNAL_JSON_POINTER_HPP
#include <algorithm>
#include <cerrno>
#include <cstddef>
#include <cstring>
#include <stdexcept>
#include <string>
#include <valijson/adapters/adapter.hpp>
#include <valijson/internal/optional.hpp>
namespace valijson {
namespace internal {
namespace json_pointer {
/**
* @brief Replace all occurrences of `search` with `replace`. Modifies `subject` in place
*
* @param subject string to operate on
* @param search string to search
* @param replace replacement string
*/
inline void replace_all_inplace(std::string& subject, const char* search,
const char* replace)
{
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, strlen(search), replace);
pos += strlen(replace);
}
}
/**
* @brief Return the char value corresponding to a 2-digit hexadecimal string
*
* @throws std::runtime_error for strings that are not exactly two characters
* in length and for strings that contain non-hexadecimal characters
*
* @return decoded char value corresponding to the hexadecimal string
*/
inline char decodePercentEncodedChar(const std::string &digits)
{
if (digits.length() != 2) {
throw std::runtime_error("Failed to decode %-encoded character '" +
digits + "' due to unexpected number of characters; "
"expected two characters");
}
errno = 0;
const char *begin = digits.c_str();
char *end = NULL;
const unsigned long value = strtoul(begin, &end, 16);
if (end != begin && *end != '\0') {
throw std::runtime_error("Failed to decode %-encoded character '" +
digits + "'");
}
return char(value);
}
/**
* @brief Extract and transform the token between two iterators
*
* This function is responsible for extracting a JSON Reference token from
* between two iterators, and performing any necessary transformations, before
* returning the resulting string. Its main purpose is to replace the escaped
* character sequences defined in the RFC-6901 (JSON Pointer), and to decode
* %-encoded character sequences defined in RFC-3986 (URI).
*
* The encoding used in RFC-3986 should be familiar to many developers, but
* the escaped character sequences used in JSON Pointers may be less so. From
* the JSON Pointer specification (RFC 6901, April 2013):
*
* Evaluation of each reference token begins by decoding any escaped
* character sequence. This is performed by first transforming any
* occurrence of the sequence '~1' to '/', and then transforming any
* occurrence of the sequence '~0' to '~'. By performing the
* substitutions in this order, an implementation avoids the error of
* turning '~01' first into '~1' and then into '/', which would be
* incorrect (the string '~01' correctly becomes '~1' after
* transformation).
*
* @param begin iterator pointing to beginning of a token
* @param end iterator pointing to one character past the end of the token
*
* @return string with escaped character sequences replaced
*
*/
inline std::string extractReferenceToken(std::string::const_iterator begin,
std::string::const_iterator end)
{
std::string token(begin, end);
// Replace JSON Pointer-specific escaped character sequences
replace_all_inplace(token, "~1", "/");
replace_all_inplace(token, "~0", "~");
// Replace %-encoded character sequences with their actual characters
for (size_t n = token.find('%'); n != std::string::npos;
n = token.find('%', n + 1)) {
try {
const char c = decodePercentEncodedChar(token.substr(n + 1, 2));
token.replace(n, 3, &c, 1);
} catch (const std::runtime_error &e) {
throw std::runtime_error(
std::string(e.what()) + "; in token: " + token);
}
}
return token;
}
/**
* @brief Recursively locate the value referenced by a JSON Pointer
*
* This function takes both a string reference and an iterator to the beginning
* of the substring that is being resolved. This iterator is expected to point
* to the beginning of a reference token, whose length will be determined by
* searching for the next delimiter ('/' or '\0'). A reference token must be
* at least one character in length to be considered valid.
*
* Once the next reference token has been identified, it will be used either as
* an array index or as an the name an object member. The validity of a
* reference token depends on the type of the node currently being traversed,
* and the applicability of the token to that node. For example, an array can
* only be dereferenced by a non-negative integral index.
*
* Once the next node has been identified, the length of the remaining portion
* of the JSON Pointer will be used to determine whether recursion should
* terminate.
*
* @param node current node in recursive evaluation of JSON Pointer
* @param jsonPointer string containing complete JSON Pointer
* @param jsonPointerItr string iterator pointing the beginning of the next
* reference token
*
* @return an instance of AdapterType that wraps the dereferenced node
*/
template<typename AdapterType>
inline AdapterType resolveJsonPointer(
const AdapterType &node,
const std::string &jsonPointer,
const std::string::const_iterator jsonPointerItr)
{
// TODO: This function will probably need to implement support for
// fetching documents referenced by JSON Pointers, similar to the
// populateSchema function.
const std::string::const_iterator jsonPointerEnd = jsonPointer.end();
// Terminate recursion if all reference tokens have been consumed
if (jsonPointerItr == jsonPointerEnd) {
return node;
}
// Reference tokens must begin with a leading slash
if (*jsonPointerItr != '/') {
throw std::runtime_error("Expected reference token to begin with "
"leading slash; remaining tokens: " +
std::string(jsonPointerItr, jsonPointerEnd));
}
// Find iterator that points to next slash or newline character; this is
// one character past the end of the current reference token
std::string::const_iterator jsonPointerNext =
std::find(jsonPointerItr + 1, jsonPointerEnd, '/');
// Extract the next reference token
const std::string referenceToken = extractReferenceToken(
jsonPointerItr + 1, jsonPointerNext);
// Empty reference tokens should be ignored
if (referenceToken.empty()) {
return resolveJsonPointer(node, jsonPointer, jsonPointerNext);
} else if (node.isArray()) {
if (referenceToken.compare("-") == 0) {
throw std::runtime_error("Hyphens cannot be used as array indices "
"since the requested array element does not yet exist");
}
try {
// Fragment must be non-negative integer
const uint64_t index = std::stoul(referenceToken);
typedef typename AdapterType::Array Array;
typename Array::const_iterator itr = node.asArray().begin();
if (index > node.asArray().size() - 1) {
throw std::runtime_error("Expected reference token to identify "
"an element in the current array, but array index is "
"out of bounds; actual token: " + referenceToken);
}
if (index > static_cast<uint64_t>(std::numeric_limits<std::ptrdiff_t>::max())) {
throw std::runtime_error("Array index out of bounds; hard "
"limit is " + std::to_string(
std::numeric_limits<std::ptrdiff_t>::max()));
}
itr.advance(static_cast<std::ptrdiff_t>(index));
// Recursively process the remaining tokens
return resolveJsonPointer(*itr, jsonPointer, jsonPointerNext);
} catch (std::invalid_argument &) {
throw std::runtime_error("Expected reference token to contain a "
"non-negative integer to identify an element in the "
"current array; actual token: " + referenceToken);
}
} else if (node.maybeObject()) {
// Fragment must identify a member of the candidate object
typedef typename AdapterType::Object Object;
typename Object::const_iterator itr = node.asObject().find(
referenceToken);
if (itr == node.asObject().end()) {
throw std::runtime_error("Expected reference token to identify an "
"element in the current object; "
"actual token: " + referenceToken);
}
// Recursively process the remaining tokens
return resolveJsonPointer(itr->second, jsonPointer, jsonPointerNext);
}
throw std::runtime_error("Expected end of JSON Pointer, but at least "
"one reference token has not been processed; remaining tokens: " +
std::string(jsonPointerNext, jsonPointerEnd));
}
/**
* @brief Return the JSON Value referenced by a JSON Pointer
*
* @param rootNode node to use as root for JSON Pointer resolution
* @param jsonPointer string containing JSON Pointer
*
* @return an instance AdapterType in the specified document
*/
template<typename AdapterType>
inline AdapterType resolveJsonPointer(
const AdapterType &rootNode,
const std::string &jsonPointer)
{
return resolveJsonPointer(rootNode, jsonPointer, jsonPointer.begin());
}
} // namespace json_pointer
} // namespace internal
} // namespace valijson
#endif

65
3rdparty/valijson/internal/json_reference.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,65 @@
#pragma once
#ifndef __VALIJSON_INTERNAL_JSON_REFERENCE_HPP
#define __VALIJSON_INTERNAL_JSON_REFERENCE_HPP
#include <stdexcept>
#include <string>
#include <valijson/internal/optional.hpp>
namespace valijson {
namespace internal {
namespace json_reference {
/**
* @brief Extract URI from JSON Reference relative to the current schema
*
* @param jsonRef JSON Reference to extract from
* @param schema Schema that JSON Reference URI is relative to
*
* @return Optional string containing URI
*/
inline opt::optional<std::string> getJsonReferenceUri(
const std::string &jsonRef)
{
const size_t ptrPos = jsonRef.find("#");
if (ptrPos == 0) {
// The JSON Reference does not contain a URI, but might contain a
// JSON Pointer that refers to the current document
return opt::optional<std::string>();
} else if (ptrPos != std::string::npos) {
// The JSON Reference contains a URI and possibly a JSON Pointer
return jsonRef.substr(0, ptrPos);
}
// The entire JSON Reference should be treated as a URI
return jsonRef;
}
/**
* @brief Extract JSON Pointer portion of a JSON Reference
*
* @param jsonRef JSON Reference to extract from
*
* @return Optional string containing JSON Pointer
*/
inline opt::optional<std::string> getJsonReferencePointer(
const std::string &jsonRef)
{
// Attempt to extract JSON Pointer if '#' character is present. Note
// that a valid pointer would contain at least a leading forward
// slash character.
const size_t ptrPos = jsonRef.find("#");
if (ptrPos != std::string::npos) {
return jsonRef.substr(ptrPos + 1);
}
return opt::optional<std::string>();
}
} // namespace json_reference
} // namespace internal
} // namespace valijson
#endif

18
3rdparty/valijson/internal/optional.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,18 @@
#pragma once
#ifndef __VALIJSON_OPTIONAL_HPP
#define __VALIJSON_OPTIONAL_HPP
#if __cplusplus >= 201703
// Visual C++ only supports __has_include in versions 14.12 and greater
# if !defined(_MSC_VER) || _MSC_VER >= 1912
# if __has_include(<optional>)
# include <optional>
namespace opt = std;
# endif
# endif
#else
# include <compat/optional.hpp>
namespace opt = std::experimental;
#endif
#endif

37
3rdparty/valijson/internal/uri.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
#pragma once
#ifndef __VALIJSON_INTERNAL_URI_HPP
#define __VALIJSON_INTERNAL_URI_HPP
#include <string>
namespace valijson {
namespace internal {
namespace uri {
/**
* @brief Placeholder function to check whether a URI is absolute
*
* This function just checks for '://'
*/
inline bool isUriAbsolute(const std::string &documentUri)
{
static const char * placeholderMarker = "://";
return documentUri.find(placeholderMarker) != std::string::npos;
}
/**
* Placeholder function to resolve a relative URI within a given scope
*/
inline std::string resolveRelativeUri(
const std::string &resolutionScope,
const std::string &relativeUri)
{
return resolutionScope + relativeUri;
}
} // namespace uri
} // namespace internal
} // namespace valijson
#endif // __VALIJSON_INTERNAL_URI_HPP

213
3rdparty/valijson/schema.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,213 @@
#pragma once
#ifndef __VALIJSON_SCHEMA_HPP
#define __VALIJSON_SCHEMA_HPP
#include <cstdio>
#include <set>
#include <valijson/subschema.hpp>
namespace valijson {
/**
* Represents the root of a JSON Schema
*
* The root is distinct from other sub-schemas because it is the canonical
* starting point for validation of a document against a given a JSON Schema.
*/
class Schema: public Subschema
{
public:
/**
* @brief Construct a new Schema instance with no constraints
*/
Schema()
: sharedEmptySubschema(newSubschema()) { }
/**
* @brief Construct a new Schema using custom memory management
* functions
*
* @param allocFn malloc- or new-like function to allocate memory
* within Schema, such as for Subschema instances
* @param freeFn free-like function to free memory allocated with
* the `customAlloc` function
*/
Schema(CustomAlloc allocFn, CustomFree freeFn)
: Subschema(allocFn, freeFn),
sharedEmptySubschema(newSubschema()) { }
/**
* @brief Clean up and free all memory managed by the Schema
*
* Note that any Subschema pointers created and returned by this Schema
* should be considered invalid.
*/
virtual ~Schema()
{
sharedEmptySubschema->~Subschema();
freeFn(const_cast<Subschema *>(sharedEmptySubschema));
sharedEmptySubschema = NULL;
try {
for (std::set<Subschema *>::iterator itr = subschemaSet.begin();
itr != subschemaSet.end(); ++itr) {
Subschema *subschema = *itr;
subschema->~Subschema();
freeFn(subschema);
}
} catch (const std::exception &e) {
fprintf(stderr, "Caught an exception while destroying Schema: %s",
e.what());
}
}
/**
* @brief Copy a constraint to a specific sub-schema
*
* @param constraint reference to a constraint that will be copied into
* the sub-schema
* @param subschema pointer to the sub-schema that will own the copied
* constraint
*
* @throws std::runtime_error if the sub-schema is not owned by this Schema
* instance
*/
void addConstraintToSubschema(const Constraint &constraint,
const Subschema *subschema)
{
// TODO: Check heirarchy for subschemas that do not belong...
mutableSubschema(subschema)->addConstraint(constraint);
}
/**
* @brief Create a new Subschema instance that is owned by this Schema
*
* @returns const pointer to the new Subschema instance
*/
const Subschema * createSubschema()
{
Subschema *subschema = newSubschema();
try {
if (!subschemaSet.insert(subschema).second) {
throw std::runtime_error(
"Failed to store pointer for new sub-schema");
}
} catch (...) {
subschema->~Subschema();
freeFn(subschema);
throw;
}
return subschema;
}
/**
* @brief Return a pointer to the shared empty schema
*/
const Subschema * emptySubschema() const
{
return sharedEmptySubschema;
}
/**
* @brief Get a pointer to the root sub-schema of this Schema instance
*/
const Subschema * root() const
{
return this;
}
/**
* @brief Update the description for one of the sub-schemas owned by this
* Schema instance
*
* @param subschema sub-schema to update
* @param description new description
*/
void setSubschemaDescription(const Subschema *subschema,
const std::string &description)
{
mutableSubschema(subschema)->setDescription(description);
}
/**
* @brief Update the ID for one of the sub-schemas owned by this Schema
* instance
*
* @param subschema sub-schema to update
* @param id new ID
*/
void setSubschemaId(const Subschema *subschema, const std::string &id)
{
mutableSubschema(subschema)->setId(id);
}
/**
* @brief Update the title for one of the sub-schemas owned by this Schema
* instance
*
* @param subschema sub-schema to update
* @param title new title
*/
void setSubschemaTitle(const Subschema *subschema, const std::string &title)
{
mutableSubschema(subschema)->setTitle(title);
}
private:
// Disable copy construction
Schema(const Schema &);
// Disable copy assignment
Schema & operator=(const Schema &);
Subschema *newSubschema()
{
void *ptr = allocFn(sizeof(Subschema));
if (!ptr) {
throw std::runtime_error(
"Failed to allocate memory for shared empty sub-schema");
}
try {
return new (ptr) Subschema();
} catch (...) {
freeFn(ptr);
throw;
}
}
Subschema * mutableSubschema(const Subschema *subschema)
{
if (subschema == this) {
return this;
}
if (subschema == sharedEmptySubschema) {
throw std::runtime_error(
"Cannot modify the shared empty sub-schema");
}
Subschema *noConst = const_cast<Subschema*>(subschema);
if (subschemaSet.find(noConst) == subschemaSet.end()) {
throw std::runtime_error(
"Subschema pointer is not owned by this Schema instance");
}
return noConst;
}
/// Set of Subschema instances owned by this schema
std::set<Subschema*> subschemaSet;
/// Empty schema that can be reused by multiple constraints
const Subschema *sharedEmptySubschema;
};
} // namespace valijson
#endif

2120
3rdparty/valijson/schema_parser.hpp поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

286
3rdparty/valijson/subschema.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,286 @@
#pragma once
#ifndef __VALIJSON_SUBSCHEMA_HPP
#define __VALIJSON_SUBSCHEMA_HPP
#include <vector>
#include <memory>
#include <valijson/constraints/constraint.hpp>
#include <valijson/internal/optional.hpp>
namespace valijson {
/**
* Represents a sub-schema within a JSON Schema
*
* While all JSON Schemas have at least one sub-schema, the root, some will
* have additional sub-schemas that are defined as part of constraints that are
* included in the schema. For example, a 'oneOf' constraint maintains a set of
* references to one or more nested sub-schemas. As per the definition of a
* oneOf constraint, a document is valid within that constraint if it validates
* against one of the nested sub-schemas.
*/
class Subschema
{
public:
/// Typedef for custom new-/malloc-like function
typedef void * (*CustomAlloc)(size_t size);
/// Typedef for custom free-like function
typedef void (*CustomFree)(void *);
/// Typedef the Constraint class into the local namespace for convenience
typedef constraints::Constraint Constraint;
/// Typedef for a function that can be applied to each of the Constraint
/// instances owned by a Schema.
typedef std::function<bool (const Constraint &)> ApplyFunction;
/**
* @brief Construct a new Subschema object
*/
Subschema()
: allocFn(::operator new)
, freeFn(::operator delete) { }
/**
* @brief Construct a new Subschema using custom memory management
* functions
*
* @param allocFn malloc- or new-like function to allocate memory
* within Schema, such as for Subschema instances
* @param freeFn free-like function to free memory allocated with
* the `customAlloc` function
*/
Subschema(CustomAlloc allocFn, CustomFree freeFn)
: allocFn(allocFn)
, freeFn(freeFn) { }
/**
* @brief Clean up and free all memory managed by the Subschema
*/
virtual ~Subschema()
{
try {
for (std::vector<const Constraint *>::iterator itr =
constraints.begin(); itr != constraints.end(); ++itr) {
Constraint *constraint = const_cast<Constraint *>(*itr);
constraint->~Constraint();
freeFn(constraint);
}
constraints.clear();
} catch (const std::exception &e) {
fprintf(stderr, "Caught an exception in Subschema destructor: %s",
e.what());
}
}
/**
* @brief Add a constraint to this sub-schema
*
* The constraint will be copied before being added to the list of
* constraints for this Subschema. Note that constraints will be copied
* only as deep as references to other Subschemas - e.g. copies of
* constraints that refer to sub-schemas, will continue to refer to the
* same Subschema instances.
*
* @param constraint Reference to the constraint to copy
*/
void addConstraint(const Constraint &constraint)
{
Constraint *newConstraint = constraint.clone(allocFn, freeFn);
try {
constraints.push_back(newConstraint);
} catch (...) {
newConstraint->~Constraint();
freeFn(newConstraint);
throw;
}
}
/**
* @brief Invoke a function on each child Constraint
*
* This function will apply the callback function to each constraint in
* the Subschema, even if one of the invokations returns \c false. However,
* if one or more invokations of the callback function return \c false,
* this function will also return \c false.
*
* @returns \c true if all invokations of the callback function are
* successful, \c false otherwise
*/
bool apply(ApplyFunction &applyFunction) const
{
bool allTrue = true;
for (const Constraint *constraint : constraints) {
allTrue = allTrue && applyFunction(*constraint);
}
return allTrue;
}
/**
* @brief Invoke a function on each child Constraint
*
* This is a stricter version of the apply() function that will return
* immediately if any of the invokations of the callback function return
* \c false.
*
* @returns \c true if all invokations of the callback function are
* successful, \c false otherwise
*/
bool applyStrict(ApplyFunction &applyFunction) const
{
for (const Constraint *constraint : constraints) {
if (!applyFunction(*constraint)) {
return false;
}
}
return true;
}
/**
* @brief Get the description associated with this sub-schema
*
* @throws std::runtime_error if a description has not been set
*
* @returns string containing sub-schema description
*/
std::string getDescription() const
{
if (description) {
return *description;
}
throw std::runtime_error("Schema does not have a description");
}
/**
* @brief Get the ID associated with this sub-schema
*
* @throws std::runtime_error if an ID has not been set
*
* @returns string containing sub-schema ID
*/
std::string getId() const
{
if (id) {
return *id;
}
throw std::runtime_error("Schema does not have an ID");
}
/**
* @brief Get the title associated with this sub-schema
*
* @throws std::runtime_error if a title has not been set
*
* @returns string containing sub-schema title
*/
std::string getTitle() const
{
if (title) {
return *title;
}
throw std::runtime_error("Schema does not have a title");
}
/**
* @brief Check whether this sub-schema has a description
*
* @return boolean value
*/
bool hasDescription() const
{
return static_cast<bool>(description);
}
/**
* @brief Check whether this sub-schema has an ID
*
* @return boolean value
*/
bool hasId() const
{
return static_cast<bool>(id);
}
/**
* @brief Check whether this sub-schema has a title
*
* @return boolean value
*/
bool hasTitle() const
{
return static_cast<bool>(title);
}
/**
* @brief Set the description for this sub-schema
*
* The description will not be used for validation, but may be used as part
* of the user interface for interacting with schemas and sub-schemas. As
* an example, it may be used as part of the validation error descriptions
* that are produced by the Validator and ValidationVisitor classes.
*
* @param description new description
*/
void setDescription(const std::string &description)
{
this->description = description;
}
void setId(const std::string &id)
{
this->id = id;
}
/**
* @brief Set the title for this sub-schema
*
* The title will not be used for validation, but may be used as part
* of the user interface for interacting with schemas and sub-schema. As an
* example, it may be used as part of the validation error descriptions
* that are produced by the Validator and ValidationVisitor classes.
*
* @param title new title
*/
void setTitle(const std::string &title)
{
this->title = title;
}
protected:
CustomAlloc allocFn;
CustomFree freeFn;
private:
// Disable copy construction
Subschema(const Subschema &);
// Disable copy assignment
Subschema & operator=(const Subschema &);
/// List of pointers to constraints that apply to this schema.
std::vector<const Constraint *> constraints;
/// Schema description (optional)
opt::optional<std::string> description;
/// Id to apply when resolving the schema URI
opt::optional<std::string> id;
/// Title string associated with the schema (optional)
opt::optional<std::string> title;
};
} // namespace valijson
#endif

48
3rdparty/valijson/utils/file_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
#pragma once
#ifndef __VALIJSON_FILE_UTILS_HPP
#define __VALIJSON_FILE_UTILS_HPP
#include <fstream>
#include <limits>
namespace valijson {
namespace utils {
/**
* Load a file into a string
*
* @param path path to the file to be loaded
* @param dest string into which file should be loaded
*
* @return true if loaded, false otherwise
*/
inline bool loadFile(const std::string &path, std::string &dest)
{
// Open file for reading
std::ifstream file(path.c_str());
if (!file.is_open()) {
return false;
}
// Allocate space for file contents
file.seekg(0, std::ios::end);
const std::streamoff offset = file.tellg();
if (offset < 0 || offset > std::numeric_limits<unsigned int>::max()) {
return false;
}
dest.clear();
dest.reserve(static_cast<unsigned int>(offset));
// Assign file contents to destination string
file.seekg(0, std::ios::beg);
dest.assign(std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>());
return true;
}
} // namespace utils
} // namespace valijson
#endif

39
3rdparty/valijson/utils/json11_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
#pragma once
#ifndef __VALIJSON_UTILS_JSON11_UTILS_HPP
#define __VALIJSON_UTILS_JSON11_UTILS_HPP
#include <iostream>
#include <json11.hpp>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, json11::Json &document)
{
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'." << std::endl;
return false;
}
// Parse schema
std::string err;
document = json11::Json::parse(file, err);
if (!err.empty()) {
std::cerr << "json11 failed to parse the document:" << std::endl
<< "Parse error: " << err << std::endl;
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

37
3rdparty/valijson/utils/jsoncpp_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
#pragma once
#ifndef __VALIJSON_UTILS_JSONCPP_UTILS_HPP
#define __VALIJSON_UTILS_JSONCPP_UTILS_HPP
#include <iostream>
#include <json/json.h>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, Json::Value &document)
{
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'." << std::endl;
return false;
}
Json::Reader reader;
bool parsingSuccessful = reader.parse(file, document);
if (!parsingSuccessful) {
std::cerr << "Jsoncpp parser failed to parse the document:" << std::endl
<< reader.getFormattedErrorMessages();
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

37
3rdparty/valijson/utils/nlohmann_json_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
#pragma once
#ifndef VALIJSON_NLOHMANN_JSON_UTILS_HPP
#define VALIJSON_NLOHMANN_JSON_UTILS_HPP
#include <iostream>
#include <json.hpp>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, nlohmann::json &document) {
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'."
<< std::endl;
return false;
}
// Parse schema
try {
document = nlohmann::json::parse(file);
} catch (std::invalid_argument const& exception) {
std::cerr << "nlohmann::json failed to parse the document\n"
<< "Parse error:" << exception.what() << "\n";
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif //VALIJSON_NLOHMANN_JSON_UTILS_HPP

37
3rdparty/valijson/utils/picojson_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
#pragma once
#ifndef __VALIJSON_UTILS_PICOJSON_UTILS_HPP
#define __VALIJSON_UTILS_PICOJSON_UTILS_HPP
#include <iostream>
#include <picojson.h>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, picojson::value &document)
{
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'." << std::endl;
return false;
}
// Parse schema
std::string err = picojson::parse(document, file);
if (!err.empty()) {
std::cerr << "PicoJson failed to parse the document:" << std::endl
<< "Parse error: " << err << std::endl;
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

40
3rdparty/valijson/utils/poco_json_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,40 @@
#pragma once
#ifndef VALIJSON_POCO_JSON_UTILS_HPP
#define VALIJSON_POCO_JSON_UTILS_HPP
#include <iostream>
#include <Poco/JSON/JSONException.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Parser.h>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, Poco::Dynamic::Var &document) {
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'."
<< std::endl;
return false;
}
// Parse schema
try {
document = Poco::JSON::Parser().parse(file);
} catch (Poco::Exception const& exception) {
std::cerr << "Poco::JSON failed to parse the document\n"
<< "Parse error:" << exception.what() << "\n";
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif //VALIJSON_POCO_JSON_UTILS_HPP

40
3rdparty/valijson/utils/property_tree_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,40 @@
#pragma once
#ifndef __VALIJSON_UTILS_PROPERTY_TREE_UTILS_HPP
#define __VALIJSON_UTILS_PROPERTY_TREE_UTILS_HPP
#include <iostream>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
# include <boost/property_tree/json_parser.hpp>
# pragma clang diagnostic pop
#else
# include <boost/property_tree/json_parser.hpp>
#endif
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, boost::property_tree::ptree &document)
{
try {
boost::property_tree::read_json(path, document);
} catch (std::exception &e) {
std::cerr << "Boost Property Tree JSON parser failed to parse the document:" << std::endl;
std::cerr << e.what() << std::endl;
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

48
3rdparty/valijson/utils/qtjson_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
#pragma once
#ifndef __VALIJSON_UTILS_QTJSON_UTILS_HPP
#define __VALIJSON_UTILS_QTJSON_UTILS_HPP
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
inline bool loadDocument(const std::string &path, QJsonValue &root)
{
// Load schema JSON from file
QFile file(QString::fromStdString(path));
if (!file.open(QFile::ReadOnly)) {
std::cerr << "Failed to load json from file '" << path << "'." << std::endl;
return false;
}
QByteArray data = file.readAll();
// Parse schema
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data);
if (doc.isNull()) {
std::cerr << "qt failed to parse the document:" << std::endl
<< parseError.errorString().toStdString() << std::endl;
return false;
} else if (doc.isObject()) {
root = QJsonValue(doc.object());
} else if (doc.isArray()) {
root = QJsonValue(doc.array());
} else if (doc.isEmpty()) {
root = QJsonValue();
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

39
3rdparty/valijson/utils/rapidjson_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
#pragma once
#ifndef __VALIJSON_UTILS_RAPIDJSON_UTILS_HPP
#define __VALIJSON_UTILS_RAPIDJSON_UTILS_HPP
#include <iostream>
#include <rapidjson/document.h>
#include <valijson/utils/file_utils.hpp>
namespace valijson {
namespace utils {
template<typename Encoding, typename Allocator>
inline bool loadDocument(const std::string &path, rapidjson::GenericDocument<Encoding, Allocator> &document)
{
// Load schema JSON from file
std::string file;
if (!loadFile(path, file)) {
std::cerr << "Failed to load json from file '" << path << "'." << std::endl;
return false;
}
// Parse schema
document.template Parse<0>(file.c_str());
if (document.HasParseError()) {
std::cerr << "RapidJson failed to parse the document:" << std::endl;
std::cerr << "Parse error: " << document.GetParseError() << std::endl;
std::cerr << "Near: " << file.substr((std::max)(size_t(0), document.GetErrorOffset() - 20), 40) << std::endl;
return false;
}
return true;
}
} // namespace utils
} // namespace valijson
#endif

64
3rdparty/valijson/utils/utf8_utils.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,64 @@
#pragma once
#ifndef __VALIJSON_UTILS_UTF8_UTILS_HPP
#define __VALIJSON_UTILS_UTF8_UTILS_HPP
#include <stdexcept>
/*
Basic UTF-8 manipulation routines, adapted from code that was released into
the public domain by Jeff Bezanson.
*/
namespace valijson {
namespace utils {
static const uint32_t offsetsFromUTF8[6] = {
0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL
};
/* is c the start of a utf8 sequence? */
inline bool isutf(char c) {
return ((c & 0xC0) != 0x80);
}
/* reads the next utf-8 sequence out of a string, updating an index */
inline uint32_t u8_nextchar(const char *s, int *i)
{
uint32_t ch = 0;
int sz = 0;
do {
ch <<= 6;
ch += (unsigned char)s[(*i)++];
sz++;
} while (s[*i] && !isutf(s[*i]));
ch -= offsetsFromUTF8[sz-1];
return ch;
}
/* number of characters */
inline uint64_t u8_strlen(const char *s)
{
static const int maxLength = std::numeric_limits<int>::max();
uint64_t count = 0;
int i = 0;
while (s[i] != 0 && u8_nextchar(s, &i) != 0) {
if (i == maxLength) {
throw std::runtime_error(
"String exceeded maximum size of " +
std::to_string(maxLength) + " bytes.");
}
count++;
}
return count;
}
} // namespace utils
} // namespace valijson
#endif

126
3rdparty/valijson/validation_results.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,126 @@
#pragma once
#ifndef __VALIJSON_VALIDATION_RESULTS_HPP
#define __VALIJSON_VALIDATION_RESULTS_HPP
#include <deque>
#include <string>
#include <vector>
namespace valijson {
/**
* @brief Class that encapsulates the storage of validation errors.
*
* This class maintains an internal FIFO queue of errors that are reported
* during validation. Errors are pushed on to the back of an internal
* queue, and can retrieved by popping them from the front of the queue.
*/
class ValidationResults
{
public:
/**
* @brief Describes a validation error.
*
* This struct is used to pass around the context and description of a
* validation error.
*/
struct Error
{
/**
* @brief Construct an Error object with no context or description.
*/
Error() { }
/**
* @brief Construct an Error object using a context and description.
*
* @param context Context string to use
* @param description Description string to use
*/
Error(const std::vector<std::string> &context, const std::string &description)
: context(context),
description(description) { }
/// Path to the node that failed validation.
std::vector<std::string> context;
/// A detailed description of the validation error.
std::string description;
};
/**
* @brief Return begin iterator for results in the queue.
*/
std::deque<Error>::const_iterator begin() const
{
return errors.begin();
}
/**
* @brief Return end iterator for results in the queue.
*/
std::deque<Error>::const_iterator end() const
{
return errors.end();
}
/**
* @brief Return the number of errors in the queue.
*/
size_t numErrors() const
{
return errors.size();
}
/**
* @brief Copy an Error and push it on to the back of the queue.
*
* @param error Reference to an Error object to be copied.
*/
void pushError(const Error &error)
{
errors.push_back(error);
}
/**
* @brief Push an error onto the back of the queue.
*
* @param context Context of the validation error.
* @param description Description of the validation error.
*/
void
pushError(const std::vector<std::string> &context, const std::string &description)
{
errors.push_back(Error(context, description));
}
/**
* @brief Pop an error from the front of the queue.
*
* @param error Reference to an Error object to populate.
*
* @returns true if an Error was popped, false otherwise.
*/
bool
popError(Error &error)
{
if (errors.empty()) {
return false;
}
error = errors.front();
errors.pop_front();
return true;
}
private:
/// FIFO queue of validation errors that have been reported
std::deque<Error> errors;
};
} // namespace valijson
#endif // __VALIJSON_VALIDATION_RESULTS_HPP

1706
3rdparty/valijson/validation_visitor.hpp поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

78
3rdparty/valijson/validator.hpp поставляемый Normal file
Просмотреть файл

@ -0,0 +1,78 @@
#pragma once
#ifndef __VALIJSON_VALIDATOR_HPP
#define __VALIJSON_VALIDATOR_HPP
#include <valijson/schema.hpp>
#include <valijson/validation_visitor.hpp>
namespace valijson {
class Schema;
class ValidationResults;
/**
* @brief Class that provides validation functionality.
*/
class Validator
{
public:
enum TypeCheckingMode
{
kStrongTypes,
kWeakTypes
};
/**
* @brief Construct a Validator that uses strong type checking by default
*/
Validator()
: strictTypes(true) { }
/**
* @brief Construct a Validator using a specific type checking mode
*
* @param typeCheckingMode choice of strong or weak type checking
*/
Validator(TypeCheckingMode typeCheckingMode)
: strictTypes(typeCheckingMode == kStrongTypes) { }
/**
* @brief Validate a JSON document and optionally return the results.
*
* When a ValidationResults object is provided via the \c results parameter,
* validation will be performed against each constraint defined by the
* schema, even if validation fails for some or all constraints.
*
* If a pointer to a ValidationResults instance is not provided, validation
* will only continue for as long as the constraints are validated
* successfully.
*
* @param schema The schema to validate against
* @param target A rapidjson::Value to be validated
*
* @param results An optional pointer to a ValidationResults instance that
* will be used to report validation errors
*
* @returns true if validation succeeds, false otherwise
*/
template<typename AdapterType>
bool validate(const Subschema &schema, const AdapterType &target,
ValidationResults *results)
{
// Construct a ValidationVisitor to perform validation at the root level
ValidationVisitor<AdapterType> v(target,
std::vector<std::string>(1, "<root>"), strictTypes, results);
return v.validateSchema(schema);
}
private:
/// Flag indicating that strict type comparisons should be used
const bool strictTypes;
};
} // namespace valijson
#endif

Просмотреть файл

@ -71,6 +71,15 @@
"commitHash": "9e554999ce02cf86fcdfe74fe740c4fe3f5a56d5"
}
}
},
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/tristanpenman/valijson",
"commitHash": "60e35eb58a0700fd3e0e973c07d3e4b38a8f9502"
}
}
}
],
"Version": 1