dbus/glib dbus-gvalue.c, 1.16, 1.17 dbus-gvalue-utils.c, 1.2, 1.3 dbus-gtype-specialized.h, 1.2, 1.3 dbus-gtype-specialized.c, 1.2, 1.3 dbus-gtest.h, 1.6, 1.7 dbus-gtest.c, 1.6, 1.7

Colin Walters walters at freedesktop.org
Sat Jul 9 11:46:53 EST 2005


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

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

	* test/glib/test-service-glib.xml: 
	* test/glib/test-service-glib.c:
	* test/glib/test-dbus-glib.c: Test a{sv}.

	* glib/examples/statemachine/statemachine.c:
	* glib/examples/statemachine/statemachine-server.c:
	* glib/examples/statemachine/statemachine-client.c: Fix some bugs,
	add progress bar, etc.

	* glib/dbus-gvalue.c (register_array, register_dict): Delete; not
	needed anymore due to generic array/map marshalling.
	(dbus_g_value_types_init): Don't register basic arrays or the
	string/string hash.
	(dbus_gtype_from_signature_iter): Don't try to recurse into
	variants.
	(dbus_gtype_to_signature): Check collection/map before type
	metadata.
	(demarshal_garray_basic): Renamed to demarshal_collection_array.
	(demarshal_ghashtable): Renamed to demarshal_map; fix to use new
	generic map creation/append functions instead of hash table
	specifically.
	(get_type_demarshaller): Handle maps.
	(demarshal_collection): Dispatch on collection type to either
	demarshal_collection_ptrarray or demarshal_collection_array.
	(get_type_marshaller): Handle maps.
	(marshal_collection): Dispatch collection type to either
	marshal_collection_ptrarray or marshal_collection_array.
	(_dbus_gvalue_test): New test.

	* glib/dbus-gvalue-utils.c (unset_and_free_g_value): New function.
	(hash_free_from_gtype): Use it to free GValues.
	(hashtable_append): New function.
	(ptrarray_append): Fix prototype.
	(slist_append): Ditto.
	(_dbus_gvalue_utils_test): Extend tests.

	* glib/dbus-gtype-specialized.c
	(dbus_g_type_specialized_init_append): Renamed from
	dbus_g_type_specialized_collection_init_append.  Remove const from
	value, since we steal it.
	(dbus_g_type_specialized_map_append): New function.

	* glib/dbus-gtype-specialized.h: Update prototypes.
	Add DBusGTypeSpecializedMapAppendFunc.

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


Index: dbus-gvalue.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- dbus-gvalue.c	8 Jul 2005 16:25:36 -0000	1.16
+++ dbus-gvalue.c	9 Jul 2005 01:46:51 -0000	1.17
@@ -22,6 +22,8 @@
  *
  */
 
+#include "config.h"
+#include "dbus-gtest.h"
 #include "dbus-gvalue.h"
 #include "dbus-gobject.h"
 #include "dbus-gvalue-utils.h"
@@ -76,12 +78,6 @@
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
-static gboolean marshal_garray_basic            (DBusMessageIter           *iter,
-						 const GValue              *value);
-static gboolean demarshal_garray_basic          (DBusGValueMarshalCtx      *context,
-						 DBusMessageIter           *iter,
-						 GValue                    *value,
-						 GError                   **error);
 static gboolean marshal_proxy                   (DBusMessageIter           *iter,
 						 const GValue             *value);
 static gboolean demarshal_proxy                 (DBusGValueMarshalCtx      *context,
@@ -102,17 +98,29 @@
 						 GError                   **error);
 static gboolean marshal_map                     (DBusMessageIter           *iter,
 						 const GValue              *value);
-static gboolean demarshal_ghashtable            (DBusGValueMarshalCtx      *context,
+static gboolean demarshal_map                   (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
 
 static gboolean marshal_collection              (DBusMessageIter           *iter,
 						 const GValue              *value);
+static gboolean marshal_collection_ptrarray     (DBusMessageIter           *iter,
+						 const GValue              *value);
+static gboolean marshal_collection_array        (DBusMessageIter           *iter,
+						 const GValue              *value);
 static gboolean demarshal_collection            (DBusGValueMarshalCtx      *context,
 						 DBusMessageIter           *iter,
 						 GValue                    *value,
 						 GError                   **error);
+static gboolean demarshal_collection_ptrarray   (DBusGValueMarshalCtx      *context,
+						 DBusMessageIter           *iter,
+						 GValue                    *value,
+						 GError                   **error);
+static gboolean demarshal_collection_array      (DBusGValueMarshalCtx      *context,
+						 DBusMessageIter           *iter,
+						 GValue                    *value,
+						 GError                   **error);
 
 static gboolean marshal_recurse                 (DBusMessageIter           *iter,
 						 const GValue              *value);
@@ -198,30 +206,6 @@
   set_type_metadata (basic_typecode_to_gtype (typecode), typedata);
 }
 
-static void
-register_array (int typecode, const DBusGTypeMarshalData *typedata)
-{
-  GType elt_gtype;
-  GType gtype;
-
-  elt_gtype = basic_typecode_to_gtype (typecode); 
-  gtype = dbus_g_type_get_collection ("GArray", elt_gtype);
-  set_type_metadata (gtype, typedata); 
-}
-
-static void
-register_dict (int key_type, int value_type, const DBusGTypeMarshalData *typedata)
-{
-  GType key_gtype;
-  GType value_gtype;
-  GType gtype;
-
-  key_gtype = basic_typecode_to_gtype (key_type); 
-  value_gtype = basic_typecode_to_gtype (value_type); 
-  gtype = dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype);
-  set_type_metadata (gtype, typedata); 
-}
-
 void
 dbus_g_value_types_init (void)
 {
@@ -240,14 +224,6 @@
     marshal_basic,
     demarshal_basic
   };
-  static const DBusGTypeMarshalVtable garray_basic_vtable = {
-    marshal_garray_basic,
-    demarshal_garray_basic
-  };
-  static const DBusGTypeMarshalVtable ghashtable_vtable = {
-    marshal_map,
-    demarshal_ghashtable
-  };
 
   /* Register basic types */
   {
@@ -374,56 +350,8 @@
     set_type_metadata (G_TYPE_STRV, &typedata);
   };
 
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_BOOLEAN, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_BYTE, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_UINT32, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_INT32, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_UINT64, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING,
-      &garray_basic_vtable
-    };
-    register_array (DBUS_TYPE_INT64, &typedata);
-  }
-  { 
-    static const DBusGTypeMarshalData typedata = {
-      DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
-      &ghashtable_vtable,
-    };
-    register_dict (DBUS_TYPE_STRING, DBUS_TYPE_STRING, &typedata);
-  }
 
