Add "Since: 2.30" for new D-Bus routines
[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  * Since: 2.30
61  */
62 GDBusInterfaceInfo *
63 g_dbus_interface_get_info (GDBusInterface *interface)
64 {
65   g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
66   return G_DBUS_INTERFACE_GET_IFACE (interface)->get_info (interface);
67 }
68
69 /**
70  * g_dbus_interface_get_object:
71  * @interface: An exported D-Bus interface.
72  *
73  * Gets the #GDBusObject that @interface belongs to, if any.
74  *
75  * Returns: (transfer none): A #GDBusObject or %NULL. The returned
76  * reference belongs to @interface and should not be freed.
77  *
78  * Since: 2.30
79  */
80 GDBusObject *
81 g_dbus_interface_get_object (GDBusInterface *interface)
82 {
83   g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
84   return G_DBUS_INTERFACE_GET_IFACE (interface)->get_object (interface);
85 }
86
87 /**
88  * g_dbus_interface_set_object:
89  * @interface: An exported D-Bus interface.
90  * @object: A #GDBusObject or %NULL.
91  *
92  * Sets the #GDBusObject for @interface to @object.
93  *
94  * Note that @interface will hold a weak reference to @object.
95  *
96  * Since: 2.30
97  */
98 void
99 g_dbus_interface_set_object (GDBusInterface    *interface,
100                              GDBusObject       *object)
101 {
102   g_return_if_fail (G_IS_DBUS_INTERFACE (interface));
103   g_return_if_fail (object == NULL || G_IS_DBUS_OBJECT (object));
104   G_DBUS_INTERFACE_GET_IFACE (interface)->set_object (interface, object);
105 }
106
107 /* Keep it here for now. TODO: move */
108
109 #include <string.h>
110
111 /**
112  * g_dbus_gvariant_to_gvalue:
113  * @value: A #GVariant.
114  * @out_gvalue: Return location for the #GValue.
115  *
116  * Convert a #GVariant to a #GValue. If @value is floating, it is consumed.
117  *
118  * Note that the passed @out_gvalue does not have to have a #GType set.
119  *
120  * Returns: %TRUE if the conversion succeeded, %FALSE otherwise.
121  *
122  * Since: 2.30
123  */
124 gboolean
125 g_dbus_gvariant_to_gvalue (GVariant             *value,
126                            GValue               *out_gvalue)
127 {
128   gboolean ret;
129   const GVariantType *type;
130   gchar **array;
131
132   g_return_val_if_fail (value != NULL, FALSE);
133   g_return_val_if_fail (out_gvalue != NULL, FALSE);
134
135   ret = FALSE;
136
137   memset (out_gvalue, '\0', sizeof (GValue));
138
139   switch (g_variant_classify (value))
140     {
141     case G_VARIANT_CLASS_BOOLEAN:
142       g_value_init (out_gvalue, G_TYPE_BOOLEAN);
143       g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
144       break;
145
146     case G_VARIANT_CLASS_BYTE:
147       g_value_init (out_gvalue, G_TYPE_UCHAR);
148       g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
149       break;
150
151     case G_VARIANT_CLASS_INT16:
152       g_value_init (out_gvalue, G_TYPE_INT);
153       g_value_set_int (out_gvalue, g_variant_get_int16 (value));
154       break;
155
156     case G_VARIANT_CLASS_UINT16:
157       g_value_init (out_gvalue, G_TYPE_UINT);
158       g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
159       break;
160
161     case G_VARIANT_CLASS_INT32:
162       g_value_init (out_gvalue, G_TYPE_INT);
163       g_value_set_int (out_gvalue, g_variant_get_int32 (value));
164       break;
165
166     case G_VARIANT_CLASS_UINT32:
167       g_value_init (out_gvalue, G_TYPE_UINT);
168       g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
169       break;
170
171     case G_VARIANT_CLASS_INT64:
172       g_value_init (out_gvalue, G_TYPE_INT64);
173       g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
174       break;
175
176     case G_VARIANT_CLASS_UINT64:
177       g_value_init (out_gvalue, G_TYPE_UINT64);
178       g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
179       break;
180
181     case G_VARIANT_CLASS_HANDLE:
182       g_value_init (out_gvalue, G_TYPE_INT);
183       g_value_set_int (out_gvalue, g_variant_get_int32 (value));
184       break;
185
186     case G_VARIANT_CLASS_DOUBLE:
187       g_value_init (out_gvalue, G_TYPE_DOUBLE);
188       g_value_set_double (out_gvalue, g_variant_get_double (value));
189       break;
190
191     case G_VARIANT_CLASS_STRING:
192       g_value_init (out_gvalue, G_TYPE_STRING);
193       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
194       break;
195
196     case G_VARIANT_CLASS_OBJECT_PATH:
197       g_value_init (out_gvalue, G_TYPE_STRING);
198       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
199       break;
200
201     case G_VARIANT_CLASS_SIGNATURE:
202       g_value_init (out_gvalue, G_TYPE_STRING);
203       g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
204       break;
205
206     case G_VARIANT_CLASS_ARRAY:
207       type = g_variant_get_type (value);
208       switch (g_variant_type_peek_string (type)[1])
209         {
210         case G_VARIANT_CLASS_BYTE:
211           g_value_init (out_gvalue, G_TYPE_STRING);
212           g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
213           break;
214
215         case G_VARIANT_CLASS_STRING:
216           g_value_init (out_gvalue, G_TYPE_STRV);
217           array = g_variant_dup_strv (value, NULL);
218           g_value_take_boxed (out_gvalue, array);
219           break;
220
221         case G_VARIANT_CLASS_ARRAY:
222           switch (g_variant_type_peek_string (type)[2])
223             {
224             case G_VARIANT_CLASS_BYTE:
225               g_value_init (out_gvalue, G_TYPE_STRV);
226               array = g_variant_dup_bytestring_array (value, NULL);
227               g_value_take_boxed (out_gvalue, array);
228               break;
229
230             default:
231               g_value_init (out_gvalue, G_TYPE_VARIANT);
232               g_value_set_variant (out_gvalue, value);
233               break;
234             }
235           break;
236
237         default:
238           g_value_init (out_gvalue, G_TYPE_VARIANT);
239           g_value_set_variant (out_gvalue, value);
240           break;
241         }
242       break;
243
244     case G_VARIANT_CLASS_VARIANT:
245     case G_VARIANT_CLASS_MAYBE:
246     case G_VARIANT_CLASS_TUPLE:
247     case G_VARIANT_CLASS_DICT_ENTRY:
248       g_value_init (out_gvalue, G_TYPE_VARIANT);
249       g_value_set_variant (out_gvalue, value);
250       break;
251     }
252
253   ret = TRUE;
254
255   return ret;
256 }
257
258
259 /**
260  * g_dbus_gvalue_to_gvariant:
261  * @gvalue: A #GValue to convert to a #GVariant.
262  * @expected_type: The #GVariantType to create.
263  *
264  * Convert a #GValue to #GVariant.
265  *
266  * Returns: A #GVariant (never floating) holding the data from @gvalue
267  * or %NULL in case of error. Free with g_variant_unref().
268  *
269  * Since: 2.30
270  */
271 GVariant *
272 g_dbus_gvalue_to_gvariant (const GValue         *gvalue,
273                            const GVariantType   *expected_type)
274 {
275   GVariant *ret;
276   const gchar *s;
277   const gchar * const *as;
278   const gchar *empty_strv[1] = {NULL};
279
280   g_return_val_if_fail (gvalue != NULL, NULL);
281   g_return_val_if_fail (expected_type != NULL, NULL);
282
283   ret = NULL;
284
285   /* The expected type could easily be e.g. "s" with the GValue holding a string.
286    * because of the UseGVariant annotation
287    */
288   if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
289     {
290       ret = g_value_dup_variant (gvalue);
291     }
292   else
293     {
294       switch (g_variant_type_peek_string (expected_type)[0])
295         {
296         case G_VARIANT_CLASS_BOOLEAN:
297           ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
298           break;
299
300         case G_VARIANT_CLASS_BYTE:
301           ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
302           break;
303
304         case G_VARIANT_CLASS_INT16:
305           ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
306           break;
307
308         case G_VARIANT_CLASS_UINT16:
309           ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
310           break;
311
312         case G_VARIANT_CLASS_INT32:
313           ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
314           break;
315
316         case G_VARIANT_CLASS_UINT32:
317           ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
318           break;
319
320         case G_VARIANT_CLASS_INT64:
321           ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
322           break;
323
324         case G_VARIANT_CLASS_UINT64:
325           ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
326           break;
327
328         case G_VARIANT_CLASS_HANDLE:
329           ret = g_variant_ref_sink (g_variant_new_handle (g_value_get_int (gvalue)));
330           break;
331
332         case G_VARIANT_CLASS_DOUBLE:
333           ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
334           break;
335
336         case G_VARIANT_CLASS_STRING:
337           s = g_value_get_string (gvalue);
338           if (s == NULL)
339             s = "";
340           ret = g_variant_ref_sink (g_variant_new_string (s));
341           break;
342
343         case G_VARIANT_CLASS_OBJECT_PATH:
344           s = g_value_get_string (gvalue);
345           if (s == NULL)
346             s = "/";
347           ret = g_variant_ref_sink (g_variant_new_object_path (s));
348           break;
349
350         case G_VARIANT_CLASS_SIGNATURE:
351           s = g_value_get_string (gvalue);
352           if (s == NULL)
353             s = "";
354           ret = g_variant_ref_sink (g_variant_new_signature (s));
355           break;
356
357         case G_VARIANT_CLASS_ARRAY:
358           switch (g_variant_type_peek_string (expected_type)[1])
359             {
360             case G_VARIANT_CLASS_BYTE:
361               s = g_value_get_string (gvalue);
362               if (s == NULL)
363                 s = "";
364               ret = g_variant_ref_sink (g_variant_new_bytestring (s));
365               break;
366
367             case G_VARIANT_CLASS_STRING:
368               as = g_value_get_boxed (gvalue);
369               if (as == NULL)
370                 as = empty_strv;
371               ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
372               break;
373
374             case G_VARIANT_CLASS_ARRAY:
375               switch (g_variant_type_peek_string (expected_type)[2])
376                 {
377                 case G_VARIANT_CLASS_BYTE:
378                   as = g_value_get_boxed (gvalue);
379                   if (as == NULL)
380                     as = empty_strv;
381                   ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
382                   break;
383
384                 default:
385                   ret = g_value_dup_variant (gvalue);
386                   break;
387                 }
388               break;
389
390             default:
391               ret = g_value_dup_variant (gvalue);
392               break;
393             }
394           break;
395
396         default:
397         case G_VARIANT_CLASS_VARIANT:
398         case G_VARIANT_CLASS_MAYBE:
399         case G_VARIANT_CLASS_TUPLE:
400         case G_VARIANT_CLASS_DICT_ENTRY:
401           ret = g_value_dup_variant (gvalue);
402           break;
403         }
404     }
405
406   /* Could be that the GValue is holding a NULL GVariant - in that case,
407    * we return an "empty" GVariant instead of a NULL GVariant
408    */
409   if (ret == NULL)
410     {
411       GVariant *untrusted_empty;
412       untrusted_empty = g_variant_new_from_data (expected_type, NULL, 0, FALSE, NULL, NULL);
413       ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
414       g_variant_unref (untrusted_empty);
415     }
416
417   g_assert (!g_variant_is_floating (ret));
418
419   return ret;
420 }