mirror of
https://github.com/tristanpenman/valijson.git
synced 2024-12-13 18:45:11 +01:00
Merge branch 'shsfre09-support_picojson'
This commit is contained in:
commit
e1a59c09ba
@ -23,6 +23,7 @@ include_directories(
|
||||
thirdparty/gtest-1.7.0/include
|
||||
thirdparty/jsoncpp-0.9.4/include
|
||||
thirdparty/rapidjson-0.1/include
|
||||
thirdparty/picojson-1.3.0
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
@ -44,11 +45,17 @@ add_executable(test_suite
|
||||
tests/test_jsoncpp_adapter.cpp
|
||||
tests/test_property_tree_adapter.cpp
|
||||
tests/test_rapidjson_adapter.cpp
|
||||
tests/test_picojson_adapter.cpp
|
||||
tests/test_uri_resolution.cpp
|
||||
tests/test_validation_errors.cpp
|
||||
tests/test_validator.cpp
|
||||
)
|
||||
|
||||
# Definition for using picojson
|
||||
set_target_properties(test_suite
|
||||
PROPERTIES COMPILE_DEFINITIONS "PICOJSON_USE_INT64"
|
||||
)
|
||||
|
||||
set(TEST_LIBS gtest gtest_main jsoncpp)
|
||||
|
||||
target_link_libraries(test_suite ${TEST_LIBS} ${Boost_LIBRARIES})
|
||||
|
@ -23,11 +23,12 @@ Required:
|
||||
|
||||
Later versions of boost (up to 1.57) are also known to work correctly.
|
||||
|
||||
Valijson supports JSON documents loaded using JsonCpp, RapidJson and Boost Property Tree. It has been tested against the following versions of these libraries:
|
||||
Valijson supports JSON documents loaded using JsonCpp, RapidJson, Boost Property Tree and PicoJSON. It has been tested against the following versions of these libraries:
|
||||
|
||||
- [boost::property_tree 1.54](http://www.boost.org/doc/libs/1_54_0/doc/html/boost_propertytree/synopsis.html)
|
||||
- [jsoncpp 0.9.4](https://github.com/open-source-parsers/jsoncpp/archive/0.9.4.tar.gz)
|
||||
- [rapidjson 0.1](https://code.google.com/p/rapidjson/downloads/detail?name=rapidjson-0.1.zip)
|
||||
- [PicoJSON 1.3.0](https://github.com/kazuho/picojson/archive/v1.3.0.tar.gz)
|
||||
|
||||
Version of JsonCpp going back to 0.5.0 should also work correctly, but versions from 1.0 onwards have not yet been tested.
|
||||
|
||||
|
691
include/valijson/adapters/picojson_adapter.hpp
Normal file
691
include/valijson/adapters/picojson_adapter.hpp
Normal file
@ -0,0 +1,691 @@
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
#ifndef __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP
|
||||
#define __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
#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.
|
||||
*/
|
||||
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 property 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
|
||||
*/
|
||||
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 boost::optional containing a PicoJsonArray instance referencing the
|
||||
* array.
|
||||
*
|
||||
* Otherwise it will return boost::none.
|
||||
*/
|
||||
boost::optional<PicoJsonArray> getArrayOptional() const
|
||||
{
|
||||
if (value.is<picojson::array>()) {
|
||||
return boost::make_optional(PicoJsonArray(value));
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* boost::optional containing a PicoJsonObject instance referencing the
|
||||
* object.
|
||||
*
|
||||
* Otherwise it will return boost::none.
|
||||
*/
|
||||
boost::optional<PicoJsonObject> getObjectOptional() const
|
||||
{
|
||||
if (value.is<picojson::object>()) {
|
||||
return boost::make_optional(PicoJsonObject(value));
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 boost iterator_facade template.
|
||||
*
|
||||
* @see PicoJsonArray
|
||||
*/
|
||||
class PicoJsonArrayValueIterator:
|
||||
public boost::iterator_facade<
|
||||
PicoJsonArrayValueIterator, // name of derived type
|
||||
PicoJsonAdapter, // value type
|
||||
boost::bidirectional_traversal_tag, // bi-directional iterator
|
||||
PicoJsonAdapter> // type returned when dereferenced
|
||||
{
|
||||
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 dereference() const
|
||||
{
|
||||
return PicoJsonAdapter(*itr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 equal(const PicoJsonArrayValueIterator &other) const
|
||||
{
|
||||
return itr == other.itr;
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
itr--;
|
||||
}
|
||||
|
||||
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 boost::iterator_facade<
|
||||
PicoJsonObjectMemberIterator, // name of derived type
|
||||
PicoJsonObjectMember, // value type
|
||||
boost::bidirectional_traversal_tag, // bi-directional iterator
|
||||
PicoJsonObjectMember> // type returned when dereferenced
|
||||
{
|
||||
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 dereference() const
|
||||
{
|
||||
return PicoJsonObjectMember(itr->first, itr->second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 equal(const PicoJsonObjectMemberIterator &other) const
|
||||
{
|
||||
return itr == other.itr;
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
itr--;
|
||||
}
|
||||
|
||||
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
|
34
include/valijson/utils/picojson_utils.hpp
Normal file
34
include/valijson/utils/picojson_utils.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef __VALIJSON_UTILS_PICOJSON_UTILS_HPP
|
||||
#define __VALIJSON_UTILS_PICOJSON_UTILS_HPP
|
||||
|
||||
#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
|
@ -6,9 +6,11 @@
|
||||
#include <valijson/adapters/jsoncpp_adapter.hpp>
|
||||
#include <valijson/adapters/property_tree_adapter.hpp>
|
||||
#include <valijson/adapters/rapidjson_adapter.hpp>
|
||||
#include <valijson/adapters/picojson_adapter.hpp>
|
||||
#include <valijson/utils/jsoncpp_utils.hpp>
|
||||
#include <valijson/utils/property_tree_utils.hpp>
|
||||
#include <valijson/utils/rapidjson_utils.hpp>
|
||||
#include <valijson/utils/picojson_utils.hpp>
|
||||
|
||||
#define TEST_DATA_DIR "../tests/data/documents/"
|
||||
|
||||
@ -135,6 +137,13 @@ TEST_F(TestAdapterComparison, JsonCppVsRapidJson)
|
||||
valijson::adapters::RapidJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, JsonCppVsPicoJson)
|
||||
{
|
||||
testComparison<
|
||||
valijson::adapters::JsonCppAdapter,
|
||||
valijson::adapters::PicoJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, PropertyTreeVsPropertyTree)
|
||||
{
|
||||
testComparison<
|
||||
@ -149,9 +158,30 @@ TEST_F(TestAdapterComparison, PropertyTreeVsRapidJson)
|
||||
valijson::adapters::RapidJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, PropertyTreeVsPicoJson)
|
||||
{
|
||||
testComparison<
|
||||
valijson::adapters::PropertyTreeAdapter,
|
||||
valijson::adapters::PicoJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, RapidJsonVsRapidJson)
|
||||
{
|
||||
testComparison<
|
||||
valijson::adapters::RapidJsonAdapter,
|
||||
valijson::adapters::RapidJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, RapidJsonVsPicoJson)
|
||||
{
|
||||
testComparison<
|
||||
valijson::adapters::RapidJsonAdapter,
|
||||
valijson::adapters::PicoJsonAdapter>();
|
||||
}
|
||||
|
||||
TEST_F(TestAdapterComparison, PicoJsonVsPicoJson)
|
||||
{
|
||||
testComparison<
|
||||
valijson::adapters::PicoJsonAdapter,
|
||||
valijson::adapters::PicoJsonAdapter>();
|
||||
}
|
||||
|
85
tests/test_picojson_adapter.cpp
Normal file
85
tests/test_picojson_adapter.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <valijson/adapters/picojson_adapter.hpp>
|
||||
|
||||
class TestPicoJsonAdapter : public testing::Test
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
TEST_F(TestPicoJsonAdapter, BasicArrayIteration)
|
||||
{
|
||||
const unsigned int numElements = 10;
|
||||
|
||||
// Create a picojson document that consists of an array of numbers
|
||||
picojson::array array;
|
||||
for (unsigned int i = 0; i < numElements; i++) {
|
||||
picojson::value value(static_cast<double>(i));
|
||||
array.push_back(value);
|
||||
}
|
||||
picojson::value document(array);
|
||||
|
||||
// Ensure that wrapping the document preserves the array and does not allow
|
||||
// it to be cast to other types
|
||||
valijson::adapters::PicoJsonAdapter adapter(document);
|
||||
ASSERT_NO_THROW( adapter.getArray() );
|
||||
ASSERT_ANY_THROW( adapter.getBool() );
|
||||
ASSERT_ANY_THROW( adapter.getDouble() );
|
||||
ASSERT_ANY_THROW( adapter.getObject() );
|
||||
ASSERT_ANY_THROW( adapter.getString() );
|
||||
|
||||
// Ensure that the array contains the expected number of elements
|
||||
EXPECT_EQ( numElements, adapter.getArray().size() );
|
||||
|
||||
// Ensure that the elements are returned in the order they were inserted
|
||||
unsigned int expectedValue = 0;
|
||||
BOOST_FOREACH( const valijson::adapters::PicoJsonAdapter value, adapter.getArray() ) {
|
||||
ASSERT_TRUE( value.isNumber() );
|
||||
EXPECT_EQ( double(expectedValue), value.getDouble() );
|
||||
expectedValue++;
|
||||
}
|
||||
|
||||
// Ensure that the correct number of elements were iterated over
|
||||
EXPECT_EQ(numElements, expectedValue);
|
||||
}
|
||||
|
||||
TEST_F(TestPicoJsonAdapter, BasicObjectIteration)
|
||||
{
|
||||
const unsigned int numElements = 10;
|
||||
|
||||
// Create a picojson document that consists of an object that maps numeric
|
||||
// strings their corresponding numeric values
|
||||
picojson::object object;
|
||||
for (unsigned int i = 0; i < numElements; i++) {
|
||||
std::string name(boost::lexical_cast<std::string>(i));
|
||||
object[name] = picojson::value(static_cast<double>(i));
|
||||
}
|
||||
picojson::value document(object);
|
||||
|
||||
// Ensure that wrapping the document preserves the object and does not
|
||||
// allow it to be cast to other types
|
||||
valijson::adapters::PicoJsonAdapter adapter(document);
|
||||
ASSERT_NO_THROW( adapter.getObject() );
|
||||
ASSERT_ANY_THROW( adapter.getArray() );
|
||||
ASSERT_ANY_THROW( adapter.getBool() );
|
||||
ASSERT_ANY_THROW( adapter.getDouble() );
|
||||
ASSERT_ANY_THROW( adapter.getString() );
|
||||
|
||||
// Ensure that the object contains the expected number of members
|
||||
EXPECT_EQ( numElements, adapter.getObject().size() );
|
||||
|
||||
// Ensure that the members are returned in the order they were inserted
|
||||
unsigned int expectedValue = 0;
|
||||
BOOST_FOREACH( const valijson::adapters::PicoJsonAdapter::ObjectMember member, adapter.getObject() ) {
|
||||
ASSERT_TRUE( member.second.isNumber() );
|
||||
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first );
|
||||
EXPECT_EQ( double(expectedValue), member.second.getDouble() );
|
||||
expectedValue++;
|
||||
}
|
||||
|
||||
// Ensure that the correct number of elements were iterated over
|
||||
EXPECT_EQ( numElements, expectedValue );
|
||||
}
|
@ -7,8 +7,10 @@
|
||||
|
||||
#include <valijson/adapters/jsoncpp_adapter.hpp>
|
||||
#include <valijson/adapters/rapidjson_adapter.hpp>
|
||||
#include <valijson/adapters/picojson_adapter.hpp>
|
||||
#include <valijson/utils/jsoncpp_utils.hpp>
|
||||
#include <valijson/utils/rapidjson_utils.hpp>
|
||||
#include <valijson/utils/picojson_utils.hpp>
|
||||
#include <valijson/schema.hpp>
|
||||
#include <valijson/schema_parser.hpp>
|
||||
#include <valijson/validation_results.hpp>
|
||||
@ -111,6 +113,7 @@ protected:
|
||||
{
|
||||
processTestFile<valijson::adapters::JsonCppAdapter>(testFile, version);
|
||||
processTestFile<valijson::adapters::RapidJsonAdapter>(testFile, version);
|
||||
processTestFile<valijson::adapters::PicoJsonAdapter>(testFile, version);
|
||||
}
|
||||
|
||||
void processDraft3TestFile(const std::string &testFile)
|
||||
|
4
thirdparty/picojson-1.3.0/.gitignore
vendored
Normal file
4
thirdparty/picojson-1.3.0/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*~
|
||||
a.out
|
||||
test-core
|
||||
test-core-int64
|
0
thirdparty/picojson-1.3.0/.gitmodules
vendored
Normal file
0
thirdparty/picojson-1.3.0/.gitmodules
vendored
Normal file
8
thirdparty/picojson-1.3.0/.travis.yml
vendored
Normal file
8
thirdparty/picojson-1.3.0/.travis.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
script:
|
||||
- make test
|
25
thirdparty/picojson-1.3.0/Changes
vendored
Normal file
25
thirdparty/picojson-1.3.0/Changes
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Revision history for picojson
|
||||
|
||||
1.3.0 2015-02-25 13:05:00+0900
|
||||
- `make check` is now synonym of `make test` (#62)
|
||||
- operator= is now safe when part of LHS is being assigned, as well as exception-safe (#66)
|
||||
|
||||
1.2.1 2014-12-16 15:33:00+0900
|
||||
- bundle the contents of `picotest/` (#61)
|
||||
|
||||
1.2.0 2014-12-15 16:20:00+0900
|
||||
- `make install` to install picojson.h (#58)
|
||||
- two-argument `picojson::parse()` for ease-of-use (#57)
|
||||
|
||||
1.1.1 2014-06-25 10:35:00+0900
|
||||
- tweaks to suppress compiler errors / warning (#38 #39)
|
||||
- clarify the licenses of the files in exmaple/ (#42)
|
||||
|
||||
1.1 2014-06-16 12:57:00+0900
|
||||
- added experimental support for int64 type (#34)
|
||||
- by default, throw std::runtime_error instead of using assert for runtime errors (#33)
|
||||
- refine compatibility regarding the use of isinf/isnan (#29, #36)
|
||||
- remove `.get<int>()` (#35)
|
||||
|
||||
1.0 2014-06-05 12:54:00+0900
|
||||
- initial release with a version number
|
25
thirdparty/picojson-1.3.0/LICENSE
vendored
Normal file
25
thirdparty/picojson-1.3.0/LICENSE
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright 2009-2010 Cybozu Labs, Inc.
|
||||
Copyright 2011-2014 Kazuho Oku
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
26
thirdparty/picojson-1.3.0/Makefile
vendored
Normal file
26
thirdparty/picojson-1.3.0/Makefile
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
prefix=/usr/local
|
||||
includedir=$(prefix)/include
|
||||
|
||||
check: test
|
||||
|
||||
test: test-core test-core-int64
|
||||
./test-core
|
||||
./test-core-int64
|
||||
|
||||
test-core: test.cc picotest/picotest.c picotest/picotest.h
|
||||
$(CXX) -Wall test.cc picotest/picotest.c -o $@
|
||||
|
||||
test-core-int64: test.cc picotest/picotest.c picotest/picotest.h
|
||||
$(CXX) -Wall -DPICOJSON_USE_INT64 test.cc picotest/picotest.c -o $@
|
||||
|
||||
clean:
|
||||
rm -f test-core test-core-int64
|
||||
|
||||
install:
|
||||
install -d $(DESTDIR)$(includedir)
|
||||
install -p -m 0644 picojson.h $(DESTDIR)$(includedir)
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(includedir)/picojson.h
|
||||
|
||||
.PHONY: test check clean install uninstall
|
195
thirdparty/picojson-1.3.0/README.mkdn
vendored
Normal file
195
thirdparty/picojson-1.3.0/README.mkdn
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
# PicoJSON - a C++ JSON parser / serializer
|
||||
|
||||
Copyright © 2009-2010 Cybozu Labs, Inc.
|
||||
Copyright © 2011-2015 Kazuho Oku
|
||||
|
||||
Licensed under [2-clause BSD license](http://opensource.org/licenses/BSD-2-Clause)
|
||||
|
||||
## Version
|
||||
|
||||
1.3.0 [![Build Status](https://travis-ci.org/kazuho/picojson.svg?branch=rel/1.3.0)](https://travis-ci.org/kazuho/picojson)
|
||||
|
||||
## Introduction
|
||||
|
||||
PicoJSON is a tiny JSON parser / serializer for C++ with following properties:
|
||||
|
||||
- header-file only
|
||||
- no external dependencies (only uses standard C++ libraries)
|
||||
- STL-frendly (arrays are represented by using std::vector, objects are std::map)
|
||||
- provides both pull interface and streaming (event-based) interface
|
||||
|
||||
## Reading JSON using the pull interface
|
||||
|
||||
There are several ways to use the pull (DOM-like) interface of picojson.
|
||||
|
||||
The easiest way is to use the two-argument `parse` function.
|
||||
|
||||
```
|
||||
std::string json = "[ \"hello JSON\" ]";
|
||||
picojson::value v;
|
||||
std::string err = picojson::parse(v, json);
|
||||
if (! err.empty()) {
|
||||
std:cerr << err << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
Four-argument `parse` function accepts a pair of iterators, and returns the end position of the input.
|
||||
|
||||
```
|
||||
const char* json = "{\"a\":1}";
|
||||
picojson::value v;
|
||||
std::string err;
|
||||
const char* json_end = picojson::parse(v, json, json + strlen(json), &err);
|
||||
if (! err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
std::istream_iterator input(std::cin);
|
||||
picojson::value v;
|
||||
std::string err;
|
||||
input = picojson::parse(v, input, std::istream_iterator(), &err);
|
||||
if (! err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
It is also possible to use the `>>` operator to parse the input, however this interface is not thread-safe.
|
||||
|
||||
```
|
||||
picosjon::value v;
|
||||
std::cin >> v;
|
||||
std::string err = picojson::get_last_error();
|
||||
```
|
||||
|
||||
## Accessing the values
|
||||
|
||||
Values of a JSON object is represented as instances of picojson::value class.
|
||||
|
||||
<pre>
|
||||
namespace picojson {
|
||||
|
||||
class value {
|
||||
...
|
||||
|
||||
public:
|
||||
|
||||
typedef std::vector<value> array;
|
||||
typedef std::map<std::string, value> object;
|
||||
|
||||
value(); // create a null object
|
||||
explicit value(bool b); // create a boolean object
|
||||
explicit value(double n); // create a number object
|
||||
explicit value(const std::string& s); // create a string object
|
||||
explicit value(const array& a); // create an array object
|
||||
explicit value(const object& o); // create an "object"
|
||||
|
||||
bool is<picojson::null>() const; // check if the object is "null"
|
||||
|
||||
bool is<bool>() const; // check if the object is a boolean
|
||||
const bool& get<bool>() const; // const accessor (usable only if the object is a boolean)
|
||||
bool& get<bool>(); // non-const accessor (usable only if the object is a boolean)
|
||||
|
||||
bool is<double>() const; // check if the object is a number
|
||||
const double& get<double>() const; // const accessor (usable only if the object is a number)
|
||||
double& get<double>(); // non-const accessor (usable only if the object is a number)
|
||||
|
||||
bool is<std::string>() const; // check if the object is a string
|
||||
const std::string& get<std::string>() const;
|
||||
// const accessor (usable only if the object is a string)
|
||||
std::string& get<std::string>(); // non-const accessor (usable only if the object is a string)
|
||||
|
||||
bool is<array>() const; // check if the object is an array
|
||||
const array& get<array>() const; // const accessor (usable only if the object is an array)
|
||||
array& get<array>(); // non-const accessor (usable only if the object is an array)
|
||||
|
||||
bool is<object>() const; // check if the object is an "object"
|
||||
const object& get<object>() const; // const accessor (usable only if the object is an object)
|
||||
object& get<object>(); // non-const accessor (usable only if the object is an array)
|
||||
|
||||
bool evaluate_as_boolean() const; // evaluates the object as a boolean
|
||||
|
||||
std::string serialize() const; // returns the object in JSON representation
|
||||
template<typename Iter> void serialize(Iter os) const;
|
||||
// serializes the object in JSON representation through an output iterator
|
||||
|
||||
std::string to_str() const; // returns the object in string (for casual use)
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
The code below parses a JSON string and prints the contents of the object.
|
||||
|
||||
<pre>
|
||||
picojson::value v;
|
||||
|
||||
// parse the input
|
||||
std::cin >> v;
|
||||
std::string err = picojson::get_last_error();
|
||||
if (! err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// check if the type of the value is "object"
|
||||
if (! v.is<picojson::object>()) {
|
||||
std::cerr << "JSON is not an object" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// obtain a const reference to the map, and print the contents
|
||||
const picojson::value::object& obj = v.get<picojson::object>();
|
||||
for (picojson::value::object::const_iterator i = obj.begin();
|
||||
i != obj.end();
|
||||
++i) {
|
||||
std::cout << i->first << ': ' << i->second.to_str() << std::endl;
|
||||
}
|
||||
</pre>
|
||||
|
||||
Please note that the type check is mandatory; do not forget to check the type of the object by calling is<type>() before accessing the value by calling get<type>().
|
||||
|
||||
## Reading JSON using the streaming (event-driven) interface
|
||||
|
||||
Please refer to the implementation of picojson::default_parse_context and picojson::null_parse_context. There is also an example (examples/streaming.cc) .
|
||||
|
||||
## Serializing to JSON
|
||||
|
||||
Instances of the picojson::value class can be serialized in three ways, to ostream, to std::string, or to an output iterator.
|
||||
|
||||
<pre>
|
||||
picojson::value v;
|
||||
...
|
||||
std::cout << v;
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
picojson::value v;
|
||||
...
|
||||
std::string json = v.serialize();
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
picojson::value v;
|
||||
...
|
||||
v.serialize(std::ostream_iterator(std::cout));
|
||||
</pre>
|
||||
|
||||
## Experimental support for int64_t
|
||||
|
||||
Experimental suport for int64_t becomes available if the code is compiled with preprocessor macro `PICOJSON_USE_INT64`.
|
||||
|
||||
Turning on the feature will cause following changes to picojson:
|
||||
- new constructor `picojson::value(int64_t)` is defined
|
||||
- `is<int64_t>()` and `get<int64_t>()` become available
|
||||
- numerics in JSON within the bounds of int64_t and not using `.` nor `e`/`E` are considered as int64 type
|
||||
- the values are also avaliable as `double`s as well (i.e. all values which are `.is<int64_t>() == true` are also `.is<double>() == true`)
|
||||
- int64 values are converted to double once `get<double>()` is called
|
||||
|
||||
Enabling the feature should not cause compatibility problem with code that do not use the feature.
|
||||
|
||||
## Further reading
|
||||
|
||||
Examples can be found in the <i>examples</i> directory, and on the [Wiki](https://github.com/kazuho/picojson/wiki). Please add your favorite examples to the Wiki.
|
110
thirdparty/picojson-1.3.0/examples/github-issues.cc
vendored
Normal file
110
thirdparty/picojson-1.3.0/examples/github-issues.cc
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2009-2010 Cybozu Labs, Inc.
|
||||
* Copyright 2011-2014 Kazuho Oku
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include "../picojson.h"
|
||||
|
||||
typedef struct {
|
||||
char* data; // response data from server
|
||||
size_t size; // response size of data
|
||||
} MEMFILE;
|
||||
|
||||
MEMFILE*
|
||||
memfopen() {
|
||||
MEMFILE* mf = (MEMFILE*) malloc(sizeof(MEMFILE));
|
||||
mf->data = NULL;
|
||||
mf->size = 0;
|
||||
return mf;
|
||||
}
|
||||
|
||||
void
|
||||
memfclose(MEMFILE* mf) {
|
||||
if (mf->data) free(mf->data);
|
||||
free(mf);
|
||||
}
|
||||
|
||||
size_t
|
||||
memfwrite(char* ptr, size_t size, size_t nmemb, void* stream) {
|
||||
MEMFILE* mf = (MEMFILE*) stream;
|
||||
int block = size * nmemb;
|
||||
if (!mf->data)
|
||||
mf->data = (char*) malloc(block);
|
||||
else
|
||||
mf->data = (char*) realloc(mf->data, mf->size + block);
|
||||
if (mf->data) {
|
||||
memcpy(mf->data + mf->size, ptr, block);
|
||||
mf->size += block;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
char*
|
||||
memfstrdup(MEMFILE* mf) {
|
||||
char* buf = (char*)malloc(mf->size + 1);
|
||||
memcpy(buf, mf->data, mf->size);
|
||||
buf[mf->size] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace picojson;
|
||||
|
||||
int
|
||||
main(int argc, char* argv[]) {
|
||||
char error[256];
|
||||
|
||||
MEMFILE* mf = memfopen();
|
||||
CURL* curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://api.github.com/repos/kazuho/picojson/issues");
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl");
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf);
|
||||
if (curl_easy_perform(curl) != CURLE_OK) {
|
||||
cerr << error << endl;
|
||||
} else {
|
||||
value v;
|
||||
string err;
|
||||
parse(v, mf->data, mf->data + mf->size, &err);
|
||||
if (err.empty()) {
|
||||
array arr = v.get<array>();
|
||||
array::iterator it;
|
||||
for (it = arr.begin(); it != arr.end(); it++) {
|
||||
object obj = it->get<object>();
|
||||
cout << "#" << obj["number"].to_str() << ": " << obj["title"].to_str() << endl;
|
||||
cout << " " << obj["html_url"].to_str() << endl << endl;
|
||||
}
|
||||
} else {
|
||||
cerr << err << endl;
|
||||
}
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
memfclose(mf);
|
||||
|
||||
return 0;
|
||||
}
|
70
thirdparty/picojson-1.3.0/examples/iostream.cc
vendored
Normal file
70
thirdparty/picojson-1.3.0/examples/iostream.cc
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2009-2010 Cybozu Labs, Inc.
|
||||
* Copyright 2011-2014 Kazuho Oku
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "../picojson.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
picojson::value v;
|
||||
|
||||
// read json value from stream
|
||||
std::cin >> v;
|
||||
if (std::cin.fail()) {
|
||||
std::cerr << picojson::get_last_error() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// dump json object
|
||||
std::cout << "---- dump input ----" << std::endl;
|
||||
std::cout << v << std::endl;
|
||||
|
||||
// accessors
|
||||
std::cout << "---- analyzing input ----" << std::endl;
|
||||
if (v.is<picojson::null>()) {
|
||||
std::cout << "input is null" << std::endl;
|
||||
} else if (v.is<bool>()) {
|
||||
std::cout << "input is " << (v.get<bool>() ? "true" : "false") << std::endl;
|
||||
} else if (v.is<double>()) {
|
||||
std::cout << "input is " << v.get<double>() << std::endl;
|
||||
} else if (v.is<std::string>()) {
|
||||
std::cout << "input is " << v.get<std::string>() << std::endl;
|
||||
} else if (v.is<picojson::array>()) {
|
||||
std::cout << "input is an array" << std::endl;
|
||||
const picojson::array& a = v.get<picojson::array>();
|
||||
for (picojson::array::const_iterator i = a.begin(); i != a.end(); ++i) {
|
||||
std::cout << " " << *i << std::endl;
|
||||
}
|
||||
} else if (v.is<picojson::object>()) {
|
||||
std::cout << "input is an object" << std::endl;
|
||||
const picojson::object& o = v.get<picojson::object>();
|
||||
for (picojson::object::const_iterator i = o.begin(); i != o.end(); ++i) {
|
||||
std::cout << i->first << " " << i->second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
76
thirdparty/picojson-1.3.0/examples/streaming.cc
vendored
Normal file
76
thirdparty/picojson-1.3.0/examples/streaming.cc
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2009-2010 Cybozu Labs, Inc.
|
||||
* Copyright 2011-2014 Kazuho Oku
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include "../picojson.h"
|
||||
|
||||
// this example reads a array of hashes (each item representing a 2D point),
|
||||
// and prints the x and y values to stdout
|
||||
|
||||
namespace {
|
||||
|
||||
class root_context : public picojson::deny_parse_context {
|
||||
public:
|
||||
bool parse_array_start() {
|
||||
return true; // only allow array as root
|
||||
}
|
||||
template <typename Iter> bool parse_array_item(picojson::input<Iter>& in, size_t) {
|
||||
picojson::value item;
|
||||
// parse the array item
|
||||
picojson::default_parse_context ctx(&item);
|
||||
if (! picojson::_parse(ctx, in)) {
|
||||
return false;
|
||||
}
|
||||
// assert that the array item is a hash
|
||||
if (! item.is<picojson::object>()) {
|
||||
return false;
|
||||
}
|
||||
// print x and y
|
||||
std::cout << item.get("x") << ',' << item.get("y").to_str()
|
||||
<< std::endl;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
root_context ctx;
|
||||
std::string err;
|
||||
|
||||
picojson::_parse(ctx, std::istream_iterator<char>(std::cin),
|
||||
std::istream_iterator<char>(), &err);
|
||||
|
||||
if (! err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
1010
thirdparty/picojson-1.3.0/picojson.h
vendored
Normal file
1010
thirdparty/picojson-1.3.0/picojson.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
99
thirdparty/picojson-1.3.0/picotest/picotest.c
vendored
Normal file
99
thirdparty/picojson-1.3.0/picotest/picotest.c
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2014 DeNA Co., Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "picotest.h"
|
||||
|
||||
struct test_t {
|
||||
int num_tests;
|
||||
int failed;
|
||||
};
|
||||
struct test_t main_tests, *cur_tests = &main_tests;
|
||||
static int test_level = 0;
|
||||
|
||||
static void indent(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i != test_level; ++i)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 1, 2)))
|
||||
void note(const char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
indent();
|
||||
printf("# ");
|
||||
|
||||
va_start(arg, fmt);
|
||||
vprintf(fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
void _ok(int cond, const char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
if (! cond)
|
||||
cur_tests->failed = 1;
|
||||
indent();
|
||||
|
||||
printf("%s %d - ", cond ? "ok" : "not ok", ++cur_tests->num_tests);
|
||||
va_start(arg, fmt);
|
||||
vprintf(fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int done_testing(void)
|
||||
{
|
||||
indent();
|
||||
printf("1..%d\n", cur_tests->num_tests);
|
||||
return cur_tests->failed;
|
||||
}
|
||||
|
||||
void subtest(const char *name, void (*cb)(void))
|
||||
{
|
||||
struct test_t test = {}, *parent_tests;
|
||||
|
||||
parent_tests = cur_tests;
|
||||
cur_tests = &test;
|
||||
++test_level;
|
||||
|
||||
note("Subtest: %s", name);
|
||||
|
||||
cb();
|
||||
|
||||
done_testing();
|
||||
|
||||
--test_level;
|
||||
cur_tests = parent_tests;
|
||||
if (test.failed)
|
||||
cur_tests->failed = 1;
|
||||
_ok(! test.failed, "%s", name);
|
||||
}
|
39
thirdparty/picojson-1.3.0/picotest/picotest.h
vendored
Normal file
39
thirdparty/picojson-1.3.0/picotest/picotest.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2014 DeNA Co., Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef picotest_h
|
||||
#define picotest_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void note(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
void _ok(int cond, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
|
||||
#define ok(cond) _ok(cond, "%s %d", __FILE__, __LINE__)
|
||||
int done_testing(void);
|
||||
void subtest(const char *name, void (*cb)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
312
thirdparty/picojson-1.3.0/test.cc
vendored
Normal file
312
thirdparty/picojson-1.3.0/test.cc
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright 2009-2010 Cybozu Labs, Inc.
|
||||
* Copyright 2011-2014 Kazuho Oku, Yasuhiro Matsumoto, Shigeo Mitsunari
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "picojson.h"
|
||||
#include "picotest/picotest.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define is(x, y, name) _ok((x) == (y), name)
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if PICOJSON_USE_LOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
// constructors
|
||||
#define TEST(expr, expected) \
|
||||
is(picojson::value expr .serialize(), string(expected), "picojson::value" #expr)
|
||||
|
||||
TEST( (true), "true");
|
||||
TEST( (false), "false");
|
||||
TEST( (42.0), "42");
|
||||
TEST( (string("hello")), "\"hello\"");
|
||||
TEST( ("hello"), "\"hello\"");
|
||||
TEST( ("hello", 4), "\"hell\"");
|
||||
|
||||
{
|
||||
double a = 1;
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
picojson::value vi(a);
|
||||
std::stringstream ss;
|
||||
ss << vi;
|
||||
picojson::value vo;
|
||||
ss >> vo;
|
||||
double b = vo.get<double>();
|
||||
if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) {
|
||||
printf("ng i=%d a=%.18e b=%.18e\n", i, a, b);
|
||||
}
|
||||
a *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#undef TEST
|
||||
|
||||
#define TEST(in, type, cmp, serialize_test) { \
|
||||
picojson::value v; \
|
||||
const char* s = in; \
|
||||
string err = picojson::parse(v, s, s + strlen(s)); \
|
||||
_ok(err.empty(), in " no error"); \
|
||||
_ok(v.is<type>(), in " check type"); \
|
||||
is(v.get<type>(), static_cast<type>(cmp), in " correct output"); \
|
||||
is(*s, '\0', in " read to eof"); \
|
||||
if (serialize_test) { \
|
||||
is(v.serialize(), string(in), in " serialize"); \
|
||||
} \
|
||||
}
|
||||
TEST("false", bool, false, true);
|
||||
TEST("true", bool, true, true);
|
||||
TEST("90.5", double, 90.5, false);
|
||||
TEST("1.7976931348623157e+308", double, DBL_MAX, false);
|
||||
TEST("\"hello\"", string, string("hello"), true);
|
||||
TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"),
|
||||
true);
|
||||
TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string,
|
||||
string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"), false);
|
||||
TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false);
|
||||
#ifdef PICOJSON_USE_INT64
|
||||
TEST("0", int64_t, 0, true);
|
||||
TEST("-9223372036854775808", int64_t, std::numeric_limits<int64_t>::min(), true);
|
||||
TEST("9223372036854775807", int64_t, std::numeric_limits<int64_t>::max(), true);
|
||||
#endif
|
||||
#undef TEST
|
||||
|
||||
#define TEST(type, expr) { \
|
||||
picojson::value v; \
|
||||
const char *s = expr; \
|
||||
string err = picojson::parse(v, s, s + strlen(s)); \
|
||||
_ok(err.empty(), "empty " #type " no error"); \
|
||||
_ok(v.is<picojson::type>(), "empty " #type " check type"); \
|
||||
_ok(v.get<picojson::type>().empty(), "check " #type " array size"); \
|
||||
}
|
||||
TEST(array, "[]");
|
||||
TEST(object, "{}");
|
||||
#undef TEST
|
||||
|
||||
{
|
||||
picojson::value v;
|
||||
const char *s = "[1,true,\"hello\"]";
|
||||
string err = picojson::parse(v, s, s + strlen(s));
|
||||
_ok(err.empty(), "array no error");
|
||||
_ok(v.is<picojson::array>(), "array check type");
|
||||
is(v.get<picojson::array>().size(), size_t(3), "check array size");
|
||||
_ok(v.contains(0), "check contains array[0]");
|
||||
_ok(v.get(0).is<double>(), "check array[0] type");
|
||||
is(v.get(0).get<double>(), 1.0, "check array[0] value");
|
||||
_ok(v.contains(1), "check contains array[1]");
|
||||
_ok(v.get(1).is<bool>(), "check array[1] type");
|
||||
_ok(v.get(1).get<bool>(), "check array[1] value");
|
||||
_ok(v.contains(2), "check contains array[2]");
|
||||
_ok(v.get(2).is<string>(), "check array[2] type");
|
||||
is(v.get(2).get<string>(), string("hello"), "check array[2] value");
|
||||
_ok(!v.contains(3), "check not contains array[3]");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v;
|
||||
const char *s = "{ \"a\": true }";
|
||||
string err = picojson::parse(v, s, s + strlen(s));
|
||||
_ok(err.empty(), "object no error");
|
||||
_ok(v.is<picojson::object>(), "object check type");
|
||||
is(v.get<picojson::object>().size(), size_t(1), "check object size");
|
||||
_ok(v.contains("a"), "check contains property");
|
||||
_ok(v.get("a").is<bool>(), "check bool property exists");
|
||||
is(v.get("a").get<bool>(), true, "check bool property value");
|
||||
is(v.serialize(), string("{\"a\":true}"), "serialize object");
|
||||
_ok(!v.contains("z"), "check not contains property");
|
||||
}
|
||||
|
||||
#define TEST(json, msg) do { \
|
||||
picojson::value v; \
|
||||
const char *s = json; \
|
||||
string err = picojson::parse(v, s, s + strlen(s)); \
|
||||
is(err, string("syntax error at line " msg), msg); \
|
||||
} while (0)
|
||||
TEST("falsoa", "1 near: oa");
|
||||
TEST("{]", "1 near: ]");
|
||||
TEST("\n\bbell", "2 near: bell");
|
||||
TEST("\"abc\nd\"", "1 near: ");
|
||||
#undef TEST
|
||||
|
||||
{
|
||||
picojson::value v1, v2;
|
||||
const char *s;
|
||||
string err;
|
||||
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
||||
err = picojson::parse(v1, s, s + strlen(s));
|
||||
s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }";
|
||||
err = picojson::parse(v2, s, s + strlen(s));
|
||||
_ok((v1 == v2), "check == operator in deep comparison");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v1, v2;
|
||||
const char *s;
|
||||
string err;
|
||||
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
||||
err = picojson::parse(v1, s, s + strlen(s));
|
||||
s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }";
|
||||
err = picojson::parse(v2, s, s + strlen(s));
|
||||
_ok((v1 != v2), "check != operator for array in deep comparison");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v1, v2;
|
||||
const char *s;
|
||||
string err;
|
||||
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
||||
err = picojson::parse(v1, s, s + strlen(s));
|
||||
s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }";
|
||||
err = picojson::parse(v2, s, s + strlen(s));
|
||||
_ok((v1 != v2), "check != operator for object in deep comparison");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v1, v2;
|
||||
const char *s;
|
||||
string err;
|
||||
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
||||
err = picojson::parse(v1, s, s + strlen(s));
|
||||
picojson::object& o = v1.get<picojson::object>();
|
||||
o.erase("b");
|
||||
picojson::array& a = o["a"].get<picojson::array>();
|
||||
picojson::array::iterator i;
|
||||
i = std::remove(a.begin(), a.end(), picojson::value(std::string("three")));
|
||||
a.erase(i, a.end());
|
||||
s = "{ \"a\": [1,2], \"d\": 2 }";
|
||||
err = picojson::parse(v2, s, s + strlen(s));
|
||||
_ok((v1 == v2), "check erase()");
|
||||
}
|
||||
|
||||
_ok(picojson::value(3.0).serialize() == "3",
|
||||
"integral number should be serialized as a integer");
|
||||
|
||||
{
|
||||
const char* s = "{ \"a\": [1,2], \"d\": 2 }";
|
||||
picojson::null_parse_context ctx;
|
||||
string err;
|
||||
picojson::_parse(ctx, s, s + strlen(s), &err);
|
||||
_ok(err.empty(), "null_parse_context");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v1, v2;
|
||||
v1 = picojson::value(true);
|
||||
swap(v1, v2);
|
||||
_ok(v1.is<picojson::null>(), "swap (null)");
|
||||
_ok(v2.get<bool>() == true, "swap (bool)");
|
||||
|
||||
v1 = picojson::value("a");
|
||||
v2 = picojson::value(1.0);
|
||||
swap(v1, v2);
|
||||
_ok(v1.get<double>() == 1.0, "swap (dobule)");
|
||||
_ok(v2.get<string>() == "a", "swap (string)");
|
||||
|
||||
v1 = picojson::value(picojson::object());
|
||||
v2 = picojson::value(picojson::array());
|
||||
swap(v1, v2);
|
||||
_ok(v1.is<picojson::array>(), "swap (array)");
|
||||
_ok(v2.is<picojson::object>(), "swap (object)");
|
||||
}
|
||||
|
||||
{
|
||||
picojson::value v;
|
||||
const char *s = "{ \"a\": 1, \"b\": [ 2, { \"b1\": \"abc\" } ], \"c\": {}, \"d\": [] }";
|
||||
string err;
|
||||
err = picojson::parse(v, s, s + strlen(s));
|
||||
_ok(err.empty(), "parse test data for prettifying output");
|
||||
_ok(v.serialize() == "{\"a\":1,\"b\":[2,{\"b1\":\"abc\"}],\"c\":{},\"d\":[]}", "non-prettifying output");
|
||||
_ok(v.serialize(true) == "{\n \"a\": 1,\n \"b\": [\n 2,\n {\n \"b1\": \"abc\"\n }\n ],\n \"c\": {},\n \"d\": []\n}\n", "prettifying output");
|
||||
}
|
||||
|
||||
try {
|
||||
picojson::value v(std::numeric_limits<double>::quiet_NaN());
|
||||
_ok(false, "should not accept NaN");
|
||||
} catch (std::overflow_error e) {
|
||||
_ok(true, "should not accept NaN");
|
||||
}
|
||||
|
||||
try {
|
||||
picojson::value v(std::numeric_limits<double>::infinity());
|
||||
_ok(false, "should not accept infinity");
|
||||
} catch (std::overflow_error e) {
|
||||
_ok(true, "should not accept infinity");
|
||||
}
|
||||
|
||||
try {
|
||||
picojson::value v(123.);
|
||||
_ok(! v.is<bool>(), "is<wrong_type>() should return false");
|
||||
v.get<bool>();
|
||||
_ok(false, "get<wrong_type>() should raise an error");
|
||||
} catch (std::runtime_error e) {
|
||||
_ok(true, "get<wrong_type>() should raise an error");
|
||||
}
|
||||
|
||||
#ifdef PICOJSON_USE_INT64
|
||||
{
|
||||
picojson::value v1((int64_t)123);
|
||||
_ok(v1.is<int64_t>(), "is int64_t");
|
||||
_ok(v1.is<double>(), "is double as well");
|
||||
_ok(v1.serialize() == "123", "serialize the value");
|
||||
_ok(v1.get<int64_t>() == 123, "value is correct as int64_t");
|
||||
_ok(v1.get<double>(), "value is correct as double");
|
||||
|
||||
_ok(! v1.is<int64_t>(), "is no more int64_type once get<double>() is called");
|
||||
_ok(v1.is<double>(), "and is still a double");
|
||||
|
||||
const char *s = "-9223372036854775809";
|
||||
_ok(picojson::parse(v1, s, s + strlen(s)).empty(), "parse underflowing int64_t");
|
||||
_ok(! v1.is<int64_t>(), "underflowing int is not int64_t");
|
||||
_ok(v1.is<double>(), "underflowing int is double");
|
||||
_ok(v1.get<double>() + 9.22337203685478e+18 < 65536, "double value is somewhat correct");
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
picojson::value v;
|
||||
std::string err = picojson::parse(v, "[ 1, \"abc\" ]");
|
||||
_ok(err.empty(), "simple API no error");
|
||||
_ok(v.is<picojson::array>(), "simple API return type is array");
|
||||
is(v.get<picojson::array>().size(), 2, "simple API array size");
|
||||
_ok(v.get<picojson::array>()[0].is<double>(), "simple API type #0");
|
||||
is(v.get<picojson::array>()[0].get<double>(), 1, "simple API value #0");
|
||||
_ok(v.get<picojson::array>()[1].is<std::string>(), "simple API type #1");
|
||||
is(v.get<picojson::array>()[1].get<std::string>(), "abc", "simple API value #1");
|
||||
}
|
||||
|
||||
return done_testing();
|
||||
}
|
Loading…
Reference in New Issue
Block a user