[json-glib] Add JsonObject iteration function



commit 3057a1722e27a13b39ddec4754fb6abda1aea199
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Sat May 16 20:09:07 2009 +0100

    Add JsonObject iteration function
    
    The json_object_foreach_member() function iterates over a JsonObject
    data type.
---
 doc/reference/json-glib-sections.txt |    2 +
 json-glib/json-object.c              |   55 ++++++++++++++++++++++++++++++++
 json-glib/json-types.h               |   25 +++++++++++++-
 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 ();
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]