summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2005-07-09 17:52:52 +0000
committerColin Walters <walters@verbum.org>2005-07-09 17:52:52 +0000
commitb1ae5399f82a88ba397d55f224d00f437564bac5 (patch)
tree5318877a5a8dffa85d2fa9e624e80fb9e9715dc4
parent0ccef79d7e9d1b19cdb10b3a147b64b41686905d (diff)
2005-07-09 Colin Walters <walters@verbum.org>
* 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.
-rw-r--r--ChangeLog30
-rw-r--r--glib/dbus-binding-tool-glib.c6
-rw-r--r--glib/dbus-binding-tool-glib.h1
-rw-r--r--glib/dbus-gidl.c30
-rw-r--r--glib/dbus-gidl.h7
-rw-r--r--glib/dbus-gobject.c48
-rw-r--r--glib/dbus-gparser.c5
-rw-r--r--test/glib/test-service-glib.c12
-rw-r--r--test/glib/test-service-glib.xml8
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 <walters@verbum.org>
+
+ * 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 <walters@verbum.org>
* 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, " <arg name=\"%s\" type=\"%s\" direction=\"%s\"/>\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 @@
<arg type="i" direction="out" />
<arg type="u" direction="out" />
<arg type="u" direction="out" />
- <arg type="s" direction="out" />
+ <arg type="s" direction="out">
+ <annotation name="org.freedesktop.DBus.GLib.Const" value=""/>
+ </arg>
</method>
<method name="Stringify">
@@ -71,7 +73,9 @@
<method name="Objpath">
<arg type="o" direction="in"/>
- <arg type="o" direction="out"/>
+ <arg type="o" direction="out">
+ <annotation name="org.freedesktop.DBus.GLib.Const" value=""/>
+ </arg>
</method>
<method name="GetObjs">