2003-03-10 Anders Carlsson <andersca@codefactory.se>

* dbus/dbus-marshal.c:
	(_dbus_marshal_set_string):
	Take a length argument so we can marshal the correct string
	length.

	(_dbus_marshal_dict), (_dbus_demarshal_dict),
	(_dbus_marshal_get_arg_end_pos), (_dbus_marshal_validate_arg),
	(_dbus_marshal_test):
	* dbus/dbus-marshal.h:
	Add support for marshalling and demarshalling dicts.

	* dbus/dbus-message-builder.c: (_dbus_message_data_load):
	Add support for TYPE DICT.

	* dbus/dbus-message.c: (set_string_field):
	Adjust header padding.

	(dbus_message_append_args_valist), (dbus_message_append_dict),
	(dbus_message_get_args_valist), (dbus_message_iter_get_arg_type),
	(dbus_message_iter_get_dict), (_dbus_message_loader_return_buffer),
	(check_message_handling), (check_have_valid_message):
	* dbus/dbus-message.h:
	Add functions for setting and getting dicts.

	* dbus/dbus-protocol.h:
	Add DBUS_TYPE_DICT.

	* dbus/dbus.h:
	Add dbus-dict.h

	* doc/dbus-specification.sgml:
	Add information about how dicts are marshalled.

	* test/data/invalid-messages/dict-with-nil-value.message:
	* test/data/invalid-messages/too-short-dict.message:
	* test/data/valid-messages/dict-simple.message:
	* test/data/valid-messages/dict.message:
	Add sample messages containing dicts.
This commit is contained in:
Anders Carlsson 2003-03-10 00:13:55 +00:00
parent 1458fb145f
commit 799a3ff443
13 changed files with 851 additions and 56 deletions

View file

@ -1,3 +1,44 @@
2003-03-10 Anders Carlsson <andersca@codefactory.se>
* dbus/dbus-marshal.c:
(_dbus_marshal_set_string):
Take a length argument so we can marshal the correct string
length.
(_dbus_marshal_dict), (_dbus_demarshal_dict),
(_dbus_marshal_get_arg_end_pos), (_dbus_marshal_validate_arg),
(_dbus_marshal_test):
* dbus/dbus-marshal.h:
Add support for marshalling and demarshalling dicts.
* dbus/dbus-message-builder.c: (_dbus_message_data_load):
Add support for TYPE DICT.
* dbus/dbus-message.c: (set_string_field):
Adjust header padding.
(dbus_message_append_args_valist), (dbus_message_append_dict),
(dbus_message_get_args_valist), (dbus_message_iter_get_arg_type),
(dbus_message_iter_get_dict), (_dbus_message_loader_return_buffer),
(check_message_handling), (check_have_valid_message):
* dbus/dbus-message.h:
Add functions for setting and getting dicts.
* dbus/dbus-protocol.h:
Add DBUS_TYPE_DICT.
* dbus/dbus.h:
Add dbus-dict.h
* doc/dbus-specification.sgml:
Add information about how dicts are marshalled.
* test/data/invalid-messages/dict-with-nil-value.message:
* test/data/invalid-messages/too-short-dict.message:
* test/data/valid-messages/dict-simple.message:
* test/data/valid-messages/dict.message:
Add sample messages containing dicts.
2003-03-08 Anders Carlsson <andersca@codefactory.se>
* dbus/dbus-dict.h: Add DBUS_END_DECLS.

View file

