diff options
author | Michael Meeks <michael@ximian.com> | 2004-05-28 13:10:36 +0000 |
---|---|---|
committer | Michael Meeks <michael@ximian.com> | 2004-05-28 13:10:36 +0000 |
commit | 0123e6a927772af6d56ddbe3f75a443ab40646d1 (patch) | |
tree | 1c31412a2a31d036a0051d364203f7a24ac8be0e /dbus | |
parent | f33553eae306f4864a0198c5f9c56f1059536cf3 (diff) |
2004-05-28 Michael Meeks <michael@ximian.com>
* glib/dbus-gvalue.c (dbus_gvalue_marshal, dbus_gvalue_demarshal):
fix no int64 case.
* dbus/dbus-string.c (_dbus_string_parse_basic_type): impl.
* dbus/dbus-message.c (_dbus_message_iter_get_basic_type),
(_dbus_message_iter_get_basic_type_array): impl.
drastically simplify ~all relevant _get methods to use these.
(_dbus_message_iter_append_basic_array),
(dbus_message_iter_append_basic): impl
drastically simplify ~all relevant _append methods to use these.
* dbus/dbus-message-builder.c (parse_basic_type)
(parse_basic_array, lookup_basic_type): impl.
(_dbus_message_data_load): prune scads of duplicate /
cut & paste coding.
* dbus/dbus-marshal.c (_dbus_demarshal_basic_type_array)
(_dbus_demarshal_basic_type): implement,
(demarshal_and_validate_len/arg): beef up debug.
(_dbus_marshal_basic_type, _dbus_marshal_basic_type_array): impl.
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-marshal.c | 202 | ||||
-rw-r--r-- | dbus/dbus-marshal.h | 22 | ||||
-rw-r--r-- | dbus/dbus-message-builder.c | 710 | ||||
-rw-r--r-- | dbus/dbus-message.c | 1351 | ||||
-rw-r--r-- | dbus/dbus-string.c | 107 | ||||
-rw-r--r-- | dbus/dbus-string.h | 5 |
6 files changed, 1049 insertions, 1348 deletions
diff --git a/dbus/dbus-marshal.c b/dbus/dbus-marshal.c index 7524452b..9856930f 100644 --- a/dbus/dbus-marshal.c +++ b/dbus/dbus-marshal.c @@ -1068,6 +1068,61 @@ _dbus_demarshal_uint64 (const DBusString *str, #endif /* DBUS_HAVE_INT64 */ /** + * Demarshals a basic type + * + * @param str the string containing the data + * @param type type of value to demarshal + * @param value pointer to return value data + * @param byte_order the byte order + * @param pos pointer to position in the string, + * updated on return to new position + **/ +void +_dbus_demarshal_basic_type (const DBusString *str, + int type, + void *value, + int byte_order, + int *pos) +{ + const char *str_data = _dbus_string_get_const_data (str); + + switch (type) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + *(unsigned char *) value = _dbus_string_get_byte (str, *pos); + (*pos)++; + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + *pos = _DBUS_ALIGN_VALUE (*pos, 4); + *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos); + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value); + *pos += 4; + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + *pos = _DBUS_ALIGN_VALUE (*pos, 8); + memcpy (value, str_data + *pos, 8); + if (byte_order != DBUS_COMPILER_BYTE_ORDER) +#ifdef DBUS_HAVE_INT64 + *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value); +#else + swap_bytes (value, 8); +#endif + *pos += 8; + break; + default: + _dbus_assert_not_reached ("not a basic type"); + break; + } +} + +/** * Demarshals an UTF-8 string. * * @todo Should we check the string to make sure @@ -1392,6 +1447,53 @@ _dbus_demarshal_double_array (const DBusString *str, (DBusOctets8**) array, array_len); } + +/** + * Demarshals an array of basic types + * + * @param str the string containing the data + * @param element_type type of array elements to demarshal + * @param array pointer to pointer to array data + * @param array_len pointer to array length + * @param byte_order the byte order + * @param pos pointer to position in the string, + * updated on return to new position + **/ +dbus_bool_t +_dbus_demarshal_basic_type_array (const DBusString *str, + int element_type, + void **array, + int *array_len, + int byte_order, + int *pos) +{ + switch (element_type) + { + case DBUS_TYPE_BOOLEAN: + /* FIXME: do we want to post-normalize these ? */ + case DBUS_TYPE_BYTE: + return _dbus_demarshal_byte_array (str, byte_order, *pos, pos, + (unsigned char **)array, array_len); + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + return demarshal_4_octets_array (str, byte_order, *pos, pos, + (dbus_uint32_t *) array, array_len); + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + return demarshal_8_octets_array (str, byte_order, *pos, pos, + (DBusOctets8**) array, array_len); + default: + _dbus_assert_not_reached ("not a basic type"); + break; + } + return FALSE; +} + /** * Demarshals a string array. * @@ -1725,7 +1827,7 @@ demarshal_and_validate_len (const DBusString *str, if (!_dbus_string_validate_nul (str, pos, align_4 - pos)) { - _dbus_verbose ("array length alignment padding not initialized to nul\n"); + _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos); return -1; } @@ -1740,8 +1842,8 @@ demarshal_and_validate_len (const DBusString *str, #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32) if (len > MAX_ARRAY_LENGTH) { - _dbus_verbose ("array length %u exceeds maximum of %u\n", - len, MAX_ARRAY_LENGTH); + _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n", + len, MAX_ARRAY_LENGTH, pos); return -1; } else @@ -2021,7 +2123,7 @@ _dbus_marshal_validate_arg (const DBusString *str, if (!_dbus_string_validate_nul (str, pos, align_8 - pos)) { - _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n"); + _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos); return FALSE; } @@ -2191,7 +2293,10 @@ _dbus_marshal_validate_arg (const DBusString *str, /* Validate element */ if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, dict_type, -1, pos, &pos)) - return FALSE; + { + _dbus_verbose ("dict arg invalid at offset %d\n", pos); + return FALSE; + } } if (pos > end) @@ -2356,6 +2461,93 @@ _dbus_verbose_bytes_of_string (const DBusString *str, _dbus_verbose_bytes (d, len); } +/** + * Marshals a basic type + * + * @param str string to marshal to + * @param type type of value + * @param value pointer to value + * @param byte_order byte order + * @returns #TRUE on success + **/ +dbus_bool_t +_dbus_marshal_basic_type (DBusString *str, + char type, + void *value, + int byte_order) +{ + dbus_bool_t retval; + + switch (type) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + retval = _dbus_string_append_byte (str, *(unsigned char *)value); + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + return marshal_4_octets (str, byte_order, *(dbus_uint32_t *)value); + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + retval = _dbus_marshal_uint64 (str, byte_order, *(dbus_uint64_t *)value); + break; +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + retval = _dbus_marshal_double (str, byte_order, *(double *)value); + break; + default: + _dbus_assert_not_reached ("not a basic type"); + retval = FALSE; + break; + } + return retval; +} + +/** + * Marshals a basic type array + * + * @param str string to marshal to + * @param element_type type of array elements + * @param value pointer to value + * @param len length of value data in elements + * @param byte_order byte order + * @returns #TRUE on success + **/ +dbus_bool_t +_dbus_marshal_basic_type_array (DBusString *str, + char element_type, + const void *value, + int len, + int byte_order) +{ + switch (element_type) + { + case DBUS_TYPE_BOOLEAN: + /* FIXME: we canonicalize to 0 or 1 for the single boolean case + * should we here too ? */ + case DBUS_TYPE_BYTE: + return _dbus_marshal_byte_array (str, byte_order, value, len); + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + return marshal_4_octets_array (str, byte_order, value, len); + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + return marshal_8_octets_array (str, byte_order, value, len); + break; + default: + _dbus_assert_not_reached ("non basic type in array"); + break; + } + return FALSE; +} + /** @} */ #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-marshal.h b/dbus/dbus-marshal.h index b1b8e2c9..1c34c531 100644 --- a/dbus/dbus-marshal.h +++ b/dbus/dbus-marshal.h @@ -184,6 +184,10 @@ dbus_bool_t _dbus_marshal_double (DBusString *str, dbus_bool_t _dbus_marshal_string (DBusString *str, int byte_order, const char *value); +dbus_bool_t _dbus_marshal_basic_type (DBusString *str, + char type, + void *value, + int byte_order); dbus_bool_t _dbus_marshal_byte_array (DBusString *str, int byte_order, const unsigned char *value, @@ -210,6 +214,12 @@ dbus_bool_t _dbus_marshal_double_array (DBusString *str, int byte_order, const double *value, int len); +dbus_bool_t _dbus_marshal_basic_type_array (DBusString *str, + char element_type, + const void *value, + int len, + int byte_order); + dbus_bool_t _dbus_marshal_string_array (DBusString *str, int byte_order, const char **value, @@ -241,6 +251,11 @@ dbus_uint64_t _dbus_demarshal_uint64 (const DBusString *str, int pos, int *new_pos); #endif /* DBUS_HAVE_INT64 */ +void _dbus_demarshal_basic_type (const DBusString *str, + int type, + void *value, + int byte_order, + int *pos); char * _dbus_demarshal_string (const DBusString *str, int byte_order, int pos, @@ -283,6 +298,13 @@ dbus_bool_t _dbus_demarshal_double_array (const DBusString *str, int *new_pos, double **array, int *array_len); +dbus_bool_t _dbus_demarshal_basic_type_array (const DBusString *str, + int type, + void **array, + int *array_len, + int byte_order, + int *pos); + dbus_bool_t _dbus_demarshal_string_array (const DBusString *str, int byte_order, int pos, diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index 00941e9c..2ff13b21 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -335,6 +335,193 @@ append_string_field (DBusString *dest, return TRUE; } +static dbus_bool_t +parse_basic_type (DBusString *src, char type, + DBusString *dest, dbus_bool_t *unalign, + int endian) +{ + int align; + int align_pad_start, align_pad_end; + unsigned char data[16]; + + switch (type) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + align = 1; + break; + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT32: + align = 4; + break; + case DBUS_TYPE_DOUBLE: + align = 8; + break; + default: + _dbus_assert_not_reached ("not a basic type"); + break; + } + + align_pad_start = _dbus_string_get_length (dest); + align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, align); + + _dbus_string_delete_first_word (src); + + if (!_dbus_string_parse_basic_type (src, type, 0, data, NULL)) + { + _dbus_verbose ("failed to parse type '%c'", type); + return FALSE; + } + + if (!_dbus_marshal_basic_type (dest, type, data, endian)) + { + _dbus_verbose ("failed to marshal type '%c'", type); + return FALSE; + } + + if (*unalign) + { + _dbus_string_delete (dest, align_pad_start, + align_pad_end - align_pad_start); + *unalign = FALSE; + } + + return TRUE; +} + +static dbus_bool_t +parse_basic_array (DBusString *src, char type, + DBusString *dest, dbus_bool_t *unalign, + int endian) +{ + int array_align, elem_size; + int i, len, allocated; + unsigned char *values, b; + int values_offset; + int align_pad_start, align_pad_end; + dbus_bool_t retval = FALSE; + + array_align = 4; /* length */ + switch (type) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + elem_size = 1; + break; + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT32: + elem_size = 4; + break; + case DBUS_TYPE_DOUBLE: + array_align = 8; + elem_size = 8; + break; + default: + _dbus_assert_not_reached ("not a basic type"); + break; + } + + align_pad_start = _dbus_string_get_length (dest); + align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, array_align); + + len = 0; + allocated = 2; + values = NULL; + values_offset = 0; + + _dbus_string_delete_first_word (src); + _dbus_string_skip_blank (src, 0, &i); + b = _dbus_string_get_byte (src, i++); + + if (b != '{') + goto failed; + + while (i < _dbus_string_get_length (src)) + { + _dbus_string_skip_blank (src, i, &i); + + if (!values || len == allocated - 1) + { + allocated *= 2; + values = dbus_realloc (values, allocated * elem_size); + if (!values) + { + _dbus_warn ("could not allocate memory for '%c' ARRAY\n", type); + goto failed; + } + } + + if (!_dbus_string_parse_basic_type (src, type, i, values + values_offset, &i)) + { + _dbus_warn ("could not parse integer element %d of '%c' ARRAY\n", len, type); + goto failed; + } + + values_offset += elem_size; + len++; + + _dbus_string_skip_blank (src, i, &i); + + b = _dbus_string_get_byte (src, i++); + + if (b == '}') + break; + else if (b != ',') + goto failed; + } + + if (!_dbus_marshal_basic_type_array (dest, type, values, len, endian)) + { + _dbus_warn ("failed to append '%c' ARRAY\n", type); + goto failed; + } + + if (*unalign) + { + _dbus_string_delete (dest, align_pad_start, + align_pad_end - align_pad_start); + *unalign = FALSE; + } + + retval = TRUE; + + failed: + dbus_free (values); + return retval; +} + +static char +lookup_basic_type (const DBusString *str, dbus_bool_t *is_array) +{ + int i; + char type = DBUS_TYPE_INVALID; + static struct { + const char *name; + char type; + } name_to_type[] = { + { "BYTE", DBUS_TYPE_BYTE }, + { "BOOLEAN", DBUS_TYPE_BOOLEAN }, + { "INT32", DBUS_TYPE_INT32 }, + { "UINT32", DBUS_TYPE_UINT32 }, + { "DOUBLE", DBUS_TYPE_DOUBLE } + }; + + for (i = 0; i < _DBUS_N_ELEMENTS(name_to_type); i++) + { + const char *name = name_to_type[i].name; + if (_dbus_string_starts_with_c_str (str, name)) + { + int offset = strlen (name); + type = name_to_type[i].type; + if (is_array) + *is_array = _dbus_string_find (str, offset, "_ARRAY", NULL); + break; + } + } + + return type; +} + /** * Reads the given filename, which should be in "message description * language" (look at some examples), and builds up the message data @@ -399,6 +586,8 @@ _dbus_message_data_load (DBusString *dest, DBusHashTable *length_hash; int endian; DBusHashIter iter; + char type; + dbus_bool_t is_array; retval = FALSE; length_hash = NULL; @@ -510,7 +699,7 @@ _dbus_message_data_load (DBusString *dest, goto parse_failed; /* client serial */ - if (!_dbus_marshal_int32 (dest, endian, 1)) + if (!_dbus_marshal_uint32 (dest, endian, 1)) { _dbus_warn ("couldn't append client serial\n"); goto parse_failed; @@ -721,16 +910,8 @@ _dbus_message_data_load (DBusString *dest, code = DBUS_TYPE_INVALID; else if (_dbus_string_starts_with_c_str (&line, "NIL")) code = DBUS_TYPE_NIL; - else if (_dbus_string_starts_with_c_str (&line, "BYTE")) - code = DBUS_TYPE_BYTE; - else if (_dbus_string_starts_with_c_str (&line, "BOOLEAN")) - code = DBUS_TYPE_BOOLEAN; - else if (_dbus_string_starts_with_c_str (&line, "INT32")) - code = DBUS_TYPE_INT32; - else if (_dbus_string_starts_with_c_str (&line, "UINT32")) - code = DBUS_TYPE_UINT32; - else if (_dbus_string_starts_with_c_str (&line, "DOUBLE")) - code = DBUS_TYPE_DOUBLE; + else if ((code = lookup_basic_type (&line, NULL)) != DBUS_TYPE_INVALID) + ; else if (_dbus_string_starts_with_c_str (&line, "STRING")) code = DBUS_TYPE_STRING; else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH")) @@ -754,380 +935,6 @@ _dbus_message_data_load (DBusString *dest, } } else if (_dbus_string_starts_with_c_str (&line, - "BYTE_ARRAY")) - { - SAVE_FOR_UNALIGN (dest, 4); - int i, len, allocated; - unsigned char *values; - unsigned char b; - long val; - - allocated = 4; - values = dbus_new (unsigned char, allocated); - if (!values) - { - _dbus_warn ("could not allocate memory for BYTE_ARRAY\n"); - goto parse_failed; - } - - len = 0; - - _dbus_string_delete_first_word (&line); - _dbus_string_skip_blank (&line, 0, &i); - b = _dbus_string_get_byte (&line, i++); - - if (b != '{') - goto parse_failed; - - while (i < _dbus_string_get_length (&line)) - { - _dbus_string_skip_blank (&line, i, &i); - - if (_dbus_string_get_byte (&line, i) == '\'' && - _dbus_string_get_length (&line) >= i + 4 && - _dbus_string_get_byte (&line, i + 1) == '\\' && - _dbus_string_get_byte (&line, i + 2) == '\'' && - _dbus_string_get_byte (&line, i + 3) == '\'') - { - val = '\''; - i += 4; - } - else if (_dbus_string_get_byte (&line, i) == '\'' && - _dbus_string_get_length (&line) >= i + 3 && - _dbus_string_get_byte (&line, i + 2) == '\'') - { - val = _dbus_string_get_byte (&line, i + 1); - i += 3; - } - else - { - if (!_dbus_string_parse_int (&line, i, &val, &i)) - { - _dbus_warn ("Failed to parse integer for BYTE_ARRAY\n"); - goto parse_failed; - } - - if (val < 0 || val > 255) - { - _dbus_warn ("A byte must be in range 0-255 not %ld\n", - val); - goto parse_failed; - } - } - - values[len++] = val; - if (len == allocated) - { - allocated *= 2; - values = dbus_realloc (values, allocated * sizeof (unsigned char)); - if (!values) - { - _dbus_warn ("could not allocate memory for BYTE_ARRAY\n"); - goto parse_failed; - } - } - - _dbus_string_skip_blank (&line, i, &i); - - b = _dbus_string_get_byte (&line, i++); - - if (b == '}') - break; - else if (b != ',') - goto parse_failed; - } - - if (!_dbus_marshal_int32 (dest, endian, len) || - !_dbus_string_append_len (dest, values, len)) - { - _dbus_warn ("failed to append BYTE_ARRAY\n"); - goto parse_failed; - } - dbus_free (values); - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "BOOLEAN_ARRAY")) - { - SAVE_FOR_UNALIGN (dest, 4); - int i, len, allocated; - unsigned char *values; - unsigned char b, val; - - allocated = 4; - values = dbus_new (unsigned char, allocated); - if (!values) - { - _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n"); - goto parse_failed; - } - - len = 0; - - _dbus_string_delete_first_word (&line); - _dbus_string_skip_blank (&line, 0, &i); - b = _dbus_string_get_byte (&line, i++); - - if (b != '{') - goto parse_failed; - - while (i < _dbus_string_get_length (&line)) - { - _dbus_string_skip_blank (&line, i, &i); - - if (_dbus_string_find_to (&line, i, i + 5, - "false", NULL)) - { - i += 5; - val = TRUE; - } - else if (_dbus_string_find_to (&line, i, i + 4, - "true", NULL)) - { - i += 4; - val = FALSE; - } - else - { - _dbus_warn ("could not parse BOOLEAN_ARRAY\n"); - goto parse_failed; - } - - values[len++] = val; - if (len == allocated) - { - allocated *= 2; - values = dbus_realloc (values, allocated * sizeof (unsigned char)); - if (!values) - { - _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n"); - goto parse_failed; - } - } - - _dbus_string_skip_blank (&line, i, &i); - - b = _dbus_string_get_byte (&line, i++); - - if (b == '}') - break; - else if (b != ',') - goto parse_failed; - } - - if (!_dbus_marshal_int32 (dest, endian, len) || - !_dbus_string_append_len (dest, values, len)) - { - _dbus_warn ("failed to append BOOLEAN_ARRAY\n"); - goto parse_failed; - } - dbus_free (values); - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "INT32_ARRAY")) - { - SAVE_FOR_UNALIGN (dest, 4); - int i, len, allocated; - dbus_int32_t *values; - long val; - unsigned char b; - - allocated = 4; - values = dbus_new (dbus_int32_t, allocated); - if (!values) - { - _dbus_warn ("could not allocate memory for INT32_ARRAY\n"); - goto parse_failed; - } - - len = 0; - - _dbus_string_delete_first_word (&line); - _dbus_string_skip_blank (&line, 0, &i); - b = _dbus_string_get_byte (&line, i++); - - if (b != '{') - goto parse_failed; - - while (i < _dbus_string_get_length (&line)) - { - _dbus_string_skip_blank (&line, i, &i); - - if (!_dbus_string_parse_int (&line, i, &val, &i)) - { - _dbus_warn ("could not parse integer for INT32_ARRAY\n"); - goto parse_failed; - } - - values[len++] = val; - if (len == allocated) - { - allocated *= 2; - values = dbus_realloc (values, allocated * sizeof (dbus_int32_t)); - if (!values) - { - _dbus_warn ("could not allocate memory for INT32_ARRAY\n"); - goto parse_failed; - } - } - - _dbus_string_skip_blank (&line, i, &i); - - b = _dbus_string_get_byte (&line, i++); - - if (b == '}') - break; - else if (b != ',') - goto parse_failed; - } - - if (!_dbus_marshal_int32_array (dest, endian, values, len)) - { - _dbus_warn ("failed to append INT32_ARRAY\n"); - goto parse_failed; - } - dbus_free (values); - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "UINT32_ARRAY")) - { - SAVE_FOR_UNALIGN (dest, 4); - int i, len, allocated; - dbus_uint32_t *values; - long val; - unsigned char b; - - allocated = 4; - values = dbus_new (dbus_uint32_t, allocated); - if (!values) - { - _dbus_warn ("could not allocate memory for UINT32_ARRAY\n"); - goto parse_failed; - } - - len = 0; - - _dbus_string_delete_first_word (&line); - _dbus_string_skip_blank (&line, 0, &i); - b = _dbus_string_get_byte (&line, i++); - - if (b != '{') - goto parse_failed; - - while (i < _dbus_string_get_length (&line)) - { - _dbus_string_skip_blank (&line, i, &i); - - if (!_dbus_string_parse_int (&line, i, &val, &i)) - { - _dbus_warn ("could not parse integer for UINT32_ARRAY\n"); - goto parse_failed; - } - - values[len++] = val; - if (len == allocated) - { - allocated *= 2; - values = dbus_realloc (values, allocated * sizeof (dbus_uint32_t)); - if (!values) - { - _dbus_warn ("could not allocate memory for UINT32_ARRAY\n"); - goto parse_failed; - } - } - - _dbus_string_skip_blank (&line, i, &i); - - b = _dbus_string_get_byte (&line, i++); - - if (b == '}') - break; - else if (b != ',') - goto parse_failed; - } - - if (!_dbus_marshal_uint32_array (dest, endian, values, len)) - { - _dbus_warn ("failed to append UINT32_ARRAY\n"); - goto parse_failed; - } - dbus_free (values); - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "DOUBLE_ARRAY")) - { - SAVE_FOR_UNALIGN (dest, 8); - int i, len, allocated; - double *values; - double val; - unsigned char b; - - allocated = 4; - values = dbus_new (double, allocated); - if (!values) - { - _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n"); - goto parse_failed; - } - - len = 0; - - _dbus_string_delete_first_word (&line); - _dbus_string_skip_blank (&line, 0, &i); - b = _dbus_string_get_byte (&line, i++); - - if (b != '{') - goto parse_failed; - - while (i < _dbus_string_get_length (&line)) - { - _dbus_string_skip_blank (&line, i, &i); - - if (!_dbus_string_parse_double (&line, i, &val, &i)) - { - _dbus_warn ("could not parse double for DOUBLE_ARRAY\n"); - goto parse_failed; - } - - values[len++] = val; - if (len == allocated) - { - allocated *= 2; - values = dbus_realloc (values, allocated * sizeof (double)); - if (!values) - { - _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n"); - goto parse_failed; - } - } - - _dbus_string_skip_blank (&line, i, &i); - - b = _dbus_string_get_byte (&line, i++); - - if (b == '}') - break; - else if (b != ',') - goto parse_failed; - } - - if (!_dbus_marshal_double_array (dest, endian, values, len)) - { - _dbus_warn ("failed to append DOUBLE_ARRAY\n"); - goto parse_failed; - } - dbus_free (values); - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, "STRING_ARRAY")) { SAVE_FOR_UNALIGN (dest, 4); @@ -1209,124 +1016,6 @@ _dbus_message_data_load (DBusString *dest, PERFORM_UNALIGN (dest); } - else if (_dbus_string_starts_with_c_str (&line, "BYTE")) - { - unsigned char the_byte; - - _dbus_string_delete_first_word (&line); - - if (_dbus_string_equal_c_str (&line, "'\\''")) - the_byte = '\''; - else if (_dbus_string_get_byte (&line, 0) == '\'' && - _dbus_string_get_length (&line) >= 3 && - _dbus_string_get_byte (&line, 2) == '\'') - the_byte = _dbus_string_get_byte (&line, 1); - else - { - long val; - if (!_dbus_string_parse_int (&line, 0, &val, NULL)) - { - _dbus_warn ("Failed to parse integer for BYTE\n"); - goto parse_failed; - } - - if (val > 255) - { - _dbus_warn ("A byte must be in range 0-255 not %ld\n", - val); - goto parse_failed; - } - the_byte = (unsigned char) val; - } - - _dbus_string_append_byte (dest, the_byte); - } - else if (_dbus_string_starts_with_c_str (&line, - "BOOLEAN")) - { - unsigned char val; - - _dbus_string_delete_first_word (&line); - - if (_dbus_string_starts_with_c_str (&line, "true")) - val = TRUE; - else if (_dbus_string_starts_with_c_str (&line, "false")) - val = FALSE; - else - { - _dbus_warn ("could not parse BOOLEAN\n"); - goto parse_failed; - } - if (!_dbus_string_append_byte (dest, val)) - { - _dbus_warn ("failed to append BOOLEAN\n"); - goto parse_failed; - } - } - - else if (_dbus_string_starts_with_c_str (&line, - "INT32")) - { - SAVE_FOR_UNALIGN (dest, 4); - long val; - - _dbus_string_delete_first_word (&line); - - if (!_dbus_string_parse_int (&line, 0, &val, NULL)) - { - _dbus_warn ("could not parse integer for INT32\n"); - goto parse_failed; - } - - if (!_dbus_marshal_int32 (dest, endian, - val)) - { - _dbus_warn ("failed to append INT32\n"); - goto parse_failed; - } - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "UINT32")) - { - SAVE_FOR_UNALIGN (dest, 4); - unsigned long val; - - _dbus_string_delete_first_word (&line); - - if (!_dbus_string_parse_uint (&line, 0, &val, NULL)) - goto parse_failed; - - if (!_dbus_marshal_uint32 (dest, endian, - val)) - { - _dbus_warn ("failed to append UINT32\n"); - goto parse_failed; - } - - PERFORM_UNALIGN (dest); - } - else if (_dbus_string_starts_with_c_str (&line, - "DOUBLE")) - { - SAVE_FOR_UNALIGN (dest, 8); - double val; - - _dbus_string_delete_first_word (&line); - - if (!_dbus_string_parse_double (&line, 0, &val, NULL)) - goto parse_failed; - - if (!_dbus_marshal_double (dest, endian, - val)) - { - _dbus_warn ("failed to append DOUBLE\n"); - goto parse_failed; - } - - PERFORM_UNALIGN (dest); - } else if (_dbus_string_starts_with_c_str (&line, "STRING")) { @@ -1357,8 +1046,21 @@ _dbus_message_data_load (DBusString *dest, PERFORM_UNALIGN (dest); } + else if ((type = lookup_basic_type (&line, &is_array)) != DBUS_TYPE_INVALID) + { + if (is_array) + { + if (!parse_basic_array (&line, type, dest, &unalign, endian)) + goto parse_failed; + } + else + { + if (!parse_basic_type (&line, type, dest, &unalign, endian)) + goto parse_failed; + } + } else if (_dbus_string_starts_with_c_str (&line, - "OBJECT_PATH")) + "OBJECT_PATH")) { SAVE_FOR_UNALIGN (dest, 4); int size_offset; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 98c0d1d1..9fa19668 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -1884,175 +1884,6 @@ dbus_message_append_args (DBusMessage *message, } /** - * This function takes a va_list for use by language bindings. - * It's otherwise the same as dbus_message_append_args(). - * - * @todo: Shouldn't this function clean up the changes to the message - * on failures? (Yes) - - * @see dbus_message_append_args. - * @param message the message - * @param first_arg_type type of first argument - * @param var_args value of first argument, then list of type/value pairs - * @returns #TRUE on success - */ -dbus_bool_t -dbus_message_append_args_valist (DBusMessage *message, - int first_arg_type, - va_list var_args) -{ - int type, old_len; - DBusMessageIter iter; - - _dbus_return_val_if_fail (message != NULL, FALSE); - - old_len = _dbus_string_get_length (&message->body); - - type = first_arg_type; - - dbus_message_append_iter_init (message, &iter); - - while (type != DBUS_TYPE_INVALID) - { - switch (type) - { - case DBUS_TYPE_NIL: - if (!dbus_message_iter_append_nil (&iter)) - goto errorout; - break; - case DBUS_TYPE_BYTE: - if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, unsigned char))) - goto errorout; - break; - case DBUS_TYPE_BOOLEAN: - if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t))) - goto errorout; - break; - case DBUS_TYPE_INT32: - if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t))) - goto errorout; - break; - case DBUS_TYPE_UINT32: - if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t))) - goto errorout; - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t))) - goto errorout; - break; - case DBUS_TYPE_UINT64: - if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t))) - goto errorout; - break; -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double))) - goto errorout; - break; - case DBUS_TYPE_STRING: - if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *))) - goto errorout; - break; - case DBUS_TYPE_OBJECT_PATH: - if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*))) - goto errorout; - break; - case DBUS_TYPE_CUSTOM: - { - const char *name; - unsigned char *data; - int len; - - name = va_arg (var_args, const char *); - data = va_arg (var_args, unsigned char *); - len = va_arg (var_args, int); - - if (!dbus_message_iter_append_custom (&iter, name, data, len)) - goto errorout; - break; - } - case DBUS_TYPE_ARRAY: - { - void *data; - int len, type; - - type = va_arg (var_args, int); - data = va_arg (var_args, void *); - len = va_arg (var_args, int); - - switch (type) - { - case DBUS_TYPE_BYTE: - if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len)) - goto errorout; - break; - case DBUS_TYPE_BOOLEAN: - if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len)) - goto errorout; - break; - case DBUS_TYPE_INT32: - if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len)) - goto errorout; - break; - case DBUS_TYPE_UINT32: - if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len)) - goto errorout; - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len)) - goto errorout; - break; - case DBUS_TYPE_UINT64: - if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len)) - goto errorout; - break; -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - if (!dbus_message_iter_append_double_array (&iter, (double *)data, len)) - goto errorout; - break; - case DBUS_TYPE_STRING: - if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len)) - goto errorout; - break; - case DBUS_TYPE_OBJECT_PATH: - if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len)) - goto errorout; - break; - case DBUS_TYPE_NIL: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_CUSTOM: - case DBUS_TYPE_DICT: - _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n"); - goto errorout; - default: - _dbus_warn ("Unknown field type %d\n", type); - goto errorout; - } - } - break; - - case DBUS_TYPE_DICT: - _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n"); - goto errorout; - default: - _dbus_warn ("Unknown field type %d\n", type); - goto errorout; - } - - type = va_arg (var_args, int); - } - - return TRUE; - - errorout: - return FALSE; -} - - -/** * Gets arguments from a message given a variable argument list. * The variable argument list should contain the type of the * argumen followed by a pointer to where the value should be @@ -2142,264 +1973,6 @@ dbus_message_iter_get_args (DBusMessageIter *iter, } /** - * This function takes a va_list for use by language bindings - * - * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64 - * only if #DBUS_HAVE_INT64 is defined. - * - * @todo this function (or some lower-level non-convenience function) - * needs better error handling; should allow the application to - * distinguish between out of memory, and bad data from the remote - * app. It also needs to not leak a bunch of args when it gets - * to the arg that's bad, as that would be a security hole - * (allow one app to force another to leak memory) - * - * @todo We need to free the argument data when an error occurs. - * - * @see dbus_message_get_args - * @param iter the message iter - * @param error error to be filled in - * @param first_arg_type type of the first argument - * @param var_args return location for first argument, followed by list of type/location pairs - * @returns #FALSE if error was set - */ -dbus_bool_t -dbus_message_iter_get_args_valist (DBusMessageIter *iter, - DBusError *error, - int first_arg_type, - va_list var_args) -{ - int spec_type, msg_type, i; - dbus_bool_t retval; - - _dbus_return_val_if_fail (iter != NULL, FALSE); - _dbus_return_val_if_error_is_set (error, FALSE); - - retval = FALSE; - - spec_type = first_arg_type; - i = 0; - - while (spec_type != DBUS_TYPE_INVALID) - { - msg_type = dbus_message_iter_get_arg_type (iter); - - if (msg_type != spec_type) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Argument %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)); - - goto out; - } - - switch (spec_type) - { - case DBUS_TYPE_NIL: - break; - case DBUS_TYPE_BYTE: - { - unsigned char *ptr; - - ptr = va_arg (var_args, unsigned char *); - - *ptr = dbus_message_iter_get_byte (iter); - break; - } - case DBUS_TYPE_BOOLEAN: - { - dbus_bool_t *ptr; - - ptr = va_arg (var_args, dbus_bool_t *); - - *ptr = dbus_message_iter_get_boolean (iter); - break; - } - 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; - } -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - { - dbus_int64_t *ptr; - - ptr = va_arg (var_args, dbus_int64_t *); - - *ptr = dbus_message_iter_get_int64 (iter); - break; - } - case DBUS_TYPE_UINT64: - { - dbus_uint64_t *ptr; - - ptr = va_arg (var_args, dbus_uint64_t *); - - *ptr = dbus_message_iter_get_uint64 (iter); - break; - } -#endif /* DBUS_HAVE_INT64 */ - - 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); - - if (!*ptr) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto out; - } - - break; - } - - case DBUS_TYPE_CUSTOM: - { - char **name; - unsigned char **data; - int *len; - - name = va_arg (var_args, char **); - data = va_arg (var_args, unsigned char **); - len = va_arg (var_args, int *); - - if (!dbus_message_iter_get_custom (iter, name, data, len)) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto out; - } - } - break; - case DBUS_TYPE_ARRAY: - { - void **data; - int *len, type; - dbus_bool_t err = FALSE; - - type = va_arg (var_args, int); - data = va_arg (var_args, void *); - len = va_arg (var_args, int *); - - _dbus_return_val_if_fail (data != NULL, FALSE); - _dbus_return_val_if_fail (len != NULL, FALSE); - - if (dbus_message_iter_get_array_type (iter) != type) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Argument %d is specified to be of type \"array of %s\", but " - "is actually of type \"array of %s\"\n", i, - _dbus_type_to_string (type), - _dbus_type_to_string (dbus_message_iter_get_array_type (iter))); - goto out; - } - - switch (type) - { - case DBUS_TYPE_BYTE: - err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len); - break; - case DBUS_TYPE_BOOLEAN: - err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len); - break; - case DBUS_TYPE_INT32: - err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len); - break; - case DBUS_TYPE_UINT32: - err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len); - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len); - break; - case DBUS_TYPE_UINT64: - err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len); - break; -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - err = !dbus_message_iter_get_double_array (iter, (double **)data, len); - break; - case DBUS_TYPE_STRING: - err = !dbus_message_iter_get_string_array (iter, (char ***)data, len); - break; - case DBUS_TYPE_NIL: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_CUSTOM: - case DBUS_TYPE_DICT: - _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n"); - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); - goto out; - default: - _dbus_warn ("Unknown field type %d\n", type); - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); - goto out; - } - if (err) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto out; - } - } - break; - case DBUS_TYPE_DICT: - _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n"); - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); - goto out; - default: - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); - _dbus_warn ("Unknown field type %d\n", spec_type); - goto out; - } - - spec_type = va_arg (var_args, int); - if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Message has only %d arguments, but more were expected", i); - goto out; - } - - i++; - } - - retval = TRUE; - - out: - - return retval; -} - - -/** * Initializes a DBusMessageIter representing the arguments of the * message passed in. * @@ -2788,6 +2361,240 @@ dbus_message_iter_get_custom (DBusMessageIter *iter, return TRUE; } +static void +_dbus_message_iter_get_basic_type (DBusMessageIter *iter, + char type, + void *value) +{ + DBusMessageRealIter *real = (DBusMessageRealIter *)iter; + int item_type, pos; + + _dbus_return_if_fail (dbus_message_iter_check (real)); + + pos = dbus_message_iter_get_data_start (real, &item_type); + + _dbus_assert (type == item_type); + + _dbus_demarshal_basic_type (&real->message->body, + type, value, + real->message->byte_order, + &pos); +} + + +/** + * This function takes a va_list for use by language bindings + * + * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64 + * only if #DBUS_HAVE_INT64 is defined. + * + * @todo this function (or some lower-level non-convenience function) + * needs better error handling; should allow the application to + * distinguish between out of memory, and bad data from the remote + * app. It also needs to not leak a bunch of args when it gets + * to the arg that's bad, as that would be a security hole + * (allow one app to force another to leak memory) + * + * @todo We need to free the argument data when an error occurs. + * + * @see dbus_message_get_args + * @param iter the message iter + * @param error error to be filled in + * @param first_arg_type type of the first argument + * @param var_args return location for first argument, followed by list of type/location pairs + * @returns #FALSE if error was set + */ +dbus_bool_t +dbus_message_iter_get_args_valist (DBusMessageIter *iter, + DBusError *error, + int first_arg_type, + va_list var_args) +{ + int spec_type, msg_type, i; + dbus_bool_t retval; + + _dbus_return_val_if_fail (iter != NULL, FALSE); + _dbus_return_val_if_error_is_set (error, FALSE); + + retval = FALSE; + + spec_type = first_arg_type; + i = 0; + + while (spec_type != DBUS_TYPE_INVALID) + { + msg_type = dbus_message_iter_get_arg_type (iter); + + if (msg_type != spec_type) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Argument %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)); + + goto out; + } + + switch (spec_type) + { + case DBUS_TYPE_NIL: + break; + case DBUS_TYPE_BOOLEAN: + { + dbus_bool_t *ptr; + + ptr = va_arg (var_args, dbus_bool_t *); + + *ptr = dbus_message_iter_get_boolean (iter); + break; + } + case DBUS_TYPE_BYTE: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + { + void *ptr = va_arg (var_args, void *); + _dbus_message_iter_get_basic_type (iter, spec_type, ptr); + break; + } + + case DBUS_TYPE_STRING: + { + char **ptr; + + ptr = va_arg (var_args, char **); + + *ptr = dbus_message_iter_get_string (iter); + + if (!*ptr) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto out; + } + + break; + } + + case DBUS_TYPE_CUSTOM: + { + char **name; + unsigned char **data; + int *len; + + name = va_arg (var_args, char **); + data = va_arg (var_args, unsigned char **); + len = va_arg (var_args, int *); + + if (!dbus_message_iter_get_custom (iter, name, data, len)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto out; + } + } + break; + case DBUS_TYPE_ARRAY: + { + void **data; + int *len, type; + dbus_bool_t err = FALSE; + + type = va_arg (var_args, int); + data = va_arg (var_args, void *); + len = va_arg (var_args, int *); + + _dbus_return_val_if_fail (data != NULL, FALSE); + _dbus_return_val_if_fail (len != NULL, FALSE); + + if (dbus_message_iter_get_array_type (iter) != type) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Argument %d is specified to be of type \"array of %s\", but " + "is actually of type \"array of %s\"\n", i, + _dbus_type_to_string (type), + _dbus_type_to_string (dbus_message_iter_get_array_type (iter))); + goto out; + } + + switch (type) + { + case DBUS_TYPE_BYTE: + err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len); + break; + case DBUS_TYPE_BOOLEAN: + err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len); + break; + case DBUS_TYPE_INT32: + err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len); + break; + case DBUS_TYPE_UINT32: + err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len); + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len); + break; + case DBUS_TYPE_UINT64: + err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len); + break; +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + err = !dbus_message_iter_get_double_array (iter, (double **)data, len); + break; + case DBUS_TYPE_STRING: + err = !dbus_message_iter_get_string_array (iter, (char ***)data, len); + break; + case DBUS_TYPE_NIL: + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_CUSTOM: + case DBUS_TYPE_DICT: + _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n"); + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); + goto out; + default: + _dbus_warn ("Unknown field type %d\n", type); + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); + goto out; + } + if (err) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto out; + } + } + break; + case DBUS_TYPE_DICT: + _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n"); + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); + goto out; + default: + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); + _dbus_warn ("Unknown field type %d\n", spec_type); + goto out; + } + + spec_type = va_arg (var_args, int); + if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Message has only %d arguments, but more were expected", i); + goto out; + } + + i++; + } + + retval = TRUE; + + out: + + return retval; +} + /** * Returns the byte value that an iterator may point to. * Note that you need to check that the iterator points to @@ -2800,22 +2607,13 @@ dbus_message_iter_get_custom (DBusMessageIter *iter, unsigned char dbus_message_iter_get_byte (DBusMessageIter *iter) { - unsigned char value; - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0); + unsigned char value = 0; - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_BYTE); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value); - value = _dbus_string_get_byte (&real->message->body, pos); - return value; } - /** * Returns the boolean value that an iterator may point to. * Note that you need to check that the iterator points to @@ -2828,19 +2626,11 @@ dbus_message_iter_get_byte (DBusMessageIter *iter) dbus_bool_t dbus_message_iter_get_boolean (DBusMessageIter *iter) { - unsigned char value; - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + unsigned char value = 0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_BOOLEAN); - - value = _dbus_string_get_byte (&real->message->body, pos); - - return value; + return (value != FALSE); } /** @@ -2855,17 +2645,11 @@ dbus_message_iter_get_boolean (DBusMessageIter *iter) dbus_int32_t dbus_message_iter_get_int32 (DBusMessageIter *iter) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + dbus_int32_t value = 0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_INT32); - - return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order, - pos, NULL); + return value; } /** @@ -2880,17 +2664,11 @@ dbus_message_iter_get_int32 (DBusMessageIter *iter) dbus_uint32_t dbus_message_iter_get_uint32 (DBusMessageIter *iter) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + dbus_int32_t value = 0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_UINT32); - - return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order, - pos, NULL); + return value; } #ifdef DBUS_HAVE_INT64 @@ -2909,17 +2687,11 @@ dbus_message_iter_get_uint32 (DBusMessageIter *iter) dbus_int64_t dbus_message_iter_get_int64 (DBusMessageIter *iter) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + dbus_int64_t value = 0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_INT64); - - return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order, - pos, NULL); + return value; } /** @@ -2936,17 +2708,11 @@ dbus_message_iter_get_int64 (DBusMessageIter *iter) dbus_uint64_t dbus_message_iter_get_uint64 (DBusMessageIter *iter) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + dbus_uint64_t value = 0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_UINT64); - - return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order, - pos, NULL); + return value; } #endif /* DBUS_HAVE_INT64 */ @@ -2963,17 +2729,11 @@ dbus_message_iter_get_uint64 (DBusMessageIter *iter) double dbus_message_iter_get_double (DBusMessageIter *iter) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; + double value = 0.0; - _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0); + _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value); - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_DOUBLE); - - return _dbus_demarshal_double (&real->message->body, real->message->byte_order, - pos, NULL); + return value; } /** @@ -3074,6 +2834,30 @@ dbus_message_iter_init_dict_iterator (DBusMessageIter *iter, return len > 0; } +static dbus_bool_t +_dbus_message_iter_get_basic_type_array (DBusMessageIter *iter, + char type, + void **array, + int *array_len) +{ + DBusMessageRealIter *real = (DBusMessageRealIter *)iter; + int item_type, pos; + + _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); + + pos = dbus_message_iter_get_data_start (real, &item_type); + + _dbus_assert (item_type == DBUS_TYPE_ARRAY); + + item_type = iter_get_array_type (real, NULL); + + _dbus_assert (type == item_type); + + return _dbus_demarshal_basic_type_array (&real->message->body, + item_type, array, array_len, + real->message->byte_order, &pos); +} + /** * Returns the byte array that the iterator may point to. * Note that you need to check that the iterator points @@ -3089,24 +2873,8 @@ dbus_message_iter_get_byte_array (DBusMessageIter *iter, unsigned char **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - - _dbus_assert (type == DBUS_TYPE_BYTE); - - if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE, + (void **) value, len); } /** @@ -3124,24 +2892,8 @@ dbus_message_iter_get_boolean_array (DBusMessageIter *iter, unsigned char **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - - _dbus_assert (type == DBUS_TYPE_BOOLEAN); - - if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN, + (void **) value, len); } /** @@ -3159,24 +2911,8 @@ dbus_message_iter_get_int32_array (DBusMessageIter *iter, dbus_int32_t **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - - _dbus_assert (type == DBUS_TYPE_INT32); - - if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32, + (void **) value, len); } /** @@ -3194,23 +2930,8 @@ dbus_message_iter_get_uint32_array (DBusMessageIter *iter, dbus_uint32_t **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - _dbus_assert (type == DBUS_TYPE_UINT32); - - if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32, + (void **) value, len); } #ifdef DBUS_HAVE_INT64 @@ -3232,24 +2953,8 @@ dbus_message_iter_get_int64_array (DBusMessageIter *iter, dbus_int64_t **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - - _dbus_assert (type == DBUS_TYPE_INT64); - - if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64, + (void **) value, len); } /** @@ -3269,23 +2974,8 @@ dbus_message_iter_get_uint64_array (DBusMessageIter *iter, dbus_uint64_t **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - _dbus_assert (type == DBUS_TYPE_UINT64); - - if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64, + (void **) value, len); } #endif /* DBUS_HAVE_INT64 */ @@ -3305,23 +2995,8 @@ dbus_message_iter_get_double_array (DBusMessageIter *iter, double **value, int *len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int type, pos; - - _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); - - pos = dbus_message_iter_get_data_start (real, &type); - - _dbus_assert (type == DBUS_TYPE_ARRAY); - - type = iter_get_array_type (real, NULL); - _dbus_assert (type == DBUS_TYPE_DOUBLE); - - if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order, - pos, NULL, value, len)) - return FALSE; - else - return TRUE; + return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE, + (void **) value, len); } /** @@ -3589,25 +3264,21 @@ dbus_message_iter_append_nil (DBusMessageIter *iter) return TRUE; } -/** - * Appends a boolean value to the message - * - * @param iter an iterator pointing to the end of the message - * @param value the boolean value - * @returns #TRUE on success - */ -dbus_bool_t -dbus_message_iter_append_boolean (DBusMessageIter *iter, - dbus_bool_t value) +static dbus_bool_t +dbus_message_iter_append_basic (DBusMessageIter *iter, + char type, + void *value) { DBusMessageRealIter *real = (DBusMessageRealIter *)iter; _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN)) + if (!dbus_message_iter_append_type (real, type)) return FALSE; - - if (!_dbus_string_append_byte (&real->message->body, (value != FALSE))) + + if (!_dbus_marshal_basic_type (&real->message->body, + type, value, + real->message->byte_order)) { _dbus_string_set_length (&real->message->body, real->pos); return FALSE; @@ -3615,7 +3286,22 @@ dbus_message_iter_append_boolean (DBusMessageIter *iter, dbus_message_iter_append_done (real); - return TRUE; + return TRUE; +} + +/** + * Appends a boolean value to the message + * + * @param iter an iterator pointing to the end of the message + * @param value the boolean value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_iter_append_boolean (DBusMessageIter *iter, + dbus_bool_t value) +{ + unsigned char val = (value != FALSE); + return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val); } /** @@ -3629,25 +3315,9 @@ dbus_bool_t dbus_message_iter_append_byte (DBusMessageIter *iter, unsigned char value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE)) - return FALSE; - - if (!_dbus_string_append_byte (&real->message->body, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value); } - /** * Appends a 32 bit signed integer to the message. * @@ -3659,22 +3329,7 @@ dbus_bool_t dbus_message_iter_append_int32 (DBusMessageIter *iter, dbus_int32_t value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32)) - return FALSE; - - if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value); } /** @@ -3688,22 +3343,7 @@ dbus_bool_t dbus_message_iter_append_uint32 (DBusMessageIter *iter, dbus_uint32_t value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32)) - return FALSE; - - if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value); } #ifdef DBUS_HAVE_INT64 @@ -3721,22 +3361,7 @@ dbus_bool_t dbus_message_iter_append_int64 (DBusMessageIter *iter, dbus_int64_t value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64)) - return FALSE; - - if (!_dbus_marshal_int64 (&real->message->body, real->message->byte_order, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value); } /** @@ -3752,22 +3377,7 @@ dbus_bool_t dbus_message_iter_append_uint64 (DBusMessageIter *iter, dbus_uint64_t value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64)) - return FALSE; - - if (!_dbus_marshal_uint64 (&real->message->body, real->message->byte_order, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value); } #endif /* DBUS_HAVE_INT64 */ @@ -3783,22 +3393,7 @@ dbus_bool_t dbus_message_iter_append_double (DBusMessageIter *iter, double value) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE)) - return FALSE; - - if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value); } /** @@ -4138,28 +3733,22 @@ dbus_message_iter_append_dict (DBusMessageIter *iter, return TRUE; } - -/** - * Appends a boolean array to the message. - * - * @param iter an iterator pointing to the end of the message - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -dbus_message_iter_append_boolean_array (DBusMessageIter *iter, - unsigned const char *value, - int len) +static dbus_bool_t +_dbus_message_iter_append_basic_array (DBusMessageIter *iter, + char type, + const void *value, + int len) { DBusMessageRealIter *real = (DBusMessageRealIter *)iter; _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL)) + if (!append_array_type (real, type, NULL, NULL)) return FALSE; - if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len)) + if (!_dbus_marshal_basic_type_array (&real->message->body, + type, value, len, + real->message->byte_order)) { _dbus_string_set_length (&real->message->body, real->pos); return FALSE; @@ -4170,35 +3759,189 @@ dbus_message_iter_append_boolean_array (DBusMessageIter *iter, return TRUE; } + /** - * Appends a 32 bit signed integer array to the message. + * This function takes a va_list for use by language bindings. + * It's otherwise the same as dbus_message_append_args(). * - * @param iter an iterator pointing to the end of the message - * @param value the array - * @param len the length of the array + * @todo: Shouldn't this function clean up the changes to the message + * on failures? (Yes) + + * @see dbus_message_append_args. + * @param message the message + * @param first_arg_type type of first argument + * @param var_args value of first argument, then list of type/value pairs * @returns #TRUE on success */ dbus_bool_t -dbus_message_iter_append_int32_array (DBusMessageIter *iter, - const dbus_int32_t *value, - int len) +dbus_message_append_args_valist (DBusMessage *message, + int first_arg_type, + va_list var_args) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; + int type, old_len; + DBusMessageIter iter; - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); + _dbus_return_val_if_fail (message != NULL, FALSE); + + old_len = _dbus_string_get_length (&message->body); + + type = first_arg_type; - if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL)) - return FALSE; + dbus_message_append_iter_init (message, &iter); - if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len)) + while (type != DBUS_TYPE_INVALID) { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; + switch (type) + { + case DBUS_TYPE_NIL: + if (!dbus_message_iter_append_nil (&iter)) + goto errorout; + break; + case DBUS_TYPE_BYTE: + if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, unsigned char))) + goto errorout; + break; + case DBUS_TYPE_BOOLEAN: + if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t))) + goto errorout; + break; + case DBUS_TYPE_INT32: + if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t))) + goto errorout; + break; + case DBUS_TYPE_UINT32: + if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t))) + goto errorout; + break; +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t))) + goto errorout; + break; + case DBUS_TYPE_UINT64: + if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t))) + goto errorout; + break; +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double))) + goto errorout; + break; + case DBUS_TYPE_STRING: + if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *))) + goto errorout; + break; + case DBUS_TYPE_OBJECT_PATH: + if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*))) + goto errorout; + break; + case DBUS_TYPE_CUSTOM: + { + const char *name; + unsigned char *data; + int len; + + name = va_arg (var_args, const char *); + data = va_arg (var_args, unsigned char *); + len = va_arg (var_args, int); + + if (!dbus_message_iter_append_custom (&iter, name, data, len)) + goto errorout; + break; + } + case DBUS_TYPE_ARRAY: + { + void *data; + int len, type; + + type = va_arg (var_args, int); + data = va_arg (var_args, void *); + len = va_arg (var_args, int); + + switch (type) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + if (!_dbus_message_iter_append_basic_array (&iter, type, data, len)) + goto errorout; + break; + case DBUS_TYPE_STRING: + if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len)) + goto errorout; + break; + case DBUS_TYPE_OBJECT_PATH: + if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len)) + goto errorout; + break; + case DBUS_TYPE_NIL: + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_CUSTOM: + case DBUS_TYPE_DICT: + _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n"); + goto errorout; + default: + _dbus_warn ("Unknown field type %d\n", type); + goto errorout; + } + } + break; + + case DBUS_TYPE_DICT: + _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n"); + goto errorout; + default: + _dbus_warn ("Unknown field type %d\n", type); + goto errorout; + } + + type = va_arg (var_args, int); } - dbus_message_iter_append_done (real); - return TRUE; + + errorout: + return FALSE; +} + +/** + * Appends a boolean array to the message. + * + * @param iter an iterator pointing to the end of the message + * @param value the array + * @param len the length of the array + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_iter_append_boolean_array (DBusMessageIter *iter, + unsigned const char *value, + int len) +{ + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN, + value, len); +} + +/** + * Appends a 32 bit signed integer array to the message. + * + * @param iter an iterator pointing to the end of the message + * @param value the array + * @param len the length of the array + * @returns #TRUE on success + */ +dbus_bool_t +dbus_message_iter_append_int32_array (DBusMessageIter *iter, + const dbus_int32_t *value, + int len) +{ + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32, + value, len); } /** @@ -4214,22 +3957,8 @@ dbus_message_iter_append_uint32_array (DBusMessageIter *iter, const dbus_uint32_t *value, int len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL)) - return FALSE; - - if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32, + value, len); } #ifdef DBUS_HAVE_INT64 @@ -4249,22 +3978,8 @@ dbus_message_iter_append_int64_array (DBusMessageIter *iter, const dbus_int64_t *value, int len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL)) - return FALSE; - - if (!_dbus_marshal_int64_array (&real->message->body, real->message->byte_order, value, len)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64, + value, len); } /** @@ -4282,22 +3997,8 @@ dbus_message_iter_append_uint64_array (DBusMessageIter *iter, const dbus_uint64_t *value, int len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL)) - return FALSE; - - if (!_dbus_marshal_uint64_array (&real->message->body, real->message->byte_order, value, len)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64, + value, len); } #endif /* DBUS_HAVE_INT64 */ @@ -4314,22 +4015,8 @@ dbus_message_iter_append_double_array (DBusMessageIter *iter, const double *value, int len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL)) - return FALSE; - - if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE, + value, len); } /** @@ -4345,22 +4032,8 @@ dbus_message_iter_append_byte_array (DBusMessageIter *iter, unsigned const char *value, int len) { - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - - _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); - - if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL)) - return FALSE; - - if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len)) - { - _dbus_string_set_length (&real->message->body, real->pos); - return FALSE; - } - - dbus_message_iter_append_done (real); - - return TRUE; + return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE, + value, len); } /** diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 8820273d..a1bab820 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -2816,6 +2816,113 @@ _dbus_string_zero (DBusString *str) #include "dbus-test.h" #include <stdio.h> +/** + * Parses a basic type defined by type contained in a DBusString. The + * end_return parameter may be #NULL if you aren't interested in it. The + * type is parsed and stored in value_return. Return parameters are not + * initialized if the function returns #FALSE. + * + * @param str the string + * @param type the type of the basic type + * @param start the byte index of the start of the type + * @param value_return return location of the value or #NULL + * @param end_return return location of the end of the type, or #NULL + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_string_parse_basic_type (const DBusString *str, + char type, + int start, + void *value, + int *end_return) +{ + int end = start; + + switch (type) + { + case DBUS_TYPE_BOOLEAN: + { + int len = _dbus_string_get_length (str) - start; + if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL)) + { + end += 5; + *(unsigned char *) value = TRUE; + } + else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL)) + { + end += 4; + *(unsigned char *) value = FALSE; + } + else + _dbus_warn ("could not parse BOOLEAN\n"); + break; + } + case DBUS_TYPE_BYTE: + { + long val = 0; + + if (_dbus_string_get_byte (str, start) == '\'' && + _dbus_string_get_length (str) >= start + 4 && + _dbus_string_get_byte (str, start + 1) == '\\' && + _dbus_string_get_byte (str, start + 2) == '\'' && + _dbus_string_get_byte (str, start + 3) == '\'') + { + val = '\''; + end += 4; + } + else if (_dbus_string_get_byte (str, start) == '\'' && + _dbus_string_get_length (str) >= start + 3 && + _dbus_string_get_byte (str, start + 2) == '\'') + { + val = _dbus_string_get_byte (str, start + 1); + end += 3; + } + else + { + if (!_dbus_string_parse_int (str, start, &val, &end)) + _dbus_warn ("Failed to parse integer for BYTE\n"); + } + + if (val > 255) + _dbus_warn ("A byte must be in range 0-255 not %ld\n", val); + + *(unsigned char *) value = val; + break; + } + case DBUS_TYPE_INT32: + { + long val; + if (_dbus_string_parse_int (str, start, &val, &end)) + *(dbus_int32_t *)value = val; + break; + } + case DBUS_TYPE_UINT32: + { + unsigned long val; + if (_dbus_string_parse_uint (str, start, &val, &end)) + *(dbus_uint32_t *)value = val; + break; + } +#ifdef DBUS_HAVE_INT64 + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + /* use stroll oull */ + _dbus_assert_not_reached ("string -> [u]int64 not supported yet"); + break; +#endif /* DBUS_HAVE_INT64 */ + case DBUS_TYPE_DOUBLE: + _dbus_string_parse_double (str, start, value, &end); + break; + default: + _dbus_assert_not_reached ("not a basic type"); + break; + } + if (end_return) + *end_return = end; + + return end != start; +} + static void test_max_len (DBusString *str, int max_len) diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 1499e0cc..2a428795 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -165,6 +165,11 @@ dbus_bool_t _dbus_string_parse_double (const DBusString *str, int start, double *value, int *end_return); +dbus_bool_t _dbus_string_parse_basic_type (const DBusString *str, + char type, + int start, + void *value, + int *end_return); dbus_bool_t _dbus_string_find (const DBusString *str, int start, const char *substr, |