+  /* Register some types specific to the D-BUS GLib bindings */
   {
     static const DBusGTypeMarshalVtable vtable = {
       marshal_proxy,
@@ -535,6 +463,7 @@
 
       context.gconnection = (iterval->value.recurse.toplevel)->value.toplevel.connection;
       context.proxy = (iterval->value.recurse.toplevel)->value.toplevel.proxy;
+
       if (!dbus_gvalue_demarshal (&context,
 				  &(iterval->value.recurse.iterator),
 				  value,
@@ -661,6 +590,10 @@
       DBusSignatureIter subiter;
 
       g_assert (dbus_type_is_container (current_type));
+
+      if (current_type == DBUS_TYPE_VARIANT)
+	return g_value_get_type ();
+      
       dbus_signature_iter_recurse (iter, &subiter);
 
       if (current_type == DBUS_TYPE_ARRAY)
@@ -673,8 +606,6 @@
 	}
       else if (current_type == DBUS_TYPE_STRUCT)
 	return signature_iter_to_g_type_struct (&subiter, is_client);
-      else if (current_type == DBUS_TYPE_VARIANT)
-	return g_value_get_type ();
       else if (current_type == DBUS_TYPE_DICT_ENTRY)
 	return G_TYPE_INVALID;
       else
@@ -721,10 +652,6 @@
   char *ret;
   DBusGTypeMarshalData *typedata;
 
-  typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
-  if (typedata == NULL)
-    return NULL;
-
   if (dbus_g_type_is_collection (gtype))
     {
       GType elt_gtype;
@@ -751,7 +678,12 @@
       g_free (val_subsig);
     }
   else
-    ret = g_strdup (typedata->sig);
+    {
+      typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
+      if (typedata == NULL)
+	return NULL;
+      ret = g_strdup (typedata->sig);
+    }
   
   return ret;
 }
@@ -1066,53 +998,18 @@
 }
 
 static gboolean
-demarshal_garray_basic (DBusGValueMarshalCtx    *context,
-			DBusMessageIter         *iter,
-			GValue                  *value,
-			GError                 **error)
-{
-  DBusMessageIter subiter;
-  GArray *ret;
-  GType elt_gtype;
-  int elt_size;
-  void *msgarray;
-  int msgarray_len;
-
-  dbus_message_iter_recurse (iter, &subiter);
-
-  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
-  g_assert (elt_gtype != G_TYPE_INVALID);
-  g_assert (dbus_g_type_is_fixed (elt_gtype));
-
-  elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-  
-  ret = g_array_new (FALSE, TRUE, elt_size);
-
-  msgarray = NULL;
-  dbus_message_iter_get_fixed_array (&subiter,
-				     &msgarray,
-				     &msgarray_len);
-  g_assert (msgarray != NULL);
-  g_assert (msgarray_len >= 0);
-  g_array_append_vals (ret, msgarray, (guint) msgarray_len);
-
-  g_value_set_boxed_take_ownership (value, ret);
-  
-  return TRUE;
-}
-
-static gboolean
-demarshal_ghashtable (DBusGValueMarshalCtx    *context,
-		      DBusMessageIter         *iter,
-		      GValue                  *value,
-		      GError                 **error)
+demarshal_map (DBusGValueMarshalCtx    *context,
+	       DBusMessageIter         *iter,
+	       GValue                  *value,
+	       GError                 **error)
 {
   GType gtype;
   DBusMessageIter subiter;
   int current_type;
-  GHashTable *ret;
+  gpointer ret;
   GType key_gtype;
   GType value_gtype;
+  DBusGTypeSpecializedAppendContext appendctx;
 
   current_type = dbus_message_iter_get_arg_type (iter);
   if (current_type != DBUS_TYPE_ARRAY)
@@ -1140,14 +1037,12 @@
     }
 
   key_gtype = dbus_g_type_get_map_key_specialization (gtype);
-  g_assert (dbus_gtype_is_valid_hash_key (key_gtype));
   value_gtype = dbus_g_type_get_map_value_specialization (gtype);
-  g_assert (dbus_gtype_is_valid_hash_value (value_gtype));
 
-  ret = g_hash_table_new_full (dbus_g_hash_func_from_gtype (key_gtype),
-			       dbus_g_hash_equal_from_gtype (key_gtype),
-			       dbus_g_hash_free_from_gtype (key_gtype),
-			       dbus_g_hash_free_from_gtype (value_gtype));
+  ret = dbus_g_type_specialized_construct (gtype);
+  g_value_set_boxed_take_ownership (value, ret);
+
+  dbus_g_type_specialized_init_append (value, &appendctx);
 
   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
     {
@@ -1176,14 +1071,11 @@
 				  error))
 	return FALSE;
 
-      dbus_g_hash_table_insert_steal_values (ret,
-					     &key_value,
-					     &value_value);
-      /* Ownership of values passes to hash table, don't unset */
+      dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
+      /* Ownership of values passes to map, don't unset */
 
       dbus_message_iter_next (&subiter);
     }
-  g_value_set_boxed_take_ownership (value, ret);
   
   return TRUE;
 }
@@ -1200,6 +1092,8 @@
 	return demarshal_recurse;
       if (dbus_g_type_is_collection (type))
 	return demarshal_collection;
+      if (dbus_g_type_is_map (type))
+	return demarshal_map;
 
       g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
       return NULL;
