From 2b43e7dbda1726f61b44c535590321dfcddde925 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Tue, 2 Feb 2010 20:59:23 +0200 Subject: [PATCH 1/9] C++: Untabify, reindent, delete trailing whitespace --- src/jansson-impl.hpp | 900 +++++++++++++++++------------------ src/jansson.hpp | 446 ++++++++--------- test/suites/api/test_cpp.cpp | 237 ++++----- 3 files changed, 793 insertions(+), 790 deletions(-) diff --git a/src/jansson-impl.hpp b/src/jansson-impl.hpp index dbf94df..de336dd 100644 --- a/src/jansson-impl.hpp +++ b/src/jansson-impl.hpp @@ -4,466 +4,466 @@ // it under the terms of the MIT license. See LICENSE for details. #if !defined(IN_JANSSON_HPP) -# error "jansson-impl.hpp may only by included from jansson.hpp" +#error "jansson-impl.hpp may only by included from jansson.hpp" #endif namespace json { - namespace _private { - // assignment operator - template - ValueBase<_Base>& ValueBase<_Base>::operator=(const Value& value) { - _Base::operator=(value); - return *this; - } - - // check value type - template - bool ValueBase<_Base>::is_undefined() const { - return _Base::as_json() == 0; - } - - template - bool ValueBase<_Base>::is_object() const { - return json_is_object(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_array() const { - return json_is_array(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_string() const { - return json_is_string(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_integer() const { - return json_is_integer(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_real() const { - return json_is_real(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_number() const { - return json_is_number(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_true() const { - return json_is_true(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_false() const { - return json_is_false(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_boolean() const { - return json_is_boolean(_Base::as_json()); - } - - template - bool ValueBase<_Base>::is_null() const { - return json_is_null(_Base::as_json()); - } - - // get size of array or object - template - unsigned int ValueBase<_Base>::size() const { - if (is_object()) - return json_object_size(_Base::as_json()); - else - return json_array_size(_Base::as_json()); - } - - // get value at array index (const version) - template - const Value ValueBase<_Base>::at(unsigned int index) const { - return Value(json_array_get(_Base::as_json(), index)); - } - - template - const Value ValueBase<_Base>::operator[](signed int index) const { return at(index); } - template - const Value ValueBase<_Base>::operator[](unsigned int index) const { return at(index); } - template - const Value ValueBase<_Base>::operator[](signed short index) const { return at(index); } - template - const Value ValueBase<_Base>::operator[](unsigned short index) const { return at(index); } - template - const Value ValueBase<_Base>::operator[](signed long index) const { return at(index); } - template - const Value ValueBase<_Base>::operator[](unsigned long index) const { return at(index); } - - // get value at array index (non-const version) - template - ValueBase ValueBase<_Base>::at(unsigned int index) { - return ElementProxy(_Base::as_json(), index); - } - - template - ValueBase ValueBase<_Base>::operator[](signed int index) { - return at(index); - } - - template - ValueBase ValueBase<_Base>::operator[](unsigned int index) { - return at(index); - } - - template - ValueBase ValueBase<_Base>::operator[](signed short index) { - return at(index); - } - - template - ValueBase ValueBase<_Base>::operator[](unsigned short index) { - return at(index); - } - - template - ValueBase ValueBase<_Base>::operator[](signed long index) { - return at(index); - } - - template - ValueBase ValueBase<_Base>::operator[](unsigned long index) { - return at(index); - } - - // get object property (const version) - template - const Value ValueBase<_Base>::get(const char* key) const { - return Value(json_object_get(_Base::as_json(), key)); - } - - template - const Value ValueBase<_Base>::get(const std::string& key) const { - return get(key.c_str()); - } - - template - const Value ValueBase<_Base>::operator[](const char* key) const { - return get(key); - } - - template - const Value ValueBase<_Base>::operator[](const std::string& key) const { - return get(key.c_str()); - } - - // get object property (non-const version) - template - ValueBase ValueBase<_Base>::get(const char* key) { - return PropertyProxy(_Base::as_json(), key); - } - - template - ValueBase ValueBase<_Base>::get(const std::string& key) { - return get(key.c_str()); - } - - template - ValueBase ValueBase<_Base>::operator[](const char* key) { - return get(key); - } - - template - ValueBase ValueBase<_Base>::operator[](const std::string& key) { - return get(key.c_str()); - } - - // clear all array/object values - template - void ValueBase<_Base>::clear() { - if (is_object()) - json_object_clear(_Base::as_json()); - else - json_array_clear(_Base::as_json()); - } - - // get value cast to specified type - template - const char* ValueBase<_Base>::as_cstring() const { - return json_string_value(_Base::as_json()); - } - - template - std::string ValueBase<_Base>::as_string() const { - const char* tmp = as_cstring(); - return tmp == 0 ? "" : tmp; - } - - template - int ValueBase<_Base>::as_integer() const { - return json_integer_value(_Base::as_json()); - } - - template - double ValueBase<_Base>::as_real() const { - return json_real_value(_Base::as_json()); - } - - template - double ValueBase<_Base>::as_number() const { - return json_number_value(_Base::as_json()); - } - - template - bool ValueBase<_Base>::as_boolean() const { - return is_true(); - } - - // set an object property (converts value to object is not one already) - template - _Base& ValueBase<_Base>::set_key(const char* key, const Value& value) { - json_object_set(_Base::as_json(), key, value._Base::as_json()); - return *this; - } - - template - _Base& ValueBase<_Base>::set_key(const std::string& key, const Value& value) { - return set_key(key.c_str(), value); - } - - // set an array index (converts value to object is not one already) - template - _Base& ValueBase<_Base>::set_at(unsigned int index, const Value& value) { - if (index == size()) - json_array_append(_Base::as_json(), value._Base::as_json()); - else - json_array_set(_Base::as_json(), index, value._Base::as_json()); - return *this; - } - - // delete an object key - template - _Base& ValueBase<_Base>::del_key(const char* key) { - json_object_del(_Base::as_json(), key); - return *this; - } - - template - _Base& ValueBase<_Base>::del_key(const std::string& key) { - return del_key(key.c_str()); - } - - // delete an item from an array by index - template - _Base& ValueBase<_Base>::del_at(unsigned int index) { - json_array_remove(_Base::as_json(), index); - return *this; - } - - // insert an item into an array at a given index - template - _Base& ValueBase<_Base>::insert_at(unsigned int index, const Value& value) { - json_array_insert(_Base::as_json(), index, value._Base::as_json()); - return *this; - } - - // write the value to a file - template - int ValueBase<_Base>::save_file(const char* path, int flags) const { - return json_dump_file(_Base::as_json(), path, flags); - } - - // write the value to a string (caller must deallocate with free()!) - template - char* ValueBase<_Base>::save_string(int flags) const { - return json_dumps(_Base::as_json(), flags); - } - - Basic::~Basic() { - json_decref(_value); - } - - // copy an existing Value - Basic& Basic::operator=(const Basic& e) { - if (&e != this) { - json_decref(_value); - _value = json_incref(e._value); - } - return *this; - } - - // get the underlying json_t - json_t* Basic::as_json() const { - return _value; - } - - // take ownership of a json_t (does not increase reference count) - Basic Basic::take_ownership(json_t* json) { - Basic v; - v._value = json; - return v; - } - - // assign value to proxied array element - ElementProxy& ElementProxy::operator=(const Value& value) { - json_array_set(_array, _index, value.as_json()); - return *this; - } - - // get the proxied element - json_t* ElementProxy::as_json() const { - return json_array_get(_array, _index); - } - - // assign value to proxied object property - PropertyProxy& PropertyProxy::operator=(const Value& value) { - json_object_set(_object, _key, value.as_json()); - return *this; - } - - json_t* PropertyProxy::as_json() const { - return json_object_get(_object, _key); - } - - } // namespace json::_private - - // construct Value::Value input - Value::Value(const char* value) { - _value = json_string(value); - } - - Value::Value(const std::string& value) { - _value = json_string(value.c_str()); - } - - Value::Value(bool value) { - _value = value ? json_true() : json_false(); - } - - Value::Value(signed int value) { - _value = json_integer(value); - } - - Value::Value(unsigned int value) { - _value = json_integer(value); - } - - Value::Value(signed short value) { - _value = json_integer(value); - } - - Value::Value(unsigned short value) { - _value = json_integer(value); - } - - Value::Value(signed long value) { - _value = json_integer(value); - } - - Value::Value(unsigned long value) { - _value = json_integer(value); - } - - Value::Value(float value) { - _value = json_real(value); - } - - Value::Value(double value) { - _value = json_real(value); - } - - // construct a new iterator for a given object - Iterator::Iterator(const Value& value) : _object(value), _iter(0) { - _iter = json_object_iter(_object.as_json()); - } - - // construct a new iterator for a given object - Iterator::Iterator(const _private::ValueBase<_private::PropertyProxy>& value) : - _object(value.as_json()), _iter(0) { - _iter = json_object_iter(_object.as_json()); - } - - // increment iterator - void Iterator::next() { - _iter = json_object_iter_next(_object.as_json(), _iter); - } - - Iterator& Iterator::operator++() { next(); return *this; } - - // test if iterator is still valid - bool Iterator::valid() const { - return _iter != 0; - } - - Iterator::operator bool() const { - return valid(); - } - - // get key - const char* Iterator::ckey() const { - return json_object_iter_key(_iter); - } - - std::string Iterator::key() const { - return ckey(); - } - - // get value - const Value Iterator::value() const { - return Value(json_object_iter_value(_iter)); - } - - // dereference value - const Value Iterator::operator*() const { - return value(); - } - - // create a new empty object - Value object() { - return Value::take_ownership(json_object()); - } - - // create a new empty array - Value array() { - return Value::take_ownership(json_array()); - } - - // create a new null value - Value null() { - return Value::take_ownership(json_null()); - } - - // load a file as a JSON value - Value load_file(const char* path, json_error_t* error) { - return Value::take_ownership(json_load_file(path, error)); - } - - // load a string as a JSON value - Value load_string(const char* string, json_error_t* error) { - return Value::take_ownership(json_loads(string, error)); - } + namespace _private { + // assignment operator + template + ValueBase<_Base>& ValueBase<_Base>::operator=(const Value& value) { + _Base::operator=(value); + return *this; + } + + // check value type + template + bool ValueBase<_Base>::is_undefined() const { + return _Base::as_json() == 0; + } + + template + bool ValueBase<_Base>::is_object() const { + return json_is_object(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_array() const { + return json_is_array(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_string() const { + return json_is_string(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_integer() const { + return json_is_integer(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_real() const { + return json_is_real(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_number() const { + return json_is_number(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_true() const { + return json_is_true(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_false() const { + return json_is_false(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_boolean() const { + return json_is_boolean(_Base::as_json()); + } + + template + bool ValueBase<_Base>::is_null() const { + return json_is_null(_Base::as_json()); + } + + // get size of array or object + template + unsigned int ValueBase<_Base>::size() const { + if (is_object()) + return json_object_size(_Base::as_json()); + else + return json_array_size(_Base::as_json()); + } + + // get value at array index (const version) + template + const Value ValueBase<_Base>::at(unsigned int index) const { + return Value(json_array_get(_Base::as_json(), index)); + } + + template + const Value ValueBase<_Base>::operator[](signed int index) const { return at(index); } + template + const Value ValueBase<_Base>::operator[](unsigned int index) const { return at(index); } + template + const Value ValueBase<_Base>::operator[](signed short index) const { return at(index); } + template + const Value ValueBase<_Base>::operator[](unsigned short index) const { return at(index); } + template + const Value ValueBase<_Base>::operator[](signed long index) const { return at(index); } + template + const Value ValueBase<_Base>::operator[](unsigned long index) const { return at(index); } + + // get value at array index (non-const version) + template + ValueBase ValueBase<_Base>::at(unsigned int index) { + return ElementProxy(_Base::as_json(), index); + } + + template + ValueBase ValueBase<_Base>::operator[](signed int index) { + return at(index); + } + + template + ValueBase ValueBase<_Base>::operator[](unsigned int index) { + return at(index); + } + + template + ValueBase ValueBase<_Base>::operator[](signed short index) { + return at(index); + } + + template + ValueBase ValueBase<_Base>::operator[](unsigned short index) { + return at(index); + } + + template + ValueBase ValueBase<_Base>::operator[](signed long index) { + return at(index); + } + + template + ValueBase ValueBase<_Base>::operator[](unsigned long index) { + return at(index); + } + + // get object property (const version) + template + const Value ValueBase<_Base>::get(const char* key) const { + return Value(json_object_get(_Base::as_json(), key)); + } + + template + const Value ValueBase<_Base>::get(const std::string& key) const { + return get(key.c_str()); + } + + template + const Value ValueBase<_Base>::operator[](const char* key) const { + return get(key); + } + + template + const Value ValueBase<_Base>::operator[](const std::string& key) const { + return get(key.c_str()); + } + + // get object property (non-const version) + template + ValueBase ValueBase<_Base>::get(const char* key) { + return PropertyProxy(_Base::as_json(), key); + } + + template + ValueBase ValueBase<_Base>::get(const std::string& key) { + return get(key.c_str()); + } + + template + ValueBase ValueBase<_Base>::operator[](const char* key) { + return get(key); + } + + template + ValueBase ValueBase<_Base>::operator[](const std::string& key) { + return get(key.c_str()); + } + + // clear all array/object values + template + void ValueBase<_Base>::clear() { + if (is_object()) + json_object_clear(_Base::as_json()); + else + json_array_clear(_Base::as_json()); + } + + // get value cast to specified type + template + const char* ValueBase<_Base>::as_cstring() const { + return json_string_value(_Base::as_json()); + } + + template + std::string ValueBase<_Base>::as_string() const { + const char* tmp = as_cstring(); + return tmp == 0 ? "" : tmp; + } + + template + int ValueBase<_Base>::as_integer() const { + return json_integer_value(_Base::as_json()); + } + + template + double ValueBase<_Base>::as_real() const { + return json_real_value(_Base::as_json()); + } + + template + double ValueBase<_Base>::as_number() const { + return json_number_value(_Base::as_json()); + } + + template + bool ValueBase<_Base>::as_boolean() const { + return is_true(); + } + + // set an object property (converts value to object is not one already) + template + _Base& ValueBase<_Base>::set_key(const char* key, const Value& value) { + json_object_set(_Base::as_json(), key, value._Base::as_json()); + return *this; + } + + template + _Base& ValueBase<_Base>::set_key(const std::string& key, const Value& value) { + return set_key(key.c_str(), value); + } + + // set an array index (converts value to object is not one already) + template + _Base& ValueBase<_Base>::set_at(unsigned int index, const Value& value) { + if (index == size()) + json_array_append(_Base::as_json(), value._Base::as_json()); + else + json_array_set(_Base::as_json(), index, value._Base::as_json()); + return *this; + } + + // delete an object key + template + _Base& ValueBase<_Base>::del_key(const char* key) { + json_object_del(_Base::as_json(), key); + return *this; + } + + template + _Base& ValueBase<_Base>::del_key(const std::string& key) { + return del_key(key.c_str()); + } + + // delete an item from an array by index + template + _Base& ValueBase<_Base>::del_at(unsigned int index) { + json_array_remove(_Base::as_json(), index); + return *this; + } + + // insert an item into an array at a given index + template + _Base& ValueBase<_Base>::insert_at(unsigned int index, const Value& value) { + json_array_insert(_Base::as_json(), index, value._Base::as_json()); + return *this; + } + + // write the value to a file + template + int ValueBase<_Base>::save_file(const char* path, int flags) const { + return json_dump_file(_Base::as_json(), path, flags); + } + + // write the value to a string (caller must deallocate with free()!) + template + char* ValueBase<_Base>::save_string(int flags) const { + return json_dumps(_Base::as_json(), flags); + } + + Basic::~Basic() { + json_decref(_value); + } + + // copy an existing Value + Basic& Basic::operator=(const Basic& e) { + if (&e != this) { + json_decref(_value); + _value = json_incref(e._value); + } + return *this; + } + + // get the underlying json_t + json_t* Basic::as_json() const { + return _value; + } + + // take ownership of a json_t (does not increase reference count) + Basic Basic::take_ownership(json_t* json) { + Basic v; + v._value = json; + return v; + } + + // assign value to proxied array element + ElementProxy& ElementProxy::operator=(const Value& value) { + json_array_set(_array, _index, value.as_json()); + return *this; + } + + // get the proxied element + json_t* ElementProxy::as_json() const { + return json_array_get(_array, _index); + } + + // assign value to proxied object property + PropertyProxy& PropertyProxy::operator=(const Value& value) { + json_object_set(_object, _key, value.as_json()); + return *this; + } + + json_t* PropertyProxy::as_json() const { + return json_object_get(_object, _key); + } + + } // namespace json::_private + + // construct Value::Value input + Value::Value(const char* value) { + _value = json_string(value); + } + + Value::Value(const std::string& value) { + _value = json_string(value.c_str()); + } + + Value::Value(bool value) { + _value = value ? json_true() : json_false(); + } + + Value::Value(signed int value) { + _value = json_integer(value); + } + + Value::Value(unsigned int value) { + _value = json_integer(value); + } + + Value::Value(signed short value) { + _value = json_integer(value); + } + + Value::Value(unsigned short value) { + _value = json_integer(value); + } + + Value::Value(signed long value) { + _value = json_integer(value); + } + + Value::Value(unsigned long value) { + _value = json_integer(value); + } + + Value::Value(float value) { + _value = json_real(value); + } + + Value::Value(double value) { + _value = json_real(value); + } + + // construct a new iterator for a given object + Iterator::Iterator(const Value& value) : _object(value), _iter(0) { + _iter = json_object_iter(_object.as_json()); + } + + // construct a new iterator for a given object + Iterator::Iterator(const _private::ValueBase<_private::PropertyProxy>& value) : + _object(value.as_json()), _iter(0) { + _iter = json_object_iter(_object.as_json()); + } + + // increment iterator + void Iterator::next() { + _iter = json_object_iter_next(_object.as_json(), _iter); + } + + Iterator& Iterator::operator++() { next(); return *this; } + + // test if iterator is still valid + bool Iterator::valid() const { + return _iter != 0; + } + + Iterator::operator bool() const { + return valid(); + } + + // get key + const char* Iterator::ckey() const { + return json_object_iter_key(_iter); + } + + std::string Iterator::key() const { + return ckey(); + } + + // get value + const Value Iterator::value() const { + return Value(json_object_iter_value(_iter)); + } + + // dereference value + const Value Iterator::operator*() const { + return value(); + } + + // create a new empty object + Value object() { + return Value::take_ownership(json_object()); + } + + // create a new empty array + Value array() { + return Value::take_ownership(json_array()); + } + + // create a new null value + Value null() { + return Value::take_ownership(json_null()); + } + + // load a file as a JSON value + Value load_file(const char* path, json_error_t* error) { + return Value::take_ownership(json_load_file(path, error)); + } + + // load a string as a JSON value + Value load_string(const char* string, json_error_t* error) { + return Value::take_ownership(json_loads(string, error)); + } } // namespace json // stream JSON value out std::ostream& operator<<(std::ostream& os, const json::Value& value) { - // get the temporary serialize string - char* tmp = value.save_string(); - if (tmp != 0) { - // stream temp string out and release it - os << tmp; - free(tmp); - } - return os; + // get the temporary serialize string + char* tmp = value.save_string(); + if (tmp != 0) { + // stream temp string out and release it + os << tmp; + free(tmp); + } + return os; } // read JSON value std::istream& operator>>(std::istream& is, json::Value& value) { - // buffer the remaining bytes into a single string for Jansson - std::stringstream tmp; - while (is) - tmp << static_cast(is.get()); - // parse the buffered string - value = json::load_string(tmp.str().c_str()); - return is; + // buffer the remaining bytes into a single string for Jansson + std::stringstream tmp; + while (is) + tmp << static_cast(is.get()); + // parse the buffered string + value = json::load_string(tmp.str().c_str()); + return is; } diff --git a/src/jansson.hpp b/src/jansson.hpp index 1bd18b1..020a277 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -13,281 +13,281 @@ #include namespace json { - // include Jansson C library into the json namespace - #include - - class Iterator; - class Value; - - // implementation details; do not use directly - namespace _private { - class ElementProxy; - class PropertyProxy; + // include Jansson C library into the json namespace +# include + + class Iterator; + class Value; + + // implementation details; do not use directly + namespace _private { + class ElementProxy; + class PropertyProxy; - // base class for JSON value interface - template - class ValueBase : public _Base { - public: - // empty constructor - ValueBase() : _Base() {} - - // copy constructor - ValueBase(const _Base& base) : _Base(base) {} - - // create reference to value - ValueBase(json_t* json) : _Base(json) {} - - // assignment operator - inline ValueBase& operator=(const Value& value); + // base class for JSON value interface + template + class ValueBase : public _Base { + public: + // empty constructor + ValueBase() : _Base() {} + + // copy constructor + ValueBase(const _Base& base) : _Base(base) {} + + // create reference to value + ValueBase(json_t* json) : _Base(json) {} + + // assignment operator + inline ValueBase& operator=(const Value& value); - // check value type - inline bool is_undefined() const; - inline bool is_object() const; - inline bool is_array() const; - inline bool is_string() const; - inline bool is_integer() const; - inline bool is_real() const; - inline bool is_number() const; - inline bool is_true() const; - inline bool is_false() const; - inline bool is_boolean() const; - inline bool is_null() const; + // check value type + inline bool is_undefined() const; + inline bool is_object() const; + inline bool is_array() const; + inline bool is_string() const; + inline bool is_integer() const; + inline bool is_real() const; + inline bool is_number() const; + inline bool is_true() const; + inline bool is_false() const; + inline bool is_boolean() const; + inline bool is_null() const; - // get size of array or object - inline unsigned int size() const; + // get size of array or object + inline unsigned int size() const; - // get value at array index (const version) - inline const Value at(unsigned int index) const; + // get value at array index (const version) + inline const Value at(unsigned int index) const; - inline const Value operator[](signed int index) const; - inline const Value operator[](unsigned int index) const; - inline const Value operator[](signed short index) const; - inline const Value operator[](unsigned short index) const; - inline const Value operator[](signed long index) const; - inline const Value operator[](unsigned long index) const; + inline const Value operator[](signed int index) const; + inline const Value operator[](unsigned int index) const; + inline const Value operator[](signed short index) const; + inline const Value operator[](unsigned short index) const; + inline const Value operator[](signed long index) const; + inline const Value operator[](unsigned long index) const; - // get value at array index (non-const version) - inline ValueBase at(unsigned int index); + // get value at array index (non-const version) + inline ValueBase at(unsigned int index); - inline ValueBase operator[](signed int index); - inline ValueBase operator[](unsigned int index); - inline ValueBase operator[](signed short index); - inline ValueBase operator[](unsigned short index); - inline ValueBase operator[](signed long index); - inline ValueBase operator[](unsigned long index); + inline ValueBase operator[](signed int index); + inline ValueBase operator[](unsigned int index); + inline ValueBase operator[](signed short index); + inline ValueBase operator[](unsigned short index); + inline ValueBase operator[](signed long index); + inline ValueBase operator[](unsigned long index); - // get object property (const version) - inline const Value get(const char* key) const; + // get object property (const version) + inline const Value get(const char* key) const; - inline const Value get(const std::string& key) const; - inline const Value operator[](const char* key) const; - inline const Value operator[](const std::string& key) const; + inline const Value get(const std::string& key) const; + inline const Value operator[](const char* key) const; + inline const Value operator[](const std::string& key) const; - // get object property (non-const version) - inline ValueBase get(const char* key); + // get object property (non-const version) + inline ValueBase get(const char* key); - inline ValueBase get(const std::string& key); - inline ValueBase operator[](const char* key); - inline ValueBase operator[](const std::string& key); + inline ValueBase get(const std::string& key); + inline ValueBase operator[](const char* key); + inline ValueBase operator[](const std::string& key); - // clear all array/object values - inline void clear(); + // clear all array/object values + inline void clear(); - // get value cast to specified type - inline const char* as_cstring() const; - inline std::string as_string() const; - inline int as_integer() const; - inline double as_real() const; - inline double as_number() const; - inline bool as_boolean() const; + // get value cast to specified type + inline const char* as_cstring() const; + inline std::string as_string() const; + inline int as_integer() const; + inline double as_real() const; + inline double as_number() const; + inline bool as_boolean() const; - // set an object property (converts value to object is not one already) - inline _Base& set_key(const char* key, const Value& value); + // set an object property (converts value to object is not one already) + inline _Base& set_key(const char* key, const Value& value); - inline _Base& set_key(const std::string& key, const Value& value); - - // set an array index (converts value to object is not one already) - inline _Base& set_at(unsigned int index, const Value& value); - - // delete an object key - inline _Base& del_key(const char* key); - - inline _Base& del_key(const std::string& key); - - // delete an item from an array by index - inline _Base& del_at(unsigned int index); - - // insert an item into an array at a given index - inline _Base& insert_at(unsigned int index, const Value& value); - - // write the value to a file - inline int save_file(const char* path, int flags = 0) const; - - // write the value to a string (caller must deallocate with free()!) - inline char* save_string(int flags = 0) const; - }; - - // represents any JSON value, private base - class Basic { - public: - // construct new Value with an undefined value - Basic() : _value(0) {} - - // copy constructor - Basic(const Basic& value) : _value(json_incref(value._value)) {} - - // make a reference to an existing json_t value - explicit Basic(json_t* value) : _value(json_incref(value)) {} - - // free Value resources - inline ~Basic(); - - // copy an existing Value - inline Basic& operator=(const Basic& e); - - // get the underlying json_t - inline json_t* as_json() const; + inline _Base& set_key(const std::string& key, const Value& value); + + // set an array index (converts value to object is not one already) + inline _Base& set_at(unsigned int index, const Value& value); + + // delete an object key + inline _Base& del_key(const char* key); + + inline _Base& del_key(const std::string& key); + + // delete an item from an array by index + inline _Base& del_at(unsigned int index); + + // insert an item into an array at a given index + inline _Base& insert_at(unsigned int index, const Value& value); + + // write the value to a file + inline int save_file(const char* path, int flags = 0) const; + + // write the value to a string (caller must deallocate with free()!) + inline char* save_string(int flags = 0) const; + }; + + // represents any JSON value, private base + class Basic { + public: + // construct new Value with an undefined value + Basic() : _value(0) {} + + // copy constructor + Basic(const Basic& value) : _value(json_incref(value._value)) {} + + // make a reference to an existing json_t value + explicit Basic(json_t* value) : _value(json_incref(value)) {} + + // free Value resources + inline ~Basic(); + + // copy an existing Value + inline Basic& operator=(const Basic& e); - // take ownership of a json_t (does not increase reference count) - inline static Basic take_ownership(json_t* json); + // get the underlying json_t + inline json_t* as_json() const; - protected: - // internal value pointer - json_t* _value; - }; + // take ownership of a json_t (does not increase reference count) + inline static Basic take_ownership(json_t* json); - // proxies an array element - class ElementProxy { - public: - // constructor - ElementProxy(json_t* array, unsigned int index) : _array(array), _index(index) {} + protected: + // internal value pointer + json_t* _value; + }; - // assign to the proxied element - inline ElementProxy& operator=(const Value& value); + // proxies an array element + class ElementProxy { + public: + // constructor + ElementProxy(json_t* array, unsigned int index) : _array(array), _index(index) {} - // get the proxied element - inline json_t* as_json() const; + // assign to the proxied element + inline ElementProxy& operator=(const Value& value); - private: - // array object we wrap - json_t* _array; + // get the proxied element + inline json_t* as_json() const; - // index of property - unsigned int _index; - }; + private: + // array object we wrap + json_t* _array; - // proxies an object property - class PropertyProxy { - public: - // constructor - PropertyProxy(json_t* array, const char* key) : _object(array), _key(key) {} + // index of property + unsigned int _index; + }; - // assign to the proxied element - inline PropertyProxy& operator=(const Value& value); + // proxies an object property + class PropertyProxy { + public: + // constructor + PropertyProxy(json_t* array, const char* key) : _object(array), _key(key) {} - // get the proxied element - inline json_t* as_json() const; + // assign to the proxied element + inline PropertyProxy& operator=(const Value& value); - private: - // array object we wrap - json_t* _object; + // get the proxied element + inline json_t* as_json() const; - // key of property - const char* _key; - }; + private: + // array object we wrap + json_t* _object; - } // namespace json::_private + // key of property + const char* _key; + }; - // represents any JSON value - class Value : public _private::ValueBase<_private::Basic> { - public: - // construct Value from input - explicit inline Value(const char* value); - explicit inline Value(const std::string& value); - explicit inline Value(bool value); - explicit inline Value(signed int value); - explicit inline Value(unsigned int value); - explicit inline Value(signed short value); - explicit inline Value(unsigned short value); - explicit inline Value(signed long value); - explicit inline Value(unsigned long value); - explicit inline Value(float value); - explicit inline Value(double value); + } // namespace json::_private - // empty constructor - Value() : _private::ValueBase<_private::Basic>() {} + // represents any JSON value + class Value : public _private::ValueBase<_private::Basic> { + public: + // construct Value from input + explicit inline Value(const char* value); + explicit inline Value(const std::string& value); + explicit inline Value(bool value); + explicit inline Value(signed int value); + explicit inline Value(unsigned int value); + explicit inline Value(signed short value); + explicit inline Value(unsigned short value); + explicit inline Value(signed long value); + explicit inline Value(unsigned long value); + explicit inline Value(float value); + explicit inline Value(double value); - // copy constructor for base - Value(const _private::Basic& value) : _private::ValueBase<_private::Basic>(value) {} - - // copy constructor for base - Value(const _private::ValueBase<_private::Basic>& value) : _private::ValueBase<_private::Basic>(value) {} + // empty constructor + Value() : _private::ValueBase<_private::Basic>() {} - // copy constructor - Value(const Value& value) : _private::ValueBase<_private::Basic>(value) {} + // copy constructor for base + Value(const _private::Basic& value) : _private::ValueBase<_private::Basic>(value) {} - // create reference to value - explicit Value(json_t* json) : _private::ValueBase<_private::Basic>(json) {} - }; + // copy constructor for base + Value(const _private::ValueBase<_private::Basic>& value) : _private::ValueBase<_private::Basic>(value) {} - // iterators over a JSON object - class Iterator { - public: - // construct a new iterator for a given object - inline Iterator(const Value& value); + // copy constructor + Value(const Value& value) : _private::ValueBase<_private::Basic>(value) {} - // construct a new iterator for a given object - inline Iterator(const _private::ValueBase<_private::PropertyProxy>& value); + // create reference to value + explicit Value(json_t* json) : _private::ValueBase<_private::Basic>(json) {} + }; - // increment iterator - inline void next(); + // iterators over a JSON object + class Iterator { + public: + // construct a new iterator for a given object + inline Iterator(const Value& value); - inline Iterator& operator++(); + // construct a new iterator for a given object + inline Iterator(const _private::ValueBase<_private::PropertyProxy>& value); - // test if iterator is still valid - inline bool valid() const; + // increment iterator + inline void next(); - inline operator bool() const; + inline Iterator& operator++(); - // get key - inline const char* ckey() const; + // test if iterator is still valid + inline bool valid() const; - inline std::string key() const; + inline operator bool() const; - // get value - inline const Value value() const; + // get key + inline const char* ckey() const; - // dereference value - inline const Value operator*() const; + inline std::string key() const; - private: - // disallow copying - Iterator(const Iterator&); - Iterator& operator=(const Iterator&); + // get value + inline const Value value() const; - // object being iterated over - Value _object; + // dereference value + inline const Value operator*() const; - // iterator value - void* _iter; - }; + private: + // disallow copying + Iterator(const Iterator&); + Iterator& operator=(const Iterator&); - // create a new empty object - inline Value object(); + // object being iterated over + Value _object; - // create a new empty array - inline Value array(); + // iterator value + void* _iter; + }; - // create a new null value - inline Value null(); + // create a new empty object + inline Value object(); - // load a file as a JSON value - inline Value load_file(const char* path, json_error_t* error = 0); + // create a new empty array + inline Value array(); - // load a string as a JSON value - inline Value load_string(const char* string, json_error_t* error = 0); + // create a new null value + inline Value null(); -} // namespace json + // load a file as a JSON value + inline Value load_file(const char* path, json_error_t* error = 0); + + // load a string as a JSON value + inline Value load_string(const char* string, json_error_t* error = 0); + +} // namespace json // stream JSON value out -- inefficient and not recommended for production use inline std::ostream& operator<<(std::ostream& os, const json::Value& value); diff --git a/test/suites/api/test_cpp.cpp b/test/suites/api/test_cpp.cpp index edcac77..5d3964a 100644 --- a/test/suites/api/test_cpp.cpp +++ b/test/suites/api/test_cpp.cpp @@ -4,156 +4,159 @@ #include "jansson.hpp" -#define ASSERT_OP(lhs, rhs, op, m) \ - do { \ - if(!((lhs) op (rhs))) { \ - std::cerr << std::boolalpha; \ - std::cerr << __FILE__ << '[' << __LINE__ << "]: ERROR: " << (m) << std::endl; \ - std::cerr << "\ttest: " << #lhs << ' ' << #op << ' ' << #rhs << std::endl; \ - std::cerr << "\tresult: " << (lhs) << ' ' << #op << ' ' << (rhs) << std::endl; \ - return 1; \ - } \ - } while(0) +#define ASSERT_OP(lhs, rhs, op, m) \ + do { \ + if(!((lhs) op (rhs))) { \ + std::cerr << std::boolalpha; \ + std::cerr << __FILE__ << '[' << __LINE__ << "]: ERROR: " \ + << (m) << std::endl; \ + std::cerr << "\ttest: " << #lhs << ' ' << #op << ' ' \ + << #rhs << std::endl; \ + std::cerr << "\tresult: " << (lhs) << ' ' << #op << ' ' \ + << (rhs) << std::endl; \ + return 1; \ + } \ + } while(0) #define ASSERT_EQ(lhs, rhs, m) ASSERT_OP(lhs, rhs, ==, m) #define ASSERT_NE(lhs, rhs, m) ASSERT_OP(lhs, rhs, !=, m) #define ASSERT_TRUE(p, m) ASSERT_OP(p, true, ==, m) #define ASSERT_FALSE(p, m) ASSERT_OP(p, true, !=, m) int main() { - json::Value e1(json::load_file("suites/api/test.json")); - json::Value e2(e1); - json::Value e3; - json::Value e4(json::load_string("{\"foo\": true, \"bar\": \"test\"}")); + json::Value e1(json::load_file("suites/api/test.json")); + json::Value e2(e1); + json::Value e3; + json::Value e4(json::load_string("{\"foo\": true, \"bar\": \"test\"}")); - ASSERT_TRUE(e1.is_object(), "e1 is not an object"); - ASSERT_TRUE(e2.is_object(), "e2 is not an object"); - ASSERT_TRUE(e3.is_undefined(), "e3 has a defined value"); - ASSERT_TRUE(e4.is_object(), "e4 is not an object"); + ASSERT_TRUE(e1.is_object(), "e1 is not an object"); + ASSERT_TRUE(e2.is_object(), "e2 is not an object"); + ASSERT_TRUE(e3.is_undefined(), "e3 has a defined value"); + ASSERT_TRUE(e4.is_object(), "e4 is not an object"); - ASSERT_EQ(e1.size(), 1, "e1 has too many properties"); - ASSERT_EQ(e2.size(), 1, "e2 has too many properties"); - ASSERT_EQ(e4.size(), 2, "e4 does not have 2 elements"); + ASSERT_EQ(e1.size(), 1, "e1 has too many properties"); + ASSERT_EQ(e2.size(), 1, "e2 has too many properties"); + ASSERT_EQ(e4.size(), 2, "e4 does not have 2 elements"); - ASSERT_TRUE(e1.get("web-app").is_object(), "e1[0].web-app is not an object"); - ASSERT_EQ(e1.get("web-app").get("servlet").at(0).get("servlet-class").as_string(), "org.cofax.cds.CDSServlet", "property has incorrect value"); - ASSERT_EQ(e1["web-app"]["servlet"][0]["servlet-class"].as_string(), "org.cofax.cds.CDSServlet", "property has incorrect value"); + ASSERT_TRUE(e1.get("web-app").is_object(), "e1[0].web-app is not an object"); + ASSERT_EQ(e1.get("web-app").get("servlet").at(0).get("servlet-class").as_string(), "org.cofax.cds.CDSServlet", "property has incorrect value"); + ASSERT_EQ(e1["web-app"]["servlet"][0]["servlet-class"].as_string(), "org.cofax.cds.CDSServlet", "property has incorrect value"); - ASSERT_EQ(e4["foo"].as_boolean(), true, "property has incorrect value"); + ASSERT_EQ(e4["foo"].as_boolean(), true, "property has incorrect value"); - json::Iterator i(e1.get("web-app")); - ASSERT_EQ(i.key(), "taglib", "first iterator result has incorrect key"); - i.next(); - ASSERT_EQ(i.key(), "servlet", "first iterator result has incorrect key"); - i.next(); - ASSERT_EQ(i.key(), "servlet-mapping", "first iterator result has incorrect key"); - i.next(); - ASSERT_FALSE(i.valid(), "iterator has more values than expected"); + json::Iterator i(e1.get("web-app")); + ASSERT_EQ(i.key(), "taglib", "first iterator result has incorrect key"); + i.next(); + ASSERT_EQ(i.key(), "servlet", "first iterator result has incorrect key"); + i.next(); + ASSERT_EQ(i.key(), "servlet-mapping", "first iterator result has incorrect key"); + i.next(); + ASSERT_FALSE(i.valid(), "iterator has more values than expected"); - json::Value e5(json::Value(12.34)); - ASSERT_TRUE(e5.is_number(), "e5 is not a number after assignment"); - ASSERT_EQ(e5.as_real(), 12.34, "e5 has incorrect value after assignment"); + json::Value e5(json::Value(12.34)); + ASSERT_TRUE(e5.is_number(), "e5 is not a number after assignment"); + ASSERT_EQ(e5.as_real(), 12.34, "e5 has incorrect value after assignment"); - json::Value e6(json::Value(true)); - ASSERT_TRUE(e6.is_boolean(), "e6 is not a boolean after assignment"); - ASSERT_EQ(e6.as_boolean(), true, "e6 has incorrect value after assignment"); + json::Value e6(json::Value(true)); + ASSERT_TRUE(e6.is_boolean(), "e6 is not a boolean after assignment"); + ASSERT_EQ(e6.as_boolean(), true, "e6 has incorrect value after assignment"); - json::Value e7(json::Value("foobar")); - ASSERT_TRUE(e7.is_string(), "e7 is not a string after assignment"); - ASSERT_EQ(e7.as_string(), "foobar", "e7 has incorrect value after assignment"); + json::Value e7(json::Value("foobar")); + ASSERT_TRUE(e7.is_string(), "e7 is not a string after assignment"); + ASSERT_EQ(e7.as_string(), "foobar", "e7 has incorrect value after assignment"); - json::Value e8(json::object()); - ASSERT_TRUE(e8.is_object(), "e8 is not an object after assignment"); + json::Value e8(json::object()); + ASSERT_TRUE(e8.is_object(), "e8 is not an object after assignment"); - json::Value e9(json::null()); - ASSERT_TRUE(e9.is_null(), "e9 is not null after assignment"); + json::Value e9(json::null()); + ASSERT_TRUE(e9.is_null(), "e9 is not null after assignment"); - json::Value e10(json::array()); - ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); + json::Value e10(json::array()); + ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); - e10.set_at(0, json::Value("foobar")); - ASSERT_EQ(e10.size(), 1, "e10 has incorrect number of elements after assignment"); - ASSERT_EQ(e10[0].as_string(), "foobar", "e10[0] has incorrect value after assignment"); + e10.set_at(0, json::Value("foobar")); + ASSERT_EQ(e10.size(), 1, "e10 has incorrect number of elements after assignment"); + ASSERT_EQ(e10[0].as_string(), "foobar", "e10[0] has incorrect value after assignment"); - e10.set_at(1, json::Value("foobar")); - ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); - ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); - ASSERT_EQ(e10[1].as_string(), "foobar", "e10[0] has incorrect value after assignment"); + e10.set_at(1, json::Value("foobar")); + ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); + ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); + ASSERT_EQ(e10[1].as_string(), "foobar", "e10[0] has incorrect value after assignment"); - e10.set_at(0, json::Value("barfoo")); - ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); - ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); - ASSERT_EQ(e10[0].as_string(), "barfoo", "e10[0] has incorrect value after assignment"); + e10.set_at(0, json::Value("barfoo")); + ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); + ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); + ASSERT_EQ(e10[0].as_string(), "barfoo", "e10[0] has incorrect value after assignment"); - e10.set_at(100, json::null()); - ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); - ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); + e10.set_at(100, json::null()); + ASSERT_TRUE(e10.is_array(), "e10 is not an array after index assignment"); + ASSERT_EQ(e10.size(), 2, "e10 has incorrect number of elements after assignment"); - e10.insert_at(1, json::Value("new")); - ASSERT_EQ(e10.size(), 3, "e10 has incorrect size after insert"); - ASSERT_EQ(e10[1].as_string(), "new", "e10[1] has incorrect value after insert"); - ASSERT_EQ(e10[2].as_string(), "foobar", "e10[2] has incorrect value after insert"); + e10.insert_at(1, json::Value("new")); + ASSERT_EQ(e10.size(), 3, "e10 has incorrect size after insert"); + ASSERT_EQ(e10[1].as_string(), "new", "e10[1] has incorrect value after insert"); + ASSERT_EQ(e10[2].as_string(), "foobar", "e10[2] has incorrect value after insert"); - e10.del_at(0); - ASSERT_EQ(e10.size(), 2, "e10 has incorrect size after delete"); - ASSERT_EQ(e10[1].as_string(), "foobar", "e10[1] has incorrect value after delete"); + e10.del_at(0); + ASSERT_EQ(e10.size(), 2, "e10 has incorrect size after delete"); + ASSERT_EQ(e10[1].as_string(), "foobar", "e10[1] has incorrect value after delete"); - e10.clear(); - ASSERT_EQ(e10.size(), 0, "e10 has incorrect number of elements after clear"); + e10.clear(); + ASSERT_EQ(e10.size(), 0, "e10 has incorrect number of elements after clear"); - json::Value e11(json::object()); - ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); + json::Value e11(json::object()); + ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); - e11.set_key("foo", json::Value("test")); - ASSERT_EQ(e11.size(), 1, "e11 has incorrect number of properties after assignment"); - ASSERT_EQ(e11["foo"].as_string(), "test", "e11.foo has incorrect value after assignment"); + e11.set_key("foo", json::Value("test")); + ASSERT_EQ(e11.size(), 1, "e11 has incorrect number of properties after assignment"); + ASSERT_EQ(e11["foo"].as_string(), "test", "e11.foo has incorrect value after assignment"); - e11.set_key("foo", json::Value("again")); - ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); - ASSERT_EQ(e11.size(), 1, "e11 has incorrect number of properties after assignment"); - ASSERT_EQ(e11["foo"].as_string(), "again", "e11.foo has incorrect value after assignment"); + e11.set_key("foo", json::Value("again")); + ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); + ASSERT_EQ(e11.size(), 1, "e11 has incorrect number of properties after assignment"); + ASSERT_EQ(e11["foo"].as_string(), "again", "e11.foo has incorrect value after assignment"); - e11.set_key("bar", json::Value("test")); - ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); - ASSERT_EQ(e11.size(), 2, "e11 has incorrect number of properties after assignment"); - ASSERT_EQ(e11["bar"].as_string(), "test", "e11.foo has incorrect value after assignment"); + e11.set_key("bar", json::Value("test")); + ASSERT_TRUE(e11.is_object(), "e11 is not an object after property assignment"); + ASSERT_EQ(e11.size(), 2, "e11 has incorrect number of properties after assignment"); + ASSERT_EQ(e11["bar"].as_string(), "test", "e11.foo has incorrect value after assignment"); - e11.clear(); - ASSERT_EQ(e11.size(), 0, "e11 has incorrect number of properties after clear"); + e11.clear(); + ASSERT_EQ(e11.size(), 0, "e11 has incorrect number of properties after clear"); - json::Value e12(json::object()); - e12.set_key("foo", json::Value("test")); - e12.set_key("bar", json::Value(3)); - char* out_cstr = e12.save_string(0); - std::string out(out_cstr); - free(out_cstr); - ASSERT_EQ(out, "{\"bar\": 3, \"foo\": \"test\"}", "object did not serialize as expected"); + json::Value e12(json::object()); + e12.set_key("foo", json::Value("test")); + e12.set_key("bar", json::Value(3)); + char* out_cstr = e12.save_string(0); + std::string out(out_cstr); + free(out_cstr); + ASSERT_EQ(out, "{\"bar\": 3, \"foo\": \"test\"}", "object did not serialize as expected"); - std::istringstream instr(out); - instr >> e12; - ASSERT_TRUE(e12.is_object(), "e12 is not an object after stream read"); - ASSERT_EQ(e12.size(), 2, "e12 has wrong size after stream read"); - ASSERT_EQ(e12.get("bar").as_integer(), 3, "e12.bar has incorrect value after stream read"); - ASSERT_EQ(e12.get("foo").as_string(), "test", "ee12.test has incorrect value after stream read"); + std::istringstream instr(out); + instr >> e12; + ASSERT_TRUE(e12.is_object(), "e12 is not an object after stream read"); + ASSERT_EQ(e12.size(), 2, "e12 has wrong size after stream read"); + ASSERT_EQ(e12.get("bar").as_integer(), 3, "e12.bar has incorrect value after stream read"); + ASSERT_EQ(e12.get("foo").as_string(), "test", "ee12.test has incorrect value after stream read"); - std::ostringstream outstr; - outstr << e12; - ASSERT_EQ(instr.str(), "{\"bar\": 3, \"foo\": \"test\"}", "object did not serialize as expected"); + std::ostringstream outstr; + outstr << e12; + ASSERT_EQ(instr.str(), "{\"bar\": 3, \"foo\": \"test\"}", "object did not serialize as expected"); - const json::Value e13(e12); - ASSERT_EQ(e13["bar"].as_integer(), 3, "e13.bar has incorrect value after copy"); + const json::Value e13(e12); + ASSERT_EQ(e13["bar"].as_integer(), 3, "e13.bar has incorrect value after copy"); - json::Value e14(json::object()); - ASSERT_TRUE(e14.is_object(), "e14 is not an object after construction"); - e14.set_key("foo", json::object()); - ASSERT_TRUE(e14["foo"].is_object(), "e14.foo is not an object after assignment"); - e14["foo"]["bar"] = json::Value(42); - ASSERT_EQ(e14["foo"]["bar"].as_integer(), 42, "e14.foo.bar has incorrect value after assignment"); + json::Value e14(json::object()); + ASSERT_TRUE(e14.is_object(), "e14 is not an object after construction"); + e14.set_key("foo", json::object()); + ASSERT_TRUE(e14["foo"].is_object(), "e14.foo is not an object after assignment"); + e14["foo"]["bar"] = json::Value(42); + ASSERT_EQ(e14["foo"]["bar"].as_integer(), 42, "e14.foo.bar has incorrect value after assignment"); - json::Value e15(json::array()); - ASSERT_TRUE(e15.is_array(), "e15 is not an array after construction"); - e15.set_at(0, json::Value(42)); - ASSERT_EQ(e15[0].as_integer(), 42, "e15[0] has incorrect value after assignment"); - e15[0] = json::Value("foo"); - ASSERT_EQ(e15[0].as_string(), "foo", "e15[0] has incorrecy value after assignment"); - return 0; + json::Value e15(json::array()); + ASSERT_TRUE(e15.is_array(), "e15 is not an array after construction"); + e15.set_at(0, json::Value(42)); + ASSERT_EQ(e15[0].as_integer(), 42, "e15[0] has incorrect value after assignment"); + e15[0] = json::Value("foo"); + ASSERT_EQ(e15[0].as_string(), "foo", "e15[0] has incorrecy value after assignment"); + return 0; } From b07e69c37aa7cc1dd27aff9f3ba5cef703f2e357 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Tue, 2 Feb 2010 21:01:50 +0200 Subject: [PATCH 2/9] C++: Rename namespace json::_private to json::detail --- src/jansson-impl.hpp | 6 +++--- src/jansson.hpp | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/jansson-impl.hpp b/src/jansson-impl.hpp index de336dd..eb68fcd 100644 --- a/src/jansson-impl.hpp +++ b/src/jansson-impl.hpp @@ -8,7 +8,7 @@ #endif namespace json { - namespace _private { + namespace detail { // assignment operator template ValueBase<_Base>& ValueBase<_Base>::operator=(const Value& value) { @@ -325,7 +325,7 @@ namespace json { return json_object_get(_object, _key); } - } // namespace json::_private + } // namespace json::detail // construct Value::Value input Value::Value(const char* value) { @@ -378,7 +378,7 @@ namespace json { } // construct a new iterator for a given object - Iterator::Iterator(const _private::ValueBase<_private::PropertyProxy>& value) : + Iterator::Iterator(const detail::ValueBase& value) : _object(value.as_json()), _iter(0) { _iter = json_object_iter(_object.as_json()); } diff --git a/src/jansson.hpp b/src/jansson.hpp index 020a277..41afd67 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -20,7 +20,7 @@ namespace json { class Value; // implementation details; do not use directly - namespace _private { + namespace detail { class ElementProxy; class PropertyProxy; @@ -196,10 +196,10 @@ namespace json { const char* _key; }; - } // namespace json::_private + } // namespace json::detail // represents any JSON value - class Value : public _private::ValueBase<_private::Basic> { + class Value : public detail::ValueBase { public: // construct Value from input explicit inline Value(const char* value); @@ -215,19 +215,19 @@ namespace json { explicit inline Value(double value); // empty constructor - Value() : _private::ValueBase<_private::Basic>() {} + Value() : detail::ValueBase() {} // copy constructor for base - Value(const _private::Basic& value) : _private::ValueBase<_private::Basic>(value) {} + Value(const detail::Basic& value) : detail::ValueBase(value) {} // copy constructor for base - Value(const _private::ValueBase<_private::Basic>& value) : _private::ValueBase<_private::Basic>(value) {} + Value(const detail::ValueBase& value) : detail::ValueBase(value) {} // copy constructor - Value(const Value& value) : _private::ValueBase<_private::Basic>(value) {} + Value(const Value& value) : detail::ValueBase(value) {} // create reference to value - explicit Value(json_t* json) : _private::ValueBase<_private::Basic>(json) {} + explicit Value(json_t* json) : detail::ValueBase(json) {} }; // iterators over a JSON object @@ -237,7 +237,7 @@ namespace json { inline Iterator(const Value& value); // construct a new iterator for a given object - inline Iterator(const _private::ValueBase<_private::PropertyProxy>& value); + inline Iterator(const detail::ValueBase& value); // increment iterator inline void next(); From d1a0c3ffc2c7d383c801e679c7aa0719a2f25794 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Tue, 2 Feb 2010 21:10:57 +0200 Subject: [PATCH 3/9] C++: Rename jansson-impl.hpp to jansson.ipp The .ipp suffix is for inlined template implementation code. While at it, use #ifdef and #ifndef instead of #if defined(). --- src/Makefile.am | 2 +- src/jansson.hpp | 8 ++++---- src/{jansson-impl.hpp => jansson.ipp} | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/{jansson-impl.hpp => jansson.ipp} (99%) diff --git a/src/Makefile.am b/src/Makefile.am index 460b26a..92fc90c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -include_HEADERS = jansson.h jansson.hpp jansson-impl.hpp +include_HEADERS = jansson.h jansson.hpp jansson.ipp lib_LTLIBRARIES = libjansson.la libjansson_la_SOURCES = \ diff --git a/src/jansson.hpp b/src/jansson.hpp index 41afd67..265b2b9 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -3,8 +3,8 @@ // Jansson is free software; you can redistribute it and/or modify // it under the terms of the MIT license. See LICENSE for details. -#if !defined(JANSSON_HPP) -#define JANSSON_HPP 1 +#ifndef JANSSON_HPP +#define JANSSON_HPP #include #include @@ -296,8 +296,8 @@ inline std::ostream& operator<<(std::ostream& os, const json::Value& value); inline std::istream& operator>>(std::istream& is, json::Value& value); // include implementation code -#define IN_JANSSON_HPP 1 -#include "jansson-impl.hpp" +#define IN_JANSSON_HPP +#include "jansson.ipp" #undef IN_JANSSON_HPP #endif // defined(JANSSON_HPP) diff --git a/src/jansson-impl.hpp b/src/jansson.ipp similarity index 99% rename from src/jansson-impl.hpp rename to src/jansson.ipp index eb68fcd..a845e84 100644 --- a/src/jansson-impl.hpp +++ b/src/jansson.ipp @@ -3,8 +3,8 @@ // Jansson is free software; you can redistribute it and/or modify // it under the terms of the MIT license. See LICENSE for details. -#if !defined(IN_JANSSON_HPP) -#error "jansson-impl.hpp may only by included from jansson.hpp" +#ifndef IN_JANSSON_HPP +#error "jansson.ipp may only be included from jansson.hpp" #endif namespace json { From c9fc055351b67256042c73a6a0a915c5b3b40c63 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Tue, 2 Feb 2010 21:14:31 +0200 Subject: [PATCH 4/9] Add myself as another copyright holder for jansson.hpp and jansson.ipp --- src/jansson.hpp | 1 + src/jansson.ipp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/jansson.hpp b/src/jansson.hpp index 265b2b9..51c1763 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2010 Sean Middleditch +// Copyright (c) 2010 Petri Lehtinen // // Jansson is free software; you can redistribute it and/or modify // it under the terms of the MIT license. See LICENSE for details. diff --git a/src/jansson.ipp b/src/jansson.ipp index a845e84..b80d1af 100644 --- a/src/jansson.ipp +++ b/src/jansson.ipp @@ -1,4 +1,5 @@ // Copyright (c) 2010 Sean Middleditch +// Copyright (c) 2010 Petri Lehtinen // // Jansson is free software; you can redistribute it and/or modify // it under the terms of the MIT license. See LICENSE for details. From 910a2f318bdf7d61d982ab76d2518d58d16b0365 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Thu, 4 Feb 2010 20:49:01 +0200 Subject: [PATCH 5/9] C++: Rename test.json to test_cpp.json --- test/suites/api/test_cpp.cpp | 3 +-- test/suites/api/{test.json => test_cpp.json} | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) rename test/suites/api/{test.json => test_cpp.json} (99%) diff --git a/test/suites/api/test_cpp.cpp b/test/suites/api/test_cpp.cpp index 5d3964a..8a3b356 100644 --- a/test/suites/api/test_cpp.cpp +++ b/test/suites/api/test_cpp.cpp @@ -1,6 +1,5 @@ #include #include -#include #include "jansson.hpp" @@ -23,7 +22,7 @@ #define ASSERT_FALSE(p, m) ASSERT_OP(p, true, !=, m) int main() { - json::Value e1(json::load_file("suites/api/test.json")); + json::Value e1(json::load_file("suites/api/test_cpp.json")); json::Value e2(e1); json::Value e3; json::Value e4(json::load_string("{\"foo\": true, \"bar\": \"test\"}")); diff --git a/test/suites/api/test.json b/test/suites/api/test_cpp.json similarity index 99% rename from test/suites/api/test.json rename to test/suites/api/test_cpp.json index 9eea6ad..d31a395 100644 --- a/test/suites/api/test.json +++ b/test/suites/api/test_cpp.json @@ -1,5 +1,5 @@ {"web-app": { - "servlet": [ + "servlet": [ { "servlet-name": "cofaxCDS", "servlet-class": "org.cofax.cds.CDSServlet", @@ -55,7 +55,7 @@ { "servlet-name": "cofaxAdmin", "servlet-class": "org.cofax.cds.AdminServlet"}, - + { "servlet-name": "fileServlet", "servlet-class": "org.cofax.cds.FileServlet"}, @@ -82,7 +82,7 @@ "cofaxAdmin": "/admin/*", "fileServlet": "/static/*", "cofaxTools": "/tools/*"}, - + "taglib": { "taglib-uri": "cofax.tld", "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} From 49d40f020b471f693fdd179729faa8be916f7114 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Thu, 4 Feb 2010 20:50:01 +0200 Subject: [PATCH 6/9] C++: #include in jansson.hpp This is to avoid standard C functions ending up in namespace json, as jansson.h is #included in there, and jansson.h in turn #includes stdio.h. --- src/jansson.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jansson.hpp b/src/jansson.hpp index 51c1763..f435493 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -11,6 +11,11 @@ #include #include #include + +// Included so that standard functions don't end up in namespace json +#include + +// For free() #include namespace json { From b8059a18801ae067d13f1e5d9e872e4cf11bc58f Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Thu, 4 Feb 2010 21:02:35 +0200 Subject: [PATCH 7/9] C++: Rename some functions to better match the C API Value::save_file -> Value::dump_file Value::save_string -> Value::dumps load_string -> loads --- src/jansson.hpp | 6 +++--- src/jansson.ipp | 10 +++++----- test/suites/api/test_cpp.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/jansson.hpp b/src/jansson.hpp index f435493..de55b75 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -127,10 +127,10 @@ namespace json { inline _Base& insert_at(unsigned int index, const Value& value); // write the value to a file - inline int save_file(const char* path, int flags = 0) const; + inline int dump_file(const char* path, int flags = 0) const; // write the value to a string (caller must deallocate with free()!) - inline char* save_string(int flags = 0) const; + inline char* dumps(int flags = 0) const; }; // represents any JSON value, private base @@ -291,7 +291,7 @@ namespace json { inline Value load_file(const char* path, json_error_t* error = 0); // load a string as a JSON value - inline Value load_string(const char* string, json_error_t* error = 0); + inline Value loads(const char* string, json_error_t* error = 0); } // namespace json diff --git a/src/jansson.ipp b/src/jansson.ipp index b80d1af..fcb4a0c 100644 --- a/src/jansson.ipp +++ b/src/jansson.ipp @@ -270,13 +270,13 @@ namespace json { // write the value to a file template - int ValueBase<_Base>::save_file(const char* path, int flags) const { + int ValueBase<_Base>::dump_file(const char* path, int flags) const { return json_dump_file(_Base::as_json(), path, flags); } // write the value to a string (caller must deallocate with free()!) template - char* ValueBase<_Base>::save_string(int flags) const { + char* ValueBase<_Base>::dumps(int flags) const { return json_dumps(_Base::as_json(), flags); } @@ -440,7 +440,7 @@ namespace json { } // load a string as a JSON value - Value load_string(const char* string, json_error_t* error) { + Value loads(const char* string, json_error_t* error) { return Value::take_ownership(json_loads(string, error)); } @@ -449,7 +449,7 @@ namespace json { // stream JSON value out std::ostream& operator<<(std::ostream& os, const json::Value& value) { // get the temporary serialize string - char* tmp = value.save_string(); + char* tmp = value.dumps(); if (tmp != 0) { // stream temp string out and release it os << tmp; @@ -465,6 +465,6 @@ std::istream& operator>>(std::istream& is, json::Value& value) { while (is) tmp << static_cast(is.get()); // parse the buffered string - value = json::load_string(tmp.str().c_str()); + value = json::loads(tmp.str().c_str()); return is; } diff --git a/test/suites/api/test_cpp.cpp b/test/suites/api/test_cpp.cpp index 8a3b356..b8626ea 100644 --- a/test/suites/api/test_cpp.cpp +++ b/test/suites/api/test_cpp.cpp @@ -25,7 +25,7 @@ int main() { json::Value e1(json::load_file("suites/api/test_cpp.json")); json::Value e2(e1); json::Value e3; - json::Value e4(json::load_string("{\"foo\": true, \"bar\": \"test\"}")); + json::Value e4(json::loads("{\"foo\": true, \"bar\": \"test\"}")); ASSERT_TRUE(e1.is_object(), "e1 is not an object"); ASSERT_TRUE(e2.is_object(), "e2 is not an object"); @@ -125,7 +125,7 @@ int main() { json::Value e12(json::object()); e12.set_key("foo", json::Value("test")); e12.set_key("bar", json::Value(3)); - char* out_cstr = e12.save_string(0); + char* out_cstr = e12.dumps(0); std::string out(out_cstr); free(out_cstr); ASSERT_EQ(out, "{\"bar\": 3, \"foo\": \"test\"}", "object did not serialize as expected"); From adb1b586274b920a78ca9dc4d728a9086510c2dd Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Thu, 4 Feb 2010 21:07:02 +0200 Subject: [PATCH 8/9] C++: Add Value::dump_file(), load_file() and loads() that take an std::string --- src/jansson.hpp | 3 +++ src/jansson.ipp | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/jansson.hpp b/src/jansson.hpp index de55b75..bf723bd 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -128,6 +128,7 @@ namespace json { // write the value to a file inline int dump_file(const char* path, int flags = 0) const; + inline int dump_file(const std::string& path, int flags = 0) const; // write the value to a string (caller must deallocate with free()!) inline char* dumps(int flags = 0) const; @@ -289,9 +290,11 @@ namespace json { // load a file as a JSON value inline Value load_file(const char* path, json_error_t* error = 0); + inline Value load_file(const std::string& path, json_error_t* error = 0); // load a string as a JSON value inline Value loads(const char* string, json_error_t* error = 0); + inline Value loads(const std::string& string, json_error_t* error = 0); } // namespace json diff --git a/src/jansson.ipp b/src/jansson.ipp index fcb4a0c..5938f0f 100644 --- a/src/jansson.ipp +++ b/src/jansson.ipp @@ -274,6 +274,11 @@ namespace json { return json_dump_file(_Base::as_json(), path, flags); } + template + int ValueBase<_Base>::dump_file(const std::string& path, int flags) const { + return dump_file(path.c_str(), flags); + } + // write the value to a string (caller must deallocate with free()!) template char* ValueBase<_Base>::dumps(int flags) const { @@ -439,11 +444,19 @@ namespace json { return Value::take_ownership(json_load_file(path, error)); } + Value load_file(const std::string& path, json_error_t* error) { + return load_file(path.c_str(), error); + } + // load a string as a JSON value Value loads(const char* string, json_error_t* error) { return Value::take_ownership(json_loads(string, error)); } + Value loads(const std::string& string, json_error_t* error) { + return loads(string.c_str(), error); + } + } // namespace json // stream JSON value out From f021ba00a2f06a08ac767a94f6fdebb01d3f74b4 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Thu, 4 Feb 2010 21:10:04 +0200 Subject: [PATCH 9/9] C++: Fix test_cpp.cpp to work with VPATH builds It reads an input file, and the file location is different with VPATH builds. Read top_srcdir from environment and use it to find the file. --- test/suites/api/test_cpp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/suites/api/test_cpp.cpp b/test/suites/api/test_cpp.cpp index b8626ea..1215e4e 100644 --- a/test/suites/api/test_cpp.cpp +++ b/test/suites/api/test_cpp.cpp @@ -22,7 +22,8 @@ #define ASSERT_FALSE(p, m) ASSERT_OP(p, true, !=, m) int main() { - json::Value e1(json::load_file("suites/api/test_cpp.json")); + std::string top_srcdir = getenv("top_srcdir"); + json::Value e1(json::load_file(top_srcdir + "/test/suites/api/test_cpp.json")); json::Value e2(e1); json::Value e3; json::Value e4(json::loads("{\"foo\": true, \"bar\": \"test\"}"));