mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-08 10:18:01 +02:00
2003-01-07 Anders Carlsson <andersca@codefactory.se>
* dbus/dbus-connection-internal.h: * dbus/dbus-connection.c: (_dbus_connection_new_for_transport), (_dbus_connection_get_next_client_serial), (dbus_connection_send_message): * dbus/dbus-internals.h: * dbus/dbus-marshal.c: (unpack_uint32), (dbus_unpack_int32), (dbus_pack_int32), (_dbus_marshal_double), (_dbus_marshal_int32), (_dbus_marshal_uint32), (_dbus_demarshal_double), (_dbus_demarshal_int32), (_dbus_demarshal_uint32), (_dbus_demarshal_string), (_dbus_marshal_get_field_end_pos), (_dbus_verbose_bytes), (_dbus_marshal_test): * dbus/dbus-marshal.h: * dbus/dbus-message-internal.h: * dbus/dbus-message.c: (_dbus_message_set_client_serial), (dbus_message_write_header), (_dbus_message_lock), (dbus_message_new), (dbus_message_ref), (dbus_message_unref), (dbus_message_get_name), (dbus_message_append_int32), (dbus_message_append_uint32), (dbus_message_append_double), (dbus_message_append_string), (dbus_message_append_byte_array), (dbus_message_get_fields_iter), (dbus_message_iter_ref), (dbus_message_iter_unref), (dbus_message_iter_has_next), (dbus_message_iter_next), (dbus_message_iter_get_field_type), (dbus_message_iter_get_string), (dbus_message_iter_get_int32), (dbus_message_iter_get_uint32), (dbus_message_iter_get_double), (decode_header_data), (_dbus_message_loader_return_buffer), (message_iter_test), (_dbus_message_test): * dbus/dbus-message.h: * dbus/dbus-protocol.h: * dbus/dbus-test.c: (main): * dbus/dbus-test.h: * glib/test-dbus-glib.c: (message_handler), (main): * test/echo-client.c: (main): * test/watch.c: (check_messages): Make messages sendable and receivable for real.
This commit is contained in:
parent
49686ee969
commit
1b53cbcce3
15 changed files with 784 additions and 106 deletions
37
ChangeLog
37
ChangeLog
|
|
@ -1,3 +1,40 @@
|
|||
2003-01-07 Anders Carlsson <andersca@codefactory.se>
|
||||
|
||||
* dbus/dbus-connection-internal.h:
|
||||
* dbus/dbus-connection.c: (_dbus_connection_new_for_transport),
|
||||
(_dbus_connection_get_next_client_serial),
|
||||
(dbus_connection_send_message):
|
||||
* dbus/dbus-internals.h:
|
||||
* dbus/dbus-marshal.c: (unpack_uint32), (dbus_unpack_int32),
|
||||
(dbus_pack_int32), (_dbus_marshal_double), (_dbus_marshal_int32),
|
||||
(_dbus_marshal_uint32), (_dbus_demarshal_double),
|
||||
(_dbus_demarshal_int32), (_dbus_demarshal_uint32),
|
||||
(_dbus_demarshal_string), (_dbus_marshal_get_field_end_pos),
|
||||
(_dbus_verbose_bytes), (_dbus_marshal_test):
|
||||
* dbus/dbus-marshal.h:
|
||||
* dbus/dbus-message-internal.h:
|
||||
* dbus/dbus-message.c: (_dbus_message_set_client_serial),
|
||||
(dbus_message_write_header), (_dbus_message_lock),
|
||||
(dbus_message_new), (dbus_message_ref), (dbus_message_unref),
|
||||
(dbus_message_get_name), (dbus_message_append_int32),
|
||||
(dbus_message_append_uint32), (dbus_message_append_double),
|
||||
(dbus_message_append_string), (dbus_message_append_byte_array),
|
||||
(dbus_message_get_fields_iter), (dbus_message_iter_ref),
|
||||
(dbus_message_iter_unref), (dbus_message_iter_has_next),
|
||||
(dbus_message_iter_next), (dbus_message_iter_get_field_type),
|
||||
(dbus_message_iter_get_string), (dbus_message_iter_get_int32),
|
||||
(dbus_message_iter_get_uint32), (dbus_message_iter_get_double),
|
||||
(decode_header_data), (_dbus_message_loader_return_buffer),
|
||||
(message_iter_test), (_dbus_message_test):
|
||||
* dbus/dbus-message.h:
|
||||
* dbus/dbus-protocol.h:
|
||||
* dbus/dbus-test.c: (main):
|
||||
* dbus/dbus-test.h:
|
||||
* glib/test-dbus-glib.c: (message_handler), (main):
|
||||
* test/echo-client.c: (main):
|
||||
* test/watch.c: (check_messages):
|
||||
Make messages sendable and receivable for real.
|
||||
|
||||
2003-01-07 Anders Carlsson <andersca@codefactory.se>
|
||||
|
||||
* dbus/dbus-marshal.c: (_dbus_marshal_double),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ void _dbus_connection_remove_watch (DBusConnection *connect
|
|||
DBusWatch *watch);
|
||||
DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport);
|
||||
|
||||
|
||||
void _dbus_connection_do_iteration (DBusConnection *connection,
|
||||
unsigned int flags,
|
||||
int timeout_milliseconds);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ struct DBusConnection
|
|||
int handlers_serial; /**< Increments when the handler table is changed. */
|
||||
DBusDataSlot *data_slots; /**< Data slots */
|
||||
int n_slots; /**< Slots allocated so far. */
|
||||
|
||||
int client_serial; /**< Client serial. Increments each time a message is sent */
|
||||
};
|
||||
|
||||
static void _dbus_connection_free_data_slots (DBusConnection *connection);
|
||||
|
|
@ -330,6 +332,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
|
|||
|
||||
connection->data_slots = NULL;
|
||||
connection->n_slots = 0;
|
||||
connection->client_serial = 1;
|
||||
|
||||
_dbus_transport_ref (transport);
|
||||
_dbus_transport_set_connection (transport, connection);
|
||||
|
|
@ -350,6 +353,19 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static dbus_int32_t
|
||||
_dbus_connection_get_next_client_serial (DBusConnection *connection)
|
||||
{
|
||||
int serial;
|
||||
|
||||
serial = connection->client_serial++;
|
||||
|
||||
if (connection->client_serial < 0)
|
||||
connection->client_serial = 1;
|
||||
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to notify a connection when a DBusMessageHandler is
|
||||
* destroyed, so the connection can drop any reference
|
||||
|
|
@ -580,7 +596,8 @@ dbus_connection_send_message (DBusConnection *connection,
|
|||
|
||||
_dbus_verbose ("Message %p added to outgoing queue, %d pending to send\n",
|
||||
message, connection->n_outgoing);
|
||||
|
||||
|
||||
_dbus_message_set_client_serial (message, _dbus_connection_get_next_client_serial (connection));
|
||||
_dbus_message_lock (message);
|
||||
|
||||
if (connection->n_outgoing == 1)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,23 @@ do {
|
|||
#define _DBUS_STRUCT_OFFSET(struct_type, member) \
|
||||
((long) ((unsigned char*) &((struct_type*) 0)->member))
|
||||
|
||||
/* This alignment thing is from ORBit2 */
|
||||
/* Align a value upward to a boundary, expressed as a number of bytes.
|
||||
* E.g. align to an 8-byte boundary with argument of 8.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (this + boundary - 1)
|
||||
* &
|
||||
* ~(boundary - 1)
|
||||
*/
|
||||
|
||||
#define _DBUS_ALIGN_VALUE(this, boundary) \
|
||||
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
||||
|
||||
#define _DBUS_ALIGN_ADDRESS(this, boundary) \
|
||||
((void*)_DBUS_ALIGN_VALUE(this, boundary))
|
||||
|
||||
char* _dbus_strdup (const char *str);
|
||||
|
||||
#define _DBUS_INT_MIN (-_DBUS_INT_MAX - 1)
|
||||
|
|
|
|||
|
|
@ -53,23 +53,6 @@
|
|||
#define DBUS_UINT32_FROM_BE(val) (DBUS_UINT32_TO_BE (val))
|
||||
|
||||
|
||||
/* This alignment thing is from ORBit2 */
|
||||
/* Align a value upward to a boundary, expressed as a number of bytes.
|
||||
* E.g. align to an 8-byte boundary with argument of 8.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (this + boundary - 1)
|
||||
* &
|
||||
* ~(boundary - 1)
|
||||
*/
|
||||
|
||||
#define DBUS_ALIGN_VALUE(this, boundary) \
|
||||
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
||||
|
||||
#define DBUS_ALIGN_ADDRESS(this, boundary) \
|
||||
((void*)DBUS_ALIGN_VALUE(this, boundary))
|
||||
|
||||
/* from ORBit */
|
||||
static void
|
||||
swap_bytes (unsigned char *data,
|
||||
|
|
@ -93,7 +76,7 @@ static dbus_uint32_t
|
|||
unpack_uint32 (int byte_order,
|
||||
const unsigned char *data)
|
||||
{
|
||||
_dbus_assert (DBUS_ALIGN_ADDRESS (data, 4) == data);
|
||||
_dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
|
||||
|
||||
if (byte_order == DBUS_LITTLE_ENDIAN)
|
||||
return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
|
||||
|
|
@ -101,11 +84,18 @@ unpack_uint32 (int byte_order,
|
|||
return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
|
||||
}
|
||||
|
||||
static dbus_int32_t
|
||||
unpack_int32 (int byte_order,
|
||||
const unsigned char *data)
|
||||
/**
|
||||
* Unpacks a 32 bit unsigned integer from a data pointer
|
||||
*
|
||||
* @param byte_order The byte order to use
|
||||
* @param data the data pointer
|
||||
* @returns the integer
|
||||
*/
|
||||
dbus_int32_t
|
||||
dbus_unpack_int32 (int byte_order,
|
||||
const unsigned char *data)
|
||||
{
|
||||
_dbus_assert (DBUS_ALIGN_ADDRESS (data, 4) == data);
|
||||
_dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
|
||||
|
||||
if (byte_order == DBUS_LITTLE_ENDIAN)
|
||||
return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
|
||||
|
|
@ -124,6 +114,26 @@ unpack_int32 (int byte_order,
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Packs a 32 bit unsigned integer into a data pointer.
|
||||
*
|
||||
* @param value the value
|
||||
* @param byte_order the byte order to use
|
||||
* @param data the data pointer
|
||||
*/
|
||||
void
|
||||
dbus_pack_int32 (dbus_int32_t value,
|
||||
int byte_order,
|
||||
unsigned char *data)
|
||||
{
|
||||
_dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
|
||||
|
||||
if ((byte_order) == DBUS_LITTLE_ENDIAN)
|
||||
*((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);
|
||||
else
|
||||
*((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshals a double value.
|
||||
*
|
||||
|
|
@ -137,6 +147,11 @@ _dbus_marshal_double (DBusString *str,
|
|||
int byte_order,
|
||||
double value)
|
||||
{
|
||||
if (!_dbus_string_set_length (str,
|
||||
_DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
|
||||
sizeof (double))))
|
||||
return FALSE;
|
||||
|
||||
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
|
||||
swap_bytes ((unsigned char *)&value, sizeof (double));
|
||||
|
||||
|
|
@ -157,7 +172,7 @@ _dbus_marshal_int32 (DBusString *str,
|
|||
dbus_int32_t value)
|
||||
{
|
||||
if (!_dbus_string_set_length (str,
|
||||
DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
|
||||
_DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
|
||||
sizeof (dbus_int32_t))))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -181,7 +196,7 @@ _dbus_marshal_uint32 (DBusString *str,
|
|||
dbus_uint32_t value)
|
||||
{
|
||||
if (!_dbus_string_set_length (str,
|
||||
DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
|
||||
_DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
|
||||
sizeof (dbus_uint32_t))))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -269,8 +284,8 @@ _dbus_demarshal_double (DBusString *str,
|
|||
double retval;
|
||||
const char *buffer;
|
||||
|
||||
pos = DBUS_ALIGN_VALUE (pos, sizeof (double));
|
||||
|
||||
pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
|
||||
|
||||
_dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
|
||||
|
||||
retval = *(double *)buffer;
|
||||
|
|
@ -301,14 +316,14 @@ _dbus_demarshal_int32 (DBusString *str,
|
|||
{
|
||||
const char *buffer;
|
||||
|
||||
pos = DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
|
||||
pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
|
||||
|
||||
_dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_int32_t));
|
||||
|
||||
if (new_pos)
|
||||
*new_pos = pos + sizeof (dbus_int32_t);
|
||||
|
||||
return unpack_int32 (byte_order, buffer);
|
||||
return dbus_unpack_int32 (byte_order, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -328,7 +343,7 @@ _dbus_demarshal_uint32 (DBusString *str,
|
|||
{
|
||||
const char *buffer;
|
||||
|
||||
pos = DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
|
||||
pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
|
||||
|
||||
_dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_uint32_t));
|
||||
|
||||
|
|
@ -368,7 +383,7 @@ _dbus_demarshal_string (DBusString *str,
|
|||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
_dbus_string_get_const_data_len (str, &data, pos, 3);
|
||||
_dbus_string_get_const_data_len (str, &data, pos, len);
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
|
@ -381,6 +396,86 @@ _dbus_demarshal_string (DBusString *str,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position right after the end position
|
||||
* end position of a field
|
||||
*
|
||||
* @param str a string
|
||||
* @param byte_order the byte order to use
|
||||
* @param pos the pos where the field starts
|
||||
* @param end_pos pointer where the position right
|
||||
* after the end position will follow
|
||||
* @returns TRUE if more data exists after the field
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_marshal_get_field_end_pos (DBusString *str,
|
||||
int byte_order,
|
||||
int pos,
|
||||
int *end_pos)
|
||||
{
|
||||
const char *data;
|
||||
|
||||
if (pos >= _dbus_string_get_length (str))
|
||||
return FALSE;
|
||||
|
||||
_dbus_string_get_const_data_len (str, &data, pos, 1);
|
||||
|
||||
switch (*data)
|
||||
{
|
||||
case DBUS_TYPE_INVALID:
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_INT32:
|
||||
*end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
|
||||
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_UINT32:
|
||||
*end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
|
||||
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
*end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
|
||||
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_STRING:
|
||||
{
|
||||
int len, new_pos;
|
||||
|
||||
/* Demarshal the length */
|
||||
len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
|
||||
|
||||
*end_pos = new_pos + len + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DBUS_TYPE_BYTE_ARRAY:
|
||||
{
|
||||
int len, new_pos;
|
||||
|
||||
/* Demarshal the length */
|
||||
len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
|
||||
|
||||
*end_pos = new_pos + len;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
_dbus_warn ("Unknown message field type %d\n", *data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*end_pos >= _dbus_string_get_length (str))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* If in verbose mode, print a block of binary data.
|
||||
*
|
||||
|
|
@ -397,7 +492,7 @@ _dbus_verbose_bytes (const unsigned char *data,
|
|||
const unsigned char *aligned;
|
||||
|
||||
/* Print blanks on first row if appropriate */
|
||||
aligned = DBUS_ALIGN_ADDRESS (data, 4);
|
||||
aligned = _DBUS_ALIGN_ADDRESS (data, 4);
|
||||
if (aligned > data)
|
||||
aligned -= 4;
|
||||
_dbus_assert (aligned <= data);
|
||||
|
|
@ -416,7 +511,7 @@ _dbus_verbose_bytes (const unsigned char *data,
|
|||
i = 0;
|
||||
while (i < len)
|
||||
{
|
||||
if (DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
|
||||
if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
|
||||
{
|
||||
_dbus_verbose ("%5d\t%p: ",
|
||||
i, &data[i]);
|
||||
|
|
@ -431,7 +526,7 @@ _dbus_verbose_bytes (const unsigned char *data,
|
|||
|
||||
++i;
|
||||
|
||||
if (DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
|
||||
if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
|
||||
{
|
||||
if (i > 3)
|
||||
_dbus_verbose ("big: %d little: %d",
|
||||
|
|
@ -486,7 +581,6 @@ _dbus_marshal_test (void)
|
|||
_dbus_assert_not_reached ("could not marshal double value");
|
||||
_dbus_assert (_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14);
|
||||
|
||||
|
||||
if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
|
||||
_dbus_assert_not_reached ("could not marshal double value");
|
||||
_dbus_assert (_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@
|
|||
#define DBUS_COMPILER_BYTE_ORDER DBUS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
void dbus_pack_int32 (dbus_int32_t value,
|
||||
int byte_order,
|
||||
unsigned char *data);
|
||||
dbus_int32_t dbus_unpack_int32 (int byte_order,
|
||||
const unsigned char *data);
|
||||
|
||||
|
||||
dbus_bool_t _dbus_marshal_double (DBusString *str,
|
||||
int byte_order,
|
||||
double value);
|
||||
|
|
@ -73,7 +80,10 @@ char * _dbus_demarshal_string (DBusString *str,
|
|||
int pos,
|
||||
int *new_pos);
|
||||
|
||||
|
||||
dbus_bool_t _dbus_marshal_get_field_end_pos (DBusString *str,
|
||||
int byte_order,
|
||||
int pos,
|
||||
int *end_pos);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,14 @@ DBUS_BEGIN_DECLS;
|
|||
|
||||
typedef struct DBusMessageLoader DBusMessageLoader;
|
||||
|
||||
void _dbus_message_get_network_data (DBusMessage *message,
|
||||
const DBusString **header,
|
||||
const DBusString **body);
|
||||
void _dbus_message_get_network_data (DBusMessage *message,
|
||||
const DBusString **header,
|
||||
const DBusString **body);
|
||||
|
||||
void _dbus_message_lock (DBusMessage *message);
|
||||
void _dbus_message_lock (DBusMessage *message);
|
||||
|
||||
void _dbus_message_set_client_serial (DBusMessage *message,
|
||||
dbus_int32_t client_serial);
|
||||
|
||||
DBusMessageLoader* _dbus_message_loader_new (void);
|
||||
void _dbus_message_loader_ref (DBusMessageLoader *loader);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
/* dbus-message.c DBusMessage object
|
||||
*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
* Copyright (C) 2002, 2003 CodeFactory AB
|
||||
*
|
||||
* Licensed under the Academic Free License version 1.2
|
||||
*
|
||||
|
|
@ -64,9 +65,26 @@ struct DBusMessage
|
|||
|
||||
DBusString body; /**< Body network data. */
|
||||
|
||||
char byte_order; /**< Message byte order. */
|
||||
|
||||
char *name; /**< Message name. */
|
||||
char *service; /**< Message destination service. */
|
||||
|
||||
dbus_int32_t client_serial; /**< Client serial or -1 if not set */
|
||||
dbus_int32_t reply_serial; /**< Reply serial or -1 if not set */
|
||||
|
||||
unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
|
||||
};
|
||||
|
||||
struct DBusMessageIter
|
||||
{
|
||||
int refcount; /**< Reference count */
|
||||
|
||||
int pos; /**< Current position in the string */
|
||||
|
||||
DBusMessage *message; /**< Message used */
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the data to be sent over the network for this message.
|
||||
* The header and then the body should be written out.
|
||||
|
|
@ -88,6 +106,69 @@ _dbus_message_get_network_data (DBusMessage *message,
|
|||
*body = &message->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client serial of a message.
|
||||
* This can only be done once on a message.
|
||||
*
|
||||
* @param message the message
|
||||
* @param client_serial the client serial
|
||||
*/
|
||||
void
|
||||
_dbus_message_set_client_serial (DBusMessage *message,
|
||||
dbus_int32_t client_serial)
|
||||
{
|
||||
_dbus_assert (message->client_serial == -1);
|
||||
|
||||
message->client_serial = client_serial;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_message_write_header (DBusMessage *message)
|
||||
{
|
||||
char *header;
|
||||
|
||||
_dbus_assert (message->client_serial != -1);
|
||||
|
||||
_dbus_string_append_byte (&message->header, DBUS_COMPILER_BYTE_ORDER);
|
||||
_dbus_string_append_len (&message->header, "\0\0\0", 3);
|
||||
|
||||
/* We just lengthen the string here and pack in the real length later */
|
||||
_dbus_string_lengthen (&message->header, 4);
|
||||
|
||||
_dbus_marshal_int32 (&message->header, DBUS_COMPILER_BYTE_ORDER, _dbus_string_get_length (&message->body));
|
||||
|
||||
/* Marshal client serial */
|
||||
_dbus_marshal_int32 (&message->header, DBUS_COMPILER_BYTE_ORDER, message->client_serial);
|
||||
|
||||
/* Marshal message service */
|
||||
if (message->service)
|
||||
{
|
||||
_dbus_string_append_len (&message->header, DBUS_HEADER_FIELD_SERVICE, 4);
|
||||
_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING);
|
||||
|
||||
_dbus_marshal_string (&message->header, DBUS_COMPILER_BYTE_ORDER, message->service);
|
||||
}
|
||||
|
||||
/* Marshal message name */
|
||||
_dbus_string_append_len (&message->header, DBUS_HEADER_FIELD_NAME, 4);
|
||||
_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING);
|
||||
|
||||
_dbus_marshal_string (&message->header, DBUS_COMPILER_BYTE_ORDER, message->name);
|
||||
|
||||
/* Marshal reply serial */
|
||||
if (message->reply_serial != -1)
|
||||
{
|
||||
_dbus_string_append_len (&message->header, DBUS_HEADER_FIELD_REPLY, 4);
|
||||
|
||||
_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32);
|
||||
_dbus_marshal_int32 (&message->header, DBUS_COMPILER_BYTE_ORDER, message->reply_serial);
|
||||
}
|
||||
|
||||
/* Fill in the length */
|
||||
_dbus_string_get_data_len (&message->header, &header, 4, 4);
|
||||
dbus_pack_int32 (_dbus_string_get_length (&message->header), DBUS_COMPILER_BYTE_ORDER, header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a message. Allows checking that applications don't keep a
|
||||
* reference to a message in the outgoing queue and change it
|
||||
|
|
@ -98,8 +179,11 @@ _dbus_message_get_network_data (DBusMessage *message,
|
|||
* @param message the message to lock.
|
||||
*/
|
||||
void
|
||||
_dbus_message_lock (DBusMessage *message)
|
||||
_dbus_message_lock (DBusMessage *message)
|
||||
{
|
||||
if (!message->locked)
|
||||
dbus_message_write_header (message);
|
||||
|
||||
message->locked = TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -128,12 +212,16 @@ _dbus_message_lock (DBusMessage *message)
|
|||
/**
|
||||
* Constructs a new message. Returns #NULL if memory
|
||||
* can't be allocated for the message.
|
||||
*
|
||||
* @return a new DBusMessage, free with dbus_message_unref()
|
||||
*
|
||||
* @param service service that the message should be sent to
|
||||
* should be sent to
|
||||
* @param name name of the message
|
||||
* @returns a new DBusMessage, free with dbus_message_unref()
|
||||
* @see dbus_message_unref()
|
||||
*/
|
||||
DBusMessage*
|
||||
dbus_message_new (void)
|
||||
dbus_message_new (const char *service,
|
||||
const char *name)
|
||||
{
|
||||
DBusMessage *message;
|
||||
|
||||
|
|
@ -142,7 +230,14 @@ dbus_message_new (void)
|
|||
return NULL;
|
||||
|
||||
message->refcount = 1;
|
||||
message->byte_order = DBUS_COMPILER_BYTE_ORDER;
|
||||
|
||||
message->service = _dbus_strdup (service);
|
||||
message->name = _dbus_strdup (name);
|
||||
|
||||
message->client_serial = -1;
|
||||
message->reply_serial = -1;
|
||||
|
||||
if (!_dbus_string_init (&message->header, _DBUS_MAX_MESSAGE_LENGTH))
|
||||
{
|
||||
dbus_free (message);
|
||||
|
|
@ -156,13 +251,6 @@ dbus_message_new (void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* We need to decide what a message contains. ;-) */
|
||||
/* (not bothering to check failure of these appends) */
|
||||
_dbus_string_append (&message->header, "H");
|
||||
_dbus_string_append_byte (&message->header, '\0');
|
||||
_dbus_string_append (&message->body, "Body");
|
||||
_dbus_string_append_byte (&message->body, '\0');
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +264,8 @@ dbus_message_new (void)
|
|||
void
|
||||
dbus_message_ref (DBusMessage *message)
|
||||
{
|
||||
_dbus_assert (message->refcount > 0);
|
||||
|
||||
message->refcount += 1;
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +278,6 @@ dbus_message_ref (DBusMessage *message)
|
|||
void
|
||||
dbus_message_unref (DBusMessage *message)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (message->refcount > 0);
|
||||
|
||||
message->refcount -= 1;
|
||||
|
|
@ -197,6 +286,7 @@ dbus_message_unref (DBusMessage *message)
|
|||
_dbus_string_free (&message->header);
|
||||
_dbus_string_free (&message->body);
|
||||
|
||||
dbus_free (message->name);
|
||||
dbus_free (message);
|
||||
}
|
||||
}
|
||||
|
|
@ -210,9 +300,7 @@ dbus_message_unref (DBusMessage *message)
|
|||
const char*
|
||||
dbus_message_get_name (DBusMessage *message)
|
||||
{
|
||||
/* FIXME */
|
||||
|
||||
return NULL;
|
||||
return message->name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -226,7 +314,6 @@ dbus_bool_t
|
|||
dbus_message_append_int32 (DBusMessage *message,
|
||||
dbus_int32_t value)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (!message->locked);
|
||||
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32))
|
||||
|
|
@ -250,7 +337,6 @@ dbus_bool_t
|
|||
dbus_message_append_uint32 (DBusMessage *message,
|
||||
dbus_uint32_t value)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (!message->locked);
|
||||
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UINT32))
|
||||
|
|
@ -274,10 +360,9 @@ dbus_bool_t
|
|||
dbus_message_append_double (DBusMessage *message,
|
||||
double value)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (!message->locked);
|
||||
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32))
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DOUBLE))
|
||||
{
|
||||
_dbus_string_shorten (&message->body, 1);
|
||||
return FALSE;
|
||||
|
|
@ -298,11 +383,9 @@ dbus_bool_t
|
|||
dbus_message_append_string (DBusMessage *message,
|
||||
const char *value)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (!message->locked);
|
||||
_dbus_assert (value != NULL);
|
||||
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UTF8_STRING))
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING))
|
||||
{
|
||||
_dbus_string_shorten (&message->body, 1);
|
||||
return FALSE;
|
||||
|
|
@ -325,9 +408,7 @@ dbus_message_append_byte_array (DBusMessage *message,
|
|||
unsigned const char *value,
|
||||
int len)
|
||||
{
|
||||
_dbus_assert (message != NULL);
|
||||
_dbus_assert (!message->locked);
|
||||
_dbus_assert (value != NULL);
|
||||
|
||||
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BYTE_ARRAY))
|
||||
{
|
||||
|
|
@ -339,6 +420,198 @@ dbus_message_append_byte_array (DBusMessage *message,
|
|||
DBUS_COMPILER_BYTE_ORDER, value, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DBusMessageIter representing the fields of the
|
||||
* message passed in.
|
||||
*
|
||||
* @param message the message
|
||||
* @returns a new iter.
|
||||
*/
|
||||
DBusMessageIter *
|
||||
dbus_message_get_fields_iter (DBusMessage *message)
|
||||
{
|
||||
DBusMessageIter *iter;
|
||||
|
||||
iter = dbus_new (DBusMessageIter, 1);
|
||||
|
||||
dbus_message_ref (message);
|
||||
|
||||
iter->refcount = 1;
|
||||
iter->message = message;
|
||||
iter->pos = 0;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the reference count of a DBusMessageIter.
|
||||
*
|
||||
* @param iter the message iter
|
||||
* @see dbus_message_iter_unref
|
||||
*/
|
||||
void
|
||||
dbus_message_iter_ref (DBusMessageIter *iter)
|
||||
{
|
||||
_dbus_assert (iter->refcount > 0);
|
||||
|
||||
iter->refcount += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the reference count of a DBusMessageIter.
|
||||
*
|
||||
* @param iter The message iter
|
||||
* @see dbus_message_iter_ref
|
||||
*/
|
||||
void
|
||||
dbus_message_iter_unref (DBusMessageIter *iter)
|
||||
{
|
||||
_dbus_assert (iter->refcount > 0);
|
||||
|
||||
iter->refcount -= 1;
|
||||
|
||||
if (iter->refcount == 0)
|
||||
{
|
||||
dbus_message_unref (iter->message);
|
||||
|
||||
dbus_free (iter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an iterator has any more fields.
|
||||
*
|
||||
* @param iter the message iter
|
||||
* @returns #TRUE if there are more fields
|
||||
* following
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_message_iter_has_next (DBusMessageIter *iter)
|
||||
{
|
||||
int end_pos;
|
||||
|
||||
if (!_dbus_marshal_get_field_end_pos (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos, &end_pos))
|
||||
return FALSE;
|
||||
|
||||
if (end_pos >= _dbus_string_get_length (&iter->message->body))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the iterator to the next field.
|
||||
*
|
||||
* @param iter The message iter
|
||||
* @returns #TRUE if the iterator was moved to the next field
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_message_iter_next (DBusMessageIter *iter)
|
||||
{
|
||||
int end_pos;
|
||||
|
||||
if (!_dbus_marshal_get_field_end_pos (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos, &end_pos))
|
||||
return FALSE;
|
||||
|
||||
if (end_pos >= _dbus_string_get_length (&iter->message->body))
|
||||
return FALSE;
|
||||
|
||||
iter->pos = end_pos;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field type of the field that the
|
||||
* message iterator points at.
|
||||
*
|
||||
* @param iter the message iter
|
||||
* @returns the field type
|
||||
*/
|
||||
int
|
||||
dbus_message_iter_get_field_type (DBusMessageIter *iter)
|
||||
{
|
||||
const char *data;
|
||||
|
||||
if (iter->pos >= _dbus_string_get_length (&iter->message->body))
|
||||
return DBUS_TYPE_INVALID;
|
||||
|
||||
_dbus_string_get_const_data_len (&iter->message->body, &data, iter->pos, 1);
|
||||
|
||||
if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_STRING)
|
||||
return *data;
|
||||
|
||||
return DBUS_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string value that an iterator may point to.
|
||||
* Note that you need to check that the iterator points to
|
||||
* a string value before using this function.
|
||||
*
|
||||
* @see dbus_message_iter_get_field_type
|
||||
* @param iter the message iter
|
||||
* @returns the string
|
||||
*/
|
||||
char *
|
||||
dbus_message_iter_get_string (DBusMessageIter *iter)
|
||||
{
|
||||
_dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_STRING);
|
||||
|
||||
return _dbus_demarshal_string (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos + 1, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 32 bit signed integer value that an iterator may point to.
|
||||
* Note that you need to check that the iterator points to
|
||||
* a string value before using this function.
|
||||
*
|
||||
* @see dbus_message_iter_get_field_type
|
||||
* @param iter the message iter
|
||||
* @returns the integer
|
||||
*/
|
||||
int
|
||||
dbus_message_iter_get_int32 (DBusMessageIter *iter)
|
||||
{
|
||||
return _dbus_demarshal_int32 (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos + 1, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 32 bit unsigned integer value that an iterator may point to.
|
||||
* Note that you need to check that the iterator points to
|
||||
* a string value before using this function.
|
||||
*
|
||||
* @see dbus_message_iter_get_field_type
|
||||
* @param iter the message iter
|
||||
* @returns the integer
|
||||
*/
|
||||
int
|
||||
dbus_message_iter_get_uint32 (DBusMessageIter *iter)
|
||||
{
|
||||
return _dbus_demarshal_uint32 (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos + 1, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the double value that an iterator may point to.
|
||||
* Note that you need to check that the iterator points to
|
||||
* a string value before using this function.
|
||||
*
|
||||
* @see dbus_message_iter_get_field_type
|
||||
* @param iter the message iter
|
||||
* @returns the double
|
||||
*/
|
||||
double
|
||||
dbus_message_iter_get_double (DBusMessageIter *iter)
|
||||
{
|
||||
return _dbus_demarshal_double (&iter->message->body, iter->message->byte_order,
|
||||
iter->pos + 1, NULL);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
@ -477,6 +750,65 @@ _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
|
|||
loader->buffer_outstanding = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The smallest header size that can occur.
|
||||
* (It won't be valid)
|
||||
*/
|
||||
#define DBUS_MINIMUM_HEADER_SIZE 16
|
||||
|
||||
static dbus_bool_t
|
||||
decode_header_data (DBusString *data,
|
||||
int header_len,
|
||||
int byte_order,
|
||||
dbus_int32_t *client_serial,
|
||||
char **service,
|
||||
char **name)
|
||||
{
|
||||
const char *field;
|
||||
int pos, new_pos;
|
||||
|
||||
/* First demarshal the client serial */
|
||||
*client_serial = _dbus_demarshal_int32 (data, byte_order, 12, &pos);
|
||||
|
||||
*service = NULL;
|
||||
*name = NULL;
|
||||
|
||||
/* Now handle the fields */
|
||||
while (pos < header_len)
|
||||
{
|
||||
_dbus_string_get_const_data_len (data, &field, pos, 4);
|
||||
pos += 4;
|
||||
|
||||
if (pos > header_len)
|
||||
return FALSE;
|
||||
|
||||
if (strncmp (field, DBUS_HEADER_FIELD_SERVICE, 4) == 0)
|
||||
{
|
||||
*service = _dbus_demarshal_string (data, byte_order, pos + 1, &new_pos);
|
||||
}
|
||||
else if (strncmp (field, DBUS_HEADER_FIELD_NAME, 4) == 0)
|
||||
{
|
||||
*name = _dbus_demarshal_string (data, byte_order, pos + 1, &new_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Encountered an unknown header field: %c%c%c%c\n",
|
||||
field[0], field[1], field[2], field[3]);
|
||||
|
||||
if (!_dbus_marshal_get_field_end_pos (data, byte_order, pos, &new_pos))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (new_pos > header_len)
|
||||
return FALSE;
|
||||
|
||||
pos = new_pos;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a buffer obtained from _dbus_message_loader_get_buffer(),
|
||||
* indicating to the loader how many bytes of the buffer were filled
|
||||
|
|
@ -495,49 +827,67 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
|
|||
_dbus_assert (loader->buffer_outstanding);
|
||||
_dbus_assert (buffer == &loader->data);
|
||||
|
||||
/* FIXME fake implementation just creates a message for every 7
|
||||
* bytes. The real implementation will pass ownership of
|
||||
* loader->data bytes to new messages, to avoid memcpy. We can also
|
||||
* smart-realloc loader->data to shrink it if it's too big, though
|
||||
* _dbus_message_loader_get_buffer() could strategically arrange for
|
||||
* that to usually not happen.
|
||||
*/
|
||||
|
||||
loader->buffer_outstanding = FALSE;
|
||||
|
||||
if (loader->corrupted)
|
||||
return;
|
||||
|
||||
while (_dbus_string_get_length (&loader->data) >= 7)
|
||||
|
||||
while (_dbus_string_get_length (&loader->data) >= 16)
|
||||
{
|
||||
DBusMessage *message;
|
||||
const char *d;
|
||||
|
||||
_dbus_string_get_const_data (&loader->data, &d);
|
||||
if (d[0] != 'H' ||
|
||||
d[1] != '\0' ||
|
||||
d[2] != 'B' ||
|
||||
d[3] != 'o' ||
|
||||
d[4] != 'd' ||
|
||||
d[5] != 'y' ||
|
||||
d[6] != '\0')
|
||||
{
|
||||
_dbus_verbose_bytes (d,
|
||||
_dbus_string_get_length (&loader->data));
|
||||
loader->corrupted = TRUE;
|
||||
return;
|
||||
}
|
||||
DBusMessage *message;
|
||||
const char *header_data;
|
||||
int byte_order, header_len, body_len;
|
||||
|
||||
message = dbus_message_new ();
|
||||
if (message == NULL)
|
||||
break; /* ugh, postpone this I guess. */
|
||||
_dbus_string_get_const_data_len (&loader->data, &header_data, 0, 16);
|
||||
byte_order = header_data[0];
|
||||
|
||||
_dbus_list_append (&loader->messages, message);
|
||||
if (byte_order != DBUS_LITTLE_ENDIAN &&
|
||||
byte_order != DBUS_BIG_ENDIAN)
|
||||
{
|
||||
loader->corrupted = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
_dbus_string_delete (&loader->data,
|
||||
0, 7);
|
||||
|
||||
_dbus_verbose ("Loaded message %p\n", message);
|
||||
header_len = dbus_unpack_int32 (byte_order, header_data + 4);
|
||||
body_len = dbus_unpack_int32 (byte_order, header_data + 8);
|
||||
|
||||
if (header_len + body_len > _DBUS_MAX_MESSAGE_LENGTH)
|
||||
{
|
||||
loader->corrupted = TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dbus_string_get_length (&loader->data) >= header_len + body_len)
|
||||
{
|
||||
dbus_int32_t client_serial;
|
||||
char *service, *name;
|
||||
|
||||
if (!decode_header_data (&loader->data, header_len, byte_order,
|
||||
&client_serial, &service, &name))
|
||||
{
|
||||
loader->corrupted = TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
message = dbus_message_new (service, name);
|
||||
dbus_free (service);
|
||||
dbus_free (name);
|
||||
|
||||
if (message == NULL)
|
||||
break; /* ugh, postpone this I guess. */
|
||||
|
||||
_dbus_string_copy (&loader->data, header_len, &message->body, 0);
|
||||
_dbus_message_set_client_serial (message, client_serial);
|
||||
|
||||
_dbus_list_append (&loader->messages, message);
|
||||
_dbus_string_delete (&loader->data, 0, header_len + body_len);
|
||||
|
||||
_dbus_verbose ("Loaded message %p\n", message);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -572,3 +922,129 @@ _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
|
|||
}
|
||||
|
||||
/** @} */
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void
|
||||
message_iter_test (DBusMessage *message)
|
||||
{
|
||||
DBusMessageIter *iter;
|
||||
char *str;
|
||||
|
||||
iter = dbus_message_get_fields_iter (message);
|
||||
|
||||
/* String tests */
|
||||
if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_STRING)
|
||||
_dbus_assert_not_reached ("Field type isn't string");
|
||||
|
||||
str = dbus_message_iter_get_string (iter);
|
||||
if (strcmp (str, "Test string") != 0)
|
||||
_dbus_assert_not_reached ("Strings differ");
|
||||
dbus_free (str);
|
||||
|
||||
if (!dbus_message_iter_next (iter))
|
||||
_dbus_assert_not_reached ("Reached end of fields");
|
||||
|
||||
/* Signed integer tests */
|
||||
if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_INT32)
|
||||
_dbus_assert_not_reached ("Field type isn't int32");
|
||||
|
||||
if (dbus_message_iter_get_int32 (iter) != -0x12345678)
|
||||
_dbus_assert_not_reached ("Signed integers differ");
|
||||
|
||||
if (!dbus_message_iter_next (iter))
|
||||
_dbus_assert_not_reached ("Reached end of fields");
|
||||
|
||||
/* Unsigned integer tests */
|
||||
if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_UINT32)
|
||||
_dbus_assert_not_reached ("Field type isn't int32");
|
||||
|
||||
if (dbus_message_iter_get_int32 (iter) != 0xedd1e)
|
||||
_dbus_assert_not_reached ("Unsigned integers differ");
|
||||
|
||||
if (!dbus_message_iter_next (iter))
|
||||
_dbus_assert_not_reached ("Reached end of fields");
|
||||
|
||||
/* Double tests */
|
||||
if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_DOUBLE)
|
||||
_dbus_assert_not_reached ("Field type isn't double");
|
||||
|
||||
if (dbus_message_iter_get_double (iter) != 3.14159)
|
||||
_dbus_assert_not_reached ("Doubles differ");
|
||||
|
||||
if (dbus_message_iter_next (iter))
|
||||
_dbus_assert_not_reached ("Didn't reach end of fields");
|
||||
|
||||
dbus_message_iter_unref (iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup DBusMessageInternals
|
||||
* Unit test for DBusMessage.
|
||||
*
|
||||
* @returns #TRUE on success.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_message_test (void)
|
||||
{
|
||||
DBusMessage *message;
|
||||
|
||||
DBusMessageLoader *loader;
|
||||
int i;
|
||||
const char *data;
|
||||
|
||||
message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
|
||||
message->client_serial = 1;
|
||||
dbus_message_append_string (message, "Test string");
|
||||
dbus_message_append_int32 (message, -0x12345678);
|
||||
dbus_message_append_uint32 (message, 0xedd1e);
|
||||
dbus_message_append_double (message, 3.14159);
|
||||
|
||||
message_iter_test (message);
|
||||
|
||||
/* Message loader test */
|
||||
_dbus_message_lock (message);
|
||||
loader = _dbus_message_loader_new ();
|
||||
|
||||
/* Write the header data one byte at a time */
|
||||
_dbus_string_get_const_data (&message->header, &data);
|
||||
for (i = 0; i < _dbus_string_get_length (&message->header); i++)
|
||||
{
|
||||
DBusString *buffer;
|
||||
|
||||
_dbus_message_loader_get_buffer (loader, &buffer);
|
||||
_dbus_string_append_byte (buffer, data[i]);
|
||||
_dbus_message_loader_return_buffer (loader, buffer, 1);
|
||||
}
|
||||
|
||||
/* Write the body data one byte at a time */
|
||||
_dbus_string_get_const_data (&message->body, &data);
|
||||
for (i = 0; i < _dbus_string_get_length (&message->body); i++)
|
||||
{
|
||||
DBusString *buffer;
|
||||
|
||||
_dbus_message_loader_get_buffer (loader, &buffer);
|
||||
_dbus_string_append_byte (buffer, data[i]);
|
||||
_dbus_message_loader_return_buffer (loader, buffer, 1);
|
||||
}
|
||||
|
||||
dbus_message_unref (message);
|
||||
|
||||
/* Now pop back the message */
|
||||
if (_dbus_message_loader_get_is_corrupted (loader))
|
||||
_dbus_assert_not_reached ("message loader corrupted");
|
||||
|
||||
message = _dbus_message_loader_pop_message (loader);
|
||||
if (!message)
|
||||
_dbus_assert_not_reached ("received a NULL message");
|
||||
|
||||
message_iter_test (message);
|
||||
|
||||
dbus_message_unref (message);
|
||||
_dbus_message_loader_unref (loader);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@
|
|||
DBUS_BEGIN_DECLS;
|
||||
|
||||
typedef struct DBusMessage DBusMessage;
|
||||
typedef struct DBusMessageIter DBusMessageIter;
|
||||
|
||||
DBusMessage* dbus_message_new (void);
|
||||
DBusMessage* dbus_message_new (const char *service,
|
||||
const char *name);
|
||||
|
||||
void dbus_message_ref (DBusMessage *message);
|
||||
void dbus_message_unref (DBusMessage *message);
|
||||
|
|
@ -53,6 +55,20 @@ dbus_bool_t dbus_message_append_byte_array (DBusMessage *message,
|
|||
unsigned const char *value,
|
||||
int len);
|
||||
|
||||
DBusMessageIter *dbus_message_get_fields_iter (DBusMessage *message);
|
||||
|
||||
void dbus_message_iter_ref (DBusMessageIter *iter);
|
||||
void dbus_message_iter_unref (DBusMessageIter *iter);
|
||||
|
||||
dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter);
|
||||
dbus_bool_t dbus_message_iter_next (DBusMessageIter *iter);
|
||||
int dbus_message_iter_get_field_type (DBusMessageIter *iter);
|
||||
int dbus_message_iter_get_int32 (DBusMessageIter *iter);
|
||||
int dbus_message_iter_get_uint32 (DBusMessageIter *iter);
|
||||
double dbus_message_iter_get_double (DBusMessageIter *iter);
|
||||
char * dbus_message_iter_get_string (DBusMessageIter *iter);
|
||||
|
||||
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,13 @@ extern "C" {
|
|||
#define DBUS_TYPE_UINT32_ARRAY 5
|
||||
#define DBUS_TYPE_DOUBLE_ARRAY 6
|
||||
#define DBUS_TYPE_BYTE_ARRAY 7
|
||||
#define DBUS_TYPE_UTF8_STRING 8
|
||||
#define DBUS_TYPE_STRING 8
|
||||
|
||||
/* Header fields */
|
||||
#define DBUS_HEADER_FIELD_NAME "name"
|
||||
#define DBUS_HEADER_FIELD_SERVICE "srvc"
|
||||
#define DBUS_HEADER_FIELD_REPLY "rply"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ main (int argc,
|
|||
printf ("%s: running marshalling tests\n", argv[0]);
|
||||
if (!_dbus_marshal_test ())
|
||||
die ("marshalling");
|
||||
|
||||
printf ("%s: running message tests\n", argv[0]);
|
||||
if (!_dbus_message_test ())
|
||||
die ("messages");
|
||||
|
||||
printf ("%s: running memory pool tests\n", argv[0]);
|
||||
if (!_dbus_mem_pool_test ())
|
||||
|
|
|
|||
|
|
@ -31,5 +31,6 @@ dbus_bool_t _dbus_list_test (void);
|
|||
dbus_bool_t _dbus_marshal_test (void);
|
||||
dbus_bool_t _dbus_mem_pool_test (void);
|
||||
dbus_bool_t _dbus_string_test (void);
|
||||
dbus_bool_t _dbus_message_test (void);
|
||||
|
||||
#endif /* DBUS_TEST_H */
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ message_handler (DBusConnection *connection,
|
|||
static int count = 0;
|
||||
DBusMessage *reply;
|
||||
|
||||
reply = dbus_message_new ();
|
||||
reply = dbus_message_new ("org.freedesktop.DBus.Test", "org.freedesktop.DBus.Test");
|
||||
dbus_connection_send_message (connection,
|
||||
reply,
|
||||
NULL);
|
||||
|
|
@ -47,7 +47,7 @@ main (int argc, char **argv)
|
|||
g_source_attach (source, NULL);
|
||||
g_source_set_callback (source, (GSourceFunc)message_handler, NULL, NULL);
|
||||
|
||||
message = dbus_message_new ();
|
||||
message = dbus_message_new ("org.freedesktop.DBus.Test", "org.freedesktop.DBus.Test");
|
||||
dbus_connection_send_message (connection,
|
||||
message,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ main (int argc,
|
|||
setup_connection (connection);
|
||||
|
||||
/* Send a message to get things going */
|
||||
message = dbus_message_new ();
|
||||
message = dbus_message_new ("org.freedesktop.DBus.Test", "org.freedesktop.DBus.Test");
|
||||
dbus_connection_send_message (connection,
|
||||
message,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ check_messages (void)
|
|||
|
||||
printf ("Received message %d, sending reply\n", count);
|
||||
|
||||
reply = dbus_message_new ();
|
||||
reply = dbus_message_new ("org.freedesktop.DBus.Test", "org.freedesktop.DBus.Test");
|
||||
dbus_connection_send_message (connection,
|
||||
reply,
|
||||
NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue