From 8e00b10d134e4fb844cdc961e5c3230edf194b57 Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Fri, 27 Jan 2006 15:40:36 +0000 Subject: 2006-01-27 Robert McQueen * glib/dbus-gtype-specialized.[ch], glib/dbus-gvalue-utils.c: Patch by me and Rob Taylor to add a simple_free function to D-Bus map and collection types, which allows those types which can be freed with a GDestroyNotify (such as GHashTables and GArrays, but not GPtrArrays) to be stored as the values in hashtables. * test/glib/test-dbus-glib.c, test/glib/test-service-glib.{c,xml}: Patch by Rob Taylor to add nested dicts to the glib tests to check the above code works, and appears not to leak when called repeatedly. --- test/glib/test-dbus-glib.c | 89 +++++++++++++++++++++++++++++++++++++++++ test/glib/test-service-glib.c | 47 ++++++++++++++++++++++ test/glib/test-service-glib.xml | 5 +++ 3 files changed, 141 insertions(+) (limited to 'test') diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index 03a1a736..0a99eda2 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -1164,6 +1164,95 @@ main (int argc, char **argv) g_value_unset (variant); } + + for (i=0; i<3; i++) + { + gchar *val; + GHashTable *table; + GHashTable *subtable; + GHashTable *ret_table; + + table = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) (g_free), + (GDestroyNotify) (g_hash_table_destroy)); + + subtable = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) (g_free), + (GDestroyNotify) (g_free)); + g_hash_table_insert (subtable, g_strdup ("foo"), g_strdup("1")); + g_hash_table_insert (subtable, g_strdup ("bar"), g_strdup("2")); + g_hash_table_insert (subtable, g_strdup ("baz"), g_strdup("3")); + + g_hash_table_insert (table, g_strdup("dict1"), subtable); + + subtable = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) (g_free), + (GDestroyNotify) (g_free)); + g_hash_table_insert (subtable, g_strdup ("foo"), g_strdup("4")); + g_hash_table_insert (subtable, g_strdup ("bar"), g_strdup("5")); + g_hash_table_insert (subtable, g_strdup ("baz"), g_strdup("6")); + + g_hash_table_insert (table, g_strdup("dict2"), subtable); + + subtable = NULL; + + ret_table = NULL; + + g_print ("Calling DictOfDicts\n"); + if (!dbus_g_proxy_call (proxy, "DictOfDicts", &error, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, + G_TYPE_STRING)), table, + G_TYPE_INVALID, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, + G_TYPE_STRING)), &ret_table, + G_TYPE_INVALID)) + lose_gerror ("Failed to complete DictOfDicts call", error); + + g_assert (ret_table != NULL); + g_assert (g_hash_table_size (ret_table) == 2); + + subtable = g_hash_table_lookup (ret_table, "dict1"); + g_assert(subtable); + g_assert (g_hash_table_size (subtable) == 3); + + val = g_hash_table_lookup (subtable, "foo"); + g_assert (val != NULL); + g_assert (!strcmp ("dict1 1", val)); + + val = g_hash_table_lookup (subtable, "bar"); + g_assert (val != NULL); + g_assert (!strcmp ("dict1 2", val)); + + val = g_hash_table_lookup (subtable, "baz"); + g_assert (val != NULL); + g_assert (!strcmp ("dict1 3", val)); + + subtable = g_hash_table_lookup (ret_table, "dict2"); + g_assert(subtable); + g_assert (g_hash_table_size (subtable) == 3); + + val = g_hash_table_lookup (subtable, "foo"); + g_assert (val != NULL); + g_assert (!strcmp ("dict2 4", val)); + + val = g_hash_table_lookup (subtable, "bar"); + g_assert (val != NULL); + g_assert (!strcmp ("dict2 5", val)); + + val = g_hash_table_lookup (subtable, "baz"); + g_assert (val != NULL); + g_assert (!strcmp ("dict2 6", val)); + + g_hash_table_destroy (table); + g_hash_table_destroy (ret_table); + + g_mem_profile (); + } + + + /* Signal handling tests */ g_print ("Testing signal handling\n"); diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index 6d10b937..829cb57d 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -101,6 +101,8 @@ gboolean my_object_echo_variant (MyObject *obj, GValue *variant, GValue *ret, GE gboolean my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *variant, GError **error); +gboolean my_object_dict_of_dicts (MyObject *obj, GHashTable *dict, GHashTable **ret, GError **error); + gboolean my_object_terminate (MyObject *obj, GError **error); void my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context); @@ -706,6 +708,51 @@ error: return FALSE; } + +typedef struct _HashAndString HashAndString; + +struct _HashAndString +{ + GHashTable *hash; + gchar* string; +}; + +static void +hash_foreach_prepend_string (gpointer key, gpointer val, gpointer user_data) +{ + HashAndString *data = (HashAndString*) user_data; + gchar *in = (gchar*) val; + g_hash_table_insert (data->hash, g_strdup ((gchar*) key), + g_strjoin (" ", data->string, in, NULL)); +} + + +static void +hash_foreach_mangle_dict_of_strings (gpointer key, gpointer val, gpointer user_data) +{ + GHashTable *out = (GHashTable*) user_data; + GHashTable *in_dict = (GHashTable *) val; + HashAndString *data = g_new0 (HashAndString, 1); + + data->string = (gchar*) key; + data->hash = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + g_hash_table_foreach (in_dict, hash_foreach_prepend_string, data); + + g_hash_table_insert(out, g_strdup ((gchar*) key), data->hash); +} + +gboolean +my_object_dict_of_dicts (MyObject *obj, GHashTable *in, + GHashTable **out, GError **error) +{ + *out = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_hash_table_destroy); + g_hash_table_foreach (in, hash_foreach_mangle_dict_of_strings, *out); + return TRUE; +} + gboolean my_object_emit_frobnicate (MyObject *obj, GError **error) { diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml index 5b589d08..91f1fe9c 100644 --- a/test/glib/test-service-glib.xml +++ b/test/glib/test-service-glib.xml @@ -137,6 +137,11 @@ + + + + + -- cgit