summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-16 21:07:27 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-16 21:07:27 -0400
commit195e7621fd34c0648b3d85cc84e9a6e0f51c96c4 (patch)
treeeb55d908a00ef0950c309df9600abade8d4dd0a2
parent35c9b3794618121cbc189e93e79daf1a5594fc42 (diff)
Simpler reply decoding
-rw-r--r--dbus.c241
-rw-r--r--libnul.h8
2 files changed, 176 insertions, 73 deletions
diff --git a/dbus.c b/dbus.c
index 12c425d..bdca8d5 100644
--- a/dbus.c
+++ b/dbus.c
@@ -61,7 +61,7 @@ struct nul_dbus_member_t
nul_ptr_t * parameters;
int n_inputs;
int n_outputs;
-
+
nul_fun_def_t * fun_def;
nul_fun_def_t * reply_fun;
};
@@ -304,12 +304,12 @@ static gboolean
do_free (gpointer data)
{
nul_ptr_t *p;
-
+
for (p = free_us; *p; ++p)
g_free (*p);
-
+
nul_ptr_array_free (free_us);
-
+
free_us = nul_ptr_array_new ();
idle_handler = 0;
@@ -358,7 +358,7 @@ introspect (nul_dbus_object_t *object)
{
nul_dbus_interface_t *interface = *p;
nul_ptr_t *q;
-
+
g_string_append_printf (
xml, " <interface name=\"%s\">\n", interface->name);
@@ -393,7 +393,6 @@ introspect (nul_dbus_object_t *object)
return idle_free (g_string_free (xml, FALSE));
}
-
static gboolean
decode_message (DBusMessage *message,
int n_parameters,
@@ -406,7 +405,7 @@ decode_message (DBusMessage *message,
const char *error;
has_args = dbus_message_iter_init (message, &iter);
-
+
/* FIXME: this function should make sure args are initialized
* to NULL values when it fails
*/
@@ -421,37 +420,37 @@ decode_message (DBusMessage *message,
goto fail;
}
- dbus_type = dbus_message_iter_get_arg_type (&iter);
+ dbus_type = dbus_message_iter_get_arg_type (&iter);
- switch (parameters[i]->type->type)
- {
- case UINT32:
- if (dbus_type != DBUS_TYPE_UINT32)
- {
- error = "Received wrong type, should be UINT32";
- goto fail;
- }
- dbus_message_iter_get_basic (&iter, &(args[i].v_uint32));
- break;
+ switch (parameters[i]->type->type)
+ {
+ case UINT32:
+ if (dbus_type != DBUS_TYPE_UINT32)
+ {
+ error = "Received wrong type, should be UINT32";
+ goto fail;
+ }
+ dbus_message_iter_get_basic (&iter, &(args[i].v_uint32));
+ break;
- case INT32:
- if (dbus_type != DBUS_TYPE_INT32)
- {
- error = "Received wrong type, should be INT32";
- goto fail;
- }
- dbus_message_iter_get_basic (&iter, &(args[i].v_int32));
- break;
+ case INT32:
+ if (dbus_type != DBUS_TYPE_INT32)
+ {
+ error = "Received wrong type, should be INT32";
+ goto fail;
+ }
+ dbus_message_iter_get_basic (&iter, &(args[i].v_int32));
+ break;
- case STRING:
- if (dbus_type != DBUS_TYPE_STRING)
- {
- error = "Received wrong type, should be STRING";
- goto fail;
- }
- dbus_message_iter_get_basic (&iter, &(args[i].v_pointer));
- break;
- }
+ case STRING:
+ if (dbus_type != DBUS_TYPE_STRING)
+ {
+ error = "Received wrong type, should be STRING";
+ goto fail;
+ }
+ dbus_message_iter_get_basic (&iter, &(args[i].v_pointer));
+ break;
+ }
if (dbus_type == DBUS_TYPE_INVALID)
has_args = FALSE;
@@ -466,6 +465,104 @@ fail:
return FALSE;
}
+static gboolean
+decode_arg (nul_arg_t **args,
+ DBusMessageIter *iter,
+ nul_dbus_parameter_t *parameter,
+ char **err)
+{
+ int dbus_type = dbus_message_iter_get_arg_type (iter);
+ nul_arg_t arg;
+
+ switch (parameter->type->type)
+ {
+ case UINT32:
+ if (dbus_type != DBUS_TYPE_UINT32)
+ {
+ *err = "Received wrong type, should be UINT32";
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (iter, &arg.v_uint32);
+ break;
+
+ case INT32:
+ if (dbus_type != DBUS_TYPE_INT32)
+ {
+ *err = "Received wrong type, should be INT32";
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (iter, &arg.v_int32);
+ break;
+
+ case STRING:
+ if (dbus_type != DBUS_TYPE_STRING)
+ {
+ *err = "Received wrong type, should be STRING";
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (iter, &arg.v_pointer);
+ break;
+ }
+
+ *args = nul_array_append (*args, &arg);
+
+ return TRUE;
+}
+
+static gboolean
+ddecode_message (nul_arg_t **args,
+ DBusMessage *message,
+ int n_parameters,
+ nul_dbus_parameter_t **parameters,
+ char **err)
+{
+ DBusMessageIter iter;
+ char *d;
+ int i;
+
+ if (!err)
+ err = &d;
+
+ i = 0;
+ if (dbus_message_iter_init (message, &iter))
+ {
+ do
+ {
+ if (i >= n_parameters)
+ {
+ *err = "Too many arguments received";
+ goto fail;
+ }
+
+ if (!decode_arg (args, &iter, parameters[i++], err))
+ goto fail;
+
+ } while (dbus_message_iter_next (&iter));
+ }
+
+ if (i < n_parameters)
+ {
+ *err = "Too few arguments received";
+ goto fail;
+ }
+
+ return TRUE;
+
+fail:
+ while (i < n_parameters)
+ {
+ nul_arg_t arg;
+
+ memset (&arg, 0, sizeof (arg));
+
+ *args = nul_array_append (*args, &arg);
+
+ i++;
+ }
+
+ return FALSE;
+}
+
static void
encode_message (DBusMessage *message,
int n_parameters,
@@ -521,20 +618,20 @@ invoke (DBusConnection *connection,
DBusMessage *error_reply;
nul_arg_t result;
int i;
-
+
if (!member->function)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
/* Add the data pointer */
args[0].v_pointer = object->data;
-
+
if (!decode_message (
message, member->n_inputs,
(nul_dbus_parameter_t **)member->parameters, &(args[1])))
{
error_reply = dbus_message_new_error (
message, DBUS_ERROR_FAILED, "FIXME: generate a real error");
-
+
dbus_connection_send (connection, error_reply, NULL);
return DBUS_HANDLER_RESULT_HANDLED;
@@ -604,11 +701,11 @@ message_function (DBusConnection *connection,
for (p = object->interfaces; *p; ++p)
{
nul_dbus_interface_t *interface = *p;
-
+
if (strcmp (msg_interface, interface->name) == 0)
{
nul_ptr_t *q;
-
+
for (q = interface->members; *q; ++q)
{
nul_dbus_member_t *member = *q;
@@ -640,12 +737,12 @@ make_ptr_array (gpointer first, va_list parameters)
if (first)
{
array = nul_ptr_array_append (array, first);
-
+
v = va_arg (parameters, gpointer);
while (v)
{
array = nul_ptr_array_append (array, v);
-
+
v = va_arg (parameters, gpointer);
}
}
@@ -660,7 +757,7 @@ get_idle_id (DBusConnection *connection)
{
if (idle_id_slot == -1)
dbus_connection_allocate_data_slot (&idle_id_slot);
-
+
return (int)dbus_connection_get_data (connection, idle_id_slot);
}
@@ -669,7 +766,7 @@ set_idle_id (DBusConnection *connection, int id)
{
if (idle_id_slot == -1)
dbus_connection_allocate_data_slot (&idle_id_slot);
-
+
dbus_connection_set_data (connection, idle_id_slot, (void *)id, NULL);
}
@@ -677,10 +774,10 @@ static gboolean
do_dispatch (gpointer data)
{
DBusConnection *connection = data;
-
+
while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS)
;
-
+
set_idle_id (connection, 0);
return FALSE;
@@ -720,7 +817,7 @@ ensure_connection (DBusConnection **connection,
add_timeout, remove_timeout, toggle_timeout,
*connection, NULL);
}
-
+
do_dispatch (*connection);
}
@@ -851,11 +948,11 @@ nul_dbus_service_stop (nul_dbus_service_t *service)
if (!service->running)
return;
-
+
for (p = service->objects; *p != NULL; ++p)
{
nul_dbus_object_t *object = *p;
-
+
dbus_connection_unregister_object_path (
service->connection, object->name);
}
@@ -963,7 +1060,7 @@ make_fun_def (nul_dbus_member_t *member)
types = idle_free (g_new0 (nul_type_t,
nul_ptr_array_len (member->parameters) + 1));
types[0] = NUL_TYPE_POINTER; /* For object->data */
-
+
for (i = 1; i < nul_ptr_array_len (member->parameters); ++i)
{
nul_dbus_parameter_t *par = member->parameters[i - 1];
@@ -988,7 +1085,7 @@ make_reply_fun (nul_dbus_member_t *member)
types = idle_free (g_new0 (nul_type_t,
nul_ptr_array_len (member->parameters) + 2));
-
+
n = 0;
for (p = member->parameters; *p; ++p)
{
@@ -1124,8 +1221,11 @@ on_reply (DBusPendingCall *pending,
{
InvokeInfo *info = data;
int n_outputs = info->method->n_outputs;
- nul_arg_t *args = idle_free (g_new0 (nul_arg_t, n_outputs + 2));
+ nul_dbus_parameter_t **outputs;
DBusMessage *reply;
+ nul_arg_t *args;
+ nul_arg_t arg;
+ char *err;
if (!info->callback)
return;
@@ -1140,19 +1240,22 @@ on_reply (DBusPendingCall *pending,
return;
}
- args[n_outputs].v_pointer = NULL; /* GError */
- if (!decode_message (reply,
- n_outputs,
- (nul_dbus_parameter_t **)&(info->method->parameters[info->method->n_inputs]),
- args))
- {
- /* FIXME: generate an error into args[n_outputs + 1] */
- args[n_outputs].v_pointer = "ERR";
- }
+ outputs = (nul_dbus_parameter_t **)&(info->method->parameters[info->method->n_inputs]);
- args[n_outputs + 1].v_pointer = info->data;
+ args = nul_array_new (sizeof (nul_arg_t));
+
+ if (!ddecode_message (&args, reply, n_outputs, outputs, &err))
+ arg.v_pointer = err;
+ else
+ arg.v_pointer = NULL;
+ args = nul_array_append (args, &arg); /* error */
+
+ arg.v_pointer = info->data;
+ args = nul_array_append (args, &arg);
nul_fun_def_invoke (info->method->reply_fun, (nul_function_t)info->callback, args);
+
+ nul_array_free (args);
}
/* Decodes strings like this:
@@ -1250,14 +1353,14 @@ nul_dbus_invoke (nul_dbus_service_t *service,
InvokeInfo *info;
DBusPendingCall *pending;
nul_ptr_t *p;
-
+
g_return_if_fail (service != NULL);
if (!decode_method_desc (method_desc, &object_str, &interface_str, &method_str))
return;
object = find_object (service, object_str);
-
+
if (!object)
{
g_critical ("Object '%s' not found", object_str);
@@ -1265,13 +1368,13 @@ nul_dbus_invoke (nul_dbus_service_t *service,
}
interface = find_interface (object, interface_str);
-
+
if (!interface)
{
g_critical ("Interface '%s' not found", interface_str);
return;
}
-
+
method = find_member (interface, method_str);
if (!method)
@@ -1279,7 +1382,7 @@ nul_dbus_invoke (nul_dbus_service_t *service,
g_critical ("Method '%s' not found", method_str);
return;
}
-
+
message = dbus_message_new_method_call (
service->name, object->name, interface->name, method->name);
@@ -1352,9 +1455,9 @@ nul_dbus_service_set_object_data (nul_dbus_service_t *service,
gpointer data)
{
nul_dbus_object_t *object = find_object (service, obj_name);
-
+
g_return_if_fail (object != NULL);
-
+
object->data = data;
}
diff --git a/libnul.h b/libnul.h
index 24e40a4..f22acf7 100644
--- a/libnul.h
+++ b/libnul.h
@@ -52,15 +52,15 @@ typedef void * const nul_const_ptr_t;
/*
* Generic arrays
*/
-nul_ptr_t nul_array_new (int element_size);
-nul_ptr_t nul_array_append (nul_ptr_t array, nul_ptr_t element);
+nul_ptr_t nul_array_new (int element_size) NUL_UR;
+nul_ptr_t nul_array_append (nul_ptr_t array, nul_ptr_t element) NUL_UR;
gsize nul_array_len (nul_ptr_t array);
void nul_array_free (nul_ptr_t array);
/*
* Pointer arrays
*/
-nul_ptr_t *nul_ptr_array_new (void);
+nul_ptr_t *nul_ptr_array_new (void) NUL_UR;
nul_ptr_t *nul_ptr_array_append (nul_ptr_t *arr,
nul_ptr_t data) NUL_UR;
gsize nul_ptr_array_len (nul_const_ptr_t *arr);
@@ -72,7 +72,7 @@ void nul_ptr_array_free (nul_ptr_t *arr);
*/
typedef char nul_string_t;
-nul_string_t *nul_string_new (void);
+nul_string_t *nul_string_new (void) NUL_UR;
void nul_string_free (nul_string_t *str);
gsize nul_string_len (const nul_string_t *str);
gboolean nul_string_empty (const nul_string_t *str);