[json-glib] boxed: Split (de)serialization registration



commit 3cf919e9c7f3201305a1a63a3c270e422a37efed
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Nov 23 22:20:58 2009 +0000

    boxed: Split (de)serialization registration
    
    A GBoxed type defined as:
    
      struct Boxed {
        int foo;
        gboolean bar;
        int baz;
      };
    
    Can be represented either by a JSON object:
    
      {
        "foo" : 1,
        "bar" : true,
        "baz" : 3
      }
    
    Or by a JSON array:
    
      [ 1, true, 3 ]
    
    The current function for registering a serialization and a
    deserialization pair does not allow registering more than one
    deserialization function - which means that there can only be
    one way to deserialize a GBoxed type into a specific JsonNode
    type.
    
    To allow having more than one JsonNodeType associated to a
    GBoxed type and a deserialization function we need to split out
    the registration of the serialization and deserialization functions
    into two distinct functions.

 doc/reference/json-glib-sections.txt |    3 +-
 json-glib/json-gboxed.c              |  115 ++++++++++++++++++++++------------
 json-glib/json-gobject.c             |    4 +-
 json-glib/json-gobject.h             |   63 +++++++++---------
 tests/test-serialize-boxed.c         |    7 +-
 5 files changed, 114 insertions(+), 78 deletions(-)
---
diff --git a/doc/reference/json-glib-sections.txt b/doc/reference/json-glib-sections.txt
index 5d6ff06..5df783c 100644
--- a/doc/reference/json-glib-sections.txt
+++ b/doc/reference/json-glib-sections.txt
@@ -219,7 +219,8 @@ json_serializable_get_type
 <TITLE>Boxed Types Serialization</TITLE>
 JsonBoxedSerializeFunc
 JsonBoxedDeserializeFunc
-json_boxed_register_transform_func
+json_boxed_register_serialize_func
+json_boxed_register_deserialize_func
 
 <SUBSECTION>
 json_boxed_can_serialize
diff --git a/json-glib/json-gboxed.c b/json-glib/json-gboxed.c
index fa1f9a3..fd2ebb9 100644
--- a/json-glib/json-gboxed.c
+++ b/json-glib/json-gboxed.c
@@ -86,8 +86,11 @@ struct _BoxedTransform
   JsonBoxedDeserializeFunc deserialize;
 };
 
-G_LOCK_DEFINE_STATIC (boxed_transforms);
-static GSList *boxed_transforms = NULL;
+G_LOCK_DEFINE_STATIC (boxed_serialize);
+static GSList *boxed_serialize = NULL;
+
+G_LOCK_DEFINE_STATIC (boxed_deserialize);
+static GSList *boxed_deserialize = NULL;
 
 static gint
 boxed_transforms_cmp (gconstpointer a,
@@ -114,8 +117,9 @@ boxed_transforms_find (gconstpointer a,
 }
 
 static BoxedTransform *
-lookup_boxed_transform (GType        gboxed_type,
-                        JsonNodeType node_type)
+lookup_boxed_transform (GSList       *transforms,
+                        GType         gboxed_type,
+                        JsonNodeType  node_type)
 {
   BoxedTransform lookup;
   GSList *t;
@@ -123,7 +127,7 @@ lookup_boxed_transform (GType        gboxed_type,
   lookup.boxed_type = gboxed_type;
   lookup.node_type = node_type;
 
-  t = g_slist_find_custom (boxed_transforms, &lookup, boxed_transforms_find);
+  t = g_slist_find_custom (transforms, &lookup, boxed_transforms_find);
   if (t == NULL)
     return NULL;
 
@@ -131,60 +135,93 @@ lookup_boxed_transform (GType        gboxed_type,
 }
 
 /**
- * json_boxed_register_transform_func:
+ * json_boxed_register_serialize_func:
  * @gboxed_type: a boxed type
  * @node_type: a node type
- * @serialize_func: (allow-none): serialization function for @boxed_type
- *   into a #JsonNode of type @node_type; can be %NULL if @deserialize_func
- *   is not %NULL
- * @deserialize_func: (allow-none): deserialization function for @boxed_type
- *   from a #JsonNode of type @node_type; can be %NULL if @serialize_func
- *   is not %NULL
+ * @serialize_func: serialization function for @boxed_type into
+ *   a #JsonNode of type @node_type
  *
- * Registers a serialization and deserialization functions for a #GBoxed
- * of type @gboxed_type to and from a #JsonNode of type @node_type
+ * Registers a serialization function for a #GBoxed of type @gboxed_type
+ * to a #JsonNode of type @node_type
  *
  * Since: 0.10
  */
 void
-json_boxed_register_transform_func (GType                    gboxed_type,
-                                    JsonNodeType             node_type,
-                                    JsonBoxedSerializeFunc   serialize_func,
-                                    JsonBoxedDeserializeFunc deserialize_func)
+json_boxed_register_serialize_func (GType                  gboxed_type,
+                                    JsonNodeType           node_type,
+                                    JsonBoxedSerializeFunc serialize_func)
 {
   BoxedTransform *t;
 
   g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type));
   g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE);
 
-  if (serialize_func == NULL)
-    g_return_if_fail (deserialize_func != NULL);
+  G_LOCK (boxed_serialize);
+
+  t = lookup_boxed_transform (boxed_serialize, gboxed_type, node_type);
+  if (t == NULL)
+    {
+      t = g_slice_new (BoxedTransform);
+
+      t->boxed_type = gboxed_type;
+      t->node_type = node_type;
+      t->serialize = serialize_func;
+
+      boxed_serialize = g_slist_insert_sorted (boxed_serialize, t,
+                                               boxed_transforms_cmp);
+    }
+  else
+    g_warning ("A serialization function for the boxed type %s into "
+               "JSON nodes of type %s already exists",
+               g_type_name (gboxed_type),
+               json_node_type_get_name (node_type));
+
+  G_UNLOCK (boxed_serialize);
+}
+
+/**
+ * json_boxed_register_deserialize_func:
+ * @gboxed_type: a boxed type
+ * @node_type: a node type
+ * @deserialize_func: deserialization function for @boxed_type from
+ *   a #JsonNode of type @node_type
+ *
+ * Registers a deserialization function for a #GBoxed of type @gboxed_type
+ * from a #JsonNode of type @node_type
+ *
+ * Since: 0.10
+ */
+void
+json_boxed_register_deserialize_func (GType                    gboxed_type,
+                                      JsonNodeType             node_type,
+                                      JsonBoxedDeserializeFunc deserialize_func)
+{
+  BoxedTransform *t;
 
-  if (deserialize_func == NULL)
-    g_return_if_fail (serialize_func != NULL);
+  g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type));
+  g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE);
 
