aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/apiref.rst24
-rw-r--r--src/jansson.h25
-rw-r--r--src/value.c47
-rw-r--r--test/testprogs/test_array.c10
-rw-r--r--test/testprogs/test_object.c8
5 files changed, 101 insertions, 13 deletions
diff --git a/doc/apiref.rst b/doc/apiref.rst
index 903b48c..c70c0bc 100644
--- a/doc/apiref.rst
+++ b/doc/apiref.rst
@@ -259,11 +259,27 @@ A JSON array is an ordered collection of other JSON values.
range for *index* is from 0 to the return value of
:cfunc:`json_array_size()` minus 1.
+.. cfunction:: int json_array_set_new(json_t *array, unsigned int index, json_t *value)
+
+ Like :cfunc:`json_array_set()` but steals the reference to *value*.
+ This is useful when *value* is newly created and not used after
+ the call.
+
+ .. versionadded:: 1.1
+
.. cfunction:: int json_array_append(json_t *array, json_t *value)
Appends *value* to the end of *array*, growing the size of *array*
by 1. Returns 0 on success and -1 on error.
+.. cfunction:: int json_array_append_new(json_t *array, json_t *value)
+
+ Like :cfunc:`json_array_append()` but steals the reference to
+ *value*. This is useful when *value* is newly created and not used
+ after the call.
+
+ .. versionadded:: 1.1
+
Object
======
@@ -292,6 +308,14 @@ Unicode string and the value is any JSON value.
a value for *key*, it is replaced by the new value. Returns 0 on
success and -1 on error.
+.. cfunction:: int json_object_set_new(json_t *object, const char *key, json_t *value)
+
+ Like :cfunc:`json_object_set()` but steals the reference to
+ *value*. This is useful when *value* is newly created and not used
+ after the call.
+
+ .. versionadded:: 1.1
+
.. cfunction:: int json_object_del(json_t *object, const char *key)
Delete *key* from *object* if it exists. Returns 0 on success, or
diff --git a/src/jansson.h b/src/jansson.h
index 6efc6db..09af7bf 100644
--- a/src/jansson.h
+++ b/src/jansson.h
@@ -72,17 +72,36 @@ static inline void json_decref(json_t *json)
/* getters, setters, manipulation */
json_t *json_object_get(const json_t *object, const char *key);
-int json_object_set(json_t *object, const char *key, json_t *value);
+int json_object_set_new(json_t *object, const char *key, json_t *value);
int json_object_del(json_t *object, const char *key);
void *json_object_iter(json_t *object);
void *json_object_iter_next(json_t *object, void *iter);
const char *json_object_iter_key(void *iter);
json_t *json_object_iter_value(void *iter);
+static inline
+int json_object_set(json_t *object, const char *key, json_t *value)
+{
+ return json_object_set_new(object, key, json_incref(value));
+}
+
unsigned int json_array_size(const json_t *array);
json_t *json_array_get(const json_t *array, unsigned int index);
-int json_array_set(json_t *array, unsigned int index, json_t *value);
-int json_array_append(json_t *array, json_t *value);
+int json_array_set_new(json_t *array, unsigned int index, json_t *value);
+int json_array_append_new(json_t *array, json_t *value);
+
+static inline
+int json_array_set(json_t *array, unsigned int index, json_t *value)
+{
+ return json_array_set_new(array, index, json_incref(value));
+}
+
+static inline
+int json_array_append(json_t *array, json_t *value)
+{
+ return json_array_append_new(array, json_incref(value));
+}
+
const char *json_string_value(const json_t *json);
int json_integer_value(const json_t *json);
diff --git a/src/value.c b/src/value.c
index fda0b03..d83d575 100644
--- a/src/value.c
+++ b/src/value.c
@@ -118,23 +118,40 @@ json_t *json_object_get(const json_t *json, const char *key)
return hashtable_get(&object->hashtable, key);
}
-int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
+int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
{
json_object_t *object;
if(!json_is_object(json))
+ {
+ json_decref(value);
return -1;
-
+ }
object = json_to_object(json);
- return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
+
+ if(hashtable_set(&object->hashtable, strdup(key), value))
+ {
+ json_decref(value);
+ return -1;
+ }
+
+ return 0;
+}
+
+int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
+{
+ return json_object_set_new_nocheck(json, key, json_incref(value));
}
-int json_object_set(json_t *json, const char *key, json_t *value)
+int json_object_set_new(json_t *json, const char *key, json_t *value)
{
if(!utf8_check_string(key, -1))
+ {
+ json_decref(value);
return -1;
+ }
- return json_object_set_nocheck(json, key, value);
+ return json_object_set_new_nocheck(json, key, value);
}
int json_object_del(json_t *json, const char *key)
@@ -235,37 +252,49 @@ json_t *json_array_get(const json_t *json, unsigned int index)
return array->table[index];
}
-int json_array_set(json_t *json, unsigned int index, json_t *value)
+int json_array_set_new(json_t *json, unsigned int index, json_t *value)
{
json_array_t *array;
if(!json_is_array(json))
+ {
+ json_decref(value);
return -1;
+ }
array = json_to_array(json);
if(index >= array->entries)
+ {
+ json_decref(value);
return -1;
+ }
json_decref(array->table[index]);
- array->table[index] = json_incref(value);
+ array->table[index] = value;
return 0;
}
-int json_array_append(json_t *json, json_t *value)
+int json_array_append_new(json_t *json, json_t *value)
{
json_array_t *array;
if(!json_is_array(json))
+ {
+ json_decref(value);
return -1;
+ }
array = json_to_array(json);
if(array->entries == array->size) {
array->size = max(8, array->size * 2);
array->table = realloc(array->table, array->size * sizeof(json_t *));
if(!array->table)
+ {
+ json_decref(value);
return -1;
+ }
}
- array->table[array->entries] = json_incref(value);
+ array->table[array->entries] = value;
array->entries++;
return 0;
diff --git a/test/testprogs/test_array.c b/test/testprogs/test_array.c
index 0ebc3d5..97a8513 100644
--- a/test/testprogs/test_array.c
+++ b/test/testprogs/test_array.c
@@ -85,6 +85,16 @@ int main()
fail("got wrong value");
}
+ json_array_set_new(array, 15, json_integer(123));
+ value = json_array_get(array, 15);
+ if(!json_is_integer(value) || json_integer_value(value) != 123)
+ fail("json_array_set_new works incorrectly");
+
+ json_array_append_new(array, json_integer(321));
+ value = json_array_get(array, json_array_size(array) - 1);
+ if(!json_is_integer(value) || json_integer_value(value) != 321)
+ fail("json_array_append_new works incorrectly");
+
json_decref(five);
json_decref(seven);
json_decref(array);
diff --git a/test/testprogs/test_object.c b/test/testprogs/test_object.c
index 9f72374..1b42c02 100644
--- a/test/testprogs/test_object.c
+++ b/test/testprogs/test_object.c
@@ -73,7 +73,7 @@ int main()
fail("unable to delete an existing key");
- /* add many keys to rehashing */
+ /* add many keys to initiate rehashing */
if(json_object_set(object, "a", string))
fail("unable to set value");
@@ -93,6 +93,12 @@ int main()
if(json_object_set(object, "e", string))
fail("unable to set value");
+
+ json_object_set_new(object, "foo", json_integer(123));
+ value = json_object_get(object, "foo");
+ if(!json_is_integer(value) || json_integer_value(value) != 123)
+ fail("json_object_set_new works incorrectly");
+
json_decref(string);
json_decref(other_string);
json_decref(object);