From e06ae1fe7dacd7bc0d4dfe65fae09f08f3025663 Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Sun, 14 Sep 2008 21:16:10 +0100 Subject: [PATCH] add support for 'g' type, as a boxed char * Adds DBUS_G_TYPE_SIGNATURE, which is a boxed type just like DBUS_G_TYPE_OBJECT_PATH. --- dbus/dbus-binding-tool-glib.c | 4 ++ dbus/dbus-glib.h | 3 + dbus/dbus-gmain.c | 5 ++- dbus/dbus-gsignature.c | 2 + dbus/dbus-gvalue.c | 80 +++++++++++++++++++++++++++++++++++++++ test/core/my-object.c | 7 +++ test/core/my-object.h | 2 + test/core/test-dbus-glib.c | 19 +++++++++ test/core/test-service-glib.xml | 5 ++ 9 files changed, 126 insertions(+), 1 deletions(-) diff --git a/dbus/dbus-binding-tool-glib.c b/dbus/dbus-binding-tool-glib.c index 84e886f..95c6d73 100644 --- a/dbus/dbus-binding-tool-glib.c +++ b/dbus/dbus-binding-tool-glib.c @@ -126,6 +126,9 @@ dbus_g_type_get_c_name (GType gtype) if (g_type_is_a (gtype, DBUS_TYPE_G_OBJECT_PATH)) return "char"; + if (g_type_is_a (gtype, DBUS_TYPE_G_SIGNATURE)) + return "char"; + return g_type_name (gtype); } @@ -1081,6 +1084,7 @@ dbus_g_type_get_lookup_function (GType gtype) MAP_KNOWN(G_TYPE_VALUE_ARRAY); MAP_KNOWN(DBUS_TYPE_G_PROXY); MAP_KNOWN(DBUS_TYPE_G_OBJECT_PATH); + MAP_KNOWN(DBUS_TYPE_G_SIGNATURE); return NULL; } #undef MAP_FUNDAMENTAL diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h index c4049f3..aa7c793 100644 --- a/dbus/dbus-glib.h +++ b/dbus/dbus-glib.h @@ -183,6 +183,9 @@ GObject * dbus_g_connection_lookup_g_object (DBusGConnection *connectio GType dbus_g_object_path_get_g_type (void) G_GNUC_CONST; #define DBUS_TYPE_G_OBJECT_PATH (dbus_g_object_path_get_g_type ()) +GType dbus_g_signature_get_g_type (void) G_GNUC_CONST; +#define DBUS_TYPE_G_SIGNATURE (dbus_g_signature_get_g_type ()) + void dbus_g_object_register_marshaller (GClosureMarshal marshaller, GType rettype, ...); diff --git a/dbus/dbus-gmain.c b/dbus/dbus-gmain.c index 2069ffa..6a64601 100644 --- a/dbus/dbus-gmain.c +++ b/dbus/dbus-gmain.c @@ -801,7 +801,10 @@ _dbus_gmain_test (const char *test_data_dir) g_assert (type == DBUS_TYPE_G_OBJECT_PATH); type = _dbus_gtype_from_signature ("o", TRUE); g_assert (type == DBUS_TYPE_G_OBJECT_PATH); - + + type = _dbus_gtype_from_signature ("g", TRUE); + g_assert (type == DBUS_TYPE_G_SIGNATURE); + return TRUE; } diff --git a/dbus/dbus-gsignature.c b/dbus/dbus-gsignature.c index 5df959d..698550c 100644 --- a/dbus/dbus-gsignature.c +++ b/dbus/dbus-gsignature.c @@ -147,6 +147,8 @@ _dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client) return _dbus_gtype_from_basic_typecode (current_type); else if (current_type == DBUS_TYPE_OBJECT_PATH) return DBUS_TYPE_G_OBJECT_PATH; + else if (current_type == DBUS_TYPE_SIGNATURE) + return DBUS_TYPE_G_SIGNATURE; else { DBusSignatureIter subiter; diff --git a/dbus/dbus-gvalue.c b/dbus/dbus-gvalue.c index a18067c..aa73a6a 100644 --- a/dbus/dbus-gvalue.c +++ b/dbus/dbus-gvalue.c @@ -85,6 +85,12 @@ static gboolean demarshal_object (DBusGValueMarshalCtx *cont DBusMessageIter *iter, GValue *value, GError **error); +static gboolean marshal_signature (DBusMessageIter *iter, + const GValue *value); +static gboolean demarshal_signature (DBusGValueMarshalCtx *context, + DBusMessageIter *iter, + GValue *value, + GError **error); static gboolean marshal_map (DBusMessageIter *iter, const GValue *value); static gboolean demarshal_map (DBusGValueMarshalCtx *context, @@ -336,6 +342,18 @@ _dbus_g_value_types_init (void) set_type_metadata (G_TYPE_OBJECT, &typedata); } + { + static const DBusGTypeMarshalVtable vtable = { + marshal_signature, + demarshal_signature + }; + static const DBusGTypeMarshalData typedata = { + DBUS_TYPE_SIGNATURE_AS_STRING, + &vtable + }; + set_type_metadata (DBUS_TYPE_G_SIGNATURE, &typedata); + } + types_initialized = TRUE; } @@ -356,6 +374,24 @@ dbus_g_object_path_get_g_type (void) return type_id; } +/** + * Get the GLib type ID for a DBusGSignature boxed type. + * + * Returns: GLib type + */ +GType +dbus_g_signature_get_g_type (void) +{ + static GType type_id = 0; + + if (G_UNLIKELY (type_id == 0)) + type_id = g_boxed_type_register_static ("DBusGSignature", + (GBoxedCopyFunc) g_strdup, + (GBoxedFreeFunc) g_free); + + return type_id; +} + char * _dbus_gtype_to_signature (GType gtype) @@ -705,6 +741,32 @@ demarshal_object (DBusGValueMarshalCtx *context, } static gboolean +demarshal_signature (DBusGValueMarshalCtx *context, + DBusMessageIter *iter, + GValue *value, + GError **error) +{ + const char *sig; + int current_type; + + current_type = dbus_message_iter_get_arg_type (iter); + if (current_type != DBUS_TYPE_SIGNATURE) + { + g_set_error (error, + DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Expected D-BUS signature, got type code \'%c\'"), (guchar) current_type); + return FALSE; + } + + dbus_message_iter_get_basic (iter, &sig); + + g_value_set_boxed_take_ownership (value, g_strdup (sig)); + + return TRUE; +} + +static gboolean demarshal_strv (DBusGValueMarshalCtx *context, DBusMessageIter *iter, GValue *value, @@ -1491,6 +1553,24 @@ marshal_object (DBusMessageIter *iter, return TRUE; } +static gboolean +marshal_signature (DBusMessageIter *iter, + const GValue *value) +{ + const char *sig; + + g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_SIGNATURE); + + sig = (const char*) g_value_get_boxed (value); + + if (!dbus_message_iter_append_basic (iter, + DBUS_TYPE_SIGNATURE, + &sig)) + return FALSE; + + return TRUE; +} + struct DBusGLibHashMarshalData { const char *entry_sig; diff --git a/test/core/my-object.c b/test/core/my-object.c index f744efd..3dd3607 100644 --- a/test/core/my-object.c +++ b/test/core/my-object.c @@ -563,6 +563,13 @@ my_object_get_value (MyObject *obj, guint *ret, GError **error) return TRUE; } +gboolean +my_object_echo_signature (MyObject *obj, const gchar *in, gchar **out, GError **error) +{ + *out = g_strdup (in); + return TRUE; +} + gboolean my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *variant, GError **error) { diff --git a/test/core/my-object.h b/test/core/my-object.h index 7815ba0..50dd07c 100644 --- a/test/core/my-object.h +++ b/test/core/my-object.h @@ -89,6 +89,8 @@ gboolean my_object_emit_signal2 (MyObject *obj, GError **error); gboolean my_object_emit_frobnicate (MyObject *obj, GError **error); +gboolean my_object_echo_signature (MyObject *obj, const gchar *in, gchar **out, GError **error); + 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); diff --git a/test/core/test-dbus-glib.c b/test/core/test-dbus-glib.c index f0d34f8..75c0ad1 100644 --- a/test/core/test-dbus-glib.c +++ b/test/core/test-dbus-glib.c @@ -985,6 +985,25 @@ main (int argc, char **argv) } { + const gchar *in_sig = "a(iou)sq"; + gchar *out_sig = NULL; + + g_print ("Calling EchoSignature: %s\n", in_sig); + if (!org_freedesktop_DBus_GLib_Tests_MyObject_echo_signature (proxy, + in_sig, &out_sig, &error)) + lose_gerror ("Failed to complete EchoSignature call", error); + + if (out_sig == NULL) + lose ("EchoSignature returned NULL"); + if (strcmp (in_sig, out_sig) != 0) + lose ("EchoSignature changed the signature"); + + g_print ("EchoSignature returned: %s\n", out_sig); + + g_free (out_sig); + } + + { GValue *val; GHashTable *table; GHashTable *ret_table; diff --git a/test/core/test-service-glib.xml b/test/core/test-service-glib.xml index edda067..9c1fe8b 100644 --- a/test/core/test-service-glib.xml +++ b/test/core/test-service-glib.xml @@ -128,6 +128,11 @@ + + + + + -- 1.5.4.4