From 1f23ea99b37bfc8197f1c6a376f9afe08037f0f6 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 7 Jan 2003 22:22:39 +0000 Subject: 2003-01-08 Anders Carlsson reviewed by: * dbus/dbus-internals.c: (_dbus_type_to_string): New function that returns a string describing a type. * dbus/dbus-internals.h: * dbus/dbus-message.c: (dbus_message_append_fields), (dbus_message_append_fields_valist), (dbus_message_get_fields), (dbus_message_get_fields_valist), (_dbus_message_test): * dbus/dbus-message.h: Add new convenience functions for appending and getting message fields. Also add a test for those. --- dbus/dbus-internals.c | 25 ++++++ dbus/dbus-internals.h | 1 + dbus/dbus-message.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++- dbus/dbus-message.h | 34 ++++--- 4 files changed, 289 insertions(+), 13 deletions(-) diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index f3527eb2..e24eb56b 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -21,6 +21,7 @@ * */ #include "dbus-internals.h" +#include "dbus-protocol.h" #include #include #include @@ -337,4 +338,28 @@ _dbus_set_fd_nonblocking (int fd, return TRUE; } +/** + * Returns a string describing the given type. + * + * @param type the type to describe + * @returns a constant string describing the type + */ +const char * +_dbus_type_to_string (int type) +{ + switch (type) + { + case DBUS_TYPE_INT32: + return "int32"; + case DBUS_TYPE_UINT32: + return "uint32"; + case DBUS_TYPE_DOUBLE: + return "double"; + case DBUS_TYPE_STRING: + return "string"; + default: + return "unknown"; + } +} + /** @} */ diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 87dfbf12..4bdf41d1 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -119,6 +119,7 @@ void _dbus_verbose_bytes_of_string (const DBusString *str, int len); +const char* _dbus_type_to_string (int type); DBUS_END_DECLS; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index fb28ced0..8dd77708 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -303,6 +303,95 @@ dbus_message_get_name (DBusMessage *message) return message->name; } +/** + * Appends fields to a message given a variable argument + * list. The variable argument list should contain the type + * of the field followed by the value to add. + * The list is terminated with 0. + * + * @param message the message + * @param ... list of fields. + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_append_fields (DBusMessage *message, + ...) +{ + dbus_bool_t retval; + va_list var_args; + + va_start (var_args, message); + retval = dbus_message_append_fields_valist (message, var_args); + va_end (var_args); + + return retval; +} + +/** + * This function takes a va_list for use by language bindings + * + * @see dbus_message_append_fields. + * @param message the message + * @param var_args list of type/value pairs + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_append_fields_valist (DBusMessage *message, + va_list var_args) +{ + int type, old_len; + + old_len = _dbus_string_get_length (&message->body); + + type = va_arg (var_args, int); + + while (type != 0) + { + switch (type) + { + case DBUS_TYPE_INT32: + if (!dbus_message_append_int32 (message, va_arg (var_args, dbus_int32_t))) + goto enomem; + break; + case DBUS_TYPE_UINT32: + if (!dbus_message_append_uint32 (message, va_arg (var_args, dbus_uint32_t))) + goto enomem; + break; + case DBUS_TYPE_DOUBLE: + if (!dbus_message_append_double (message, va_arg (var_args, double))) + goto enomem; + break; + case DBUS_TYPE_STRING: + if (!dbus_message_append_string (message, va_arg (var_args, const char *))) + goto enomem; + break; + case DBUS_TYPE_BYTE_ARRAY: + { + int len; + unsigned char *data; + + data = va_arg (var_args, unsigned char *); + len = va_arg (var_args, int); + + if (!dbus_message_append_byte_array (message, data, len)) + goto enomem; + + break; + } + default: + _dbus_warn ("Unknown field type %d\n", type); + } + + type = va_arg (var_args, int); + } + + return TRUE; + + enomem: + _dbus_string_set_length (&message->body, old_len); + return FALSE; +} + /** * Appends a 32 bit signed integer to the message. * @@ -420,6 +509,128 @@ dbus_message_append_byte_array (DBusMessage *message, DBUS_COMPILER_BYTE_ORDER, value, len); } +/** + * Gets fields from a message given a variable argument list. + * The variable argument list should contain the type of the + * field followed by a pointer to where the value should be + * stored. The list is terminated with 0. + * + * @param message the message + * @param ... list of fields. + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_get_fields (DBusMessage *message, + ...) +{ + dbus_bool_t retval; + va_list var_args; + + va_start (var_args, message); + retval = dbus_message_get_fields_valist (message, var_args); + va_end (var_args); + + return retval; +} + +/** + * This function takes a va_list for use by language bindings + * + * @see dbus_message_get_fields + * @param message the message + * @param var_args list of type/pointer pairs + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_get_fields_valist (DBusMessage *message, + va_list var_args) +{ + int spec_type, msg_type, i; + DBusMessageIter *iter; + + iter = dbus_message_get_fields_iter (message); + + if (iter == NULL) + return FALSE; + + spec_type = va_arg (var_args, int); + i = 0; + + while (spec_type != 0) + { + msg_type = dbus_message_iter_get_field_type (iter); + + if (msg_type != spec_type) + { + _dbus_warn ("Field %d is specified to be of type \"%s\", but " + "is actually of type \"%s\"\n", i, + _dbus_type_to_string (spec_type), + _dbus_type_to_string (msg_type)); + dbus_message_iter_unref (iter); + + return FALSE; + } + + switch (spec_type) + { + case DBUS_TYPE_INT32: + { + dbus_int32_t *ptr; + + ptr = va_arg (var_args, dbus_int32_t *); + + *ptr = dbus_message_iter_get_int32 (iter); + break; + } + case DBUS_TYPE_UINT32: + { + dbus_uint32_t *ptr; + + ptr = va_arg (var_args, dbus_uint32_t *); + + *ptr = dbus_message_iter_get_uint32 (iter); + break; + } + + case DBUS_TYPE_DOUBLE: + { + double *ptr; + + ptr = va_arg (var_args, double *); + + *ptr = dbus_message_iter_get_double (iter); + break; + } + + case DBUS_TYPE_STRING: + { + char **ptr; + + ptr = va_arg (var_args, char **); + + *ptr = dbus_message_iter_get_string (iter); + break; + } + + default: + _dbus_warn ("Unknown field type %d\n", spec_type); + } + + spec_type = va_arg (var_args, int); + if (spec_type != 0 && !dbus_message_iter_next (iter)) + { + _dbus_warn ("More fields than exists in the message were specified"); + + dbus_message_iter_unref (iter); + return FALSE; + } + i++; + } + + dbus_message_iter_unref (iter); + return TRUE; +} + /** * Returns a DBusMessageIter representing the fields of the * message passed in. @@ -989,11 +1200,38 @@ dbus_bool_t _dbus_message_test (void) { DBusMessage *message; - DBusMessageLoader *loader; int i; const char *data; - + dbus_int32_t our_int; + char *our_str; + double our_double; + + /* Test the vararg functions */ + message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage"); + message->client_serial = 1; + dbus_message_append_fields (message, + DBUS_TYPE_INT32, -0x12345678, + DBUS_TYPE_STRING, "Test string", + DBUS_TYPE_DOUBLE, 3.14159, + 0); + + if (!dbus_message_get_fields (message, + DBUS_TYPE_INT32, &our_int, + DBUS_TYPE_STRING, &our_str, + DBUS_TYPE_DOUBLE, &our_double, + 0)) + _dbus_assert_not_reached ("Could not get fields"); + + if (our_int != -0x12345678) + _dbus_assert_not_reached ("integers differ!"); + + if (our_double != 3.14159) + _dbus_assert_not_reached ("doubles differ!"); + + if (strcmp (our_str, "Test string") != 0) + _dbus_assert_not_reached ("strings differ!"); + message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage"); message->client_serial = 1; dbus_message_append_string (message, "Test string"); diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index b8eb0eec..1fa54e57 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -29,6 +29,7 @@ #include #include +#include DBUS_BEGIN_DECLS; @@ -43,20 +44,31 @@ void dbus_message_unref (DBusMessage *message); const char* dbus_message_get_name (DBusMessage *message); -dbus_bool_t dbus_message_append_int32 (DBusMessage *message, - dbus_int32_t value); -dbus_bool_t dbus_message_append_uint32 (DBusMessage *message, - dbus_uint32_t value); -dbus_bool_t dbus_message_append_double (DBusMessage *message, - double value); -dbus_bool_t dbus_message_append_string (DBusMessage *message, - const char *value); -dbus_bool_t dbus_message_append_byte_array (DBusMessage *message, - unsigned const char *value, - int len); + +dbus_bool_t dbus_message_append_fields (DBusMessage *message, + ...); +dbus_bool_t dbus_message_append_fields_valist (DBusMessage *message, + va_list var_args); +dbus_bool_t dbus_message_append_int32 (DBusMessage *message, + dbus_int32_t value); +dbus_bool_t dbus_message_append_uint32 (DBusMessage *message, + dbus_uint32_t value); +dbus_bool_t dbus_message_append_double (DBusMessage *message, + double value); +dbus_bool_t dbus_message_append_string (DBusMessage *message, + const char *value); +dbus_bool_t dbus_message_append_byte_array (DBusMessage *message, + unsigned const char *value, + int len); + DBusMessageIter *dbus_message_get_fields_iter (DBusMessage *message); +dbus_bool_t dbus_message_get_fields (DBusMessage *message, + ...); +dbus_bool_t dbus_message_get_fields_valist (DBusMessage *message, + va_list var_args); + void dbus_message_iter_ref (DBusMessageIter *iter); void dbus_message_iter_unref (DBusMessageIter *iter); -- cgit