-  G_LOCK (boxed_transforms);
+  G_LOCK (boxed_deserialize);
 
-  t = lookup_boxed_transform (gboxed_type, node_type);
+  t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
   if (t == NULL)
     {
       t = g_slice_new (BoxedTransform);
 
       t->boxed_type = gboxed_type;
       t->node_type = node_type;
-      t->serialize = serialize_func;
       t->deserialize = deserialize_func;
 
-      boxed_transforms = g_slist_insert_sorted (boxed_transforms, t,
-                                                boxed_transforms_cmp);
+      boxed_deserialize = g_slist_insert_sorted (boxed_deserialize, t,
+                                                 boxed_transforms_cmp);
     }
   else
-    g_warning ("A transformation for the boxed type %s into "
+    g_warning ("A deserialization function for the boxed type %s from "
                "JSON nodes of type %s already exists",
                g_type_name (gboxed_type),
                json_node_type_get_name (node_type));
 
-  G_UNLOCK (boxed_transforms);
+  G_UNLOCK (boxed_deserialize);
 }
 
 /**
@@ -212,8 +249,8 @@ json_boxed_can_serialize (GType         gboxed_type,
   g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
   g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
 
-  t = lookup_boxed_transform (gboxed_type, -1);
-  if (t != NULL && t->serialize != NULL)
+  t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1);
+  if (t != NULL)
     {
       if (node_type)
         *node_type = t->node_type;
@@ -245,8 +282,8 @@ json_boxed_can_deserialize (GType        gboxed_type,
   g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
   g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
 
-  t = lookup_boxed_transform (gboxed_type, node_type);
-  if (t != NULL && t->deserialize != NULL)
+  t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
+  if (t != NULL)
     return TRUE;
 
   return FALSE;
@@ -255,11 +292,10 @@ json_boxed_can_deserialize (GType        gboxed_type,
 /**
  * json_boxed_serialize:
  * @gboxed_type: a boxed type
- * @node_type: a #JsonNode type
  * @boxed: a pointer to a #GBoxed of type @gboxed_type
  *
  * Serializes @boxed, a pointer to a #GBoxed of type @gboxed_type,
- * into a #JsonNode of type @node_type
+ * into a #JsonNode
  *
  * Return value: a #JsonNode with the serialization of the boxed
  *   type, or %NULL if serialization either failed or was not
@@ -268,9 +304,8 @@ json_boxed_can_deserialize (GType        gboxed_type,
  * Since: 0.10
  */
 JsonNode *
