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