summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorMichael Meeks <michael@ximian.com>2004-05-28 13:10:36 +0000
committerMichael Meeks <michael@ximian.com>2004-05-28 13:10:36 +0000
commit0123e6a927772af6d56ddbe3f75a443ab40646d1 (patch)
tree1c31412a2a31d036a0051d364203f7a24ac8be0e /dbus
parentf33553eae306f4864a0198c5f9c56f1059536cf3 (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.c202
-rw-r--r--dbus/dbus-marshal.h22
-rw-r--r--dbus/dbus-message-builder.c710
-rw-r--r--dbus/dbus-message.c1351
-rw-r--r--dbus/dbus-string.c107
-rw-r--r--dbus/dbus-string.h5
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,