1 /* json-gobject.c - JSON GObject integration
3 * This file is part of JSON-GLib
4 * Copyright (C) 2007 OpenedHand Ltd.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
17 * Emmanuele Bassi <ebassi@openedhand.com>
21 * SECTION:json-gobject
22 * @short_description: Serialize and deserialize GObjects
24 * JSON-GLib provides API for serializing and deserializing #GObject
25 * instances to and from JSON data streams.
27 * Simple #GObject classes can be (de)serialized into JSON objects, if the
28 * properties have compatible types with the native JSON types (integers,
29 * booleans, strings, string vectors). If the class to be (de)serialized has
30 * complex data types for properties (like boxed types or other objects)
31 * then the class should implement the provided #JsonSerializable interface
32 * and its virtual functions.
40 #include <glib/gi18n-lib.h>
42 #include "json-types-private.h"
43 #include "json-gobject-private.h"
45 #include "json-debug.h"
46 #include "json-parser.h"
47 #include "json-generator.h"
50 enum_from_string (GType type,
58 gboolean retval = TRUE;
60 g_return_val_if_fail (G_TYPE_IS_ENUM (type), 0);
61 g_return_val_if_fail (string != NULL, 0);
63 value = strtoul (string, &endptr, 0);
64 if (endptr != string) /* parsed a number */
68 eclass = g_type_class_ref (type);
69 ev = g_enum_get_value_by_name (eclass, string);
71 ev = g_enum_get_value_by_nick (eclass, string);
74 *enum_value = ev->value;
78 g_type_class_unref (eclass);
85 flags_from_string (GType type,
90 gchar *endptr, *prevptr;
91 guint i, j, ret, value;
98 g_return_val_if_fail (G_TYPE_IS_FLAGS (type), 0);
99 g_return_val_if_fail (string != 0, 0);
103 value = strtoul (string, &endptr, 0);
104 if (endptr != string) /* parsed a number */
105 *flags_value = value;
108 fclass = g_type_class_ref (type);
110 flagstr = g_strdup (string);
111 for (value = i = j = 0; ; i++)
113 eos = flagstr[i] == '\0';
115 if (!eos && flagstr[i] != '|')
119 endptr = &flagstr[i];
130 ch = g_utf8_get_char (flag);
131 if (!g_unichar_isspace (ch))
133 flag = g_utf8_next_char (flag);
136 while (endptr > flag)
138 prevptr = g_utf8_prev_char (endptr);
139 ch = g_utf8_get_char (prevptr);
140 if (!g_unichar_isspace (ch))
148 fv = g_flags_get_value_by_name (fclass, flag);
151 fv = g_flags_get_value_by_nick (fclass, flag);
164 *flags_value = value;
171 g_type_class_unref (fclass);
178 json_gobject_new (GType gtype,
181 JsonSerializableIface *iface = NULL;
182 JsonSerializable *serializable = NULL;
183 gboolean find_property;
184 gboolean deserialize_property;
185 gboolean set_property;
186 GList *members, *members_left, *l;
190 GArray *construct_params;
193 klass = g_type_class_ref (gtype);
195 n_members = json_object_get_size (object);
196 members = json_object_get_members (object);
199 /* first pass: construct-only properties; here we cannot use Serializable
200 * because we don't have an instance yet; we use the default implementation
201 * of json_deserialize_pspec() to deserialize known types
203 * FIXME - find a way to allow deserialization for these properties
205 construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members);
207 for (l = members; l != NULL; l = l->next)
209 const gchar *member_name = l->data;
211 GParameter param = { NULL, };
213 gboolean res = FALSE;
215 pspec = g_object_class_find_property (klass, member_name);
219 /* we only apply construct-only properties here */
220 if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0)
223 if (!(pspec->flags & G_PARAM_WRITABLE))
226 g_value_init (¶m.value, G_PARAM_SPEC_VALUE_TYPE (pspec));
228 val = json_object_get_member (object, member_name);
229 res = json_deserialize_pspec (¶m.value, pspec, val);
232 g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
233 pspec->name, G_VALUE_TYPE_NAME (¶m.value), g_type_name (gtype));
235 g_value_unset (¶m.value);
239 param.name = g_strdup (pspec->name);
241 g_array_append_val (construct_params, param);
247 members_left = g_list_prepend (members_left, l->data);
250 retval = g_object_newv (gtype,
251 construct_params->len,
252 (GParameter *) construct_params->data);
254 /* free the contents of the GArray */
255 for (i = 0; i < construct_params->len; i++)
257 GParameter *param = &g_array_index (construct_params, GParameter, i);
259 g_free ((gchar *) param->name);
260 g_value_unset (¶m->value);
263 g_array_free (construct_params, TRUE);
264 g_list_free (members);
266 /* we use g_list_prepend() above, but we want to maintain
267 * the ordering of json_object_get_members() here
269 members = g_list_reverse (members_left);
271 /* do the Serializable type check once */
272 if (g_type_is_a (gtype, JSON_TYPE_SERIALIZABLE))
274 serializable = JSON_SERIALIZABLE (retval);
275 iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
276 find_property = (iface->find_property != NULL);
277 deserialize_property = (iface->deserialize_property != NULL);
278 set_property = (iface->set_property != NULL);
282 find_property = FALSE;
283 deserialize_property = FALSE;
284 set_property = FALSE;
287 g_object_freeze_notify (retval);
289 for (l = members; l != NULL; l = l->next)
291 const gchar *member_name = l->data;
294 GValue value = { 0, };
295 gboolean res = FALSE;
298 pspec = json_serializable_find_property (serializable, member_name);
300 pspec = g_object_class_find_property (klass, member_name);
305 /* we should have dealt with these above */
306 if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
309 if (!(pspec->flags & G_PARAM_WRITABLE))
312 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
314 val = json_object_get_member (object, member_name);
316 if (deserialize_property)
318 JSON_NOTE (GOBJECT, "Using JsonSerializable for property '%s'", pspec->name);
319 res = json_serializable_deserialize_property (serializable,
328 JSON_NOTE (GOBJECT, "Using json_deserialize_pspec for property '%s'", pspec->name);
329 res = json_deserialize_pspec (&value, pspec, val);
334 JSON_NOTE (GOBJECT, "Calling set_property('%s', '%s')",
336 g_type_name (G_VALUE_TYPE (&value)));
339 json_serializable_set_property (serializable, pspec, &value);
341 g_object_set_property (retval, pspec->name, &value);
344 g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
345 pspec->name, g_type_name (G_VALUE_TYPE (&value)), g_type_name (gtype));
347 g_value_unset (&value);
350 g_list_free (members);
352 g_object_thaw_notify (retval);
354 g_type_class_unref (klass);
360 json_gobject_dump (GObject *gobject)
362 JsonSerializableIface *iface = NULL;
363 JsonSerializable *serializable = NULL;
364 gboolean list_properties = FALSE;
365 gboolean serialize_property = FALSE;
366 gboolean get_property = FALSE;
371 if (JSON_IS_SERIALIZABLE (gobject))
373 serializable = JSON_SERIALIZABLE (gobject);
374 iface = JSON_SERIALIZABLE_GET_IFACE (gobject);
375 list_properties = (iface->list_properties != NULL);
376 serialize_property = (iface->serialize_property != NULL);
377 get_property = (iface->get_property != NULL);
380 object = json_object_new ();
383 pspecs = json_serializable_list_properties (serializable, &n_pspecs);
385 pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
387 for (i = 0; i < n_pspecs; i++)
389 GParamSpec *pspec = pspecs[i];
390 GValue value = { 0, };
391 JsonNode *node = NULL;
393 /* read only what we can */
394 if (!(pspec->flags & G_PARAM_READABLE))
397 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
400 json_serializable_get_property (serializable, pspec, &value);
402 g_object_get_property (gobject, pspec->name, &value);
404 /* if there is a serialization vfunc, then it is completely responsible
405 * for serializing the property, possibly by calling the implementation
406 * of the default JsonSerializable interface through chaining up
408 if (serialize_property)
410 node = json_serializable_serialize_property (serializable,
415 /* skip if the value is the default for the property */
416 else if (!g_param_value_defaults (pspec, &value))
417 node = json_serialize_pspec (&value, pspec);
420 json_object_set_member (object, pspec->name, node);
422 g_value_unset (&value);
431 json_deserialize_pspec (GValue *value,
435 GValue node_value = { 0, };
436 gboolean retval = FALSE;
438 if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOXED)
440 JsonNodeType node_type = json_node_get_node_type (node);
441 GType boxed_type = G_VALUE_TYPE (value);
443 if (json_boxed_can_deserialize (boxed_type, node_type))
445 gpointer boxed = json_boxed_deserialize (boxed_type, node);
447 g_value_take_boxed (value, boxed);
453 switch (JSON_NODE_TYPE (node))
455 case JSON_NODE_OBJECT:
456 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT))
460 object = json_gobject_new (G_VALUE_TYPE (value), json_node_get_object (node));
462 g_value_take_object (value, object);
464 g_value_set_object (value, NULL);
470 case JSON_NODE_ARRAY:
471 if (G_VALUE_HOLDS (value, G_TYPE_STRV))
473 JsonArray *array = json_node_get_array (node);
474 guint i, array_len = json_array_get_length (array);
475 GPtrArray *str_array = g_ptr_array_sized_new (array_len + 1);
477 for (i = 0; i < array_len; i++)
479 JsonNode *val = json_array_get_element (array, i);
481 if (JSON_NODE_TYPE (val) != JSON_NODE_VALUE)
484 if (json_node_get_string (val) != NULL)
485 g_ptr_array_add (str_array, (gpointer) json_node_get_string (val));
488 g_ptr_array_add (str_array, NULL);
490 g_value_set_boxed (value, str_array->pdata);
492 g_ptr_array_free (str_array, TRUE);
498 case JSON_NODE_VALUE:
499 json_node_get_value (node, &node_value);
502 gchar *node_str = g_strdup_value_contents (&node_value);
503 g_debug ("%s: value type '%s' := node value type '%s' -> '%s'",
505 g_type_name (G_VALUE_TYPE (value)),
506 g_type_name (G_VALUE_TYPE (&node_value)),
512 switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
517 if (G_VALUE_HOLDS (&node_value, G_VALUE_TYPE (value)))
519 g_value_copy (&node_value, value);
525 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
527 g_value_set_int (value, (gint) g_value_get_int64 (&node_value));
533 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
535 g_value_set_schar (value, (gchar) g_value_get_int64 (&node_value));
541 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
543 g_value_set_uint (value, (guint) g_value_get_int64 (&node_value));
549 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
551 g_value_set_uchar (value, (guchar) g_value_get_int64 (&node_value));
557 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
559 g_value_set_long (value, (glong) g_value_get_int64 (&node_value));
565 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
567 g_value_set_ulong (value, (gulong) g_value_get_int64 (&node_value));
573 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
575 g_value_set_uint64 (value, (guint64) g_value_get_int64 (&node_value));
582 if (G_VALUE_HOLDS (&node_value, G_TYPE_DOUBLE))
584 g_value_set_double (value, g_value_get_double (&node_value));
587 else if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
589 g_value_set_double (value, (gdouble) g_value_get_int64 (&node_value));
596 if (G_VALUE_HOLDS (&node_value, G_TYPE_DOUBLE))
598 g_value_set_float (value, (gfloat) g_value_get_double (&node_value));
601 else if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
603 g_value_set_float (value, (gfloat) g_value_get_int64 (&node_value));
613 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
615 enum_value = g_value_get_int64 (&node_value);
618 else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
620 retval = enum_from_string (G_VALUE_TYPE (value),
621 g_value_get_string (&node_value),
626 g_value_set_enum (value, enum_value);
632 gint flags_value = 0;
634 if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
636 flags_value = g_value_get_int64 (&node_value);
639 else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
641 retval = flags_from_string (G_VALUE_TYPE (value),
642 g_value_get_string (&node_value),
647 g_value_set_flags (value, flags_value);
656 g_value_unset (&node_value);
660 if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING)
662 g_value_set_string (value, NULL);
665 else if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_OBJECT)
667 g_value_set_object (value, NULL);
680 json_serialize_pspec (const GValue *real_value,
683 JsonNode *retval = NULL;
684 JsonNodeType node_type;
686 switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value)))
688 /* JSON native types */
690 retval = json_node_init_int (json_node_alloc (), g_value_get_int64 (real_value));
694 retval = json_node_init_boolean (json_node_alloc (), g_value_get_boolean (real_value));
698 retval = json_node_init_double (json_node_alloc (), g_value_get_double (real_value));
702 retval = json_node_init_string (json_node_alloc (), g_value_get_string (real_value));
705 /* auto-promoted types */
707 retval = json_node_init_int (json_node_alloc (), g_value_get_int (real_value));
711 retval = json_node_init_int (json_node_alloc (), g_value_get_uint (real_value));
715 retval = json_node_init_int (json_node_alloc (), g_value_get_long (real_value));
719 retval = json_node_init_int (json_node_alloc (), g_value_get_ulong (real_value));
723 retval = json_node_init_int (json_node_alloc (), g_value_get_uint64 (real_value));
727 retval = json_node_init_double (json_node_alloc (), g_value_get_float (real_value));
731 retval = json_node_alloc ();
732 json_node_init_int (retval, g_value_get_schar (real_value));
736 retval = json_node_init_int (json_node_alloc (), g_value_get_uchar (real_value));
740 retval = json_node_init_int (json_node_alloc (), g_value_get_enum (real_value));
744 retval = json_node_init_int (json_node_alloc (), g_value_get_flags (real_value));
749 if (G_VALUE_HOLDS (real_value, G_TYPE_STRV))
751 gchar **strv = g_value_get_boxed (real_value);
755 strv_len = g_strv_length (strv);
756 array = json_array_sized_new (strv_len);
758 for (i = 0; i < strv_len; i++)
760 JsonNode *str = json_node_new (JSON_NODE_VALUE);
762 json_node_set_string (str, strv[i]);
763 json_array_add_element (array, str);
766 retval = json_node_init_array (json_node_alloc (), array);
767 json_array_unref (array);
769 else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type))
771 gpointer boxed = g_value_get_boxed (real_value);
773 retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed);
776 g_warning ("Boxed type '%s' is not handled by JSON-GLib",
777 g_type_name (G_VALUE_TYPE (real_value)));
782 GObject *object = g_value_get_object (real_value);
784 retval = json_node_alloc ();
788 json_node_init (retval, JSON_NODE_OBJECT);
789 json_node_take_object (retval, json_gobject_dump (object));
792 json_node_init_null (retval);
797 retval = json_node_new (JSON_NODE_NULL);
801 g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value)));
809 * json_gobject_deserialize:
810 * @gtype: the type of the #GObject to create
811 * @node: a #JsonNode of type %JSON_NODE_OBJECT describing the
812 * instance of type @gtype
814 * Creates a new #GObject of type @gtype, and constructs it
815 * using the members of the passed #JsonObject
817 * Return value: (transfer full): The newly created #GObject
818 * instance. Use g_object_unref() to free the resources
819 * allocated by this function
824 json_gobject_deserialize (GType gtype,
827 g_return_val_if_fail (g_type_is_a (gtype, G_TYPE_OBJECT), NULL);
828 g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
830 return json_gobject_new (gtype, json_node_get_object (node));
834 * json_gobject_serialize:
835 * @gobject: a #GObject
837 * Creates a #JsonNode representing the passed #GObject
838 * instance. Each member of the returned JSON object will
839 * map to a property of the #GObject
841 * Return value: (transfer full): the newly created #JsonNode
842 * of type %JSON_NODE_OBJECT. Use json_node_unref() to free
843 * the resources allocated by this function
848 json_gobject_serialize (GObject *gobject)
852 g_return_val_if_fail (G_IS_OBJECT (gobject), NULL);
854 retval = json_node_new (JSON_NODE_OBJECT);
855 json_node_take_object (retval, json_gobject_dump (gobject));
861 * json_construct_gobject:
862 * @gtype: the #GType of object to construct
863 * @data: a JSON data stream
864 * @length: length of the data stream
865 * @error: return location for a #GError, or %NULL
867 * Deserializes a JSON data stream and creates the corresponding
868 * #GObject class. If @gtype implements the #JsonSerializableIface
869 * interface, it will be asked to deserialize all the JSON members
870 * into the respective properties; otherwise, the default implementation
871 * will be used to translate the compatible JSON native types.
873 * Note: the JSON data stream must be an object declaration.
875 * Return value: (transfer full): a #GObject or %NULL
879 * Deprecated: 0.10: Use json_gobject_from_data() instead
882 json_construct_gobject (GType gtype,
887 return json_gobject_from_data (gtype, data, strlen (data), error);
891 * json_gobject_from_data:
892 * @gtype: the #GType of object to construct
893 * @data: a JSON data stream
894 * @length: length of the data stream, or -1 if it is NUL-terminated
895 * @error: return location for a #GError, or %NULL
897 * Deserializes a JSON data stream and creates the corresponding
898 * #GObject class. If @gtype implements the #JsonSerializableIface
899 * interface, it will be asked to deserialize all the JSON members
900 * into the respective properties; otherwise, the default implementation
901 * will be used to translate the compatible JSON native types.
903 * Note: the JSON data stream must be an object declaration.
905 * Return value: (transfer full): a #GObject or %NULL
910 json_gobject_from_data (GType gtype,
920 g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
921 g_return_val_if_fail (data != NULL, NULL);
924 length = strlen (data);
926 parser = json_parser_new ();
929 json_parser_load_from_data (parser, data, length, &parse_error);
932 g_propagate_error (error, parse_error);
933 g_object_unref (parser);
937 root = json_parser_get_root (parser);
938 if (root == NULL || JSON_NODE_TYPE (root) != JSON_NODE_OBJECT)
940 g_set_error (error, JSON_PARSER_ERROR,
941 JSON_PARSER_ERROR_PARSE,
942 /* translators: the %s is the name of the data structure */
943 _("Expecting a JSON object, but the root node is of type `%s'"),
944 json_node_type_name (root));
945 g_object_unref (parser);
949 retval = json_gobject_deserialize (gtype, root);
951 g_object_unref (parser);
957 * json_serialize_gobject:
958 * @gobject: a #GObject
959 * @length: (out): return value for the length of the buffer, or %NULL
961 * Serializes a #GObject into a JSON data stream. If @gobject implements
962 * the #JsonSerializableIface interface, it will be asked to serizalize all
963 * its properties; otherwise, the default implementation will be use to
964 * translate the compatible types into JSON native types.
966 * Return value: a JSON data stream representing the passed #GObject
968 * Deprecated: 0.10: Use json_gobject_to_data() instead
971 json_serialize_gobject (GObject *gobject,
974 return json_gobject_to_data (gobject, length);
978 * json_gobject_to_data:
979 * @gobject: a #GObject
980 * @length: (out): return value for the length of the buffer, or %NULL
982 * Serializes a #GObject into a JSON data stream, iterating recursively
983 * over each property.
985 * If @gobject implements the #JsonSerializableIface interface, it will
986 * be asked to serialize all its properties; otherwise, the default
987 * implementation will be use to translate the compatible types into
990 * Return value: a JSON data stream representing the passed #GObject
995 json_gobject_to_data (GObject *gobject,
1002 g_return_val_if_fail (G_OBJECT (gobject), NULL);
1004 root = json_gobject_serialize (gobject);
1006 gen = g_object_new (JSON_TYPE_GENERATOR,
1012 data = json_generator_to_data (gen, length);
1013 g_object_unref (gen);
1015 json_node_unref (root);