-json_boxed_serialize (GType          gboxed_type,
-                      JsonNodeType   node_type,
-                      gconstpointer  boxed)
+json_boxed_serialize (GType         gboxed_type,
+                      gconstpointer boxed)
 {
   BoxedTransform *t;
 
@@ -278,7 +313,7 @@ json_boxed_serialize (GType          gboxed_type,
   g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
   g_return_val_if_fail (boxed != NULL, NULL);
 
-  t = lookup_boxed_transform (gboxed_type, node_type);
+  t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1);
   if (t != NULL && t->serialize != NULL)
     return t->serialize (boxed);
 
@@ -310,7 +345,7 @@ json_boxed_deserialize (GType     gboxed_type,
 
   node_type = json_node_get_node_type (node);
 
-  t = lookup_boxed_transform (gboxed_type, node_type);
+  t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
   if (t != NULL && t->deserialize != NULL)
     return t->deserialize (node);
 
diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c
index 574ff38..0a98aa8 100644
--- a/json-glib/json-gobject.c
+++ b/json-glib/json-gobject.c
@@ -627,9 +627,7 @@ json_serialize_pspec (const GValue *real_value,
         {
           gpointer boxed = g_value_get_boxed (real_value);
 
-          retval = json_boxed_serialize (G_VALUE_TYPE (real_value),
-                                         node_type,
-                                         boxed);
+          retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed);
         }
       else
         g_warning ("Boxed type '%s' is not handled by JSON-GLib",
diff --git a/json-glib/json-gobject.h b/json-glib/json-gobject.h
index 69ae4e2..0fde684 100644
--- a/json-glib/json-gobject.h
+++ b/json-glib/json-gobject.h
@@ -113,39 +113,40 @@ typedef JsonNode *(* JsonBoxedSerializeFunc) (gconstpointer boxed);
  */
 typedef gpointer (* JsonBoxedDeserializeFunc) (JsonNode *node);
 
-void      json_boxed_register_transform_func (GType                     gboxed_type,
-                                              JsonNodeType              node_type,
-                                              JsonBoxedSerializeFunc    serialize_func,
-                                              JsonBoxedDeserializeFunc  deserialize_func);
-gboolean  json_boxed_can_serialize           (GType                     gboxed_type,
-                                              JsonNodeType             *node_type);
-gboolean  json_boxed_can_deserialize         (GType                     gboxed_type,
-                                              JsonNodeType              node_type);
-JsonNode *json_boxed_serialize               (GType                     gboxed_type,
-                                              JsonNodeType              node_type,
-                                              gconstpointer             boxed);
-gpointer  json_boxed_deserialize             (GType                     gboxed_type,
-                                              JsonNode                 *node);
-
-JsonNode *json_gobject_serialize             (GObject                  *gobject);
-GObject * json_gobject_deserialize           (GType                     gtype,
-                                              JsonNode                 *node);
-
-GObject * json_gobject_from_data             (GType                     gtype,
-                                              const gchar              *data,
-                                              gssize                    length,
-                                              GError                  **error);
-gchar *   json_gobject_to_data               (GObject                  *gobject,
-                                              gsize                    *length);
+void      json_boxed_register_serialize_func   (GType                    gboxed_type,
+                                                JsonNodeType             node_type,
+                                                JsonBoxedSerializeFunc   serialize_func);
+void      json_boxed_register_deserialize_func (GType                    gboxed_type,
+                                                JsonNodeType             node_type,
+                                                JsonBoxedDeserializeFunc serialize_func);
+gboolean  json_boxed_can_serialize             (GType                    gboxed_type,
+                                                JsonNodeType            *node_type);
+gboolean  json_boxed_can_deserialize           (GType                    gboxed_type,
+                                                JsonNodeType             node_type);
+JsonNode *json_boxed_serialize                 (GType                    gboxed_type,
+                                                gconstpointer            boxed);
+gpointer  json_boxed_deserialize               (GType                    gboxed_type,
+                                                JsonNode                *node);
+
+JsonNode *json_gobject_serialize               (GObject                 *gobject);
+GObject * json_gobject_deserialize             (GType                    gtype,
+                                                JsonNode                *node);
+
+GObject * json_gobject_from_data               (GType                    gtype,
+                                                const gchar             *data,
+                                                gssize                   length,
+                                                GError                 **error);
+gchar *   json_gobject_to_data                 (GObject                 *gobject,
+                                                gsize                   *length);
 
 #ifndef JSON_DISABLE_DEPRECATED
-GObject * json_construct_gobject   (GType         gtype,
-                                    const gchar  *data,
-                                    gsize         length,
-                                    GError      **error) G_GNUC_DEPRECATED;
-gchar *   json_serialize_gobject   (GObject      *gobject,
-                                    gsize        *length) G_GNUC_MALLOC G_GNUC_DEPRECATED;
-#endif
+GObject * json_construct_gobject               (GType                    gtype,
+                                                const gchar             *data,
+                                                gsize                    length,
+                                                GError                 **error) G_GNUC_DEPRECATED;
+gchar *   json_serialize_gobject               (GObject                 *gobject,
+                                                gsize                   *length) G_GNUC_MALLOC G_GNUC_DEPRECATED;
+#endif /* JSON_DISABLE_DEPRECATED */
 
 
 G_END_DECLS
diff --git a/tests/test-serialize-boxed.c b/tests/test-serialize-boxed.c
index 053fc68..deeef13 100644
--- a/tests/test-serialize-boxed.c
+++ b/tests/test-serialize-boxed.c
@@ -121,9 +121,10 @@ test_boxed_get_type (void)
       if (g_test_verbose ())
         g_print ("Registering transform functions\n");
 
-      json_boxed_register_transform_func (b_type, JSON_NODE_OBJECT,
-                                          test_boxed_serialize,
-                                          test_boxed_deserialize);
+      json_boxed_register_serialize_func (b_type, JSON_NODE_OBJECT,
+                                          test_boxed_serialize);
+      json_boxed_register_deserialize_func (b_type, JSON_NODE_OBJECT,
+                                            test_boxed_deserialize);
     }
 
   return b_type;



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