Extend object API

Added functions:

  json_object_size
  json_object_clear
  json_object_update
This commit is contained in:
Petri Lehtinen 2009-10-11 20:42:43 +03:00
parent 40bb7bf437
commit 1e00cd58a5
6 changed files with 255 additions and 17 deletions

View File

@ -343,6 +343,13 @@ Unicode string and the value is any JSON value.
Returns a new JSON object, or *NULL* on error. Initially, the Returns a new JSON object, or *NULL* on error. Initially, the
object is empty. object is empty.
.. cfunction:: unsigned int json_object_size(const json_t *object)
Returns the number of elements in *object*, or 0 if *object* is not
a JSON object.
.. versionadded:: 1.1
.. cfunction:: json_t *json_object_get(const json_t *object, const char *key) .. cfunction:: json_t *json_object_get(const json_t *object, const char *key)
.. refcounting:: borrow .. refcounting:: borrow
@ -371,6 +378,21 @@ Unicode string and the value is any JSON value.
-1 if *key* was not found. -1 if *key* was not found.
.. cfunction:: int json_object_clear(json_t *object)
Remove all elements from *object*. Returns 0 on success and -1 if
*object* is not a JSON object.
.. versionadded:: 1.1
.. cfunction:: int json_object_update(json_t *object, json_t *other)
Update *object* with the key-value pairs from *other*, overwriting
existing keys. Returns 0 on success or -1 on error.
.. versionadded:: 1.1
The following functions implement an iteration protocol for objects: The following functions implement an iteration protocol for objects:
.. cfunction:: void *json_object_iter(json_t *object) .. cfunction:: void *json_object_iter(json_t *object)

View File

