dbus/glib dbus-gvalue.h, 1.5, 1.6 dbus-gvalue.c, 1.15, 1.16 dbus-gvalue-utils.h, 1.1, 1.2 dbus-gvalue-utils.c, 1.1, 1.2 dbus-gtype-specialized.h, 1.1, 1.2 dbus-gtype-specialized.c, 1.1, 1.2 dbus-gtest.h, 1.5, 1.6 dbus-gtest.c, 1.5, 1.6 dbus-gproxy.c, 1.35, 1.36 dbus-gobject.c, 1.39, 1.40

Colin Walters walters at freedesktop.org
Sat Jul 9 02:25:39 EST 2005


Update of /cvs/dbus/dbus/glib
In directory gabe:/tmp/cvs-serv2325/glib

Modified Files:
	dbus-gvalue.h dbus-gvalue.c dbus-gvalue-utils.h 
	dbus-gvalue-utils.c dbus-gtype-specialized.h 
	dbus-gtype-specialized.c dbus-gtest.h dbus-gtest.c 
	dbus-gproxy.c dbus-gobject.c 
Log Message:
2005-07-08  Colin Walters  <walters at verbum.org>

	* tools/Makefile.am: Kill of print-introspect in favor of using
	dbus-send --print-reply=literal.
	* tools/print-introspect.c: Deleted.

	* test/glib/test-service-glib.xml: 
	* test/glib/test-service-glib.c (my_object_get_objs): New test
	for "ao".

	* test/glib/test-dbus-glib.c (echo_received_cb): Free echo data.
	(main): Test GetObjs.

	* glib/examples/statemachine/Makefile.am:
	* glib/examples/statemachine/sm-marshal.list:
	* glib/examples/statemachine/statemachine-client.c:
	* glib/examples/statemachine/statemachine-server.c:
	* glib/examples/statemachine/statemachine-server.xml:
	* glib/examples/statemachine/statemachine.c:
	* glib/examples/statemachine/statemachine.h:
	* glib/examples/statemachine/statemachine.xml:

	New example.

	* glib/examples/example-service.c (main): Move invocation
	of dbus_g_object_type_install_info earlier, to emphasize it
	should only be done once.

	* glib/examples/example-signal-emitter.c (main): Ditto.

	* glib/examples/Makefile.am (SUBDIRS): Include statemachine.

	* glib/dbus-gvalue.h (dbus_gtype_to_signature)
	(dbus_gvalue_marshal): Update prototypes.

	* glib/dbus-gvalue.c: Update all marshalling functions to take
	const GValue instead of GValue.
	(signature_iter_to_g_type_array): Return a GPtrArray for nonfixed
	types.
	(dbus_gvalue_to_signature): Update for dbus_gtype_to_signature
	change.
	(dbus_gtype_to_signature): Handle generic collecitons and maps.
	Return a newly-allocated string.
	(demarshal_proxy, demarshal_object_path, demarshal_object)
	(demarshal_strv, demarshal_ghashtable): Set error, don't assert if
	we get the wrong types from message.
	(get_type_demarshaller): New function, extracted from
	dbus_gvalue_demarshal.
	(demarshal_collection): New function, demarshals generic
	collection.
	(dbus_gvalue_demarshal): Just invoke result of
	get_type_demarshaller.  Throw error if we don't have one.
	(marshal_garray_basic): Abort on OOM.
	(get_type_marshaller): New function, extracted from
	dbus_gvalue_marshal.
	(collection_marshal_iterator, marshal_collection): New functions;
	implements generic marshalling for an iteratable specialized
	collection.
	(dbus_gvalue_marshal): Just invoke result of get_type_marshaller.

	* glib/dbus-gvalue-utils.c (gvalue_from_ptrarray_value): Handle
	G_TYPE_STRING.
	(ptrarray_value_from_gvalue): Ditto.
	(ptrarray_append, ptrarray_free): New functions.
	(slist_constructor, slist_iterator, slist_copy_elt, slist_copy) 
	(slist_append, slist_end_append, slist_free): New functions.
	(dbus_g_type_specialized_builtins_init): Add append fuctions
	for GPtrArray and GSList.  Register GSList.
	(test_specialized_hash, _dbus_gvalue_utils_test): New functions.

	* glib/dbus-gtype-specialized.h (DBusGTypeSpecializedAppendContext):
	New.
	(dbus_g_type_specialized_collection_init_append)
	(dbus_g_type_specialized_collection_append)
	(dbus_g_type_specialized_collection_end_append): Prototype.
	(DBusGTypeSpecializedCollectionVtable): Add append_func and
	end_append_func.

	* glib/dbus-gtype-specialized.c (dbus_g_type_specialized_collection_init_append) 
	(dbus_g_type_specialized_collection_append) 
	(dbus_g_type_specialized_collection_end_append): New functions.
	(dbus_g_type_map_value_iterate): Take const GValue.
	(dbus_g_type_collection_value_iterate): Ditto.

	* glib/dbus-gtest.c (dbus_glib_internal_do_not_use_run_tests): Run
	_dbus_gvalue_utils_test.
	
	* glib/dbus-gtest.h: Prototype it.

	* glib/dbus-gproxy.c (dbus_g_proxy_manager_filter): Avoid
	using uninitialized owner_list.
	(dbus_g_proxy_begin_call_internal): Move return_if_fail to
	public API.
	(dbus_g_proxy_end_call_internal): Update to use error set
	from dbus_gvalue_demarshal instead of setting it here.
	(dbus_g_proxy_begin_call): Move return_if_fail here.

	* glib/dbus-gobject.c (write_interface): Update for
	dbus_gtype_to_signature returning new string.

	* configure.in: Add glib/examples/statemachine.


