diff --git a/doc/apiref.rst b/doc/apiref.rst index 3c4fa47..5d8d41b 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -708,6 +708,24 @@ allowed in object keys. .. versionadded:: 2.3 +.. function:: int json_object_update_new(json_t *object, json_t *other) + + Like :func:`json_object_update()`, but steals the reference to + *other*. This is useful when *other* is newly created and not used + after the call. + +.. function:: int json_object_update_existing_new(json_t *object, json_t *other) + + Like :func:`json_object_update_new()`, but only the values of existing + keys are updated. No new keys are created. Returns 0 on success or + -1 on error. + +.. function:: int json_object_update_missing_new(json_t *object, json_t *other) + + Like :func:`json_object_update_new()`, but only new keys are created. + The value of any existing key is not changed. Returns 0 on success + or -1 on error. + .. function:: json_object_foreach(object, key, value) Iterate over every key-value pair of ``object``, running the block diff --git a/src/jansson.h b/src/jansson.h index b2b980b..1aa3c2c 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -242,6 +242,30 @@ int json_object_iter_set(json_t *object, void *iter, json_t *value) return json_object_iter_set_new(object, iter, json_incref(value)); } +static JSON_INLINE +int json_object_update_new(json_t *object, json_t *other) +{ + int ret = json_object_update(object, other); + json_decref(other); + return ret; +} + +static JSON_INLINE +int json_object_update_existing_new(json_t *object, json_t *other) +{ + int ret = json_object_update_existing(object, other); + json_decref(other); + return ret; +} + +static JSON_INLINE +int json_object_update_missing_new(json_t *object, json_t *other) +{ + int ret = json_object_update_missing(object, other); + json_decref(other); + return ret; +} + size_t json_array_size(const json_t *array); json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS(warn_unused_result); int json_array_set_new(json_t *array, size_t index, json_t *value); diff --git a/test/suites/api/test_object.c b/test/suites/api/test_object.c index 521ca81..0d320b3 100644 --- a/test/suites/api/test_object.c +++ b/test/suites/api/test_object.c @@ -133,6 +133,32 @@ static void test_update() json_object_get(object, "h") != nine) fail("update works incorrectly"); + /* update_new check */ + if(json_object_clear(object)) + fail("clear failed"); + + if(json_object_set(object, "a", ten) || + json_object_set(object, "b", ten) || + json_object_set(object, "c", ten) || + json_object_set(object, "d", ten) || + json_object_set(object, "e", ten)) + fail("unable to set value"); + + if(json_object_update_new(object, json_pack("{s:O, s:O, s:O}", "b", nine, "f", nine, "g", nine))) + fail("unable to update_new a nonempty object"); + + if(json_object_size(object) != 7) + fail("invalid size after update_new"); + + if(json_object_get(object, "a") != ten || + json_object_get(object, "b") != nine || + json_object_get(object, "c") != ten || + json_object_get(object, "d") != ten || + json_object_get(object, "e") != ten || + json_object_get(object, "f") != nine || + json_object_get(object, "g") != nine) + fail("update_new works incorrectly"); + json_decref(nine); json_decref(ten); json_decref(other); @@ -186,6 +212,23 @@ static void test_conditional_updates() json_decref(object); + /* json_object_update_existing_new check */ + object = json_pack("{sisi}", "foo", 1, "bar", 2); + + if(json_object_update_existing_new(object, json_pack("{sisi}", "foo", 3, "baz", 4))) + fail("json_object_update_existing_new failed"); + + if(json_object_size(object) != 2) + fail("json_object_update_existing_new added new items"); + + if(json_integer_value(json_object_get(object, "foo")) != 3) + fail("json_object_update_existing_new failed to update existing key"); + + if(json_integer_value(json_object_get(object, "bar")) != 2) + fail("json_object_update_existing_new updated wrong key"); + + json_decref(object); + object = json_pack("{sisi}", "foo", 1, "bar", 2); if(json_object_update_missing(object, other)) @@ -203,6 +246,26 @@ static void test_conditional_updates() if(json_integer_value(json_object_get(object, "baz")) != 4) fail("json_object_update_missing didn't add new items"); + json_decref(object); + + /* json_object_update_missing_new check */ + object = json_pack("{sisi}", "foo", 1, "bar", 2); + + if(json_object_update_missing_new(object, json_pack("{sisi}", "foo", 3, "baz", 4))) + fail("json_object_update_missing_new failed"); + + if(json_object_size(object) != 3) + fail("json_object_update_missing_new didn't add new items"); + + if(json_integer_value(json_object_get(object, "foo")) != 1) + fail("json_object_update_missing_new updated existing key"); + + if(json_integer_value(json_object_get(object, "bar")) != 2) + fail("json_object_update_missing_new updated wrong key"); + + if(json_integer_value(json_object_get(object, "baz")) != 4) + fail("json_object_update_missing_new didn't add new items"); + json_decref(object); json_decref(other); }