diff options
author | Emmanuele Bassi <ebassi@linux.intel.com> | 2009-05-16 20:09:07 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@linux.intel.com> | 2009-05-16 20:09:07 +0100 |
commit | 3057a1722e27a13b39ddec4754fb6abda1aea199 (patch) | |
tree | 8a5163c07abc96263e34f3026978d111943a1b3f | |
parent | 5778210462b8b7a1a5d98466508276f712ea8c47 (diff) | |
download | json-glib-3057a1722e27a13b39ddec4754fb6abda1aea199.tar.gz |
Add JsonObject iteration function
The json_object_foreach_member() function iterates over a JsonObject
data type.
-rw-r--r-- | doc/reference/json-glib-sections.txt | 2 | ||||
-rw-r--r-- | json-glib/json-object.c | 55 | ||||
-rw-r--r-- | json-glib/json-types.h | 25 | ||||
-rw-r--r-- | json-glib/tests/object-test.c | 57 |
4 files changed, 137 insertions, 2 deletions
diff --git a/doc/reference/json-glib-sections.txt b/doc/reference/json-glib-sections.txt index b30e190..368af77 100644 --- a/doc/reference/json-glib-sections.txt +++ b/doc/reference/json-glib-sections.txt @@ -16,6 +16,8 @@ json_object_get_members json_object_get_values json_object_get_size json_object_remove_member +JsonObjectForeach +json_object_foreach_member <SUBSECTION> json_object_set_array_member diff --git a/json-glib/json-object.c b/json-glib/json-object.c index 675038a..6397954 100644 --- a/json-glib/json-object.c +++ b/json-glib/json-object.c @@ -831,3 +831,58 @@ json_object_remove_member (JsonObject *object, g_hash_table_remove (object->members, name); g_free (name); } + +typedef struct _ForeachClosure ForeachClosure; + +struct _ForeachClosure +{ + JsonObject *object; + + JsonObjectForeach func; + gpointer data; +}; + +static void +json_object_foreach_internal (gpointer key, + gpointer value, + gpointer data) +{ + ForeachClosure *clos = data; + const gchar *member_name = key; + JsonNode *member_node = value; + + clos->func (clos->object, member_name, member_node, clos->data); +} + +/** + * json_object_foreach_member: + * @object: a #JsonObject + * @func: the function to be called on each member + * @data: data to be passed to the function + * + * Iterates over all members of @object and calls @func on + * each one of them. + * + * It is safe to change the value of a #JsonNode of the @object + * from within the iterator @func, but it is not safe to add or + * remove members from the @object. + * + * Since: 0.8 + */ +void +json_object_foreach_member (JsonObject *object, + JsonObjectForeach func, + gpointer data) +{ + ForeachClosure clos; + + g_return_if_fail (object != NULL); + g_return_if_fail (func != NULL); + + clos.object = object; + clos.func = func; + clos.data = data; + g_hash_table_foreach (object->members, + json_object_foreach_internal, + &clos); +} diff --git a/json-glib/json-types.h b/json-glib/json-types.h index 1851ef0..da5a268 100644 --- a/json-glib/json-types.h +++ b/json-glib/json-types.h @@ -36,6 +36,8 @@ G_BEGIN_DECLS #define JSON_TYPE_OBJECT (json_object_get_type ()) #define JSON_TYPE_ARRAY (json_array_get_type ()) +typedef struct _JsonNode JsonNode; + /** * JsonObject: * @@ -52,8 +54,6 @@ typedef struct _JsonObject JsonObject; */ typedef struct _JsonArray JsonArray; -typedef struct _JsonNode JsonNode; - /** * JsonNodeType: * @JSON_NODE_OBJECT: The node contains a #JsonObject @@ -71,6 +71,24 @@ typedef enum { } JsonNodeType; /** + * JsonObjectForeach: + * @object: the iterated #JsonObject + * @member_name: the name of the member + * @member_node: a #JsonNode containing the @member_name value + * @user_data: data passed to the function + * + * The function to be passed to json_object_foreach_member(). You + * should not add or remove members to and from @object within + * this function. It is safe to change the value of @member_node. + * + * Since: 0.8 + */ +typedef void (* JsonObjectForeach) (JsonObject *object, + const gchar *member_name, + JsonNode *member_node, + gpointer user_data); + +/** * JsonNode: * @type: the type of node * @@ -197,6 +215,9 @@ void json_object_remove_member (JsonObject *object, const gchar *member_name); GList * json_object_get_values (JsonObject *object); guint json_object_get_size (JsonObject *object); +void json_object_foreach_member (JsonObject *object, + JsonObjectForeach func, + gpointer data); GType json_array_get_type (void) G_GNUC_CONST; JsonArray * json_array_new (void); diff --git a/json-glib/tests/object-test.c b/json-glib/tests/object-test.c index 4803e96..5528342 100644 --- a/json-glib/tests/object-test.c +++ b/json-glib/tests/object-test.c @@ -47,6 +47,62 @@ test_remove_member (void) json_object_unref (object); } +typedef struct _TestForeachFixture +{ + gint n_members; +} TestForeachFixture; + +static const struct { + const gchar *member_name; + JsonNodeType member_type; + GType member_gtype; +} type_verify[] = { + { "integer", JSON_NODE_VALUE, G_TYPE_INT }, + { "boolean", JSON_NODE_VALUE, G_TYPE_BOOLEAN }, + { "string", JSON_NODE_VALUE, G_TYPE_STRING }, + { "null", JSON_NODE_NULL, G_TYPE_INVALID } +}; + +static void +verify_foreach (JsonObject *object, + const gchar *member_name, + JsonNode *member_node, + gpointer user_data) +{ + TestForeachFixture *fixture = user_data; + gint i; + + for (i = 0; i < G_N_ELEMENTS (type_verify); i++) + { + if (strcmp (member_name, type_verify[i].member_name) == 0) + { + g_assert (json_node_get_node_type (member_node) == type_verify[i].member_type); + g_assert (json_node_get_value_type (member_node) == type_verify[i].member_gtype); + break; + } + } + + fixture->n_members += 1; +} + +static void +test_foreach_member (void) +{ + JsonObject *object = json_object_new (); + TestForeachFixture fixture = { 0, }; + + json_object_set_int_member (object, "integer", 42); + json_object_set_boolean_member (object, "boolean", TRUE); + json_object_set_string_member (object, "string", "hello"); + json_object_set_null_member (object, "null"); + + json_object_foreach_member (object, verify_foreach, &fixture); + + g_assert_cmpint (fixture.n_members, ==, json_object_get_size (object)); + + json_object_unref (object); +} + int main (int argc, char *argv[]) @@ -57,6 +113,7 @@ main (int argc, g_test_add_func ("/object/empty-object", test_empty_object); g_test_add_func ("/object/add-member", test_add_member); g_test_add_func ("/object/remove-member", test_remove_member); + g_test_add_func ("/object/foreach-member", test_foreach_member); return g_test_run (); } |