Index: dbus-gvalue.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- dbus-gvalue.h	13 Jun 2005 03:01:24 -0000	1.5
+++ dbus-gvalue.h	8 Jul 2005 16:25:36 -0000	1.6
@@ -22,7 +22,7 @@
 GType          dbus_gtype_from_signature_iter (DBusSignatureIter       *sigiter,
 					       gboolean                 is_client);
 
-const char *   dbus_gtype_to_signature        (GType                    type);
+char *         dbus_gtype_to_signature        (GType                    type);
 
 GArray *       dbus_gtypes_from_arg_signature (const char              *signature,
 					       gboolean                 is_client);
@@ -44,7 +44,7 @@
 					       GError                 **error);
 
 gboolean       dbus_gvalue_marshal            (DBusMessageIter         *iter,
-					       GValue                  *value);
+					       const GValue            *value);
 
 G_END_DECLS
 

Index: dbus-gvalue.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dbus-gvalue.c	1 Jul 2005 15:44:12 -0000	1.15
+++ dbus-gvalue.c	8 Jul 2005 16:25:36 -0000	1.16
@@ -59,56 +59,70 @@
 };
 
 static gboolean marshal_basic                   (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_basic                 (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_strv                    (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_strv                  (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_variant                 (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_variant               (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_garray_basic            (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_garray_basic          (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_proxy                   (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue             *value);
 static gboolean demarshal_proxy                 (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_object_path             (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue             *value);
 static gboolean demarshal_object_path           (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_object                  (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_object                (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 static gboolean marshal_map                     (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 static gboolean demarshal_ghashtable            (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 
+static gboolean marshal_collection              (DBusMessageIter           *iter,
+						 const GValue              *value);
+static gboolean demarshal_collection            (DBusGValueMarshalCtx      *context,
+						 DBusMessageIter           *iter,
+						 GValue                    *value,
+						 GError                   **error);
+
+static gboolean marshal_recurse                 (DBusMessageIter           *iter,
+						 const GValue              *value);
+static gboolean demarshal_recurse               (DBusGValueMarshalCtx      *context,
+						 DBusMessageIter           *iter,
+						 GValue                    *value,
+						 GError                   **error);
+
 typedef gboolean (*DBusGValueMarshalFunc)       (DBusMessageIter           *iter,
-						 GValue                    *value);
+						 const GValue              *value);
 typedef gboolean (*DBusGValueDemarshalFunc)     (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
@@ -602,6 +616,9 @@
     return G_TYPE_STRV;
   if (dbus_g_type_is_fixed (elt_gtype))
     return dbus_g_type_get_collection ("GArray", elt_gtype);
+  else if (g_type_is_a (elt_gtype, G_TYPE_OBJECT)
+	   || g_type_is_a (elt_gtype, G_TYPE_BOXED))
+    return dbus_g_type_get_collection ("GPtrArray", elt_gtype);
 
   /* Later we need to return DBUS_TYPE_G_VALUE */
   return G_TYPE_INVALID; 
@@ -681,11 +698,11 @@
 static char *
 dbus_gvalue_to_signature (GValue *value)
 {
-  const char *ret;
+  char *ret;
 
   ret = dbus_gtype_to_signature (G_VALUE_TYPE (value));
   if (ret)
-    return g_strdup (ret);
+    return ret;
   else
     {
       DBusGValue *val;
@@ -698,15 +715,45 @@
     }
 }
 
-const char *
+char *
 dbus_gtype_to_signature (GType gtype)
 {
+  char *ret;
   DBusGTypeMarshalData *typedata;
 
   typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
   if (typedata == NULL)
     return NULL;
-  return typedata->sig;
+
+  if (dbus_g_type_is_collection (gtype))
+    {
+      GType elt_gtype;
+      char *subsig;
+
+      elt_gtype = dbus_g_type_get_collection_specialization (gtype);
+      subsig = dbus_gtype_to_signature (elt_gtype);
+      ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING, subsig, NULL);
+      g_free (subsig);
+    }
+  else if (dbus_g_type_is_map (gtype))
+    {
+      GType key_gtype;
+      GType val_gtype;
+      char *key_subsig;
+      char *val_subsig;
+
+      key_gtype = dbus_g_type_get_map_key_specialization (gtype);
+      val_gtype = dbus_g_type_get_map_value_specialization (gtype);
+      key_subsig = dbus_gtype_to_signature (key_gtype);
+      val_subsig = dbus_gtype_to_signature (val_gtype);
+      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);
+      g_free (key_subsig);
+      g_free (val_subsig);
+    }
+  else
+    ret = g_strdup (typedata->sig);
+  
+  return ret;
 }
 
 GArray *
@@ -878,7 +925,14 @@
   int current_type;
 
   current_type = dbus_message_iter_get_arg_type (iter);
-  g_assert (current_type == DBUS_TYPE_OBJECT_PATH);
+  if (current_type != DBUS_TYPE_OBJECT_PATH)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
 
   g_assert (context->proxy != NULL);
   
@@ -900,7 +954,14 @@
   int current_type;
 
   current_type = dbus_message_iter_get_arg_type (iter);
-  g_assert (current_type == DBUS_TYPE_OBJECT_PATH);
+  if (current_type != DBUS_TYPE_OBJECT_PATH)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
 
   dbus_message_iter_get_basic (iter, &objpath);
 
@@ -920,7 +981,14 @@
   GObject *obj;
 
   current_type = dbus_message_iter_get_arg_type (iter);
-  g_assert (current_type == DBUS_TYPE_OBJECT_PATH);
+  if (current_type != DBUS_TYPE_OBJECT_PATH)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
   g_assert (context->proxy == NULL);
 
   dbus_message_iter_get_basic (iter, &objpath);
@@ -952,8 +1020,29 @@
   int len;
   int i;
 
+  current_type = dbus_message_iter_get_arg_type (iter);
+  if (current_type != DBUS_TYPE_ARRAY)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
+
   dbus_message_iter_recurse (iter, &subiter);
 
+  current_type = dbus_message_iter_get_arg_type (&subiter);
+  if (current_type != DBUS_TYPE_INVALID
+      && current_type != DBUS_TYPE_STRING)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS string, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
+
   len = dbus_message_iter_get_array_len (&subiter);
   g_assert (len >= 0);
   ret = g_malloc (sizeof (char *) * (len + 1));
@@ -1026,13 +1115,29 @@
   GType value_gtype;
 
   current_type = dbus_message_iter_get_arg_type (iter);
-  g_assert (current_type == DBUS_TYPE_ARRAY);
+  if (current_type != DBUS_TYPE_ARRAY)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
 
   gtype = G_VALUE_TYPE (value);
 
   dbus_message_iter_recurse (iter, &subiter);
 
-  g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_DICT_ENTRY);
+  current_type = dbus_message_iter_get_arg_type (&subiter);
+  if (current_type != DBUS_TYPE_INVALID
+      && current_type != DBUS_TYPE_DICT_ENTRY)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS dict entry, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
 
   key_gtype = dbus_g_type_get_map_key_specialization (gtype);
   g_assert (dbus_gtype_is_valid_hash_key (key_gtype));
@@ -1083,6 +1188,95 @@
   return TRUE;
 }
 
+static DBusGValueDemarshalFunc
+get_type_demarshaller (GType type)
+{
+  DBusGTypeMarshalData *typedata;
+
+  typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
+  if (typedata == NULL)
+    {
+      if (g_type_is_a (type, DBUS_TYPE_G_VALUE))
+	return demarshal_recurse;
+      if (dbus_g_type_is_collection (type))
+	return demarshal_collection;
+
+      g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
+      return NULL;
+    }
+  g_assert (typedata->vtable);
+  return typedata->vtable->demarshaller;
+}
+
+static gboolean
+demarshal_collection (DBusGValueMarshalCtx    *context,
+		      DBusMessageIter         *iter,
+		      GValue                  *value,
+		      GError                 **error)
+{
+  GType coltype;
+  GType subtype;
+  gpointer instance;
+  DBusGTypeSpecializedAppendContext ctx;
+  DBusGValueDemarshalFunc demarshaller;
+  DBusMessageIter subiter;
+  int current_type;
+
+  current_type = dbus_message_iter_get_arg_type (iter);
+
+  if (current_type != DBUS_TYPE_ARRAY)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
+      return FALSE;
+    }
+
+  dbus_message_iter_recurse (iter, &subiter);
+  
+  coltype = G_VALUE_TYPE (value);
+  subtype = dbus_g_type_get_collection_specialization (coltype);
+
+  demarshaller = get_type_demarshaller (subtype);
+
+  if (!demarshaller)
+    {
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("No demarshaller registered for type \"%s\" of collection \"%s\""),
+		   g_type_name (coltype),
+		   g_type_name (subtype));
+      return FALSE;
+    }
+
+  instance = dbus_g_type_specialized_construct (coltype);
+  g_value_set_boxed_take_ownership (value, instance);
+
+  dbus_g_type_specialized_collection_init_append (value, &ctx);
+
+  while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
+    {
+      GValue eltval = {0, };
+
+      g_value_init (&eltval, subtype);
+
+      if (!demarshaller (context, &subiter, &eltval, error))
+	{
+	  dbus_g_type_specialized_collection_end_append (&ctx);
+	  g_value_unset (value);
+	  return FALSE;
+	}
+      dbus_g_type_specialized_collection_append (&ctx, &eltval);
+      
+      dbus_message_iter_next (&subiter);
+    }
+  dbus_g_type_specialized_collection_end_append (&ctx);
+  
+  return TRUE;
+}
+
 static gboolean
 demarshal_recurse (DBusGValueMarshalCtx    *context,
 		   DBusMessageIter         *iter,
@@ -1099,21 +1293,23 @@
 		       GError                 **error)
 {
   GType gtype;
-  DBusGTypeMarshalData *typedata;
+  DBusGValueDemarshalFunc demarshaller;
 
   gtype = G_VALUE_TYPE (value);
 
-  typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
-  g_return_val_if_fail (typedata != NULL || g_type_is_a (gtype, DBUS_TYPE_G_VALUE), FALSE);
+  demarshaller = get_type_demarshaller (gtype);
 
-  if (typedata == NULL)
+  if (demarshaller == NULL)
     {
-      if (g_type_is_a (gtype, DBUS_TYPE_G_VALUE))
-	return demarshal_recurse (context, iter, value, error);
-      g_assert_not_reached ();
+      g_set_error (error,
+		   DBUS_GERROR,
+		   DBUS_GERROR_INVALID_ARGS,
+		   _("No demarshaller registered for type \"%s\""),
+		   g_type_name (gtype));
+      return FALSE;
     }
-  g_assert (typedata->vtable);
-  return typedata->vtable->demarshaller (context, iter, value, error);
+  
+  return demarshaller (context, iter, value, error);
 }
 
 gboolean
@@ -1180,7 +1376,7 @@
 }
 
 static gboolean
-marshal_basic (DBusMessageIter *iter, GValue *value)
+marshal_basic (DBusMessageIter *iter, const GValue *value)
 {
   GType value_type;
 
@@ -1316,7 +1512,7 @@
 
 static gboolean
 marshal_strv (DBusMessageIter   *iter,
-	      GValue             *value)
+	      const GValue       *value)
 {
   DBusMessageIter subiter;
   char **array;
@@ -1350,14 +1546,13 @@
 
 static gboolean
 marshal_garray_basic (DBusMessageIter   *iter,
-		      GValue            *value)
+		      const GValue      *value)
 {
   GType elt_gtype;
   DBusMessageIter subiter;
   GArray *array;
   guint elt_size;
-  const char *subsignature_str;
-  gboolean ret = FALSE;
+  char *subsignature_str;
 
   elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
   /* FIXME - this means we can't send an array of DBusGValue right now... */
@@ -1372,7 +1567,7 @@
 					 DBUS_TYPE_ARRAY,
 					 subsignature_str,
 					 &subiter))
-    goto out;
+    goto oom;
 
   /* TODO - This assumes that basic values are the same size
    * is this always true?  If it is we can probably avoid
@@ -1382,18 +1577,20 @@
 					     subsignature_str[0],
 					     &(array->data),
 					     array->len))
-    goto out;
+    goto oom;
 
   if (!dbus_message_iter_close_container (iter, &subiter))
-    goto out;
-  ret = TRUE;
- out:
-  return ret;
+    goto oom;
+  g_free (subsignature_str);
+  return TRUE;
+ oom:
+  g_error ("out of memory");
+  return FALSE;
 }
 
 static gboolean
 marshal_proxy (DBusMessageIter         *iter,
-	       GValue                  *value)
+	       const GValue            *value)
 {
   const char *path;
   DBusGProxy *proxy;
@@ -1412,7 +1609,7 @@
 
 static gboolean
 marshal_object_path (DBusMessageIter         *iter,
-		     GValue                  *value)
+		     const GValue            *value)
 {
   const char *path;
 
@@ -1429,7 +1626,7 @@
 
 static gboolean
 marshal_object (DBusMessageIter         *iter,
-		GValue                  *value)
+		const GValue            *value)
 {
   const char *path;
   GObject *obj;
@@ -1472,10 +1669,10 @@
 					 &subiter))
     goto lose;
 
-  if (!dbus_gvalue_marshal (&subiter, (GValue*) key))
+  if (!dbus_gvalue_marshal (&subiter, key))
     goto lose;
 
-  if (!dbus_gvalue_marshal (&subiter, (GValue*) value))
+  if (!dbus_gvalue_marshal (&subiter, value))
     goto lose;
 
   if (!dbus_message_iter_close_container (hashdata->iter, &subiter))
@@ -1488,7 +1685,7 @@
 
 static gboolean
 marshal_map (DBusMessageIter   *iter,
-	     GValue            *value)
+	     const GValue      *value)
 {
   GType gtype;
   DBusMessageIter arr_iter;
@@ -1545,7 +1742,7 @@
 
 static gboolean
 marshal_variant (DBusMessageIter          *iter,
-		 GValue                   *value)
+		 const GValue             *value)
 {
   GType value_gtype;
   DBusMessageIter subiter;
@@ -1582,29 +1779,106 @@
   return ret;
 }
 
+static DBusGValueMarshalFunc
+get_type_marshaller (GType type)
+{
+  DBusGTypeMarshalData *typedata;
+
+  typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
+  if (typedata == NULL)
+    {
+      if (g_type_is_a (type, DBUS_TYPE_G_VALUE))
+	return marshal_recurse;
+      if (dbus_g_type_is_collection (type))
+	return marshal_collection;
+
+      g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
+      return NULL;
+    }
+  g_assert (typedata->vtable);
+  return typedata->vtable->marshaller;
+}
+
+typedef struct
+{
+  DBusMessageIter *iter;
+  DBusGValueMarshalFunc marshaller;
+  gboolean err;
+} DBusGValueCollectionMarshalData;
+
+static void
+collection_marshal_iterator (const GValue *eltval,
+			     gpointer      user_data)
+{
+  DBusGValueCollectionMarshalData *data = user_data;
+
+  if (data->err)
+    return;
+
+  if (!data->marshaller (data->iter, eltval))
+    data->err = TRUE;
+}
+
+static gboolean
+marshal_collection (DBusMessageIter         *iter,
+		    const GValue            *value)
+{
+  GType coltype;
+  GType elt_gtype;
+  DBusGValueCollectionMarshalData data;
+  DBusMessageIter subiter;
+  char *elt_sig;
+  
+  coltype = G_VALUE_TYPE (value);
+  elt_gtype = dbus_g_type_get_collection_specialization (coltype);
+  data.marshaller = get_type_marshaller (elt_gtype);
+  if (!data.marshaller)
+    return FALSE;
+
+  /* FIXME - this means we can't send an array of DBusGValue right now... */
+  elt_sig = dbus_gtype_to_signature (elt_gtype);
+
+  if (!dbus_message_iter_open_container (iter,
+					 DBUS_TYPE_ARRAY,
+					 elt_sig,
+					 &subiter))
+    goto oom;
+  g_free (elt_sig);
+
+  data.iter = &subiter;
+  data.err = FALSE;
+
+  dbus_g_type_collection_value_iterate (value,
+					collection_marshal_iterator,
+					&data);
+
+  if (!dbus_message_iter_close_container (iter, &subiter))
+    goto oom;
+  
+  return !data.err;
+ oom:
+  g_error ("out of memory");
+  return FALSE;
+}
+
 static gboolean
 marshal_recurse (DBusMessageIter         *iter,
-		 GValue                  *value)
+		 const GValue            *value)
 {
   return FALSE;
 }
 
 gboolean
 dbus_gvalue_marshal (DBusMessageIter         *iter,
-		     GValue                  *value)
+		     const GValue       *value)
 {
   GType gtype;
-  DBusGTypeMarshalData *typedata;
+  DBusGValueMarshalFunc marshaller;
 
   gtype = G_VALUE_TYPE (value);
 
-  typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
-  if (typedata == NULL)
-    {
-      if (g_type_is_a (gtype, DBUS_TYPE_G_VALUE))
-	return marshal_recurse (iter, value);
-      return FALSE;
-    }
-  g_assert (typedata->vtable);
-  return typedata->vtable->marshaller (iter, value);
+  marshaller = get_type_marshaller (gtype);
+  if (marshaller == NULL)
+    return FALSE;
+  return marshaller (iter, value);
 }

Index: dbus-gvalue-utils.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-gvalue-utils.h	13 Jun 2005 03:01:24 -0000	1.1
+++ dbus-gvalue-utils.h	8 Jul 2005 16:25:36 -0000	1.2
@@ -64,7 +64,6 @@
 gboolean       dbus_gvalue_take                      (GValue          *value,
 						      GTypeCValue     *cvalue);
 
-
 G_END_DECLS
 
 #endif

Index: dbus-gvalue-utils.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-gvalue-utils.c	13 Jun 2005 03:01:24 -0000	1.1
+++ dbus-gvalue-utils.c	8 Jul 2005 16:25:36 -0000	1.2
@@ -21,8 +21,10 @@
  *
  */
 
+#include <config.h>
 #include "dbus/dbus-glib.h"
 #include "dbus-gvalue-utils.h"
+#include "dbus-gtest.h"
 #include <glib.h>
 #include <string.h>
 #include <gobject/gvaluecollector.h>
@@ -572,6 +574,9 @@
 {
   switch (g_type_fundamental (G_VALUE_TYPE (value)))
     {
+    case G_TYPE_STRING:
+      g_value_set_string (value, instance);
+      break;
     case G_TYPE_POINTER:
       g_value_set_pointer (value, instance);
       break;
@@ -593,6 +598,9 @@
 {
   switch (g_type_fundamental (G_VALUE_TYPE (value)))
     {
+    case G_TYPE_STRING:
+      return (gpointer) g_value_get_string (value);
+      break;
     case G_TYPE_POINTER:
       return g_value_get_pointer (value);
       break;
@@ -659,11 +667,105 @@
 }
 
 static void
+ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+{
+  GPtrArray *array;
+
+  array = g_value_get_boxed (ctx->val);
+
+  g_ptr_array_add (array, ptrarray_value_from_gvalue (value));
+}
+
+static void
 ptrarray_free (GType type, gpointer val)
 {
-  GArray *array;
+  GPtrArray *array;
   array = val;
-  g_array_free (array, TRUE);
+  g_ptr_array_free (array, TRUE);
+}
+
+static gpointer
+slist_constructor (GType type)
+{
+  return NULL;
+}
+
+static void
+slist_iterator (GType                                   list_type,
+		gpointer                                instance,
+		DBusGTypeSpecializedCollectionIterator  iterator,
+		gpointer                                user_data)
+{
+  GSList *slist;
+  GType elt_gtype;
+
+  slist = instance;
+
+  elt_gtype = dbus_g_type_get_collection_specialization (list_type);
+
+  while (slist != NULL)
+    {
+      GValue val = {0, };
+      g_value_init (&val, elt_gtype);
+      gvalue_from_ptrarray_value (&val, slist->data);
+      iterator (&val, user_data);
+    }
+}
+
+static void
+slist_copy_elt (const GValue *val, gpointer user_data)
+{
+  GSList *dest = user_data;
+  GValue val_copy = {0, }; 
+  
+  g_value_init (&val_copy, G_VALUE_TYPE (val));
+  g_value_copy (val, &val_copy);
+
+  g_slist_append (dest, ptrarray_value_from_gvalue (&val_copy));
+}
+
+static gpointer
+slist_copy (GType type, gpointer src)
+{
+  GSList *new;
+  GValue slist_val = {0, };
+
+  g_value_init (&slist_val, type);
+  g_value_set_static_boxed (&slist_val, src);
+
+  new = slist_constructor (type);
+  dbus_g_type_collection_value_iterate (&slist_val, slist_copy_elt, new);
+
+  return new;
+}
+
+static void
+slist_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+{
+  GSList *list;
+
+  list = g_value_get_boxed (ctx->val);
+  list = g_slist_prepend (list, ptrarray_value_from_gvalue (value));
+  g_value_set_static_boxed (ctx->val, list);
+}
+
+static void
+slist_end_append (DBusGTypeSpecializedAppendContext *ctx)
+{
+  GSList *list;
+
+  list = g_value_get_boxed (ctx->val);
+  list = g_slist_reverse (list);
+
+  g_value_set_static_boxed (ctx->val, list);
+}
+
+static void
+slist_free (GType type, gpointer val)
+{
+  GSList *list;
+  list = val;
+  g_slist_free (list);
 }
 
 void
@@ -674,11 +776,10 @@
       array_constructor,
       array_free,
       array_copy,
-      NULL,
-      NULL,
-      NULL
     },
     array_fixed_accessor,
+    NULL,
+    NULL,
     NULL
   };
 
@@ -689,16 +790,29 @@
       ptrarray_constructor,
       ptrarray_free,
       ptrarray_copy,
-      NULL,
-      NULL,
-      NULL
     },
     NULL,
-    ptrarray_iterator
+    ptrarray_iterator,
+    ptrarray_append,
+    NULL,
   };
 
   dbus_g_type_register_collection ("GPtrArray", &ptrarray_vtable, 0);
 
+  static const DBusGTypeSpecializedCollectionVtable slist_vtable = {
+    {
+      slist_constructor,
+      slist_free,
+      slist_copy,
+    },
+    NULL,
+    slist_iterator,
+    slist_append,
+    slist_end_append,
+  };
+
+  dbus_g_type_register_collection ("GSList", &slist_vtable, 0);
+
   static const DBusGTypeSpecializedMapVtable hashtable_vtable = {
     {
       hashtable_constructor,
@@ -713,3 +827,132 @@
 
   dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0);
 }
+
+#ifdef DBUS_BUILD_TESTS
+
+typedef struct
+{
+  gboolean seen_foo;
+  gboolean seen_baz;
+} TestSpecializedHashData;
+
+static void
+test_specialized_hash (const GValue *key, const GValue *val, gpointer user_data)
+{
+  TestSpecializedHashData *data = user_data;
+
+  g_assert (G_VALUE_HOLDS_STRING (key));
+  g_assert (G_VALUE_HOLDS_STRING (val));
+
+  if (!strcmp (g_value_get_string (key), "foo"))
+    {
+      data->seen_foo = TRUE;
+      g_assert (!strcmp (g_value_get_string (val), "bar"));
+    }
+  else if (!strcmp (g_value_get_string (key), "baz"))
+    {
+      data->seen_baz = TRUE;
+      g_assert (!strcmp (g_value_get_string (val), "moo"));
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+}
+
+gboolean
+_dbus_gvalue_utils_test (const char *datadir)
+{
+  GType type;
+
+  dbus_g_type_specialized_init ();
+  dbus_g_type_specialized_builtins_init ();
+
+  type = dbus_g_type_get_collection ("GArray", G_TYPE_UINT);
+  g_assert (dbus_g_type_is_collection (type));
+  g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_UINT);
+  {
+    GArray *instance;
+
+    instance = dbus_g_type_specialized_construct (type);
+
+    g_assert (instance->len == 0);
+
+    g_array_free (instance, TRUE);
+  }
+
+  type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING);
+  g_assert (dbus_g_type_is_map (type));
+  g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING);
+  g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_STRING);
+  {
+    GHashTable *instance;
+    GValue val = { 0, };
+    TestSpecializedHashData hashdata;
+
+    instance = dbus_g_type_specialized_construct (type);
+
+    g_assert (g_hash_table_size (instance) == 0);
+    g_hash_table_insert (instance, g_strdup ("foo"), g_strdup ("bar"));
+    g_hash_table_insert (instance, g_strdup ("baz"), g_strdup ("moo"));
+    g_assert (g_hash_table_size (instance) == 2);
+
+    g_value_init (&val, type);
+    g_value_set_boxed_take_ownership (&val, instance);
+    hashdata.seen_foo = FALSE;
+    hashdata.seen_baz = FALSE;
+    dbus_g_type_map_value_iterate (&val,
+				   test_specialized_hash, 
+				   &hashdata);
+    
+    g_assert (hashdata.seen_foo);
+    g_assert (hashdata.seen_baz);
+
+    g_value_unset (&val);
+  }
+
+  type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING);
+  g_assert (dbus_g_type_is_collection (type));
+  g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_STRING);
+  {
+    GPtrArray *instance;
+    DBusGTypeSpecializedAppendContext ctx;
+    GValue val = {0, };
+    GValue eltval = {0, };
+
+    instance = dbus_g_type_specialized_construct (type);
+
+    g_assert (instance->len == 0);
+
+    g_value_init (&val, type);
+    g_value_set_boxed_take_ownership (&val, instance);
+
+    dbus_g_type_specialized_collection_init_append (&val, &ctx);
+
+    g_value_init (&eltval, G_TYPE_STRING);
+    g_value_set_static_string (&eltval, "foo");
+    dbus_g_type_specialized_collection_append (&ctx, &eltval);
+
+    g_value_reset (&eltval);
+    g_value_set_static_string (&eltval, "bar");
+    dbus_g_type_specialized_collection_append (&ctx, &eltval);
+
+    g_value_reset (&eltval);
+    g_value_set_static_string (&eltval, "baz");
+    dbus_g_type_specialized_collection_append (&ctx, &eltval);
+
+    dbus_g_type_specialized_collection_end_append (&ctx);
+
+    g_assert (instance->len == 3);
+
+    g_assert (!strcmp ("foo", g_ptr_array_index (instance, 0)));
+    g_assert (!strcmp ("bar", g_ptr_array_index (instance, 1)));
+    g_assert (!strcmp ("baz", g_ptr_array_index (instance, 2)));
+
+    g_value_unset (&val);
+  }
+
+  return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */

