Initial Import
[profile/ivi/json-glib.git] / json-glib / json-serializable.c
1 /* json-gobject.c - JSON GObject integration
2  * 
3  * This file is part of JSON-GLib
4  * Copyright (C) 2007  OpenedHand Ltd.
5  *
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.
10  *
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.
15  *
16  * Author:
17  *   Emmanuele Bassi  <ebassi@openedhand.com>
18  */
19
20 /**
21  * SECTION:json-serializable
22  * @short_description: Interface for serialize and deserialize special GObjects
23  *
24  * #JsonSerializable is an interface for #GObject classes that
25  * allows controlling how the class is going to be serialized
26  * or deserialized by json_construct_gobject() and
27  * json_serialize_gobject() respectively.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <string.h>
35 #include <stdlib.h>
36
37 #include "json-types-private.h"
38 #include "json-gobject-private.h"
39 #include "json-debug.h"
40
41 /**
42  * json_serializable_serialize_property:
43  * @serializable: a #JsonSerializable object
44  * @property_name: the name of the property
45  * @value: the value of the property
46  * @pspec: a #GParamSpec
47  *
48  * Asks a #JsonSerializable implementation to serialize a #GObject
49  * property into a #JsonNode object.
50  *
51  * Return value: a #JsonNode containing the serialized property
52  */
53 JsonNode *
54 json_serializable_serialize_property (JsonSerializable *serializable,
55                                       const gchar      *property_name,
56                                       const GValue     *value,
57                                       GParamSpec       *pspec)
58 {
59   JsonSerializableIface *iface;
60
61   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
62   g_return_val_if_fail (property_name != NULL, NULL);
63   g_return_val_if_fail (value != NULL, NULL);
64   g_return_val_if_fail (pspec != NULL, NULL);
65
66   iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
67
68   return iface->serialize_property (serializable, property_name, value, pspec);
69 }
70
71 /**
72  * json_serializable_deserialize_property:
73  * @serializable: a #JsonSerializable
74  * @property_name: the name of the property
75  * @value: (out): a pointer to an uninitialized #GValue
76  * @pspec: a #GParamSpec
77  * @property_node: a #JsonNode containing the serialized property
78  *
79  * Asks a #JsonSerializable implementation to deserialize the
80  * property contained inside @property_node into @value.
81  *
82  * Return value: %TRUE if the property was successfully deserialized.
83  */
84 gboolean
85 json_serializable_deserialize_property (JsonSerializable *serializable,
86                                         const gchar      *property_name,
87                                         GValue           *value,
88                                         GParamSpec       *pspec,
89                                         JsonNode         *property_node)
90 {
91   JsonSerializableIface *iface;
92
93   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE);
94   g_return_val_if_fail (property_name != NULL, FALSE);
95   g_return_val_if_fail (value != NULL, FALSE);
96   g_return_val_if_fail (pspec != NULL, FALSE);
97   g_return_val_if_fail (property_node != NULL, FALSE);
98
99   iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
100
101   return iface->deserialize_property (serializable,
102                                       property_name,
103                                       value,
104                                       pspec,
105                                       property_node);
106 }
107
108 static gboolean
109 json_serializable_real_deserialize (JsonSerializable *serializable,
110                                     const gchar      *name,
111                                     GValue           *value,
112                                     GParamSpec       *pspec,
113                                     JsonNode         *node)
114 {
115   JSON_NOTE (GOBJECT, "Default deserialization for property '%s'", pspec->name);
116   return json_deserialize_pspec (value, pspec, node);
117 }
118
119 static JsonNode *
120 json_serializable_real_serialize (JsonSerializable *serializable,
121                                   const gchar      *name,
122                                   const GValue     *value,
123                                   GParamSpec       *pspec)
124 {
125   JSON_NOTE (GOBJECT, "Default serialization for property '%s'", pspec->name);
126
127   if (g_param_value_defaults (pspec, (GValue *)value))
128     return NULL;
129
130   return json_serialize_pspec (value, pspec);
131 }
132
133 static GParamSpec *
134 json_serializable_real_find_property (JsonSerializable *serializable,
135                                       const char       *name)
136 {
137   return g_object_class_find_property (G_OBJECT_GET_CLASS (serializable), name);
138 }
139
140 static GParamSpec **
141 json_serializable_real_list_properties (JsonSerializable *serializable,
142                                         guint            *n_pspecs)
143 {
144   return g_object_class_list_properties (G_OBJECT_GET_CLASS (serializable), n_pspecs);
145 }
146
147 static void
148 json_serializable_real_set_property (JsonSerializable *serializable,
149                                      GParamSpec       *pspec,
150                                      const GValue     *value)
151 {
152   g_object_set_property (G_OBJECT (serializable), pspec->name, value);
153 }
154
155 static void
156 json_serializable_real_get_property (JsonSerializable *serializable,
157                                      GParamSpec       *pspec,
158                                      GValue           *value)
159 {
160   g_object_get_property (G_OBJECT (serializable), pspec->name, value);
161 }
162
163 /* typedef to satisfy G_DEFINE_INTERFACE's naming */
164 typedef JsonSerializableIface   JsonSerializableInterface;
165
166 static void
167 json_serializable_default_init (JsonSerializableInterface *iface)
168 {
169   iface->serialize_property = json_serializable_real_serialize;
170   iface->deserialize_property = json_serializable_real_deserialize;
171   iface->find_property = json_serializable_real_find_property;
172   iface->list_properties = json_serializable_real_list_properties;
173   iface->set_property = json_serializable_real_set_property;
174   iface->get_property = json_serializable_real_get_property;
175 }
176
177 G_DEFINE_INTERFACE (JsonSerializable, json_serializable, G_TYPE_OBJECT);
178
179 /**
180  * json_serializable_default_serialize_property:
181  * @serializable: a #JsonSerializable object
182  * @property_name: the name of the property
183  * @value: the value of the property
184  * @pspec: a #GParamSpec
185  *
186  * Calls the default implementation of the #JsonSerializable
187  * serialize_property() virtual function
188  *
189  * This function can be used inside a custom implementation
190  * of the serialize_property() virtual function in lieu of:
191  *
192  * |[
193  *   JsonSerializable *iface;
194  *   JsonNode *node;
195  *
196  *   iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
197  *   node = iface->serialize_property (serializable, property_name,
198  *                                     value,
199  *                                     pspec);
200  * ]|
201  *
202  * Return value: (transfer full): a #JsonNode containing the serialized
203  *   property
204  *
205  * Since: 0.10
206  */
207 JsonNode *
208 json_serializable_default_serialize_property (JsonSerializable *serializable,
209                                               const gchar      *property_name,
210                                               const GValue     *value,
211                                               GParamSpec       *pspec)
212 {
213   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
214   g_return_val_if_fail (property_name != NULL, NULL);
215   g_return_val_if_fail (value != NULL, NULL);
216   g_return_val_if_fail (pspec != NULL, NULL);
217
218   return json_serializable_real_serialize (serializable,
219                                            property_name,
220                                            value, pspec);
221 }
222
223 /**
224  * json_serializable_default_deserialize_property:
225  * @serializable: a #JsonSerializable
226  * @property_name: the name of the property
227  * @value: a pointer to an uninitialized #GValue
228  * @pspec: a #GParamSpec
229  * @property_node: a #JsonNode containing the serialized property
230  *
231  * Calls the default implementation of the #JsonSerializable
232  * deserialize_property() virtual function
233  *
234  * This function can be used inside a custom implementation
235  * of the deserialize_property() virtual function in lieu of:
236  *
237  * |[
238  *   JsonSerializable *iface;
239  *   gboolean res;
240  *
241  *   iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
242  *   res = iface->deserialize_property (serializable, property_name,
243  *                                      value,
244  *                                      pspec,
245  *                                      property_node);
246  * ]|
247  *
248  * Return value: %TRUE if the property was successfully deserialized.
249  *
250  * Since: 0.10
251  */
252 gboolean
253 json_serializable_default_deserialize_property (JsonSerializable *serializable,
254                                                 const gchar      *property_name,
255                                                 GValue           *value,
256                                                 GParamSpec       *pspec,
257                                                 JsonNode         *property_node)
258 {
259   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE);
260   g_return_val_if_fail (property_name != NULL, FALSE);
261   g_return_val_if_fail (value != NULL, FALSE);
262   g_return_val_if_fail (pspec != NULL, FALSE);
263   g_return_val_if_fail (property_node != NULL, FALSE);
264
265   return json_serializable_real_deserialize (serializable,
266                                              property_name,
267                                              value, pspec,
268                                              property_node);
269 }
270
271 /**
272  * json_serializable_find_property:
273  * @serializable: a #JsonSerializable
274  * @name: the name of the property
275  *
276  * FIXME
277  *
278  * Return value: (transfer none): the #GParamSpec for the property
279  *   or %NULL if no property was found
280  *
281  * Since: 0.14
282  */
283 GParamSpec *
284 json_serializable_find_property (JsonSerializable *serializable,
285                                  const char       *name)
286 {
287   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
288   g_return_val_if_fail (name != NULL, NULL);
289
290   return JSON_SERIALIZABLE_GET_IFACE (serializable)->find_property (serializable, name);
291 }
292
293 /**
294  * json_serializable_list_properties:
295  * @serializable: a #JsonSerializable
296  * @n_pspecs: (out): return location for the length of the array
297  *   of #GParamSpec returned by the function
298  *
299  * FIXME
300  *
301  * Return value: (array length=n_pspecs) (transfer container): an array
302  *   of #GParamSpec. Use g_free() to free the array when done.
303  *
304  * Since: 0.14
305  */
306 GParamSpec **
307 json_serializable_list_properties (JsonSerializable *serializable,
308                                    guint            *n_pspecs)
309 {
310   g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
311
312   return JSON_SERIALIZABLE_GET_IFACE (serializable)->list_properties (serializable, n_pspecs);
313 }
314
315 void
316 json_serializable_set_property (JsonSerializable *serializable,
317                                 GParamSpec       *pspec,
318                                 const GValue     *value)
319 {
320   g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
321   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
322   g_return_if_fail (value != NULL);
323
324   JSON_SERIALIZABLE_GET_IFACE (serializable)->set_property (serializable,
325                                                             pspec,
326                                                             value);
327 }
328
329 void
330 json_serializable_get_property (JsonSerializable *serializable,
331                                 GParamSpec       *pspec,
332                                 GValue           *value)
333 {
334   g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
335   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
336   g_return_if_fail (value != NULL);
337
338   JSON_SERIALIZABLE_GET_IFACE (serializable)->get_property (serializable,
339                                                             pspec,
340                                                             value);
341 }