@@ -1216,6 +1110,24 @@
 {
   GType coltype;
   GType subtype;
+  
+  coltype = G_VALUE_TYPE (value);
+  subtype = dbus_g_type_get_collection_specialization (coltype);
+
+  if (dbus_g_type_is_fixed (subtype))
+    return demarshal_collection_array (context, iter, value, error);
+  else
+    return demarshal_collection_ptrarray (context, iter, value, error);
+}
+
+static gboolean
+demarshal_collection_ptrarray (DBusGValueMarshalCtx    *context,
+			       DBusMessageIter         *iter,
+			       GValue                  *value,
+			       GError                 **error)
+{
+  GType coltype;
+  GType subtype;
   gpointer instance;
   DBusGTypeSpecializedAppendContext ctx;
   DBusGValueDemarshalFunc demarshaller;
@@ -1254,7 +1166,7 @@
   instance = dbus_g_type_specialized_construct (coltype);
   g_value_set_boxed_take_ownership (value, instance);
 
-  dbus_g_type_specialized_collection_init_append (value, &ctx);
+  dbus_g_type_specialized_init_append (value, &ctx);
 
   while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
     {
@@ -1278,6 +1190,42 @@
 }
 
 static gboolean
+demarshal_collection_array (DBusGValueMarshalCtx    *context,
+			    DBusMessageIter         *iter,
+			    GValue                  *value,
+			    GError                 **error)
+{
+  DBusMessageIter subiter;
+  GArray *ret;
+  GType elt_gtype;
+  int elt_size;
+  void *msgarray;
+  int msgarray_len;
+
+  dbus_message_iter_recurse (iter, &subiter);
+
+  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+  g_assert (elt_gtype != G_TYPE_INVALID);
+  g_assert (dbus_g_type_is_fixed (elt_gtype));
+
+  elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+  
+  ret = g_array_new (FALSE, TRUE, elt_size);
+
+  msgarray = NULL;
+  dbus_message_iter_get_fixed_array (&subiter,
+				     &msgarray,
+				     &msgarray_len);
+  g_assert (msgarray != NULL);
+  g_assert (msgarray_len >= 0);
+  g_array_append_vals (ret, msgarray, (guint) msgarray_len);
+
+  g_value_set_boxed_take_ownership (value, ret);
+  
+  return TRUE;
+}
+
+static gboolean
 demarshal_recurse (DBusGValueMarshalCtx    *context,
 		   DBusMessageIter         *iter,
 		   GValue                  *value,
@@ -1545,50 +1493,6 @@
 }
 
 static gboolean
-marshal_garray_basic (DBusMessageIter   *iter,
-		      const GValue      *value)
-{
-  GType elt_gtype;
-  DBusMessageIter subiter;
-  GArray *array;
-  guint elt_size;
-  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... */
-  subsignature_str = dbus_gtype_to_signature (elt_gtype);
-  g_assert (subsignature_str != NULL);
-  
-  elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-
-  array = g_value_get_boxed (value);
-
-  if (!dbus_message_iter_open_container (iter,
-					 DBUS_TYPE_ARRAY,
-					 subsignature_str,
-					 &subiter))
-    goto oom;
-
-  /* TODO - This assumes that basic values are the same size
-   * is this always true?  If it is we can probably avoid
-   * a lot of the overhead in _marshal_basic_instance...
-   */
-  if (!dbus_message_iter_append_fixed_array (&subiter,
-					     subsignature_str[0],
-					     &(array->data),
-					     array->len))
-    goto oom;
-
-  if (!dbus_message_iter_close_container (iter, &subiter))
-    goto oom;
-  g_free (subsignature_str);
-  return TRUE;
- oom:
-  g_error ("out of memory");
-  return FALSE;
-}
-
-static gboolean
 marshal_proxy (DBusMessageIter         *iter,
 	       const GValue            *value)
 {
@@ -1791,6 +1695,8 @@
 	return marshal_recurse;
       if (dbus_g_type_is_collection (type))
 	return marshal_collection;
+      if (dbus_g_type_is_map (type))
+	return marshal_map;
 
       g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
       return NULL;
@@ -1824,6 +1730,22 @@
 		    const GValue            *value)
 {
   GType coltype;
+  GType subtype;
+  
+  coltype = G_VALUE_TYPE (value);
+  subtype = dbus_g_type_get_collection_specialization (coltype);
+
+  if (dbus_g_type_is_fixed (subtype))
+    return marshal_collection_array (iter, value);
+  else
+    return marshal_collection_ptrarray (iter, value);
+}
+
+static gboolean
+marshal_collection_ptrarray (DBusMessageIter         *iter,
+			     const GValue            *value)
+{
+  GType coltype;
   GType elt_gtype;
   DBusGValueCollectionMarshalData data;
   DBusMessageIter subiter;
@@ -1861,6 +1783,51 @@
   return FALSE;
 }
 
+
+static gboolean
+marshal_collection_array (DBusMessageIter   *iter,
+			  const GValue      *value)
+{
+  GType elt_gtype;
+  DBusMessageIter subiter;
+  GArray *array;
+  guint elt_size;
+  char *subsignature_str;
+
+  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+  g_assert (dbus_g_type_is_fixed (elt_gtype));
+  subsignature_str = dbus_gtype_to_signature (elt_gtype);
+  g_assert (subsignature_str != NULL);
+  
+  elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+
+  array = g_value_get_boxed (value);
+
+  if (!dbus_message_iter_open_container (iter,
+					 DBUS_TYPE_ARRAY,
+					 subsignature_str,
+					 &subiter))
+    goto oom;
+
+  /* TODO - This assumes that basic values are the same size
+   * is this always true?  If it is we can probably avoid
+   * a lot of the overhead in _marshal_basic_instance...
+   */
+  if (!dbus_message_iter_append_fixed_array (&subiter,
+					     subsignature_str[0],
+					     &(array->data),
+					     array->len))
+    goto oom;
+
+  if (!dbus_message_iter_close_container (iter, &subiter))
+    goto oom;
+  g_free (subsignature_str);
+  return TRUE;
+ oom:
+  g_error ("out of memory");
+  return FALSE;
+}
+
 static gboolean
 marshal_recurse (DBusMessageIter         *iter,
 		 const GValue            *value)
@@ -1882,3 +1849,54 @@
     return FALSE;
   return marshaller (iter, value);
 }