@ -198,6 +198,7 @@ _dbus_marshal_set_uint32 (DBusString *str,
* @param offset the byte offset where string should be written
* @param byte_order the byte order to use
* @param value the value
* @param len the length to use
* @returns #TRUE on success
*
*/
@ -205,10 +206,10 @@ dbus_bool_t
_dbus_marshal_set_string (DBusString *str,
int byte_order,
int offset,
const DBusString *value)
const DBusString *value,
int len)
{
int old_len;
int new_len;
_dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
byte_order == DBUS_BIG_ENDIAN);
@ -216,14 +217,12 @@ _dbus_marshal_set_string (DBusString *str,
old_len = _dbus_demarshal_uint32 (str, byte_order,
offset, NULL);
new_len = _dbus_string_get_length (value);
if (!_dbus_string_replace_len (value, 0, new_len,
if (!_dbus_string_replace_len (value, 0, len,
str, offset + 4, old_len))
return FALSE;
_dbus_marshal_set_uint32 (str, byte_order,
offset, new_len);
offset, len);
return TRUE;
}
@ -496,6 +495,193 @@ _dbus_marshal_string_array (DBusString *str,
return FALSE;
}
/**
* Marshals a dict
* @param str the string to append the marshalled value to
* @param byte_order the byte order to use
* @param dict the dict
* @returns #TRUE on success
*/
dbus_bool_t
_dbus_marshal_dict (DBusString *str,
int byte_order,
DBusDict *dict)
{
int old_string_len;
int i, len;
char **keys;
old_string_len = _dbus_string_get_length (str);
if (!dbus_dict_get_keys (dict, &keys, &len))
goto error;
if (len == 0)
return TRUE;
if (!_dbus_marshal_string_array (str, byte_order,
keys, len))
goto error;
for (i = 0; i < len; i++)
{
int value_type;
value_type = dbus_dict_get_value_type (dict, keys[i]);
if (!_dbus_string_append_byte (str, value_type))
goto error;
switch (dbus_dict_get_value_type (dict, keys[i]))
{
case DBUS_TYPE_BOOLEAN:
{
dbus_bool_t value;
if (!dbus_dict_get_boolean (dict, keys[i], &value))
goto error;
if (!_dbus_string_append_byte (str, (value != FALSE)))
goto error;
break;
}
case DBUS_TYPE_INT32:
{
dbus_int32_t value;
if (!dbus_dict_get_int32 (dict, keys[i], &value))
goto error;
if (!_dbus_marshal_int32 (str, byte_order, value))
goto error;
break;
}
case DBUS_TYPE_UINT32:
{
dbus_uint32_t value;
if (!dbus_dict_get_uint32 (dict, keys[i], &value))
goto error;
if (!_dbus_marshal_uint32 (str, byte_order, value))
goto error;
break;
}
case DBUS_TYPE_DOUBLE:
{
double value;
if (!dbus_dict_get_double (dict, keys[i], &value))
goto error;
if (!_dbus_marshal_double (str, byte_order, value))
goto error;
break;
}
case DBUS_TYPE_INT32_ARRAY:
{
const dbus_int32_t *value;
int len;
if (!dbus_dict_get_int32_array (dict, keys[i], &value, &len))
goto error;
if (!_dbus_marshal_int32_array (str, byte_order, value, len))
goto error;
break;
}
case DBUS_TYPE_STRING:
{
const char *value;
if (!dbus_dict_get_string (dict, keys[i], &value))
goto error;
if (!_dbus_marshal_string (str, byte_order, value))
goto error;
break;
}
case DBUS_TYPE_BOOLEAN_ARRAY:
{
const unsigned char *value;
int len;
if (!dbus_dict_get_boolean_array (dict, keys[i], &value, &len))
goto error;
if (!_dbus_marshal_byte_array (str, byte_order, value, len))
goto error;
break;
}
case DBUS_TYPE_UINT32_ARRAY:
{
const dbus_uint32_t *value;
int len;
if (!dbus_dict_get_uint32_array (dict, keys[i], &value, &len))
goto error;
if (!_dbus_marshal_uint32_array (str, byte_order, value, len))
goto error;
break;
}
case DBUS_TYPE_DOUBLE_ARRAY:
{
const double *value;
int len;
if (!dbus_dict_get_double_array (dict, keys[i], &value, &len))
goto error;
if (!_dbus_marshal_double_array (str, byte_order, value, len))
goto error;
break;
}
case DBUS_TYPE_STRING_ARRAY:
{
const char **value;
int len;
if (!dbus_dict_get_string_array (dict, keys[i], &value, &len))
goto error;
if (!_dbus_marshal_string_array (str, byte_order, value, len))
goto error;
break;
}
default:
_dbus_warn ("unknwon value type %d\n", dbus_dict_get_value_type (dict, keys[i]));
_dbus_assert_not_reached ("unknown value type in dict");
}
}
dbus_free_string_array (keys);
return TRUE;
error:
dbus_free_string_array (keys);
/* Restore previous length */
_dbus_string_set_length (str, old_string_len);
return FALSE;
}
/**
* Demarshals a double.
*
@ -848,6 +1034,212 @@ _dbus_demarshal_string_array (const DBusString *str,
return NULL;
}
/**
* Demarshals a dict
*
* @param str the string containing the data
* @param byte_order the byte order
* @param pos the position in the string
* @param new_pos the new position in the string
* @returns the demarshalled dict
*/
DBusDict *
_dbus_demarshal_dict (const DBusString *str,
int byte_order,
int pos,
int *new_pos)
{
char **keys;
int i, len;
DBusDict *dict;
dict = dbus_dict_new ();
if (!dict)
return NULL;
keys = _dbus_demarshal_string_array (str, byte_order, pos, &pos, &len);
if (!keys)
goto error;
for (i = 0; i < len; i++)
{
int value_type;
switch ((value_type = _dbus_string_get_byte (str, pos ++)))
{
case DBUS_TYPE_BOOLEAN:
{
dbus_bool_t value;
value = _dbus_string_get_byte (str, pos ++);
if (!dbus_dict_set_boolean (dict, keys[i], value))
goto error;
break;
}
case DBUS_TYPE_INT32:
{
dbus_int32_t value;
value = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
if (!dbus_dict_set_int32 (dict, keys[i], value))
goto error;
break;
}
case DBUS_TYPE_UINT32:
{
dbus_uint32_t value;
value = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
if (!dbus_dict_set_uint32 (dict, keys[i], value))
goto error;
break;
}
case DBUS_TYPE_DOUBLE:
{
double value;
value = _dbus_demarshal_double (str, byte_order, pos, &pos);
if (!dbus_dict_set_double (dict, keys[i], value))
goto error;
break;
}
case DBUS_TYPE_STRING:
{
char *value;
value = _dbus_demarshal_string (str, byte_order, pos, &pos);
if (!value)
goto error;
if (!dbus_dict_set_string (dict, keys[i], value))
{
dbus_free (value);
goto error;
}
dbus_free (value);
break;
}
case DBUS_TYPE_BOOLEAN_ARRAY:
{
unsigned char *value;
int len;
value = _dbus_demarshal_byte_array (str, byte_order, pos, &pos, &len);
if (!value)
goto error;
if (!dbus_dict_set_boolean_array (dict, keys[i], value, len))
{
dbus_free (value);
goto error;
}
dbus_free (value);
break;
}
case DBUS_TYPE_INT32_ARRAY:
{
dbus_int32_t *value;
int len;
value = _dbus_demarshal_int32_array (str, byte_order, pos, &pos, &len);
if (!value)
goto error;
if (!dbus_dict_set_int32_array (dict, keys[i], value, len))
{
dbus_free (value);
goto error;
}
dbus_free (value);
break;
}
case DBUS_TYPE_UINT32_ARRAY:
{
dbus_uint32_t *value;
int len;
value = _dbus_demarshal_uint32_array (str, byte_order, pos, &pos, &len);
if (!value)
goto error;
if (!dbus_dict_set_uint32_array (dict, keys[i], value, len))
{
dbus_free (value);
goto error;
}
dbus_free (value);
break;
}
case DBUS_TYPE_DOUBLE_ARRAY:
{
double *value;
int len;
value = _dbus_demarshal_double_array (str, byte_order, pos, &pos, &len);
if (!value)
goto error;
if (!dbus_dict_set_double_array (dict, keys[i], value, len))
{
dbus_free (value);
goto error;
}
dbus_free (value);
break;
}
case DBUS_TYPE_STRING_ARRAY:
{
char **value;
int len;
value = _dbus_demarshal_string_array (str, byte_order, pos, &pos, &len);
if (!value)
goto error;
if (!dbus_dict_set_string_array (dict, keys[i], value, len))
{
dbus_free_string_array (value);
goto error;
}
dbus_free_string_array (value);
break;
}
default:
_dbus_warn ("unknown value type %d\n", value_type);
_dbus_assert_not_reached ("unknown value arg");
}
}
dbus_free_string_array (keys);
return dict;
error:
dbus_free_string_array (keys);
dbus_dict_unref (dict);
return NULL;
}
/**
* Returns the position right after the end of an argument. PERFORMS
* NO VALIDATION WHATSOEVER. The message must have been previously
@ -980,7 +1372,34 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
*end_pos = pos;
}
break;
case DBUS_TYPE_DICT:
{
int len, i;
/* Demarshal the length */
len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
for (i = 0; i < len; i++)
{
int str_len;
/* Demarshal string length */
str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
pos += str_len + 1;
}
/* Now check the values */
for (i = 0; i < len; i++)
{
if (!_dbus_marshal_get_arg_end_pos (str, byte_order, pos, &pos))
return FALSE;
}
*end_pos = pos;
break;
}
default:
_dbus_warn ("Unknown message arg type %d\n", *data);
_dbus_assert_not_reached ("Unknown message argument type\n");
@ -1289,7 +1708,53 @@ _dbus_marshal_validate_arg (const DBusString *str,
*end_pos = pos;
}
break;
case DBUS_TYPE_DICT:
{
int len;
int i;
len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
if (len < 0)
return FALSE;
for (i = 0; i < len; i++)
{
int str_len;
str_len = demarshal_and_validate_len (str, byte_order,
pos, &pos);
if (str_len < 0)
return FALSE;
if (!validate_string (str, pos, str_len, &pos))
return FALSE;
}
/* Now validate each argument */
for (i = 0; i < len; i++)
{
if (pos >= _dbus_string_get_length (str))
{
_dbus_verbose ("not enough values in dict\n");
return FALSE;
}
if (_dbus_string_get_byte (str, pos) == DBUS_TYPE_NIL)
{
_dbus_verbose ("can't have NIL values in dicts\n");
return FALSE;
}
if (!_dbus_marshal_validate_arg (str, byte_order, pos, &pos))
return FALSE;
}
*end_pos = pos;
break;
}
default:
_dbus_verbose ("Unknown message arg type %d\n", *data);
return FALSE;
@ -1426,7 +1891,23 @@ _dbus_marshal_test (void)
DBusString str;
char *tmp1, *tmp2;
dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
int pos = 0, len;
int pos = 0, i, len;
dbus_bool_t our_bool;
dbus_int32_t our_int;
dbus_uint32_t our_uint;
double our_double;
const char *our_string;
const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
const unsigned char *our_boolean_array;
const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
const dbus_int32_t *our_int32_array;
const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
const dbus_uint32_t *our_uint32_array;
const double double_array[] = { 3.14159, 1.2345, 6.7890 };
const double *our_double_array;
const char *string_array[] = { "This", "Is", "A", "Test" };
const char **our_string_array;
DBusDict *dict;
if (!_dbus_string_init (&str, _DBUS_INT_MAX))
_dbus_assert_not_reached ("failed to init string");
@ -1491,7 +1972,96 @@ _dbus_marshal_test (void)
dbus_free (array2);
/* Marshal dicts */
dict = dbus_dict_new ();
if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
_dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
_dbus_assert_not_reached ("could not add boolean value");
if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
_dbus_assert_not_reached ("could not add int32 value");
if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
_dbus_assert_not_reached ("could not add uint32 value");
if (!dbus_dict_set_double (dict, "double", 3.14159))
_dbus_assert_not_reached ("could not add double value");
if (!dbus_dict_set_string (dict, "string", "test string"))
_dbus_assert_not_reached ("could not add string value");
if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
_dbus_assert_not_reached ("could not add boolean array");
if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
_dbus_assert_not_reached ("could not add int32 array");
if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
_dbus_assert_not_reached ("could not add uint32 array");
if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
_dbus_assert_not_reached ("could not add double array");
if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
_dbus_assert_not_reached ("could not add string array");
if (!_dbus_marshal_dict (&str, DBUS_BIG_ENDIAN, dict))
_dbus_assert_not_reached ("could not marshal dict");
dbus_dict_unref (dict);
dict = _dbus_demarshal_dict (&str, DBUS_BIG_ENDIAN, pos, &pos);
if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
!our_bool)
_dbus_assert_not_reached ("could not get boolean value");
if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
_dbus_assert_not_reached ("could not get int32 value or int32 values differ");
if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
_dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
if (!dbus_dict_get_double (dict, "double", &our_double)
|| our_double != 3.14159)
_dbus_assert_not_reached ("could not get double value or double values differ");
if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
_dbus_assert_not_reached ("could not get string value or string values differ");
if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
_dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
_dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
_dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
_dbus_assert_not_reached ("could not get double array value or double array values differ");
if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
_dbus_assert_not_reached ("could not get string array value");
if (len != 4)
_dbus_assert_not_reached ("string array lengths differ");
for (i = 0; i < len; i++)
{
if (strcmp (our_string_array[i], string_array[i]) != 0)
_dbus_assert_not_reached ("string array fields differ");
}
dbus_dict_unref (dict);
_dbus_string_free (&str);

