I made this patch a few days ago, but I'm not quite sure what to think
of it. It does the job and lets me get on with my coding, but it's
ultimately not right. It provides a pair of methods which use a dataset
to annotate a GPtrArray and a GHashTable with the D-Bus signature of the
values they contain within. This is necessary when you want to marshal
to a type like a{s(...)} or a(...), because given the GType for a
GValueArray, it's unable to work out the D-Bus signature to open the
array with.
This isn't really the right way to fix it, but I'm proposing the patch
as a straw man so that hopefully someone will decide to implement the
correct fix which I don't have time for at the moment. In my opinion,
this would be to allow registering specialisation types for structs in
the same way that you can do currently for maps and collections, where
it stores the GTypes of the stuff held within. This would boil down to
allowing you to call a varargs method like dbus_g_type_get_struct
("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, NULL), and the
rest would be obvious... :)
Anyone keen to attempt a real fix? We could probably afford to put a
bounty on getting this fixed, or contract someone to fix it if anyone
has the time & expertise.
Regards,
Rob
Index: glib/dbus-gvalue.c
===================================================================
--- glib/dbus-gvalue.c.orig 2006-01-19 03:23:10.364210704 +0000
+++ glib/dbus-gvalue.c 2006-01-19 03:51:44.523618864 +0000
@@ -346,6 +346,57 @@
return type_id;
}
+
+static GQuark
+dbus_g_contents_signature_quark ()
+{
+ static GQuark quark;
+ if (!quark)
+ quark = g_quark_from_static_string ("DBusGContentsSignature");
+
+ return quark;
+}
+
+/**
+ * Set the D-Bus signature type for the contents of a collection.
+ *
+ * @param collection the GPtrArray representing the collection
+ * @param signature the D-Bus signature for a single element of the
collection
+ */
+void
+dbus_g_collection_set_signature (GPtrArray *collection,
+ const char *signature)
+{
+ g_return_if_fail (collection != NULL);
+ g_return_if_fail (dbus_signature_validate_single (signature, NULL));
+
+ g_dataset_id_set_data_full (collection,
+ dbus_g_contents_signature_quark (),
+ g_strdup (signature),
+ g_free);
+}
+
+
+/**
+ * Set the D-Bus signature type for the values of a map.
+ *
+ * @param collection the GHashTable representing the map
+ * @param signature the D-Bus signature for a single value in the map
+ */
+void
+dbus_g_map_set_value_signature (GHashTable *map,
+ const char *signature)
+{
+ g_return_if_fail (map != NULL);
+ g_return_if_fail (dbus_signature_validate_single (signature, NULL));
+
+ g_dataset_id_set_data_full (map,
+ dbus_g_contents_signature_quark (),
+ g_strdup (signature),
+ g_free);
+}
+
+
char *
_dbus_gtype_to_signature (GType gtype)
{
@@ -1415,6 +1466,16 @@
value_sig = _dbus_gtype_to_signature (value_type);
if (!value_sig)
{
+ gpointer pointer = g_value_peek_pointer (value);
+
+ value_sig = g_strdup (
+ g_dataset_id_get_data (pointer,
+ dbus_g_contents_signature_quark ()));
+
+ g_dataset_destroy (pointer);
+ }
+ if (!value_sig)
+ {
g_free (key_sig);
g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name
(value_type));
return FALSE;
@@ -1567,6 +1628,16 @@
elt_sig = _dbus_gtype_to_signature (elt_gtype);
if (!elt_sig)
{
+ gpointer pointer = g_value_peek_pointer (value);
+
+ elt_sig = g_strdup (
+ g_dataset_id_get_data (pointer,
+ dbus_g_contents_signature_quark ()));
+
+ g_dataset_destroy (pointer);
+ }
+ if (!elt_sig)
+ {
g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name
(elt_gtype));
return FALSE;
}
Index: dbus/dbus-glib.h
===================================================================
--- dbus/dbus-glib.h.orig 2006-01-19 03:23:10.365210552 +0000
+++ dbus/dbus-glib.h 2006-01-19 03:50:34.751225880 +0000
@@ -240,6 +240,12 @@
void dbus_g_method_return_error (DBusGMethodInvocation
*context, GError *error);
+void dbus_g_collection_set_signature (GPtrArray *collection,
+ const char *signature);
+
+void dbus_g_map_set_value_signature (GHashTable *map,
+ const char *signature);
+
/* Probably possible to replace this with a closure */
typedef struct {
GCallback cb;
_______________________________________________
dbus mailing list
dbus-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@xxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dbus
|