+
+#ifdef DBUS_BUILD_TESTS
+
+static void
+assert_type_maps_to (GType gtype, const char *expected_sig)
+{
+  char *sig;
+  sig = dbus_gtype_to_signature (gtype);
+  g_assert (sig != NULL);
+  g_assert (!strcmp (expected_sig, sig));
+  g_free (sig);
+}
+
+static void
+assert_signature_maps_to (const char *sig, GType expected_gtype)
+{
+  g_assert (dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
+}
+
+static void
+assert_bidirectional_mapping (GType gtype, const char *expected_sig)
+{
+  assert_type_maps_to (gtype, expected_sig);
+  assert_signature_maps_to (expected_sig, gtype);
+}
+
+/**
+ * @ingroup DBusGLibInternals
+ * Unit test for general glib stuff
+ * @returns #TRUE on success.
+ */
+gboolean
+_dbus_gvalue_test (const char *test_data_dir)
+{
+  dbus_g_value_types_init ();
+  
+  assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING);
+  assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
+  assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
+
+  assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+				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);
+  assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+				DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING);
+  assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT),
+				DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);
+
+  return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */

Index: dbus-gvalue-utils.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- dbus-gvalue-utils.c	8 Jul 2005 16:25:36 -0000	1.2
+++ dbus-gvalue-utils.c	9 Jul 2005 01:46:51 -0000	1.3
@@ -226,6 +226,15 @@
     }
 }
 
+static void
+unset_and_free_g_value (gpointer val)
+{
+  GValue *value = val;
+
+  g_value_unset (value);
+  g_free (value);
+}
+
 static gboolean
 hash_free_from_gtype (GType gtype, GDestroyNotify *func)
 {
@@ -244,7 +253,7 @@
     default:
       if (gtype == G_TYPE_VALUE)
 	{
-	  *func = (GDestroyNotify) g_value_unset;
+	  *func = unset_and_free_g_value;
 	  return TRUE;
 	}
       return FALSE;
@@ -441,6 +450,17 @@
   g_hash_table_insert (table, key, val);
 }
 
