summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert McQueen <robert.mcqueen@collabora.co.uk>2008-09-22 20:40:48 (GMT)
committerRobert McQueen <robert.mcqueen@collabora.co.uk>2008-11-29 03:18:22 (GMT)
commit143b09b42d73451dcc3b835f76f8d43da786342a (patch)
tree2a2d0686595e219228097756373d9be04bb216dc
parente4c917189dc9478c261c94703b311e1579292f22 (diff)
downloaddbus-glib-143b09b42d73451dcc3b835f76f8d43da786342a.tar.gz
dbus-glib-143b09b42d73451dcc3b835f76f8d43da786342a.tar.xz
Bug #17798: 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.
-rw-r--r--dbus/dbus-gvalue-utils.c29
-rw-r--r--test/core/my-object.c16
-rw-r--r--test/core/my-object.h4
-rw-r--r--test/core/test-dbus-glib.c96
-rw-r--r--test/core/test-service-glib.xml12
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 783f041..cf1d281 100644
--- a/test/core/my-object.c
+++ b/test/core/my-object.c
@@ -654,6 +654,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 e465ede..cf70d8f 100644
--- a/test/core/my-object.h
+++ b/test/core/my-object.h
@@ -96,6 +96,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 d3e3401..6cff89a 100644
--- a/test/core/test-service-glib.xml
+++ b/test/core/test-service-glib.xml
@@ -147,6 +147,18 @@
<arg type="a{sa{ss}}" direction="out"/>
</method>
+ <method name="DictOfSigs">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="a{gas}" direction="in" />
+ <arg type="a{gas}" direction="out" />
+ </method>
+
+ <method name="DictOfObjs">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="a{oas}" direction="in" />
+ <arg type="a{oas}" direction="out" />
+ </method>
+
<method name="EmitFrobnicate">
</method>