Start merging gdbus-codegen code
[platform/upstream/glib.git] / gio / gdbusinterface.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include "gdbusobject.h"
26 #include "gdbusinterface.h"
27 #include "gio-marshal.h"
28
29 #include "glibintl.h"
30
31 /**
32  * SECTION:gdbusinterface
33  * @short_description: Base type for D-Bus interfaces
34  * @include: gio/gio.h
35  *
36  * The #GDBusInterface type is the base type for D-Bus interfaces both
37  * on the service side (see #GDBusInterfaceStub) and client side (see
38  * #GDBusProxy).
39  */
40
41 typedef GDBusInterfaceIface GDBusInterfaceInterface;
42 G_DEFINE_INTERFACE (GDBusInterface, g_dbus_interface, G_TYPE_OBJECT)
43
44 static void
45 g_dbus_interface_default_init (GDBusInterfaceIface *iface)
46 {
47 }
48
49 /* ---------------------------------------------------------------------------------------------------- */
50
51 /**
52  * g_dbus_interface_get_info:
53  * @interface: An exported D-Bus interface.
54  *
55  * Gets D-Bus introspection information for the D-Bus interface
56  * implemented by @interface.
57  *
58  * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
59  */
60 GDBusInterfaceInfo *
61 g_dbus_interface_get_info (GDBusInterface *interface)
62 {
63   g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
64   return G_DBUS_INTERFACE_GET_IFACE (interface)->get_info (interface);
65 }
66
67 /**
68  * g_dbus_interface_get_object:
69  * @interface: An exported D-Bus interface.
70  *
71  * Gets the #GDBusObject that @interface belongs to, if any.
72  *
73  * Returns: (transfer none): A #GDBusObject or %NULL. The returned
74  * reference belongs to @interface and should not be freed.
75  */
76 GDBusObject *
77 g_dbus_interface_get_object (GDBusInterface *interface)
78 {
79   g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
80   return G_DBUS_INTERFACE_GET_IFACE (interface)->get_object (interface);
81 }
82
83 /**
84  * g_dbus_interface_set_object:
85  * @interface: An exported D-Bus interface.
86  * @object: A #GDBusObject or %NULL.
87  *
88  * Sets the #GDBusObject for @interface to @object.
89  *
90  * Note that @interface will hold a weak reference to @object.
91  */
92 void
93 g_dbus_interface_set_object (GDBusInterface    *interface,
94                              GDBusObject       *object)
95 {
96   g_return_if_fail (G_IS_DBUS_INTERFACE (interface));
97   g_return_if_fail (object == NULL || G_IS_DBUS_OBJECT (object));
98   G_DBUS_INTERFACE_GET_IFACE (interface)->set_object (interface, object);
99 }
100
101 /* Keep it here for now. TODO: move */
102
103 #include <string.h>
104
105 /**
106  * g_dbus_gvariant_to_gvalue:
107  * @value: A #GVariant.
108  * @out_gvalue: Return location for the #GValue.
109  *
110  * Convert a #GVariant to a #GValue. If @value is floating, it is consumed.
111  *
112  * Note that the passed @out_gvalue does not have to have a #GType set.
113  *
114  * Returns: %TRUE if the conversion succeeded, %FALSE otherwise.
115  */
116 gboolean
117 g_dbus_gvariant_to_gvalue (GVariant             *value,
118                            GValue               *out_gvalue)
119 {
120   gboolean ret;
121   const GVariantType *type;
122   gchar **array;
123
124   g_return_val_if_fail (value != NULL, FALSE);
125   g_return_val_if_fail (out_gvalue != NULL, FALSE);
126
127   ret = FALSE;
128
129   memset (out_gvalue, '\0', sizeof (GValue));
130
131   switch (g_variant_classify (value))
132     {
133     case G_VARIANT_CLASS_BOOLEAN:
134       g_value_init (out_gvalue, G_TYPE_BOOLEAN);
135       g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
136       break;
137
138     case G_VARIANT_CLASS_BYTE:
139       g_value_init (out_gvalue, G_TYPE_UCHAR);
140       g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
141       break;
142
143     case G_VARIANT_CLASS_INT16:
144       g_value_init (out_gvalue, G_TYPE_INT);
145       g_value_set_int (out_gvalue, g_variant_get_int16 (value));
146       break;
147
148     case G_VARIANT_CLASS_UINT16:
149       g_value_init (out_gvalue, G_TYPE_UINT);
150       g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
151       break;
152
153     case G_VARIANT_CLASS_INT32:
154       g_value_init (out_gvalue, G_TYPE_INT);
155       g_value_set_int (out_gvalue, g_variant_get_int32 (value));
156       break;
157
158     case G_VARIANT_CLASS_UINT32:
159       g_value_init (out_gvalue, G_TYPE_UINT);
160       g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
161       break;
162
163     case G_VARIANT_CLASS_INT64:
164       g_value_init (out_gvalue, G_TYPE_INT64);
165       g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
166       break;
167
168     case G_VARIANT_CLASS_UINT64:
169       g_value_init (out_gvalue, G_TYPE_UINT64);
170       g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
171       break;
172
173     case G_VARIANT_CLASS_HANDLE:
174       g_value_init (out_gvalue, G_TYPE_INT);
175       g_value_set_int (out_gvalue, g_variant_get_int32 (value));
176       break;
177
178     case G_VARIANT_CLASS_DOUBLE:
179       g_value_init (out_gvalue, G_TYPE_DOUBLE);
180       g_value_set_double (out_gvalue, g_variant_get_double (value));
181       break;
182
183     case G_VARIANT_CLASS_STRING:
184       g_value_init (out_gvalue, G_TYPE_STRING);
185       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
186       break;
187
188     case G_VARIANT_CLASS_OBJECT_PATH:
189       g_value_init (out_gvalue, G_TYPE_STRING);
190       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
191       break;
192
193     case G_VARIANT_CLASS_SIGNATURE:
194       g_value_init (out_gvalue, G_TYPE_STRING);
195       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
196       break;
197
198     case G_VARIANT_CLASS_ARRAY:
199       type = g_variant_get_type (value);
200       switch (g_variant_type_peek_string (type)[1])
201         {
202         case G_VARIANT_CLASS_BYTE:
203           g_value_init (out_gvalue, G_TYPE_STRING);
204           g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
205           break;
206
207         case G_VARIANT_CLASS_STRING:
208           g_value_init (out_gvalue, G_TYPE_STRV);
209           array = g_variant_dup_strv (value, NULL);
210           g_value_take_boxed (out_gvalue, array);
211           break;
212
213         case G_VARIANT_CLASS_ARRAY:
214           switch (g_variant_type_peek_string (type)[2])
215             {
216             case G_VARIANT_CLASS_BYTE:
217               g_value_init (out_gvalue, G_TYPE_STRV);
218               array = g_variant_dup_bytestring_array (value, NULL);
219               g_value_take_boxed (out_gvalue, array);
220               break;
221
222             default:
223               g_value_init (out_gvalue, G_TYPE_VARIANT);
224               g_value_set_variant (out_gvalue, value);
225               break;
226             }
227           break;
228
229         default:
230           g_value_init (out_gvalue, G_TYPE_VARIANT);
231           g_value_set_variant (out_gvalue, value);
232           break;
233         }
234       break;
235
236     case G_VARIANT_CLASS_VARIANT:
237     case G_VARIANT_CLASS_MAYBE:
238     case G_VARIANT_CLASS_TUPLE:
239     case G_VARIANT_CLASS_DICT_ENTRY:
240       g_value_init (out_gvalue, G_TYPE_VARIANT);
241       g_value_set_variant (out_gvalue, value);
242       break;
243     }
244
245   ret = TRUE;
246
247   return ret;
248 }
249
250
251 /**
252  * g_dbus_gvalue_to_gvariant:
253  * @gvalue: A #GValue to convert to a #GVariant.
254  * @expected_type: The #GVariantType to create.
255  *
256  * Convert a #GValue to #GVariant.
257  *
258  * Returns: A #GVariant (never floating) holding the data from @gvalue
259  * or %NULL in case of error. Free with g_variant_unref().
260  */
261 GVariant *
262 g_dbus_gvalue_to_gvariant (const GValue         *gvalue,
263                            const GVariantType   *expected_type)
264 {
265   GVariant *ret;
266   const gchar *s;
267   const gchar * const *as;
268   const gchar *empty_strv[1] = {NULL};
269
270   g_return_val_if_fail (gvalue != NULL, NULL);
271   g_return_val_if_fail (expected_type != NULL, NULL);
272
273   ret = NULL;
274
275   /* The expected type could easily be e.g. "s" with the GValue holding a string.
276    * because of the UseGVariant annotation
277    */
278   if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
279     {
280       ret = g_value_dup_variant (gvalue);
281     }
282   else
283     {
284       switch (g_variant_type_peek_string (expected_type)[0])
285         {
286         case G_VARIANT_CLASS_BOOLEAN:
287           ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
288           break;
289
290         case G_VARIANT_CLASS_BYTE:
291           ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
292           break;
293
294         case G_VARIANT_CLASS_INT16:
295           ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
296           break;
297
298         case G_VARIANT_CLASS_UINT16:
299           ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
300           break;
301
302         case G_VARIANT_CLASS_INT32:
303           ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
304           break;
305
306         case G_VARIANT_CLASS_UINT32:
307           ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
308           break;
309
310         case G_VARIANT_CLASS_INT64:
311           ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
312           break;
313
314         case G_VARIANT_CLASS_UINT64:
315           ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
316           break;
317
318         case G_VARIANT_CLASS_HANDLE:
319           ret = g_variant_ref_sink (g_variant_new_handle (g_value_get_int (gvalue)));
320           break;
321
322         case G_VARIANT_CLASS_DOUBLE:
323           ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
324           break;
325
326         case G_VARIANT_CLASS_STRING:
327           s = g_value_get_string (gvalue);
328           if (s == NULL)
329             s = "";
330           ret = g_variant_ref_sink (g_variant_new_string (s));
331           break;
332
333         case G_VARIANT_CLASS_OBJECT_PATH:
334           s = g_value_get_string (gvalue);
335           if (s == NULL)
336             s = "/";
337           ret = g_variant_ref_sink (g_variant_new_object_path (s));
338           break;
339
340         case G_VARIANT_CLASS_SIGNATURE:
341           s = g_value_get_string (gvalue);
342           if (s == NULL)
343             s = "";
344           ret = g_variant_ref_sink (g_variant_new_signature (s));
345           break;
346
347         case G_VARIANT_CLASS_ARRAY:
348           switch (g_variant_type_peek_string (expected_type)[1])
349             {
350             case G_VARIANT_CLASS_BYTE:
351               s = g_value_get_string (gvalue);
352               if (s == NULL)
353                 s = "";
354               ret = g_variant_ref_sink (g_variant_new_bytestring (s));
355               break;
356
357             case G_VARIANT_CLASS_STRING:
358               as = g_value_get_boxed (gvalue);
359               if (as == NULL)
360                 as = empty_strv;
361               ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
362               break;
363
364             case G_VARIANT_CLASS_ARRAY:
365               switch (g_variant_type_peek_string (expected_type)[2])
366                 {
367                 case G_VARIANT_CLASS_BYTE:
368                   as = g_value_get_boxed (gvalue);
369                   if (as == NULL)
370                     as = empty_strv;
371                   ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
372                   break;
373
374                 default:
375                   ret = g_value_dup_variant (gvalue);
376                   break;
377                 }
378               break;
379
380             default:
381               ret = g_value_dup_variant (gvalue);
382               break;
383             }
384           break;
385
386         default:
387         case G_VARIANT_CLASS_VARIANT:
388         case G_VARIANT_CLASS_MAYBE:
389         case G_VARIANT_CLASS_TUPLE:
390         case G_VARIANT_CLASS_DICT_ENTRY:
391           ret = g_value_dup_variant (gvalue);
392           break;
393         }
394     }
395
396   /* Could be that the GValue is holding a NULL GVariant - in that case,
397    * we return an "empty" GVariant instead of a NULL GVariant
398    */
399   if (ret == NULL)
400     {
401       GVariant *untrusted_empty;
402       untrusted_empty = g_variant_new_from_data (expected_type, NULL, 0, FALSE, NULL, NULL);
403       ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
404       g_variant_unref (untrusted_empty);
405     }
406
407   g_assert (!g_variant_is_floating (ret));
408
409   return ret;
410 }