diff options
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/test-07.c | 265 |
2 files changed, 268 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index bb7a323..583135c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,7 +4,8 @@ noinst_PROGRAMS = \ test-03 \ test-04 \ test-05 \ - test-06 + test-06 \ + test-07 INCLUDES = -I$(top_srcdir) LDADD = $(top_builddir)/json-glib/libjson-glib-1.0.la @@ -18,3 +19,4 @@ test_03_SOURCES = test-03.c test_04_SOURCES = test-04.c test_05_SOURCES = test-05.c test_06_SOURCES = test-06.c +test_07_SOURCES = test-07.c diff --git a/tests/test-07.c b/tests/test-07.c new file mode 100644 index 0000000..fe5dafa --- /dev/null +++ b/tests/test-07.c @@ -0,0 +1,265 @@ +#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; + + gint foo; + gboolean bar; + gchar *baz; + TestBoxed blah; +}; + +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +GType test_object_get_type (void); + +/*** implementation ***/ + +static TestBoxed * +test_boxed_copy (const TestBoxed *src) +{ + TestBoxed *copy = g_slice_new (TestBoxed); + + *copy = *src; + + return copy; +} + +static void +test_boxed_free (TestBoxed *boxed) +{ + if (G_LIKELY (boxed)) + { + g_slice_free (TestBoxed, boxed); + } +} + +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", + (GBoxedCopyFunc) test_boxed_copy, + (GBoxedFreeFunc) test_boxed_free); + + return b_type; +} + +enum +{ + PROP_0, + + PROP_FOO, + PROP_BAR, + PROP_BAZ, + PROP_BLAH +}; + +static void json_serializable_iface_init (gpointer g_iface); + +G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE, + json_serializable_iface_init)); + +static JsonNode * +test_object_serialize_property (JsonSerializable *serializable, + const gchar *name, + const GValue *value, + GParamSpec *pspec) +{ + JsonNode *retval; + + if (strcmp (name, "blah") == 0) + { + TestBoxed *boxed; + JsonObject *obj; + JsonNode *val; + + retval = json_node_new (JSON_NODE_OBJECT); + obj = json_object_new (); + + boxed = g_value_get_boxed (value); + + val = json_node_new (JSON_NODE_VALUE); + json_node_set_int (val, boxed->foo); + json_object_add_member (obj, "foo", val); + + val = json_node_new (JSON_NODE_VALUE); + json_node_set_boolean (val, boxed->bar); + json_object_add_member (obj, "bar", val); + + json_node_take_object (retval, obj); + + test_boxed_free (boxed); + } + else + { + GValue copy = { 0, }; + + retval = json_node_new (JSON_NODE_VALUE); + + g_value_init (©, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_value_copy (value, ©); + json_node_set_value (retval, ©); + g_value_unset (©); + } + + return retval; +} + +static void +json_serializable_iface_init (gpointer g_iface) +{ + JsonSerializableIface *iface = g_iface; + + iface->serialize_property = test_object_serialize_property; +} + +static void +test_object_finalize (GObject *gobject) +{ + g_free (TEST_OBJECT (gobject)->baz); + + 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_FOO: + TEST_OBJECT (gobject)->foo = g_value_get_int (value); + break; + case PROP_BAR: + TEST_OBJECT (gobject)->bar = g_value_get_boolean (value); + break; + case PROP_BAZ: + g_free (TEST_OBJECT (gobject)->baz); + TEST_OBJECT (gobject)->baz = g_value_dup_string (value); + 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_FOO: + g_value_set_int (value, TEST_OBJECT (gobject)->foo); + break; + case PROP_BAR: + g_value_set_boolean (value, TEST_OBJECT (gobject)->bar); + break; + case PROP_BAZ: + g_value_set_string (value, TEST_OBJECT (gobject)->baz); + break; + 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_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + 0, G_MAXINT, 42, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAR, + g_param_spec_boolean ("bar", "Bar", "Bar", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAZ, + g_param_spec_string ("baz", "Baz", "Baz", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BLAH, + g_param_spec_boxed ("blah", "Blah", "Blah", + TEST_TYPE_BOXED, + G_PARAM_READABLE)); +} + +static void +test_object_init (TestObject *object) +{ + object->foo = 42; + object->bar = TRUE; + object->baz = g_strdup ("Test"); + + object->blah.foo = object->foo; + object->blah.bar = object->bar; +} + +int +main (int argc, char *argvp[]) +{ + TestObject *object; + gchar *data; + gsize len; + + g_type_init (); + + object = g_object_new (TEST_TYPE_OBJECT, NULL); + data = json_serialize_gobject (G_OBJECT (object), &len); + + g_print ("*** TestObject (len:%d) ***\n%s\n", len, data); + + g_free (data); + g_object_unref (object); + + return EXIT_SUCCESS; +} |