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; |