diff options
author | Emmanuele Bassi <ebassi@openedhand.com> | 2007-10-02 12:11:55 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@openedhand.com> | 2007-10-02 12:11:55 +0100 |
commit | 3666613e47b66d67a28bc06c6dcf678fe97eae50 (patch) | |
tree | 5c6249da25e3de5ed6746fea0773666972640330 /json-glib/json-gobject.c | |
parent | 8398253c76cf5dda23891b49b1aaa49e57d95a8d (diff) | |
download | json-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.c | 169 |
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; +} |