+static void
+hashtable_append (DBusGTypeSpecializedAppendContext *ctx,
+		  GValue                            *key,
+		  GValue                            *val)
+{
+  GHashTable *table;
+
+  table = g_value_get_boxed (ctx->val);
+  dbus_g_hash_table_insert_steal_values (table, key, val);
+}
+
 static gpointer
 hashtable_constructor (GType type)
 {
@@ -667,7 +687,7 @@
 }
 
 static void
-ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)
 {
   GPtrArray *array;
 
@@ -740,7 +760,7 @@
 }
 
 static void
-slist_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+slist_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)
 {
   GSList *list;
 
@@ -822,7 +842,8 @@
       NULL,
       NULL
     },
-    hashtable_iterator
+    hashtable_iterator,
+    hashtable_append
   };
 
   dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0);
@@ -860,6 +881,35 @@
     }
 }
 
+static void
+test_specialized_hash_2 (const GValue *key, const GValue *val, gpointer user_data)
+{
+  TestSpecializedHashData *data = user_data;
+  const GValue *realval;
+
+  g_assert (G_VALUE_HOLDS_STRING (key));
+  g_assert (G_VALUE_TYPE (val) == G_TYPE_VALUE);
+
+  realval = g_value_get_boxed (val);
+
+  if (!strcmp (g_value_get_string (key), "foo"))
+    {
+      data->seen_foo = TRUE;
+      g_assert (G_VALUE_HOLDS_UINT (realval));
+      g_assert (g_value_get_uint (realval) == 20);
+    }
+  else if (!strcmp (g_value_get_string (key), "baz"))
+    {
+      data->seen_baz = TRUE;
+      g_assert (G_VALUE_HOLDS_STRING (realval));
+      g_assert (!strcmp ("bar", g_value_get_string (realval)));
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+}
+
 gboolean
 _dbus_gvalue_utils_test (const char *datadir)
 {
@@ -911,6 +961,62 @@
     g_value_unset (&val);
   }
 
+  type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
+  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_VALUE);
+  {
+    GHashTable *instance;
+    GValue val = { 0, };
+    TestSpecializedHashData hashdata;
+    DBusGTypeSpecializedAppendContext ctx;
+    GValue *eltval;
+
+    instance = dbus_g_type_specialized_construct (type);
+    g_value_init (&val, type);
+    g_value_set_boxed_take_ownership (&val, instance);
+
+    dbus_g_type_specialized_init_append (&val, &ctx);
+
+    {
+      GValue keyval = { 0, };
+      GValue valval = { 0, };
+      g_value_init (&keyval, G_TYPE_STRING);
+      g_value_set_string (&keyval, "foo"); 
+
+      g_value_init (&valval, G_TYPE_VALUE);
+      eltval = g_new0 (GValue, 1);
+      g_value_init (eltval, G_TYPE_UINT);
+      g_value_set_uint (eltval, 20);
+      g_value_set_boxed_take_ownership (&valval, eltval);
+      dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
+    }
+
+    {
+      GValue keyval = { 0, };
+      GValue valval = { 0, };
+      g_value_init (&keyval, G_TYPE_STRING);
+      g_value_set_string (&keyval, "baz"); 
+      g_value_init (&valval, G_TYPE_VALUE);
+      eltval = g_new0 (GValue, 1);
+      g_value_init (eltval, G_TYPE_STRING);
+      g_value_set_string (eltval, "bar");
+      g_value_set_boxed_take_ownership (&valval, eltval);
+      dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
+    }
+
+    hashdata.seen_foo = FALSE;
+    hashdata.seen_baz = FALSE;
+    dbus_g_type_map_value_iterate (&val,
+				   test_specialized_hash_2, 
+				   &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);
@@ -927,7 +1033,7 @@
     g_value_init (&val, type);
     g_value_set_boxed_take_ownership (&val, instance);
 
-    dbus_g_type_specialized_collection_init_append (&val, &ctx);
+    dbus_g_type_specialized_init_append (&val, &ctx);
 
     g_value_init (&eltval, G_TYPE_STRING);
     g_value_set_static_string (&eltval, "foo");

Index: dbus-gtype-specialized.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- dbus-gtype-specialized.h	8 Jul 2005 16:25:36 -0000	1.2
+++ dbus-gtype-specialized.h	9 Jul 2005 01:46:51 -0000	1.3
@@ -58,12 +58,17 @@
   gpointer d;
 } DBusGTypeSpecializedAppendContext;
 
