2003-01-08 Anders Carlsson <andersca@codefactory.se>

reviewed by: <delete if not using a buddy>

	* 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.
This commit is contained in:
Anders Carlsson 2003-01-07 22:22:39 +00:00
parent 1b53cbcce3
commit 1f23ea99b3
4 changed files with 288 additions and 12 deletions

View file

@ -21,6 +21,7 @@
*
*/
#include "dbus-internals.h"
#include "dbus-protocol.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@ -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";
}
}
/** @} */

View file

@ -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;

View file

@ -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");

View file

@ -29,6 +29,7 @@
#include <dbus/dbus-macros.h>
#include <dbus/dbus-types.h>
#include <stdarg.h>
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);