summaryrefslogtreecommitdiff
path: root/json-glib/json-gobject.c
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@openedhand.com>2007-10-02 12:11:55 +0100
committerEmmanuele Bassi <ebassi@openedhand.com>2007-10-02 12:11:55 +0100
commit3666613e47b66d67a28bc06c6dcf678fe97eae50 (patch)
tree5c6249da25e3de5ed6746fea0773666972640330 /json-glib/json-gobject.c
parent8398253c76cf5dda23891b49b1aaa49e57d95a8d (diff)
downloadjson-glib-3666613e47b66d67a28bc06c6dcf678fe97eae50.tar.gz
Add GObject serialization support for JSON-GLib
This commit adds json-gobject.h and json_serialize_gobject() to JSON-GLib, to serialize a GObject instance into a JSON data stream.
Diffstat (limited to 'json-glib/json-gobject.c')
-rw-r--r--json-glib/json-gobject.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c
new file mode 100644
index 0000000..ee652aa
--- /dev/null
+++ b/json-glib/json-gobject.c
@@ -0,0 +1,169 @@
+/* json-gobject.h - JSON GObject integration
+ *
+ * This file is part of JSON-GLib
+ * Copyright (C) 2007 OpenedHand Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi@openedhand.com>
+ */
+
+/**
+ * SECTION:json-gobject
+ * @short_description: Serialize and deserialize GObjects
+ *
+ * JSON-GLib provides API for serializing and deserializing #GObject<!-- -->s
+ * to and from JSON data streams.
+ *
+ * The simplest form to serialize a #GObject class is calling the
+ * json_serialize_gobject() function on a #GObject instance: every
+ * property using a fundamental type (or a type that can be coherced
+ * into a fundamental type) will be converted into a JSON type.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "json-gobject.h"
+#include "json-parser.h"
+#include "json-generator.h"
+
+static JsonNode *
+json_serialize_pspec (GObject *gobject,
+ GParamSpec *pspec)
+{
+ JsonNode *retval = NULL;
+ GValue real_value = { 0, };
+ GValue value = { 0, };
+
+ g_value_init (&real_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_object_get_property (gobject, pspec->name, &real_value);
+
+ if (!G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (&real_value)))
+ {
+ g_warning ("Complex types are not supported.");
+ return NULL;
+ }
+
+ switch (G_VALUE_TYPE (&real_value))
+ {
+ case G_TYPE_INT:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_FLOAT:
+ /* JSON native types */
+ retval = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_VALUE_TYPE (&real_value));
+ g_value_copy (&real_value, &value);
+ json_node_set_value (retval, &value);
+ g_value_unset (&value);
+ break;
+
+ case G_TYPE_STRING:
+ /* strings might be NULL */
+ if (!g_value_get_string (&real_value))
+ retval = json_node_new (JSON_NODE_NULL);
+ else
+ {
+ retval = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, g_value_get_string (&real_value));
+ json_node_set_value (retval, &value);
+ g_value_unset (&value);
+ }
+ break;
+
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_ENUM:
+ case G_TYPE_FLAGS:
+ /* these should fit into an int */
+ retval = json_node_new (JSON_NODE_VALUE);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_copy (&real_value, &value);
+ json_node_set_value (retval, &value);
+ g_value_unset (&value);
+ break;
+
+ case G_TYPE_NONE:
+ retval = json_node_new (JSON_NODE_NULL);
+ break;
+
+ default:
+ g_warning ("Unsupported type `%s'",
+ g_type_name (G_VALUE_TYPE (&real_value)));
+ break;
+ }
+
+ g_value_unset (&real_value);
+
+ return retval;
+}
+
+/**
+ * json_serialize_gobject:
+ * @gobject: a #GObject
+ * @length: return value for the length of the buffer, or %NULL
+ *
+ * Serializes a #GObject into a JSON data stream.
+ *
+ * Return value: a JSON data stream representing the passed #GObject
+ */
+gchar *
+json_serialize_gobject (GObject *gobject,
+ gsize *length)
+{
+ JsonGenerator *gen;
+ JsonNode *root;
+ JsonObject *object;
+ GParamSpec **pspecs;
+ guint n_pspecs, i;
+ gchar *data;
+
+ g_return_val_if_fail (G_IS_OBJECT (gobject), NULL);
+
+ object = json_object_new ();
+
+ root = json_node_new (JSON_NODE_OBJECT);
+ json_node_take_object (root, object);
+
+ pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject),
+ &n_pspecs);
+
+ for (i = 0; i < n_pspecs; i++)
+ {
+ GParamSpec *pspec = pspecs[i];
+ JsonNode *value;
+
+ /* read only what we can */
+ if (!(pspec->flags & G_PARAM_READABLE))
+ continue;
+
+ value = json_serialize_pspec (gobject, pspec);
+ if (value)
+ json_object_add_member (object, pspec->name, value);
+ }
+
+ g_free (pspecs);
+
+ gen = json_generator_new ();
+ json_generator_set_root (gen, root);
+ g_object_set (gen, "pretty", TRUE, NULL);
+ data = json_generator_to_data (gen, length);
+ g_object_unref (gen);
+
+ return data;
+}