diff options
| -rw-r--r-- | dbus/dbus-marshal-basic.c | 2611 | ||||
| -rw-r--r-- | dbus/dbus-marshal-basic.h | 243 | ||||
| -rw-r--r-- | dbus/dbus-marshal-recursive.c | 103 | ||||
| -rw-r--r-- | dbus/dbus-marshal-recursive.h | 19 | 
4 files changed, 662 insertions, 2314 deletions
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 771ca2b6..7de7a4a6 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -2,10 +2,10 @@  /* dbus-marshal-basic.c  Marshalling routines for basic (primitive) types   *   * Copyright (C) 2002 CodeFactory AB - * Copyright (C) 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.   *   * Licensed under the Academic Free License version 2.1 - *  + *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by   * the Free Software Foundation; either version 2 of the License, or @@ -15,7 +15,7 @@   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details. - *  + *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA @@ -23,9 +23,6 @@   */  #include "dbus-internals.h" -#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 -#include "dbus-string-private.h" -  #include "dbus-marshal-basic.h"  #include <string.h> @@ -50,7 +47,7 @@ unpack_4_octets (int                  byte_order,                   const unsigned char *data)  {    _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); -   +    if (byte_order == DBUS_LITTLE_ENDIAN)      return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);    else @@ -80,7 +77,7 @@ swap_bytes (unsigned char *data,  /**   * Union used to manipulate 8 bytes as if they - * were various types.  + * were various types.   */  typedef union  { @@ -96,10 +93,10 @@ unpack_8_octets (int                  byte_order,                   const unsigned char *data)  {    DBusOctets8 r; -   +    _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);    _dbus_assert (sizeof (r) == 8); -   +  #ifdef DBUS_HAVE_INT64    if (byte_order == DBUS_LITTLE_ENDIAN)      r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data); @@ -110,7 +107,7 @@ unpack_8_octets (int                  byte_order,    if (byte_order != DBUS_COMPILER_BYTE_ORDER)      swap_bytes ((unsigned char*) &r, sizeof (r));  #endif -   +    return r;  } @@ -126,7 +123,7 @@ _dbus_unpack_uint32 (int                  byte_order,                       const unsigned char *data)  {    return unpack_4_octets (byte_order, data); -}   +}  /**   * Unpacks a 32 bit signed integer from a data pointer @@ -155,11 +152,11 @@ _dbus_unpack_uint64 (int                  byte_order,                       const unsigned char *data)  {    DBusOctets8 r; -   +    r = unpack_8_octets (byte_order, data);    return r.u; -}   +}  /**   * Unpacks a 64 bit signed integer from a data pointer @@ -173,7 +170,7 @@ _dbus_unpack_int64 (int                  byte_order,                      const unsigned char *data)  {    DBusOctets8 r; -   +    r = unpack_8_octets (byte_order, data);    return r.s; @@ -187,9 +184,9 @@ pack_4_octets (dbus_uint32_t   value,                 unsigned char  *data)  {    _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); -   -  if ((byte_order) == DBUS_LITTLE_ENDIAN)                   -    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);        + +  if ((byte_order) == DBUS_LITTLE_ENDIAN) +    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);    else      *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);  } @@ -216,8 +213,8 @@ pack_8_octets (DBusOctets8     value,    _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);  #ifdef DBUS_HAVE_INT64 -  if ((byte_order) == DBUS_LITTLE_ENDIAN)                   -    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);  +  if ((byte_order) == DBUS_LITTLE_ENDIAN) +    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);    else      *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);  #else @@ -299,10 +296,10 @@ set_4_octets (DBusString          *str,                dbus_uint32_t        value)  {    char *data; -   +    _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||                  byte_order == DBUS_BIG_ENDIAN); -   +    data = _dbus_string_get_data_len (str, offset, 4);    _dbus_pack_uint32 (value, byte_order, data); @@ -315,10 +312,10 @@ set_8_octets (DBusString          *str,                DBusOctets8          value)  {    char *data; -   +    _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||                  byte_order == DBUS_BIG_ENDIAN); -   +    data = _dbus_string_get_data_len (str, offset, 8);    pack_8_octets (value, byte_order, data); @@ -332,7 +329,7 @@ set_8_octets (DBusString          *str,   * @param offset the byte offset where int should be written   * @param byte_order the byte order to use   * @param value the value - *  + *   */  void  _dbus_marshal_set_int32 (DBusString          *str, @@ -351,7 +348,7 @@ _dbus_marshal_set_int32 (DBusString          *str,   * @param offset the byte offset where int should be written   * @param byte_order the byte order to use   * @param value the value - *  + *   */  void  _dbus_marshal_set_uint32 (DBusString          *str, @@ -372,7 +369,7 @@ _dbus_marshal_set_uint32 (DBusString          *str,   * @param offset the byte offset where int should be written   * @param byte_order the byte order to use   * @param value the value - *  + *   */  void  _dbus_marshal_set_int64 (DBusString          *str, @@ -393,7 +390,7 @@ _dbus_marshal_set_int64 (DBusString          *str,   * @param offset the byte offset where int should be written   * @param byte_order the byte order to use   * @param value the value - *  + *   */  void  _dbus_marshal_set_uint64 (DBusString          *str, @@ -423,7 +420,7 @@ _dbus_marshal_set_uint64 (DBusString          *str,   * @param value the value   * @param len the length to use   * @returns #TRUE on success - *  + *   */  dbus_bool_t  _dbus_marshal_set_string (DBusString          *str, @@ -433,10 +430,10 @@ _dbus_marshal_set_string (DBusString          *str,  			  int                  len)  {    int old_len; -   +    _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||                  byte_order == DBUS_BIG_ENDIAN); -   +    old_len = _dbus_demarshal_uint32 (str, byte_order,                                      offset, NULL); @@ -450,658 +447,23 @@ _dbus_marshal_set_string (DBusString          *str,    return TRUE;  } -/** - * Sets the existing marshaled object path at the given offset to a new - * value. The given offset must point to an existing object path or this - * function doesn't make sense. - * - * @todo implement this function - * - * @param str the string to write the marshalled path to - * @param offset the byte offset where path should be written - * @param byte_order the byte order to use - * @param path the new path - * @param path_len number of elements in the path - */ -void -_dbus_marshal_set_object_path (DBusString         *str, -                               int                 byte_order, -                               int                 offset, -                               const char        **path, -                               int                 path_len) -{ - -  /* FIXME */ -} - -static dbus_bool_t -marshal_4_octets (DBusString   *str, -                  int           insert_at, -                  int           byte_order, -                  dbus_uint32_t value) -{ -  _dbus_assert (sizeof (value) == 4); -   -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    value = DBUS_UINT32_SWAP_LE_BE (value); - -  return _dbus_string_insert_4_aligned (str, insert_at, -                                        (const unsigned char *)&value); -} - -static dbus_bool_t -marshal_8_octets (DBusString *str, -                  int         insert_at, -                  int         byte_order, -                  DBusOctets8 value) -{ -  _dbus_assert (sizeof (value) == 8); - -  swap_8_octets (&value, byte_order); -   -  return _dbus_string_insert_8_aligned (str, insert_at, -                                        (const unsigned char *)&value); -} - -/** - * Marshals a double value. - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the value - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_double (DBusString *str, -		      int         byte_order, -		      double      value) -{ -  DBusOctets8 r; -  r.d = value; -  return marshal_8_octets (str, _dbus_string_get_length (str), -                           byte_order, r); -} - -/** - * Marshals a 32 bit signed integer value. - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the value - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_int32  (DBusString   *str, -		      int           byte_order, -		      dbus_int32_t  value) -{ -  return marshal_4_octets (str, _dbus_string_get_length (str), -                           byte_order, (dbus_uint32_t) value); -} - -/** - * Marshals a 32 bit unsigned integer value. - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the value - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_uint32 (DBusString   *str, -                      int           byte_order, -                      dbus_uint32_t value) -{ -  return marshal_4_octets (str, _dbus_string_get_length (str), -                           byte_order, value); -} - - -#ifdef DBUS_HAVE_INT64 -/** - * Marshals a 64 bit signed integer value. - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the value - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_int64  (DBusString   *str, -		      int           byte_order, -		      dbus_int64_t  value) -{ -  DBusOctets8 r; -  r.s = value; -  return marshal_8_octets (str, _dbus_string_get_length (str), -                           byte_order, r); -} - -/** - * Marshals a 64 bit unsigned integer value. - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the value - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_uint64 (DBusString    *str, -		      int            byte_order, -		      dbus_uint64_t  value) -{ -  DBusOctets8 r; -  r.u = value; -  return marshal_8_octets (str, _dbus_string_get_length (str), -                           byte_order, r); -} - -#endif /* DBUS_HAVE_INT64 */ - -/** - * Marshals a UTF-8 string - * - * @todo: If the string append fails we need to restore - * the old length. (also for other marshallers) - *  - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the string - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_string (DBusString    *str, -		      int            byte_order, -		      const char    *value) -{ -  int len, old_string_len; - -  old_string_len = _dbus_string_get_length (str); -   -  len = strlen (value); - -  if (!_dbus_marshal_uint32 (str, byte_order, len)) -    { -      /* Restore the previous length */ -      _dbus_string_set_length (str, old_string_len); - -      return FALSE; -    } - -  return _dbus_string_append_len (str, value, len + 1); -} - -/** - * Marshals a UTF-8 string - * - * @todo: If the string append fails we need to restore - * the old length. (also for other marshallers) - *  - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the string - * @param len length of string to marshal in bytes - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_string_len (DBusString    *str, -                          int            byte_order, -                          const char    *value, -                          int            len) -{ -  int old_string_len; - -  old_string_len = _dbus_string_get_length (str); - -  if (!_dbus_marshal_uint32 (str, byte_order, len)) -    { -      /* Restore the previous length */ -      _dbus_string_set_length (str, old_string_len); - -      return FALSE; -    } - -  if (!_dbus_string_append_len (str, value, len)) -    return FALSE; - -  /* add a nul byte */ -  if (!_dbus_string_lengthen (str, 1)) -    return FALSE; - -  return TRUE; -} - -static dbus_bool_t -_dbus_marshal_signature (DBusString    *str, -                         const char    *value) -{ -  int len, old_string_len; - -  old_string_len = _dbus_string_get_length (str); -   -  len = strlen (value); - -  _dbus_assert (len <= DBUS_MAXIMUM_SIGNATURE_LENGTH); -   -  if (!_dbus_string_append_byte (str, len)) -    { -      /* Restore the previous length */ -      _dbus_string_set_length (str, old_string_len); - -      return FALSE; -    } - -  return _dbus_string_append_len (str, value, len + 1); -} - -/** - * Marshals a byte array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len number of elements in the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_byte_array (DBusString          *str, -			  int                  byte_order, -			  const unsigned char *value, -			  int                  len) -{ -  int old_string_len; - -  old_string_len = _dbus_string_get_length (str); -   -  if (!_dbus_marshal_uint32 (str, byte_order, len)) -    { -      /* Restore the previous length */ -      _dbus_string_set_length (str, old_string_len); - -      return FALSE; -    } - -  if (len == 0) -    return TRUE; -  else -    return _dbus_string_append_len (str, value, len); -} - -static dbus_bool_t -marshal_4_octets_array (DBusString          *str, -                        int                  byte_order, -                        const dbus_uint32_t *value, -                        int                  len) -{ -  int old_string_len; -  int array_start; - -  old_string_len = _dbus_string_get_length (str); - -  if (!_dbus_marshal_uint32 (str, byte_order, len * 4)) -    goto error; - -  array_start = _dbus_string_get_length (str); -   -  if (!_dbus_string_append_len (str, (const unsigned char*) value, -                                len * 4)) -    goto error; -   -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    { -      const unsigned char *d; -      const unsigned char *end; -       -      d = _dbus_string_get_data (str) + array_start; -      end = d + len * 4; -      while (d != end) -        { -          *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d)); -          d += 4; -        } -    } - -  return TRUE; -   - error: -  /* Restore previous length */ -  _dbus_string_set_length (str, old_string_len); -   -  return FALSE;   -} - -static dbus_bool_t -marshal_8_octets_array (DBusString          *str, -                        int                  byte_order, -                        const DBusOctets8   *value, -                        int                  len) -{ -  int old_string_len; -  int array_start; -   -  old_string_len = _dbus_string_get_length (str); - -  /*  The array length is the length in bytes of the array, -   * *excluding* alignment padding. -   */ -  if (!_dbus_marshal_uint32 (str, byte_order, len * 8)) -    goto error; - -  array_start = _dbus_string_get_length (str); - -  /* Note that we do alignment padding unconditionally -   * even if the array is empty; this means that -   * padding + len is always equal to the number of bytes -   * in the array. -   */ -   -  if (!_dbus_string_align_length (str, 8)) -    goto error; -   -  if (!_dbus_string_append_len (str, (const unsigned char*) value, -                                len * 8)) -    goto error; -   -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    { -      const unsigned char *d; -      const unsigned char *end; -       -      d = _dbus_string_get_data (str) + array_start; -      end = d + len * 8; -      while (d != end) -        { -#ifdef DBUS_HAVE_INT64 -          *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d)); -#else -          swap_bytes ((unsigned char*) d, 8); -#endif -          d += 8; -        } -    } - -  return TRUE; -   - error: -  /* Restore previous length */ -  _dbus_string_set_length (str, old_string_len); -   -  return FALSE;   -} - -/** - * Marshals a 32 bit signed integer array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_int32_array (DBusString         *str, -			   int                 byte_order, -			   const dbus_int32_t *value, -			   int                 len) -{ -  return marshal_4_octets_array (str, byte_order, -                                 (const dbus_uint32_t*) value, -                                 len); -} - -/** - * Marshals a 32 bit unsigned integer array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_uint32_array (DBusString          *str, -			    int                  byte_order, -			    const dbus_uint32_t  *value, -			    int                  len) -{ -  return marshal_4_octets_array (str, byte_order, -                                 value, -                                 len); -} - -#ifdef DBUS_HAVE_INT64 - -/** - * Marshals a 64 bit signed integer array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_int64_array (DBusString         *str, -			   int                 byte_order, -			   const dbus_int64_t *value, -			   int                 len) -{ -  return marshal_8_octets_array (str, byte_order, -                                 (const DBusOctets8*) value, -                                 len); -} - -/** - * Marshals a 64 bit unsigned integer array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_uint64_array (DBusString          *str, -			    int                  byte_order, -			    const dbus_uint64_t  *value, -			    int                  len) -{ -  return marshal_8_octets_array (str, byte_order, -                                 (const DBusOctets8*) value, -                                 len); -} - -#endif /* DBUS_HAVE_INT64 */ - -/** - * Marshals a double array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_double_array (DBusString          *str, -			    int                  byte_order, -			    const double        *value, -			    int                  len) -{ -  return marshal_8_octets_array (str, byte_order, -                                 (const DBusOctets8*) value, -                                 len); -} - -/** - * Marshals a string array - * - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param value the array - * @param len the length of the array - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_marshal_string_array (DBusString  *str, -			    int          byte_order, -			    const char **value, -			    int          len) -{ -  int i, old_string_len, array_start; - -  old_string_len = _dbus_string_get_length (str); - -  /* Set the length to 0 temporarily */ -  if (!_dbus_marshal_uint32 (str, byte_order, 0)) -    goto error; - -  array_start = _dbus_string_get_length (str); -   -  for (i = 0; i < len; i++) -    if (!_dbus_marshal_string (str, byte_order, value[i])) -      goto error; - -  /* Write the length now that we know it */ -  _dbus_marshal_set_uint32 (str, byte_order, -			    _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)), -			    _dbus_string_get_length (str) - array_start); -   -  return TRUE; -   - error: -  /* Restore previous length */ -  _dbus_string_set_length (str, old_string_len); -   -  return FALSE;       -} - -/** - * Marshals an object path value. - *  - * @param str the string to append the marshalled value to - * @param byte_order the byte order to use - * @param path the path - * @param path_len length of the path - * @returns #TRUE on success - */ -static dbus_bool_t -_dbus_marshal_object_path (DBusString            *str, -                           int                    byte_order, -                           const char           **path, -                           int                    path_len) -{ -  int array_start, old_string_len; -  int i; -   -  old_string_len = _dbus_string_get_length (str); -   -  /* Set the length to 0 temporarily */ -  if (!_dbus_marshal_uint32 (str, byte_order, 0)) -    goto nomem; - -  array_start = _dbus_string_get_length (str); -   -  i = 0; -  while (i < path_len) -    { -      if (!_dbus_string_append_byte (str, '/')) -        goto nomem; -       -      if (!_dbus_string_append (str, path[0])) -        goto nomem; - -      ++i; -    } - -  /* Write the length now that we know it */ -  _dbus_marshal_set_uint32 (str, byte_order, -			    _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)), -			    _dbus_string_get_length (str) - array_start);   - -  return TRUE; - - nomem: -  /* Restore the previous length */ -  _dbus_string_set_length (str, old_string_len); -   -  return FALSE; -} -  static dbus_uint32_t  demarshal_4_octets (const DBusString *str,                      int               byte_order,                      int               pos,                      int              *new_pos)  { -  const DBusRealString *real = (const DBusRealString*) str; -      pos = _DBUS_ALIGN_VALUE (pos, 4); -   -  if (new_pos) -    *new_pos = pos + 4; - -  return unpack_4_octets (byte_order, real->str + pos); -} -static DBusOctets8 -demarshal_8_octets (const DBusString *str, -                    int               byte_order, -                    int               pos, -                    int              *new_pos) -{ -  const DBusRealString *real = (const DBusRealString*) str; -   -  pos = _DBUS_ALIGN_VALUE (pos, 8); -      if (new_pos) -    *new_pos = pos + 8; - -  return unpack_8_octets (byte_order, real->str + pos); -} - -/** - * Demarshals a double. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @returns the demarshaled double. - */ -double -_dbus_demarshal_double (const DBusString  *str, -			int                byte_order, -			int                pos, -			int               *new_pos) -{ -  DBusOctets8 r; - -  r = demarshal_8_octets (str, byte_order, pos, new_pos); +    *new_pos = pos + 4; -  return r.d; +  return unpack_4_octets (byte_order, +                          _dbus_string_get_const_data (str) + pos);  }  /** - * Demarshals a 32 bit signed integer. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @returns the demarshaled integer. - */ -dbus_int32_t -_dbus_demarshal_int32  (const DBusString *str, -			int               byte_order, -			int               pos, -			int              *new_pos) -{ -  return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos); -} - -/** - * Demarshals a 32 bit unsigned integer. + * Convenience function to demarshal a 32 bit unsigned integer.   *   * @param str the string containing the data   * @param byte_order the byte order @@ -1111,61 +473,13 @@ _dbus_demarshal_int32  (const DBusString *str,   */  dbus_uint32_t  _dbus_demarshal_uint32  (const DBusString *str, -			 int         byte_order, -			 int         pos, -			 int        *new_pos) +			 int               byte_order, +			 int               pos, +			 int              *new_pos)  {    return demarshal_4_octets (str, byte_order, pos, new_pos);  } -#ifdef DBUS_HAVE_INT64 - -/** - * Demarshals a 64 bit signed integer. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @returns the demarshaled integer. - */ -dbus_int64_t -_dbus_demarshal_int64  (const DBusString *str, -			int               byte_order, -			int               pos, -			int              *new_pos) -{ -  DBusOctets8 r; - -  r = demarshal_8_octets (str, byte_order, pos, new_pos); - -  return r.s; -} - -/** - * Demarshals a 64 bit unsigned integer. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @returns the demarshaled integer. - */ -dbus_uint64_t -_dbus_demarshal_uint64  (const DBusString *str, -			 int         byte_order, -			 int         pos, -			 int        *new_pos) -{ -  DBusOctets8 r; - -  r = demarshal_8_octets (str, byte_order, pos, new_pos); - -  return r.u; -} - -#endif /* DBUS_HAVE_INT64 */ -  /**   * Demarshals a basic type   * @@ -1173,661 +487,84 @@ _dbus_demarshal_uint64  (const DBusString *str,   * @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 + * @param pos position in the string + * @param new_pos pointer to update with new position, or #NULL   **/  void  _dbus_demarshal_basic_type (const DBusString      *str,  			    int                    type,  			    void                  *value,  			    int                    byte_order, -			    int                   *pos) +			    int                    pos, +                            int                   *new_pos)  { -  const char *str_data = _dbus_string_get_const_data (str); +  const char *str_data; + +  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)++; +      *(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); +      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; +      pos += 4;        break;  #ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64:  +    case DBUS_TYPE_UINT64:  #endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE: -      *pos = _DBUS_ALIGN_VALUE (*pos, 8); -      memcpy (value, str_data + *pos, 8); +      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	 +#else  	swap_bytes (value, 8);  #endif -      *pos += 8; +      pos += 8;        break;      case DBUS_TYPE_STRING:      case DBUS_TYPE_OBJECT_PATH:        {          int len; -         -        len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos); -         -        *(const char**) value = str_data + *pos; -        *pos += len + 1; /* length plus nul */ +        len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); + +        *(const char**) value = str_data + pos; + +        pos += len + 1; /* length plus nul */        }        break;      case DBUS_TYPE_SIGNATURE:        {          int len; -         -        len = _dbus_string_get_byte (str, *pos); -        *pos += 1; -         -        *(const char**) value = str_data + *pos; - -        *pos += len + 1; /* length plus nul */ -      } -      break; -    default: -      _dbus_verbose ("type %s not a basic type\n", -                     _dbus_type_to_string (type)); -      _dbus_assert_not_reached ("not a basic type"); -      break; -    } -} - -/** - * Demarshals an UTF-8 string. - * - * @todo Should we check the string to make sure - * that it's  valid UTF-8, and maybe "fix" the string - * if it's broken? - * - * @todo Should probably demarshal to a DBusString, - * having memcpy() in here is Evil(tm). - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @returns the demarshaled string. - */ -char * -_dbus_demarshal_string (const DBusString *str, -			int               byte_order, -			int               pos, -			int              *new_pos) -{ -  int len; -  char *retval; -  const char *data; -   -  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - -  retval = dbus_malloc (len + 1); - -  if (!retval) -    return NULL; - -  data = _dbus_string_get_const_data_len (str, pos, len + 1); - -  if (!data) -    return NULL; - -  memcpy (retval, data, len + 1); - -  if (new_pos) -    *new_pos = pos + len + 1; -   -  return retval; -} - -/** - * Demarshals a byte array. - * - * @todo Should probably demarshal to a DBusString, - * having memcpy() in here is Evil(tm). - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data -  - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_byte_array (const DBusString  *str, -			    int                byte_order, -			    int                pos, -			    int               *new_pos, -			    unsigned char    **array, -			    int               *array_len) -{ -  int len; -  unsigned char *retval; -  const char *data; - -  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - -  if (len == 0) -    { -      *array_len = len; -      *array = NULL; - -      if (new_pos) -	*new_pos = pos; -       -      return TRUE; -    } -   -  retval = dbus_malloc (len); - -  if (!retval) -    return FALSE; - -  data = _dbus_string_get_const_data_len (str, pos, len); - -  if (!data) -    { -      dbus_free (retval); -      return FALSE; -    } - -  memcpy (retval, data, len); - -  if (new_pos) -    *new_pos = pos + len; - -  *array = retval; -  *array_len = len; -   -  return TRUE; -} - -static dbus_bool_t -demarshal_4_octets_array (const DBusString  *str, -                          int                byte_order, -                          int                pos, -                          int               *new_pos, -                          dbus_uint32_t    **array, -                          int               *array_len) -{ -  int len, i; -  dbus_uint32_t *retval; -  int byte_len; -   -  byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); -  len = byte_len / 4; - -  if (len == 0) -    { -      *array_len = 0; -      *array = NULL; - -      if (new_pos) -	*new_pos = pos; -       -      return TRUE; -    } - -  if (!_dbus_string_copy_data_len (str, (char**) &retval, -                                   pos, byte_len)) -    return FALSE; -   -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    { -      for (i = 0; i < len; i++) -        retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]); -    } - -  if (new_pos) -    *new_pos = pos + byte_len; - -  *array_len = len; -  *array = retval; -   -  return TRUE;   -} - -static dbus_bool_t -demarshal_8_octets_array (const DBusString  *str, -                          int                byte_order, -                          int                pos, -                          int               *new_pos, -                          DBusOctets8      **array, -                          int               *array_len) -{ -  int len, i; -  DBusOctets8 *retval; -  int byte_len; -   -  byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - -  pos = _DBUS_ALIGN_VALUE (pos, 8); -   -  len = byte_len / 8; - -  if (len == 0) -    { -      *array_len = 0; -      *array = NULL; - -      if (new_pos) -	*new_pos = pos; -       -      return TRUE; -    } - -  if (!_dbus_string_copy_data_len (str, (char**) &retval, -                                   pos, byte_len)) -    return FALSE; -   -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    { -      for (i = 0; i < len; i++) -        { -#ifdef DBUS_HAVE_INT64 -          retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u); -#else -          swap_bytes ((unsigned char *) &retval[i], 8); -#endif -        } -    } - -  if (new_pos) -    *new_pos = pos + byte_len; - -  *array_len = len; -  *array = retval; -   -  return TRUE;   -} - -/** - * Demarshals a 32 bit signed integer array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_int32_array (const DBusString  *str, -			     int                byte_order, -			     int                pos, -			     int               *new_pos, -			     dbus_int32_t     **array, -			     int               *array_len) -{ -  return demarshal_4_octets_array (str, byte_order, pos, new_pos, -                                   (dbus_uint32_t**) array, array_len); -} - -/** - * Demarshals a 32 bit unsigned integer array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_uint32_array (const DBusString  *str, -			      int                byte_order, -			      int                pos, -			      int               *new_pos, -			      dbus_uint32_t    **array, -			      int               *array_len) -{ -  return demarshal_4_octets_array (str, byte_order, pos, new_pos, -                                   array, array_len); -} - -#ifdef DBUS_HAVE_INT64 - -/** - * Demarshals a 64 bit signed integer array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_int64_array (const DBusString  *str, -			     int                byte_order, -			     int                pos, -			     int               *new_pos, -			     dbus_int64_t     **array, -			     int               *array_len) -{ -  return demarshal_8_octets_array (str, byte_order, pos, new_pos, -                                   (DBusOctets8**) array, array_len); -} -/** - * Demarshals a 64 bit unsigned integer array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_uint64_array (const DBusString  *str, -			      int                byte_order, -			      int                pos, -			      int               *new_pos, -			      dbus_uint64_t    **array, -			      int               *array_len) -{ -  return demarshal_8_octets_array (str, byte_order, pos, new_pos, -                                   (DBusOctets8**) array, array_len); -} +        len = _dbus_string_get_byte (str, pos); +        pos += 1; -#endif /* DBUS_HAVE_INT64 */ +        *(const char**) value = str_data + pos; -/** - * Demarshals a double array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len length of the demarshaled data - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_double_array (const DBusString  *str, -			      int                byte_order, -			      int                pos, -			      int               *new_pos, -			      double           **array, -			      int               *array_len) -{ -  return demarshal_8_octets_array (str, byte_order, pos, new_pos, -                                   (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); +        pos += len + 1; /* length plus nul */ +      }        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_warn ("type %s not a basic type\n", +                  _dbus_type_to_string (type));        _dbus_assert_not_reached ("not a basic type");        break;      } -  return FALSE; -} - -/** - * Demarshals a string array. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param array the array - * @param array_len location for length of the demarshaled data or NULL - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_demarshal_string_array (const DBusString   *str, -			      int                 byte_order, -			      int                 pos, -			      int                *new_pos, -			      char             ***array, -			      int                *array_len) -{ -  int bytes_len, i; -  int len, allocated; -  int end_pos; -  char **retval; -   -  bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); -   -  if (bytes_len == 0) -    { -      *array_len = 0; -      *array = NULL; - -      if (new_pos) -	*new_pos = pos; -       -      return TRUE; -    } - -  len = 0; -  allocated = 4; -  end_pos = pos + bytes_len; -   -  retval = dbus_new (char *, allocated); - -  if (!retval) -    return FALSE; - -  while (pos < end_pos) -    { -      retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos); -       -      if (retval[len] == NULL) -	goto error; -       -      len += 1; - -      if (len >= allocated - 1) /* -1 for NULL termination */ -        { -          char **newp; -          newp = dbus_realloc (retval, -                               sizeof (char*) * allocated * 2); -          if (newp == NULL) -            goto error; - -          allocated *= 2; -          retval = newp; -        } -    } -       -  retval[len] = NULL;    if (new_pos)      *new_pos = pos; -   -  *array = retval; -  *array_len = len; -   -  return TRUE; - - error: -  for (i = 0; i < len; i++) -    dbus_free (retval[i]); -  dbus_free (retval); - -  return FALSE; -} - -/** Set to 1 to get a bunch of spew about disassembling the path string */ -#define VERBOSE_DECOMPOSE 0 - -/** - * Decompose an object path.  A path of just "/" is - * represented as an empty vector of strings. - *  - * @param data the path data - * @param len  the length of the path string - * @param path address to store new object path - * @param path_len length of stored path - */ -dbus_bool_t -_dbus_decompose_path (const char*     data, -                      int             len, -                      char         ***path, -                      int            *path_len) -{ -  char **retval; -  int n_components; -  int i, j, comp; - -  _dbus_assert (data != NULL); - -#if VERBOSE_DECOMPOSE -  _dbus_verbose ("Decomposing path \"%s\"\n", -                 data); -#endif -   -  n_components = 0; -  i = 0; -  while (i < len) -    { -      if (data[i] == '/') -        n_components += 1; -      ++i; -    } -   -  retval = dbus_new0 (char*, n_components + 1); - -  if (retval == NULL) -    return FALSE; - -  comp = 0; -  i = 0; -  while (i < len) -    { -      if (data[i] == '/') -        ++i; -      j = i; - -      while (j < len && data[j] != '/') -        ++j; - -      /* Now [i, j) is the path component */ -      _dbus_assert (i < j); -      _dbus_assert (data[i] != '/'); -      _dbus_assert (j == len || data[j] == '/'); - -#if VERBOSE_DECOMPOSE -      _dbus_verbose ("  (component in [%d,%d))\n", -                     i, j); -#endif -       -      retval[comp] = _dbus_memdup (&data[i], j - i + 1); -      if (retval[comp] == NULL) -        { -          dbus_free_string_array (retval); -          return FALSE; -        } -      retval[comp][j-i] = '\0'; -#if VERBOSE_DECOMPOSE -      _dbus_verbose ("  (component %d = \"%s\")\n", -                     comp, retval[comp]); -#endif - -      ++comp; -      i = j; -    } -  _dbus_assert (i == len); -   -  *path = retval; -  if (path_len) -    *path_len = n_components; -   -  return TRUE; -} - -/** - * Demarshals an object path.  A path of just "/" is - * represented as an empty vector of strings. - *  - * @param str the string containing the data - * @param byte_order the byte order - * @param pos the position in the string - * @param new_pos the new position of the string - * @param path address to store new object path - * @param path_len length of stored path - */ -dbus_bool_t -_dbus_demarshal_object_path (const DBusString *str, -                             int               byte_order, -                             int               pos, -                             int              *new_pos, -                             char           ***path, -                             int              *path_len) -{ -  int len; -  const char *data; -   -  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); -  data = _dbus_string_get_const_data_len (str, pos, len + 1); - -  if (!_dbus_decompose_path (data, len, path, path_len)) -    return FALSE; - -  if (new_pos) -    *new_pos = pos + len + 1; - -  return TRUE;  }  /** @@ -1858,7 +595,7 @@ _dbus_marshal_skip_basic_type (const DBusString      *str,        break;  #ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64:  +    case DBUS_TYPE_UINT64:  #endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE:        *pos = _DBUS_ALIGN_VALUE (*pos, 8); @@ -1868,24 +605,24 @@ _dbus_marshal_skip_basic_type (const DBusString      *str,      case DBUS_TYPE_OBJECT_PATH:        {          int len; -         +          len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos); -         +          *pos += len + 1; /* length plus nul */        }        break;      case DBUS_TYPE_SIGNATURE:        {          int len; -         +          len = _dbus_string_get_byte (str, *pos); -         +          *pos += len + 2; /* length byte plus length plus nul */        }        break;      default: -      _dbus_verbose ("type %s not a basic type\n", -                     _dbus_type_to_string (type)); +      _dbus_warn ("type %s not a basic type\n", +                  _dbus_type_to_string (type));        _dbus_assert_not_reached ("not a basic type");        break;      } @@ -1902,534 +639,27 @@ _dbus_marshal_skip_basic_type (const DBusString      *str,  void  _dbus_marshal_skip_array (const DBusString  *str,                            int                byte_order, +                          int                element_type,                            int               *pos)  { -  int len; - -  len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos); - -  /* FIXME we need to insert alignment padding according to array type */ -   -  *pos += len; -} - -/**  - * Returns the position right after the end of an argument.  PERFORMS - * NO VALIDATION WHATSOEVER. The message must have been previously - * validated. - * - * @param str a string - * @param byte_order the byte order to use - * @param type the type of the argument - * @param pos the pos where the arg starts - * @param end_pos pointer where the position right - * after the end position will follow - * @returns TRUE if more data exists after the arg - */ -dbus_bool_t -_dbus_marshal_get_arg_end_pos (const DBusString *str, -                               int               byte_order, -			       int               type, -                               int               pos, -                               int              *end_pos) -{ -  if (pos >= _dbus_string_get_length (str)) -    return FALSE; - -  switch (type) -    { -    case DBUS_TYPE_INVALID: -      return FALSE; -      break; - -    case DBUS_TYPE_BYTE: -      *end_pos = pos + 1; -      break; -       -    case DBUS_TYPE_BOOLEAN: -      *end_pos = pos + 1; -      break; - -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -      *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4; -      break; - -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64: -    case DBUS_TYPE_DOUBLE: -       -      *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8; -      break; - -    case DBUS_TYPE_OBJECT_PATH: -    case DBUS_TYPE_STRING: -      { -	int len; -	 -	/* Demarshal the length */ -	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - -	*end_pos = pos + len + 1; -      } -      break; -       -    case DBUS_TYPE_ARRAY: -      { -	int len; - -	/* Demarshal the length  */ -	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - -        /* FIXME needs to align to the right boundary for the array type */ -	*end_pos = _DBUS_ALIGN_VALUE (pos, 4) + len; -      } -      break; -       -    default: -      _dbus_warn ("Unknown message arg type %d\n", type); -      _dbus_assert_not_reached ("Unknown message argument type\n"); -      return FALSE; -    } - -  if (*end_pos > _dbus_string_get_length (str)) -    return FALSE; -   -  return TRUE; -} - -/** - * Demarshals and validates a length; returns < 0 if the validation - * fails. The length is required to be small enough that - * len*sizeof(double) will not overflow, and small enough to fit in a - * signed integer. DOES NOT check whether the length points - * beyond the end of the string, because it doesn't know the - * size of array elements. - * - * @param str the string - * @param byte_order the byte order - * @param pos the unaligned string position (snap to next aligned) - * @param new_pos return location for new position. - */ -static int -demarshal_and_validate_len (const DBusString *str, -                            int               byte_order, -                            int               pos, -                            int              *new_pos) -{ -  int align_4 = _DBUS_ALIGN_VALUE (pos, 4); -  unsigned int len; - -  _dbus_assert (new_pos != NULL); -   -  if ((align_4 + 4) > _dbus_string_get_length (str)) -    { -      _dbus_verbose ("not enough room in message for array length\n"); -      return -1; -    } -   -  if (!_dbus_string_validate_nul (str, pos, -                                  align_4 - pos)) -    { -      _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos); -      return -1; -    } - -  len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos); - -  /* note that the len is the number of bytes, so we need it to be -   * at least SIZE_T_MAX, but make it smaller just to keep things -   * sane.  We end up using ints for most sizes to avoid unsigned mess -   * so limit to maximum 32-bit signed int divided by at least 8, more -   * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes. -   */   -#define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32) -  if (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 -    return (int) len; -} - -static dbus_bool_t -validate_string (const DBusString *str, -                 int               pos, -                 int               len_without_nul, -                 int              *end_pos) -{ -  *end_pos = pos + len_without_nul + 1; -   -  if (*end_pos > _dbus_string_get_length (str)) -    { -      _dbus_verbose ("string length outside length of the message\n"); -      return FALSE; -    } -   -  if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0') -    { -      _dbus_verbose ("string arg not nul-terminated\n"); -      return FALSE; -    } -   -  if (!_dbus_string_validate_utf8 (str, pos, len_without_nul)) -    { -      _dbus_verbose ("string is not valid UTF-8\n"); -      return FALSE; -    } - -  return TRUE; -}    - -/** - * Validates and returns a typecode at a specific position - * in the message - * - * @param str a string - * @param type the type of the argument - * @param pos the pos where the typecode starts - * @param end_pos pointer where the position right - * after the end position will follow - * @returns #TRUE if the type is valid. - */ -dbus_bool_t -_dbus_marshal_validate_type   (const DBusString *str, -			       int               pos, -			       int              *type, -			       int              *end_pos) -{ -  const char *data; -   -  if (pos >= _dbus_string_get_length (str)) -    return FALSE; - -  data = _dbus_string_get_const_data_len (str, pos, 1); - -  if (_dbus_type_is_valid (*data)) -    { -      *type = *data; -      if (end_pos != NULL) -	*end_pos = pos + 1; -      return TRUE; -    } - -  _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data); -   -  return FALSE; -} - -/* Faster validator for array data that doesn't call - * validate_arg for each value - */ -static dbus_bool_t -validate_array_data (const DBusString *str, -                     int	       byte_order, -                     int               depth, -                     int               type, -                     int               array_type_pos, -                     int               pos, -                     int              *new_pos, -                     int               end) -{ -  switch (type) -    { -    case DBUS_TYPE_INVALID: -      return FALSE; -      break; - -    case DBUS_TYPE_OBJECT_PATH: -    case DBUS_TYPE_STRING: -    case DBUS_TYPE_ARRAY: -      /* This clean recursion to validate_arg is what we -       * are doing logically for all types, but we don't -       * really want to call validate_arg for every byte -       * in a byte array, so the primitive types are -       * special-cased. -       */ -      while (pos < end) -        { -          if (!_dbus_marshal_validate_arg (str, byte_order, depth, -                                           type, array_type_pos, pos, &pos)) -            return FALSE; -        } -      break; -       -    case DBUS_TYPE_BYTE: -      pos = end; -      break; -       -    case DBUS_TYPE_BOOLEAN: -      while (pos < end) -        { -          unsigned char c; -           -          c = _dbus_string_get_byte (str, pos); -           -          if (!(c == 0 || c == 1)) -            { -              _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c); -              return FALSE; -            } -           -          ++pos; -        } -      break; -       -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -      /* Call validate arg one time to check alignment padding -       * at start of array -       */ -      if (!_dbus_marshal_validate_arg (str, byte_order, depth, -                                       type, array_type_pos, pos, &pos)) -        return FALSE; -      pos = _DBUS_ALIGN_VALUE (end, 4); -      break; - -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64: -    case DBUS_TYPE_DOUBLE: -      /* Call validate arg one time to check alignment padding -       * at start of array -       */ -      if (!_dbus_marshal_validate_arg (str, byte_order, depth, -                                       type, array_type_pos, pos, &pos)) -        return FALSE; -      pos = _DBUS_ALIGN_VALUE (end, 8); -      break; -       -    default: -      _dbus_verbose ("Unknown message arg type %d\n", type); -      return FALSE; -    } - -  *new_pos = pos; - -  return TRUE; -} - -/**  - * Validates an argument of a specific type, checking that it - * is well-formed, for example no ludicrous length fields, strings - * are nul-terminated, etc. - * Returns the end position of the argument in end_pos, and - * returns #TRUE if a valid arg begins at "pos" - * - * @todo security: need to audit this function. - *  - * @param str a string - * @param byte_order the byte order to use - * @param depth current recursion depth, to prevent excessive recursion - * @param type the type of the argument - * @param array_type_pos the position of the current array type, or - *        -1 if not in an array - * @param pos the pos where the arg starts - * @param end_pos pointer where the position right - * after the end position will follow - * @returns #TRUE if the arg is valid. - */ -dbus_bool_t -_dbus_marshal_validate_arg (const DBusString *str, -                            int	              byte_order, -                            int               depth, -			    int               type, -			    int               array_type_pos, -                            int               pos, -                            int              *end_pos) -{ -  if (pos > _dbus_string_get_length (str)) -    { -      _dbus_verbose ("Validation went off the end of the message\n"); -      return FALSE; -    } +  dbus_uint32_t array_len; +  int i; +  int alignment; -#define MAX_VALIDATION_DEPTH 32 -   -  if (depth > MAX_VALIDATION_DEPTH) -    { -      _dbus_verbose ("Maximum recursion depth reached validating message\n"); -      return FALSE; -    } -   -  switch (type) -    { -    case DBUS_TYPE_INVALID: -      return FALSE; -      break; +  i = _DBUS_ALIGN_VALUE (*pos, 4); -    case DBUS_TYPE_BYTE: -      if (1 > _dbus_string_get_length (str) - pos) -	{ -	  _dbus_verbose ("no room for byte value\n"); -	  return FALSE; -	} -	 -      *end_pos = pos + 1; -      break; -       -    case DBUS_TYPE_BOOLEAN: -      { -	unsigned char c; - -        if (1 > _dbus_string_get_length (str) - pos) -          { -            _dbus_verbose ("no room for boolean value\n"); -            return FALSE; -          } -         -	c = _dbus_string_get_byte (str, pos); - -	if (!(c == 0 || c == 1)) -	  { -	    _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c); -	    return FALSE; -	  } -	 -        *end_pos = pos + 1; -      } -      break; -       -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -      { -        int align_4 = _DBUS_ALIGN_VALUE (pos, 4); -         -        if (!_dbus_string_validate_nul (str, pos, -                                        align_4 - pos)) -          { -            _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n"); -            return FALSE; -          } - -        *end_pos = align_4 + 4; -      } -      break; +  _dbus_demarshal_basic_type (str, +                              DBUS_TYPE_UINT32, +                              &array_len, +                              byte_order, +                              i, +                              &i); -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64:       -    case DBUS_TYPE_DOUBLE: -      { -        int align_8 = _DBUS_ALIGN_VALUE (pos, 8); - -        _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos)); -         -        if (!_dbus_string_validate_nul (str, pos, -                                        align_8 - pos)) -          { -            _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos); -            return FALSE; -          } - -        *end_pos = align_8 + 8; -      } -      break; +  alignment = _dbus_type_get_alignment (element_type); -    case DBUS_TYPE_OBJECT_PATH: -    case DBUS_TYPE_STRING: -      { -	int len; - -	/* Demarshal the length, which does NOT include -         * nul termination -         */ -	len = demarshal_and_validate_len (str, byte_order, pos, &pos); -        if (len < 0) -          return FALSE; - -        if (!validate_string (str, pos, len, end_pos)) -          return FALSE; - -        if (type == DBUS_TYPE_OBJECT_PATH) -          { -            if (!_dbus_string_validate_path (str, pos, len)) -              return FALSE; -          } -      } -      break; -       -    case DBUS_TYPE_ARRAY: -      { -	int len; -	int end; -	int array_type; - -	if (array_type_pos == -1) -	  { -	    array_type_pos = pos; - -	    do -	      { -		if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos)) -		  { -		    _dbus_verbose ("invalid array type\n"); -		    return FALSE; -		  } -	      } -	    while (array_type == DBUS_TYPE_ARRAY); -	  } -	else -	  array_type_pos++; - -	if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL)) -	  { -	    _dbus_verbose ("invalid array type\n"); -	    return FALSE; -	  } -         -	len = demarshal_and_validate_len (str, byte_order, pos, &pos); -        if (len < 0) -	  { -	    _dbus_verbose ("invalid array length (<0)\n"); -	    return FALSE; -	  } - -        if (len > _dbus_string_get_length (str) - pos) -          { -            _dbus_verbose ("array length outside length of the message\n"); -            return FALSE; -          } -	 -	end = pos + len; - -        if (len > 0 && !validate_array_data (str, byte_order, depth + 1, -					     array_type, array_type_pos, -					     pos, &pos, end)) -	  { -	    _dbus_verbose ("invalid array data\n"); -	    return FALSE; -	  } - -        if (pos < end) -          { -            /* This should not be able to happen, as long as validate_arg moves forward; -             * but the check is here just to be paranoid. -             */ -            _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n", -                           len, end - pos); -            return FALSE; -          } -         -	if (pos > end) -	  { -	    _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end); -	    return FALSE; -	  } - -	*end_pos = pos; -      } -      break; -       -    default: -      _dbus_verbose ("Unknown message arg type %d\n", type); -      return FALSE; -    } +  i = _DBUS_ALIGN_VALUE (i, alignment); -  if (*end_pos > _dbus_string_get_length (str)) -    return FALSE; -   -  return TRUE; +  *pos = i + array_len;  }  /** @@ -2451,11 +681,12 @@ _dbus_type_is_valid (int typecode)      case DBUS_TYPE_DOUBLE:      case DBUS_TYPE_STRING:      case DBUS_TYPE_OBJECT_PATH: +    case DBUS_TYPE_SIGNATURE:      case DBUS_TYPE_ARRAY:      case DBUS_TYPE_STRUCT:      case DBUS_TYPE_VARIANT:        return TRUE; -       +      default:        return FALSE;      } @@ -2495,7 +726,7 @@ _dbus_type_get_alignment (int typecode)         */      case DBUS_TYPE_STRUCT:        return 8; -       +      default:        _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");        return 0; @@ -2506,7 +737,7 @@ _dbus_type_get_alignment (int typecode)   * If in verbose mode, print a block of binary data.   *   * @todo right now it prints even if not in verbose mode - *  + *   * @param data the data   * @param len the length of the data   * @param offset where to start counting for byte indexes @@ -2520,7 +751,7 @@ _dbus_verbose_bytes (const unsigned char *data,    const unsigned char *aligned;    _dbus_assert (len >= 0); -   +    /* Print blanks on first row if appropriate */    aligned = _DBUS_ALIGN_ADDRESS (data, 4);    if (aligned > data) @@ -2529,7 +760,7 @@ _dbus_verbose_bytes (const unsigned char *data,    if (aligned != data)      { -      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);  +      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);        while (aligned != data)          {            _dbus_verbose ("    "); @@ -2546,7 +777,7 @@ _dbus_verbose_bytes (const unsigned char *data,            _dbus_verbose ("%4d\t%p: ",                           offset + i, &data[i]);          } -       +        if (data[i] >= 32 &&            data[i] <= 126)          _dbus_verbose (" '%c' ", data[i]); @@ -2563,13 +794,13 @@ _dbus_verbose_bytes (const unsigned char *data,                             _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),                             _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); -          if (i > 7 &&  +          if (i > 7 &&                _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])              {                _dbus_verbose (" dbl: %g",                               *(double*)&data[i-8]);              } -           +            _dbus_verbose ("\n");          }      } @@ -2595,7 +826,7 @@ _dbus_verbose_bytes_of_string (const DBusString    *str,    real_len = _dbus_string_get_length (str);    _dbus_assert (start >= 0); -   +    if (start > real_len)      {        _dbus_verbose ("  [%d,%d) is not inside string of length %d\n", @@ -2609,12 +840,164 @@ _dbus_verbose_bytes_of_string (const DBusString    *str,                       start, len, real_len);        len = real_len - start;      } -   +    d = _dbus_string_get_const_data_len (str, start, len);    _dbus_verbose_bytes (d, len, start);  } +static dbus_bool_t +marshal_4_octets (DBusString   *str, +                  int           insert_at, +                  dbus_uint32_t value, +                  int           byte_order, +                  int          *pos_after) +{ +  dbus_bool_t retval; +  int orig_len; + +  _dbus_assert (sizeof (value) == 4); + +  if (byte_order != DBUS_COMPILER_BYTE_ORDER) +    value = DBUS_UINT32_SWAP_LE_BE (value); + +  orig_len = _dbus_string_get_length (str); + +  retval = _dbus_string_insert_4_aligned (str, insert_at, +                                          (const unsigned char *)&value); + +  if (pos_after) +    { +      *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); +      _dbus_assert (*pos_after <= _dbus_string_get_length (str)); +    } + +  return retval; +} + +static dbus_bool_t +marshal_8_octets (DBusString *str, +                  int         insert_at, +                  DBusOctets8 value, +                  int         byte_order, +                  int        *pos_after) +{ +  dbus_bool_t retval; +  int orig_len; + +  _dbus_assert (sizeof (value) == 8); + +  swap_8_octets (&value, byte_order); + +  orig_len = _dbus_string_get_length (str); + +  retval = _dbus_string_insert_8_aligned (str, insert_at, +                                          (const unsigned char *)&value); + +  if (pos_after) +    *pos_after = insert_at + _dbus_string_get_length (str) - orig_len; + +  return retval; +} + +enum +  { +    MARSHAL_AS_STRING, +    MARSHAL_AS_SIGNATURE, +    MARSHAL_AS_BYTE_ARRAY +  }; + +static dbus_bool_t +marshal_len_followed_by_bytes (int                  marshal_as, +                               DBusString          *str, +                               int                  insert_at, +                               const unsigned char *value, +                               int                  data_len, /* doesn't include nul if any */ +                               int                  byte_order, +                               int                 *pos_after) +{ +  int pos; +  DBusString value_str; +  int value_len; + +  if (marshal_as == MARSHAL_AS_BYTE_ARRAY) +    value_len = data_len; +  else +    value_len = data_len + 1; /* value has a nul */ + +  /* FIXME this is probably broken for byte arrays because +   * DBusString wants strings to be nul-terminated? +   * Maybe I planned on this when writing init_const_len though +   */ +  _dbus_string_init_const_len (&value_str, value, value_len); + +  pos = insert_at; + +  if (marshal_as == MARSHAL_AS_SIGNATURE) +    { +      if (!_dbus_string_insert_byte (str, pos, data_len)) +        goto oom; + +      pos += 1; +    } +  else +    { +      if (!marshal_4_octets (str, pos, data_len, +                             byte_order, &pos)) +        goto oom; +    } + +  if (!_dbus_string_copy_len (&value_str, 0, value_len, +                              str, pos)) +    goto oom; + +#if 1 +  /* too expensive */ +  _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len, +                                              str, pos)); +  _dbus_verbose_bytes_of_string (str, pos, value_len); +#endif + +  pos += value_len; + +  if (pos_after) +    *pos_after = pos; + +  return TRUE; + + oom: +  /* Delete what we've inserted */ +  _dbus_string_delete (str, insert_at, pos - insert_at); + +  return FALSE; +} + +static dbus_bool_t +marshal_string (DBusString    *str, +                int            insert_at, +                const char    *value, +                int            byte_order, +                int           *pos_after) +{ +  return marshal_len_followed_by_bytes (MARSHAL_AS_STRING, +                                        str, insert_at, value, +                                        strlen (value), +                                        byte_order, pos_after); +} + +static dbus_bool_t +marshal_signature (DBusString    *str, +                   int            insert_at, +                   const char    *value, +                   int           *pos_after) +{ +  return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE, +                                        str, insert_at, value, +                                        strlen (value), +                                        DBUS_COMPILER_BYTE_ORDER, /* irrelevant */ +                                        pos_after); +} +  /**   * Marshals a basic type   * @@ -2623,6 +1006,7 @@ _dbus_verbose_bytes_of_string (const DBusString    *str,   * @param type type of value   * @param value pointer to value   * @param byte_order byte order + * @param pos_after #NULL or the position after the type   * @returns #TRUE on success   **/  dbus_bool_t @@ -2630,19 +1014,23 @@ _dbus_marshal_basic_type (DBusString *str,                            int         insert_at,  			  char        type,  			  const void *value, -			  int         byte_order) +			  int         byte_order, +                          int        *pos_after)  { -  dbus_bool_t retval; -    switch (type)      {      case DBUS_TYPE_BYTE:      case DBUS_TYPE_BOOLEAN: -      retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value); +      if (!_dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value)) +        return FALSE; +      if (pos_after) +        *pos_after = insert_at + 1; +      return TRUE;        break;      case DBUS_TYPE_INT32:      case DBUS_TYPE_UINT32: -      return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value); +      return marshal_4_octets (str, insert_at, *(const dbus_uint32_t *)value, +                               byte_order, pos_after);        break;  #ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64: @@ -2650,7 +1038,7 @@ _dbus_marshal_basic_type (DBusString *str,        {          DBusOctets8 r;          r.u = *(const dbus_uint64_t *)value; -        retval = marshal_8_octets (str, insert_at, byte_order, r); +        return marshal_8_octets (str, insert_at, r, byte_order, pos_after);        }        break;  #endif /* DBUS_HAVE_INT64 */ @@ -2658,22 +1046,142 @@ _dbus_marshal_basic_type (DBusString *str,        {          DBusOctets8 r;          r.d = *(const double *)value; -        retval = marshal_8_octets (str, insert_at, byte_order, r); +        return marshal_8_octets (str, insert_at, r, byte_order, pos_after);        }        break;      case DBUS_TYPE_STRING:      case DBUS_TYPE_OBJECT_PATH: -      retval = _dbus_marshal_string (str, byte_order, (const char*) value); +      return marshal_string (str, insert_at, (const char*) value, byte_order, pos_after);        break;      case DBUS_TYPE_SIGNATURE: -      retval = _dbus_marshal_signature (str, (const char*) value); +      return marshal_signature (str, insert_at, (const char*) value, pos_after);        break;      default:        _dbus_assert_not_reached ("not a basic type"); -      retval = FALSE; +      return FALSE;        break;      } -  return retval; +} + +static dbus_bool_t +marshal_1_octets_array (DBusString          *str, +                        int                  insert_at, +                        const unsigned char *value, +                        int                  len, +                        int                  byte_order, +                        int                 *pos_after) +{ +  return marshal_len_followed_by_bytes (MARSHAL_AS_BYTE_ARRAY, +                                        str, insert_at, value, len, +                                        byte_order, pos_after); +} + +static dbus_bool_t +marshal_4_octets_array (DBusString          *str, +                        int                  insert_at, +                        const dbus_uint32_t *value, +                        int                  len, +                        int                  byte_order) +{ +  int old_string_len; +  int array_start; + +  _dbus_assert_not_reached ("FIXME insert_at"); + +  old_string_len = _dbus_string_get_length (str); + +  if (!marshal_4_octets (str, insert_at, len*4, byte_order, NULL)) +    goto error; + +  array_start = _dbus_string_get_length (str); + +  if (!_dbus_string_append_len (str, (const unsigned char*) value, +                                len * 4)) +    goto error; + +  if (byte_order != DBUS_COMPILER_BYTE_ORDER) +    { +      const unsigned char *d; +      const unsigned char *end; + +      d = _dbus_string_get_data (str) + array_start; +      end = d + len * 4; +      while (d != end) +        { +          *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d)); +          d += 4; +        } +    } + +  return TRUE; + + error: +  /* Restore previous length */ +  _dbus_string_set_length (str, old_string_len); + +  return FALSE; +} + +static dbus_bool_t +marshal_8_octets_array (DBusString          *str, +                        int                  insert_at, +                        const DBusOctets8   *value, +                        int                  len, +                        int                  byte_order) +{ +  int old_string_len; +  int array_start; + +  _dbus_assert_not_reached ("FIXME insert_at"); + +  old_string_len = _dbus_string_get_length (str); + +  /*  The array length is the length in bytes of the array, +   * *excluding* alignment padding. +   */ +  if (!marshal_4_octets (str, insert_at, len*8, byte_order, NULL)) +    goto error; + +  array_start = _dbus_string_get_length (str); + +  /* Note that we do alignment padding unconditionally +   * even if the array is empty; this means that +   * padding + len is always equal to the number of bytes +   * in the array. +   */ + +  if (!_dbus_string_align_length (str, 8)) +    goto error; + +  if (!_dbus_string_append_len (str, (const unsigned char*) value, +                                len * 8)) +    goto error; + +  if (byte_order != DBUS_COMPILER_BYTE_ORDER) +    { +      const unsigned char *d; +      const unsigned char *end; + +      d = _dbus_string_get_data (str) + array_start; +      end = d + len * 8; +      while (d != end) +        { +#ifdef DBUS_HAVE_INT64 +          *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d)); +#else +          swap_bytes ((unsigned char*) d, 8); +#endif +          d += 8; +        } +    } + +  return TRUE; + + error: +  /* Restore previous length */ +  _dbus_string_set_length (str, old_string_len); + +  return FALSE;  }  /** @@ -2685,6 +1193,7 @@ _dbus_marshal_basic_type (DBusString *str,   * @param value pointer to value   * @param len length of value data in elements   * @param byte_order byte order + * @param pos_after #NULL or the position after the type   * @returns #TRUE on success   **/  dbus_bool_t @@ -2693,33 +1202,45 @@ _dbus_marshal_basic_type_array (DBusString *str,  				char        element_type,  				const void *value,  				int         len, -				int         byte_order) +				int         byte_order, +                                int        *pos_after)  { -  /* FIXME use the insert_at arg */ -   +  /* FIXME use the insert_at arg and fill in pos_after */ +    switch (element_type)      {      case DBUS_TYPE_BOOLEAN: -      /* FIXME: we canonicalize to 0 or 1 for the single boolean case  +      /* 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); +      return marshal_1_octets_array (str, insert_at, value, len, byte_order, pos_after);        break;      case DBUS_TYPE_INT32:      case DBUS_TYPE_UINT32: -      return marshal_4_octets_array (str, byte_order, value, len); +      return marshal_4_octets_array (str, insert_at, value, len, byte_order);        break;  #ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64:  +    case DBUS_TYPE_UINT64:  #endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE: -      return marshal_8_octets_array (str, byte_order, value, len); +      return marshal_8_octets_array (str, insert_at, value, len, byte_order); +      break; + +    case DBUS_TYPE_STRING: +    case DBUS_TYPE_OBJECT_PATH: +      _dbus_assert_not_reached ("handle string arrays"); +      break; + +    case DBUS_TYPE_SIGNATURE: +      _dbus_assert_not_reached ("handle signature");        break; +      default:        _dbus_assert_not_reached ("non basic type in array");        break;      } +    return FALSE;  } @@ -2729,118 +1250,144 @@ _dbus_marshal_basic_type_array (DBusString *str,  #include "dbus-test.h"  #include <stdio.h> +#define MARSHAL_BASIC(typename, byte_order, literal)                    \ +  do {                                                                  \ +     v_##typename = literal;                                            \ +     if (!_dbus_marshal_basic_type (&str, pos, DBUS_TYPE_##typename,    \ +                                    &v_##typename,                      \ +                                    byte_order, NULL))                  \ +       _dbus_assert_not_reached ("no memory");                          \ +   } while (0) + +#define DEMARSHAL_BASIC(typename, byte_order)                                   \ +  do {                                                                          \ +    _dbus_demarshal_basic_type (&str, DBUS_TYPE_##typename, &v_##typename,      \ +                                byte_order, pos, &pos);                         \ +  } while (0) + +#define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \ +  do {                                                                                  \ +    DEMARSHAL_BASIC (typename, byte_order);                                             \ +    if (literal != v_##typename)                                                        \ +      {                                                                                 \ +        _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \ +                                     _dbus_string_get_length (&str) - dump_pos);        \ +        _dbus_assert_not_reached ("demarshaled wrong value");                           \ +      }                                                                                 \ +  } while (0) + +#define MARSHAL_TEST(typename, byte_order, literal)             \ +  do {                                                          \ +    MARSHAL_BASIC (typename, byte_order, literal);              \ +    dump_pos = pos;                                             \ +    DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal);  \ +  } while (0) + +#define MARSHAL_TEST_STRCMP(typename, byte_order, literal)                              \ +  do {                                                                                  \ +    if (!_dbus_marshal_basic_type (&str, pos, DBUS_TYPE_##typename,                     \ +                                   literal,                                             \ +                                   byte_order, NULL))                                   \ +       _dbus_assert_not_reached ("no memory");                                          \ +    dump_pos = pos;                                                                     \ +    DEMARSHAL_BASIC (typename, byte_order);                                             \ +    if (strcmp (literal, v_##typename) != 0)                                            \ +      {                                                                                 \ +        _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \ +                                       _dbus_string_get_length (&str) - dump_pos);      \ +        _dbus_warn ("literal '%s'\nvalue  '%s'\n", literal, v_##typename);              \ +        _dbus_assert_not_reached ("demarshaled wrong value");                           \ +      }                                                                                 \ +  } while (0) +  dbus_bool_t  _dbus_marshal_test (void)  {    DBusString str; -  char *tmp1, *tmp2; -  int pos = 0, len; +  int pos, dump_pos; +#if 0    dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;  #ifdef DBUS_HAVE_INT64 -  dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),  -                             DBUS_INT64_CONSTANT (0x456ffffffff),  +  dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), +                             DBUS_INT64_CONSTANT (0x456ffffffff),                               DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;  #endif -  char *s; +#endif    DBusString t; -   +  double v_DOUBLE; +  double t_DOUBLE; +  dbus_int32_t v_INT32; +  dbus_uint32_t v_UINT32; +  dbus_int64_t v_INT64; +  dbus_uint64_t v_UINT64; +  unsigned char v_BYTE; +  unsigned char v_BOOLEAN; +  const char *v_STRING; +  const char *v_SIGNATURE; +  const char *v_OBJECT_PATH; +  int byte_order; +    if (!_dbus_string_init (&str))      _dbus_assert_not_reached ("failed to init string"); +  pos = 0; +    /* Marshal doubles */ -  if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14)) -    _dbus_assert_not_reached ("could not marshal double value"); -  if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14) -    _dbus_assert_not_reached ("demarshal failed"); - -  if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14)) -    _dbus_assert_not_reached ("could not marshal double value"); -  if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14) -    _dbus_assert_not_reached ("demarshal failed"); -   +  MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14); +  DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN); +  t_DOUBLE = 3.14; +  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) +    _dbus_assert_not_reached ("got wrong double value"); + +  MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14); +  DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN); +  t_DOUBLE = 3.14; +  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) +    _dbus_assert_not_reached ("got wrong double value"); +    /* Marshal signed integers */ -  if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678)) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678) -    _dbus_assert_not_reached ("demarshal failed"); - -  if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678)) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678) -    _dbus_assert_not_reached ("demarshal failed"); -   +  MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678); +  MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678); +    /* Marshal unsigned integers */ -  if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678)) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678) -    _dbus_assert_not_reached ("demarshal failed"); -   -  if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678)) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678) -    _dbus_assert_not_reached ("demarshal failed"); +  MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678); +  MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);  #ifdef DBUS_HAVE_INT64    /* Marshal signed integers */ -  if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7))) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7)) -    _dbus_assert_not_reached ("demarshal failed"); - -  if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7))) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7)) -    _dbus_assert_not_reached ("demarshal failed"); -   +  MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); +  MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); +    /* Marshal unsigned integers */ -  if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7))) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7))) -    _dbus_assert_not_reached ("demarshal failed"); -   -  if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7))) -    _dbus_assert_not_reached ("could not marshal signed integer value"); -  if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7))) -    _dbus_assert_not_reached ("demarshal failed"); +  MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); +  MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));  #endif /* DBUS_HAVE_INT64 */ -   + +  /* Marshal byte */ +  MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5); +  MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5); + +  /* Marshal all possible bools! */ +  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE); +  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE); +  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE); +  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE); +    /* Marshal strings */ -  tmp1 = "This is the dbus test string"; -  if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1)) -    _dbus_assert_not_reached ("could not marshal string"); -  tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos); -  if (!strcmp (tmp1, tmp2) == 0) -    _dbus_assert_not_reached ("demarshal failed"); -  dbus_free (tmp2); - -  tmp1 = "This is the dbus test string"; -  if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1)) -    _dbus_assert_not_reached ("could not marshal string"); -  tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos); -  if (!strcmp (tmp1, tmp2) == 0) -    _dbus_assert_not_reached ("demarshal failed"); -  dbus_free (tmp2); - -  /* Marshal signed integer arrays */ -  if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3)) -    _dbus_assert_not_reached ("could not marshal integer array"); -  if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len)) -    _dbus_assert_not_reached ("could not demarshal integer array"); - -  if (len != 3) -    _dbus_assert_not_reached ("Signed integer array lengths differ!\n"); -  dbus_free (array2); +  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, ""); +  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, ""); +  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string"); +  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string"); -#ifdef DBUS_HAVE_INT64 -  /* Marshal 64-bit signed integer arrays */ -  if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3)) -    _dbus_assert_not_reached ("could not marshal integer array"); -  if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len)) -    _dbus_assert_not_reached ("could not demarshal integer array"); +  /* object paths */ +  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c"); +  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c"); -  if (len != 3) -    _dbus_assert_not_reached ("Signed integer array lengths differ!\n"); -  dbus_free (array4); +  /* signatures */ +  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, ""); +  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, ""); +  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)"); +  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");    /* set/pack 64-bit integers */    _dbus_string_set_length (&str, 8); @@ -2848,7 +1395,7 @@ _dbus_marshal_test (void)    /* signed little */    _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,                             0, DBUS_INT64_CONSTANT (-0x123456789abc7)); -   +    _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==                  _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,                                      _dbus_string_get_const_data (&str))); @@ -2865,7 +1412,7 @@ _dbus_marshal_test (void)    _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),                      DBUS_LITTLE_ENDIAN,                      _dbus_string_get_data (&str)); -   +    _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==                  _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,                                      _dbus_string_get_const_data (&str))); @@ -2882,7 +1429,7 @@ _dbus_marshal_test (void)    /* unsigned little */    _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,                              0, DBUS_UINT64_CONSTANT (0x123456789abc7)); -   +    _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==                  _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,                                       _dbus_string_get_const_data (&str))); @@ -2899,7 +1446,7 @@ _dbus_marshal_test (void)    _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),                       DBUS_LITTLE_ENDIAN,                       _dbus_string_get_data (&str)); -   +    _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==                  _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,                                       _dbus_string_get_const_data (&str))); @@ -2912,8 +1459,6 @@ _dbus_marshal_test (void)    _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==                  _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,                                       _dbus_string_get_const_data (&str))); -   -#endif    /* set/pack 32-bit integers */    _dbus_string_set_length (&str, 4); @@ -2921,7 +1466,7 @@ _dbus_marshal_test (void)    /* signed little */    _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,                             0, -0x123456); -   +    _dbus_assert (-0x123456 ==                  _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,                                      _dbus_string_get_const_data (&str))); @@ -2938,7 +1483,7 @@ _dbus_marshal_test (void)    _dbus_pack_int32 (-0x123456,                      DBUS_LITTLE_ENDIAN,                      _dbus_string_get_data (&str)); -   +    _dbus_assert (-0x123456 ==                  _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,                                      _dbus_string_get_const_data (&str))); @@ -2955,7 +1500,7 @@ _dbus_marshal_test (void)    /* unsigned little */    _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,                              0, 0x123456); -   +    _dbus_assert (0x123456 ==                  _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,                                       _dbus_string_get_const_data (&str))); @@ -2972,7 +1517,7 @@ _dbus_marshal_test (void)    _dbus_pack_uint32 (0x123456,                       DBUS_LITTLE_ENDIAN,                       _dbus_string_get_data (&str)); -   +    _dbus_assert (0x123456 ==                  _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,                                       _dbus_string_get_const_data (&str))); @@ -2986,67 +1531,49 @@ _dbus_marshal_test (void)                  _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,                                       _dbus_string_get_const_data (&str))); +  /* Strings in-place set */ +  byte_order = DBUS_LITTLE_ENDIAN; +  while (TRUE) +    { +      /* Init a string */ +      _dbus_string_set_length (&str, 0); + +      /* reset pos for the macros */ +      pos = 0; + +      MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world"); + +      /* Set it to something longer */ +      _dbus_string_init_const (&t, "Hello world foo"); -  /* Strings */ -   -  _dbus_string_set_length (&str, 0); - -  _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, -                        "Hello world"); -   -  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello world") == 0); -  dbus_free (s); - -  _dbus_string_init_const (&t, "Hello world foo"); -   -  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0, -                            &t, _dbus_string_get_length (&t)); -   -  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello world foo") == 0); -  dbus_free (s); - -  _dbus_string_init_const (&t, "Hello"); -   -  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0, -                            &t, _dbus_string_get_length (&t)); -   -  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello") == 0); -  dbus_free (s); - -  /* Strings (big endian) */ -   -  _dbus_string_set_length (&str, 0); - -  _dbus_marshal_string (&str, DBUS_BIG_ENDIAN, -                        "Hello world"); -   -  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello world") == 0); -  dbus_free (s); - -  _dbus_string_init_const (&t, "Hello world foo"); -   -  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0, -                            &t, _dbus_string_get_length (&t)); -   -  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello world foo") == 0); -  dbus_free (s); - -  _dbus_string_init_const (&t, "Hello"); -   -  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0, -                            &t, _dbus_string_get_length (&t)); -   -  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL); -  _dbus_assert (strcmp (s, "Hello") == 0); -  dbus_free (s); -   +      _dbus_marshal_set_string (&str, byte_order, 0, +                                &t, _dbus_string_get_length (&t)); + +      _dbus_demarshal_basic_type (&str, DBUS_TYPE_STRING, +                                  &v_STRING, byte_order, +                                  0, NULL); +      _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0); + +      /* Set it to something shorter */ +      _dbus_string_init_const (&t, "Hello"); + +      _dbus_marshal_set_string (&str, byte_order, 0, +                                &t, _dbus_string_get_length (&t)); +      _dbus_demarshal_basic_type (&str, DBUS_TYPE_STRING, +                                  &v_STRING, byte_order, +                                  0, NULL); +      _dbus_assert (strcmp (v_STRING, "Hello") == 0); + +      /* Do the other byte order */ +      if (byte_order == DBUS_LITTLE_ENDIAN) +        byte_order = DBUS_BIG_ENDIAN; +      else +        break; +    } + +  /* Clean up */    _dbus_string_free (&str); -       +    return TRUE;  } diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h index df3794d1..992e6764 100644 --- a/dbus/dbus-marshal-basic.h +++ b/dbus/dbus-marshal-basic.h @@ -5,7 +5,7 @@   * Copyright (C) 2004  Red Hat, Inc.   *   * Licensed under the Academic Free License version 2.1 - *  + *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by   * the Free Software Foundation; either version 2 of the License, or @@ -15,7 +15,7 @@   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details. - *  + *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA @@ -232,6 +232,7 @@ void          _dbus_pack_uint32   (dbus_uint32_t        value,                                     unsigned char       *data);  dbus_uint32_t _dbus_unpack_uint32 (int                  byte_order,                                     const unsigned char *data); +  #ifdef DBUS_HAVE_INT64  void          _dbus_pack_int64    (dbus_int64_t         value,                                     int                  byte_order, @@ -264,205 +265,43 @@ void        _dbus_marshal_set_uint64 (DBusString       *str,                                        dbus_uint64_t     value);  #endif /* DBUS_HAVE_INT64 */ -dbus_bool_t _dbus_marshal_set_string      (DBusString         *str, -                                           int                 byte_order, -                                           int                 offset, -                                           const DBusString   *value, -                                           int                 len); -void        _dbus_marshal_set_object_path (DBusString         *str, -                                           int                 byte_order, -                                           int                 offset, -                                           const char        **path, -                                           int                 path_len); - -dbus_bool_t   _dbus_marshal_int32          (DBusString            *str, -					    int                    byte_order, -					    dbus_int32_t           value); -dbus_bool_t   _dbus_marshal_uint32         (DBusString            *str, -					    int                    byte_order, -					    dbus_uint32_t          value); - -#ifdef DBUS_HAVE_INT64 -dbus_bool_t   _dbus_marshal_int64          (DBusString            *str, -					    int                    byte_order, -					    dbus_int64_t           value); -dbus_bool_t   _dbus_marshal_uint64         (DBusString            *str, -					    int                    byte_order, -					    dbus_uint64_t          value); -#endif /* DBUS_HAVE_INT64 */ -dbus_bool_t   _dbus_marshal_double         (DBusString            *str, -					    int                    byte_order, -					    double                 value); - -dbus_bool_t   _dbus_marshal_string         (DBusString            *str, -					    int                    byte_order, -					    const char            *value); -dbus_bool_t   _dbus_marshal_string_len     (DBusString            *str, -					    int                    byte_order, -					    const char            *value, -                                            int                    len); - -dbus_bool_t   _dbus_marshal_basic_type     (DBusString            *str, -                                            int                    insert_at, -					    char                   type, -					    const void            *value, -					    int                    byte_order); -dbus_bool_t   _dbus_marshal_basic_type_array (DBusString            *str, -                                              int                    insert_at, -					      char                   element_type, -					      const void	    *value, -					      int                    len, -					      int                    byte_order); -dbus_bool_t   _dbus_marshal_byte_array     (DBusString            *str, -					    int                    byte_order, -					    const unsigned char   *value, -					    int                    len); -dbus_bool_t   _dbus_marshal_int32_array    (DBusString            *str, -					    int                    byte_order, -					    const dbus_int32_t    *value, -					    int                    len); -dbus_bool_t   _dbus_marshal_uint32_array   (DBusString            *str, -					    int                    byte_order, -					    const dbus_uint32_t   *value, -					    int                    len); -#ifdef DBUS_HAVE_INT64 -dbus_bool_t   _dbus_marshal_int64_array    (DBusString            *str, -					    int                    byte_order, -					    const dbus_int64_t    *value, -					    int                    len); -dbus_bool_t   _dbus_marshal_uint64_array   (DBusString            *str, -					    int                    byte_order, -					    const dbus_uint64_t   *value, -					    int                    len); -#endif /* DBUS_HAVE_INT64 */ -dbus_bool_t   _dbus_marshal_double_array   (DBusString            *str, -					    int                    byte_order, -					    const double          *value, -					    int                    len); -dbus_bool_t   _dbus_marshal_string_array   (DBusString            *str, -					    int                    byte_order, -					    const char           **value, -					    int                    len); -double        _dbus_demarshal_double       (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos); -dbus_int32_t  _dbus_demarshal_int32        (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos); -dbus_uint32_t _dbus_demarshal_uint32       (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos); -#ifdef DBUS_HAVE_INT64 -dbus_int64_t  _dbus_demarshal_int64        (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos); -dbus_uint64_t _dbus_demarshal_uint64       (const DBusString      *str, -					    int                    byte_order, -					    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, -					    int                   *new_pos); -dbus_bool_t   _dbus_demarshal_byte_array   (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos, -					    unsigned char        **array, -					    int                   *array_len); -dbus_bool_t   _dbus_demarshal_int32_array  (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos, -					    dbus_int32_t         **array, -					    int                   *array_len); -dbus_bool_t   _dbus_demarshal_uint32_array (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos, -					    dbus_uint32_t        **array, -					    int                   *array_len); -#ifdef DBUS_HAVE_INT64 -dbus_bool_t   _dbus_demarshal_int64_array  (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos, -					    dbus_int64_t         **array, -					    int                   *array_len); -dbus_bool_t   _dbus_demarshal_uint64_array (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    int                   *new_pos, -					    dbus_uint64_t        **array, -					    int                   *array_len); -#endif /* DBUS_HAVE_INT64 */ -dbus_bool_t   _dbus_demarshal_double_array (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -					    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, -					    int                   *new_pos, -					    char                ***array, -					    int                   *array_len); -dbus_bool_t   _dbus_decompose_path         (const char*            data, -					    int                    len, -					    char                ***path, -					    int                   *path_len); -dbus_bool_t   _dbus_demarshal_object_path  (const DBusString      *str, -					    int                    byte_order, -					    int                    pos, -                                            int                   *new_pos, -                                            char                ***path, -                                            int                   *path_len); - -void         _dbus_marshal_skip_basic_type (const DBusString      *str, -                                            int                    type, -                                            int                    byte_order, -					    int                   *pos); -void         _dbus_marshal_skip_array      (const DBusString      *str, -                                            int                    byte_order, -					    int                   *pos); - -dbus_bool_t _dbus_marshal_get_arg_end_pos (const DBusString *str, -                                           int               byte_order, -					   int               type, -                                           int               pos, -                                           int              *end_pos); -dbus_bool_t _dbus_marshal_validate_type   (const DBusString *str, -                                           int               pos, -					   int              *type, -                                           int              *end_pos); -dbus_bool_t _dbus_marshal_validate_arg    (const DBusString *str, -                                           int               depth, -                                           int               byte_order, -					   int               type, -					   int               array_type_pos, -                                           int               pos, -                                           int              *end_pos); - -dbus_bool_t _dbus_type_is_valid           (int               typecode); - -int         _dbus_type_get_alignment      (int               typecode); +dbus_bool_t   _dbus_marshal_set_string       (DBusString       *str, +                                              int               byte_order, +                                              int               offset, +                                              const DBusString *value, +                                              int               len); +dbus_bool_t   _dbus_marshal_basic_type       (DBusString       *str, +                                              int               insert_at, +                                              char              type, +                                              const void       *value, +                                              int               byte_order, +                                              int              *pos_after); +dbus_bool_t   _dbus_marshal_basic_type_array (DBusString       *str, +                                              int               insert_at, +                                              char              element_type, +                                              const void       *value, +                                              int               len, +                                              int               byte_order, +                                              int              *pos_after); +dbus_uint32_t _dbus_demarshal_uint32         (const DBusString *str, +                                              int               byte_order, +                                              int               pos, +                                              int              *new_pos); +void          _dbus_demarshal_basic_type     (const DBusString *str, +                                              int               type, +                                              void             *value, +                                              int               byte_order, +                                              int               pos, +                                              int              *new_pos); +void          _dbus_marshal_skip_basic_type  (const DBusString *str, +                                              int               type, +                                              int               byte_order, +                                              int              *pos); +void          _dbus_marshal_skip_array       (const DBusString *str, +                                              int               byte_order, +                                              int               element_type, +                                              int              *pos); +dbus_bool_t   _dbus_type_is_valid            (int               typecode); +int           _dbus_type_get_alignment       (int               typecode);  #endif /* DBUS_MARSHAL_H */ diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index bce6e533..0bf59ed1 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -22,6 +22,7 @@   */  #include "dbus-marshal-recursive.h" +#include "dbus-marshal-basic.h"  #include "dbus-internals.h"  /** @@ -147,6 +148,7 @@ array_reader_recurse (DBusTypeReader *sub,                                DBUS_TYPE_UINT32,                                &array_len,                                sub->byte_order, +                              sub->value_pos,                                &sub->value_pos);    sub->u.array.len = array_len; @@ -291,31 +293,6 @@ skip_one_complete_type (const DBusString *type_str,  }  static void -skip_array_values (int               element_type, -                   const DBusString *value_str, -                   int              *value_pos, -                   int               byte_order) -{ -  dbus_uint32_t array_len; -  int pos; -  int alignment; - -  pos = _DBUS_ALIGN_VALUE (*value_pos, 4); - -  _dbus_demarshal_basic_type (value_str, -                              DBUS_TYPE_UINT32, -                              &array_len, -                              byte_order, -                              &pos); - -  alignment = _dbus_type_get_alignment (element_type); - -  pos = _DBUS_ALIGN_VALUE (pos, alignment); - -  *value_pos = pos + array_len; -} - -static void  base_reader_next (DBusTypeReader *reader,                    int             current_type)  { @@ -354,9 +331,10 @@ base_reader_next (DBusTypeReader *reader,      case DBUS_TYPE_ARRAY:        {          if (!reader->klass->types_only) -          skip_array_values (first_type_in_signature (reader->type_str, -                                                      reader->type_pos + 1), -                             reader->value_str, &reader->value_pos, reader->byte_order); +          _dbus_marshal_skip_array (reader->value_str, reader->byte_order, +                                    first_type_in_signature (reader->type_str, +                                                             reader->type_pos + 1), +                                    &reader->value_pos);          skip_one_complete_type (reader->type_str, &reader->type_pos);        } @@ -441,9 +419,10 @@ array_reader_next (DBusTypeReader *reader,      case DBUS_TYPE_ARRAY:        { -        skip_array_values (first_type_in_signature (reader->type_str, -                                                    reader->type_pos + 1), -                           reader->value_str, &reader->value_pos, reader->byte_order); +        _dbus_marshal_skip_array (reader->value_str, reader->byte_order, +                                  first_type_in_signature (reader->type_str, +                                                           reader->type_pos + 1), +                                  &reader->value_pos);        }        break; @@ -581,18 +560,20 @@ dbus_bool_t  _dbus_type_reader_array_is_empty (DBusTypeReader *reader)  {    dbus_uint32_t array_len; -  int len_pos;    _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY);    _dbus_assert (!reader->klass->types_only); -  len_pos = _DBUS_ALIGN_VALUE (reader->value_pos, 4); +  /* reader is supposed to be at an array child */ +  _dbus_verbose ("checking array len at %d\n", reader->value_pos);    _dbus_demarshal_basic_type (reader->value_str,                                DBUS_TYPE_UINT32,                                &array_len,                                reader->byte_order, -                              &len_pos); +                              reader->value_pos, +                              NULL); +  _dbus_verbose (" ... array len = %d\n", array_len);    return array_len == 0;  } @@ -602,22 +583,20 @@ _dbus_type_reader_read_basic (DBusTypeReader    *reader,                                void              *value)  {    int t; -  int next;    _dbus_assert (!reader->klass->types_only);    t = _dbus_type_reader_get_current_type (reader); -  next = reader->value_pos;    _dbus_demarshal_basic_type (reader->value_str,                                t, value,                                reader->byte_order, -                              &next); +                              reader->value_pos, NULL);  #if RECURSIVE_MARSHAL_TRACE -  _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n", -                 reader, reader->type_pos, reader->value_pos, next, +  _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d remaining sig '%s'\n", +                 reader, reader->type_pos, reader->value_pos,                   _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));  #endif  } @@ -765,23 +744,12 @@ _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,                                             int             type,                                             const void     *value)  { -  int old_value_len; -  int bytes_written; - -  old_value_len = _dbus_string_get_length (writer->value_str); - -  if (!_dbus_marshal_basic_type (writer->value_str, -                                 writer->value_pos, -                                 type, -                                 value, -                                 writer->byte_order)) -    return FALSE; - -  bytes_written = _dbus_string_get_length (writer->value_str) - old_value_len; - -  writer->value_pos += bytes_written; - -  return TRUE; +  return _dbus_marshal_basic_type (writer->value_str, +                                   writer->value_pos, +                                   type, +                                   value, +                                   writer->byte_order, +                                   &writer->value_pos);  }  /* If our parent is an array, things are a little bit complicated. @@ -1037,8 +1005,9 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,    _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);  #if RECURSIVE_MARSHAL_TRACE -  _dbus_verbose ("  type writer %p recurse array done remaining sig '%s'\n", sub, -                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0)); +  _dbus_verbose ("  type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d\n", sub, +                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0), +                 sub->u.array.start_pos, sub->u.array.len_pos);  #endif    return TRUE; @@ -1928,7 +1897,9 @@ run_test_nodes_iteration (void *data)        ++i;      } -  /* FIXME type-iterate both signature and value */ +  /* FIXME type-iterate both signature and value and compare the resulting +   * tree to the node tree +   */    return TRUE;  } @@ -2382,9 +2353,12 @@ _dbus_marshal_recursive_test (void)  }  #if 1 +dbus_bool_t _dbus_marshal_test (void);  int  main (int argc, char **argv)  { +  _dbus_marshal_test (); +    _dbus_marshal_recursive_test ();    return 0; @@ -2692,11 +2666,6 @@ double_write_value (TestTypeNode   *node,                                          &v);  } -/* Maybe this macro should be in a real header, - * depends on why it's needed which I don't understand yet - */ -#define DOUBLES_BITWISE_EQUAL(a, b) \ -  (memcmp ((char*)&(a), (char*)&(b), 8) == 0)  static dbus_bool_t  double_read_value (TestTypeNode   *node,                     DataBlock      *block, @@ -2713,7 +2682,7 @@ double_read_value (TestTypeNode   *node,    expected = double_from_seed (seed); -  if (!DOUBLES_BITWISE_EQUAL (v, expected)) +  if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))      {  #ifdef DBUS_HAVE_INT64        _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n", @@ -2748,7 +2717,7 @@ object_path_from_seed (char *buf,        ++i;        buf[i] = v;        ++i; -       +        v += 1;      } @@ -2813,7 +2782,7 @@ signature_from_seed (char *buf,    };    s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]; -   +    for (i = 0; s[i]; i++)      {        buf[i] = s[i]; diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h index 08df130a..f8384478 100644 --- a/dbus/dbus-marshal-recursive.h +++ b/dbus/dbus-marshal-recursive.h @@ -4,7 +4,7 @@   * Copyright (C) 2004 Red Hat, Inc.   *   * Licensed under the Academic Free License version 2.1 - *  + *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by   * the Free Software Foundation; either version 2 of the License, or @@ -14,7 +14,7 @@   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details. - *  + *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA @@ -25,12 +25,25 @@  #define DBUS_MARSHAL_RECURSIVE_H  #include <config.h> -#include <dbus/dbus-marshal-basic.h> +#include <dbus/dbus-marshal-basic.h> /* this can become protocol.h when we merge */  #ifndef PACKAGE  #error "config.h not included here"  #endif +/* Features we need to port dbus-message: + *  - memoize a position of a reader for small/fast access later + *  - delete an array element and re-align the remainder of the array + *    (not necessary yet to re-align remainder of entire string, + *     though that's probably just as hard/easy) + *  - set string, int, etc. values at a memoized position + *    (implement generic set of any value? changes only + *     value_str not type_str) + *  - implement has_next() + *  - the all-in-one-block array accessors + *  - validation + */ +  typedef struct DBusTypeReader      DBusTypeReader;  typedef struct DBusTypeWriter      DBusTypeWriter;  typedef struct DBusTypeReaderClass DBusTypeReaderClass;  | 
