From a2ee43050b1010cc103254ef072aa08fd3e9aa67 Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Mon, 22 Sep 2008 21:40:48 +0100 Subject: [PATCH] add support for 'o', 'g' and 'as' in dictionaries This teaches the parameterised hash table about how to hash, compare and free object paths and signatures, allowing them to be used as hash keys and values, and also how to free strvs, so they can be used as values. Adds some simple test methods which echo a{gas} and a{oas} dictionaries back immediately and compare the results. --- dbus/dbus-gvalue-utils.c | 29 ++++++++++++ test/core/my-object.c | 16 +++++++ test/core/my-object.h | 4 ++ test/core/test-dbus-glib.c | 96 +++++++++++++++++++++++++++++++++++++++ test/core/test-service-glib.xml | 12 +++++ 5 files changed, 157 insertions(+), 0 deletions(-) diff --git a/dbus/dbus-gvalue-utils.c b/dbus/dbus-gvalue-utils.c index 55b4cac..6e50be1 100644 --- a/dbus/dbus-gvalue-utils.c +++ b/dbus/dbus-gvalue-utils.c @@ -269,6 +269,16 @@ hash_func_from_gtype (GType gtype, GHashFunc *func) *func = g_str_hash; return TRUE; default: + if (gtype == DBUS_TYPE_G_OBJECT_PATH) + { + *func = g_str_hash; + return TRUE; + } + else if (gtype == DBUS_TYPE_G_SIGNATURE) + { + *func = g_str_hash; + return TRUE; + } return FALSE; } } @@ -309,6 +319,21 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func) *func = (GDestroyNotify) g_value_array_free; return TRUE; } + else if (gtype == G_TYPE_STRV) + { + *func = (GDestroyNotify) g_strfreev; + return TRUE; + } + else if (gtype == DBUS_TYPE_G_OBJECT_PATH) + { + *func = g_free; + return TRUE; + } + else if (gtype == DBUS_TYPE_G_SIGNATURE) + { + *func = g_free; + return TRUE; + } else if (dbus_g_type_is_collection (gtype)) { const DBusGTypeSpecializedCollectionVtable* vtable; @@ -383,6 +408,10 @@ _dbus_g_hash_equal_from_gtype (GType gtype) case G_TYPE_STRING: return g_str_equal; default: + if (gtype == DBUS_TYPE_G_OBJECT_PATH) + return g_str_equal; + else if (gtype == DBUS_TYPE_G_SIGNATURE) + return g_str_equal; g_assert_not_reached (); return NULL; } diff --git a/test/core/my-object.c b/test/core/my-object.c index 3dd3607..5f6b8ee 100644 --- a/test/core/my-object.c +++ b/test/core/my-object.c @@ -643,6 +643,22 @@ my_object_dict_of_dicts (MyObject *obj, GHashTable *in, return TRUE; } +void +my_object_dict_of_sigs (MyObject *obj, + GHashTable *dict, + DBusGMethodInvocation *context) +{ + dbus_g_method_return (context, dict); +} + +void +my_object_dict_of_objs (MyObject *obj, + GHashTable *dict, + DBusGMethodInvocation *context) +{ + dbus_g_method_return (context, dict); +} + gboolean my_object_emit_frobnicate (MyObject *obj, GError **error) { diff --git a/test/core/my-object.h b/test/core/my-object.h index 50dd07c..a954670 100644 --- a/test/core/my-object.h +++ b/test/core/my-object.h @@ -95,6 +95,10 @@ gboolean my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *v gboolean my_object_dict_of_dicts (MyObject *obj, GHashTable *dict, GHashTable **ret, GError **error); +void my_object_dict_of_sigs (MyObject *obj, GHashTable *dict, DBusGMethodInvocation *ctx); + +void my_object_dict_of_objs (MyObject *obj, GHashTable *dict, DBusGMethodInvocation *ctx); + gboolean my_object_terminate (MyObject *obj, GError **error); void my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context); diff --git a/test/core/test-dbus-glib.c b/test/core/test-dbus-glib.c index 75c0ad1..b813828 100644 --- a/test/core/test-dbus-glib.c +++ b/test/core/test-dbus-glib.c @@ -1328,6 +1328,102 @@ main (int argc, char **argv) g_mem_profile (); } + for (i=0; i<3; i++) + { + GHashTable *table; + GHashTable *ret_table = NULL; + const gchar *foo[] = { "foo", NULL }; + const gchar *bar[] = { "bar", "baz", NULL }; + const gchar **ret_foo = NULL, **ret_bar = NULL; + + table = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (table, "dub", foo); + g_hash_table_insert (table, "sox", bar); + + g_print ("Calling DictOfSigs\n"); + + if (!org_freedesktop_DBus_GLib_Tests_MyObject_dict_of_sigs (proxy, table, + &ret_table, &error)) + lose_gerror ("Failed to complete DictOfSigs call", error); + + if (ret_table == NULL) + lose ("DictOfSigs didn't return a hash table"); + + if (g_hash_table_size (ret_table) != 2) + lose ("DictOfSigs has too many entries"); + + ret_foo = g_hash_table_lookup (ret_table, "dub"); + ret_bar = g_hash_table_lookup (ret_table, "sox"); + + if (ret_foo == NULL || ret_bar == NULL) + lose ("DictOfSigs is missing entries"); + + if (ret_foo[0] == NULL || + ret_foo[1] != NULL || + strcmp (ret_foo[0], "foo") != 0) + lose ("DictOfSigs mangled foo"); + + if (ret_bar[0] == NULL || + ret_bar[1] == NULL || + ret_bar[2] != NULL || + strcmp (ret_bar[0], "bar") != 0 || + strcmp (ret_bar[1], "baz") != 0) + lose ("DictOfSigs mangled bar"); + + g_hash_table_destroy (table); + g_hash_table_destroy (ret_table); + + g_mem_profile (); + } + + for (i=0; i<3; i++) + { + GHashTable *table; + GHashTable *ret_table = NULL; + const gchar *foo[] = { "foo", NULL }; + const gchar *bar[] = { "bar", "baz", NULL }; + const gchar **ret_foo = NULL, **ret_bar = NULL; + + table = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (table, "/foo", foo); + g_hash_table_insert (table, "/bar", bar); + + g_print ("Calling DictOfObjs\n"); + + if (!org_freedesktop_DBus_GLib_Tests_MyObject_dict_of_objs (proxy, table, + &ret_table, &error)) + lose_gerror ("Failed to complete DictOfObjs call", error); + + if (ret_table == NULL) + lose ("DictOfObjs didn't return a hash table"); + + if (g_hash_table_size (ret_table) != 2) + lose ("DictOfObjs has too many entries"); + + ret_foo = g_hash_table_lookup (ret_table, "/foo"); + ret_bar = g_hash_table_lookup (ret_table, "/bar"); + + if (ret_foo == NULL || ret_bar == NULL) + lose ("DictOfObjs is missing entries"); + + if (ret_foo[0] == NULL || + ret_foo[1] != NULL || + strcmp (ret_foo[0], "foo") != 0) + lose ("DictOfObjs mangled foo"); + + if (ret_bar[0] == NULL || + ret_bar[1] == NULL || + ret_bar[2] != NULL || + strcmp (ret_bar[0], "bar") != 0 || + strcmp (ret_bar[1], "baz") != 0) + lose ("DictOfObjs mangled bar"); + + g_hash_table_destroy (table); + g_hash_table_destroy (ret_table); + + g_mem_profile (); + } + /* Signal handling tests */ diff --git a/test/core/test-service-glib.xml b/test/core/test-service-glib.xml index 9c1fe8b..b635731 100644 --- a/test/core/test-service-glib.xml +++ b/test/core/test-service-glib.xml @@ -142,6 +142,18 @@ + + + + + + + + + + + + -- 1.5.4.4