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 | |
| 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.
| -rw-r--r-- | ChangeLog | 24 | ||||
| -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 | ||||
| -rw-r--r-- | glib/dbus-gvalue.c | 4 | 
8 files changed, 1077 insertions, 1348 deletions
@@ -1,3 +1,27 @@ +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. +  2004-05-27  Seth Nickell  <seth@gnome.org>  	* configure.in: 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, diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c index 06bf2182..04e962fe 100644 --- a/glib/dbus-gvalue.c +++ b/glib/dbus-gvalue.c @@ -17,8 +17,10 @@ dbus_gvalue_demarshal (DBusMessageIter *iter, GValue *value)      MAP(TYPE_BOOLEAN, get_boolean, TYPE_BOOLEAN , set_boolean);      MAP(TYPE_INT32, get_int32, TYPE_INT , set_int);      MAP(TYPE_UINT32, get_uint32, TYPE_UINT , set_uint); +#ifdef DBUS_HAVE_INT64      MAP(TYPE_INT64, get_int64, TYPE_INT64 , set_int64);      MAP(TYPE_UINT64, get_uint64, TYPE_UINT64 , set_uint64); +#endif      MAP(TYPE_DOUBLE, get_double, TYPE_DOUBLE , set_double);      case DBUS_TYPE_STRING:        { @@ -82,6 +84,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value)        dbus_message_iter_append_uint32 (iter,                                         g_value_get_ulong (value));        break; +#ifdef DBUS_HAVE_INT64      case G_TYPE_INT64:        dbus_message_iter_append_int64 (iter,                                        g_value_get_int64 (value)); @@ -90,6 +93,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value)        dbus_message_iter_append_uint64 (iter,                                         g_value_get_uint64 (value));        break; +#endif      case G_TYPE_FLOAT:        dbus_message_iter_append_double (iter,                                         g_value_get_float (value));  | 
