migration from private to rsa
[external/dbus-glib.git] / dbus / dbus-gvalue.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-gvalue.c GValue to-from DBusMessageIter
3  *
4  * Copyright (C) 2004 Ximian, Inc.
5  * Copyright (C) 2005 Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include "config.h"
26 #include "dbus-gtest.h"
27 #include "dbus-gvalue.h"
28 #include "dbus-gsignature.h"
29 #include "dbus-gobject.h"
30 #include "dbus-gvalue-utils.h"
31 #include "dbus/dbus-glib.h"
32 #include <string.h>
33 #include <glib.h>
34 #include "dbus/dbus-signature.h"
35
36 /* Seems reasonable, but this should probably be part of the standard protocol */
37 #define DBUS_GLIB_MAX_VARIANT_RECURSION 32
38
39 static gboolean demarshal_static_variant (DBusGValueMarshalCtx    *context,
40                                           DBusMessageIter         *iter,
41                                           GValue                  *value,
42                                           GError                 **error);
43
44
45 static gboolean marshal_basic                   (DBusMessageIter           *iter,
46                                                  const GValue              *value);
47 static gboolean demarshal_basic                 (DBusGValueMarshalCtx      *context,
48                                                  DBusMessageIter           *iter,
49                                                  GValue                    *value,
50                                                  GError                   **error);
51 static gboolean marshal_strv                    (DBusMessageIter           *iter,
52                                                  const GValue              *value);
53 static gboolean demarshal_strv                  (DBusGValueMarshalCtx      *context,
54                                                  DBusMessageIter           *iter,
55                                                  GValue                    *value,
56                                                  GError                   **error);
57 static gboolean marshal_valuearray              (DBusMessageIter           *iter,
58                                                  const GValue              *value);
59 static gboolean demarshal_valuearray            (DBusGValueMarshalCtx      *context,
60                                                  DBusMessageIter           *iter,
61                                                  GValue                    *value,
62                                                  GError                   **error);
63 static gboolean marshal_variant                 (DBusMessageIter           *iter,
64                                                  const GValue              *value);
65 static gboolean demarshal_variant               (DBusGValueMarshalCtx      *context,
66                                                  DBusMessageIter           *iter,
67                                                  GValue                    *value,
68                                                  GError                   **error);
69 static gboolean marshal_proxy                   (DBusMessageIter           *iter,
70                                                  const GValue             *value);
71 static gboolean demarshal_proxy                 (DBusGValueMarshalCtx      *context,
72                                                  DBusMessageIter           *iter,
73                                                  GValue                    *value,
74                                                  GError                   **error);
75 static gboolean marshal_object_path             (DBusMessageIter           *iter,
76                                                  const GValue             *value);
77 static gboolean demarshal_object_path           (DBusGValueMarshalCtx      *context,
78                                                  DBusMessageIter           *iter,
79                                                  GValue                    *value,
80                                                  GError                   **error);
81 static gboolean marshal_object                  (DBusMessageIter           *iter,
82                                                  const GValue              *value);
83 static gboolean demarshal_object                (DBusGValueMarshalCtx      *context,
84                                                  DBusMessageIter           *iter,
85                                                  GValue                    *value,
86                                                  GError                   **error);
87 static gboolean marshal_signature               (DBusMessageIter           *iter,
88                                                  const GValue             *value);
89 static gboolean demarshal_signature             (DBusGValueMarshalCtx      *context,
90                                                  DBusMessageIter           *iter,
91                                                  GValue                    *value,
92                                                  GError                   **error);
93 static gboolean marshal_map                     (DBusMessageIter           *iter,
94                                                  const GValue              *value);
95 static gboolean demarshal_map                   (DBusGValueMarshalCtx      *context,
96                                                  DBusMessageIter           *iter,
97                                                  GValue                    *value,
98                                                  GError                   **error);
99
100 static gboolean marshal_collection              (DBusMessageIter           *iter,
101                                                  const GValue              *value);
102 static gboolean marshal_collection_ptrarray     (DBusMessageIter           *iter,
103                                                  const GValue              *value);
104 static gboolean marshal_collection_array        (DBusMessageIter           *iter,
105                                                  const GValue              *value);
106 static gboolean demarshal_collection            (DBusGValueMarshalCtx      *context,
107                                                  DBusMessageIter           *iter,
108                                                  GValue                    *value,
109                                                  GError                   **error);
110 static gboolean demarshal_collection_ptrarray   (DBusGValueMarshalCtx      *context,
111                                                  DBusMessageIter           *iter,
112                                                  GValue                    *value,
113                                                  GError                   **error);
114 static gboolean demarshal_collection_array      (DBusGValueMarshalCtx      *context,
115                                                  DBusMessageIter           *iter,
116                                                  GValue                    *value,
117                                                  GError                   **error);
118 static gboolean marshal_struct                  (DBusMessageIter           *iter,
119                                                  const GValue              *value);
120 static gboolean demarshal_struct                (DBusGValueMarshalCtx      *context,
121                                                  DBusMessageIter           *iter,
122                                                  GValue                    *value,
123                                                  GError                   **error);
124
125
126 typedef gboolean (*DBusGValueMarshalFunc)       (DBusMessageIter           *iter,
127                                                  const GValue              *value);
128 typedef gboolean (*DBusGValueDemarshalFunc)     (DBusGValueMarshalCtx      *context,
129                                                  DBusMessageIter           *iter,
130                                                  GValue                    *value,
131                                                  GError                   **error);
132
133 typedef struct {
134   DBusGValueMarshalFunc       marshaller;
135   DBusGValueDemarshalFunc     demarshaller;
136 } DBusGTypeMarshalVtable;
137
138 typedef struct {
139   const char                       *sig;
140   const DBusGTypeMarshalVtable     *vtable;
141 } DBusGTypeMarshalData;
142
143 static GQuark
144 dbus_g_type_metadata_data_quark ()
145 {
146   static GQuark quark;
147   if (!quark)
148     quark = g_quark_from_static_string ("DBusGTypeMetaData");
149   
150   return quark;
151 }
152
153 static void
154 set_type_metadata (GType type, const DBusGTypeMarshalData *data)
155 {
156   g_type_set_qdata (type, dbus_g_type_metadata_data_quark (), (gpointer) data);
157 }
158
159 static void
160 register_basic (int typecode, const DBusGTypeMarshalData *typedata)
161 {
162   set_type_metadata (_dbus_gtype_from_basic_typecode (typecode), typedata);
163 }
164
165 void
166 _dbus_g_value_types_init (void)
167 {
168   static gboolean types_initialized;
169
170   static const DBusGTypeMarshalVtable basic_vtable = {
171     marshal_basic,
172     demarshal_basic
173   };
174
175   if (types_initialized)
176     return;
177
178   dbus_g_type_specialized_init ();
179
180   /* Register basic types */
181   {
182     static const DBusGTypeMarshalData typedata = {
183       DBUS_TYPE_BOOLEAN_AS_STRING,
184       &basic_vtable,
185     };
186     register_basic (DBUS_TYPE_BOOLEAN, &typedata);
187   }
188   {
189     static const DBusGTypeMarshalData typedata = {
190       DBUS_TYPE_BYTE_AS_STRING,
191       &basic_vtable,
192     };
193     register_basic (DBUS_TYPE_BYTE, &typedata);
194   }
195   {
196     static const DBusGTypeMarshalData typedata = {
197       DBUS_TYPE_INT16_AS_STRING,
198       &basic_vtable,
199     };
200     register_basic (DBUS_TYPE_INT16, &typedata);
201   }
202   {
203     static const DBusGTypeMarshalData typedata = {
204       DBUS_TYPE_UINT16_AS_STRING,
205       &basic_vtable,
206     };
207     register_basic (DBUS_TYPE_UINT16, &typedata);
208   }
209   {
210     static const DBusGTypeMarshalData typedata = {
211       DBUS_TYPE_UINT32_AS_STRING,
212       &basic_vtable,
213     };
214     register_basic (DBUS_TYPE_UINT32, &typedata);
215   }
216   {
217     static const DBusGTypeMarshalData typedata = {
218       DBUS_TYPE_INT32_AS_STRING,
219       &basic_vtable,
220     };
221     register_basic (DBUS_TYPE_INT32, &typedata);
222   }
223   {
224     static const DBusGTypeMarshalData typedata = {
225       DBUS_TYPE_UINT64_AS_STRING,
226       &basic_vtable,
227     };
228     register_basic (DBUS_TYPE_UINT64, &typedata);
229   }
230   {
231     static const DBusGTypeMarshalData typedata = {
232       DBUS_TYPE_INT64_AS_STRING,
233       &basic_vtable,
234     };
235     register_basic (DBUS_TYPE_INT64, &typedata);
236   }
237   {
238     static const DBusGTypeMarshalData typedata = {
239       DBUS_TYPE_DOUBLE_AS_STRING,
240       &basic_vtable,
241     };
242     register_basic (DBUS_TYPE_DOUBLE, &typedata);
243   }
244   {
245     static const DBusGTypeMarshalData typedata = {
246       DBUS_TYPE_STRING_AS_STRING,
247       &basic_vtable,
248     };
249     register_basic (DBUS_TYPE_STRING, &typedata);
250   }
251   /* fundamental GTypes that don't map 1:1 with D-BUS types */
252   {
253     static const DBusGTypeMarshalData typedata = {
254       DBUS_TYPE_BYTE_AS_STRING,
255       &basic_vtable,
256     };
257     set_type_metadata (G_TYPE_CHAR, &typedata);
258   }
259   {
260     static const DBusGTypeMarshalData typedata = {
261       DBUS_TYPE_INT32_AS_STRING,
262       &basic_vtable,
263     };
264     set_type_metadata (G_TYPE_LONG, &typedata);
265   }
266   {
267     static const DBusGTypeMarshalData typedata = {
268       DBUS_TYPE_UINT32_AS_STRING,
269       &basic_vtable,
270     };
271     set_type_metadata (G_TYPE_ULONG, &typedata);
272   }
273   {
274     static const DBusGTypeMarshalData typedata = {
275       DBUS_TYPE_DOUBLE_AS_STRING,
276       &basic_vtable,
277     };
278     set_type_metadata (G_TYPE_FLOAT, &typedata);
279   }
280
281   /* Register complex types with builtin GType mappings */
282   {
283     static const DBusGTypeMarshalVtable vtable = {
284       marshal_variant,
285       demarshal_variant
286     };
287     static const DBusGTypeMarshalData typedata = {
288       DBUS_TYPE_VARIANT_AS_STRING,
289       &vtable
290     };
291     set_type_metadata (G_TYPE_VALUE, &typedata);
292   };
293   {
294     static const DBusGTypeMarshalVtable vtable = {
295       marshal_strv,
296       demarshal_strv
297     };
298     static const DBusGTypeMarshalData typedata = {
299       DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
300       &vtable
301     };
302     set_type_metadata (G_TYPE_STRV, &typedata);
303   };
304
305
306   /* Register some types specific to the D-BUS GLib bindings */
307   {
308     static const DBusGTypeMarshalVtable vtable = {
309       marshal_proxy,
310       demarshal_proxy
311     };
312     static const DBusGTypeMarshalData typedata = {
313       DBUS_TYPE_OBJECT_PATH_AS_STRING,
314       &vtable
315     };
316     set_type_metadata (DBUS_TYPE_G_PROXY, &typedata);
317   }
318
319   {
320     static const DBusGTypeMarshalVtable vtable = {
321       marshal_object_path,
322       demarshal_object_path
323     };
324     static const DBusGTypeMarshalData typedata = {
325       DBUS_TYPE_OBJECT_PATH_AS_STRING,
326       &vtable
327     };
328     set_type_metadata (DBUS_TYPE_G_OBJECT_PATH, &typedata);
329   }
330
331   {
332     static const DBusGTypeMarshalVtable vtable = {
333       marshal_object,
334       demarshal_object
335     };
336     static const DBusGTypeMarshalData typedata = {
337       DBUS_TYPE_OBJECT_PATH_AS_STRING,
338       &vtable
339     };
340     set_type_metadata (G_TYPE_OBJECT, &typedata);
341   }
342
343   {
344     static const DBusGTypeMarshalVtable vtable = {
345       marshal_signature,
346       demarshal_signature
347     };
348     static const DBusGTypeMarshalData typedata = {
349       DBUS_TYPE_SIGNATURE_AS_STRING,
350       &vtable
351     };
352     set_type_metadata (DBUS_TYPE_G_SIGNATURE, &typedata);
353   }
354
355   types_initialized = TRUE;
356 }
357
358 /**
359  * DBusGObjectPath:
360  *
361  * A typedef for a string used to represent D-Bus object paths.
362  * Its GType is %DBUS_TYPE_G_OBJECT_PATH, derived from %G_TYPE_BOXED.
363  *
364  * Prior to version 0.FIXME this was used as the type name of
365  * %DBUS_TYPE_G_OBJECT_PATH, but did not actually exist as a typedef.
366  *
367  * Since: 0.FIXME
368  */
369
370 /**
371  * DBUS_TYPE_G_OBJECT_PATH:
372  *
373  * The #GType of a #DBusGObjectPath, which is a boxed type containing a
374  * D-Bus object path as a zero-terminated string. Object paths can be
375  * copied with g_strdup() and freed with g_free(), just like %G_TYPE_STRING,
376  * but have a distinct boxed type to allow them to be distinguished when
377  * stored in a #GValue.
378  *
379  * Returns: a type derived from %G_TYPE_BOXED
380  */
381 GType
382 dbus_g_object_path_get_g_type (void)
383 {
384   static GType type_id = 0;
385
386   if (!type_id)
387     type_id = g_boxed_type_register_static ("DBusGObjectPath",
388                                             (GBoxedCopyFunc) g_strdup,
389                                             (GBoxedFreeFunc) g_free);
390   return type_id;
391 }
392
393 /**
394  * DBusGSignature:
395  *
396  * A typedef for a string used to represent D-Bus signatures.
397  * Its GType is %DBUS_TYPE_G_SIGNATURE, derived from %G_TYPE_BOXED.
398  *
399  * Prior to version 0.FIXME this was used as the type name of
400  * %DBUS_TYPE_G_SIGNATURE, but did not actually exist as a typedef.
401  *
402  * Since: 0.FIXME
403  */
404
405 /**
406  * DBUS_TYPE_G_SIGNATURE:
407  *
408  * The #GType of a #DBusGSignature, which is a boxed type containing a
409  * D-Bus signature as a zero-terminated string. Signatures can be
410  * copied with g_strdup() and freed with g_free(), just like %G_TYPE_STRING,
411  * but have a distinct boxed type to allow them to be distinguished when
412  * stored in a #GValue.
413  *
414  * Returns: a type derived from %G_TYPE_BOXED
415  */
416 GType
417 dbus_g_signature_get_g_type (void)
418 {
419   static GType type_id = 0;
420
421   if (G_UNLIKELY (type_id == 0))
422     type_id = g_boxed_type_register_static ("DBusGSignature",
423                                             (GBoxedCopyFunc) g_strdup,
424                                             (GBoxedFreeFunc) g_free);
425
426   return type_id;
427 }
428
429
430 char *
431 _dbus_gtype_to_signature (GType gtype)
432 {
433   char *ret;
434   DBusGTypeMarshalData *typedata;
435
436   if (dbus_g_type_is_collection (gtype))
437     {
438       GType elt_gtype;
439       char *subsig;
440
441       elt_gtype = dbus_g_type_get_collection_specialization (gtype);
442       subsig = _dbus_gtype_to_signature (elt_gtype);
443       ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING, subsig, NULL);
444       g_free (subsig);
445     }
446   else if (dbus_g_type_is_map (gtype))
447     {
448       GType key_gtype;
449       GType val_gtype;
450       char *key_subsig;
451       char *val_subsig;
452
453       key_gtype = dbus_g_type_get_map_key_specialization (gtype);
454       val_gtype = dbus_g_type_get_map_value_specialization (gtype);
455       key_subsig = _dbus_gtype_to_signature (key_gtype);
456       val_subsig = _dbus_gtype_to_signature (val_gtype);
457       ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING, key_subsig, val_subsig, DBUS_DICT_ENTRY_END_CHAR_AS_STRING, NULL);
458       g_free (key_subsig);
459       g_free (val_subsig);
460     }
461   else if (dbus_g_type_is_struct (gtype))
462     {
463       guint i, size;
464       GString *sig;
465       size = dbus_g_type_get_struct_size (gtype);
466       sig = g_string_sized_new (size+2); /*some sensible starting size*/
467       g_string_assign (sig, DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
468       for (i = 0; i < size; i++)
469         {
470           gchar *subsig;
471           subsig = _dbus_gtype_to_signature (
472               dbus_g_type_get_struct_member_type (gtype, i));
473           g_string_append (sig, subsig);
474           g_free (subsig);
475         }
476       g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING);
477       ret = g_string_free (sig, FALSE);
478     }
479   else
480     {
481       typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
482       if (typedata == NULL)
483         return NULL;
484       ret = g_strdup (typedata->sig);
485     }
486   return ret;
487 }
488
489 char *
490 _dbus_gvalue_to_signature (const GValue *val)
491 {
492   GType gtype;
493
494   gtype = G_VALUE_TYPE (val);
495   if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY))
496     {
497       GString *str;
498       guint i;
499       GValueArray *array;
500
501       array = g_value_get_boxed (val);
502       
503       str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
504       for (i = 0; i < array->n_values; i++)
505         {
506           char *sig;
507           sig = _dbus_gvalue_to_signature (g_value_array_get_nth (array, i));
508           g_string_append (str, sig);
509           g_free (sig);
510         }
511       g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING);
512       
513       return g_string_free (str, FALSE);
514     }
515   else
516     return _dbus_gtype_to_signature (gtype);
517 }
518
519 static gboolean
520 demarshal_basic (DBusGValueMarshalCtx      *context,
521                  DBusMessageIter           *iter,
522                  GValue                    *value,
523                  GError                   **error)
524 {
525   int current_type;
526   
527   current_type = dbus_message_iter_get_arg_type (iter);
528   g_assert (dbus_type_is_basic (current_type));
529
530   switch (current_type)
531     {
532     case DBUS_TYPE_BOOLEAN:
533       {
534         dbus_bool_t bool;
535         if (!G_VALUE_HOLDS (value, G_TYPE_BOOLEAN))
536           goto invalid_type;
537         dbus_message_iter_get_basic (iter, &bool);
538         g_value_set_boolean (value, bool);
539         return TRUE;
540       }
541     case DBUS_TYPE_BYTE:
542       {
543         unsigned char byte;
544         if (!G_VALUE_HOLDS (value, G_TYPE_UCHAR))
545           goto invalid_type;
546         dbus_message_iter_get_basic (iter, &byte);
547         g_value_set_uchar (value, byte);
548         return TRUE;
549       }
550     case DBUS_TYPE_INT32:
551       {
552         dbus_int32_t intval;
553         if (!G_VALUE_HOLDS (value, G_TYPE_INT))
554           goto invalid_type;
555         dbus_message_iter_get_basic (iter, &intval);
556         g_value_set_int (value, intval);
557         return TRUE;
558       }
559     case DBUS_TYPE_UINT32:
560       {
561         dbus_uint32_t intval;
562         if (!G_VALUE_HOLDS (value, G_TYPE_UINT))
563           goto invalid_type;
564         dbus_message_iter_get_basic (iter, &intval);
565         g_value_set_uint (value, intval);
566         return TRUE;
567       }
568     case DBUS_TYPE_INT64:
569       {
570         dbus_int64_t intval;
571         if (!G_VALUE_HOLDS (value, G_TYPE_INT64))
572           goto invalid_type;
573         dbus_message_iter_get_basic (iter, &intval);
574         g_value_set_int64 (value, intval);
575         return TRUE;
576       }
577     case DBUS_TYPE_UINT64:
578       {
579         dbus_uint64_t intval;
580         if (!G_VALUE_HOLDS (value, G_TYPE_UINT64))
581           goto invalid_type;
582         dbus_message_iter_get_basic (iter, &intval);
583         g_value_set_uint64 (value, intval);
584         return TRUE;
585       }
586     case DBUS_TYPE_DOUBLE:
587       {
588         double dval;
589         if (!G_VALUE_HOLDS (value, G_TYPE_DOUBLE))
590           goto invalid_type;
591         dbus_message_iter_get_basic (iter, &dval);
592         g_value_set_double (value, dval);
593         return TRUE;
594       }
595     case DBUS_TYPE_INT16:
596       {
597         dbus_int16_t v;
598         if (!G_VALUE_HOLDS (value, G_TYPE_INT))
599           goto invalid_type;
600         dbus_message_iter_get_basic (iter, &v);
601         g_value_set_int (value, v);
602         return TRUE;
603       }
604     case DBUS_TYPE_UINT16:
605       {
606         dbus_uint16_t v;
607         if (!G_VALUE_HOLDS (value, G_TYPE_UINT))
608           goto invalid_type;
609         dbus_message_iter_get_basic (iter, &v);
610         g_value_set_uint (value, v);
611         return TRUE;
612       }
613     case DBUS_TYPE_STRING:
614       {
615         const char *s;
616         if (!G_VALUE_HOLDS (value, G_TYPE_STRING))
617           goto invalid_type;
618         dbus_message_iter_get_basic (iter, &s);
619         g_value_set_string (value, s);
620         return TRUE;
621       }
622     default:
623       /* fall through to invalid_type */
624       break;
625     }
626   invalid_type:
627     g_set_error (error,
628                  DBUS_GERROR,
629                  DBUS_GERROR_INVALID_ARGS,
630                  "Expected type %s, got type code \'%c\'",
631                  g_type_name (G_VALUE_TYPE (value)),
632                  (guchar) current_type);
633     return FALSE;
634 }
635
636 static gboolean
637 demarshal_static_variant (DBusGValueMarshalCtx    *context,
638                           DBusMessageIter         *iter,
639                           GValue                  *value,
640                           GError                 **error)
641 {
642   char *sig;
643   DBusMessageIter subiter;
644   GType variant_type;
645
646   dbus_message_iter_recurse (iter, &subiter);
647   sig = dbus_message_iter_get_signature (&subiter);
648
649   variant_type = _dbus_gtype_from_signature (sig, context->proxy != NULL);
650   if (variant_type != G_TYPE_INVALID)
651     {
652       g_value_init (value, variant_type);
653
654       if (!_dbus_gvalue_demarshal (context, &subiter, value, error))
655         {
656           dbus_free (sig);
657           return FALSE;
658         }
659     }
660   dbus_free (sig);
661   return TRUE;
662 }
663
664 static gboolean
665 demarshal_variant (DBusGValueMarshalCtx    *context,
666                    DBusMessageIter         *iter,
667                    GValue                  *value,
668                    GError                 **error)
669
670 {
671   GValue *variant_val;
672   variant_val = g_new0 (GValue, 1);
673
674   if (!demarshal_static_variant (context, iter, variant_val, error))
675     return FALSE;
676   
677   g_value_take_boxed (value, variant_val);
678   return TRUE;
679 }
680
681 static gboolean
682 demarshal_proxy (DBusGValueMarshalCtx    *context,
683                  DBusMessageIter         *iter,
684                  GValue                  *value,
685                  GError                 **error)
686 {
687   DBusGProxy *new_proxy;
688   const char *objpath;
689   int current_type;
690
691   current_type = dbus_message_iter_get_arg_type (iter);
692   if (current_type != DBUS_TYPE_OBJECT_PATH)
693     {
694       g_set_error (error,
695                    DBUS_GERROR,
696                    DBUS_GERROR_INVALID_ARGS,
697                    "Expected D-BUS object path, got type code \'%c\'", (guchar) current_type);
698       return FALSE;
699     }
700
701   g_assert (context->proxy != NULL);
702   
703   dbus_message_iter_get_basic (iter, &objpath);
704
705   new_proxy = dbus_g_proxy_new_from_proxy (context->proxy, NULL, objpath);
706   g_value_take_object (value, new_proxy);
707
708   return TRUE;
709 }
710
711 static gboolean
712 demarshal_object_path (DBusGValueMarshalCtx    *context,
713                        DBusMessageIter         *iter,
714                        GValue                  *value,
715                        GError                 **error)
716 {
717   const char *objpath;
718   int current_type;
719
720   current_type = dbus_message_iter_get_arg_type (iter);
721   if (current_type != DBUS_TYPE_OBJECT_PATH)
722     {
723       g_set_error (error,
724                    DBUS_GERROR,
725                    DBUS_GERROR_INVALID_ARGS,
726                    "Expected D-BUS object path, got type code \'%c\'", (guchar) current_type);
727       return FALSE;
728     }
729
730   dbus_message_iter_get_basic (iter, &objpath);
731
732   g_value_set_boxed (value, objpath);
733
734   return TRUE;
735 }
736
737 static gboolean
738 demarshal_object (DBusGValueMarshalCtx    *context,
739                   DBusMessageIter         *iter,
740                   GValue                  *value,
741                   GError                 **error)
742 {
743   const char *objpath;
744   int current_type;
745   GObject *obj;
746
747   current_type = dbus_message_iter_get_arg_type (iter);
748   if (current_type != DBUS_TYPE_OBJECT_PATH)
749     {
750       g_set_error (error,
751                    DBUS_GERROR,
752                    DBUS_GERROR_INVALID_ARGS,
753                    "Expected D-BUS object path, got type code \'%c\'", (guchar) current_type);
754       return FALSE;
755     }
756   g_assert (context->proxy == NULL);
757
758   dbus_message_iter_get_basic (iter, &objpath);
759
760   obj = dbus_g_connection_lookup_g_object (context->gconnection, objpath);
761   if (obj == NULL)
762     {
763       g_set_error (error,
764                    DBUS_GERROR,
765                    DBUS_GERROR_INVALID_ARGS,
766                    "Unregistered object at path '%s'",
767                    objpath);
768       return FALSE;
769     }
770   g_value_set_object (value, obj);
771
772   return TRUE;
773 }
774
775 static gboolean
776 demarshal_signature (DBusGValueMarshalCtx    *context,
777                      DBusMessageIter         *iter,
778                      GValue                  *value,
779                      GError                 **error)
780 {
781   const char *sig;
782   int current_type;
783
784   current_type = dbus_message_iter_get_arg_type (iter);
785   if (current_type != DBUS_TYPE_SIGNATURE)
786     {
787       g_set_error (error,
788                    DBUS_GERROR,
789                    DBUS_GERROR_INVALID_ARGS,
790                    "Expected D-BUS signature, got type code \'%c\'", (guchar) current_type);
791       return FALSE;
792     }
793
794   dbus_message_iter_get_basic (iter, &sig);
795
796   g_value_set_boxed (value, sig);
797
798   return TRUE;
799 }
800
801 static gboolean
802 demarshal_strv (DBusGValueMarshalCtx    *context,
803                 DBusMessageIter         *iter,
804                 GValue                  *value,
805                 GError                 **error)
806 {
807   DBusMessageIter subiter;
808   int current_type;
809   GArray *arr;
810
811   current_type = dbus_message_iter_get_arg_type (iter);
812   if (current_type != DBUS_TYPE_ARRAY)
813     {
814       g_set_error (error,
815                    DBUS_GERROR,
816                    DBUS_GERROR_INVALID_ARGS,
817                    "Expected D-BUS array, got type code \'%c\'", (guchar) current_type);
818       return FALSE;
819     }
820
821   dbus_message_iter_recurse (iter, &subiter);
822
823   current_type = dbus_message_iter_get_arg_type (&subiter);
824   if (current_type != DBUS_TYPE_INVALID
825       && current_type != DBUS_TYPE_STRING)
826     {
827       g_set_error (error,
828                    DBUS_GERROR,
829                    DBUS_GERROR_INVALID_ARGS,
830                    "Expected D-BUS string, got type code \'%c\'", (guchar) current_type);
831       return FALSE;
832     }
833
834   arr = g_array_new (TRUE, FALSE, sizeof (char *));
835
836   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
837     {
838       g_assert (current_type == DBUS_TYPE_STRING);
839       const char *str;
840       char *copy;
841       
842       dbus_message_iter_get_basic (&subiter, &str);
843       copy = g_strdup (str);
844       g_array_append_val (arr, copy);
845
846       dbus_message_iter_next (&subiter);
847     }
848
849   g_value_take_boxed (value, arr->data);
850   g_array_free (arr, FALSE);
851   
852   return TRUE;
853 }
854
855 static gboolean
856 demarshal_valuearray (DBusGValueMarshalCtx    *context,
857                       DBusMessageIter         *iter,
858                       GValue                  *value,
859                       GError                 **error)
860 {
861   int current_type;
862   GValueArray *ret;
863   DBusMessageIter subiter;
864
865   current_type = dbus_message_iter_get_arg_type (iter);
866   if (current_type != DBUS_TYPE_STRUCT)
867     {
868       g_set_error (error,
869                    DBUS_GERROR,
870                    DBUS_GERROR_INVALID_ARGS,
871                    "Expected D-BUS struct, got type code \'%c\'", (guchar) current_type);
872       return FALSE;
873     }
874
875   dbus_message_iter_recurse (iter, &subiter);
876
877   ret = g_value_array_new (12);
878
879   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
880     {
881       GValue *val;
882       GType elt_type; 
883       char *current_sig;
884
885       g_value_array_append (ret, NULL);
886       val = g_value_array_get_nth (ret, ret->n_values - 1);
887
888       current_sig = dbus_message_iter_get_signature (&subiter);
889       elt_type = _dbus_gtype_from_signature (current_sig, TRUE);
890
891       if (elt_type == G_TYPE_INVALID)
892         {
893           g_value_array_free (ret);
894           g_set_error (error,
895                        DBUS_GERROR,
896                        DBUS_GERROR_INVALID_ARGS,
897                        "Couldn't demarshal argument with signature \"%s\"", current_sig);
898           dbus_free (current_sig);
899           return FALSE;
900         }
901       dbus_free (current_sig);
902       
903       g_value_init (val, elt_type);
904
905       if (!_dbus_gvalue_demarshal (context, &subiter, val, error))
906         {
907           g_value_array_free (ret);
908           return FALSE;
909         }
910
911       dbus_message_iter_next (&subiter);
912     }
913
914   g_value_take_boxed (value, ret);
915   
916   return TRUE;
917 }
918
919 static gboolean
920 demarshal_map (DBusGValueMarshalCtx    *context,
921                DBusMessageIter         *iter,
922                GValue                  *value,
923                GError                 **error)
924 {
925   GType gtype;
926   DBusMessageIter subiter;
927   int current_type;
928   gpointer ret;
929   GType key_gtype;
930   GType value_gtype;
931   DBusGTypeSpecializedAppendContext appendctx;
932
933   current_type = dbus_message_iter_get_arg_type (iter);
934   if (current_type != DBUS_TYPE_ARRAY)
935     {
936       g_set_error (error,
937                    DBUS_GERROR,
938                    DBUS_GERROR_INVALID_ARGS,
939                    "Expected D-BUS array, got type code \'%c\'", (guchar) current_type);
940       return FALSE;
941     }
942
943   gtype = G_VALUE_TYPE (value);
944
945   dbus_message_iter_recurse (iter, &subiter);
946
947   current_type = dbus_message_iter_get_arg_type (&subiter);
948   if (current_type != DBUS_TYPE_INVALID
949       && current_type != DBUS_TYPE_DICT_ENTRY)
950     {
951       g_set_error (error,
952                    DBUS_GERROR,
953                    DBUS_GERROR_INVALID_ARGS,
954                    "Expected D-BUS dict entry, got type code \'%c\'", (guchar) current_type);
955       return FALSE;
956     }
957
958   key_gtype = dbus_g_type_get_map_key_specialization (gtype);
959   value_gtype = dbus_g_type_get_map_value_specialization (gtype);
960
961   ret = dbus_g_type_specialized_construct (gtype);
962   g_value_take_boxed (value, ret);
963
964   dbus_g_type_specialized_init_append (value, &appendctx);
965
966   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
967     {
968       DBusMessageIter entry_iter;
969       GValue key_value = {0,};
970       GValue value_value = {0,};
971
972       current_type = dbus_message_iter_get_arg_type (&subiter);
973       g_assert (current_type == DBUS_TYPE_DICT_ENTRY);
974
975       dbus_message_iter_recurse (&subiter, &entry_iter);
976
977       g_value_init (&key_value, key_gtype);
978       if (!_dbus_gvalue_demarshal (context,
979                                   &entry_iter,
980                                   &key_value,
981                                   error))
982         return FALSE;
983
984       dbus_message_iter_next (&entry_iter);
985
986       g_value_init (&value_value, value_gtype);
987       if (!_dbus_gvalue_demarshal (context,
988                                   &entry_iter,
989                                   &value_value,
990                                   error))
991         return FALSE;
992
993       dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
994       /* Ownership of values passes to map, don't unset */
995
996       dbus_message_iter_next (&subiter);
997     }
998   
999   return TRUE;
1000 }
1001
1002 static gboolean
1003 demarshal_struct (DBusGValueMarshalCtx    *context,
1004                   DBusMessageIter         *iter,
1005                   GValue                  *value,
1006                   GError                 **error)
1007 {
1008   int current_type;
1009   DBusMessageIter subiter;
1010   guint i, size;
1011   GValue val = {0,};
1012   GType elt_type;
1013
1014   current_type = dbus_message_iter_get_arg_type (iter);
1015   if (current_type != DBUS_TYPE_STRUCT)
1016     {
1017       g_set_error (error,
1018                    DBUS_GERROR,
1019                    DBUS_GERROR_INVALID_ARGS,
1020                    "Expected D-BUS struct, got type code \'%c\'", (guchar) current_type);
1021       return FALSE;
1022     }
1023
1024   dbus_message_iter_recurse (iter, &subiter);
1025
1026   g_value_take_boxed (value,
1027     dbus_g_type_specialized_construct (G_VALUE_TYPE (value)));
1028
1029   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
1030
1031   for (i=0; i < size; i++)
1032     {
1033
1034       elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i);
1035       if (elt_type == G_TYPE_INVALID)
1036         {
1037           g_value_unset (value);
1038           g_set_error (error,
1039                        DBUS_GERROR,
1040                        DBUS_GERROR_INVALID_ARGS,
1041                        "Couldn't demarshal argument, "
1042                          "struct type %s has no member %d",
1043                        g_type_name (G_VALUE_TYPE(value)), i);
1044           return FALSE;
1045         }
1046
1047       g_value_init (&val, elt_type);
1048
1049       if (!_dbus_gvalue_demarshal (context, &subiter, &val, error))
1050         {
1051           g_value_unset (&val);
1052           g_value_unset (value);
1053           return FALSE;
1054         }
1055       if (!dbus_g_type_struct_set_member (value, i, &val))
1056         {
1057           g_value_unset (&val);
1058           g_value_unset (value);
1059           return FALSE;
1060         }
1061
1062       dbus_message_iter_next (&subiter);
1063       g_value_unset (&val);
1064     }
1065
1066   g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID);
1067
1068   return TRUE;
1069 }
1070
1071
1072 static DBusGValueDemarshalFunc
1073 get_type_demarshaller (GType type)
1074 {
1075   DBusGTypeMarshalData *typedata;
1076
1077   typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
1078   if (typedata == NULL)
1079     {
1080       if (g_type_is_a (type, G_TYPE_VALUE_ARRAY))
1081         return demarshal_valuearray;
1082       if (dbus_g_type_is_collection (type))
1083         return demarshal_collection;
1084       if (dbus_g_type_is_map (type))
1085         return demarshal_map;
1086       if (dbus_g_type_is_struct (type))
1087         return demarshal_struct;
1088
1089       g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
1090       return NULL;
1091     }
1092   g_assert (typedata->vtable);
1093   return typedata->vtable->demarshaller;
1094 }
1095
1096 static gboolean
1097 demarshal_collection (DBusGValueMarshalCtx    *context,
1098                       DBusMessageIter         *iter,
1099                       GValue                  *value,
1100                       GError                 **error)
1101 {
1102   GType coltype;
1103   GType subtype;
1104   
1105   coltype = G_VALUE_TYPE (value);
1106   subtype = dbus_g_type_get_collection_specialization (coltype);
1107
1108   if (_dbus_g_type_is_fixed (subtype))
1109     return demarshal_collection_array (context, iter, value, error);
1110   else
1111     return demarshal_collection_ptrarray (context, iter, value, error);
1112 }
1113
1114 static gboolean
1115 demarshal_collection_ptrarray (DBusGValueMarshalCtx    *context,
1116                                DBusMessageIter         *iter,
1117                                GValue                  *value,
1118                                GError                 **error)
1119 {
1120   GType coltype;
1121   GType subtype;
1122   gpointer instance;
1123   DBusGTypeSpecializedAppendContext ctx;
1124   DBusGValueDemarshalFunc demarshaller;
1125   DBusMessageIter subiter;
1126   int current_type;
1127
1128   current_type = dbus_message_iter_get_arg_type (iter);
1129
1130   if (current_type != DBUS_TYPE_ARRAY)
1131     {
1132       g_set_error (error,
1133                    DBUS_GERROR,
1134                    DBUS_GERROR_INVALID_ARGS,
1135                    "Expected D-BUS array, got type code \'%c\'", (guchar) current_type);
1136       return FALSE;
1137     }
1138
1139   dbus_message_iter_recurse (iter, &subiter);
1140   
1141   coltype = G_VALUE_TYPE (value);
1142   subtype = dbus_g_type_get_collection_specialization (coltype);
1143
1144   demarshaller = get_type_demarshaller (subtype);
1145
1146   if (!demarshaller)
1147     {
1148       g_set_error (error,
1149                    DBUS_GERROR,
1150                    DBUS_GERROR_INVALID_ARGS,
1151                    "No demarshaller registered for type \"%s\" of collection \"%s\"",
1152                    g_type_name (coltype),
1153                    g_type_name (subtype));
1154       return FALSE;
1155     }
1156
1157   instance = dbus_g_type_specialized_construct (coltype);
1158   g_value_take_boxed (value, instance);
1159
1160   dbus_g_type_specialized_init_append (value, &ctx);
1161
1162   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1163     {
1164       GValue eltval = {0, };
1165
1166       g_value_init (&eltval, subtype);
1167
1168       if (!demarshaller (context, &subiter, &eltval, error))
1169         {
1170           dbus_g_type_specialized_collection_end_append (&ctx);
1171           g_value_unset (value);
1172           return FALSE;
1173         }
1174       dbus_g_type_specialized_collection_append (&ctx, &eltval);
1175       
1176       dbus_message_iter_next (&subiter);
1177     }
1178   dbus_g_type_specialized_collection_end_append (&ctx);
1179   
1180   return TRUE;
1181 }
1182
1183 static gboolean
1184 demarshal_collection_array (DBusGValueMarshalCtx    *context,
1185                             DBusMessageIter         *iter,
1186                             GValue                  *value,
1187                             GError                 **error)
1188 {
1189   DBusMessageIter subiter;
1190   GArray *ret;
1191   GType elt_gtype;
1192   int elt_size;
1193   void *msgarray;
1194   int msgarray_len;
1195
1196   dbus_message_iter_recurse (iter, &subiter);
1197
1198   elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
1199   g_assert (elt_gtype != G_TYPE_INVALID);
1200   g_assert (_dbus_g_type_is_fixed (elt_gtype));
1201
1202   elt_size = _dbus_g_type_fixed_get_size (elt_gtype);
1203   
1204   ret = g_array_new (FALSE, TRUE, elt_size);
1205
1206   msgarray = NULL;
1207   dbus_message_iter_get_fixed_array (&subiter,
1208                                      &msgarray,
1209                                      &msgarray_len);
1210   g_assert (msgarray != NULL || msgarray_len == 0);
1211
1212   if (msgarray_len)
1213     g_array_append_vals (ret, msgarray, (guint) msgarray_len);
1214
1215   g_value_take_boxed (value, ret);
1216   
1217   return TRUE;
1218 }
1219
1220 gboolean
1221 _dbus_gvalue_demarshal (DBusGValueMarshalCtx    *context,
1222                        DBusMessageIter         *iter,
1223                        GValue                  *value,
1224                        GError                 **error)
1225 {
1226   GType gtype;
1227   DBusGValueDemarshalFunc demarshaller;
1228   gboolean retcode = FALSE;
1229
1230   if (context->recursion_depth > DBUS_GLIB_MAX_VARIANT_RECURSION)
1231     {
1232       g_set_error (error, DBUS_GERROR,
1233                    DBUS_GERROR_NO_MEMORY, 
1234                    "Variant recursion limit exceeded");
1235       return FALSE;
1236     }
1237   context->recursion_depth++;
1238
1239   gtype = G_VALUE_TYPE (value);
1240
1241   demarshaller = get_type_demarshaller (gtype);
1242
1243   if (demarshaller == NULL)
1244     {
1245       g_set_error (error,
1246                    DBUS_GERROR,
1247                    DBUS_GERROR_INVALID_ARGS,
1248                    "No demarshaller registered for type \"%s\"",
1249                    g_type_name (gtype));
1250     
1251       goto out;
1252     }
1253   
1254   retcode = demarshaller (context, iter, value, error);
1255  out:
1256   context->recursion_depth--;  
1257   return retcode;
1258 }
1259
1260 gboolean
1261 _dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx    *context,
1262                                DBusMessageIter         *iter,
1263                                GValue                  *value,
1264                                GError                 **error)
1265 {
1266   return demarshal_static_variant (context, iter, value, error);
1267 }
1268
1269 GValueArray *
1270 _dbus_gvalue_demarshal_message  (DBusGValueMarshalCtx    *context,
1271                                 DBusMessage             *message,
1272                                 guint                    n_types,
1273                                 const GType             *types,
1274                                 GError                 **error)
1275 {
1276   GValueArray *ret;
1277   DBusMessageIter iter;
1278   int current_type;
1279   guint index_;
1280   
1281   ret = g_value_array_new (6);  /* 6 is a typical maximum for arguments */
1282
1283   dbus_message_iter_init (message, &iter);
1284   index_ = 0;
1285   while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
1286     {
1287       GValue *value;
1288       GType gtype;
1289
1290       if (index_ >= n_types)
1291         {
1292           g_set_error (error, DBUS_GERROR,
1293                        DBUS_GERROR_INVALID_ARGS,
1294                        "Too many arguments in message");
1295           goto lose;
1296         }
1297       
1298       g_value_array_append (ret, NULL);
1299       value = g_value_array_get_nth (ret, index_);
1300
1301       gtype = types[index_]; 
1302       g_value_init (value, gtype);
1303
1304       if (!_dbus_gvalue_demarshal (context, &iter, value, error))
1305         goto lose;
1306       dbus_message_iter_next (&iter);
1307       index_++;
1308     }
1309   if (index_ < n_types)
1310     {
1311       g_set_error (error, DBUS_GERROR,
1312                    DBUS_GERROR_INVALID_ARGS,
1313                    "Too few arguments in message");
1314       goto lose;
1315     }
1316
1317   return ret;
1318  lose:
1319   g_value_array_free (ret);
1320   return NULL;
1321 }
1322
1323 static void oom (void) G_GNUC_NORETURN;
1324 static void
1325 oom (void)
1326 {
1327   g_error ("no memory");
1328 }
1329
1330 static gboolean
1331 marshal_basic (DBusMessageIter *iter, const GValue *value)
1332 {
1333   GType value_type;
1334
1335   value_type = G_VALUE_TYPE (value);
1336   
1337   switch (value_type)
1338     {
1339     case G_TYPE_CHAR:
1340       {
1341         char b = g_value_get_char (value);
1342         if (!dbus_message_iter_append_basic (iter,
1343                                              DBUS_TYPE_BYTE,
1344                                              &b))
1345           oom ();
1346       }
1347       return TRUE;
1348     case G_TYPE_UCHAR:
1349       {
1350         unsigned char b = g_value_get_uchar (value);
1351         if (!dbus_message_iter_append_basic (iter,
1352                                              DBUS_TYPE_BYTE,
1353                                              &b))
1354           oom ();
1355       }
1356       return TRUE;
1357     case G_TYPE_BOOLEAN:
1358       {
1359         dbus_bool_t b = g_value_get_boolean (value);
1360
1361         g_return_val_if_fail (b == TRUE || b == FALSE, FALSE);
1362
1363         if (!dbus_message_iter_append_basic (iter,
1364                                              DBUS_TYPE_BOOLEAN,
1365                                              &b))
1366           oom ();
1367       }
1368       return TRUE;
1369     case G_TYPE_INT:
1370       {
1371         dbus_int32_t v = g_value_get_int (value);
1372         if (!dbus_message_iter_append_basic (iter,
1373                                              DBUS_TYPE_INT32,
1374                                              &v))
1375           oom ();
1376       }
1377       return TRUE;
1378     case G_TYPE_UINT:
1379       {
1380         dbus_uint32_t v = g_value_get_uint (value);
1381         if (!dbus_message_iter_append_basic (iter,
1382                                              DBUS_TYPE_UINT32,
1383                                              &v))
1384           oom ();
1385       }
1386       return TRUE;
1387     case G_TYPE_LONG:
1388       {
1389         dbus_int32_t v = g_value_get_long (value);
1390         if (!dbus_message_iter_append_basic (iter,
1391                                              DBUS_TYPE_INT32,
1392                                              &v))
1393           oom ();
1394       }
1395       return TRUE;
1396     case G_TYPE_ULONG:
1397       {
1398         dbus_uint32_t v = g_value_get_ulong (value);
1399         if (!dbus_message_iter_append_basic (iter,
1400                                              DBUS_TYPE_UINT32,
1401                                              &v))
1402           oom ();
1403       }
1404       return TRUE;
1405     case G_TYPE_INT64:
1406       {
1407         gint64 v = g_value_get_int64 (value);
1408         if (!dbus_message_iter_append_basic (iter,
1409                                              DBUS_TYPE_INT64,
1410                                              &v))
1411           oom ();
1412       }
1413       return TRUE;
1414     case G_TYPE_UINT64:
1415       {
1416         guint64 v = g_value_get_uint64 (value);
1417         if (!dbus_message_iter_append_basic (iter,
1418                                              DBUS_TYPE_UINT64,
1419                                              &v))
1420           oom ();
1421       }
1422       return TRUE;
1423     case G_TYPE_FLOAT:
1424       {
1425         double v = g_value_get_float (value);
1426         
1427         if (!dbus_message_iter_append_basic (iter,
1428                                              DBUS_TYPE_DOUBLE,
1429                                              &v))
1430           oom ();
1431       }
1432       return TRUE;
1433     case G_TYPE_DOUBLE:
1434       {
1435         double v = g_value_get_double (value);
1436         
1437         if (!dbus_message_iter_append_basic (iter,
1438                                              DBUS_TYPE_DOUBLE,
1439                                              &v))
1440           oom ();
1441       }
1442       return TRUE;
1443     case G_TYPE_STRING:
1444       {
1445         const char *v = g_value_get_string (value);
1446         if (!v)
1447           v = "";
1448
1449         /* FIXME: fd.o #16320: consider using g_return_if_fail to check UTF-8
1450          * validity */
1451
1452         if (!dbus_message_iter_append_basic (iter,
1453                                              DBUS_TYPE_STRING,
1454                                              &v))
1455           {
1456             gchar *s = g_strdup_value_contents (value);
1457
1458             g_critical ("Unable to marshal string (not UTF-8 or OOM?): %s",
1459                 s);
1460             g_free (s);
1461             return FALSE;
1462           }
1463       }
1464       return TRUE;
1465       
1466     default:
1467       {
1468         g_assert_not_reached ();
1469         return FALSE;
1470       }
1471     }
1472 }
1473
1474 static gboolean
1475 marshal_strv (DBusMessageIter   *iter,
1476               const GValue       *value)
1477 {
1478   DBusMessageIter subiter;
1479   char **array;
1480   char **elt;
1481   gboolean ret = FALSE;
1482
1483   g_assert (G_VALUE_TYPE (value) == g_strv_get_type ());
1484
1485   array = g_value_get_boxed (value);
1486
1487   if (!dbus_message_iter_open_container (iter,
1488                                          DBUS_TYPE_ARRAY,
1489                                          "s",
1490                                          &subiter))
1491     goto out;
1492
1493   if (array)
1494     {
1495       for (elt = array; *elt; elt++)
1496         {
1497           if (!dbus_message_iter_append_basic (&subiter,
1498                                            DBUS_TYPE_STRING,
1499                                            elt))
1500                 goto out;
1501         }
1502     }
1503
1504   if (!dbus_message_iter_close_container (iter, &subiter))
1505     goto out;
1506   ret = TRUE;
1507  out:
1508   return ret;
1509 }
1510
1511 static gboolean
1512 marshal_valuearray (DBusMessageIter   *iter,
1513                     const GValue       *value)
1514 {
1515   GValueArray *array;
1516   guint i;
1517   DBusMessageIter subiter;
1518
1519   g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
1520
1521   array = g_value_get_boxed (value);
1522
1523   if (!dbus_message_iter_open_container (iter,
1524                                          DBUS_TYPE_STRUCT,
1525                                          NULL,
1526                                          &subiter))
1527     oom ();
1528
1529   if (array)
1530     {
1531       for (i = 0; i < array->n_values; i++)
1532         {
1533           if (!_dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i)))
1534             {
1535               dbus_message_iter_abandon_container (iter, &subiter);
1536               return FALSE;
1537             }
1538         }
1539     }
1540
1541   return dbus_message_iter_close_container (iter, &subiter);
1542 }
1543
1544 static gboolean
1545 marshal_proxy (DBusMessageIter         *iter,
1546                const GValue            *value)
1547 {
1548   const char *path;
1549   DBusGProxy *proxy;
1550
1551   g_assert (G_VALUE_TYPE (value) == dbus_g_proxy_get_type ());
1552
1553   proxy = g_value_get_object (value);
1554   g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE);
1555   path = dbus_g_proxy_get_path (proxy);
1556   g_return_val_if_fail (g_variant_is_object_path (path), FALSE);
1557
1558   if (!dbus_message_iter_append_basic (iter,
1559                                        DBUS_TYPE_OBJECT_PATH,
1560                                        &path))
1561     oom ();
1562
1563   return TRUE;
1564 }
1565
1566 static gboolean
1567 marshal_object_path (DBusMessageIter         *iter,
1568                      const GValue            *value)
1569 {
1570   const char *path;
1571
1572   g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_PATH);
1573
1574   path = g_value_get_boxed (value);
1575   g_return_val_if_fail (g_variant_is_object_path (path), FALSE);
1576
1577   if (!dbus_message_iter_append_basic (iter,
1578                                        DBUS_TYPE_OBJECT_PATH,
1579                                        &path))
1580     oom ();
1581
1582   return TRUE;
1583 }
1584
1585 static gboolean
1586 marshal_object (DBusMessageIter         *iter,
1587                 const GValue            *value)
1588 {
1589   const char *path;
1590   GObject *obj;
1591
1592   obj = g_value_get_object (value);
1593   g_return_val_if_fail (G_IS_OBJECT (obj), FALSE);
1594
1595   path = _dbus_gobject_get_path (obj);
1596   g_return_val_if_fail (g_variant_is_object_path (path), FALSE);
1597
1598   if (!dbus_message_iter_append_basic (iter,
1599                                        DBUS_TYPE_OBJECT_PATH,
1600                                        &path))
1601     oom ();
1602
1603   return TRUE;
1604 }
1605
1606 static gboolean
1607 marshal_signature (DBusMessageIter         *iter,
1608                    const GValue            *value)
1609 {
1610   const char *sig;
1611
1612   g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_SIGNATURE);
1613
1614   sig = g_value_get_boxed (value);
1615   g_return_val_if_fail (g_variant_is_signature (sig), FALSE);
1616
1617   /* failure here isn't strictly *guaranteed* to be OOM, since GDBus might
1618    * understand more type-codes than our libdbus */
1619   if (!dbus_message_iter_append_basic (iter,
1620                                        DBUS_TYPE_SIGNATURE,
1621                                        &sig))
1622     return FALSE;
1623
1624   return TRUE;
1625 }
1626
1627 struct DBusGLibHashMarshalData
1628 {
1629   const char *entry_sig;
1630   DBusMessageIter *iter;
1631   gboolean err;
1632 };
1633
1634 static void
1635 marshal_map_entry (const GValue *key,
1636                    const GValue *value,
1637                    gpointer data)
1638 {
1639   struct DBusGLibHashMarshalData *hashdata = data;
1640   DBusMessageIter subiter;
1641
1642   if (hashdata->err)
1643     return;
1644
1645   if (!dbus_message_iter_open_container (hashdata->iter,
1646                                          DBUS_TYPE_DICT_ENTRY,
1647                                          NULL,
1648                                          &subiter))
1649     goto lose;
1650
1651   if (!_dbus_gvalue_marshal (&subiter, key))
1652     goto lose;
1653
1654   if (!_dbus_gvalue_marshal (&subiter, value))
1655     goto lose;
1656
1657   if (!dbus_message_iter_close_container (hashdata->iter, &subiter))
1658     goto lose;
1659   
1660   return;
1661  lose:
1662   hashdata->err = TRUE;
1663 }
1664
1665 static gboolean
1666 marshal_map (DBusMessageIter   *iter,
1667              const GValue      *value)
1668 {
1669   GType gtype;
1670   DBusMessageIter arr_iter;
1671   struct DBusGLibHashMarshalData hashdata;
1672   char *key_sig;
1673   char *value_sig;
1674   GType key_type;
1675   GType value_type;
1676   char *entry_sig;
1677   char *array_sig;
1678
1679   gtype = G_VALUE_TYPE (value);
1680
1681   key_type = dbus_g_type_get_map_key_specialization (gtype);
1682   g_assert (_dbus_gtype_is_valid_hash_key (key_type));
1683   value_type = dbus_g_type_get_map_value_specialization (gtype);
1684   g_assert (_dbus_gtype_is_valid_hash_value (value_type));
1685
1686   key_sig = _dbus_gtype_to_signature (key_type);
1687   if (!key_sig)
1688     {
1689       g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type));
1690       return FALSE;
1691     }
1692   value_sig = _dbus_gtype_to_signature (value_type);
1693   if (!value_sig)
1694     {
1695       g_free (key_sig);
1696       g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type));
1697       return FALSE;
1698     }
1699   entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig);
1700   g_free (key_sig);
1701   g_free (value_sig);
1702   array_sig = g_strdup_printf ("%c%s%c",
1703                                DBUS_DICT_ENTRY_BEGIN_CHAR,
1704                                entry_sig,
1705                                DBUS_DICT_ENTRY_END_CHAR);
1706   if (!dbus_message_iter_open_container (iter,
1707                                          DBUS_TYPE_ARRAY,
1708                                          array_sig,
1709                                          &arr_iter))
1710     goto lose;
1711
1712   hashdata.iter = &arr_iter;
1713   hashdata.err = FALSE;
1714   hashdata.entry_sig = entry_sig;
1715
1716   dbus_g_type_map_value_iterate (value,
1717                                  marshal_map_entry,
1718                                  &hashdata);
1719
1720   if (hashdata.err)
1721     {
1722       dbus_message_iter_abandon_container (iter, &arr_iter);
1723       goto lose;
1724     }
1725   else if (!dbus_message_iter_close_container (iter, &arr_iter))
1726     {
1727       goto lose;
1728     }
1729
1730  out:
1731   g_free (entry_sig);
1732   g_free (array_sig);
1733   return !hashdata.err;
1734  lose:
1735   hashdata.err = TRUE;
1736   goto out;
1737 }
1738
1739 static gboolean
1740 marshal_struct (DBusMessageIter   *iter,
1741                 const GValue      *value)
1742 {
1743   GType gtype;
1744   DBusMessageIter subiter;
1745   guint size, i;
1746   GValue val = {0,};
1747
1748   gtype = G_VALUE_TYPE (value);
1749
1750   size = dbus_g_type_get_struct_size (gtype);
1751
1752   if (!dbus_message_iter_open_container (iter,
1753                                          DBUS_TYPE_STRUCT,
1754                                          NULL,
1755                                          &subiter))
1756     oom ();
1757
1758   for (i = 0; i < size; i++)
1759     {
1760       g_value_init (&val, dbus_g_type_get_struct_member_type
1761           (G_VALUE_TYPE(value), i));
1762
1763       if (!dbus_g_type_struct_get_member (value, i, &val))
1764         goto abandon;
1765
1766       if (!_dbus_gvalue_marshal (&subiter, &val))
1767         goto abandon;
1768
1769       g_value_unset(&val);
1770     }
1771
1772   return dbus_message_iter_close_container (iter, &subiter);
1773
1774 abandon:
1775   dbus_message_iter_abandon_container (iter, &subiter);
1776   return FALSE;
1777 }
1778
1779 static gboolean
1780 marshal_variant (DBusMessageIter          *iter,
1781                  const GValue             *value)
1782 {
1783   GType value_gtype;
1784   DBusMessageIter subiter;
1785   char *variant_sig;
1786   GValue *real_value;
1787   gboolean ret = FALSE;
1788
1789   real_value = g_value_get_boxed (value);
1790   value_gtype = G_VALUE_TYPE (real_value);
1791
1792   variant_sig = _dbus_gvalue_to_signature (real_value);
1793   if (variant_sig == NULL)
1794     {
1795       g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype));
1796       return FALSE;
1797     }
1798
1799   if (!dbus_message_iter_open_container (iter,
1800                                          DBUS_TYPE_VARIANT,
1801                                          variant_sig,
1802                                          &subiter))
1803     goto out;
1804
1805   if (!_dbus_gvalue_marshal (&subiter, real_value))
1806     {
1807       dbus_message_iter_abandon_container (iter, &subiter);
1808       goto out;
1809     }
1810
1811   if (!dbus_message_iter_close_container (iter, &subiter))
1812     goto out;
1813
1814   ret = TRUE;
1815  out:
1816   g_free (variant_sig);
1817   return ret;
1818 }
1819
1820 static DBusGValueMarshalFunc
1821 get_type_marshaller (GType type)
1822 {
1823   DBusGTypeMarshalData *typedata;
1824
1825   typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
1826   if (typedata == NULL)
1827     {
1828       if (g_type_is_a (type, G_TYPE_VALUE_ARRAY))
1829         return marshal_valuearray;
1830       if (dbus_g_type_is_collection (type))
1831         return marshal_collection;
1832       if (dbus_g_type_is_map (type))
1833         return marshal_map;
1834       if (dbus_g_type_is_struct (type))
1835         return marshal_struct;
1836
1837       g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
1838       return NULL;
1839     }
1840   g_assert (typedata->vtable);
1841   return typedata->vtable->marshaller;
1842 }
1843
1844 typedef struct
1845 {
1846   DBusMessageIter *iter;
1847   DBusGValueMarshalFunc marshaller;
1848   gboolean err;
1849 } DBusGValueCollectionMarshalData;
1850
1851 static void
1852 collection_marshal_iterator (const GValue *eltval,
1853                              gpointer      user_data)
1854 {
1855   DBusGValueCollectionMarshalData *data = user_data;
1856
1857   if (data->err)
1858     return;
1859
1860   if (!data->marshaller (data->iter, eltval))
1861     data->err = TRUE;
1862 }
1863
1864 static gboolean
1865 marshal_collection (DBusMessageIter         *iter,
1866                     const GValue            *value)
1867 {
1868   GType coltype;
1869   GType subtype;
1870   
1871   coltype = G_VALUE_TYPE (value);
1872   subtype = dbus_g_type_get_collection_specialization (coltype);
1873
1874   if (_dbus_g_type_is_fixed (subtype))
1875     return marshal_collection_array (iter, value);
1876   else
1877     return marshal_collection_ptrarray (iter, value);
1878 }
1879
1880 static gboolean
1881 marshal_collection_ptrarray (DBusMessageIter         *iter,
1882                              const GValue            *value)
1883 {
1884   GType coltype;
1885   GType elt_gtype;
1886   DBusGValueCollectionMarshalData data;
1887   DBusMessageIter subiter;
1888   char *elt_sig;
1889   
1890   coltype = G_VALUE_TYPE (value);
1891   elt_gtype = dbus_g_type_get_collection_specialization (coltype);
1892   data.marshaller = get_type_marshaller (elt_gtype);
1893   if (!data.marshaller)
1894     return FALSE;
1895
1896   elt_sig = _dbus_gtype_to_signature (elt_gtype);
1897   if (!elt_sig)
1898     {
1899       g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1900       return FALSE;
1901     }
1902   g_assert (g_variant_is_signature (elt_sig));
1903
1904   if (!dbus_message_iter_open_container (iter,
1905                                          DBUS_TYPE_ARRAY,
1906                                          elt_sig,
1907                                          &subiter))
1908     oom ();
1909
1910   g_free (elt_sig);
1911
1912   data.iter = &subiter;
1913   data.err = FALSE;
1914
1915   dbus_g_type_collection_value_iterate (value,
1916                                         collection_marshal_iterator,
1917                                         &data);
1918
1919   if (data.err)
1920     {
1921       dbus_message_iter_abandon_container (iter, &subiter);
1922       return FALSE;
1923     }
1924
1925   return dbus_message_iter_close_container (iter, &subiter);
1926 }
1927
1928 /* If any of these assertions are violated, then marshal_collection_array
1929  * is buggy for that type. dbus_g_value_basic_array_parse_variant() has
1930  * general size-conversion code, if needed. */
1931 G_STATIC_ASSERT (sizeof (dbus_bool_t) == sizeof (gboolean));
1932 G_STATIC_ASSERT (sizeof (dbus_int32_t) == sizeof (gint));
1933 G_STATIC_ASSERT (sizeof (dbus_uint32_t) == sizeof (guint));
1934 /* These should be true regardless, but just for completeness... */
1935 G_STATIC_ASSERT (sizeof (dbus_int64_t) == sizeof (gint64));
1936 G_STATIC_ASSERT (sizeof (dbus_uint64_t) == sizeof (guint64));
1937 G_STATIC_ASSERT (sizeof (double) == sizeof (gdouble));
1938
1939 static gboolean
1940 marshal_collection_array (DBusMessageIter   *iter,
1941                           const GValue      *value)
1942 {
1943   GType elt_gtype;
1944   DBusMessageIter subiter;
1945   GArray *array;
1946   char *subsignature_str;
1947
1948   array = g_value_get_boxed (value);
1949   g_return_val_if_fail (array != NULL, FALSE);
1950
1951   elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
1952   g_assert (_dbus_g_type_is_fixed (elt_gtype));
1953   subsignature_str = _dbus_gtype_to_signature (elt_gtype);
1954   if (!subsignature_str)
1955     {
1956       g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1957       return FALSE;
1958     }
1959   g_assert (g_variant_is_signature (subsignature_str));
1960
1961   if (!dbus_message_iter_open_container (iter,
1962                                          DBUS_TYPE_ARRAY,
1963                                          subsignature_str,
1964                                          &subiter))
1965     oom ();
1966
1967   /* TODO - This assumes that basic values are the same size
1968    * is this always true?  If it is we can probably avoid
1969    * a lot of the overhead in _marshal_basic_instance...
1970    */
1971   if (!dbus_message_iter_append_fixed_array (&subiter,
1972                                              subsignature_str[0],
1973                                              &(array->data),
1974                                              array->len))
1975     {
1976       g_critical ("Unable to serialize %u GArray members as signature %s "
1977           "(OOM or invalid boolean value?)", array->len, subsignature_str);
1978
1979       g_free (subsignature_str);
1980       dbus_message_iter_abandon_container (iter, &subiter);
1981       return FALSE;
1982     }
1983
1984   g_free (subsignature_str);
1985   return dbus_message_iter_close_container (iter, &subiter);
1986 }
1987
1988 gboolean
1989 _dbus_gvalue_marshal (DBusMessageIter         *iter,
1990                      const GValue       *value)
1991 {
1992   GType gtype;
1993   DBusGValueMarshalFunc marshaller;
1994
1995   gtype = G_VALUE_TYPE (value);
1996
1997   marshaller = get_type_marshaller (gtype);
1998   if (marshaller == NULL)
1999     return FALSE;
2000   return marshaller (iter, value);
2001 }
2002
2003 #ifdef DBUS_BUILD_TESTS
2004
2005 static void
2006 assert_type_maps_to (GType gtype, const char *expected_sig)
2007 {
2008   char *sig;
2009   sig = _dbus_gtype_to_signature (gtype);
2010   g_assert (sig != NULL);
2011   g_assert (!strcmp (expected_sig, sig));
2012   g_free (sig);
2013 }
2014
2015 static void
2016 assert_signature_maps_to (const char *sig, GType expected_gtype)
2017 {
2018   g_assert (_dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
2019 }
2020
2021 static void
2022 assert_bidirectional_mapping (GType gtype, const char *expected_sig)
2023 {
2024   assert_type_maps_to (gtype, expected_sig);
2025   assert_signature_maps_to (expected_sig, gtype);
2026 }
2027
2028 /*
2029  * Unit test for general glib stuff
2030  * Returns: %TRUE on success.
2031  */
2032 gboolean
2033 _dbus_gvalue_test (const char *test_data_dir)
2034 {
2035   _dbus_g_value_types_init ();
2036   
2037   assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING);
2038   assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
2039   assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
2040
2041   assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
2042                               DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
2043   assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
2044                                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING);
2045   assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT),
2046                                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);
2047
2048   assert_bidirectional_mapping (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID),
2049                                 DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING );
2050   return TRUE;
2051 }
2052
2053 #endif /* DBUS_BUILD_TESTS */