View file

@ -25,6 +25,7 @@
#define DBUS_MARSHAL_H
#include <config.h>
#include <dbus/dbus-dict.h>
#include <dbus/dbus-protocol.h>
#include <dbus/dbus-types.h>
#include <dbus/dbus-string.h>
@ -88,7 +89,8 @@ void _dbus_marshal_set_uint32 (DBusString *str,
dbus_bool_t _dbus_marshal_set_string (DBusString *str,
int byte_order,
int offset,
const DBusString *value);
const DBusString *value,
int len);
dbus_bool_t _dbus_marshal_int32 (DBusString *str,
@ -123,48 +125,56 @@ dbus_bool_t _dbus_marshal_string_array (DBusString *str,
int byte_order,
const char **value,
int len);
dbus_bool_t _dbus_marshal_dict (DBusString *str,
int byte_order,
DBusDict *dict);
double _dbus_demarshal_double (const DBusString *str,
int byte_order,
int pos,
int *new_pos);
int byte_order,
int pos,
int *new_pos);
dbus_int32_t _dbus_demarshal_int32 (const DBusString *str,
int byte_order,
int pos,
int *new_pos);
int byte_order,
int pos,
int *new_pos);
dbus_uint32_t _dbus_demarshal_uint32 (const DBusString *str,
int byte_order,
int pos,
int *new_pos);
int byte_order,
int pos,
int *new_pos);
char * _dbus_demarshal_string (const DBusString *str,
int byte_order,
int pos,
int *new_pos);
int byte_order,
int pos,
int *new_pos);
unsigned char *_dbus_demarshal_byte_array (const DBusString *str,
int byte_order,
int pos,
int *new_pos,
int *array_len);
int byte_order,
int pos,
int *new_pos,
int *array_len);
dbus_int32_t * _dbus_demarshal_int32_array (const DBusString *str,
int byte_order,
int pos,
int *new_pos,
int *array_len);
int byte_order,
int pos,
int *new_pos,
int *array_len);
dbus_uint32_t *_dbus_demarshal_uint32_array (const DBusString *str,
int byte_order,
int pos,
int *new_pos,
int *array_len);
int byte_order,
int pos,
int *new_pos,
int *array_len);
double * _dbus_demarshal_double_array (const DBusString *str,
int byte_order,
int pos,
int *new_pos,
int *array_len);
int byte_order,
int pos,
int *new_pos,
int *array_len);
char ** _dbus_demarshal_string_array (const DBusString *str,
int byte_order,
int pos,
int *new_pos,
int *array_len);
int byte_order,
int pos,
int *new_pos,
int *array_len);
DBusDict * _dbus_demarshal_dict (const DBusString *str,
int byte_order,
int pos,
int *new_pos);
dbus_bool_t _dbus_marshal_get_arg_end_pos (const DBusString *str,

View file

@ -648,6 +648,8 @@ _dbus_message_data_load (DBusString *dest,
code = DBUS_TYPE_DOUBLE;
else if (_dbus_string_starts_with_c_str (&line, "STRING"))
code = DBUS_TYPE_STRING;
else if (_dbus_string_starts_with_c_str (&line, "DICT"))
code = DBUS_TYPE_DICT;
else
{
const char *s;

View file

@ -493,15 +493,21 @@ set_string_field (DBusMessage *message,
DBusString v;
int old_len;
int new_len;
int len;
clear_header_padding (message);
old_len = _dbus_string_get_length (&message->header);
len = strlen (value);
_dbus_string_init_const_len (&v, value,
strlen (value) + 1); /* include nul */
len + 1); /* include nul */
if (!_dbus_marshal_set_string (&message->header,
message->byte_order,
offset, &v))
return FALSE;
offset, &v,
len))
goto failed;
new_len = _dbus_string_get_length (&message->header);
@ -509,7 +515,19 @@ set_string_field (DBusMessage *message,
offset,
new_len - old_len);
if (!append_header_padding (message))
goto failed;
return TRUE;
failed:
/* this must succeed because it was allocated on function entry and
* DBusString doesn't ever realloc smaller
*/
if (!append_header_padding (message))
_dbus_assert_not_reached ("failed to reappend header padding");
return FALSE;
}
}
@ -1162,7 +1180,15 @@ dbus_message_append_args_valist (DBusMessage *message,
goto enomem;
}
break;
case DBUS_TYPE_DICT:
{
DBusDict *dict;
dict = va_arg (var_args, DBusDict *);
if (!dbus_message_append_dict (message, dict))
goto enomem;
}
default:
_dbus_warn ("Unknown field type %d\n", type);
}
@ -1484,6 +1510,31 @@ dbus_message_append_string_array (DBusMessage *message,
return TRUE;
}
/**
* Appends a dict to the message.
*
* @param message the message
* @param dict the dict
* @returns #TRUE on success
*/
dbus_bool_t
dbus_message_append_dict (DBusMessage *message,
DBusDict *dict)
{
_dbus_assert (!message->locked);
if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DICT))
return FALSE;
if (!_dbus_marshal_dict (&message->body, message->byte_order, dict))
{
_dbus_string_shorten (&message->body, 1);
return FALSE;
}
return TRUE;
}
/**
* Gets arguments from a message given a variable argument list.
* The variable argument list should contain the type of the
@ -1696,6 +1747,16 @@ dbus_message_get_args_valist (DBusMessage *message,
return DBUS_RESULT_NO_MEMORY;
break;
}
case DBUS_TYPE_DICT:
{
DBusDict **dict;
dict = va_arg (var_args, DBusDict **);
if (!dbus_message_iter_get_dict (iter, dict))
return DBUS_RESULT_NO_MEMORY;
break;
}
default:
_dbus_warn ("Unknown field type %d\n", spec_type);
}
@ -1850,7 +1911,7 @@ dbus_message_iter_get_arg_type (DBusMessageIter *iter)
_dbus_string_get_const_data_len (&iter->message->body, &data, iter->pos, 1);
if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_STRING_ARRAY)
if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_DICT)
return *data;
return DBUS_TYPE_INVALID;
@ -2062,7 +2123,7 @@ dbus_message_iter_get_double_array (DBusMessageIter *iter,
* @param iter the iterator
* @param value return location for array values
* @param len return location for length of byte array
* @returns the byte array
* @returns #TRUE on success
*/
dbus_bool_t
dbus_message_iter_get_byte_array (DBusMessageIter *iter,
@ -2093,7 +2154,7 @@ dbus_message_iter_get_byte_array (DBusMessageIter *iter,
* @param iter the iterator
* @param value return location for string values
* @param len return location for length of byte array
* @returns the byte array
* @returns #TRUE on success
*/
dbus_bool_t
dbus_message_iter_get_string_array (DBusMessageIter *iter,
@ -2111,6 +2172,30 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,
return TRUE;
}
/**
* Returns the dict that the iterator may point to.
* Note that you need to check that the iterator points
* to a dict prior to using this function.
*
* @param iter the iterator
* @param dict return location for dict
* @returns #TRUE on success
*/
dbus_bool_t
dbus_message_iter_get_dict (DBusMessageIter *iter,
DBusDict **dict)
{
_dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DICT);
*dict = _dbus_demarshal_dict (&iter->message->body, iter->message->byte_order,
iter->pos + 1, NULL);
if (!*dict)
return FALSE;
else
return TRUE;
}
/**
* Sets the message sender.
*
@ -2630,9 +2715,10 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
*/
header_len = header_len_unsigned;
body_len = body_len_unsigned;
if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
{
_dbus_verbose ("header length %d is not aligned to 8 bytes\n",
header_len);
loader->corrupted = TRUE;
@ -2654,8 +2740,8 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
int next_arg;
#if 0
_dbus_verbose_bytes_of_string (&loader->data, 0, header_len);
#endif
_dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
#endif
if (!decode_header_data (&loader->data, header_len, byte_order,
fields, &header_padding))
{
@ -2899,7 +2985,7 @@ check_message_handling (DBusMessage *message)
/* If we implement message_set_arg (message, n, value)
* then we would want to test it here
*/
iter = dbus_message_get_args_iter (message);
while ((type = dbus_message_iter_get_arg_type (iter)) != DBUS_TYPE_INVALID)
{
@ -2967,7 +3053,18 @@ check_message_handling (DBusMessage *message)
dbus_free_string_array (values);
}
break;
case DBUS_TYPE_DICT:
{
DBusDict *dict;
if (!dbus_message_iter_get_dict (iter, &dict))
return FALSE;
dbus_dict_unref (dict);
}
break;
default:
break;
}
@ -3025,6 +3122,7 @@ check_have_valid_message (DBusMessageLoader *loader)
failed:
if (message)
dbus_message_unref (message);
return retval;
}

View file

@ -28,6 +28,7 @@
#define DBUS_MESSAGE_H
#include <dbus/dbus-macros.h>
#include <dbus/dbus-dict.h>
#include <dbus/dbus-types.h>
#include <stdarg.h>
@ -94,7 +95,8 @@ dbus_bool_t dbus_message_append_byte_array (DBusMessage *message,
dbus_bool_t dbus_message_append_string_array (DBusMessage *message,
const char **value,
int len);
dbus_bool_t dbus_message_append_dict (DBusMessage *message,
DBusDict *dict);
DBusMessageIter *dbus_message_get_args_iter (DBusMessage *message);
DBusResultCode dbus_message_get_args (DBusMessage *message,
@ -134,6 +136,8 @@ dbus_bool_t dbus_message_iter_get_byte_array (DBusMessageIter *iter,
dbus_bool_t dbus_message_iter_get_string_array (DBusMessageIter *iter,
char ***value,
int *len);
dbus_bool_t dbus_message_iter_get_dict (DBusMessageIter *iter,
DBusDict **dict);
DBUS_END_DECLS;

View file

@ -53,6 +53,7 @@ extern "C" {
#define DBUS_TYPE_DOUBLE_ARRAY 10
#define DBUS_TYPE_BYTE_ARRAY 11
#define DBUS_TYPE_STRING_ARRAY 12
#define DBUS_TYPE_DICT 13
/* Header flags */
#define DBUS_HEADER_FLAG_ERROR 0x1

View file

@ -29,6 +29,7 @@
#include <dbus/dbus-address.h>
#include <dbus/dbus-bus.h>
#include <dbus/dbus-connection.h>
#include <dbus/dbus-dict.h>
#include <dbus/dbus-errors.h>
#include <dbus/dbus-macros.h>
#include <dbus/dbus-message.h>

View file

@ -406,7 +406,12 @@
<entry>UINT32 giving the number of values in the array,
followed by the given number of STRING values.
</entry>
</row>
</row><row>
<entry>DICT</entry>
<entry>STRING_ARRAY with the keys, followed by the given
number of values encoded as type code as a byte followed by the encoded value.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>

View file

@ -0,0 +1,12 @@
# Message with lots of different argument types
VALID_HEADER
END_LENGTH Header
ALIGN 8
START_LENGTH Body
TYPE DICT
STRING_ARRAY { 'nil', 'uint32' }
TYPE NIL
TYPE UINT32
UINT32 0x8765432
END_LENGTH Body

View file

@ -0,0 +1,11 @@
# Message with lots of different argument types
VALID_HEADER
END_LENGTH Header
ALIGN 8
START_LENGTH Body
TYPE DICT
STRING_ARRAY { 'int32', 'uint32' }
TYPE UINT32
UINT32 0x8765432
END_LENGTH Body

View file

@ -0,0 +1,11 @@
# A simple dict
VALID_HEADER
END_LENGTH Header
ALIGN 8
START_LENGTH Body
TYPE DICT
STRING_ARRAY { 'int32' }
TYPE INT32
INT32 0x12345678
END_LENGTH Body

View file

@ -0,0 +1,29 @@
# Dict with different values
VALID_HEADER
END_LENGTH Header
ALIGN 8
START_LENGTH Body
TYPE DICT
STRING_ARRAY { 'boolean', 'int32', 'uint32', 'double', 'string', 'boolean_array', 'int32_array', 'uint32_array', 'double_array', 'string_array' }
TYPE BOOLEAN
BYTE 1
TYPE INT32
INT32 0x12345678
TYPE UINT32
UINT32 0x8765432
TYPE DOUBLE
DOUBLE 3.141592653589
TYPE STRING
STRING 'This is a string'
TYPE BOOLEAN_ARRAY
BOOLEAN_ARRAY { true, false, false, true, false }
TYPE INT32_ARRAY
INT32_ARRAY { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10 }
TYPE UINT32_ARRAY
UINT32_ARRAY { 11, 12, 314, 1911, 57692, 1237, 2834 }
TYPE DOUBLE_ARRAY
DOUBLE_ARRAY { 0.1, 0.2, 3.1415926, 2.7183, 10.0, 9.99 }
TYPE STRING_ARRAY
STRING_ARRAY { 'Hello', 'This', 'Is', 'A', 'String', 'Array!' }
END_LENGTH Body