From cfc0f8ecd004b444c9e997e7719d8d042d82cd0c Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 2 Feb 2015 21:22:38 +1100 Subject: [PATCH] json: move tree parsing code to json::tree --- colour.cpp | 6 +- colour.hpp | 2 +- json.cpp.rl | 158 ++++++++-------- json.hpp | 406 ++++++++++++++++++++-------------------- range.cpp | 6 +- test/json_types.cpp | 4 +- tools/json-clean.cpp | 4 +- tools/json-schema.cpp | 204 ++++++++++---------- tools/json-validate.cpp | 4 +- vector.cpp | 8 +- vector.hpp | 2 +- 11 files changed, 405 insertions(+), 399 deletions(-) diff --git a/colour.cpp b/colour.cpp index 9c612c08..0c42e298 100644 --- a/colour.cpp +++ b/colour.cpp @@ -52,9 +52,9 @@ util::colour::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 (node[0].as_number ()); c.g = static_cast (node[1].as_number ()); c.b = static_cast (node[2].as_number ()); diff --git a/colour.hpp b/colour.hpp index ff77374f..9adb6453 100644 --- a/colour.hpp +++ b/colour.hpp @@ -41,7 +41,7 @@ namespace util { typedef colour 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&); } diff --git a/json.cpp.rl b/json.cpp.rl index 56d9d84d..04006ac5 100644 --- a/json.cpp.rl +++ b/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 (nodestack.back ().value)); + unique_ptr (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 (nodestack.back ().value)); + json::tree::array *array = (json::tree::array *)nodestack.back ().root; + array->insert (unique_ptr (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::parse (const boost::filesystem::path &path) { +std::unique_ptr +json::tree::parse (const boost::filesystem::path &path) { auto data = slurp (path); return parse (static_cast (data.get ())); } -std::unique_ptr -json::parse (const std::string &path) +std::unique_ptr +json::tree::parse (const std::string &path) { return parse (path.c_str (), path.c_str () + path.size ()); } -std::unique_ptr -json::parse (const char *start, +std::unique_ptr +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 fsmstack; @@ -292,50 +292,50 @@ json::parse (const char *start, throw parse_error (os.str ()); } - return std::unique_ptr (__root); + return std::unique_ptr (__root); } -std::unique_ptr -json::parse (const char *start) +std::unique_ptr +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 &&value) +json::tree::object::insert (const std::string &_key, unique_ptr &&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 &&_value) - { m_values.push_back (move (_value)); } +json::tree::array::insert (unique_ptr &&_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::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 io::serialise (const bool &b) { @@ -600,4 +604,4 @@ namespace json { io::serialise (const float &f) { return std::unique_ptr (new number (f)); } -} +} } diff --git a/json.hpp b/json.hpp index af4ccd7b..760ed292 100644 --- a/json.hpp +++ b/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 parse (const boost::filesystem::path &path); - extern std::unique_ptr parse (const char *start, const char *stop); - extern std::unique_ptr parse (const char *start); - extern std::unique_ptr parse (const std::string&); + /// Parse an encoded form of JSON into a tree structure + extern std::unique_ptr parse (const boost::filesystem::path &path); + extern std::unique_ptr parse (const char *start, const char *stop); + extern std::unique_ptr parse (const char *start); + extern std::unique_ptr 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> 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> 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&& 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&& 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>::iterator pointer_array_iterator; - typedef std::vector>::const_iterator const_pointer_array_iterator; + /// Represents a JSON array, and contains its children. + class array : public node { + protected: + typedef std::vector>::iterator pointer_array_iterator; + typedef std::vector>::const_iterator const_pointer_array_iterator; - public: - typedef referencing_iterator iterator; - typedef referencing_iterator const_iterator; + public: + typedef referencing_iterator iterator; + typedef referencing_iterator const_iterator; - protected: - std::vector> m_values; + protected: + std::vector> 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 &&_value); + virtual void insert (std::unique_ptr &&_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 - struct io { - static std::unique_ptr serialise (const T&); - static T deserialise (const json::node&); - }; -} - - -template -std::unique_ptr to_json (const T &t, Args&&... args) { - return json::io::serialise (t, std::forward(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 + struct io { + static std::unique_ptr serialise (const T&); + static T deserialise (const json::tree::node&); + }; + } } template -T from_json (const json::node &n, Args&&... args) { - return json::io::deserialise (n, std::forward(args)...); +std::unique_ptr to_json (const T &t, Args&&... args) { + return json::tree::io::serialise (t, std::forward(args)...); +} + +template +T from_json (const json::tree::node &n, Args&&... args) { + return json::tree::io::deserialise (n, std::forward(args)...); } #endif diff --git a/range.cpp b/range.cpp index 688d5e78..b82916a6 100644 --- a/range.cpp +++ b/range.cpp @@ -186,10 +186,10 @@ namespace util { //----------------------------------------------------------------------------- -namespace json { +namespace json { namespace tree { template <> util::range - io>::deserialise (const json::node &node) { + io>::deserialise (const json::tree::node &node) { if (node.is_string () && (node == "UNIT" || node == "unit")) { return util::range::UNIT; @@ -203,4 +203,4 @@ namespace json { }; } } -} +} } diff --git a/test/json_types.cpp b/test/json_types.cpp index a6e6bcff..320f03ee 100644 --- a/test/json_types.cpp +++ b/test/json_types.cpp @@ -24,10 +24,10 @@ main (int, char**) { " ]" "}"; - std::unique_ptr ptr = json::parse (TEST_STRING); + std::unique_ptr 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 ()); diff --git a/tools/json-clean.cpp b/tools/json-clean.cpp index 6f72a9b0..769d3b92 100644 --- a/tools/json-clean.cpp +++ b/tools/json-clean.cpp @@ -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; } diff --git a/tools/json-schema.cpp b/tools/json-schema.cpp index 4980b988..309804f0 100644 --- a/tools/json-schema.cpp +++ b/tools/json-schema.cpp @@ -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> 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> 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 (node), constraint); +is_enum_valid (const json::tree::string &node, + const json::tree::node &constraint) { + return is_enum_valid (static_cast (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 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 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 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 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 schema, input; + unique_ptr 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)) { diff --git a/tools/json-validate.cpp b/tools/json-validate.cpp index d0d19616..b2c45167 100644 --- a/tools/json-validate.cpp +++ b/tools/json-validate.cpp @@ -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; } diff --git a/vector.cpp b/vector.cpp index 875d841a..8e50b0ce 100644 --- a/vector.cpp +++ b/vector.cpp @@ -414,9 +414,9 @@ util::operator<< (std::ostream &os, const util::vector &v) { //----------------------------------------------------------------------------- template -const json::node& -util::operator>> (const json::node &node, util::vector &v) { - const json::array &array = node.as_array (); +const json::tree::node& +util::operator>> (const json::tree::node &node, util::vector &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 util::operator* (float, const util::vector&); template util::vector util::operator+ (T, const util::vector&); \ template util::vector util::operator- (T, const util::vector&); \ template std::ostream& util::operator<< (std::ostream&, const util::vector &v);\ -template const json::node& util::operator>> (const json::node&, util::vector&); +template const json::tree::node& util::operator>> (const json::tree::node&, util::vector&); #define INSTANTIATE(T) \ diff --git a/vector.hpp b/vector.hpp index 2b827806..9383d0b3 100644 --- a/vector.hpp +++ b/vector.hpp @@ -100,7 +100,7 @@ namespace util { template std::ostream& operator<< (std::ostream&, const vector&); template - const json::node& operator>> (const json::node&, vector&); + const json::tree::node& operator>> (const json::tree::node&, vector&); // convenience typedefs typedef vector<2,size_t> vector2u;