-void           dbus_g_type_specialized_collection_init_append  (GValue *val, DBusGTypeSpecializedAppendContext *ctx);
+void           dbus_g_type_specialized_init_append             (GValue *val, DBusGTypeSpecializedAppendContext *ctx);
 
-void           dbus_g_type_specialized_collection_append       (DBusGTypeSpecializedAppendContext *ctx, const GValue *elt);
+void           dbus_g_type_specialized_collection_append       (DBusGTypeSpecializedAppendContext *ctx, GValue *elt);
 
 void           dbus_g_type_specialized_collection_end_append   (DBusGTypeSpecializedAppendContext *ctx);
 
+void           dbus_g_type_specialized_map_append              (DBusGTypeSpecializedAppendContext *ctx,
+								GValue                            *key,
+								GValue                            *val);
+								
+
 gboolean       dbus_g_type_collection_get_fixed             (GValue                                 *value,
 							     gpointer                               *data,
 							     guint                                  *len);
@@ -90,8 +95,8 @@
 } 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     (*DBusGTypeSpecializedCollectionAppendFunc)        (DBusGTypeSpecializedAppendContext *ctx, const GValue *val);
+typedef void     (*DBusGTypeSpecializedCollectionIteratorFunc)      (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data);
+typedef void     (*DBusGTypeSpecializedCollectionAppendFunc)        (DBusGTypeSpecializedAppendContext *ctx, GValue *val);
 typedef void     (*DBusGTypeSpecializedCollectionEndAppendFunc)     (DBusGTypeSpecializedAppendContext *ctx);
 
 typedef struct {
@@ -103,10 +108,12 @@
 } DBusGTypeSpecializedCollectionVtable;
 
 typedef void (*DBusGTypeSpecializedMapIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedMapIterator iterator, gpointer user_data);
+typedef void (*DBusGTypeSpecializedMapAppendFunc)   (DBusGTypeSpecializedAppendContext *ctx, GValue *key, GValue *val);
 
 typedef struct {
   DBusGTypeSpecializedVtable                        base_vtable;
   DBusGTypeSpecializedMapIteratorFunc               iterator;
+  DBusGTypeSpecializedMapAppendFunc                 append_func;
 } DBusGTypeSpecializedMapVtable;
 
 void           dbus_g_type_specialized_init           (void);

Index: dbus-gtype-specialized.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- dbus-gtype-specialized.c	8 Jul 2005 16:25:36 -0000	1.2
+++ dbus-gtype-specialized.c	9 Jul 2005 01:46:51 -0000	1.3
@@ -427,7 +427,7 @@
 } DBusGTypeSpecializedAppendContextReal;
 
 void
-dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
+dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
 {
   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
   GType gtype;
@@ -446,7 +446,7 @@
 
 void
 dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
-					   const GValue *elt)
+					   GValue                            *elt)
 {
   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
   ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
@@ -461,6 +461,15 @@
 }
 
 void
+dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
+				    GValue                            *key,
+				    GValue                            *val)
+{
+  DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
+  ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val);
+}
+
+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.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- dbus-gtest.h	8 Jul 2005 16:25:36 -0000	1.6
+++ dbus-gtest.h	9 Jul 2005 01:46:51 -0000	1.7
@@ -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_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.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- dbus-gtest.c	8 Jul 2005 16:25:36 -0000	1.6
+++ dbus-gtest.c	9 Jul 2005 01:46:51 -0000	1.7
@@ -63,6 +63,10 @@
   if (!_dbus_gvalue_utils_test (test_data_dir))
     die ("gvalue utils");
 
+  printf ("%s: running GValue tests\n", "dbus-glib-test");
+  if (!_dbus_gvalue_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");



More information about the dbus-commit mailing list