@ -133,6 +133,23 @@ static int hashtable_do_del(hashtable_t *hashtable,
return 0; return 0;
} }
static void hashtable_do_clear(hashtable_t *hashtable)
{
list_t *list, *next;
pair_t *pair;
for(list = hashtable->list.next; list != &hashtable->list; list = next)
{
next = list->next;
pair = list_to_pair(list);
if(hashtable->free_key)
hashtable->free_key(pair->key);
if(hashtable->free_value)
hashtable->free_value(pair->value);
free(pair);
}
}
static int hashtable_do_rehash(hashtable_t *hashtable) static int hashtable_do_rehash(hashtable_t *hashtable)
{ {
list_t *list, *next; list_t *list, *next;
@ -220,19 +237,7 @@ int hashtable_init(hashtable_t *hashtable,
void hashtable_close(hashtable_t *hashtable) void hashtable_close(hashtable_t *hashtable)
{ {
list_t *list, *next; hashtable_do_clear(hashtable);
pair_t *pair;
for(list = hashtable->list.next; list != &hashtable->list; list = next)
{
next = list->next;
pair = list_to_pair(list);
if(hashtable->free_key)
hashtable->free_key(pair->key);
if(hashtable->free_value)
hashtable->free_value(pair->value);
free(pair);
}
free(hashtable->buckets); free(hashtable->buckets);
} }
@ -292,6 +297,22 @@ int hashtable_del(hashtable_t *hashtable, const void *key)
return hashtable_do_del(hashtable, key, hash); return hashtable_do_del(hashtable, key, hash);
} }
void hashtable_clear(hashtable_t *hashtable)
{
unsigned int i;
hashtable_do_clear(hashtable);
for(i = 0; i < num_buckets(hashtable); i++)
{
hashtable->buckets[i].first = hashtable->buckets[i].last =
&hashtable->list;
}
list_init(&hashtable->list);
hashtable->size = 0;
}
void *hashtable_iter(hashtable_t *hashtable) void *hashtable_iter(hashtable_t *hashtable)
{ {
return hashtable_iter_next(hashtable, &hashtable->list); return hashtable_iter_next(hashtable, &hashtable->list);

View File

@ -134,6 +134,15 @@ void *hashtable_get(hashtable_t *hashtable, const void *key);
*/ */
int hashtable_del(hashtable_t *hashtable, const void *key); int hashtable_del(hashtable_t *hashtable, const void *key);
/**
* hashtable_clear - Clear hashtable
*
* @hashtable: The hashtable object
*
* Removes all items from the hashtable.
*/
void hashtable_clear(hashtable_t *hashtable);
/** /**
* hashtable_iter - Iterate over hashtable * hashtable_iter - Iterate over hashtable
* *

View File

@ -71,9 +71,12 @@ static inline void json_decref(json_t *json)
/* getters, setters, manipulation */ /* getters, setters, manipulation */
unsigned int json_object_size(const json_t *object);
json_t *json_object_get(const json_t *object, const char *key); json_t *json_object_get(const json_t *object, const char *key);
int json_object_set_new(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); int json_object_del(json_t *object, const char *key);
int json_object_clear(json_t *object);
int json_object_update(json_t *object, json_t *other);
void *json_object_iter(json_t *object); void *json_object_iter(json_t *object);
void *json_object_iter_next(json_t *object, void *iter); void *json_object_iter_next(json_t *object, void *iter);
const char *json_object_iter_key(void *iter); const char *json_object_iter_key(void *iter);

View File

@ -107,6 +107,17 @@ static void json_delete_object(json_object_t *object)
free(object); free(object);
} }
unsigned int json_object_size(const json_t *json)
{
json_object_t *object;
if(!json_is_object(json))
return -1;
object = json_to_object(json);
return object->hashtable.size;
}
json_t *json_object_get(const json_t *json, const char *key) json_t *json_object_get(const json_t *json, const char *key)
{ {
json_object_t *object; json_object_t *object;
@ -168,6 +179,43 @@ int json_object_del(json_t *json, const char *key)
return hashtable_del(&object->hashtable, key); return hashtable_del(&object->hashtable, key);
} }
int json_object_clear(json_t *json)
{
json_object_t *object;
if(!json_is_object(json))
return -1;
object = json_to_object(json);
hashtable_clear(&object->hashtable);
return 0;
}
int json_object_update(json_t *object, json_t *other)
{
void *iter;
if(!json_is_object(object) || !json_is_object(other))
return -1;
iter = json_object_iter(other);
while(iter) {
const char *key;
json_t *value;
key = json_object_iter_key(iter);
value = json_object_iter_value(iter);
if(json_object_set(object, key, value))
return -1;
iter = json_object_iter_next(other, iter);
}
return 0;
}
void *json_object_iter(json_t *json) void *json_object_iter(json_t *json)
{ {
json_object_t *object; json_object_t *object;

View File

@ -9,7 +9,137 @@
#include <string.h> #include <string.h>
#include "util.h" #include "util.h"
int main() static void test_clear()
{
json_t *object, *ten;
object = json_object();
ten = json_integer(10);
if(!object)
fail("unable to create object");
if(!ten)
fail("unable to create integer");
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_size(object) != 5)
fail("invalid size");
json_object_clear(object);
if(json_object_size(object) != 0)
fail("invalid size after clear");
json_decref(ten);
json_decref(object);
}
static void test_update()
{
json_t *object, *other, *nine, *ten;
object = json_object();
other = json_object();
nine = json_integer(9);
ten = json_integer(10);
if(!object || !other)
fail("unable to create object");
if(!nine || !ten)
fail("unable to create integer");
/* update an empty object with an empty object */
if(json_object_update(object, other))
fail("unable to update an emtpy object with an empty object");
if(json_object_size(object) != 0)
fail("invalid size after update");
if(json_object_size(other) != 0)
fail("invalid size for updater after update");
/* update an empty object with a nonempty object */
if(json_object_set(other, "a", ten) ||
json_object_set(other, "b", ten) ||
json_object_set(other, "c", ten) ||
json_object_set(other, "d", ten) ||
json_object_set(other, "e", ten))
fail("unable to set value");
if(json_object_update(object, other))
fail("unable to update an empty object");
if(json_object_size(object) != 5)
fail("invalid size after update");
if(json_object_get(object, "a") != ten ||
json_object_get(object, "b") != ten ||
json_object_get(object, "c") != ten ||
json_object_get(object, "d") != ten ||
json_object_get(object, "e") != ten)
fail("update works incorrectly");
/* perform the same update again */
if(json_object_update(object, other))
fail("unable to update an empty object");
if(json_object_size(object) != 5)
fail("invalid size after update");
if(json_object_get(object, "a") != ten ||
json_object_get(object, "b") != ten ||
json_object_get(object, "c") != ten ||
json_object_get(object, "d") != ten ||
json_object_get(object, "e") != ten)
fail("update works incorrectly");
/* update a nonempty object with a nonempty object with both old
and new keys */
if(json_object_clear(other))
fail("clear failed");
if(json_object_set(other, "a", nine) ||
json_object_set(other, "b", nine) ||
json_object_set(other, "f", nine) ||
json_object_set(other, "g", nine) ||
json_object_set(other, "h", nine))
fail("unable to set value");
if(json_object_update(object, other))
fail("unable to update a nonempty object");
if(json_object_size(object) != 8)
fail("invalid size after update");
if(json_object_get(object, "a") != nine ||
json_object_get(object, "b") != nine ||
json_object_get(object, "f") != nine ||
json_object_get(object, "g") != nine ||
json_object_get(object, "h") != nine)
fail("update works incorrectly");
json_decref(nine);
json_decref(ten);
json_decref(other);
json_decref(object);
}
static void test_misc()
{ {
json_t *object, *string, *other_string, *value; json_t *object, *string, *other_string, *value;
void *iter; void *iter;
@ -20,9 +150,7 @@ int main()
if(!object) if(!object)
fail("unable to create object"); fail("unable to create object");
if(!string) if(!string || !other_string)
fail("unable to create string");
if(!other_string)
fail("unable to create string"); fail("unable to create string");
if(json_object_get(object, "a")) if(json_object_get(object, "a"))
@ -129,6 +257,13 @@ int main()
json_decref(string); json_decref(string);
json_decref(other_string); json_decref(other_string);
json_decref(object); json_decref(object);
}
int main()
{
test_misc();
test_clear();
test_update();
return 0; return 0;
} }