diff --git a/janssonxx.h b/janssonxx.h index 193a354..2193ff1 100644 --- a/janssonxx.h +++ b/janssonxx.h @@ -22,6 +22,7 @@ namespace jansson { class Iterator; class Value; class _ArrayProxy; + class _ObjectProxy; // base class for JSON value interface template @@ -75,13 +76,20 @@ namespace jansson { inline _ValueBase<_ArrayProxy> operator[](signed long index); inline _ValueBase<_ArrayProxy> operator[](unsigned long index); - // get object property + // 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; + // get object property (non-const version) + inline _ValueBase<_ObjectProxy> get(const char* key); + + inline _ValueBase<_ObjectProxy> get(const std::string& key); + inline _ValueBase<_ObjectProxy> operator[](const char* key); + inline _ValueBase<_ObjectProxy> operator[](const std::string& key); + // clear all array/object values inline void clear(); @@ -156,9 +164,6 @@ namespace jansson { // 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) {} @@ -176,6 +181,26 @@ namespace jansson { unsigned int _index; }; + // proxies an object property + class _ObjectProxy { + public: + // constructor + _ObjectProxy(json_t* array, const char* key) : _object(array), _key(key) {} + + // assign to the proxied element + inline _ObjectProxy& operator=(const Value& value); + + // get the proxied element + json_t* as_json() const { return json_object_get(_object, _key); } + + private: + // array object we wrap + json_t* _object; + + // key of property + const char* _key; + }; + // represents any JSON value class Value : public _ValueBase<_Value> { public: @@ -245,6 +270,11 @@ namespace jansson { _iter = json_object_iter(_object.as_json()); } + // construct a new iterator for a given object + Iterator(const _ValueBase<_ObjectProxy>& value) : _object(value.as_json()), _iter(0) { + _iter = json_object_iter(_object.as_json()); + } + // increment iterator void next() { _iter = json_object_iter_next(_object.as_json(), _iter); diff --git a/janssonxx.tcc b/janssonxx.tcc index c4b1efa..27ed239 100644 --- a/janssonxx.tcc +++ b/janssonxx.tcc @@ -45,7 +45,7 @@ jansson::_ValueBase jansson::_ValueBase<_Base>::operator[] template jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](unsigned long index) { return at(index); } -// get object property +// get object property (const version) template const jansson::Value jansson::_ValueBase<_Base>::get(const char* key) const { return jansson::Value(json_object_get(_Base::as_json(), key)); @@ -58,6 +58,19 @@ const jansson::Value jansson::_ValueBase<_Base>::operator[](const char* key) con template const jansson::Value jansson::_ValueBase<_Base>::operator[](const std::string& key) const { return get(key.c_str()); } +// get object property (non-const version) +template +jansson::_ValueBase jansson::_ValueBase<_Base>::get(const char* key) { + return _ObjectProxy(_Base::as_json(), key); +} + +template +jansson::_ValueBase jansson::_ValueBase<_Base>::get(const std::string& key) { return get(key.c_str()); } +template +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](const char* key) { return get(key); } +template +jansson::_ValueBase jansson::_ValueBase<_Base>::operator[](const std::string& key) { return get(key.c_str()); } + // clear all array/object values template void jansson::_ValueBase<_Base>::clear() { @@ -137,3 +150,9 @@ jansson::_ArrayProxy& jansson::_ArrayProxy::operator=(const Value& value) { json_array_set(_array, _index, value.as_json()); return *this; } + +// assign value to proxied object property +jansson::_ObjectProxy& jansson::_ObjectProxy::operator=(const Value& value) { + json_object_set(_object, _key, value.as_json()); + return *this; +} diff --git a/test.cc b/test.cc index bff3cef..092679d 100644 --- a/test.cc +++ b/test.cc @@ -148,8 +148,8 @@ int main() { ASSERT_TRUE(e14.is_object(), "e14 is not an object after construction"); 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 incorrect value after assignment"); + e14["foo"]["bar"] = jansson::Value::from(42); + 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");