json: move tree parsing code to json::tree
This commit is contained in:
parent
ebd1087087
commit
cfc0f8ecd0
@ -52,9 +52,9 @@ util::colour<T>::BLUE (0.f, 0.f, 1.f, 1.f);
|
||||
//! Extract a colour object from a JSON node.
|
||||
//!
|
||||
//! Data must be an array or 3 or 4 numbers. Guarantees success, or throws a
|
||||
//! json::type_error.
|
||||
const json::node&
|
||||
operator>> (const json::node &node, colour4f &c) {
|
||||
//! json::tree::type_error.
|
||||
const json::tree::node&
|
||||
operator>> (const json::tree::node &node, colour4f &c) {
|
||||
c.r = static_cast<float> (node[0].as_number ());
|
||||
c.g = static_cast<float> (node[1].as_number ());
|
||||
c.b = static_cast<float> (node[2].as_number ());
|
||||
|
@ -41,7 +41,7 @@ namespace util {
|
||||
|
||||
typedef colour<float> colour4f;
|
||||
|
||||
const json::node& operator>> (const json::node&, util::colour4f&);
|
||||
const json::tree::node& operator>> (const json::tree::node&, util::colour4f&);
|
||||
std::ostream& operator<< (std::ostream&, const util::colour4f&);
|
||||
}
|
||||
|
||||
|
158
json.cpp.rl
158
json.cpp.rl
@ -44,7 +44,7 @@ using namespace util;
|
||||
// Parsing
|
||||
|
||||
struct parse_context {
|
||||
parse_context(json::node *_root):
|
||||
parse_context(json::tree::node *_root):
|
||||
root (_root),
|
||||
value (NULL),
|
||||
key (NULL),
|
||||
@ -52,7 +52,7 @@ struct parse_context {
|
||||
stop (NULL)
|
||||
{ ; }
|
||||
|
||||
json::node *root,
|
||||
json::tree::node *root,
|
||||
*value,
|
||||
*key;
|
||||
const char *start,
|
||||
@ -76,8 +76,8 @@ struct parse_context {
|
||||
}
|
||||
|
||||
|
||||
action new_object { nodestack.push_back (parse_context(new json::object)); }
|
||||
action new_array { nodestack.push_back (parse_context(new json::array)); }
|
||||
action new_object { nodestack.push_back (parse_context(new json::tree::object)); }
|
||||
action new_array { nodestack.push_back (parse_context(new json::tree::array)); }
|
||||
|
||||
action new_object_value {
|
||||
CHECK (nodestack.back ().root->is_object ());
|
||||
@ -87,9 +87,9 @@ struct parse_context {
|
||||
if (!nodestack.back ().key->is_string ())
|
||||
throw parse_error ("object keys must be strings");
|
||||
|
||||
json::object *object = (json::object*)nodestack.back ().root;
|
||||
json::tree::object *object = (json::tree::object*)nodestack.back ().root;
|
||||
object->insert (nodestack.back ().key->as_string (),
|
||||
unique_ptr<json::node> (nodestack.back ().value));
|
||||
unique_ptr<json::tree::node> (nodestack.back ().value));
|
||||
nodestack.back ().key = NULL;
|
||||
nodestack.back ().value = NULL;
|
||||
}
|
||||
@ -98,8 +98,8 @@ struct parse_context {
|
||||
CHECK (nodestack.back ().root->is_array ());
|
||||
CHECK (nodestack.back ().value);
|
||||
|
||||
json::array *array = (json::array *)nodestack.back ().root;
|
||||
array->insert (unique_ptr<json::node> (nodestack.back ().value));
|
||||
json::tree::array *array = (json::tree::array *)nodestack.back ().root;
|
||||
array->insert (unique_ptr<json::tree::node> (nodestack.back ().value));
|
||||
nodestack.back ().value = NULL;
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ struct parse_context {
|
||||
|
||||
std::string value (std::string (nodestack.back ().start,
|
||||
nodestack.back ().stop));
|
||||
nodestack.back ().value = new json::string(value);
|
||||
nodestack.back ().value = new json::tree::string(value);
|
||||
}
|
||||
|
||||
action new_boolean {
|
||||
@ -133,14 +133,14 @@ struct parse_context {
|
||||
double value = strtod (back.start, &end);
|
||||
if (end == back.start || errno)
|
||||
throw parse_error ("unable to parse number");
|
||||
back.value = new json::number (value);
|
||||
back.value = new json::tree::number (value);
|
||||
}
|
||||
|
||||
action new_null {
|
||||
CHECK (!nodestack.empty ());
|
||||
CHECK (!nodestack.back ().value);
|
||||
|
||||
nodestack.back().value = new json::null ();
|
||||
nodestack.back().value = new json::tree::null ();
|
||||
}
|
||||
|
||||
action new_object_key {
|
||||
@ -199,8 +199,8 @@ struct parse_context {
|
||||
|
||||
## other
|
||||
boolean =
|
||||
'true' @{ nodestack.back ().value = new json::boolean ( true); }
|
||||
| 'false' @{ nodestack.back ().value = new json::boolean (false); };
|
||||
'true' @{ nodestack.back ().value = new json::tree::boolean ( true); }
|
||||
| 'false' @{ nodestack.back ().value = new json::tree::boolean (false); };
|
||||
|
||||
## components
|
||||
object = '{' @{ fhold; fcall _object; } '}';
|
||||
@ -242,14 +242,14 @@ struct parse_context {
|
||||
|
||||
template <>
|
||||
bool
|
||||
is_integer (const json::number &node) {
|
||||
is_integer (const json::tree::number &node) {
|
||||
return is_integer (node.native ());
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
bool
|
||||
is_integer (const json::node &node) {
|
||||
is_integer (const json::tree::node &node) {
|
||||
return node.is_number () &&
|
||||
is_integer (node.as_number ());
|
||||
}
|
||||
@ -258,22 +258,22 @@ is_integer (const json::node &node) {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Node
|
||||
|
||||
std::unique_ptr<json::node>
|
||||
json::parse (const boost::filesystem::path &path) {
|
||||
std::unique_ptr<json::tree::node>
|
||||
json::tree::parse (const boost::filesystem::path &path) {
|
||||
auto data = slurp (path);
|
||||
return parse (static_cast <const char *> (data.get ()));
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<json::node>
|
||||
json::parse (const std::string &path)
|
||||
std::unique_ptr<json::tree::node>
|
||||
json::tree::parse (const std::string &path)
|
||||
{ return parse (path.c_str (), path.c_str () + path.size ()); }
|
||||
|
||||
std::unique_ptr<json::node>
|
||||
json::parse (const char *start,
|
||||
std::unique_ptr<json::tree::node>
|
||||
json::tree::parse (const char *start,
|
||||
const char *stop) {
|
||||
bool __success = true;
|
||||
json::node *__root = nullptr;
|
||||
json::tree::node *__root = nullptr;
|
||||
size_t top = 0;
|
||||
int cs;
|
||||
deque <int> fsmstack;
|
||||
@ -292,50 +292,50 @@ json::parse (const char *start,
|
||||
throw parse_error (os.str ());
|
||||
}
|
||||
|
||||
return std::unique_ptr<json::node> (__root);
|
||||
return std::unique_ptr<json::tree::node> (__root);
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<json::node>
|
||||
json::parse (const char *start)
|
||||
std::unique_ptr<json::tree::node>
|
||||
json::tree::parse (const char *start)
|
||||
{ return parse (start, start + strlen (start)); }
|
||||
|
||||
|
||||
void
|
||||
json::write (const json::node &node, std::ostream &os)
|
||||
json::tree::write (const json::tree::node &node, std::ostream &os)
|
||||
{ node.write (os); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Type conversion
|
||||
|
||||
const json::object&
|
||||
json::node::as_object (void) const
|
||||
const json::tree::object&
|
||||
json::tree::node::as_object (void) const
|
||||
{ throw type_error ("node is not an object"); }
|
||||
|
||||
|
||||
const json::array&
|
||||
json::node::as_array (void) const
|
||||
const json::tree::array&
|
||||
json::tree::node::as_array (void) const
|
||||
{ throw type_error ("node is not an array"); }
|
||||
|
||||
|
||||
const json::string&
|
||||
json::node::as_string (void) const
|
||||
const json::tree::string&
|
||||
json::tree::node::as_string (void) const
|
||||
{ throw type_error ("node is not a string"); }
|
||||
|
||||
|
||||
const json::number&
|
||||
json::node::as_number (void) const
|
||||
const json::tree::number&
|
||||
json::tree::node::as_number (void) const
|
||||
{ throw type_error ("node is not a number"); }
|
||||
|
||||
|
||||
const json::boolean&
|
||||
json::node::as_boolean (void) const
|
||||
const json::tree::boolean&
|
||||
json::tree::node::as_boolean (void) const
|
||||
{ throw type_error ("node is not a boolean"); }
|
||||
|
||||
|
||||
const json::null&
|
||||
json::node::as_null (void) const
|
||||
const json::tree::null&
|
||||
json::tree::node::as_null (void) const
|
||||
{ throw type_error ("node is not a null"); }
|
||||
|
||||
|
||||
@ -343,38 +343,38 @@ json::node::as_null (void) const
|
||||
// Global operatoers
|
||||
|
||||
bool
|
||||
json::node::operator!= (const node &rhs) const
|
||||
json::tree::node::operator!= (const node &rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
|
||||
|
||||
bool json::node::operator==(const char *rhs) const {
|
||||
bool json::tree::node::operator==(const char *rhs) const {
|
||||
try {
|
||||
return as_string ().native () == rhs;
|
||||
} catch (const json::type_error&) {
|
||||
} catch (const json::tree::type_error&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const json::node&
|
||||
json::node::operator[] (const std::string &key) const
|
||||
const json::tree::node&
|
||||
json::tree::node::operator[] (const std::string &key) const
|
||||
{ return as_object ()[key]; }
|
||||
|
||||
|
||||
const json::node&
|
||||
json::node::operator[] (unsigned int idx) const
|
||||
const json::tree::node&
|
||||
json::tree::node::operator[] (unsigned int idx) const
|
||||
{ return as_array()[idx]; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object
|
||||
|
||||
json::object::~object ()
|
||||
json::tree::object::~object ()
|
||||
{ ; }
|
||||
|
||||
|
||||
bool
|
||||
json::object::operator ==(const json::object &rhs) const {
|
||||
json::tree::object::operator ==(const json::tree::object &rhs) const {
|
||||
for (auto i = rhs.m_values.begin (), j = m_values.begin ();
|
||||
i != rhs.m_values.end () && j != m_values.end ();
|
||||
++i, ++j)
|
||||
@ -390,17 +390,17 @@ json::object::operator ==(const json::object &rhs) const {
|
||||
|
||||
|
||||
void
|
||||
json::object::insert (const std::string &_key, unique_ptr<json::node> &&value)
|
||||
json::tree::object::insert (const std::string &_key, unique_ptr<json::tree::node> &&value)
|
||||
{ m_values[_key] = move(value); }
|
||||
|
||||
|
||||
const json::node&
|
||||
json::object::operator[](const std::string &key) const {
|
||||
const json::tree::node&
|
||||
json::tree::object::operator[](const std::string &key) const {
|
||||
auto value = m_values.find (key);
|
||||
if (value == m_values.end ()) {
|
||||
ostringstream ss;
|
||||
ss << "no key: " << key;
|
||||
throw json::error (ss.str());
|
||||
throw json::tree::error (ss.str());
|
||||
}
|
||||
|
||||
return *value->second;
|
||||
@ -408,38 +408,38 @@ json::object::operator[](const std::string &key) const {
|
||||
|
||||
|
||||
bool
|
||||
json::object::has (const std::string &key) const {
|
||||
json::tree::object::has (const std::string &key) const {
|
||||
return m_values.find (key) != m_values.end ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
json::object::clear (void)
|
||||
json::tree::object::clear (void)
|
||||
{ m_values.clear (); }
|
||||
|
||||
|
||||
void
|
||||
json::object::erase (const std::string &key) {
|
||||
json::tree::object::erase (const std::string &key) {
|
||||
auto pos = m_values.find (key);
|
||||
if (pos == m_values.end ())
|
||||
throw json::error ("erasing invalid key");
|
||||
throw json::tree::error ("erasing invalid key");
|
||||
|
||||
m_values.erase (key);
|
||||
}
|
||||
|
||||
|
||||
json::object::const_iterator
|
||||
json::object::begin (void) const
|
||||
json::tree::object::const_iterator
|
||||
json::tree::object::begin (void) const
|
||||
{ return m_values.begin (); }
|
||||
|
||||
|
||||
json::object::const_iterator
|
||||
json::object::end (void) const
|
||||
json::tree::object::const_iterator
|
||||
json::tree::object::end (void) const
|
||||
{ return m_values.end (); }
|
||||
|
||||
|
||||
std::ostream&
|
||||
json::object::write (std::ostream &os) const {
|
||||
json::tree::object::write (std::ostream &os) const {
|
||||
os << "{\n";
|
||||
{
|
||||
indenter raii(os);
|
||||
@ -460,17 +460,21 @@ json::object::write (std::ostream &os) const {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Array
|
||||
|
||||
json::array::~array()
|
||||
{ ; }
|
||||
json::tree::array::~array()
|
||||
{
|
||||
m_values.clear ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
json::array::insert (unique_ptr<json::node> &&_value)
|
||||
{ m_values.push_back (move (_value)); }
|
||||
json::tree::array::insert (unique_ptr<json::tree::node> &&_value)
|
||||
{
|
||||
m_values.push_back (move (_value));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
json::array::operator ==(const json::array &rhs) const {
|
||||
json::tree::array::operator ==(const json::tree::array &rhs) const {
|
||||
for (auto i = rhs.m_values.begin (), j = m_values.begin ();
|
||||
i != rhs.m_values.end () && j != m_values.end ();
|
||||
++i, ++j)
|
||||
@ -481,7 +485,7 @@ json::array::operator ==(const json::array &rhs) const {
|
||||
|
||||
|
||||
std::ostream&
|
||||
json::array::write (std::ostream &os) const {
|
||||
json::tree::array::write (std::ostream &os) const {
|
||||
os << "[\n";
|
||||
{
|
||||
indenter raii(os);
|
||||
@ -502,19 +506,19 @@ json::array::write (std::ostream &os) const {
|
||||
// String
|
||||
|
||||
std::ostream&
|
||||
json::string::write (std::ostream &os) const {
|
||||
json::tree::string::write (std::ostream &os) const {
|
||||
os << '"' << m_value << '"';
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
json::string::operator ==(const json::string &rhs) const
|
||||
json::tree::string::operator ==(const json::tree::string &rhs) const
|
||||
{ return rhs.m_value == m_value; }
|
||||
|
||||
|
||||
bool
|
||||
json::string::operator ==(const char *rhs) const
|
||||
json::tree::string::operator ==(const char *rhs) const
|
||||
{ return rhs == m_value; }
|
||||
|
||||
|
||||
@ -522,14 +526,14 @@ json::string::operator ==(const char *rhs) const
|
||||
// Number
|
||||
|
||||
std::ostream&
|
||||
json::number::write (std::ostream &os) const {
|
||||
json::tree::number::write (std::ostream &os) const {
|
||||
os << setprecision (numeric_limits<double>::digits10) << m_value;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
json::number::operator ==(const json::number &rhs) const
|
||||
json::tree::number::operator ==(const json::tree::number &rhs) const
|
||||
{ return almost_equal (rhs.m_value, m_value); }
|
||||
|
||||
|
||||
@ -537,13 +541,13 @@ json::number::operator ==(const json::number &rhs) const
|
||||
// Boolean
|
||||
|
||||
std::ostream&
|
||||
json::boolean::write (std::ostream &os) const {
|
||||
json::tree::boolean::write (std::ostream &os) const {
|
||||
os << (m_value ? "true" : "false");
|
||||
return os;
|
||||
}
|
||||
|
||||
bool
|
||||
json::boolean::operator ==(const json::boolean &rhs) const
|
||||
json::tree::boolean::operator ==(const json::tree::boolean &rhs) const
|
||||
{ return rhs.m_value == m_value; }
|
||||
|
||||
|
||||
@ -551,20 +555,20 @@ json::boolean::operator ==(const json::boolean &rhs) const
|
||||
// Null
|
||||
|
||||
std::ostream&
|
||||
json::null::write (std::ostream &os) const {
|
||||
json::tree::null::write (std::ostream &os) const {
|
||||
os << "null";
|
||||
return os;
|
||||
}
|
||||
|
||||
ostream&
|
||||
json::operator <<(ostream &os, const json::node &n)
|
||||
json::tree::operator <<(ostream &os, const json::tree::node &n)
|
||||
{ return n.write (os); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// to_json
|
||||
|
||||
namespace json {
|
||||
namespace json { namespace tree {
|
||||
template <>
|
||||
std::unique_ptr<node>
|
||||
io<bool>::serialise (const bool &b) {
|
||||
@ -600,4 +604,4 @@ namespace json {
|
||||
io<float>::serialise (const float &f) {
|
||||
return std::unique_ptr<node> (new number (f));
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
406
json.hpp
406
json.hpp
@ -31,270 +31,272 @@
|
||||
#include "iterator.hpp"
|
||||
|
||||
namespace json {
|
||||
class node;
|
||||
class object;
|
||||
class array;
|
||||
class string;
|
||||
class number;
|
||||
class boolean;
|
||||
class null;
|
||||
namespace tree {
|
||||
class node;
|
||||
class object;
|
||||
class array;
|
||||
class string;
|
||||
class number;
|
||||
class boolean;
|
||||
class null;
|
||||
|
||||
/// Parse an encoded form of JSON into a tree structure
|
||||
extern std::unique_ptr<node> parse (const boost::filesystem::path &path);
|
||||
extern std::unique_ptr<node> parse (const char *start, const char *stop);
|
||||
extern std::unique_ptr<node> parse (const char *start);
|
||||
extern std::unique_ptr<node> parse (const std::string&);
|
||||
/// Parse an encoded form of JSON into a tree structure
|
||||
extern std::unique_ptr<node> parse (const boost::filesystem::path &path);
|
||||
extern std::unique_ptr<node> parse (const char *start, const char *stop);
|
||||
extern std::unique_ptr<node> parse (const char *start);
|
||||
extern std::unique_ptr<node> parse (const std::string&);
|
||||
|
||||
extern void write (const json::node&, std::ostream&);
|
||||
extern void write (const json::tree::node&, std::ostream&);
|
||||
|
||||
/// Abstract base for all JSON values
|
||||
class node {
|
||||
public:
|
||||
virtual ~node () { ; }
|
||||
/// Abstract base for all JSON values
|
||||
class node {
|
||||
public:
|
||||
virtual ~node () { ; }
|
||||
|
||||
virtual const object& as_object (void) const;
|
||||
virtual const array& as_array (void) const;
|
||||
virtual const string& as_string (void) const;
|
||||
virtual const number& as_number (void) const;
|
||||
virtual const boolean& as_boolean (void) const;
|
||||
virtual const null& as_null (void) const;
|
||||
virtual const object& as_object (void) const;
|
||||
virtual const array& as_array (void) const;
|
||||
virtual const string& as_string (void) const;
|
||||
virtual const number& as_number (void) const;
|
||||
virtual const boolean& as_boolean (void) const;
|
||||
virtual const null& as_null (void) const;
|
||||
|
||||
virtual bool is_object (void) const { return false; }
|
||||
virtual bool is_array (void) const { return false; }
|
||||
virtual bool is_string (void) const { return false; }
|
||||
virtual bool is_number (void) const { return false; }
|
||||
virtual bool is_boolean (void) const { return false; }
|
||||
virtual bool is_null (void) const { return false; }
|
||||
virtual bool is_object (void) const { return false; }
|
||||
virtual bool is_array (void) const { return false; }
|
||||
virtual bool is_string (void) const { return false; }
|
||||
virtual bool is_number (void) const { return false; }
|
||||
virtual bool is_boolean (void) const { return false; }
|
||||
virtual bool is_null (void) const { return false; }
|
||||
|
||||
virtual bool operator==(const node &rhs) const = 0;
|
||||
virtual bool operator!=(const node &rhs) const;
|
||||
virtual bool operator==(const object &) const { return false; }
|
||||
virtual bool operator==(const array &) const { return false; }
|
||||
virtual bool operator==(const string &) const { return false; }
|
||||
virtual bool operator==(const number &) const { return false; }
|
||||
virtual bool operator==(const boolean &) const { return false; }
|
||||
virtual bool operator==(const null &) const { return false; }
|
||||
virtual bool operator==(const node &rhs) const = 0;
|
||||
virtual bool operator!=(const node &rhs) const;
|
||||
virtual bool operator==(const object &) const { return false; }
|
||||
virtual bool operator==(const array &) const { return false; }
|
||||
virtual bool operator==(const string &) const { return false; }
|
||||
virtual bool operator==(const number &) const { return false; }
|
||||
virtual bool operator==(const boolean &) const { return false; }
|
||||
virtual bool operator==(const null &) const { return false; }
|
||||
|
||||
virtual bool operator==(const char *rhs) const;
|
||||
virtual bool operator!=(const char *rhs) const { return !(*this == rhs); }
|
||||
virtual bool operator==(const char *rhs) const;
|
||||
virtual bool operator!=(const char *rhs) const { return !(*this == rhs); }
|
||||
|
||||
virtual const node& operator[] (const std::string&) const;
|
||||
virtual const node& operator[] (unsigned int) const;
|
||||
virtual const node& operator[] (const std::string&) const;
|
||||
virtual const node& operator[] (unsigned int) const;
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const = 0;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON object, and contains its children.
|
||||
class object : public node {
|
||||
protected:
|
||||
typedef std::map<std::string, std::unique_ptr<node>> value_store;
|
||||
public:
|
||||
typedef value_store::iterator iterator;
|
||||
typedef value_store::const_iterator const_iterator;
|
||||
/// Represents a JSON object, and contains its children.
|
||||
class object : public node {
|
||||
protected:
|
||||
typedef std::map<std::string, std::unique_ptr<node>> value_store;
|
||||
public:
|
||||
typedef value_store::iterator iterator;
|
||||
typedef value_store::const_iterator const_iterator;
|
||||
|
||||
protected:
|
||||
value_store m_values;
|
||||
protected:
|
||||
value_store m_values;
|
||||
|
||||
public:
|
||||
virtual ~object ();
|
||||
public:
|
||||
virtual ~object ();
|
||||
|
||||
virtual const object& as_object (void) const { return *this; }
|
||||
virtual bool is_object (void) const { return true; }
|
||||
virtual bool operator==(const object &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
virtual const object& as_object (void) const { return *this; }
|
||||
virtual bool is_object (void) const { return true; }
|
||||
virtual bool operator==(const object &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
virtual void insert (const std::string &key, std::unique_ptr<node>&& value);
|
||||
virtual const node& operator[](const std::string &key) const;
|
||||
virtual bool has (const std::string&) const;
|
||||
virtual void insert (const std::string &key, std::unique_ptr<node>&& value);
|
||||
virtual const node& operator[](const std::string &key) const;
|
||||
virtual bool has (const std::string&) const;
|
||||
|
||||
virtual void clear (void);
|
||||
virtual void erase (const std::string &key);
|
||||
virtual void clear (void);
|
||||
virtual void erase (const std::string &key);
|
||||
|
||||
virtual const_iterator begin (void) const;
|
||||
virtual const_iterator end (void) const;
|
||||
virtual const_iterator begin (void) const;
|
||||
virtual const_iterator end (void) const;
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON array, and contains its children.
|
||||
class array : public node {
|
||||
protected:
|
||||
typedef std::vector<std::unique_ptr<node>>::iterator pointer_array_iterator;
|
||||
typedef std::vector<std::unique_ptr<node>>::const_iterator const_pointer_array_iterator;
|
||||
/// Represents a JSON array, and contains its children.
|
||||
class array : public node {
|
||||
protected:
|
||||
typedef std::vector<std::unique_ptr<node>>::iterator pointer_array_iterator;
|
||||
typedef std::vector<std::unique_ptr<node>>::const_iterator const_pointer_array_iterator;
|
||||
|
||||
public:
|
||||
typedef referencing_iterator<pointer_array_iterator> iterator;
|
||||
typedef referencing_iterator<const_pointer_array_iterator> const_iterator;
|
||||
public:
|
||||
typedef referencing_iterator<pointer_array_iterator> iterator;
|
||||
typedef referencing_iterator<const_pointer_array_iterator> const_iterator;
|
||||
|
||||
protected:
|
||||
std::vector<std::unique_ptr<node>> m_values;
|
||||
protected:
|
||||
std::vector<std::unique_ptr<node>> m_values;
|
||||
|
||||
public:
|
||||
virtual ~array();
|
||||
public:
|
||||
virtual ~array();
|
||||
|
||||
virtual const array& as_array (void) const { return *this; }
|
||||
virtual bool is_array (void) const { return true; }
|
||||
virtual bool operator==(const array &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
virtual const array& as_array (void) const { return *this; }
|
||||
virtual bool is_array (void) const { return true; }
|
||||
virtual bool operator==(const array &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
virtual size_t size (void) const
|
||||
{ return m_values.size (); }
|
||||
virtual node& operator [](unsigned int idx)
|
||||
{ return *m_values[idx]; }
|
||||
virtual const node& operator [](unsigned int idx) const
|
||||
{ return *m_values[idx]; }
|
||||
virtual size_t size (void) const
|
||||
{ return m_values.size (); }
|
||||
virtual node& operator [](unsigned int idx)
|
||||
{ return *m_values[idx]; }
|
||||
virtual const node& operator [](unsigned int idx) const
|
||||
{ return *m_values[idx]; }
|
||||
|
||||
virtual const_iterator begin (void) const { return const_iterator (m_values.begin ()); }
|
||||
virtual const_iterator end (void) const { return const_iterator (m_values.end ()); }
|
||||
virtual const_iterator begin (void) const { return const_iterator (m_values.begin ()); }
|
||||
virtual const_iterator end (void) const { return const_iterator (m_values.end ()); }
|
||||
|
||||
virtual void insert (std::unique_ptr<json::node> &&_value);
|
||||
virtual void insert (std::unique_ptr<json::tree::node> &&_value);
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON string literal.
|
||||
class string : public node {
|
||||
protected:
|
||||
std::string m_value;
|
||||
/// Represents a JSON string literal.
|
||||
class string : public node {
|
||||
protected:
|
||||
std::string m_value;
|
||||
|
||||
public:
|
||||
explicit string (const std::string &_value): m_value (_value) { ; }
|
||||
explicit string (const char *_value): m_value (_value) { ; }
|
||||
public:
|
||||
explicit string (const std::string &_value): m_value (_value) { ; }
|
||||
explicit string (const char *_value): m_value (_value) { ; }
|
||||
string (const char *_first, const char *_last): m_value (_first, _last) { ; }
|
||||
|
||||
virtual const string& as_string (void) const { return *this; }
|
||||
virtual bool is_string (void) const { return true; }
|
||||
virtual bool operator==(const char *rhs) const;
|
||||
virtual bool operator==(const string &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
virtual const string& as_string (void) const { return *this; }
|
||||
virtual bool is_string (void) const { return true; }
|
||||
virtual bool operator==(const char *rhs) const;
|
||||
virtual bool operator==(const string &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
virtual size_t size (void) const { return m_value.size (); }
|
||||
virtual size_t size (void) const { return m_value.size (); }
|
||||
|
||||
operator const std::string&(void) const { return m_value; }
|
||||
const std::string& native (void) const { return m_value; }
|
||||
operator const std::string&(void) const { return m_value; }
|
||||
const std::string& native (void) const { return m_value; }
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON integer/float literal.
|
||||
class number : public node {
|
||||
protected:
|
||||
double m_value;
|
||||
/// Represents a JSON integer/float literal.
|
||||
class number : public node {
|
||||
protected:
|
||||
double m_value;
|
||||
|
||||
public:
|
||||
explicit number (double _value): m_value (_value) { ; }
|
||||
explicit number (int _value): m_value (_value) { ; }
|
||||
explicit number (size_t _value): m_value (_value) { ; }
|
||||
public:
|
||||
explicit number (double _value): m_value (_value) { ; }
|
||||
explicit number (int _value): m_value (_value) { ; }
|
||||
explicit number (size_t _value): m_value (_value) { ; }
|
||||
|
||||
virtual const number& as_number (void) const { return *this; }
|
||||
virtual bool is_number (void) const { return true; }
|
||||
virtual bool operator==(const number &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
virtual const number& as_number (void) const { return *this; }
|
||||
virtual bool is_number (void) const { return true; }
|
||||
virtual bool operator==(const number &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
operator double(void) const { return m_value; }
|
||||
double native (void) const { return m_value; }
|
||||
operator double(void) const { return m_value; }
|
||||
double native (void) const { return m_value; }
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON boolean literal.
|
||||
class boolean : public node {
|
||||
protected:
|
||||
bool m_value;
|
||||
/// Represents a JSON boolean literal.
|
||||
class boolean : public node {
|
||||
protected:
|
||||
bool m_value;
|
||||
|
||||
public:
|
||||
explicit boolean (bool _value): m_value (_value) { ; }
|
||||
public:
|
||||
explicit boolean (bool _value): m_value (_value) { ; }
|
||||
|
||||
virtual const boolean& as_boolean (void) const { return *this; }
|
||||
virtual bool is_boolean (void) const { return true; }
|
||||
virtual bool operator==(const boolean &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
virtual const boolean& as_boolean (void) const { return *this; }
|
||||
virtual bool is_boolean (void) const { return true; }
|
||||
virtual bool operator==(const boolean &rhs) const;
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
operator bool (void) const { return m_value; }
|
||||
bool native (void) const { return m_value; }
|
||||
operator bool (void) const { return m_value; }
|
||||
bool native (void) const { return m_value; }
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a JSON null value.
|
||||
class null : public node {
|
||||
public:
|
||||
virtual bool operator==(const null&) const { return true; }
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
/// Represents a JSON null value.
|
||||
class null : public node {
|
||||
public:
|
||||
virtual bool operator==(const null&) const { return true; }
|
||||
virtual bool operator==(const node &rhs) const
|
||||
{ return rhs == *this; }
|
||||
|
||||
virtual bool is_null (void) const { return true; }
|
||||
virtual const null& as_null (void) const { return *this; }
|
||||
virtual bool is_null (void) const { return true; }
|
||||
virtual const null& as_null (void) const { return *this; }
|
||||
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
virtual std::ostream& write (std::ostream &os) const;
|
||||
};
|
||||
|
||||
|
||||
/// The base class for all exceptions throw directly by the json namespace.
|
||||
class error : public std::runtime_error {
|
||||
public:
|
||||
error (const std::string &_what):
|
||||
std::runtime_error (_what)
|
||||
{ ; }
|
||||
};
|
||||
/// The base class for all exceptions throw directly by the json namespace.
|
||||
class error : public std::runtime_error {
|
||||
public:
|
||||
error (const std::string &_what):
|
||||
std::runtime_error (_what)
|
||||
{ ; }
|
||||
};
|
||||
|
||||
/// Base class for all type conversion errors
|
||||
class type_error : public error {
|
||||
public:
|
||||
type_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
/// Base class for all type conversion errors
|
||||
class type_error : public error {
|
||||
public:
|
||||
type_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
|
||||
/// Base class for errors thrown during parsing
|
||||
class parse_error : public error {
|
||||
public:
|
||||
parse_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
/// Base class for errors thrown during parsing
|
||||
class parse_error : public error {
|
||||
public:
|
||||
parse_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
|
||||
/// Base class for errors thrown during schema validation
|
||||
class schema_error : public error {
|
||||
public:
|
||||
schema_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
/// Base class for errors thrown during schema validation
|
||||
class schema_error : public error {
|
||||
public:
|
||||
schema_error (const std::string &_what):
|
||||
error (_what)
|
||||
{ ; }
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator <<(std::ostream &os, const json::node &n);
|
||||
std::ostream&
|
||||
operator <<(std::ostream &os, const json::tree::node &n);
|
||||
|
||||
|
||||
// Instantiate this template for the type you wish to output. We use a
|
||||
// helper class here to avoid partial template specialisation of a
|
||||
// function (eg, for templated types).
|
||||
template <typename T>
|
||||
struct io {
|
||||
static std::unique_ptr<json::node> serialise (const T&);
|
||||
static T deserialise (const json::node&);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class ...Args>
|
||||
std::unique_ptr<json::node> to_json (const T &t, Args&&... args) {
|
||||
return json::io<T>::serialise (t, std::forward<Args>(args)...);
|
||||
// Instantiate this template for the type you wish to output. We use a
|
||||
// helper class here to avoid partial template specialisation of a
|
||||
// function (eg, for templated types).
|
||||
template <typename T>
|
||||
struct io {
|
||||
static std::unique_ptr<json::tree::node> serialise (const T&);
|
||||
static T deserialise (const json::tree::node&);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class ...Args>
|
||||
T from_json (const json::node &n, Args&&... args) {
|
||||
return json::io<T>::deserialise (n, std::forward<Args>(args)...);
|
||||
std::unique_ptr<json::tree::node> to_json (const T &t, Args&&... args) {
|
||||
return json::tree::io<T>::serialise (t, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, class ...Args>
|
||||
T from_json (const json::tree::node &n, Args&&... args) {
|
||||
return json::tree::io<T>::deserialise (n, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -186,10 +186,10 @@ namespace util {
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace json {
|
||||
namespace json { namespace tree {
|
||||
template <>
|
||||
util::range<double>
|
||||
io<util::range<double>>::deserialise (const json::node &node) {
|
||||
io<util::range<double>>::deserialise (const json::tree::node &node) {
|
||||
if (node.is_string () && (node == "UNIT" ||
|
||||
node == "unit")) {
|
||||
return util::range<double>::UNIT;
|
||||
@ -203,4 +203,4 @@ namespace json {
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
@ -24,10 +24,10 @@ main (int, char**) {
|
||||
" ]"
|
||||
"}";
|
||||
|
||||
std::unique_ptr<json::node> ptr = json::parse (TEST_STRING);
|
||||
std::unique_ptr<json::tree::node> ptr = json::tree::parse (TEST_STRING);
|
||||
CHECK (ptr->is_object ());
|
||||
|
||||
const json::node &ref = *ptr;
|
||||
const json::tree::node &ref = *ptr;
|
||||
|
||||
CHECK ( ref["string"].is_string ());
|
||||
CHECK (!ref["string"].is_array ());
|
||||
|
@ -48,8 +48,8 @@ main (int argc, char **argv) {
|
||||
|
||||
try {
|
||||
boost::filesystem::path input (argv[ARG_INPUT]);
|
||||
std::cout << *json::parse (input) << "\n";
|
||||
} catch (const json::error& err) {
|
||||
std::cout << *json::tree::parse (input) << "\n";
|
||||
} catch (const json::tree::error& err) {
|
||||
std::cerr << err.what () << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ print_usage (int argc, char **argv) {
|
||||
|
||||
|
||||
const char*
|
||||
type_to_string (const json::node &node) {
|
||||
type_to_string (const json::tree::node &node) {
|
||||
if (node.is_array ()) return "array";
|
||||
if (node.is_boolean ()) return "boolean";
|
||||
if (node.is_null ()) return "null";
|
||||
@ -68,13 +68,13 @@ type_to_string (const json::node &node) {
|
||||
|
||||
|
||||
bool
|
||||
is_node_valid (const json::node &node,
|
||||
const json::object &schema);
|
||||
is_node_valid (const json::tree::node &node,
|
||||
const json::tree::object &schema);
|
||||
|
||||
|
||||
bool
|
||||
is_type_valid (const json::node &node,
|
||||
const json::node &type) {
|
||||
is_type_valid (const json::tree::node &node,
|
||||
const json::tree::node &type) {
|
||||
if (type.is_array ()) {
|
||||
return any_of (type.as_array ().begin (),
|
||||
type.as_array ().end (),
|
||||
@ -82,20 +82,20 @@ is_type_valid (const json::node &node,
|
||||
}
|
||||
|
||||
if (!type.is_string ())
|
||||
throw json::schema_error ("schema type requires array, string, or object");
|
||||
throw json::tree::schema_error ("schema type requires array, string, or object");
|
||||
|
||||
static const auto ANY_VALIDATOR = [] (const json::node &) { return true; };
|
||||
static const auto INT_VALIDATOR = [] (const json::node &n) {
|
||||
static const auto ANY_VALIDATOR = [] (const json::tree::node &) { return true; };
|
||||
static const auto INT_VALIDATOR = [] (const json::tree::node &n) {
|
||||
return n.is_number () && is_integer (n.as_number ());
|
||||
};
|
||||
|
||||
static const map<string, function<bool(const json::node&)>> TYPE_VALIDATORS ({
|
||||
{ "array", bind (&json::node::is_array, _1) },
|
||||
{ "boolean", bind (&json::node::is_boolean, _1) },
|
||||
{ "null", bind (&json::node::is_null, _1) },
|
||||
{ "number", bind (&json::node::is_number, _1) },
|
||||
{ "object", bind (&json::node::is_object, _1) },
|
||||
{ "string", bind (&json::node::is_string, _1) },
|
||||
static const map<string, function<bool(const json::tree::node&)>> TYPE_VALIDATORS ({
|
||||
{ "array", bind (&json::tree::node::is_array, _1) },
|
||||
{ "boolean", bind (&json::tree::node::is_boolean, _1) },
|
||||
{ "null", bind (&json::tree::node::is_null, _1) },
|
||||
{ "number", bind (&json::tree::node::is_number, _1) },
|
||||
{ "object", bind (&json::tree::node::is_object, _1) },
|
||||
{ "string", bind (&json::tree::node::is_string, _1) },
|
||||
{ "any", ANY_VALIDATOR },
|
||||
{ "integer", INT_VALIDATOR },
|
||||
});
|
||||
@ -111,18 +111,18 @@ is_type_valid (const json::node &node,
|
||||
|
||||
|
||||
bool
|
||||
is_disallow_valid (const json::node &node,
|
||||
const json::node &constraint)
|
||||
is_disallow_valid (const json::tree::node &node,
|
||||
const json::tree::node &constraint)
|
||||
{ return !is_type_valid (node, constraint); }
|
||||
|
||||
|
||||
bool
|
||||
is_enum_valid (const json::node &node,
|
||||
const json::node &constraint) {
|
||||
is_enum_valid (const json::tree::node &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!constraint.is_array ())
|
||||
throw json::schema_error ("enum validation requires an array");
|
||||
throw json::tree::schema_error ("enum validation requires an array");
|
||||
|
||||
const json::array &valids = constraint.as_array ();
|
||||
const json::tree::array &valids = constraint.as_array ();
|
||||
return valids.end () != std::find (valids.begin (),
|
||||
valids.end (),
|
||||
node);
|
||||
@ -130,15 +130,15 @@ is_enum_valid (const json::node &node,
|
||||
|
||||
|
||||
bool
|
||||
is_enum_valid (const json::string &node,
|
||||
const json::node &constraint) {
|
||||
return is_enum_valid (static_cast<const json::node&> (node), constraint);
|
||||
is_enum_valid (const json::tree::string &node,
|
||||
const json::tree::node &constraint) {
|
||||
return is_enum_valid (static_cast<const json::tree::node&> (node), constraint);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_always_valid (const json::node &,
|
||||
const json::node &)
|
||||
is_always_valid (const json::tree::node &,
|
||||
const json::tree::node &)
|
||||
{ return true; }
|
||||
|
||||
|
||||
@ -153,14 +153,14 @@ is_always_valid (const json::node &,
|
||||
|
||||
|
||||
bool
|
||||
is_boolean_valid (const json::node &node,
|
||||
const json::object &)
|
||||
is_boolean_valid (const json::tree::node &node,
|
||||
const json::tree::object &)
|
||||
{ return node.is_boolean (); }
|
||||
|
||||
|
||||
bool
|
||||
is_null_valid (const json::node &node,
|
||||
const json::object &)
|
||||
is_null_valid (const json::tree::node &node,
|
||||
const json::tree::object &)
|
||||
{ return node.is_null (); }
|
||||
|
||||
|
||||
@ -169,36 +169,36 @@ is_null_valid (const json::node &node,
|
||||
//
|
||||
|
||||
bool
|
||||
is_minimum_valid (const json::number &node,
|
||||
const json::node &constraint) {
|
||||
is_minimum_valid (const json::tree::number &node,
|
||||
const json::tree::node &constraint) {
|
||||
return constraint["minimum"].as_number () <= node;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_maximum_valid (const json::number &node,
|
||||
const json::node &constraint) {
|
||||
is_maximum_valid (const json::tree::number &node,
|
||||
const json::tree::node &constraint) {
|
||||
return constraint["maximum"].as_number () >= node;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_exclusive_minimum_valid (const json::number &node,
|
||||
const json::node &constraint) {
|
||||
is_exclusive_minimum_valid (const json::tree::number &node,
|
||||
const json::tree::node &constraint) {
|
||||
return constraint["exclusiveMinimum"].as_number () < node;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_exclusive_maximum_valid (const json::number &node,
|
||||
const json::node &constraint) {
|
||||
is_exclusive_maximum_valid (const json::tree::number &node,
|
||||
const json::tree::node &constraint) {
|
||||
return constraint["exclusiveMaximum"].as_number () > node;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_divisible_by_valid (const json::number &node,
|
||||
const json::node &constraint) {
|
||||
is_divisible_by_valid (const json::tree::number &node,
|
||||
const json::tree::node &constraint) {
|
||||
return exactly_equal (fmod (node.native (),
|
||||
constraint["divisibleBy"].as_number ()),
|
||||
0.0);
|
||||
@ -206,9 +206,9 @@ is_divisible_by_valid (const json::number &node,
|
||||
|
||||
|
||||
bool
|
||||
is_number_valid (const json::number &node,
|
||||
const json::object &schema) {
|
||||
typedef bool (*number_validator_t)(const json::number&, const json::node&);
|
||||
is_number_valid (const json::tree::number &node,
|
||||
const json::tree::object &schema) {
|
||||
typedef bool (*number_validator_t)(const json::tree::number&, const json::tree::node&);
|
||||
static const map<string, number_validator_t> VALIDATORS = {
|
||||
{ "minimum", &is_minimum_valid },
|
||||
{ "maximum", &is_maximum_valid },
|
||||
@ -239,8 +239,8 @@ is_number_valid (const json::number &node,
|
||||
|
||||
|
||||
bool
|
||||
is_min_length_valid (const json::string &node,
|
||||
const json::node &constraint) {
|
||||
is_min_length_valid (const json::tree::string &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!is_integer (constraint))
|
||||
return false;
|
||||
|
||||
@ -249,8 +249,8 @@ is_min_length_valid (const json::string &node,
|
||||
|
||||
|
||||
bool
|
||||
is_max_length_valid (const json::string &node,
|
||||
const json::node &constraint) {
|
||||
is_max_length_valid (const json::tree::string &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!is_integer (constraint))
|
||||
return false;
|
||||
|
||||
@ -259,8 +259,8 @@ is_max_length_valid (const json::string &node,
|
||||
|
||||
|
||||
bool
|
||||
is_pattern_valid (const json::string &node,
|
||||
const json::node &constraint) {
|
||||
is_pattern_valid (const json::tree::string &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!constraint.is_string ())
|
||||
return false;
|
||||
|
||||
@ -271,9 +271,9 @@ is_pattern_valid (const json::string &node,
|
||||
|
||||
|
||||
bool
|
||||
is_string_valid (const json::string &node,
|
||||
const json::object &schema) {
|
||||
typedef bool (*string_validator_t)(const json::string&, const json::node&);
|
||||
is_string_valid (const json::tree::string &node,
|
||||
const json::tree::object &schema) {
|
||||
typedef bool (*string_validator_t)(const json::tree::string&, const json::tree::node&);
|
||||
static const map<std::string, string_validator_t> VALIDATORS = {
|
||||
{ "minLength", &is_min_length_valid },
|
||||
{ "maxLength", &is_max_length_valid },
|
||||
@ -281,9 +281,9 @@ is_string_valid (const json::string &node,
|
||||
{ "enum", &is_enum_valid },
|
||||
};
|
||||
|
||||
for (const json::object::const_iterator::value_type &i: schema) {
|
||||
for (const json::tree::object::const_iterator::value_type &i: schema) {
|
||||
const std::string &key = i.first;
|
||||
const json::node &constraint = *i.second;
|
||||
const json::tree::node &constraint = *i.second;
|
||||
|
||||
auto validator = VALIDATORS.find (key);
|
||||
if (validator == VALIDATORS.end ()) {
|
||||
@ -302,8 +302,8 @@ is_string_valid (const json::string &node,
|
||||
|
||||
|
||||
bool
|
||||
is_string_valid (const json::node &node,
|
||||
const json::object &schema) {
|
||||
is_string_valid (const json::tree::node &node,
|
||||
const json::tree::object &schema) {
|
||||
if (!node.is_string ())
|
||||
return false;
|
||||
return is_string_valid (node.as_string (), schema);
|
||||
@ -315,36 +315,36 @@ is_string_valid (const json::node &node,
|
||||
|
||||
|
||||
bool
|
||||
is_max_items_valid (const json::array &node,
|
||||
const json::node &constraint) {
|
||||
is_max_items_valid (const json::tree::array &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!constraint.is_number () && is_integer (constraint.as_number ()))
|
||||
throw json::schema_error ("max_items should be an integer");
|
||||
throw json::tree::schema_error ("max_items should be an integer");
|
||||
|
||||
return node.size () <= constraint.as_number ();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_min_items_valid (const json::array &node,
|
||||
const json::node &constraint) {
|
||||
is_min_items_valid (const json::tree::array &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!constraint.is_number () && is_integer (constraint.as_number ()))
|
||||
throw json::schema_error ("min_items should be an integer");
|
||||
throw json::tree::schema_error ("min_items should be an integer");
|
||||
|
||||
return node.size () >= constraint.as_number ();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_unique_items_valid (const json::array &node,
|
||||
const json::node &constraint) {
|
||||
is_unique_items_valid (const json::tree::array &node,
|
||||
const json::tree::node &constraint) {
|
||||
if (!constraint.is_boolean ())
|
||||
throw json::schema_error ("uniqueItems must be a boolean");
|
||||
throw json::tree::schema_error ("uniqueItems must be a boolean");
|
||||
|
||||
if (node.size () < 2)
|
||||
return true;
|
||||
|
||||
|
||||
for (json::array::const_iterator i = node.begin (); i != node.end () - 1; ++i) {
|
||||
for (json::tree::array::const_iterator i = node.begin (); i != node.end () - 1; ++i) {
|
||||
if (find (i + 1, node.end (), *i) != node.end ())
|
||||
return false;
|
||||
}
|
||||
@ -354,13 +354,13 @@ is_unique_items_valid (const json::array &node,
|
||||
|
||||
|
||||
bool
|
||||
is_items_valid (const json::array &node,
|
||||
const json::node &_schema) {
|
||||
is_items_valid (const json::tree::array &node,
|
||||
const json::tree::node &_schema) {
|
||||
if (!_schema.is_object ())
|
||||
throw json::schema_error ("array_items constraint must be an object");
|
||||
const json::object &schema = _schema.as_object ();
|
||||
throw json::tree::schema_error ("array_items constraint must be an object");
|
||||
const json::tree::object &schema = _schema.as_object ();
|
||||
|
||||
for (const json::node &i: node)
|
||||
for (const json::tree::node &i: node)
|
||||
if (!is_node_valid (i, schema))
|
||||
return false;
|
||||
|
||||
@ -372,19 +372,19 @@ is_items_valid (const json::array &node,
|
||||
|
||||
|
||||
bool
|
||||
is_additional_items_valid (const json::array &,
|
||||
const json::node &) {
|
||||
is_additional_items_valid (const json::tree::array &,
|
||||
const json::tree::node &) {
|
||||
not_implemented ();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_array_valid (const json::array &node,
|
||||
const json::object &schema) {
|
||||
is_array_valid (const json::tree::array &node,
|
||||
const json::tree::object &schema) {
|
||||
CHECK (node.is_array ());
|
||||
|
||||
typedef bool (*array_validator_t)(const json::array&, const json::node&);
|
||||
typedef bool (*array_validator_t)(const json::tree::array&, const json::tree::node&);
|
||||
static const map<string, array_validator_t> VALIDATORS ({
|
||||
{ "items", &is_items_valid },
|
||||
{ "minItems", &is_min_items_valid },
|
||||
@ -393,9 +393,9 @@ is_array_valid (const json::array &node,
|
||||
{ "additionalItems", &is_additional_items_valid },
|
||||
});
|
||||
|
||||
for (const json::object::const_iterator::value_type &i: schema) {
|
||||
for (const json::tree::object::const_iterator::value_type &i: schema) {
|
||||
const std::string &key = i.first;
|
||||
const json::node &constraint = *i.second;
|
||||
const json::tree::node &constraint = *i.second;
|
||||
|
||||
auto validator = VALIDATORS.find (key);
|
||||
if (validator == VALIDATORS.end ()) {
|
||||
@ -418,11 +418,11 @@ is_array_valid (const json::array &node,
|
||||
//
|
||||
|
||||
bool
|
||||
is_properties_valid (const json::object &node,
|
||||
const json::object &schema) {
|
||||
for (const json::object::const_iterator::value_type &element: node) {
|
||||
is_properties_valid (const json::tree::object &node,
|
||||
const json::tree::object &schema) {
|
||||
for (const json::tree::object::const_iterator::value_type &element: node) {
|
||||
const std::string &key = element.first;
|
||||
const json::node &val = *element.second;
|
||||
const json::tree::node &val = *element.second;
|
||||
|
||||
if (!schema.has (key)) {
|
||||
std::cerr << "[warning] no constraint found for key: " << key << "\n";
|
||||
@ -440,30 +440,30 @@ is_properties_valid (const json::object &node,
|
||||
|
||||
|
||||
bool
|
||||
is_properties_valid (const json::object &node,
|
||||
const json::node &constraint) {
|
||||
is_properties_valid (const json::tree::object &node,
|
||||
const json::tree::node &constraint) {
|
||||
CHECK (node.is_object ());
|
||||
|
||||
if (!constraint.is_object ())
|
||||
throw json::schema_error ("properties needs an object");
|
||||
throw json::tree::schema_error ("properties needs an object");
|
||||
|
||||
return is_properties_valid (node, constraint.as_object ());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_object_valid (const json::object &node,
|
||||
const json::object &schema) {
|
||||
typedef bool (*object_validator_t)(const json::object&, const json::node&);
|
||||
is_object_valid (const json::tree::object &node,
|
||||
const json::tree::object &schema) {
|
||||
typedef bool (*object_validator_t)(const json::tree::object&, const json::tree::node&);
|
||||
static const map<string, object_validator_t> VALIDATORS = {
|
||||
{ "properties", &is_properties_valid },
|
||||
//{ "patternProperties", &is_pattern_properties_valid },
|
||||
//{ "additionalProperties", &is_additionaL_properties_valid },
|
||||
};
|
||||
|
||||
for (const json::object::const_iterator::value_type &i: schema) {
|
||||
for (const json::tree::object::const_iterator::value_type &i: schema) {
|
||||
const std::string &name = i.first;
|
||||
const json::node &constraint = *i.second;
|
||||
const json::tree::node &constraint = *i.second;
|
||||
|
||||
auto validator = VALIDATORS.find (name);
|
||||
if (validator == VALIDATORS.end ()) {
|
||||
@ -482,8 +482,8 @@ is_object_valid (const json::object &node,
|
||||
|
||||
|
||||
bool
|
||||
is_object_valid (const json::node &node,
|
||||
const json::object &schema) {
|
||||
is_object_valid (const json::tree::node &node,
|
||||
const json::tree::object &schema) {
|
||||
if (!node.is_object ())
|
||||
return false;
|
||||
|
||||
@ -496,8 +496,8 @@ is_object_valid (const json::node &node,
|
||||
//
|
||||
|
||||
bool
|
||||
is_node_valid (const json::node &node,
|
||||
const json::object &schema) {
|
||||
is_node_valid (const json::tree::node &node,
|
||||
const json::tree::object &schema) {
|
||||
if (schema.has ("$ref")) {
|
||||
const std::string &uri = schema["$ref"].as_string ();
|
||||
std::cerr << "loading referenced schema: " << uri << "\n";
|
||||
@ -507,7 +507,7 @@ is_node_valid (const json::node &node,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto referenced = json::parse (boost::filesystem::path (uri));
|
||||
auto referenced = json::tree::parse (boost::filesystem::path (uri));
|
||||
return is_node_valid (node, referenced->as_object ());
|
||||
}
|
||||
|
||||
@ -558,8 +558,8 @@ is_node_valid (const json::node &node,
|
||||
|
||||
|
||||
bool
|
||||
is_root_valid (const json::node &node,
|
||||
const json::object &schema) {
|
||||
is_root_valid (const json::tree::node &node,
|
||||
const json::tree::object &schema) {
|
||||
if (!node.is_array () && !node.is_object ())
|
||||
return false;
|
||||
return is_node_valid (node, schema);
|
||||
@ -579,11 +579,11 @@ main (int argc, char **argv) {
|
||||
}
|
||||
|
||||
// Load the schema and input
|
||||
unique_ptr<json::node> schema, input;
|
||||
unique_ptr<json::tree::node> schema, input;
|
||||
try {
|
||||
schema = json::parse (boost::filesystem::path (argv[ARG_SCHEMA]));
|
||||
input = json::parse (boost::filesystem::path (argv[ARG_INPUT]));
|
||||
} catch (const json::parse_error &err) {
|
||||
schema = json::tree::parse (boost::filesystem::path (argv[ARG_SCHEMA]));
|
||||
input = json::tree::parse (boost::filesystem::path (argv[ARG_INPUT]));
|
||||
} catch (const json::tree::parse_error &err) {
|
||||
std::cerr << "malformed json for schema or input. " << err.what () << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -594,7 +594,7 @@ main (int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const json::object &schema_object = schema->as_object ();
|
||||
const json::tree::object &schema_object = schema->as_object ();
|
||||
|
||||
// Check input is valid
|
||||
if (!is_node_valid (*input, schema_object)) {
|
||||
|
@ -23,8 +23,8 @@ main (int argc, char ** argv) {
|
||||
}
|
||||
|
||||
try {
|
||||
json::parse (boost::filesystem::path (argv[ARG_PATH]));
|
||||
} catch (json::error &x) {
|
||||
json::tree::parse (boost::filesystem::path (argv[ARG_PATH]));
|
||||
} catch (json::tree::error &x) {
|
||||
std::cerr << "Error: " << x.what () << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -414,9 +414,9 @@ util::operator<< (std::ostream &os, const util::vector<S,T> &v) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <size_t S, typename T>
|
||||
const json::node&
|
||||
util::operator>> (const json::node &node, util::vector<S,T> &v) {
|
||||
const json::array &array = node.as_array ();
|
||||
const json::tree::node&
|
||||
util::operator>> (const json::tree::node &node, util::vector<S,T> &v) {
|
||||
const json::tree::array &array = node.as_array ();
|
||||
if (array.size () != S)
|
||||
throw std::runtime_error ("Invalid dimensionality for json-to-vector");
|
||||
|
||||
@ -440,7 +440,7 @@ template util::vector<S,T> util::operator* (float, const util::vector<S,T>&);
|
||||
template util::vector<S,T> util::operator+ (T, const util::vector<S,T>&); \
|
||||
template util::vector<S,T> util::operator- (T, const util::vector<S,T>&); \
|
||||
template std::ostream& util::operator<< (std::ostream&, const util::vector<S,T> &v);\
|
||||
template const json::node& util::operator>> (const json::node&, util::vector<S,T>&);
|
||||
template const json::tree::node& util::operator>> (const json::tree::node&, util::vector<S,T>&);
|
||||
|
||||
|
||||
#define INSTANTIATE(T) \
|
||||
|
@ -100,7 +100,7 @@ namespace util {
|
||||
template <size_t S, typename T> std::ostream& operator<< (std::ostream&, const vector<S,T>&);
|
||||
|
||||
template <size_t S, typename T>
|
||||
const json::node& operator>> (const json::node&, vector<S,T>&);
|
||||
const json::tree::node& operator>> (const json::tree::node&, vector<S,T>&);
|
||||
|
||||
// convenience typedefs
|
||||
typedef vector<2,size_t> vector2u;
|
||||
|
Loading…
Reference in New Issue
Block a user