From 1bc0225441d17011de0681004265e9edec1a8eab Mon Sep 17 00:00:00 2001 From: Sean Middleditch Date: Sat, 16 Jan 2010 01:24:27 -0800 Subject: [PATCH] add array element proxy support --- janssonxx.h | 41 ++++++++++++++++++++++++++++++++++------- janssonxx.tcc | 22 ++++++++++++++-------- test.cc | 8 +++++++- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/janssonxx.h b/janssonxx.h index 935ac9e..193a354 100644 --- a/janssonxx.h +++ b/janssonxx.h @@ -21,6 +21,7 @@ namespace jansson { class Iterator; class Value; + class _ArrayProxy; // base class for JSON value interface template @@ -35,6 +36,9 @@ namespace jansson { // create reference to value _ValueBase(json_t* json) : _Base(json) {} + // assignment operator + _ValueBase& operator=(const Value& value) { _Base::operator=(value); return *this; } + // check value type bool is_undefined() const { return _Base::as_json() == 0; } bool is_object() const { return json_is_object(_Base::as_json()); } @@ -62,14 +66,14 @@ namespace jansson { inline const Value operator[](unsigned long index) const; // get value at array index (non-const version) - inline Value at(unsigned int index); + inline _ValueBase<_ArrayProxy> at(unsigned int index); - inline Value operator[](signed int index); - inline Value operator[](unsigned int index); - inline Value operator[](signed short index); - inline Value operator[](unsigned short index); - inline Value operator[](signed long index); - inline Value operator[](unsigned long index); + inline _ValueBase<_ArrayProxy> operator[](signed int index); + inline _ValueBase<_ArrayProxy> operator[](unsigned int index); + inline _ValueBase<_ArrayProxy> operator[](signed short index); + inline _ValueBase<_ArrayProxy> operator[](unsigned short index); + inline _ValueBase<_ArrayProxy> operator[](signed long index); + inline _ValueBase<_ArrayProxy> operator[](unsigned long index); // get object property inline const Value get(const char* key) const; @@ -149,6 +153,29 @@ namespace jansson { json_t* _value; }; + // proxies an array element + class _ArrayProxy { + public: + // construct new Value with an undefined value + _ArrayProxy() : _array(0), _index(0) {} + + // constructor + _ArrayProxy(json_t* array, unsigned int index) : _array(array), _index(index) {} + + // assign to the proxied element + inline _ArrayProxy& operator=(const Value& value); + + // get the proxied element + json_t* as_json() const { return json_array_get(_array, _index); } + + private: + // array object we wrap + json_t* _array; + + // index of property + unsigned int _index; + }; + // represents any JSON value class Value : public _ValueBase<_Value> { public: diff --git a/janssonxx.tcc b/janssonxx.tcc index 2b5c8aa..c4b1efa 100644 --- a/janssonxx.tcc +++ b/janssonxx.tcc @@ -28,22 +28,22 @@ const jansson::Value jansson::_ValueBase<_Base>::operator[](unsigned long index) // get value at array index (non-const version) template -jansson::Value jansson::_ValueBase<_Base>::at(unsigned int index) { - return jansson::Value(json_array_get(_Base::as_json(), index)); +jansson::_ValueBase jansson::_ValueBase<_Base>::at(unsigned int index) { + return _ArrayProxy(_Base::as_json(), index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](signed int index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](signed int index) { return at(index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](unsigned int index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](unsigned int index) { return at(index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](signed short index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](signed short index) { return at(index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](unsigned short index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](unsigned short index) { return at(index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](signed long index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](signed long index) { return at(index); } template -jansson::Value jansson::_ValueBase<_Base>::operator[](unsigned long index) { return at(index); } +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](unsigned long index) { return at(index); } // get object property template @@ -131,3 +131,9 @@ template json_array_insert(_Base::as_json(), index, value._Base::as_json()); return *this; } + +// assign value to proxied array element +jansson::_ArrayProxy& jansson::_ArrayProxy::operator=(const Value& value) { + json_array_set(_array, _index, value.as_json()); + return *this; +} diff --git a/test.cc b/test.cc index fb66f63..bff3cef 100644 --- a/test.cc +++ b/test.cc @@ -149,7 +149,13 @@ int main() { e14.set_key("foo", jansson::Value::object()); ASSERT_TRUE(e14["foo"].is_object(), "e14.foo is not an object after assignment"); //e14["foo"]["bar"] = jansson::Value::from(42); - //ASSERT_EQ(e14["foo"]["bar"].as_integer(), 42, "e14.foo.bar has incorrecy value after assignment"); + //ASSERT_EQ(e14["foo"]["bar"].as_integer(), 42, "e14.foo.bar has incorrect value after assignment"); + jansson::Value e15(jansson::Value::array()); + ASSERT_TRUE(e15.is_array(), "e15 is not an array after construction"); + e15.set_at(0, jansson::Value::from(42)); + ASSERT_EQ(e15[0].as_integer(), 42, "e15[0] has incorrect value after assignment"); + e15[0] = jansson::Value::from("foo"); + ASSERT_EQ(e15[0].as_string(), "foo", "e15[0] has incorrecy value after assignment"); return 0; }