From b1ae5399f82a88ba397d55f224d00f437564bac5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 9 Jul 2005 17:52:52 +0000 Subject: 2005-07-09 Colin Walters * glib/dbus-binding-tool-glib.h (DBUS_GLIB_ANNOTATION_CONST): Define. * glib/dbus-binding-tool-glib.c (generate_glue): Handle Const annotation. * glib/dbus-gobject.c (arg_iterate): Update to parse constval too. (method_dir_signature_from_object_info): Handle arg_iterate change. (write_interface): Ditto. (lookup_object_info): Don't barf if format_version is > 0. (invoke_object_method): Handle arg constness. * glib/dbus-gidl.c (struct ArgInfo): Add annotations. (arg_info_new): Create. (arg_info_unref): Destroy. (arg_info_get_annotations, arg_info_get_annotation) (arg_info_add_annotation): New functions. * glib/dbus-gidl.h: Prototype them. * glib/dbus-gparser.c (parse_annotation): Allow annotations in args, disallow them in properties. (parse_annotation): Handle arg annotations. * test/glib/test-service-glib.xml: * test/glib/test-service-glib.c: Update to make some methods const. --- ChangeLog | 30 ++++++++++++++++++++++++++ glib/dbus-binding-tool-glib.c | 6 ++++++ glib/dbus-binding-tool-glib.h | 1 + glib/dbus-gidl.c | 30 ++++++++++++++++++++++++++ glib/dbus-gidl.h | 7 ++++++ glib/dbus-gobject.c | 48 +++++++++++++++++++++++++++++++++++------ glib/dbus-gparser.c | 5 ++++- test/glib/test-service-glib.c | 12 +++++------ test/glib/test-service-glib.xml | 8 +++++-- 9 files changed, 131 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index f98a6e76..d6734049 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2005-07-09 Colin Walters + + * glib/dbus-binding-tool-glib.h (DBUS_GLIB_ANNOTATION_CONST): + Define. + + * glib/dbus-binding-tool-glib.c (generate_glue): Handle Const + annotation. + + * glib/dbus-gobject.c (arg_iterate): Update to parse constval too. + (method_dir_signature_from_object_info): Handle arg_iterate change. + (write_interface): Ditto. + (lookup_object_info): Don't barf if format_version is > 0. + (invoke_object_method): Handle arg constness. + + * glib/dbus-gidl.c (struct ArgInfo): Add annotations. + (arg_info_new): Create. + (arg_info_unref): Destroy. + (arg_info_get_annotations, arg_info_get_annotation) + (arg_info_add_annotation): New functions. + + * glib/dbus-gidl.h: Prototype them. + + * glib/dbus-gparser.c (parse_annotation): Allow annotations in + args, disallow them in properties. + (parse_annotation): Handle arg annotations. + + * test/glib/test-service-glib.xml: + * test/glib/test-service-glib.c: Update to make some methods + const. + 2005-07-08 Colin Walters * test/glib/test-service-glib.xml: diff --git a/glib/dbus-binding-tool-glib.c b/glib/dbus-binding-tool-glib.c index e503f05c..c87327a3 100644 --- a/glib/dbus-binding-tool-glib.c +++ b/glib/dbus-binding-tool-glib.c @@ -554,6 +554,12 @@ generate_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error) g_string_append_c (object_introspection_data_blob, direction); g_string_append_c (object_introspection_data_blob, '\0'); + if (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_CONST) != NULL) + g_string_append_c (object_introspection_data_blob, 'C'); + else + g_string_append_c (object_introspection_data_blob, 'F'); + g_string_append_c (object_introspection_data_blob, '\0'); + g_string_append (object_introspection_data_blob, arg_info_get_type (arg)); g_string_append_c (object_introspection_data_blob, '\0'); } diff --git a/glib/dbus-binding-tool-glib.h b/glib/dbus-binding-tool-glib.h index 257b5347..62ad2b79 100644 --- a/glib/dbus-binding-tool-glib.h +++ b/glib/dbus-binding-tool-glib.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS #define DBUS_GLIB_ANNOTATION_C_SYMBOL "org.freedesktop.DBus.GLib.CSymbol" #define DBUS_GLIB_ANNOTATION_ASYNC "org.freedesktop.DBus.GLib.Async" +#define DBUS_GLIB_ANNOTATION_CONST "org.freedesktop.DBus.GLib.Const" gboolean dbus_binding_tool_output_glib_client (BaseInfo *info, GIOChannel *channel, gboolean ignore_unsupported, GError **error); gboolean dbus_binding_tool_output_glib_server (BaseInfo *info, GIOChannel *channel, const char *prefix, GError **error); diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c index 3ca0a478..e04b9f46 100644 --- a/glib/dbus-gidl.c +++ b/glib/dbus-gidl.c @@ -75,6 +75,7 @@ struct ArgInfo BaseInfo base; char *type; ArgDirection direction; + GHashTable *annotations; }; static void @@ -699,6 +700,9 @@ arg_info_new (const char *name, info->base.name = g_strdup (name); info->direction = direction; info->type = g_strdup (type); + info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); return info; } @@ -717,10 +721,12 @@ arg_info_unref (ArgInfo *info) info->base.refcount -= 1; if (info->base.refcount == 0) { + g_hash_table_destroy (info->annotations); base_info_free (info); g_free (info->type); } } + const char* arg_info_get_name (ArgInfo *info) { @@ -739,6 +745,30 @@ arg_info_get_direction (ArgInfo *info) return info->direction; } +GSList* +arg_info_get_annotations (ArgInfo *info) +{ + return get_hash_keys (info->annotations); +} + +const char* +arg_info_get_annotation (ArgInfo *info, + const char *annotation) +{ + return g_hash_table_lookup (info->annotations, annotation); +} + +void +arg_info_add_annotation (ArgInfo *info, + const char *name, + const char *value) +{ + g_hash_table_insert (info->annotations, + g_strdup (name), + g_strdup (value)); +} + + #ifdef DBUS_BUILD_TESTS /** diff --git a/glib/dbus-gidl.h b/glib/dbus-gidl.h index 46374c3a..53bab67a 100644 --- a/glib/dbus-gidl.h +++ b/glib/dbus-gidl.h @@ -143,6 +143,13 @@ void arg_info_unref (ArgInfo *info); const char* arg_info_get_name (ArgInfo *info); const char* arg_info_get_type (ArgInfo *info); ArgDirection arg_info_get_direction (ArgInfo *info); +GSList* arg_info_get_annotations (ArgInfo *info); +const char* arg_info_get_annotation (ArgInfo *info, + const char *annotation); +void arg_info_add_annotation (ArgInfo *info, + const char *name, + const char *value); + G_END_DECLS diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c index 4f076cc6..ce90eaa7 100644 --- a/glib/dbus-gobject.c +++ b/glib/dbus-gobject.c @@ -144,8 +144,11 @@ method_arg_info_from_object_info (const DBusGObjectInfo *object, } static const char * -arg_iterate (const char *data, const char **name, gboolean *in, - const char **type) +arg_iterate (const char *data, + const char **name, + gboolean *in, + gboolean *constval, + const char **type) { *name = data; @@ -162,6 +165,20 @@ arg_iterate (const char *data, const char **name, gboolean *in, g_warning ("invalid arg direction"); break; } + + data = string_table_next (data); + switch (*data) + { + case 'F': + *constval = FALSE; + break; + case 'C': + *constval = TRUE; + break; + default: + g_warning ("invalid arg const value"); + break; + } data = string_table_next (data); *type = data; @@ -185,9 +202,10 @@ method_dir_signature_from_object_info (const DBusGObjectInfo *object, { const char *name; gboolean arg_in; + gboolean constval; const char *type; - arg = arg_iterate (arg, &name, &arg_in, &type); + arg = arg_iterate (arg, &name, &arg_in, &constval, &type); if (arg_in == in) g_string_append (ret, type); @@ -245,7 +263,7 @@ lookup_object_info (GObject *object) info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ()); - if (info != NULL && info->format_version == 0) + if (info != NULL && info->format_version >= 0) { ret = info; break; @@ -322,9 +340,10 @@ write_interface (gpointer key, gpointer val, gpointer user_data) { const char *name; gboolean arg_in; + gboolean constval; const char *type; - args = arg_iterate (args, &name, &arg_in, &type); + args = arg_iterate (args, &name, &arg_in, &constval, &type); /* FIXME - handle container types */ g_string_append_printf (xml, " \n", @@ -976,6 +995,12 @@ invoke_object_method (GObject *object, if (!had_error) { DBusMessageIter iter; + const char *arg_metadata; + + /* Grab the metadata and iterate over it so we can determine + * whether or not a value is constant + */ + arg_metadata = method_arg_info_from_object_info (object_info, method); reply = dbus_message_new_method_return (message); if (reply == NULL) @@ -989,6 +1014,13 @@ invoke_object_method (GObject *object, while ((current_type = dbus_signature_iter_get_current_type (&out_signature_iter)) != DBUS_TYPE_INVALID) { GValue gvalue = {0, }; + const char *arg_name; + gboolean arg_in; + gboolean constval; + const char *arg_signature; + + g_assert (*arg_metadata); + arg_metadata = arg_iterate (arg_metadata, &arg_name, &arg_in, &constval, &arg_signature); g_value_init (&gvalue, dbus_gtype_from_signature_iter (&out_signature_iter, FALSE)); if (current_type != DBUS_TYPE_VARIANT) @@ -1007,9 +1039,11 @@ invoke_object_method (GObject *object, if (!dbus_gvalue_marshal (&iter, &gvalue)) goto nomem; /* Here we actually free the allocated value; we - * took ownership of it with dbus_gvalue_take. + * took ownership of it with dbus_gvalue_take, unless + * an annotation has specified this value as constant. */ - g_value_unset (&gvalue); + if (!constval) + g_value_unset (&gvalue); dbus_signature_iter_next (&out_signature_iter); } } diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c index 49593839..4c962874 100644 --- a/glib/dbus-gparser.c +++ b/glib/dbus-gparser.c @@ -694,9 +694,10 @@ parse_annotation (Parser *parser, const char *name; const char *value; - if (!(parser->method || parser->interface) || + if (!(parser->method || parser->interface || parser->arg) || parser->node_stack == NULL || parser->signal || + parser->property || parser->in_annotation) { g_set_error (error, G_MARKUP_ERROR, @@ -735,6 +736,8 @@ parse_annotation (Parser *parser, method_info_add_annotation (parser->method, name, value); else if (parser->interface) interface_info_add_annotation (parser->interface, name, value); + else if (parser->arg) + arg_info_add_annotation (parser->arg, name, value); else g_assert_not_reached (); diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index 580eb107..853b401a 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -58,14 +58,14 @@ gboolean my_object_uppercase (MyObject *obj, const char *str, char **ret, GError gboolean my_object_many_args (MyObject *obj, guint32 x, const char *str, double trouble, double *d_ret, char **str_ret, GError **error); -gboolean my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint32 *arg2, guint32 *arg3, guint32 *arg4, char **arg5, GError **error); +gboolean my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint32 *arg2, guint32 *arg3, guint32 *arg4, const char **arg5, GError **error); gboolean my_object_recursive1 (MyObject *obj, GArray *array, guint32 *len_ret, GError **error); gboolean my_object_recursive2 (MyObject *obj, guint32 reqlen, GArray **array, GError **error); gboolean my_object_many_stringify (MyObject *obj, GHashTable *vals, GHashTable **ret, GError **error); -gboolean my_object_objpath (MyObject *obj, const char *in, char **arg1, GError **error); +gboolean my_object_objpath (MyObject *obj, const char *in, const char **arg1, GError **error); gboolean my_object_get_objs (MyObject *obj, GPtrArray **objs, GError **error); @@ -310,14 +310,14 @@ my_object_many_args (MyObject *obj, guint32 x, const char *str, double trouble, } gboolean -my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint32 *arg2, guint32 *arg3, guint32 *arg4, char **arg5, GError **error) +my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint32 *arg2, guint32 *arg3, guint32 *arg4, const char **arg5, GError **error) { *arg0 = 42; *arg1 = g_strdup ("42"); *arg2 = -67; *arg3 = 2; *arg4 = 26; - *arg5 = g_strdup ("hello world"); + *arg5 = "hello world"; /* Annotation specifies as const */ return TRUE; } @@ -432,7 +432,7 @@ my_object_many_stringify (MyObject *obj, GHashTable /* char * -> GValue * */ *va } gboolean -my_object_objpath (MyObject *obj, const char *incoming, char **outgoing, GError **error) +my_object_objpath (MyObject *obj, const char *incoming, const char **outgoing, GError **error) { if (strcmp (incoming, "/org/freedesktop/DBus/Tests/MyTestObject")) { @@ -442,7 +442,7 @@ my_object_objpath (MyObject *obj, const char *incoming, char **outgoing, GError "invalid incoming object"); return FALSE; } - *outgoing = g_strdup ("/org/freedesktop/DBus/Tests/MyTestObject2"); + *outgoing = "/org/freedesktop/DBus/Tests/MyTestObject2"; return TRUE; } diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml index c299a80c..84524a10 100644 --- a/test/glib/test-service-glib.xml +++ b/test/glib/test-service-glib.xml @@ -32,7 +32,9 @@ - + + + @@ -71,7 +73,9 @@ - + + + -- cgit