void *iface_user_data;
};
-static void print_arguments(GString *gstr, const char *sig,
+static void print_arguments(GString *gstr, const GDBusArgInfo *args,
const char *direction)
{
- int i;
-
- for (i = 0; sig[i]; i++) {
- char type[32];
- int struct_level, dict_level;
- unsigned int len;
- gboolean complete;
-
- complete = FALSE;
- struct_level = dict_level = 0;
-
- /* Gather enough data to have a single complete type */
- for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
- switch (sig[i]) {
- case '(':
- struct_level++;
- break;
- case ')':
- struct_level--;
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- case '{':
- dict_level++;
- break;
- case '}':
- dict_level--;
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- case 'a':
- break;
- default:
- if (struct_level <= 0 && dict_level <= 0)
- complete = TRUE;
- break;
- }
-
- type[len] = sig[i];
-
- if (complete)
- break;
- }
-
- type[len + 1] = '\0';
-
- if (!complete) {
- error("Unexpected signature: %s", sig);
- return;
- }
+ for (; args && args->name; args++) {
+ g_string_append_printf(gstr,
+ "\t\t\t<arg name=\"%s\" type=\"%s\"",
+ args->name, args->signature);
if (direction)
g_string_append_printf(gstr,
- "\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
- type, direction);
+ " direction=\"%s\"/>\n", direction);
else
- g_string_append_printf(gstr,
- "\t\t\t<arg type=\"%s\"/>\n",
- type);
+ g_string_append_printf(gstr, "/>\n");
+
}
}
const GDBusSignalTable *signal;
for (method = iface->methods; method && method->name; method++) {
- if (!strlen(method->signature) && !strlen(method->reply))
+ gboolean deprecated = method->flags &
+ G_DBUS_METHOD_FLAG_DEPRECATED;
+ gboolean noreply = method->flags &
+ G_DBUS_METHOD_FLAG_NOREPLY;
+
+ if (!deprecated && !noreply &&
+ !(method->in_args && method->in_args->name) &&
+ !(method->out_args && method->out_args->name))
g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
method->name);
else {
g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
method->name);
- print_arguments(gstr, method->signature, "in");
- print_arguments(gstr, method->reply, "out");
+ print_arguments(gstr, method->in_args, "in");
+ print_arguments(gstr, method->out_args, "out");
+
+ if (deprecated)
+ g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
+
+ if (noreply)
+ g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n");
+
g_string_append_printf(gstr, "\t\t</method>\n");
}
}
for (signal = iface->signals; signal && signal->name; signal++) {
- if (!strlen(signal->signature))
+ gboolean deprecated = signal->flags &
+ G_DBUS_SIGNAL_FLAG_DEPRECATED;
+
+ if (!deprecated && !(signal->args && signal->args->name))
g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
signal->name);
else {
g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
signal->name);
- print_arguments(gstr, signal->signature, NULL);
+ print_arguments(gstr, signal->args, NULL);
+
+ if (deprecated)
+ g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
+
g_string_append_printf(gstr, "\t\t</signal>\n");
}
}
struct generic_data *data = user_data;
DBusMessage *reply;
- if (!dbus_message_has_signature(message, DBUS_TYPE_INVALID_AS_STRING)) {
- error("Unexpected signature to introspect call");
- return NULL;
- }
-
if (data->introspect == NULL)
generate_introspection_xml(connection, data,
dbus_message_get_path(message));
return NULL;
}
+static gboolean g_dbus_args_have_signature(const GDBusArgInfo *args,
+ DBusMessage *message)
+{
+ const char *sig = dbus_message_get_signature(message);
+ const char *p = NULL;
+
+ for (; args && args->signature && *sig; args++) {
+ p = args->signature;
+
+ for (; *sig && *p; sig++, p++) {
+ if (*p != *sig)
+ return FALSE;
+ }
+ }
+
+ if (*sig || (p && *p) || (args && args->signature))
+ return FALSE;
+
+ return TRUE;
+}
+
static DBusHandlerResult generic_message(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
method->name) == FALSE)
continue;
- if (dbus_message_has_signature(message,
- method->signature) == FALSE)
+ if (g_dbus_args_have_signature(method->in_args,
+ message) == FALSE)
continue;
if (check_privilege(connection, message, method,
}
static const GDBusMethodTable introspect_methods[] = {
- { _GDBUS_METHOD("Introspect", "", "s", NULL,
+ { GDBUS_METHOD("Introspect", NULL,
GDBUS_ARGS({ "xml", "s" }), introspect) },
{ }
};
static gboolean check_signal(DBusConnection *conn, const char *path,
const char *interface, const char *name,
- const char **args)
+ const GDBusArgInfo **args)
{
struct generic_data *data = NULL;
struct interface_data *iface;
for (signal = iface->signals; signal && signal->name; signal++) {
if (!strcmp(signal->name, name)) {
- *args = signal->signature;
- break;
+ *args = signal->args;
+ return TRUE;
}
}
- if (*args == NULL) {
- error("No signal named %s on interface %s", name, interface);
- return FALSE;
- }
-
- return TRUE;
+ error("No signal named %s on interface %s", name, interface);
+ return FALSE;
}
static dbus_bool_t emit_signal_valist(DBusConnection *conn,
{
DBusMessage *signal;
dbus_bool_t ret;
- const char *signature, *args;
+ const GDBusArgInfo *args;
if (!check_signal(conn, path, interface, name, &args))
return FALSE;
if (!ret)
goto fail;
- signature = dbus_message_get_signature(signal);
- if (strcmp(args, signature) != 0) {
+ if (g_dbus_args_have_signature(args, signal) == FALSE) {
error("%s.%s: expected signature'%s' but got '%s'",
interface, name, args, signature);
ret = FALSE;