[json-glib] gobject: Add experimental GBoxed<->JSON transformation
- From: Emmanuele Bassi <ebassi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [json-glib] gobject: Add experimental GBoxed<->JSON transformation
- Date: Tue, 27 Oct 2009 18:02:13 +0000 (UTC)
commit ff986ee5b8df45255f4f5ab01be0bbad893bc55e
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Tue Oct 27 17:53:34 2009 +0000
gobject: Add experimental GBoxed<->JSON transformation
Serializing and deserializing GBoxed types is fairly complicated
currently. If a GObject implements JsonSerializable it is possible
for the class to intercept the JsonNode, parse it manually and
then set the value to the property.
This leaves a hole opened for:
â?¢ manual (de)serialization of GBoxed types
â?¢ (de)serialization of GBoxed properties in classes not
implementing JsonSerializable
In order to serialize and deserialize a GBoxed JSON-GLib should
provide a mechanism similar to the GValue transformation functions:
when registering the boxed type the developer should also be able
to register a serialization and a deserialization functions pair
matching the tuple:
(GBoxed type, JSON type)
The serialization function would be:
JsonNode *(* JsonBoxedSerializeFunc) (gconstpointer boxed);
And, conversely, the deserialization function would be:
gpointer (* JsonBoxedDeserializeFunc) (JsonNode *node);
Obviously, the whole machinery works only for GBoxed types that
register the serialization and deserialization functions.
.gitignore | 68 ++++++-----
json-glib/json-gobject.c | 264 +++++++++++++++++++++++++++++++++++++++++-
json-glib/json-gobject.h | 37 ++++++
tests/Makefile.am | 8 +-
tests/test-serialize-boxed.c | 263 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 602 insertions(+), 38 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index caf3c70..4b93725 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ autom4te.cache
!/build/autotools/shave.m4
!/build/autotools/as-compiler-flag.m4
!/build/autotools/introspection.m4
+compile
configure
config.guess
config.h
@@ -16,7 +17,7 @@ config.log
config.status
config.sub
depcomp
-doc/reference/version.xml
+/doc/reference/version.xml
gtk-doc.make
install-sh
json-glib-1.0.pc
@@ -25,46 +26,47 @@ json-glib.pc
.libs
*.o
*.lo
-json-enum-types.[ch]
-json-marshal.[ch]
-json-version.h
-Json-1.0.gir
-Json-1.0.typelib
-*.la
-stamp-enum-types
-stamp-marshal
-array-test
-object-test
-node-test
+/json-glib/json-enum-types.[ch]
+/json-glib/json-marshal.[ch]
+/json-glib/json-version.h
+/json-glib/Json-1.0.gir
+/json-glib/Json-1.0.typelib
+/json-glib/*.la
+/json-glib/stamp-enum-types
+/json-glib/stamp-marshal
+/json-glib/tests/array-test
+/json-glib/tests/object-test
+/json-glib/tests/node-test
libtool
ltmain.sh
missing
stamp-h1
test-report.xml
test-report.html
-test-parser
-test-generator
-test-serialize-simple
-test-serialize-complex
-test-serialize-full
+/tests/test-parser
+/tests/test-generator
+/tests/test-serialize-simple
+/tests/test-serialize-complex
+/tests/test-serialize-full
+/tests/test-serialize-boxed
.*.swp
*.stamp
-doc/reference/html
-doc/reference/tmpl
-doc/reference/xml
-doc/reference/json-glib-decl-list.txt
-doc/reference/json-glib-decl-list.txt.bak
-doc/reference/json-glib-decl.txt
-doc/reference/json-glib-decl.txt.bak
-doc/reference/json-glib-overrides.txt
-doc/reference/json-glib-undeclared.txt
-doc/reference/json-glib-undocumented.txt
-doc/reference/json-glib-unused.txt
-doc/reference/json-glib.args
-doc/reference/json-glib.hierarchy
-doc/reference/json-glib.interfaces
-doc/reference/json-glib.prerequisites
-doc/reference/json-glib.signals
+/doc/reference/html
+/doc/reference/tmpl
+/doc/reference/xml
+/doc/reference/json-glib-decl-list.txt
+/doc/reference/json-glib-decl-list.txt.bak
+/doc/reference/json-glib-decl.txt
+/doc/reference/json-glib-decl.txt.bak
+/doc/reference/json-glib-overrides.txt
+/doc/reference/json-glib-undeclared.txt
+/doc/reference/json-glib-undocumented.txt
+/doc/reference/json-glib-unused.txt
+/doc/reference/json-glib.args
+/doc/reference/json-glib.hierarchy
+/doc/reference/json-glib.interfaces
+/doc/reference/json-glib.prerequisites
+/doc/reference/json-glib.signals
omf.make
xmldocs.make
/build/autotools/gtk-doc.m4
diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c
index 2a8ec94..7c9a04d 100644
--- a/json-glib/json-gobject.c
+++ b/json-glib/json-gobject.c
@@ -45,6 +45,243 @@
#include "json-parser.h"
#include "json-generator.h"
+typedef struct _BoxedTransform BoxedTransform;
+
+struct _BoxedTransform
+{
+ GType boxed_type;
+ gint node_type;
+
+ JsonBoxedSerializeFunc serialize;
+ JsonBoxedDeserializeFunc deserialize;
+};
+
+G_LOCK_DEFINE_STATIC (boxed_transforms);
+static GSList *boxed_transforms = NULL;
+
+static gint
+boxed_transforms_cmp (gconstpointer a,
+ gconstpointer b)
+{
+ const BoxedTransform *ta = a;
+ const BoxedTransform *tb = b;
+
+ return tb->boxed_type - ta->boxed_type;
+}
+
+static gint
+boxed_transforms_find (gconstpointer a,
+ gconstpointer b)
+{
+ const BoxedTransform *haystack = a;
+ const BoxedTransform *needle = b;
+
+ if (needle->node_type != -1)
+ return (haystack->boxed_type == needle->boxed_type &&
+ haystack->node_type == needle->node_type) ? 0 : 1;
+ else
+ return (haystack->boxed_type == needle->boxed_type) ? 0 : 1;
+}
+
+static BoxedTransform *
+lookup_boxed_transform (GType gboxed_type,
+ JsonNodeType node_type)
+{
+ BoxedTransform lookup;
+ GSList *t;
+
+ lookup.boxed_type = gboxed_type;
+ lookup.node_type = node_type;
+
+ t = g_slist_find_custom (boxed_transforms, &lookup, boxed_transforms_find);
+ if (t == NULL)
+ return NULL;
+
+ return t->data;
+}
+
+/**
+ * json_boxed_register_transform_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
+ *
+ * Registers a serialization and deserialization functions for a #GBoxed
+ * of type @gboxed_type to and from 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)
+{
+ 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);
+
+ if (deserialize_func == NULL)
+ g_return_if_fail (serialize_func != NULL);
+
+ G_LOCK (boxed_transforms);
+
+ t = lookup_boxed_transform (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);
+ }
+ else
+ g_warning ("A transformation 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_transforms);
+}
+
+/**
+ * json_boxed_can_serialize:
+ * @gboxed_type: a boxed type
+ * @node_type: (out): the #JsonNode type to which the boxed type can be
+ * deserialized into
+ *
+ * Checks whether it is possible to serialize a #GBoxed of
+ * type @gboxed_type into a #JsonNode of type @node_type
+ *
+ * Return value: %TRUE if the type can be serialized, %FALSE otherwise
+ *
+ * Since: 0.10
+ */
+gboolean
+json_boxed_can_serialize (GType gboxed_type,
+ JsonNodeType *node_type)
+{
+ BoxedTransform *t;
+
+ 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)
+ {
+ if (node_type)
+ *node_type = t->node_type;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * json_boxed_can_deserialize:
+ * @gboxed_type: a boxed type
+ * @node_type: a #JsonNode type
+ *
+ * Checks whether it is possible to deserialize a #GBoxed of
+ * type @gboxed_type from a #JsonNode of type @node_type
+ *
+ * Return value: %TRUE if the type can be deserialized, %FALSE otherwise
+ *
+ * Since: 0.10
+ */
+gboolean
+json_boxed_can_deserialize (GType gboxed_type,
+ JsonNodeType node_type)
+{
+ BoxedTransform *t;
+
+ 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)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * 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
+ *
+ * Return value: a #JsonNode with the serialization of the boxed
+ * type, or %NULL if serialization either failed or was not
+ * possible
+ *
+ * Since: 0.10
+ */
+JsonNode *
+json_boxed_serialize (GType gboxed_type,
+ JsonNodeType node_type,
+ gconstpointer boxed)
+{
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
+ 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);
+ if (t != NULL && t->serialize != NULL)
+ return t->serialize (boxed);
+
+ return NULL;
+}
+
+/**
+ * json_boxed_serialize:
+ * @gboxed_type: a boxed type
+ * @node: a #JsonNode
+ *
+ * Deserializes @node into @boxed, a pointer to a #GBoxed of type
+ * @gboxed_type
+ *
+ * Since: 0.10
+ */
+gpointer
+json_boxed_deserialize (GType gboxed_type,
+ JsonNode *node)
+{
+ JsonNodeType node_type;
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
+ g_return_val_if_fail (node != NULL, NULL);
+
+ node_type = json_node_get_node_type (node);
+
+ t = lookup_boxed_transform (gboxed_type, node_type);
+ if (t != NULL && t->deserialize != NULL)
+ return t->deserialize (node);
+
+ return NULL;
+}
+
/* forward declaration */
static JsonNode *json_serialize_pspec (const GValue *real_value,
GParamSpec *pspec);
@@ -396,6 +633,21 @@ json_deserialize_pspec (GValue *value,
GValue node_value = { 0, };
gboolean retval = FALSE;
+ if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOXED)
+ {
+ JsonNodeType node_type = json_node_get_node_type (node);
+ GType boxed_type = G_VALUE_TYPE (value);
+
+ if (json_boxed_can_deserialize (boxed_type, node_type))
+ {
+ gpointer boxed = json_boxed_deserialize (boxed_type, node);
+
+ g_value_take_boxed (value, boxed);
+
+ return TRUE;
+ }
+ }
+
switch (JSON_NODE_TYPE (node))
{
case JSON_NODE_OBJECT:
@@ -554,6 +806,7 @@ json_serialize_pspec (const GValue *real_value,
{
JsonNode *retval = NULL;
GValue value = { 0, };
+ JsonNodeType node_type;
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value)))
{
@@ -611,10 +864,17 @@ json_serialize_pspec (const GValue *real_value,
retval = json_node_new (JSON_NODE_ARRAY);
json_node_take_array (retval, array);
}
- else
+ else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type))
{
- g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value)));
+ gpointer boxed = g_value_get_boxed (real_value);
+
+ retval = json_boxed_serialize (G_VALUE_TYPE (real_value),
+ node_type,
+ boxed);
}
+ else
+ g_warning ("Boxed type '%s' is not handled by JSON-GLib",
+ g_type_name (G_VALUE_TYPE (real_value)));
break;
case G_TYPE_UINT:
diff --git a/json-glib/json-gobject.h b/json-glib/json-gobject.h
index 8eacc58..207db52 100644
--- a/json-glib/json-gobject.h
+++ b/json-glib/json-gobject.h
@@ -79,6 +79,43 @@ gboolean json_serializable_deserialize_property (JsonSerializable *serializable
GParamSpec *pspec,
JsonNode *property_node);
+/**
+ * JsonBoxedSerializeFunc:
+ * @boxed: a #GBoxed
+ *
+ * Serializes the passed #GBoxed and stores it inside a #JsonNode
+ *
+ * Return value: the newly created #JsonNode
+ *
+ * Since: 0.10
+ */
+typedef JsonNode *(* JsonBoxedSerializeFunc) (gconstpointer boxed);
+
+/**
+ * JsonBoxedDeserializeFunc:
+ * @node: a #JsonNode
+ *
+ * Deserializes the contents of the passed #JsonNode into a #GBoxed
+ *
+ * Return value: the newly created boxed type
+ *
+ * Since: 0.10
+ */
+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);
GObject *json_construct_gobject (GType gtype,
const gchar *data,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 87f24ac..8209aa9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,9 +6,7 @@ NULL =
noinst_PROGRAMS = $(TEST_PROGS)
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/json-glib
-AM_CFLAGS = -g $(JSON_CFLAGS)
-AM_CPPFLAGS = $(JSON_DEBUG_CFLAGS)
-
+AM_CPPFLAGS = $(JSON_DEBUG_CFLAGS) $(JSON_CFLAGS) $(MAINTAINER_CFLAGS)
progs_ldadd = $(top_builddir)/json-glib/libjson-glib-1.0.la $(JSON_LIBS)
TESTS_ENVIRONMENT = srcdir=$(srcdir)
@@ -29,6 +27,10 @@ TEST_PROGS += test-serialize-complex
test_serialize_complex_SOURCES = test-serialize-complex.c
test_serialize_complex_LDADD = $(progs_ldadd)
+TEST_PROGS += test-serialize-boxed
+test_serialize_boxed_SOURCES = test-serialize-boxed.c
+test_serialize_boxed_LDADD = $(progs_ldadd)
+
TEST_PROGS += test-serialize-full
test_serialize_full_SOURCES = test-serialize-full.c
test_serialize_full_LDADD = $(progs_ldadd)
diff --git a/tests/test-serialize-boxed.c b/tests/test-serialize-boxed.c
new file mode 100644
index 0000000..d96acfd
--- /dev/null
+++ b/tests/test-serialize-boxed.c
@@ -0,0 +1,263 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <glib-object.h>
+
+#include <json-glib/json-glib.h>
+#include <json-glib/json-gobject.h>
+
+#define TEST_TYPE_BOXED (test_boxed_get_type ())
+#define TEST_TYPE_OBJECT (test_object_get_type ())
+#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
+#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
+#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
+#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
+#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
+
+typedef struct _TestBoxed TestBoxed;
+typedef struct _TestObject TestObject;
+typedef struct _TestObjectClass TestObjectClass;
+
+struct _TestBoxed
+{
+ gint foo;
+ gboolean bar;
+};
+
+struct _TestObject
+{
+ GObject parent_instance;
+
+ TestBoxed blah;
+};
+
+struct _TestObjectClass
+{
+ GObjectClass parent_class;
+};
+
+GType test_object_get_type (void);
+
+/*** implementation ***/
+
+static gpointer
+test_boxed_copy (gpointer src)
+{
+ return g_slice_dup (TestBoxed, src);
+}
+
+static void
+test_boxed_free (gpointer boxed)
+{
+ if (G_LIKELY (boxed != NULL))
+ g_slice_free (TestBoxed, boxed);
+}
+
+static JsonNode *
+test_boxed_serialize (gconstpointer boxed)
+{
+ const TestBoxed *test = boxed;
+ JsonObject *object;
+ JsonNode *node;
+
+ if (boxed == NULL)
+ return json_node_new (JSON_NODE_NULL);
+
+ object = json_object_new ();
+ node = json_node_new (JSON_NODE_OBJECT);
+
+ json_object_set_int_member (object, "foo", test->foo);
+ json_object_set_boolean_member (object, "bar", test->bar);
+
+ json_node_take_object (node, object);
+
+ if (g_test_verbose ())
+ {
+ g_print ("Serialize: { foo: %" G_GINT64_FORMAT ", bar: %s }\n",
+ json_object_get_int_member (object, "foo"),
+ json_object_get_boolean_member (object, "bar") ? "true" : "false");
+ }
+
+ return node;
+}
+
+static gpointer
+test_boxed_deserialize (JsonNode *node)
+{
+ JsonObject *object;
+ TestBoxed *test;
+
+ if (json_node_get_node_type (node) != JSON_NODE_OBJECT)
+ return NULL;
+
+ object = json_node_get_object (node);
+
+ test = g_slice_new (TestBoxed);
+ test->foo = json_object_get_int_member (object, "foo");
+ test->bar = json_object_get_boolean_member (object, "bar");
+
+ if (g_test_verbose ())
+ {
+ g_print ("Deserialize: { foo: %d, bar: %s }\n",
+ test->foo,
+ test->bar ? "true" : "false");
+ }
+
+ return test;
+}
+
+GType
+test_boxed_get_type (void)
+{
+ static GType b_type = 0;
+
+ if (G_UNLIKELY (b_type == 0))
+ {
+ b_type = g_boxed_type_register_static ("TestBoxed",
+ test_boxed_copy,
+ test_boxed_free);
+
+ 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);
+ }
+
+ return b_type;
+}
+
+enum
+{
+ PROP_0,
+
+ PROP_BLAH
+};
+
+G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
+
+static void
+test_object_finalize (GObject *gobject)
+{
+ G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
+}
+
+static void
+test_object_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_BLAH:
+ {
+ const TestBoxed *blah = g_value_get_boxed (value);
+
+ TEST_OBJECT (gobject)->blah = *blah;
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ }
+}
+
+static void
+test_object_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_BLAH:
+ g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ }
+}
+
+static void
+test_object_class_init (TestObjectClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = test_object_set_property;
+ gobject_class->get_property = test_object_get_property;
+ gobject_class->finalize = test_object_finalize;
+
+ g_object_class_install_property (gobject_class,
+ PROP_BLAH,
+ g_param_spec_boxed ("blah", "Blah", "Blah",
+ TEST_TYPE_BOXED,
+ G_PARAM_READWRITE));
+}
+
+static void
+test_object_init (TestObject *object)
+{
+ object->blah.foo = 0;
+ object->blah.bar = FALSE;
+}
+
+static const gchar *serialize_data =
+"{\n"
+" \"blah\" : {\n"
+" \"foo\" : 42,\n"
+" \"bar\" : true\n"
+" }\n"
+"}";
+
+static void
+test_serialize_boxed (void)
+{
+ TestBoxed boxed = { 42, TRUE };
+ GObject *obj;
+ gchar *data;
+ gsize len;
+
+ obj = g_object_new (TEST_TYPE_OBJECT, "blah", &boxed, NULL);
+
+ data = json_serialize_gobject (obj, &len);
+
+ g_assert_cmpint (len, ==, strlen (serialize_data));
+ g_assert_cmpstr (data, ==, serialize_data);
+
+ if (g_test_verbose ())
+ g_print ("TestObject:\n%s\n", data);
+
+ g_free (data);
+ g_object_unref (obj);
+}
+
+static void
+test_deserialize_boxed (void)
+{
+
+ GObject *obj;
+
+ obj = json_construct_gobject (TEST_TYPE_OBJECT, serialize_data, -1, NULL);
+ g_assert (TEST_IS_OBJECT (obj));
+ g_assert_cmpint (TEST_OBJECT (obj)->blah.foo, ==, 42);
+ g_assert (TEST_OBJECT (obj)->blah.bar);
+
+ g_object_unref (obj);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/boxed/serialize-property", test_serialize_boxed);
+ g_test_add_func ("/boxed/deserialize-property", test_deserialize_boxed);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]