diff options
| author | Havoc Pennington <hp@redhat.com> | 2005-01-02 08:46:42 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2005-01-02 08:46:42 +0000 | 
| commit | fed88a4b843d8bb11cc486a36ba51441a65c506e (patch) | |
| tree | 5d1e264a78de9c4ff2af57839922480e972d4ddb | |
| parent | fb40fedb9ebb629c9de87338e2223024b2ecbca1 (diff) | |
delete some more noise, put args in consistent order (a big bug trap sadly),
and work on the set value stuff some
| -rw-r--r-- | dbus/dbus-marshal-basic.c | 1239 | ||||
| -rw-r--r-- | dbus/dbus-marshal-basic.h | 76 | ||||
| -rw-r--r-- | dbus/dbus-marshal-recursive.c | 166 | ||||
| -rw-r--r-- | dbus/dbus-marshal-recursive.h | 13 | 
4 files changed, 806 insertions, 688 deletions
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 11f069e2..92517c9f 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -42,6 +42,67 @@   * @{   */ +static void +pack_4_octets (dbus_uint32_t   value, +               int             byte_order, +               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); +  else +    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value); +} + +static void +pack_8_octets (DBusBasicValue     value, +               int                byte_order, +               unsigned char     *data) +{ +  _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.u64); +  else +    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64); +#else +  *(DBus8ByteStruct*)data = value.u64; +  swap_8_octets ((DBusBasicValue*)data, byte_order); +#endif +} + +/** + * Packs a 32 bit unsigned integer into a data pointer. + * + * @param value the value + * @param byte_order the byte order to use + * @param data the data pointer + */ +void +_dbus_pack_uint32 (dbus_uint32_t   value, +                   int             byte_order, +                   unsigned char  *data) +{ +  pack_4_octets (value, byte_order, data); +} + +/** + * Packs a 32 bit signed integer into a data pointer. + * + * @param value the value + * @param byte_order the byte order to use + * @param data the data pointer + */ +void +_dbus_pack_int32 (dbus_int32_t   value, +                  int            byte_order, +                  unsigned char *data) +{ +  pack_4_octets ((dbus_uint32_t) value, byte_order, data); +} +  static dbus_uint32_t  unpack_4_octets (int                  byte_order,                   const unsigned char *data) @@ -75,37 +136,37 @@ swap_bytes (unsigned char *data,  }  #endif /* !DBUS_HAVE_INT64 */ -/** - * Union used to manipulate 8 bytes as if they - * were various types. - */ -typedef union +static void +swap_8_octets (DBusBasicValue    *value, +               int                byte_order)  { +  if (byte_order != DBUS_COMPILER_BYTE_ORDER) +    {  #ifdef DBUS_HAVE_INT64 -  dbus_int64_t  s; /**< 64-bit integer */ -  dbus_uint64_t u; /**< 64-bit unsigned integer */ +      value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64); +#else +      swap_bytes ((unsigned char *)value, 8);  #endif -  double d;        /**< double */ -} DBusOctets8; +    } +} -static DBusOctets8 +static DBusBasicValue  unpack_8_octets (int                  byte_order,                   const unsigned char *data)  { -  DBusOctets8 r; +  DBusBasicValue 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); +    r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);    else -    r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data); +    r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);  #else -  r.d = *(double*)data; -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    swap_bytes ((unsigned char*) &r, sizeof (r)); +  r.u64 = *(DBus8ByteStruct*)data; +  swap_8_octets (&r, byte_order);  #endif    return r; @@ -139,161 +200,11 @@ _dbus_unpack_int32 (int                  byte_order,    return (dbus_int32_t) unpack_4_octets (byte_order, data);  } -#ifdef DBUS_HAVE_INT64 -/** - * Unpacks a 64 bit unsigned integer from a data pointer - * - * @param byte_order The byte order to use - * @param data the data pointer - * @returns the integer - */ -dbus_uint64_t -_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 - * - * @param byte_order The byte order to use - * @param data the data pointer - * @returns the integer - */ -dbus_int64_t -_dbus_unpack_int64 (int                  byte_order, -                    const unsigned char *data) -{ -  DBusOctets8 r; - -  r = unpack_8_octets (byte_order, data); - -  return r.s; -} - -#endif /* DBUS_HAVE_INT64 */ - -static void -pack_4_octets (dbus_uint32_t   value, -               int             byte_order, -               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); -  else -    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value); -} - -static void -swap_8_octets (DBusOctets8    *value, -               int             byte_order) -{ -  if (byte_order != DBUS_COMPILER_BYTE_ORDER) -    { -#ifdef DBUS_HAVE_INT64 -      value->u = DBUS_UINT64_SWAP_LE_BE (value->u); -#else -      swap_bytes ((unsigned char *)value, 8); -#endif -    } -} - -static void -pack_8_octets (DBusOctets8     value, -               int             byte_order, -               unsigned char  *data) -{ -  _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); -  else -    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u); -#else -  memcpy (data, &value, 8); -  swap_8_octets ((DBusOctets8*)data, byte_order); -#endif -} - -/** - * Packs a 32 bit unsigned integer into a data pointer. - * - * @param value the value - * @param byte_order the byte order to use - * @param data the data pointer - */ -void -_dbus_pack_uint32 (dbus_uint32_t   value, -                   int             byte_order, -                   unsigned char  *data) -{ -  pack_4_octets (value, byte_order, data); -} - -/** - * Packs a 32 bit signed integer into a data pointer. - * - * @param value the value - * @param byte_order the byte order to use - * @param data the data pointer - */ -void -_dbus_pack_int32 (dbus_int32_t   value, -                  int            byte_order, -                  unsigned char *data) -{ -  pack_4_octets ((dbus_uint32_t) value, byte_order, data); -} - -#ifdef DBUS_HAVE_INT64 -/** - * Packs a 64 bit unsigned integer into a data pointer. - * - * @param value the value - * @param byte_order the byte order to use - * @param data the data pointer - */ -void -_dbus_pack_uint64 (dbus_uint64_t   value, -                   int             byte_order, -                   unsigned char  *data) -{ -  DBusOctets8 r; -  r.u = value; -  pack_8_octets (r, byte_order, data); -} - -/** - * Packs a 64 bit signed integer into a data pointer. - * - * @param value the value - * @param byte_order the byte order to use - * @param data the data pointer - */ -void -_dbus_pack_int64 (dbus_int64_t   value, -                  int            byte_order, -                  unsigned char *data) -{ -  DBusOctets8 r; -  r.s = value; -  pack_8_octets (r, byte_order, data); -} -#endif /* DBUS_HAVE_INT64 */ -  static void  set_4_octets (DBusString          *str, -              int                  byte_order,                int                  offset, -              dbus_uint32_t        value) +              dbus_uint32_t        value, +              int                  byte_order)  {    char *data; @@ -307,9 +218,9 @@ set_4_octets (DBusString          *str,  static void  set_8_octets (DBusString          *str, -              int                  byte_order,                int                  offset, -              DBusOctets8          value) +              DBusBasicValue       value, +              int                  byte_order)  {    char *data; @@ -322,87 +233,23 @@ set_8_octets (DBusString          *str,  }  /** - * Sets the 4 bytes at the given offset to a marshaled signed integer, - * replacing anything found there previously. - * - * @param str the string to write the marshalled int to - * @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, -                         int                  byte_order, -                         int                  offset, -                         dbus_int32_t         value) -{ -  set_4_octets (str, byte_order, offset, (dbus_uint32_t) value); -} - -/**   * Sets the 4 bytes at the given offset to a marshaled unsigned   * integer, replacing anything found there previously.   *   * @param str the string to write the marshalled int to - * @param offset the byte offset where int should be written - * @param byte_order the byte order to use + * @param pos the byte offset where int should be written   * @param value the value - * - */ -void -_dbus_marshal_set_uint32 (DBusString          *str, -                          int                  byte_order, -                          int                  offset, -                          dbus_uint32_t        value) -{ -  set_4_octets (str, byte_order, offset, value); -} - -#ifdef DBUS_HAVE_INT64 - -/** - * Sets the 8 bytes at the given offset to a marshaled signed integer, - * replacing anything found there previously. - * - * @param str the string to write the marshalled int to - * @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, -                         int                  byte_order, -                         int                  offset, -                         dbus_int64_t         value) -{ -  DBusOctets8 r; -  r.s = value; -  set_8_octets (str, byte_order, offset, r); -} - -/** - * Sets the 8 bytes at the given offset to a marshaled unsigned - * integer, replacing anything found there previously. - * - * @param str the string to write the marshalled int to - * @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, -                          int                  byte_order, -                          int                  offset, -                          dbus_uint64_t        value) +_dbus_marshal_set_uint32 (DBusString          *str, +                          int                  pos, +                          dbus_uint32_t        value, +                          int                  byte_order)  { -  DBusOctets8 r; -  r.u = value; -  set_8_octets (str, byte_order, offset, r); +  set_4_octets (str, pos, value, byte_order);  } -#endif /* DBUS_HAVE_INT64 */  /**   * Sets the existing marshaled string at the given offset with @@ -415,42 +262,166 @@ _dbus_marshal_set_uint64 (DBusString          *str,   * string. Use with caution.   *   * @param str the string to write the marshalled string to - * @param offset the byte offset where string should be written + * @param pos the position of the marshaled string length + * @param value the value   * @param byte_order the byte order to use + * @param old_end_pos place to store byte after the nul byte of the old value + * @param new_end_pos place to store byte after the nul byte of the new value + * @returns #TRUE on success, #FALSE if no memory + * + */ +static dbus_bool_t +set_string (DBusString          *str, +            int                  pos, +            const char          *value, +            int                  byte_order, +            int                 *old_end_pos, +            int                 *new_end_pos) +{ +  int old_len, new_len; +  DBusString dstr; + +  _dbus_string_init_const (&dstr, value); + +  old_len = _dbus_demarshal_uint32 (str, pos, byte_order, NULL); + +  new_len = _dbus_string_get_length (&dstr); + +  if (!_dbus_string_replace_len (&dstr, 0, new_len, +                                 str, pos + 4, old_len)) +    return FALSE; + +  _dbus_marshal_set_uint32 (str, pos, new_len, byte_order); + +  if (old_end_pos) +    *old_end_pos = pos + 4 + old_len + 1; +  if (new_end_pos) +    *new_end_pos = pos + 4 + new_len + 1; + +  return TRUE; +} + +/** + * Sets the existing marshaled signature at the given offset to a new + * marshaled signature. Same basic ideas as set_string(). + * + * @param str the string to write the marshalled signature to + * @param pos the position of the marshaled signature length   * @param value the value - * @param len the length to use - * @returns #TRUE on success + * @param byte_order the byte order to use + * @param old_end_pos place to store byte after the nul byte of the old value + * @param new_end_pos place to store byte after the nul byte of the new value + * @returns #TRUE on success, #FALSE if no memory   *   */ -dbus_bool_t -_dbus_marshal_set_string (DBusString          *str, -                          int                  byte_order, -                          int                  offset, -                          const DBusString    *value, -			  int                  len) +static dbus_bool_t +set_signature (DBusString          *str, +               int                  pos, +               const char          *value, +               int                  byte_order, +               int                 *old_end_pos, +               int                 *new_end_pos)  { -  int old_len; +  int old_len, new_len; +  DBusString dstr; -  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || -                byte_order == DBUS_BIG_ENDIAN); +  _dbus_string_init_const (&dstr, value); -  old_len = _dbus_demarshal_uint32 (str, byte_order, -                                    offset, NULL); +  old_len = _dbus_string_get_byte (str, pos); +  new_len = _dbus_string_get_length (&dstr); -  if (!_dbus_string_replace_len (value, 0, len, -                                 str, offset + 4, old_len)) +  if (!_dbus_string_replace_len (&dstr, 0, new_len, +                                 str, pos + 1, old_len))      return FALSE; -  _dbus_marshal_set_uint32 (str, byte_order, -                            offset, len); +  _dbus_string_set_byte (str, pos, new_len); + +  if (old_end_pos) +    *old_end_pos = pos + 1 + old_len + 1; +  if (new_end_pos) +    *new_end_pos = pos + 1 + new_len + 1;    return TRUE;  } +/** + * Sets an existing basic type value to a new value. + * Arguments work the same way as _dbus_marshal_basic_type(). + * + * @param str the string + * @param pos location of the current value + * @param type the type of the current and new values + * @param value the address of the new value + * @param byte_order byte order for marshaling + * @param old_end_pos location to store end position of the old value, or #NULL + * @param new_end_pos location to store end position of the new value, or #NULL + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_marshal_set_basic_type (DBusString       *str, +                              int               pos, +                              int               type, +                              const void       *value, +                              int               byte_order, +                              int              *old_end_pos, +                              int              *new_end_pos) +{ +  const DBusBasicValue *vp; + +  vp = value; + +  switch (type) +    { +    case DBUS_TYPE_BYTE: +    case DBUS_TYPE_BOOLEAN: +      _dbus_string_set_byte (str, pos, vp->byt); +      if (old_end_pos) +        *old_end_pos = pos + 1; +      if (new_end_pos) +        *new_end_pos = pos + 1; +      return TRUE; +      break; +    case DBUS_TYPE_INT32: +    case DBUS_TYPE_UINT32: +      set_4_octets (str, pos, vp->u32, byte_order); +      if (old_end_pos) +        *old_end_pos = pos + 4; +      if (new_end_pos) +        *new_end_pos = pos + 4; +      return TRUE; +      break; +    case DBUS_TYPE_INT64: +    case DBUS_TYPE_UINT64: +    case DBUS_TYPE_DOUBLE: +      { +        set_8_octets (str, pos, *vp, byte_order); +        if (old_end_pos) +        *old_end_pos = pos + 8; +        if (new_end_pos) +          *new_end_pos = pos + 8; +        return TRUE; +      } +      break; +    case DBUS_TYPE_STRING: +    case DBUS_TYPE_OBJECT_PATH: +      return set_string (str, pos, vp->str, byte_order, +                         old_end_pos, new_end_pos); +      break; +    case DBUS_TYPE_SIGNATURE: +      return set_signature (str, pos, vp->str, byte_order, +                            old_end_pos, new_end_pos); +      break; +    default: +      _dbus_assert_not_reached ("not a basic type"); +      return FALSE; +      break; +    } +} +  static dbus_uint32_t  demarshal_4_octets (const DBusString *str, -                    int               byte_order,                      int               pos, +                    int               byte_order,                      int              *new_pos)  {    pos = _DBUS_ALIGN_VALUE (pos, 4); @@ -473,11 +444,11 @@ demarshal_4_octets (const DBusString *str,   */  dbus_uint32_t  _dbus_demarshal_uint32  (const DBusString *str, -			 int               byte_order,  			 int               pos, +                         int               byte_order,  			 int              *new_pos)  { -  return demarshal_4_octets (str, byte_order, pos, new_pos); +  return demarshal_4_octets (str, pos, byte_order, new_pos);  }  /** @@ -486,7 +457,7 @@ _dbus_demarshal_uint32  (const DBusString *str,   * if the basic type is "double" then the pointer is   * a double*, and if it's "char*" then the pointer is   * a "char**". - *  + *   * A value of type #DBusBasicValue is guaranteed to be large enough to   * hold any of the types that may be returned, which is handy if you   * are trying to do things generically. For example you can pass @@ -495,26 +466,28 @@ _dbus_demarshal_uint32  (const DBusString *str,   * move a value from one place to another.   *   * @param str the string containing the data + * @param pos position in the string   * @param type type of value to demarshal   * @param value pointer to return value data   * @param byte_order the byte order - * @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                    pos,  			    int                    type,  			    void                  *value,  			    int                    byte_order, -			    int                    pos,                              int                   *new_pos)  {    const char *str_data;    DBusBasicValue *vp; +  _dbus_assert (_dbus_type_is_basic (type)); +    str_data = _dbus_string_get_const_data (str);    vp = value; -   +    switch (type)      {      case DBUS_TYPE_BYTE: @@ -527,21 +500,21 @@ _dbus_demarshal_basic_type (const DBusString      *str,        pos = _DBUS_ALIGN_VALUE (pos, 4);        vp->u32 = *(dbus_uint32_t *)(str_data + pos);        if (byte_order != DBUS_COMPILER_BYTE_ORDER) -	vp->u32 = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value); +	vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32);        pos += 4;        break; -#ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64:      case DBUS_TYPE_UINT64: -#endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE:        pos = _DBUS_ALIGN_VALUE (pos, 8); -      memcpy (vp, str_data + pos, 8); -      if (byte_order != DBUS_COMPILER_BYTE_ORDER)  #ifdef DBUS_HAVE_INT64 -	vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value); +      if (byte_order != DBUS_COMPILER_BYTE_ORDER) +        vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); +      else +        vp->u64 = *(dbus_uint64_t*)(str_data + pos);  #else -      swap_bytes (value, 8); +      vp->u64 = *(DBus8ByteStruct*) (str_data + pos); +      swap_8_octets (vp, byte_order);  #endif        pos += 8;        break; @@ -550,7 +523,7 @@ _dbus_demarshal_basic_type (const DBusString      *str,        {          int len; -        len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); +        len = _dbus_demarshal_uint32 (str, pos, byte_order, &pos);          vp->str = (char*) str_data + pos; @@ -580,285 +553,6 @@ _dbus_demarshal_basic_type (const DBusString      *str,      *new_pos = pos;  } -/** - * Skips over a basic type, reporting the following position. - * - * @param str the string containing the data - * @param type type of value to demarshal - * @param byte_order the byte order - * @param pos pointer to position in the string, - *            updated on return to new position - **/ -void -_dbus_marshal_skip_basic_type (const DBusString      *str, -                               int                    type, -                               int                    byte_order, -                               int                   *pos) -{ -  switch (type) -    { -    case DBUS_TYPE_BYTE: -    case DBUS_TYPE_BOOLEAN: -      (*pos)++; -      break; -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -      *pos = _DBUS_ALIGN_VALUE (*pos, 4); -      *pos += 4; -      break; -#ifdef DBUS_HAVE_INT64 -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64: -#endif /* DBUS_HAVE_INT64 */ -    case DBUS_TYPE_DOUBLE: -      *pos = _DBUS_ALIGN_VALUE (*pos, 8); -      *pos += 8; -      break; -    case DBUS_TYPE_STRING: -    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_warn ("type %s not a basic type\n", -                  _dbus_type_to_string (type)); -      _dbus_assert_not_reached ("not a basic type"); -      break; -    } -} - -/** - * Skips an array, returning the next position. - * - * @param str the string containing the data - * @param byte_order the byte order - * @param pos pointer to position in the string, - *            updated on return to new position - */ -void -_dbus_marshal_skip_array (const DBusString  *str, -                          int                byte_order, -                          int                element_type, -                          int               *pos) -{ -  dbus_uint32_t array_len; -  int i; -  int alignment; - -  i = _DBUS_ALIGN_VALUE (*pos, 4); - -  _dbus_demarshal_basic_type (str, -                              DBUS_TYPE_UINT32, -                              &array_len, -                              byte_order, -                              i, -                              &i); - -  alignment = _dbus_type_get_alignment (element_type); - -  i = _DBUS_ALIGN_VALUE (i, alignment); - -  *pos = i + array_len; -} - -/** - * Return #TRUE if the typecode is a valid typecode - * - * @returns #TRUE if valid - */ -dbus_bool_t -_dbus_type_is_valid (int typecode) -{ -  switch (typecode) -    { -    case DBUS_TYPE_BYTE: -    case DBUS_TYPE_BOOLEAN: -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64: -    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; -    } -} - -/** - * Gets the alignment requirement for the given type; - * will be 1, 4, or 8. - * - * @param typecode the type - * @returns alignment of 1, 4, or 8 - */ -int -_dbus_type_get_alignment (int typecode) -{ -  switch (typecode) -    { -    case DBUS_TYPE_BYTE: -    case DBUS_TYPE_BOOLEAN: -    case DBUS_TYPE_VARIANT: -    case DBUS_TYPE_SIGNATURE: -      return 1; -    case DBUS_TYPE_INT32: -    case DBUS_TYPE_UINT32: -      /* this stuff is 4 since it starts with a length */ -    case DBUS_TYPE_STRING: -    case DBUS_TYPE_OBJECT_PATH: -    case DBUS_TYPE_ARRAY: -      return 4; -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64: -    case DBUS_TYPE_DOUBLE: -      /* struct is 8 since it could contain an 8-aligned item -       * and it's simpler to just always align structs to 8; -       * we want the amount of padding in a struct of a given -       * type to be predictable, not location-dependent. -       */ -    case DBUS_TYPE_STRUCT: -      return 8; - -    default: -      _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); -      return 0; -    } -} - -/** - * 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 - */ -void -_dbus_verbose_bytes (const unsigned char *data, -                     int                  len, -                     int                  offset) -{ -  int i; -  const unsigned char *aligned; - -  _dbus_assert (len >= 0); - -  /* Print blanks on first row if appropriate */ -  aligned = _DBUS_ALIGN_ADDRESS (data, 4); -  if (aligned > data) -    aligned -= 4; -  _dbus_assert (aligned <= data); - -  if (aligned != data) -    { -      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); -      while (aligned != data) -        { -          _dbus_verbose ("    "); -          ++aligned; -        } -    } - -  /* now print the bytes */ -  i = 0; -  while (i < len) -    { -      if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) -        { -          _dbus_verbose ("%4d\t%p: ", -                         offset + i, &data[i]); -        } - -      if (data[i] >= 32 && -          data[i] <= 126) -        _dbus_verbose (" '%c' ", data[i]); -      else -        _dbus_verbose ("0x%s%x ", -                       data[i] <= 0xf ? "0" : "", data[i]); - -      ++i; - -      if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) -        { -          if (i > 3) -            _dbus_verbose ("BE: %d LE: %d", -                           _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), -                           _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); - -          if (i > 7 && -              _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) -            { -              _dbus_verbose (" dbl: %g", -                             *(double*)&data[i-8]); -            } - -          _dbus_verbose ("\n"); -        } -    } - -  _dbus_verbose ("\n"); -} - -/** - * Dump the given part of the string to verbose log. - * - * @param str the string - * @param start the start of range to dump - * @param len length of range - */ -void -_dbus_verbose_bytes_of_string (const DBusString    *str, -                               int                  start, -                               int                  len) -{ -  const char *d; -  int real_len; - -  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", -                     start, len, real_len); -      return; -    } - -  if ((start + len) > real_len) -    { -      _dbus_verbose ("  [%d,%d) extends outside string of length %d\n", -                     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, @@ -889,11 +583,11 @@ marshal_4_octets (DBusString   *str,  }  static dbus_bool_t -marshal_8_octets (DBusString *str, -                  int         insert_at, -                  DBusOctets8 value, -                  int         byte_order, -                  int        *pos_after) +marshal_8_octets (DBusString    *str, +                  int            insert_at, +                  DBusBasicValue value, +                  int            byte_order, +                  int           *pos_after)  {    dbus_bool_t retval;    int orig_len; @@ -933,6 +627,11 @@ marshal_len_followed_by_bytes (int                  marshal_as,    DBusString value_str;    int value_len; +  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN); +  if (insert_at > _dbus_string_get_length (str)) +    _dbus_warn ("insert_at = %d string len = %d data_len = %d\n", +                insert_at, _dbus_string_get_length (str), data_len); +    if (marshal_as == MARSHAL_AS_BYTE_ARRAY)      value_len = data_len;    else @@ -1030,15 +729,17 @@ marshal_signature (DBusString    *str,  dbus_bool_t  _dbus_marshal_basic_type (DBusString *str,                            int         insert_at, -			  char        type, +			  int         type,  			  const void *value,  			  int         byte_order,                            int        *pos_after)  {    const DBusBasicValue *vp; +  _dbus_assert (_dbus_type_is_basic (type)); +    vp = value; -   +    switch (type)      {      case DBUS_TYPE_BYTE: @@ -1054,23 +755,12 @@ _dbus_marshal_basic_type (DBusString *str,        return marshal_4_octets (str, insert_at, vp->u32,                                 byte_order, pos_after);        break; -#ifdef DBUS_HAVE_INT64      case DBUS_TYPE_INT64:      case DBUS_TYPE_UINT64: -      { -        DBusOctets8 r; -        r.u = vp->u64; -        return marshal_8_octets (str, insert_at, r, byte_order, pos_after); -      } -      break; -#endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE: -      { -        DBusOctets8 r; -        r.d = vp->dbl; -        return marshal_8_octets (str, insert_at, r, byte_order, pos_after); -      } +      return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);        break; +      case DBUS_TYPE_STRING:      case DBUS_TYPE_OBJECT_PATH:        return marshal_string (str, insert_at, vp->str, byte_order, pos_after); @@ -1145,11 +835,11 @@ marshal_4_octets_array (DBusString          *str,  }  static dbus_bool_t -marshal_8_octets_array (DBusString          *str, -                        int                  insert_at, -                        const DBusOctets8   *value, -                        int                  len, -                        int                  byte_order) +marshal_8_octets_array (DBusString           *str, +                        int                   insert_at, +                        const DBusBasicValue *value, +                        int                   len, +                        int                   byte_order)  {    int old_string_len;    int array_start; @@ -1191,7 +881,7 @@ marshal_8_octets_array (DBusString          *str,  #ifdef DBUS_HAVE_INT64            *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));  #else -          swap_bytes ((unsigned char*) d, 8); +          swap_8_bytes ((DBusBasicValue*) d);  #endif            d += 8;          } @@ -1221,7 +911,7 @@ marshal_8_octets_array (DBusString          *str,  dbus_bool_t  _dbus_marshal_basic_type_array (DBusString *str,                                  int         insert_at, -				char        element_type, +				int         element_type,  				const void *value,  				int         len,  				int         byte_order, @@ -1241,10 +931,8 @@ _dbus_marshal_basic_type_array (DBusString *str,      case DBUS_TYPE_UINT32:        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: -#endif /* DBUS_HAVE_INT64 */      case DBUS_TYPE_DOUBLE:        return marshal_8_octets_array (str, insert_at, value, len, byte_order);        break; @@ -1266,6 +954,363 @@ _dbus_marshal_basic_type_array (DBusString *str,    return FALSE;  } + +/** + * Skips over a basic type, reporting the following position. + * + * @param str the string containing the data + * @param type type of value to demarshal + * @param byte_order the byte order + * @param pos pointer to position in the string, + *            updated on return to new position + **/ +void +_dbus_marshal_skip_basic_type (const DBusString      *str, +                               int                    type, +                               int                    byte_order, +                               int                   *pos) +{ +  switch (type) +    { +    case DBUS_TYPE_BYTE: +    case DBUS_TYPE_BOOLEAN: +      (*pos)++; +      break; +    case DBUS_TYPE_INT32: +    case DBUS_TYPE_UINT32: +      *pos = _DBUS_ALIGN_VALUE (*pos, 4); +      *pos += 4; +      break; +    case DBUS_TYPE_INT64: +    case DBUS_TYPE_UINT64: +    case DBUS_TYPE_DOUBLE: +      *pos = _DBUS_ALIGN_VALUE (*pos, 8); +      *pos += 8; +      break; +    case DBUS_TYPE_STRING: +    case DBUS_TYPE_OBJECT_PATH: +      { +        int len; + +        len = _dbus_demarshal_uint32 (str, *pos, byte_order, 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_warn ("type %s not a basic type\n", +                  _dbus_type_to_string (type)); +      _dbus_assert_not_reached ("not a basic type"); +      break; +    } +} + +/** + * Skips an array, returning the next position. + * + * @param str the string containing the data + * @param element_type the type of array elements + * @param byte_order the byte order + * @param pos pointer to position in the string, + *            updated on return to new position + */ +void +_dbus_marshal_skip_array (const DBusString  *str, +                          int                element_type, +                          int                byte_order, +                          int               *pos) +{ +  dbus_uint32_t array_len; +  int i; +  int alignment; + +  i = _DBUS_ALIGN_VALUE (*pos, 4); + +  _dbus_demarshal_basic_type (str, +                              i, +                              DBUS_TYPE_UINT32, +                              &array_len, +                              byte_order, +                              &i); + +  alignment = _dbus_type_get_alignment (element_type); + +  i = _DBUS_ALIGN_VALUE (i, alignment); + +  *pos = i + array_len; +} + +/** + * Gets the alignment requirement for the given type; + * will be 1, 4, or 8. + * + * @param typecode the type + * @returns alignment of 1, 4, or 8 + */ +int +_dbus_type_get_alignment (int typecode) +{ +  switch (typecode) +    { +    case DBUS_TYPE_BYTE: +    case DBUS_TYPE_BOOLEAN: +    case DBUS_TYPE_VARIANT: +    case DBUS_TYPE_SIGNATURE: +      return 1; +    case DBUS_TYPE_INT32: +    case DBUS_TYPE_UINT32: +      /* this stuff is 4 since it starts with a length */ +    case DBUS_TYPE_STRING: +    case DBUS_TYPE_OBJECT_PATH: +    case DBUS_TYPE_ARRAY: +      return 4; +    case DBUS_TYPE_INT64: +    case DBUS_TYPE_UINT64: +    case DBUS_TYPE_DOUBLE: +      /* struct is 8 since it could contain an 8-aligned item +       * and it's simpler to just always align structs to 8; +       * we want the amount of padding in a struct of a given +       * type to be predictable, not location-dependent. +       */ +    case DBUS_TYPE_STRUCT: +      return 8; + +    default: +      _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); +      return 0; +    } +} + + +/** + * Return #TRUE if the typecode is a valid typecode. + * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and + * random unknown bytes aren't either. This function is safe with + * untrusted data. + * + * @returns #TRUE if valid + */ +dbus_bool_t +_dbus_type_is_valid (int typecode) +{ +  switch (typecode) +    { +    case DBUS_TYPE_BYTE: +    case DBUS_TYPE_BOOLEAN: +    case DBUS_TYPE_INT32: +    case DBUS_TYPE_UINT32: +    case DBUS_TYPE_INT64: +    case DBUS_TYPE_UINT64: +    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; +    } +} + +#define TYPE_IS_CONTAINER(typecode)             \ +    ((typecode) == DBUS_TYPE_STRUCT ||          \ +     (typecode) == DBUS_TYPE_VARIANT ||         \ +     (typecode) == DBUS_TYPE_ARRAY) + +/** + * A "container type" can contain basic types, or nested + * container types. #DBUS_TYPE_INVALID is not a container type. + * This function will crash if passed a typecode that isn't + * in dbus-protocol.h + * + * @returns #TRUE if type is a container + */ +dbus_bool_t +_dbus_type_is_container (int typecode) +{ +  /* only reasonable (non-line-noise) typecodes are allowed */ +  _dbus_assert (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID); +  return TYPE_IS_CONTAINER (typecode); +} + +/** + * A "basic type" is a somewhat arbitrary concept, but the intent + * is to include those types that are fully-specified by a single + * typecode, with no additional type information or nested + * values. So all numbers and strings are basic types and + * structs, arrays, and variants are not basic types. + * #DBUS_TYPE_INVALID is not a basic type. + * + * This function is defined to return #TRUE for exactly those + * types that can be written with _dbus_marshal_basic_type() + * and read with _dbus_demarshal_basic_type(). + * + * This function will crash if passed a typecode that isn't + * in dbus-protocol.h + * + * @returns #TRUE if type is basic + */ +dbus_bool_t +_dbus_type_is_basic (int typecode) +{ +  /* only reasonable (non-line-noise) typecodes are allowed */ +  _dbus_assert (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID); + +  /* everything that isn't invalid or a container */ +  return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); +} + +/** + * Tells you whether values of this type can change length if you set + * them to some other value. For this purpose, you assume that the + * first byte of the old and new value would be in the same location, + * so alignment padding is not a factor. + * + * @returns #TRUE if the type can occupy different lengths + */ +dbus_bool_t +_dbus_type_length_varies (int typecode) +{ +  switch (typecode) +    { +    case DBUS_TYPE_BYTE: +    case DBUS_TYPE_BOOLEAN: +    case DBUS_TYPE_INT32: +    case DBUS_TYPE_UINT32: +    case DBUS_TYPE_INT64: +    case DBUS_TYPE_UINT64: +    case DBUS_TYPE_DOUBLE: +      return FALSE; +    default: +      return TRUE; +    } +} + +/** + * 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 + */ +void +_dbus_verbose_bytes (const unsigned char *data, +                     int                  len, +                     int                  offset) +{ +  int i; +  const unsigned char *aligned; + +  _dbus_assert (len >= 0); + +  /* Print blanks on first row if appropriate */ +  aligned = _DBUS_ALIGN_ADDRESS (data, 4); +  if (aligned > data) +    aligned -= 4; +  _dbus_assert (aligned <= data); + +  if (aligned != data) +    { +      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); +      while (aligned != data) +        { +          _dbus_verbose ("    "); +          ++aligned; +        } +    } + +  /* now print the bytes */ +  i = 0; +  while (i < len) +    { +      if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) +        { +          _dbus_verbose ("%4d\t%p: ", +                         offset + i, &data[i]); +        } + +      if (data[i] >= 32 && +          data[i] <= 126) +        _dbus_verbose (" '%c' ", data[i]); +      else +        _dbus_verbose ("0x%s%x ", +                       data[i] <= 0xf ? "0" : "", data[i]); + +      ++i; + +      if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) +        { +          if (i > 3) +            _dbus_verbose ("BE: %d LE: %d", +                           _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), +                           _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); + +          if (i > 7 && +              _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) +            { +              _dbus_verbose (" dbl: %g", +                             *(double*)&data[i-8]); +            } + +          _dbus_verbose ("\n"); +        } +    } + +  _dbus_verbose ("\n"); +} + +/** + * Dump the given part of the string to verbose log. + * + * @param str the string + * @param start the start of range to dump + * @param len length of range + */ +void +_dbus_verbose_bytes_of_string (const DBusString    *str, +                               int                  start, +                               int                  len) +{ +  const char *d; +  int real_len; + +  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", +                     start, len, real_len); +      return; +    } + +  if ((start + len) > real_len) +    { +      _dbus_verbose ("  [%d,%d) extends outside string of length %d\n", +                     start, len, real_len); +      len = real_len - start; +    } + +  d = _dbus_string_get_const_data_len (str, start, len); + +  _dbus_verbose_bytes (d, len, start); +} +  /** @} */  #ifdef DBUS_BUILD_TESTS @@ -1283,8 +1328,8 @@ _dbus_marshal_basic_type_array (DBusString *str,  #define DEMARSHAL_BASIC(typename, byte_order)                                   \    do {                                                                          \ -    _dbus_demarshal_basic_type (&str, DBUS_TYPE_##typename, &v_##typename,      \ -                                byte_order, pos, &pos);                         \ +    _dbus_demarshal_basic_type (&str, pos, DBUS_TYPE_##typename, &v_##typename, \ +                                byte_order, &pos);                              \    } while (0)  #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \ @@ -1408,6 +1453,13 @@ _dbus_marshal_test (void)    MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");    MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)"); +#if 0 + +  /* +   * FIXME restore the set/pack tests +   */ + +#ifdef DBUS_HAVE_INT64    /* set/pack 64-bit integers */    _dbus_string_set_length (&str, 8); @@ -1478,6 +1530,7 @@ _dbus_marshal_test (void)    _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==                  _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,                                       _dbus_string_get_const_data (&str))); +#endif /* DBUS_HAVE_INT64 */    /* set/pack 32-bit integers */    _dbus_string_set_length (&str, 4); @@ -1550,6 +1603,8 @@ _dbus_marshal_test (void)                  _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,                                       _dbus_string_get_const_data (&str))); +#endif /* set/pack tests for integers */ +    /* Strings in-place set */    byte_order = DBUS_LITTLE_ENDIAN;    while (TRUE) @@ -1565,22 +1620,24 @@ _dbus_marshal_test (void)        /* Set it to something longer */        _dbus_string_init_const (&t, "Hello world foo"); -      _dbus_marshal_set_string (&str, byte_order, 0, -                                &t, _dbus_string_get_length (&t)); +      v_STRING = _dbus_string_get_const_data (&t); +      _dbus_marshal_set_basic_type (&str, 0, DBUS_TYPE_STRING, +                                    &v_STRING, byte_order, NULL, NULL); -      _dbus_demarshal_basic_type (&str, DBUS_TYPE_STRING, +      _dbus_demarshal_basic_type (&str, 0, DBUS_TYPE_STRING,                                    &v_STRING, byte_order, -                                  0, NULL); +                                  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 = _dbus_string_get_const_data (&t); +      _dbus_marshal_set_basic_type (&str, 0, DBUS_TYPE_STRING, +                                    &v_STRING, byte_order, NULL, NULL); +      _dbus_demarshal_basic_type (&str, 0, DBUS_TYPE_STRING,                                    &v_STRING, byte_order, -                                  0, NULL); +                                  NULL);        _dbus_assert (strcmp (v_STRING, "Hello") == 0);        /* Do the other byte order */ diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h index 1987dcea..89565079 100644 --- a/dbus/dbus-marshal-basic.h +++ b/dbus/dbus-marshal-basic.h @@ -226,6 +226,14 @@ _hack_dbus_type_to_string (int type)  #define DBUS_UINT64_FROM_BE(val) (DBUS_UINT64_TO_BE (val))  #endif /* DBUS_HAVE_INT64 */ +#ifdef DBUS_HAVE_INT64 +typedef struct +{ +  dbus_uint32_t first32; +  dbus_uint32_t second32; +} DBus8ByteStruct; +#endif /* DBUS_HAVE_INT64 */ +  typedef union  {    dbus_int32_t  i32; @@ -233,6 +241,8 @@ typedef union  #ifdef DBUS_HAVE_INT64    dbus_int64_t  i64;    dbus_uint64_t u64; +#else +  DBus8ByteStruct u64;  #endif    double dbl;    unsigned char byt; @@ -251,75 +261,55 @@ void          _dbus_pack_uint32   (dbus_uint32_t        value,  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, -                                   unsigned char       *data); -dbus_int64_t  _dbus_unpack_int64  (int                  byte_order, -                                   const unsigned char *data); -void          _dbus_pack_uint64   (dbus_uint64_t        value, -                                   int                  byte_order, -                                   unsigned char       *data); -dbus_uint64_t _dbus_unpack_uint64 (int                  byte_order, -                                   const unsigned char *data); -#endif /* DBUS_HAVE_INT64 */ - -void        _dbus_marshal_set_int32  (DBusString       *str, -                                      int               byte_order, -                                      int               offset, -                                      dbus_int32_t      value); -void        _dbus_marshal_set_uint32 (DBusString       *str, -                                      int               byte_order, -                                      int               offset, -                                      dbus_uint32_t     value); -#ifdef DBUS_HAVE_INT64 -void        _dbus_marshal_set_int64  (DBusString       *str, -                                      int               byte_order, -                                      int               offset, -                                      dbus_int64_t      value); -void        _dbus_marshal_set_uint64 (DBusString       *str, -                                      int               byte_order, -                                      int               offset, -                                      dbus_uint64_t     value); -#endif /* DBUS_HAVE_INT64 */ -dbus_bool_t   _dbus_marshal_set_string       (DBusString       *str, +dbus_bool_t   _dbus_marshal_set_basic_type   (DBusString       *str, +                                              int               pos, +                                              int               type, +                                              const void       *value,                                                int               byte_order, -                                              int               offset, -                                              const DBusString *value, -                                              int               len); +                                              int              *old_end_pos, +                                              int              *new_end_pos);  dbus_bool_t   _dbus_marshal_basic_type       (DBusString       *str,                                                int               insert_at, -                                              char              type, +                                              int               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, +                                              int               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               pos,                                                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               byte_order,                                                int              *pos); +void          _dbus_marshal_set_uint32       (DBusString       *str, +                                              int               pos, +                                              dbus_uint32_t     value, +                                              int               byte_order); +dbus_uint32_t _dbus_demarshal_uint32         (const DBusString *str, +                                              int               pos, +                                              int               byte_order, +                                              int              *new_pos);  dbus_bool_t   _dbus_type_is_valid            (int               typecode);  int           _dbus_type_get_alignment       (int               typecode); +dbus_bool_t   _dbus_type_is_basic            (int               typecode); +dbus_bool_t   _dbus_type_is_container        (int               typecode); +dbus_bool_t   _dbus_type_length_varies       (int               typecode); + +  #endif /* DBUS_MARSHAL_H */ diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index 398b39d4..21f922fa 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -136,21 +136,22 @@ array_reader_get_array_len (const DBusTypeReader *reader)  {    dbus_uint32_t array_len;    int len_pos; -   +    /* array_len_offset is the offset back from start_pos to end of the len */    len_pos = reader->u.array.start_pos - ((int)reader->array_len_offset) - 4; -   +    _dbus_demarshal_basic_type (reader->value_str, +                              len_pos,                                DBUS_TYPE_UINT32,                                &array_len,                                reader->byte_order, -                              len_pos, NULL); +                              NULL);    _dbus_verbose ("   reader %p len_pos %d array len %u len_offset %d\n",                   reader, len_pos, array_len, reader->array_len_offset);    _dbus_assert (reader->u.array.start_pos - len_pos - 4 < 8); -   +    return array_len;  } @@ -168,7 +169,7 @@ array_reader_recurse (DBusTypeReader *sub,    len_pos = sub->value_pos;    sub->value_pos += 4; /* for the length */ -   +    alignment = element_type_get_alignment (sub->type_str,                                            sub->type_pos); @@ -231,7 +232,7 @@ array_reader_check_finished (const DBusTypeReader *reader)    _dbus_assert (reader->value_pos <= end_pos);    _dbus_assert (reader->value_pos >= reader->u.array.start_pos); -   +    return reader->value_pos == end_pos;  } @@ -320,9 +321,10 @@ base_reader_next (DBusTypeReader *reader,      case DBUS_TYPE_ARRAY:        {          if (!reader->klass->types_only) -          _dbus_marshal_skip_array (reader->value_str, reader->byte_order, +          _dbus_marshal_skip_array (reader->value_str,                                      first_type_in_signature (reader->type_str,                                                               reader->type_pos + 1), +                                    reader->byte_order,                                      &reader->value_pos);          skip_one_complete_type (reader->type_str, &reader->type_pos); @@ -409,9 +411,10 @@ array_reader_next (DBusTypeReader *reader,      case DBUS_TYPE_ARRAY:        { -        _dbus_marshal_skip_array (reader->value_str, reader->byte_order, +        _dbus_marshal_skip_array (reader->value_str,                                    first_type_in_signature (reader->type_str,                                                             reader->type_pos + 1), +                                  reader->byte_order,                                    &reader->value_pos);        }        break; @@ -555,7 +558,7 @@ _dbus_type_reader_init_from_mark (DBusTypeReader     *reader,    if (reader->klass->init_from_mark)      (* reader->klass->init_from_mark) (reader, mark); -   +  #if RECURSIVE_MARSHAL_TRACE    _dbus_verbose ("  type reader %p init from mark type_pos = %d value_pos = %d remaining sig '%s'\n",                   reader, reader->type_pos, reader->value_pos, @@ -595,7 +598,7 @@ _dbus_type_reader_init_types_only_from_mark (DBusTypeReader     *reader,    if (reader->klass->init_from_mark)      (* reader->klass->init_from_mark) (reader, mark); -   +  #if RECURSIVE_MARSHAL_TRACE    _dbus_verbose ("  type reader %p init types only from mark type_pos = %d remaining sig '%s'\n",                   reader, reader->type_pos, @@ -631,7 +634,7 @@ _dbus_type_reader_get_current_type (const DBusTypeReader *reader)    else      t = first_type_in_signature (reader->type_str,                                   reader->type_pos); -   +    _dbus_assert (t != DBUS_STRUCT_END_CHAR);    _dbus_assert (t != DBUS_STRUCT_BEGIN_CHAR); @@ -658,10 +661,10 @@ _dbus_type_reader_array_is_empty (const DBusTypeReader *reader)  #endif    _dbus_demarshal_basic_type (reader->value_str, +                              reader->value_pos,                                DBUS_TYPE_UINT32,                                &array_len,                                reader->byte_order, -                              reader->value_pos,                                NULL);  #if RECURSIVE_MARSHAL_TRACE    _dbus_verbose (" ... array len = %d\n", array_len); @@ -681,9 +684,10 @@ _dbus_type_reader_read_basic (const DBusTypeReader    *reader,    t = _dbus_type_reader_get_current_type (reader);    _dbus_demarshal_basic_type (reader->value_str, +                              reader->value_pos,                                t, value,                                reader->byte_order, -                              reader->value_pos, NULL); +                              NULL);  #if RECURSIVE_MARSHAL_TRACE @@ -754,7 +758,7 @@ _dbus_type_reader_recurse (DBusTypeReader *reader,      }    _dbus_assert (sub->klass == all_reader_classes[sub->klass->id]); -   +    (* sub->klass->recurse) (sub, reader);  #if RECURSIVE_MARSHAL_TRACE @@ -854,6 +858,66 @@ _dbus_type_reader_get_signature (const DBusTypeReader  *reader,    *len_p = find_len_of_complete_type (reader->type_str, reader->type_pos);  } +static void +reader_fixed_length_set_basic (DBusTypeReader *reader, +                               int             current_type, +                               const void     *value) +{ +  _dbus_marshal_set_basic_type ((DBusString*) reader->value_str, +                                reader->value_pos, +                                current_type, +                                value, +                                reader->byte_order, +                                NULL, NULL); +} + +/** + *  Sets a new value for the basic type pointed to by the reader, + *  leaving the reader valid to continue reading. Any other + *  readers may of course be invalidated if you set a variable-length + *  type such as a string. + * + *  @todo DBusTypeReader currently takes "const" versions of the + *  type and value strings, and this function modifies those strings + *  by casting away the const, which is of course bad if we want to + *  get picky. (To be truly clean you'd have an object which contained + *  the type and value strings and set_basic would be a method on + *  that object... this would also make DBusTypeReader the same thing + *  as DBusTypeMark. But since DBusMessage is effectively that object + *  for D-BUS it doesn't seem worth creating some random object.) + * + * @param reader reader indicating where to set a new value + * @param value address of the value to set + * @returns #FALSE if not enough memory + */ +dbus_bool_t +_dbus_type_reader_set_basic (DBusTypeReader *reader, +                             const void     *value) +{ +  int current_type; +  dbus_bool_t retval; + +  retval = FALSE; + +  current_type = _dbus_type_reader_get_current_type (reader); + +  _dbus_assert (_dbus_type_is_basic (current_type)); + +  if (!_dbus_type_length_varies (current_type)) +    { +      reader_fixed_length_set_basic (reader, current_type, value); +      return TRUE; +    } + +  /* FIXME */ + +  retval = TRUE; + + out: + +  return retval; +} +  /*   *   * @@ -882,7 +946,7 @@ _dbus_type_reader_get_signature (const DBusTypeReader  *reader,   * @param type_pos where to insert typecodes   * @param value_str the string to write values into   * @param value_pos where to insert values - *  + *   */  void  _dbus_type_writer_init (DBusTypeWriter *writer, @@ -1060,7 +1124,7 @@ writer_recurse_struct (DBusTypeWriter   *writer,     * almost trivially fix the code so if it's present we     * write it out and then set type_pos_is_expectation     */ -   +    /* Ensure that we'll be able to add alignment padding and the typecode */    if (!_dbus_string_alloc_space (sub->value_str, 8))      return FALSE; @@ -1278,7 +1342,7 @@ _dbus_type_writer_recurse_contained_len (DBusTypeWriter   *writer,                                           DBusTypeWriter   *sub)  {    writer_recurse_init_and_check (writer, container_type, sub); -   +    switch (container_type)      {      case DBUS_TYPE_STRUCT: @@ -1356,9 +1420,9 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer,        /* Set the array length */        len = sub->value_pos - sub->u.array.start_pos;        _dbus_marshal_set_uint32 (sub->value_str, -                                sub->byte_order,                                  sub->u.array.len_pos, -                                len); +                                len, +                                sub->byte_order);  #if RECURSIVE_MARSHAL_TRACE        _dbus_verbose ("    filled in sub array len to %u at len_pos %d\n",                       len, sub->u.array.len_pos); @@ -1483,11 +1547,11 @@ _dbus_type_writer_write_reader (DBusTypeWriter *writer,    int orig_value_len;    int new_bytes;    int current_type; -   +    orig = *writer;    orig_type_len = _dbus_string_get_length (writer->type_str);    orig_value_len = _dbus_string_get_length (writer->value_str); -   +    while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)      {        switch (current_type) @@ -1511,7 +1575,7 @@ _dbus_type_writer_write_reader (DBusTypeWriter *writer,                                                            sig_str, sig_start, sig_len,                                                            &subwriter))                goto oom; -             +              if (!_dbus_type_writer_write_reader (&subwriter, &subreader))                goto oom; @@ -1523,7 +1587,7 @@ _dbus_type_writer_write_reader (DBusTypeWriter *writer,          default:            {              DBusBasicValue val; -             +              _dbus_type_reader_read_basic (reader, &val);              if (!_dbus_type_writer_write_basic (writer, current_type, &val)) @@ -1531,7 +1595,7 @@ _dbus_type_writer_write_reader (DBusTypeWriter *writer,            }            break;          } -       +        _dbus_type_reader_next (reader);      } @@ -1547,7 +1611,7 @@ _dbus_type_writer_write_reader (DBusTypeWriter *writer,    _dbus_string_delete (writer->value_str, orig.value_pos, new_bytes);    *writer = orig; -   +    return FALSE;  } @@ -1616,7 +1680,7 @@ data_block_init (DataBlock *block,    block->byte_order = byte_order;    block->initial_offset = initial_offset; -   +    return TRUE;  } @@ -1651,7 +1715,7 @@ data_block_verify (DataBlock *block)        offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;        if (offset < 0)          offset = 0; -       +        _dbus_verbose_bytes_of_string (&block->signature,                                       offset,                                       _dbus_string_get_length (&block->signature) - offset); @@ -1671,7 +1735,7 @@ data_block_verify (DataBlock *block)                                       _dbus_string_get_length (&block->body) - offset);        _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");      } -   +    _dbus_assert (_dbus_string_validate_nul (&block->signature,                                             0, block->initial_offset));    _dbus_assert (_dbus_string_validate_nul (&block->body, @@ -1682,7 +1746,7 @@ static void  data_block_free (DataBlock *block)  {    data_block_verify (block); -   +    _dbus_string_free (&block->signature);    _dbus_string_free (&block->body);  } @@ -1691,7 +1755,7 @@ static void  data_block_reset (DataBlock *block)  {    data_block_verify (block); -   +    _dbus_string_delete (&block->signature,                         block->initial_offset,                         _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset); @@ -2195,14 +2259,14 @@ node_write_value (TestTypeNode   *node,                    int             seed)  {    dbus_bool_t retval; -   +    retval = (* node->klass->write_value) (node, block, writer, seed);  #if 0    /* Handy to see where things break, but too expensive to do all the time */    data_block_verify (block);  #endif -   +    return retval;  } @@ -2216,7 +2280,7 @@ node_read_value (TestTypeNode   *node,    DBusTypeReader restored;    _dbus_type_reader_save_mark (reader, &mark); -   +    if (!(* node->klass->read_value) (node, block, reader, seed))      return FALSE; @@ -2231,7 +2295,7 @@ node_read_value (TestTypeNode   *node,    if (!(* node->klass->read_value) (node, block, &restored, seed))      return FALSE; -   +    return TRUE;  } @@ -2266,9 +2330,9 @@ run_test_copy (DataBlock *src)    dbus_bool_t retval;    DBusTypeReader reader;    DBusTypeWriter writer; -   +    retval = FALSE; -   +    if (!data_block_init (&dest, src->byte_order, src->initial_offset))      return FALSE; @@ -2281,7 +2345,7 @@ run_test_copy (DataBlock *src)    if (!_dbus_string_insert_byte (&dest.signature,                                   dest.initial_offset, '\0'))      goto out; -   +    if (!_dbus_type_writer_write_reader (&writer, &reader))      goto out; @@ -2307,13 +2371,13 @@ run_test_copy (DataBlock *src)                                       _dbus_string_get_length (&dest.body));        _dbus_assert_not_reached ("bodies did not match");      } -   +    retval = TRUE;   out:    data_block_free (&dest); -   +    return retval;  } @@ -2346,7 +2410,7 @@ run_test_nodes_iteration (void *data)     * 4. type-iterate the signature and the value and see if they are the same type-wise     */    retval = FALSE; -   +    data_block_init_reader_writer (nid->block,                                   &reader, &writer); @@ -2356,7 +2420,7 @@ run_test_nodes_iteration (void *data)    if (!_dbus_string_insert_byte (&nid->block->signature,                                   nid->type_offset, '\0'))      goto out; -   +    i = 0;    while (i < nid->n_nodes)      { @@ -2392,17 +2456,17 @@ run_test_nodes_iteration (void *data)    if (n_iterations_expected_this_test <= MAX_ITERATIONS_TO_TEST_COPYING)      run_test_copy (nid->block); -   +    /* FIXME type-iterate both signature and value and compare the resulting     * tree to the node tree perhaps     */ -   +    retval = TRUE; -   +   out: -   +    data_block_reset (nid->block); -   +    return retval;  } @@ -2485,7 +2549,7 @@ run_test_nodes (TestTypeNode **nodes,      {        fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));      } -   +    _dbus_string_free (&signature);  } @@ -2578,7 +2642,7 @@ start_next_test (const char *format,    n_iterations_expected_this_test = expected;    fprintf (stderr, ">>> >>> "); -  fprintf (stderr, format,  +  fprintf (stderr, format,             n_iterations_expected_this_test);  } @@ -3075,7 +3139,7 @@ string_write_value (TestTypeNode   *node,    string_from_seed (buf, node->klass->subclass_detail,                      seed); -   +    return _dbus_type_writer_write_basic (writer,                                          node->klass->typecode,                                          &v_string); @@ -3265,7 +3329,7 @@ object_path_write_value (TestTypeNode   *node,  {    char buf[MAX_SAMPLE_OBJECT_PATH_LEN];    const char *v_string = buf; -   +    object_path_from_seed (buf, seed);    return _dbus_type_writer_write_basic (writer, @@ -3332,7 +3396,7 @@ signature_write_value (TestTypeNode   *node,  {    char buf[MAX_SAMPLE_SIGNATURE_LEN];    const char *v_string = buf; -   +    signature_from_seed (buf, seed);    return _dbus_type_writer_write_basic (writer, diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h index 79ce52c2..064bf156 100644 --- a/dbus/dbus-marshal-recursive.h +++ b/dbus/dbus-marshal-recursive.h @@ -46,6 +46,8 @@   *  - implement has_next()   *  - the all-in-one-block array accessors   *  - validation + * + * - remember to try a HAVE_INT64=0 build at the end   */  typedef struct DBusTypeMark        DBusTypeMark; @@ -54,7 +56,12 @@ typedef struct DBusTypeWriter      DBusTypeWriter;  typedef struct DBusTypeReaderClass DBusTypeReaderClass;  /* The mark is a way to compress a TypeReader; it isn't all that - * successful though. + * successful though. The idea was to use this for caching header + * fields in dbus-message.c. However now I'm thinking why not cache + * the actual values (e.g. char*) and if the field needs to be set or + * deleted, just linear search for it. Those operations are uncommon, + * and getting the values should be fast and not involve all this type + * reader nonsense.   */  struct DBusTypeMark  { @@ -145,6 +152,8 @@ void        _dbus_type_reader_get_signature             (const DBusTypeReader  *                                                           const DBusString     **str_p,                                                           int                   *start_p,                                                           int                   *len_p); +dbus_bool_t _dbus_type_reader_set_basic                 (DBusTypeReader        *reader, +                                                         const void            *value);  void        _dbus_type_writer_init         (DBusTypeWriter   *writer,                                              int               byte_order, @@ -169,6 +178,4 @@ dbus_bool_t _dbus_type_writer_unrecurse    (DBusTypeWriter   *writer,  dbus_bool_t _dbus_type_writer_write_reader (DBusTypeWriter   *writer,                                              DBusTypeReader   *reader); - -  #endif /* DBUS_MARSHAL_RECURSIVE_H */  | 