Index: dbus-gtype-specialized.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-gtype-specialized.h	13 Jun 2005 03:01:24 -0000	1.1
+++ dbus-gtype-specialized.h	8 Jul 2005 16:25:36 -0000	1.2
@@ -48,21 +48,37 @@
 
 gpointer       dbus_g_type_specialized_construct            (GType type);
 
+typedef struct {
+  /* public */
+  GValue *val;
+  GType specialization_type;
+  /* padding */
+  gpointer b;
+  guint c;
+  gpointer d;
+} DBusGTypeSpecializedAppendContext;
+
+void           dbus_g_type_specialized_collection_init_append  (GValue *val, DBusGTypeSpecializedAppendContext *ctx);
+
+void           dbus_g_type_specialized_collection_append       (DBusGTypeSpecializedAppendContext *ctx, const GValue *elt);
+
+void           dbus_g_type_specialized_collection_end_append   (DBusGTypeSpecializedAppendContext *ctx);
+
 gboolean       dbus_g_type_collection_get_fixed             (GValue                                 *value,
 							     gpointer                               *data,
 							     guint                                  *len);
 
-void           dbus_g_type_collection_value_iterate         (GValue                                 *value,
+void           dbus_g_type_collection_value_iterate         (const GValue                           *value,
 							     DBusGTypeSpecializedCollectionIterator  iterator,
 							     gpointer                                user_data);
 
-void           dbus_g_type_map_value_iterate                (GValue                                 *value,
+void           dbus_g_type_map_value_iterate                (const GValue                           *value,
 							     DBusGTypeSpecializedMapIterator         iterator,
 							     gpointer                                user_data);
 
-typedef gpointer (*DBusGTypeSpecializedConstructor) (GType type);
-typedef void     (*DBusGTypeSpecializedFreeFunc)    (GType type, gpointer val);
-typedef gpointer (*DBusGTypeSpecializedCopyFunc)    (GType type, gpointer src);
+typedef gpointer (*DBusGTypeSpecializedConstructor)     (GType type);
+typedef void     (*DBusGTypeSpecializedFreeFunc)        (GType type, gpointer val);
+typedef gpointer (*DBusGTypeSpecializedCopyFunc)        (GType type, gpointer src);
 
 typedef struct {
   DBusGTypeSpecializedConstructor    constructor;
@@ -74,12 +90,16 @@
 } DBusGTypeSpecializedVtable;
 
 typedef gboolean (*DBusGTypeSpecializedCollectionFixedAccessorFunc) (GType type, gpointer instance, gpointer *values, guint *len);
-typedef void (*DBusGTypeSpecializedCollectionIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data);
+typedef void (*DBusGTypeSpecializedCollectionIteratorFunc)          (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data);
+typedef void     (*DBusGTypeSpecializedCollectionAppendFunc)        (DBusGTypeSpecializedAppendContext *ctx, const GValue *val);
+typedef void     (*DBusGTypeSpecializedCollectionEndAppendFunc)     (DBusGTypeSpecializedAppendContext *ctx);
 
 typedef struct {
   DBusGTypeSpecializedVtable                        base_vtable;
   DBusGTypeSpecializedCollectionFixedAccessorFunc   fixed_accessor;
   DBusGTypeSpecializedCollectionIteratorFunc        iterator;
+  DBusGTypeSpecializedCollectionAppendFunc          append_func;
+  DBusGTypeSpecializedCollectionEndAppendFunc       end_append_func;
 } DBusGTypeSpecializedCollectionVtable;
 
 typedef void (*DBusGTypeSpecializedMapIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedMapIterator iterator, gpointer user_data);

Index: dbus-gtype-specialized.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-gtype-specialized.c	13 Jun 2005 03:01:24 -0000	1.1
+++ dbus-gtype-specialized.c	8 Jul 2005 16:25:36 -0000	1.2
@@ -401,7 +401,7 @@
 }
 
 void
-dbus_g_type_collection_value_iterate (GValue                                 *value,
+dbus_g_type_collection_value_iterate (const GValue                           *value,
 				      DBusGTypeSpecializedCollectionIterator  iterator,
 				      gpointer                                user_data)
 {
@@ -420,8 +420,48 @@
 									    iterator, user_data);
 }
 
+typedef struct {
+  GValue *val;
+  GType specialization_type;
+  DBusGTypeSpecializedData *specdata;
+} DBusGTypeSpecializedAppendContextReal;
+
 void
-dbus_g_type_map_value_iterate (GValue                                 *value,
+dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
+{
+  DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
+  GType gtype;
+  DBusGTypeSpecializedData *specdata;
+  
+  g_return_if_fail (specialized_types_is_initialized ());
+  g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
+  gtype = G_VALUE_TYPE (value);
+  specdata = lookup_specialization_data (gtype);
+  g_return_if_fail (specdata != NULL);
+  
+  realctx->val = value;
+  realctx->specialization_type = specdata->types[0];
+  realctx->specdata = specdata;
+}
+
+void
+dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
+					   const GValue *elt)
+{
+  DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
+  ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
+}
+
+void
+dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx)
+{
+  DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
+  if (((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func != NULL)
+    ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func (ctx);
+}
+
+void
+dbus_g_type_map_value_iterate (const GValue                           *value,
 			       DBusGTypeSpecializedMapIterator         iterator,
 			       gpointer                                user_data)
 {

Index: dbus-gtest.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtest.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- dbus-gtest.h	10 Aug 2004 03:07:01 -0000	1.5
+++ dbus-gtest.h	8 Jul 2005 16:25:36 -0000	1.6
@@ -30,6 +30,7 @@
 gboolean _dbus_gobject_test (const char *test_data_dir);
 gboolean _dbus_gutils_test  (const char *test_data_dir);
 gboolean _dbus_glib_test    (const char *test_data_dir);
+gboolean _dbus_gvalue_utils_test    (const char *test_data_dir);
 
 void dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir);
 

Index: dbus-gtest.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtest.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- dbus-gtest.c	10 Aug 2004 03:07:01 -0000	1.5
+++ dbus-gtest.c	8 Jul 2005 16:25:36 -0000	1.6
@@ -25,6 +25,7 @@
 #include "dbus-gtest.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <glib.h>
 
 #ifdef DBUS_BUILD_TESTS
 static void
@@ -56,6 +57,12 @@
   else
     printf ("No test data!\n");
 
+  g_type_init ();
+
+  printf ("%s: running GValue util tests\n", "dbus-glib-test");
+  if (!_dbus_gvalue_utils_test (test_data_dir))
+    die ("gvalue utils");
+
   printf ("%s: running glib tests\n", "dbus-glib-test");
   if (!_dbus_glib_test (test_data_dir))
     die ("glib");

Index: dbus-gproxy.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gproxy.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- dbus-gproxy.c	6 Jul 2005 21:27:49 -0000	1.35
+++ dbus-gproxy.c	8 Jul 2005 16:25:36 -0000	1.36
@@ -1204,7 +1204,8 @@
 						  dbus_message_get_interface (message));
 
 	      owner_list = g_hash_table_lookup (manager->proxy_lists, tri);
-	      full_list = g_slist_concat (full_list, g_slist_copy (owner_list->proxies));
+	      if (owner_list != NULL)
+		full_list = g_slist_concat (full_list, g_slist_copy (owner_list->proxies));
 	      g_free (tri);
 	    }
 	}
@@ -2033,9 +2034,6 @@
   GPendingNotifyClosure *closure;
   guint call_id;
 
-  g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE);
-  g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE);
-
   pending = NULL;
 
   message = dbus_g_proxy_marshal_args_to_message (proxy, method, args);
@@ -2152,26 +2150,8 @@
 	    {
 	      g_value_init (&gvalue, valtype);
 
-	      /* FIXME, should use error here instead of NULL */ 
-	      if (!dbus_gvalue_demarshal (&context, &msgiter, &gvalue, NULL))
-		{
-		  g_set_error (error,
-			       DBUS_GERROR,
-			       DBUS_GERROR_INVALID_ARGS,
-			       _("Couldn't convert argument, expected \"%s\""),
-			       g_type_name (valtype));
-		  goto out;
-		}
-
-	      if (G_VALUE_TYPE (&gvalue) != valtype)
-		{
-		  g_set_error (error, DBUS_GERROR,
-			       DBUS_GERROR_INVALID_ARGS,
-			       _("Reply argument was \"%s\", expected \"%s\""),
-			       g_type_name (G_VALUE_TYPE (&gvalue)),
-			       g_type_name (valtype));  
-		  goto out;
-		}
+	      if (!dbus_gvalue_demarshal (&context, &msgiter, &gvalue, error))
+		goto out;
 
 	      /* Anything that can be demarshaled must be storable */
 	      if (!dbus_gvalue_store (&gvalue, (gpointer*) return_storage))
@@ -2274,6 +2254,9 @@
   va_list args;
   GValueArray *arg_values;
   
+  g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE);
+  g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE);
+
   va_start (args, first_arg_type);
 
   DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args);

Index: dbus-gobject.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gobject.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- dbus-gobject.c	6 Jul 2005 21:27:49 -0000	1.39
+++ dbus-gobject.c	8 Jul 2005 16:25:37 -0000	1.40
@@ -358,13 +358,14 @@
 
       for (arg = 0; arg < query.n_params; arg++)
 	{
-	  const char *dbus_type = dbus_gtype_to_signature (query.param_types[arg]);
+	  char *dbus_type = dbus_gtype_to_signature (query.param_types[arg]);
 
 	  g_assert (dbus_type != NULL);
 
           g_string_append (xml, "      <arg type=\"");
           g_string_append (xml, dbus_type);
           g_string_append (xml, "\"/>\n");
+	  g_free (dbus_type);
 	}
 
       g_string_append (xml, "    </signal>\n");
@@ -376,7 +377,7 @@
     {
       const char *propname;
       GParamSpec *spec;
-      const char *dbus_type;
+      char *dbus_type;
       gboolean can_set;
       gboolean can_get;
       char *s;
@@ -417,6 +418,7 @@
 	  g_string_append (xml, "\"/>\n");
 	}
       
+      g_free (dbus_type);
       g_free (s);
 
       g_string_append (xml, "    </property>\n");



More information about the dbus-commit mailing list