Add reference stealing functions for inserting values to objects and arrays
authorPetri Lehtinen <petri@digip.org>
Thu, 3 Sep 2009 14:56:00 +0000 (17:56 +0300)
committerPetri Lehtinen <petri@digip.org>
Fri, 4 Sep 2009 06:52:37 +0000 (09:52 +0300)
The non-stealing functions are now just simple wrappers around these.

doc/apiref.rst
src/jansson.h
src/value.c
test/testprogs/test_array.c
test/testprogs/test_object.c

index 903b48c..c70c0bc 100644 (file)
@@ -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
index 6efc6db..09af7bf 100644 (file)
@@ -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);
index fda0b03..d83d575 100644 (file)
@@ -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;
index 0ebc3d5..97a8513 100644 (file)
@@ -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);
index 9f72374..1b42c02 100644 (file)
@@ -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);