diff options
Diffstat (limited to 'dbus/dbus-marshal.c')
-rw-r--r-- | dbus/dbus-marshal.c | 2941 |
1 files changed, 0 insertions, 2941 deletions
diff --git a/dbus/dbus-marshal.c b/dbus/dbus-marshal.c deleted file mode 100644 index 00821daf..00000000 --- a/dbus/dbus-marshal.c +++ /dev/null @@ -1,2941 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-marshal.c Marshalling routines - * - * Copyright (C) 2002 CodeFactory AB - * Copyright (C) 2003, 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 - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * 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 - * - */ - -#include "dbus-marshal.h" -#include "dbus-internals.h" -#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 -#include "dbus-string-private.h" - -#include <string.h> - -/** - * @defgroup DBusMarshal marshaling and unmarshaling - * @ingroup DBusInternals - * @brief functions to marshal/unmarshal data from the wire - * - * Types and functions related to converting primitive data types from - * wire format to native machine format, and vice versa. - * - * @{ - */ - -static dbus_uint32_t -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 - return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data); -} - -#ifndef DBUS_HAVE_INT64 -/* from ORBit */ -static void -swap_bytes (unsigned char *data, - unsigned int len) -{ - unsigned char *p1 = data; - unsigned char *p2 = data + len - 1; - - while (p1 < p2) - { - unsigned char tmp = *p1; - *p1 = *p2; - *p2 = tmp; - - --p2; - ++p1; - } -} -#endif /* !DBUS_HAVE_INT64 */ - -/** - * Union used to manipulate 8 bytes as if they - * were various types. - */ -typedef union -{ -#ifdef DBUS_HAVE_INT64 - dbus_int64_t s; /**< 64-bit integer */ - dbus_uint64_t u; /**< 64-bit unsinged integer */ -#endif - double d; /**< double */ -} DBusOctets8; - -static DBusOctets8 -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); - else - r.u = 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)); -#endif - - return r; -} - -/** - * Unpacks a 32 bit unsigned integer from a data pointer - * - * @param byte_order The byte order to use - * @param data the data pointer - * @returns the integer - */ -dbus_uint32_t -_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 - * - * @param byte_order The byte order to use - * @param data the data pointer - * @returns the integer - */ -dbus_int32_t -_dbus_unpack_int32 (int byte_order, - const unsigned char *data) -{ - 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 -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); - if (byte_order != DBUS_COMPILER_BYTE_ORDER) - swap_bytes ((unsigned char *)data, 8); -#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) -{ - 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); -} - -static void -set_8_octets (DBusString *str, - int byte_order, - int offset, - 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); -} - -/** - * 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 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) -{ - DBusOctets8 r; - r.u = value; - set_8_octets (str, byte_order, offset, r); -} -#endif /* DBUS_HAVE_INT64 */ - -/** - * Sets the existing marshaled string at the given offset with - * a new marshaled string. The given offset must point to - * an existing string or the wrong length will be deleted - * and replaced with the new string. - * - * Note: no attempt is made by this function to re-align - * any data which has been already marshalled after this - * 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 byte_order the byte order to use - * @param value the value - * @param len the length to use - * @returns #TRUE on success - * - */ -dbus_bool_t -_dbus_marshal_set_string (DBusString *str, - int byte_order, - int offset, - const DBusString *value, - 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); - - if (!_dbus_string_replace_len (value, 0, len, - str, offset + 4, old_len)) - return FALSE; - - _dbus_marshal_set_uint32 (str, byte_order, - offset, len); - - 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 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_append_4_aligned (str, - (const unsigned char *)&value); -} - -static dbus_bool_t -marshal_8_octets (DBusString *str, - int byte_order, - DBusOctets8 value) -{ - _dbus_assert (sizeof (value) == 8); - - if (byte_order != DBUS_COMPILER_BYTE_ORDER) - pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */ - - return _dbus_string_append_8_aligned (str, - (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, 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, 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, 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, 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, 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; -} - -/** - * 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); - - if (!_dbus_marshal_uint32 (str, byte_order, len * 8)) - goto error; - - array_start = _dbus_string_get_length (str); - - 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 - */ -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); - - return r.d; -} - -/** - * 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. - * - * @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_uint32_t -_dbus_demarshal_uint32 (const DBusString *str, - 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 - * - * @param str the string containing the data - * @param type type of value to demarshal - * @param value pointer to return value data - * @param byte_order the byte order - * @param pos pointer to position in the string, - * updated on return to new position - **/ -void -_dbus_demarshal_basic_type (const DBusString *str, - int type, - void *value, - int byte_order, - int *pos) -{ - const char *str_data = _dbus_string_get_const_data (str); - - switch (type) - { - case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: - *(unsigned char *) value = _dbus_string_get_byte (str, *pos); - (*pos)++; - break; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - *pos = _DBUS_ALIGN_VALUE (*pos, 4); - *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos); - if (byte_order != DBUS_COMPILER_BYTE_ORDER) - *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value); - *pos += 4; - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - *pos = _DBUS_ALIGN_VALUE (*pos, 8); - memcpy (value, str_data + *pos, 8); - if (byte_order != DBUS_COMPILER_BYTE_ORDER) -#ifdef DBUS_HAVE_INT64 - *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value); -#else - swap_bytes (value, 8); -#endif - *pos += 8; - break; - default: - _dbus_assert_not_reached ("not a basic type"); - break; - } -} - -/** - * Demarshals an UTF-8 string. - * - * @todo Should we check the string to make sure - * 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); - 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); -} - -#endif /* DBUS_HAVE_INT64 */ - -/** - * 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); - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - return demarshal_8_octets_array (str, byte_order, *pos, pos, - (DBusOctets8**) array, array_len); - default: - _dbus_assert_not_reached ("not a basic type"); - break; - } - return FALSE; -} - -/** - * Demarshals a string array. - * - * @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; -} - -/** - * 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_NIL: - *end_pos = pos; - 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_CUSTOM: - { - int len; - - /* Demarshal the string length */ - len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - - pos += len + 1; - - /* Demarshal the data length */ - len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - - *end_pos = pos + len; - } - break; - - case DBUS_TYPE_ARRAY: - { - int len; - - /* Demarshal the length */ - len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - - *end_pos = pos + len; - } - break; - - case DBUS_TYPE_DICT: - { - int len; - - /* Demarshal the length */ - len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); - - *end_pos = pos + 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_NIL: - break; - - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_STRING: - case DBUS_TYPE_CUSTOM: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_DICT: - /* 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; - } - -#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; - - case DBUS_TYPE_NIL: - *end_pos = pos; - break; - - 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; - - 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; - - 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_CUSTOM: - { - int len; - - /* Demarshal the string 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, &pos)) - return FALSE; - - /* Validate data */ - len = demarshal_and_validate_len (str, byte_order, pos, &pos); - if (len < 0) - return FALSE; - - *end_pos = pos + len; - } - 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; - } - - /* NIL values take up no space, so you couldn't iterate over an array of them. - * array of nil seems useless anyway; the useful thing might be array of - * (nil OR string) but we have no framework for that. - */ - if (array_type == DBUS_TYPE_NIL) - { - _dbus_verbose ("array of NIL is not allowed\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; - - case DBUS_TYPE_DICT: - { - int dict_type; - int len; - int end; - - len = demarshal_and_validate_len (str, byte_order, pos, &pos); - if (len < 0) - return FALSE; - - if (len > _dbus_string_get_length (str) - pos) - { - _dbus_verbose ("dict length outside length of the message\n"); - return FALSE; - } - - end = pos + len; - - while (pos < end) - { - /* Validate name */ - if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, - DBUS_TYPE_STRING, -1, pos, &pos)) - return FALSE; - - if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos)) - { - _dbus_verbose ("invalid dict entry type at offset %d\n", pos); - return FALSE; - } - - /* Validate element */ - if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, - dict_type, -1, pos, &pos)) - { - _dbus_verbose ("dict arg invalid at offset %d\n", pos); - return FALSE; - } - } - - if (pos > end) - { - _dbus_verbose ("dict contents exceed stated dict length\n"); - return FALSE; - } - - *end_pos = pos; - } - break; - - default: - _dbus_verbose ("Unknown message arg type %d\n", type); - return FALSE; - } - - if (*end_pos > _dbus_string_get_length (str)) - return FALSE; - - return TRUE; -} - -/** - * 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_NIL: - 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_CUSTOM: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_DICT: - case DBUS_TYPE_OBJECT_PATH: - return TRUE; - - default: - return FALSE; - } -} - -/** - * 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 - */ -void -_dbus_verbose_bytes (const unsigned char *data, - int len) -{ - 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: ", - 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); -} - -/** - * Marshals a basic type - * - * @param str string to marshal to - * @param type type of value - * @param value pointer to value - * @param byte_order byte order - * @returns #TRUE on success - **/ -dbus_bool_t -_dbus_marshal_basic_type (DBusString *str, - char type, - void *value, - int byte_order) -{ - dbus_bool_t retval; - - switch (type) - { - case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: - retval = _dbus_string_append_byte (str, *(unsigned char *)value); - break; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - return marshal_4_octets (str, byte_order, *(dbus_uint32_t *)value); - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: - retval = _dbus_marshal_uint64 (str, byte_order, *(dbus_uint64_t *)value); - break; -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - retval = _dbus_marshal_double (str, byte_order, *(double *)value); - break; - default: - _dbus_assert_not_reached ("not a basic type"); - retval = FALSE; - break; - } - return retval; -} - -/** - * Marshals a basic type array - * - * @param str string to marshal to - * @param element_type type of array elements - * @param value pointer to value - * @param len length of value data in elements - * @param byte_order byte order - * @returns #TRUE on success - **/ -dbus_bool_t -_dbus_marshal_basic_type_array (DBusString *str, - char element_type, - const void *value, - int len, - int byte_order) -{ - switch (element_type) - { - case DBUS_TYPE_BOOLEAN: - /* FIXME: we canonicalize to 0 or 1 for the single boolean case - * should we here too ? */ - case DBUS_TYPE_BYTE: - return _dbus_marshal_byte_array (str, byte_order, value, len); - break; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - return marshal_4_octets_array (str, byte_order, value, len); - break; -#ifdef DBUS_HAVE_INT64 - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: -#endif /* DBUS_HAVE_INT64 */ - case DBUS_TYPE_DOUBLE: - return marshal_8_octets_array (str, byte_order, value, len); - break; - default: - _dbus_assert_not_reached ("non basic type in array"); - break; - } - return FALSE; -} - -/** @} */ - -#ifdef DBUS_BUILD_TESTS -#include "dbus-test.h" -#include <stdio.h> - -dbus_bool_t -_dbus_marshal_test (void) -{ - DBusString str; - char *tmp1, *tmp2; - int pos = 0, len; - 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_CONSTANT (0x789ffffffff) }, *array4; -#endif - char *s; - DBusString t; - - if (!_dbus_string_init (&str)) - _dbus_assert_not_reached ("failed to init string"); - - /* 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 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 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"); - -#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 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"); -#endif /* DBUS_HAVE_INT64 */ - - /* 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); - -#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"); - - if (len != 3) - _dbus_assert_not_reached ("Signed integer array lengths differ!\n"); - dbus_free (array4); - - /* set/pack 64-bit integers */ - _dbus_string_set_length (&str, 8); - - /* 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))); - - /* signed big */ - _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN, - 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); - - _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == - _dbus_unpack_int64 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* signed little pack */ - _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))); - - /* signed big pack */ - _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), - DBUS_BIG_ENDIAN, - _dbus_string_get_data (&str)); - - _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == - _dbus_unpack_int64 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* 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))); - - /* unsigned big */ - _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN, - 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); - - _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == - _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* unsigned little pack */ - _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))); - - /* unsigned big pack */ - _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), - DBUS_BIG_ENDIAN, - _dbus_string_get_data (&str)); - - _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); - - /* 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))); - - /* signed big */ - _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN, - 0, -0x123456); - - _dbus_assert (-0x123456 == - _dbus_unpack_int32 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* signed little pack */ - _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))); - - /* signed big pack */ - _dbus_pack_int32 (-0x123456, - DBUS_BIG_ENDIAN, - _dbus_string_get_data (&str)); - - _dbus_assert (-0x123456 == - _dbus_unpack_int32 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* 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))); - - /* unsigned big */ - _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN, - 0, 0x123456); - - _dbus_assert (0x123456 == - _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - /* unsigned little pack */ - _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))); - - /* unsigned big pack */ - _dbus_pack_uint32 (0x123456, - DBUS_BIG_ENDIAN, - _dbus_string_get_data (&str)); - - _dbus_assert (0x123456 == - _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, - _dbus_string_get_const_data (&str))); - - - /* 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_string_free (&str); - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ |