Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-marshal-basic.c  Marshalling routines for basic (primitive) types
      3  *
      4  * Copyright (C) 2002 CodeFactory AB
      5  * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
      6  *
      7  * Licensed under the Academic Free License version 2.1
      8  *
      9  * This program is free software; you can redistribute it and/or modify
     10  * it under the terms of the GNU General Public License as published by
     11  * the Free Software Foundation; either version 2 of the License, or
     12  * (at your option) any later version.
     13  *
     14  * This program is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  * GNU General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU General Public License
     20  * along with this program; if not, write to the Free Software
     21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     22  *
     23  */
     24 
     25 #include <config.h>
     26 #include "dbus-internals.h"
     27 #include "dbus-marshal-basic.h"
     28 #include "dbus-signature.h"
     29 
     30 #include <string.h>
     31 
     32 #if defined(__GNUC__) && (__GNUC__ >= 4)
     33 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
     34   _DBUS_STATIC_ASSERT (__extension__ __alignof__ (type) op val)
     35 #else
     36   /* not gcc, so probably no alignof operator: just use a no-op statement
     37    * that's valid in the same contexts */
     38 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
     39   _DBUS_STATIC_ASSERT (TRUE)
     40 #endif
     41 
     42 /* True by definition, but just for completeness... */
     43 _DBUS_STATIC_ASSERT (sizeof (char) == 1);
     44 _DBUS_ASSERT_ALIGNMENT (char, ==, 1);
     45 
     46 _DBUS_STATIC_ASSERT (sizeof (dbus_int16_t) == 2);
     47 _DBUS_ASSERT_ALIGNMENT (dbus_int16_t, <=, 2);
     48 _DBUS_STATIC_ASSERT (sizeof (dbus_uint16_t) == 2);
     49 _DBUS_ASSERT_ALIGNMENT (dbus_uint16_t, <=, 2);
     50 
     51 _DBUS_STATIC_ASSERT (sizeof (dbus_int32_t) == 4);
     52 _DBUS_ASSERT_ALIGNMENT (dbus_int32_t, <=, 4);
     53 _DBUS_STATIC_ASSERT (sizeof (dbus_uint32_t) == 4);
     54 _DBUS_ASSERT_ALIGNMENT (dbus_uint32_t, <=, 4);
     55 _DBUS_STATIC_ASSERT (sizeof (dbus_bool_t) == 4);
     56 _DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4);
     57 
     58 _DBUS_STATIC_ASSERT (sizeof (double) == 8);
     59 _DBUS_ASSERT_ALIGNMENT (double, <=, 8);
     60 
     61 #ifdef DBUS_HAVE_INT64
     62 _DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8);
     63 _DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8);
     64 _DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8);
     65 _DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8);
     66 #endif
     67 
     68 _DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8);
     69 /* The alignment of a DBusBasicValue might conceivably be > 8 because of the
     70  * pointer, so we don't assert about it */
     71 
     72 _DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8);
     73 _DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8);
     74 
     75 /**
     76  * @defgroup DBusMarshal marshaling and unmarshaling
     77  * @ingroup  DBusInternals
     78  * @brief functions to marshal/unmarshal data from the wire
     79  *
     80  * Types and functions related to converting primitive data types from
     81  * wire format to native machine format, and vice versa.
     82  *
     83  * A signature is just a string with multiple types one after the other.
     84  * for example a type is "i" or "(ii)", a signature is "i(ii)"
     85  * where i is int and (ii) is struct { int; int; }
     86  *
     87  * @{
     88  */
     89 
     90 static void
     91 pack_2_octets (dbus_uint16_t   value,
     92                int             byte_order,
     93                unsigned char  *data)
     94 {
     95   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
     96 
     97   if ((byte_order) == DBUS_LITTLE_ENDIAN)
     98     *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
     99   else
    100     *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
    101 }
    102 
    103 static void
    104 pack_4_octets (dbus_uint32_t   value,
    105                int             byte_order,
    106                unsigned char  *data)
    107 {
    108   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
    109 
    110   if ((byte_order) == DBUS_LITTLE_ENDIAN)
    111     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
    112   else
    113     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
    114 }
    115 
    116 static void
    117 pack_8_octets (DBusBasicValue     value,
    118                int                byte_order,
    119                unsigned char     *data)
    120 {
    121   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
    122 
    123 #ifdef DBUS_HAVE_INT64
    124   if ((byte_order) == DBUS_LITTLE_ENDIAN)
    125     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
    126   else
    127     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
    128 #else
    129   *(DBus8ByteStruct*)data = value.eight;
    130   swap_8_octets ((DBusBasicValue*)data, byte_order);
    131 #endif
    132 }
    133 
    134 /**
    135  * Packs a 32 bit unsigned integer into a data pointer.
    136  *
    137  * @param value the value
    138  * @param byte_order the byte order to use
    139  * @param data the data pointer
    140  */
    141 void
    142 _dbus_pack_uint32 (dbus_uint32_t   value,
    143                    int             byte_order,
    144                    unsigned char  *data)
    145 {
    146   pack_4_octets (value, byte_order, data);
    147 }
    148 
    149 #ifndef DBUS_HAVE_INT64
    150 /* from ORBit */
    151 static void
    152 swap_bytes (unsigned char *data,
    153             unsigned int   len)
    154 {
    155   unsigned char *p1 = data;
    156   unsigned char *p2 = data + len - 1;
    157 
    158   while (p1 < p2)
    159     {
    160       unsigned char tmp = *p1;
    161       *p1 = *p2;
    162       *p2 = tmp;
    163 
    164       --p2;
    165       ++p1;
    166     }
    167 }
    168 #endif /* !DBUS_HAVE_INT64 */
    169 
    170 static void
    171 swap_8_octets (DBusBasicValue    *value,
    172                int                byte_order)
    173 {
    174   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    175     {
    176 #ifdef DBUS_HAVE_INT64
    177       value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
    178 #else
    179       swap_bytes (&value->bytes, 8);
    180 #endif
    181     }
    182 }
    183 
    184 #if 0
    185 static DBusBasicValue
    186 unpack_8_octets (int                  byte_order,
    187                  const unsigned char *data)
    188 {
    189   DBusBasicValue r;
    190 
    191   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
    192   _dbus_assert (sizeof (r) == 8);
    193 
    194 #ifdef DBUS_HAVE_INT64
    195   if (byte_order == DBUS_LITTLE_ENDIAN)
    196     r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
    197   else
    198     r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
    199 #else
    200   r.eight = *(DBus8ByteStruct*)data;
    201   swap_8_octets (&r, byte_order);
    202 #endif
    203 
    204   return r;
    205 }
    206 #endif
    207 
    208 #ifndef _dbus_unpack_uint16
    209 /**
    210  * Unpacks a 16 bit unsigned integer from a data pointer
    211  *
    212  * @param byte_order The byte order to use
    213  * @param data the data pointer
    214  * @returns the integer
    215  */
    216 dbus_uint16_t
    217 _dbus_unpack_uint16 (int                  byte_order,
    218                      const unsigned char *data)
    219 {
    220   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
    221 
    222   if (byte_order == DBUS_LITTLE_ENDIAN)
    223     return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
    224   else
    225     return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
    226 }
    227 #endif /* _dbus_unpack_uint16 */
    228 
    229 #ifndef _dbus_unpack_uint32
    230 /**
    231  * Unpacks a 32 bit unsigned integer from a data pointer
    232  *
    233  * @param byte_order The byte order to use
    234  * @param data the data pointer
    235  * @returns the integer
    236  */
    237 dbus_uint32_t
    238 _dbus_unpack_uint32 (int                  byte_order,
    239                      const unsigned char *data)
    240 {
    241   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
    242 
    243   if (byte_order == DBUS_LITTLE_ENDIAN)
    244     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
    245   else
    246     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
    247 }
    248 #endif /* _dbus_unpack_uint32 */
    249 
    250 static void
    251 set_2_octets (DBusString          *str,
    252               int                  offset,
    253               dbus_uint16_t        value,
    254               int                  byte_order)
    255 {
    256   char *data;
    257 
    258   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
    259                 byte_order == DBUS_BIG_ENDIAN);
    260 
    261   data = _dbus_string_get_data_len (str, offset, 2);
    262 
    263   pack_2_octets (value, byte_order, data);
    264 }
    265 
    266 static void
    267 set_4_octets (DBusString          *str,
    268               int                  offset,
    269               dbus_uint32_t        value,
    270               int                  byte_order)
    271 {
    272   char *data;
    273 
    274   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
    275                 byte_order == DBUS_BIG_ENDIAN);
    276 
    277   data = _dbus_string_get_data_len (str, offset, 4);
    278 
    279   pack_4_octets (value, byte_order, data);
    280 }
    281 
    282 static void
    283 set_8_octets (DBusString          *str,
    284               int                  offset,
    285               DBusBasicValue       value,
    286               int                  byte_order)
    287 {
    288   char *data;
    289 
    290   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
    291                 byte_order == DBUS_BIG_ENDIAN);
    292 
    293   data = _dbus_string_get_data_len (str, offset, 8);
    294 
    295   pack_8_octets (value, byte_order, data);
    296 }
    297 
    298 /**
    299  * Sets the 4 bytes at the given offset to a marshaled unsigned
    300  * integer, replacing anything found there previously.
    301  *
    302  * @param str the string to write the marshalled int to
    303  * @param pos the byte offset where int should be written
    304  * @param value the value
    305  * @param byte_order the byte order to use
    306  *
    307  */
    308 void
    309 _dbus_marshal_set_uint32 (DBusString          *str,
    310                           int                  pos,
    311                           dbus_uint32_t        value,
    312                           int                  byte_order)
    313 {
    314   set_4_octets (str, pos, value, byte_order);
    315 }
    316 
    317 /**
    318  * Sets the existing marshaled string at the given offset with
    319  * a new marshaled string. The given offset must point to
    320  * an existing string or the wrong length will be deleted
    321  * and replaced with the new string.
    322  *
    323  * Note: no attempt is made by this function to re-align
    324  * any data which has been already marshalled after this
    325  * string. Use with caution.
    326  *
    327  * @param str the string to write the marshalled string to
    328  * @param pos the position of the marshaled string length
    329  * @param value the value
    330  * @param byte_order the byte order to use
    331  * @param old_end_pos place to store byte after the nul byte of the old value
    332  * @param new_end_pos place to store byte after the nul byte of the new value
    333  * @returns #TRUE on success, #FALSE if no memory
    334  *
    335  */
    336 static dbus_bool_t
    337 set_string (DBusString          *str,
    338             int                  pos,
    339             const char          *value,
    340             int                  byte_order,
    341             int                 *old_end_pos,
    342             int                 *new_end_pos)
    343 {
    344   int old_len, new_len;
    345   DBusString dstr;
    346 
    347   _dbus_string_init_const (&dstr, value);
    348 
    349   _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
    350   old_len = _dbus_unpack_uint32 (byte_order,
    351                                  _dbus_string_get_const_data_len (str, pos, 4));
    352 
    353   new_len = _dbus_string_get_length (&dstr);
    354 
    355   if (!_dbus_string_replace_len (&dstr, 0, new_len,
    356                                  str, pos + 4, old_len))
    357     return FALSE;
    358 
    359   _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
    360 
    361   if (old_end_pos)
    362     *old_end_pos = pos + 4 + old_len + 1;
    363   if (new_end_pos)
    364     *new_end_pos = pos + 4 + new_len + 1;
    365 
    366   return TRUE;
    367 }
    368 
    369 /**
    370  * Sets the existing marshaled signature at the given offset to a new
    371  * marshaled signature. Same basic ideas as set_string().
    372  *
    373  * @param str the string to write the marshalled signature to
    374  * @param pos the position of the marshaled signature length
    375  * @param value the value
    376  * @param byte_order the byte order to use
    377  * @param old_end_pos place to store byte after the nul byte of the old value
    378  * @param new_end_pos place to store byte after the nul byte of the new value
    379  * @returns #TRUE on success, #FALSE if no memory
    380  *
    381  */
    382 static dbus_bool_t
    383 set_signature (DBusString          *str,
    384                int                  pos,
    385                const char          *value,
    386                int                  byte_order,
    387                int                 *old_end_pos,
    388                int                 *new_end_pos)
    389 {
    390   int old_len, new_len;
    391   DBusString dstr;
    392 
    393   _dbus_string_init_const (&dstr, value);
    394 
    395   old_len = _dbus_string_get_byte (str, pos);
    396   new_len = _dbus_string_get_length (&dstr);
    397 
    398   if (!_dbus_string_replace_len (&dstr, 0, new_len,
    399                                  str, pos + 1, old_len))
    400     return FALSE;
    401 
    402   _dbus_string_set_byte (str, pos, new_len);
    403 
    404   if (old_end_pos)
    405     *old_end_pos = pos + 1 + old_len + 1;
    406   if (new_end_pos)
    407     *new_end_pos = pos + 1 + new_len + 1;
    408 
    409   return TRUE;
    410 }
    411 
    412 /**
    413  * Sets an existing basic type value to a new value.
    414  * Arguments work the same way as _dbus_marshal_basic_type().
    415  *
    416  * @param str the string
    417  * @param pos location of the current value
    418  * @param type the type of the current and new values
    419  * @param value the address of the new value
    420  * @param byte_order byte order for marshaling
    421  * @param old_end_pos location to store end position of the old value, or #NULL
    422  * @param new_end_pos location to store end position of the new value, or #NULL
    423  * @returns #FALSE if no memory
    424  */
    425 dbus_bool_t
    426 _dbus_marshal_set_basic (DBusString       *str,
    427                          int               pos,
    428                          int               type,
    429                          const void       *value,
    430                          int               byte_order,
    431                          int              *old_end_pos,
    432                          int              *new_end_pos)
    433 {
    434   const DBusBasicValue *vp;
    435 
    436   vp = value;
    437 
    438   switch (type)
    439     {
    440     case DBUS_TYPE_BYTE:
    441       _dbus_string_set_byte (str, pos, vp->byt);
    442       if (old_end_pos)
    443         *old_end_pos = pos + 1;
    444       if (new_end_pos)
    445         *new_end_pos = pos + 1;
    446       return TRUE;
    447       break;
    448     case DBUS_TYPE_INT16:
    449     case DBUS_TYPE_UINT16:
    450       pos = _DBUS_ALIGN_VALUE (pos, 2);
    451       set_2_octets (str, pos, vp->u16, byte_order);
    452       if (old_end_pos)
    453         *old_end_pos = pos + 2;
    454       if (new_end_pos)
    455         *new_end_pos = pos + 2;
    456       return TRUE;
    457       break;
    458     case DBUS_TYPE_BOOLEAN:
    459     case DBUS_TYPE_INT32:
    460     case DBUS_TYPE_UINT32:
    461     case DBUS_TYPE_UNIX_FD:
    462       pos = _DBUS_ALIGN_VALUE (pos, 4);
    463       set_4_octets (str, pos, vp->u32, byte_order);
    464       if (old_end_pos)
    465         *old_end_pos = pos + 4;
    466       if (new_end_pos)
    467         *new_end_pos = pos + 4;
    468       return TRUE;
    469       break;
    470     case DBUS_TYPE_INT64:
    471     case DBUS_TYPE_UINT64:
    472     case DBUS_TYPE_DOUBLE:
    473       pos = _DBUS_ALIGN_VALUE (pos, 8);
    474       set_8_octets (str, pos, *vp, byte_order);
    475       if (old_end_pos)
    476         *old_end_pos = pos + 8;
    477       if (new_end_pos)
    478         *new_end_pos = pos + 8;
    479       return TRUE;
    480       break;
    481     case DBUS_TYPE_STRING:
    482     case DBUS_TYPE_OBJECT_PATH:
    483       pos = _DBUS_ALIGN_VALUE (pos, 4);
    484       _dbus_assert (vp->str != NULL);
    485       return set_string (str, pos, vp->str, byte_order,
    486                          old_end_pos, new_end_pos);
    487       break;
    488     case DBUS_TYPE_SIGNATURE:
    489       _dbus_assert (vp->str != NULL);
    490       return set_signature (str, pos, vp->str, byte_order,
    491                             old_end_pos, new_end_pos);
    492       break;
    493     default:
    494       _dbus_assert_not_reached ("not a basic type");
    495       return FALSE;
    496       break;
    497     }
    498 }
    499 
    500 /**
    501  * Convenience function to demarshal a 32 bit unsigned integer.
    502  *
    503  * @param str the string containing the data
    504  * @param byte_order the byte order
    505  * @param pos the position in the string
    506  * @param new_pos the new position of the string
    507  * @returns the demarshaled integer.
    508  */
    509 dbus_uint32_t
    510 _dbus_marshal_read_uint32  (const DBusString *str,
    511                             int               pos,
    512                             int               byte_order,
    513                             int              *new_pos)
    514 {
    515   pos = _DBUS_ALIGN_VALUE (pos, 4);
    516 
    517   if (new_pos)
    518     *new_pos = pos + 4;
    519 
    520   _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
    521 
    522   return _dbus_unpack_uint32 (byte_order,
    523                               _dbus_string_get_const_data (str) + pos);
    524 }
    525 
    526 /**
    527  * Demarshals a basic-typed value. The "value" pointer is always
    528  * the address of a variable of the basic type. So e.g.
    529  * if the basic type is "double" then the pointer is
    530  * a double*, and if it's "char*" then the pointer is
    531  * a "char**".
    532  *
    533  * A value of type #DBusBasicValue is guaranteed to be large enough to
    534  * hold any of the types that may be returned, which is handy if you
    535  * are trying to do things generically. For example you can pass
    536  * a DBusBasicValue* in to this function, and then pass the same
    537  * DBusBasicValue* in to _dbus_marshal_basic_type() in order to
    538  * move a value from one place to another.
    539  *
    540  * @param str the string containing the data
    541  * @param pos position in the string
    542  * @param type type of value to demarshal
    543  * @param value pointer to return value data
    544  * @param byte_order the byte order
    545  * @param new_pos pointer to update with new position, or #NULL
    546  **/
    547 void
    548 _dbus_marshal_read_basic (const DBusString      *str,
    549                           int                    pos,
    550                           int                    type,
    551                           void                  *value,
    552                           int                    byte_order,
    553                           int                   *new_pos)
    554 {
    555   const char *str_data;
    556 
    557   _dbus_assert (dbus_type_is_basic (type));
    558 
    559   str_data = _dbus_string_get_const_data (str);
    560 
    561   /* Below we volatile types to avoid aliasing issues;
    562    * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
    563    */
    564 
    565   switch (type)
    566     {
    567     case DBUS_TYPE_BYTE:
    568       {
    569       volatile unsigned char *vp = value;
    570       *vp = (unsigned char) _dbus_string_get_byte (str, pos);
    571       (pos)++;
    572       }
    573       break;
    574     case DBUS_TYPE_INT16:
    575     case DBUS_TYPE_UINT16:
    576       {
    577       volatile dbus_uint16_t *vp = value;
    578       pos = _DBUS_ALIGN_VALUE (pos, 2);
    579       *vp = *(dbus_uint16_t *)(str_data + pos);
    580       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    581 	*vp = DBUS_UINT16_SWAP_LE_BE (*vp);
    582       pos += 2;
    583       }
    584       break;
    585     case DBUS_TYPE_INT32:
    586     case DBUS_TYPE_UINT32:
    587     case DBUS_TYPE_BOOLEAN:
    588     case DBUS_TYPE_UNIX_FD:
    589       {
    590       volatile dbus_uint32_t *vp = value;
    591       pos = _DBUS_ALIGN_VALUE (pos, 4);
    592       *vp = *(dbus_uint32_t *)(str_data + pos);
    593       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    594 	*vp = DBUS_UINT32_SWAP_LE_BE (*vp);
    595       pos += 4;
    596       }
    597       break;
    598     case DBUS_TYPE_INT64:
    599     case DBUS_TYPE_UINT64:
    600     case DBUS_TYPE_DOUBLE:
    601       {
    602       volatile dbus_uint64_t *vp = value;
    603       pos = _DBUS_ALIGN_VALUE (pos, 8);
    604 #ifdef DBUS_HAVE_INT64
    605       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    606         *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
    607       else
    608         *vp = *(dbus_uint64_t*)(str_data + pos);
    609 #else
    610       *vp = *(DBus8ByteStruct*) (str_data + pos);
    611       swap_8_octets (vp, byte_order);
    612 #endif
    613       pos += 8;
    614       }
    615       break;
    616     case DBUS_TYPE_STRING:
    617     case DBUS_TYPE_OBJECT_PATH:
    618       {
    619         int len;
    620         volatile char **vp = value;
    621 
    622         len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
    623 
    624         *vp = (char*) str_data + pos;
    625 
    626         pos += len + 1; /* length plus nul */
    627       }
    628       break;
    629     case DBUS_TYPE_SIGNATURE:
    630       {
    631         int len;
    632         volatile char **vp = value;
    633 
    634         len = _dbus_string_get_byte (str, pos);
    635         pos += 1;
    636 
    637         *vp = (char*) str_data + pos;
    638 
    639         pos += len + 1; /* length plus nul */
    640       }
    641       break;
    642     default:
    643       _dbus_warn_check_failed ("type %s %d not a basic type\n",
    644                                _dbus_type_to_string (type), type);
    645       _dbus_assert_not_reached ("not a basic type");
    646       break;
    647     }
    648 
    649   if (new_pos)
    650     *new_pos = pos;
    651 }
    652 
    653 static dbus_bool_t
    654 marshal_2_octets (DBusString   *str,
    655                   int           insert_at,
    656                   dbus_uint16_t value,
    657                   int           byte_order,
    658                   int          *pos_after)
    659 {
    660   dbus_bool_t retval;
    661   int orig_len;
    662 
    663   _dbus_assert (sizeof (value) == 2);
    664 
    665   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    666     value = DBUS_UINT16_SWAP_LE_BE (value);
    667 
    668   orig_len = _dbus_string_get_length (str);
    669 
    670   retval = _dbus_string_insert_2_aligned (str, insert_at,
    671                                           (const unsigned char *)&value);
    672 
    673   if (pos_after)
    674     {
    675       *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
    676       _dbus_assert (*pos_after <= _dbus_string_get_length (str));
    677     }
    678 
    679   return retval;
    680 }
    681 
    682 static dbus_bool_t
    683 marshal_4_octets (DBusString   *str,
    684                   int           insert_at,
    685                   dbus_uint32_t value,
    686                   int           byte_order,
    687                   int          *pos_after)
    688 {
    689   dbus_bool_t retval;
    690   int orig_len;
    691 
    692   _dbus_assert (sizeof (value) == 4);
    693 
    694   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
    695     value = DBUS_UINT32_SWAP_LE_BE (value);
    696 
    697   orig_len = _dbus_string_get_length (str);
    698 
    699   retval = _dbus_string_insert_4_aligned (str, insert_at,
    700                                           (const unsigned char *)&value);
    701 
    702   if (pos_after)
    703     {
    704       *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
    705       _dbus_assert (*pos_after <= _dbus_string_get_length (str));
    706     }
    707 
    708   return retval;
    709 }
    710 
    711 static dbus_bool_t
    712 marshal_8_octets (DBusString    *str,
    713                   int            insert_at,
    714                   DBusBasicValue value,
    715                   int            byte_order,
    716                   int           *pos_after)
    717 {
    718   dbus_bool_t retval;
    719   int orig_len;
    720 
    721   _dbus_assert (sizeof (value) == 8);
    722 
    723   swap_8_octets (&value, byte_order);
    724 
    725   orig_len = _dbus_string_get_length (str);
    726 
    727   retval = _dbus_string_insert_8_aligned (str, insert_at,
    728                                           (const unsigned char *)&value);
    729 
    730   if (pos_after)
    731     *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
    732 
    733   return retval;
    734 }
    735 
    736 enum
    737   {
    738     MARSHAL_AS_STRING,
    739     MARSHAL_AS_SIGNATURE,
    740     MARSHAL_AS_BYTE_ARRAY
    741   };
    742 
    743 static dbus_bool_t
    744 marshal_len_followed_by_bytes (int                  marshal_as,
    745                                DBusString          *str,
    746                                int                  insert_at,
    747                                const unsigned char *value,
    748                                int                  data_len, /* doesn't include nul if any */
    749                                int                  byte_order,
    750                                int                 *pos_after)
    751 {
    752   int pos;
    753   DBusString value_str;
    754   int value_len;
    755 
    756   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
    757   if (insert_at > _dbus_string_get_length (str))
    758     _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
    759                 insert_at, _dbus_string_get_length (str), data_len);
    760 
    761   if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
    762     value_len = data_len;
    763   else
    764     value_len = data_len + 1; /* value has a nul */
    765 
    766   _dbus_string_init_const_len (&value_str, value, value_len);
    767 
    768   pos = insert_at;
    769 
    770   if (marshal_as == MARSHAL_AS_SIGNATURE)
    771     {
    772       _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
    773       _dbus_assert (data_len <= 255); /* same as max sig len right now */
    774 
    775       if (!_dbus_string_insert_byte (str, pos, data_len))
    776         goto oom;
    777 
    778       pos += 1;
    779     }
    780   else
    781     {
    782       if (!marshal_4_octets (str, pos, data_len,
    783                              byte_order, &pos))
    784         goto oom;
    785     }
    786 
    787   if (!_dbus_string_copy_len (&value_str, 0, value_len,
    788                               str, pos))
    789     goto oom;
    790 
    791 #if 0
    792   /* too expensive */
    793   _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
    794                                               str, pos));
    795   _dbus_verbose_bytes_of_string (str, pos, value_len);
    796 #endif
    797 
    798   pos += value_len;
    799 
    800   if (pos_after)
    801     *pos_after = pos;
    802 
    803   return TRUE;
    804 
    805  oom:
    806   /* Delete what we've inserted */
    807   _dbus_string_delete (str, insert_at, pos - insert_at);
    808 
    809   return FALSE;
    810 }
    811 
    812 static dbus_bool_t
    813 marshal_string (DBusString    *str,
    814                 int            insert_at,
    815                 const char    *value,
    816                 int            byte_order,
    817                 int           *pos_after)
    818 {
    819   return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
    820                                         str, insert_at, value,
    821                                         strlen (value),
    822                                         byte_order, pos_after);
    823 }
    824 
    825 static dbus_bool_t
    826 marshal_signature (DBusString    *str,
    827                    int            insert_at,
    828                    const char    *value,
    829                    int           *pos_after)
    830 {
    831   return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
    832                                         str, insert_at, value,
    833                                         strlen (value),
    834                                         DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
    835                                         pos_after);
    836 }
    837 
    838 /**
    839  * Marshals a basic-typed value. The "value" pointer is always the
    840  * address of a variable containing the basic type value.
    841  * So for example for int32 it will be dbus_int32_t*, and
    842  * for string it will be const char**. This is for symmetry
    843  * with _dbus_marshal_read_basic() and to have a simple
    844  * consistent rule.
    845  *
    846  * @param str string to marshal to
    847  * @param insert_at where to insert the value
    848  * @param type type of value
    849  * @param value pointer to a variable containing the value
    850  * @param byte_order byte order
    851  * @param pos_after #NULL or the position after the type
    852  * @returns #TRUE on success
    853  **/
    854 dbus_bool_t
    855 _dbus_marshal_write_basic (DBusString *str,
    856                            int         insert_at,
    857                            int         type,
    858                            const void *value,
    859                            int         byte_order,
    860                            int        *pos_after)
    861 {
    862   const DBusBasicValue *vp;
    863 
    864   _dbus_assert (dbus_type_is_basic (type));
    865 
    866   vp = value;
    867 
    868   switch (type)
    869     {
    870     case DBUS_TYPE_BYTE:
    871       if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
    872         return FALSE;
    873       if (pos_after)
    874         *pos_after = insert_at + 1;
    875       return TRUE;
    876       break;
    877     case DBUS_TYPE_INT16:
    878     case DBUS_TYPE_UINT16:
    879       return marshal_2_octets (str, insert_at, vp->u16,
    880                                byte_order, pos_after);
    881       break;
    882     case DBUS_TYPE_BOOLEAN:
    883       return marshal_4_octets (str, insert_at, vp->u32 != FALSE,
    884                                byte_order, pos_after);
    885       break;
    886     case DBUS_TYPE_INT32:
    887     case DBUS_TYPE_UINT32:
    888     case DBUS_TYPE_UNIX_FD:
    889       return marshal_4_octets (str, insert_at, vp->u32,
    890                                byte_order, pos_after);
    891       break;
    892     case DBUS_TYPE_INT64:
    893     case DBUS_TYPE_UINT64:
    894     case DBUS_TYPE_DOUBLE:
    895       return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
    896       break;
    897 
    898     case DBUS_TYPE_STRING:
    899     case DBUS_TYPE_OBJECT_PATH:
    900       _dbus_assert (vp->str != NULL);
    901       return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
    902       break;
    903     case DBUS_TYPE_SIGNATURE:
    904       _dbus_assert (vp->str != NULL);
    905       return marshal_signature (str, insert_at, vp->str, pos_after);
    906       break;
    907     default:
    908       _dbus_assert_not_reached ("not a basic type");
    909       return FALSE;
    910       break;
    911     }
    912 }
    913 
    914 static dbus_bool_t
    915 marshal_1_octets_array (DBusString          *str,
    916                         int                  insert_at,
    917                         const unsigned char *value,
    918                         int                  n_elements,
    919                         int                  byte_order,
    920                         int                 *pos_after)
    921 {
    922   int pos;
    923   DBusString value_str;
    924 
    925   _dbus_string_init_const_len (&value_str, value, n_elements);
    926 
    927   pos = insert_at;
    928 
    929   if (!_dbus_string_copy_len (&value_str, 0, n_elements,
    930                               str, pos))
    931     return FALSE;
    932 
    933   pos += n_elements;
    934 
    935   if (pos_after)
    936     *pos_after = pos;
    937 
    938   return TRUE;
    939 }
    940 
    941 /**
    942  * Swaps the elements of an array to the opposite byte order
    943  *
    944  * @param data start of array
    945  * @param n_elements number of elements
    946  * @param alignment size of each element
    947  */
    948 void
    949 _dbus_swap_array (unsigned char *data,
    950                   int            n_elements,
    951                   int            alignment)
    952 {
    953   unsigned char *d;
    954   unsigned char *end;
    955 
    956   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
    957 
    958   /* we use const_data and cast it off so DBusString can be a const string
    959    * for the unit tests. don't ask.
    960    */
    961   d = data;
    962   end = d + (n_elements * alignment);
    963 
    964   if (alignment == 8)
    965     {
    966       while (d != end)
    967         {
    968 #ifdef DBUS_HAVE_INT64
    969           *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
    970 #else
    971           swap_8_bytes ((DBusBasicValue*) d);
    972 #endif
    973           d += 8;
    974         }
    975     }
    976   else if (alignment == 4)
    977     {
    978       while (d != end)
    979         {
    980           *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
    981           d += 4;
    982         }
    983     }
    984   else
    985     {
    986       _dbus_assert (alignment == 2);
    987 
    988       while (d != end)
    989         {
    990           *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
    991           d += 2;
    992         }
    993     }
    994 }
    995 
    996 static void
    997 swap_array (DBusString *str,
    998             int         array_start,
    999             int         n_elements,
   1000             int         byte_order,
   1001             int         alignment)
   1002 {
   1003   _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
   1004 
   1005   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
   1006     {
   1007       /* we use const_data and cast it off so DBusString can be a const string
   1008        * for the unit tests. don't ask.
   1009        */
   1010       _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
   1011                         n_elements, alignment);
   1012     }
   1013 }
   1014 
   1015 static dbus_bool_t
   1016 marshal_fixed_multi (DBusString           *str,
   1017                      int                   insert_at,
   1018                      const DBusBasicValue *value,
   1019                      int                   n_elements,
   1020                      int                   byte_order,
   1021                      int                   alignment,
   1022                      int                  *pos_after)
   1023 {
   1024   int old_string_len;
   1025   int array_start;
   1026   DBusString t;
   1027   int len_in_bytes;
   1028 
   1029   _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
   1030 
   1031   old_string_len = _dbus_string_get_length (str);
   1032 
   1033   len_in_bytes = n_elements * alignment;
   1034   array_start = insert_at;
   1035 
   1036   /* Note that we do alignment padding unconditionally
   1037    * even if the array is empty; this means that
   1038    * padding + len is always equal to the number of bytes
   1039    * in the array.
   1040    */
   1041 
   1042   if (!_dbus_string_insert_alignment (str, &array_start, alignment))
   1043     goto error;
   1044 
   1045   _dbus_string_init_const_len (&t,
   1046                                (const unsigned char*) value,
   1047                                len_in_bytes);
   1048 
   1049   if (!_dbus_string_copy (&t, 0,
   1050                           str, array_start))
   1051     goto error;
   1052 
   1053   swap_array (str, array_start, n_elements, byte_order, alignment);
   1054 
   1055   if (pos_after)
   1056     *pos_after = array_start + len_in_bytes;
   1057 
   1058   return TRUE;
   1059 
   1060  error:
   1061   _dbus_string_delete (str, insert_at,
   1062                        _dbus_string_get_length (str) - old_string_len);
   1063 
   1064   return FALSE;
   1065 }
   1066 
   1067 /**
   1068  * Marshals a block of values of fixed-length type all at once, as an
   1069  * optimization.  dbus_type_is_fixed() returns #TRUE for fixed-length
   1070  * types, which are the basic types minus the string-like types.
   1071  *
   1072  * The value argument should be the adddress of an
   1073  * array, so e.g. "const dbus_uint32_t**"
   1074  *
   1075  * @param str string to marshal to
   1076  * @param insert_at where to insert the value
   1077  * @param element_type type of array elements
   1078  * @param value address of an array to marshal
   1079  * @param n_elements number of elements in the array
   1080  * @param byte_order byte order
   1081  * @param pos_after #NULL or the position after the type
   1082  * @returns #TRUE on success
   1083  **/
   1084 dbus_bool_t
   1085 _dbus_marshal_write_fixed_multi (DBusString *str,
   1086                                  int         insert_at,
   1087                                  int         element_type,
   1088                                  const void *value,
   1089                                  int         n_elements,
   1090                                  int         byte_order,
   1091                                  int        *pos_after)
   1092 {
   1093   const void* vp = *(const DBusBasicValue**)value;
   1094 
   1095   _dbus_assert (dbus_type_is_fixed (element_type));
   1096   _dbus_assert (n_elements >= 0);
   1097 
   1098 #if 0
   1099   _dbus_verbose ("writing %d elements of %s\n",
   1100                  n_elements, _dbus_type_to_string (element_type));
   1101 #endif
   1102 
   1103   switch (element_type)
   1104     {
   1105     case DBUS_TYPE_BYTE:
   1106       return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after);
   1107       break;
   1108     case DBUS_TYPE_INT16:
   1109     case DBUS_TYPE_UINT16:
   1110       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
   1111     case DBUS_TYPE_BOOLEAN:
   1112     case DBUS_TYPE_INT32:
   1113     case DBUS_TYPE_UINT32:
   1114     case DBUS_TYPE_UNIX_FD:
   1115       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
   1116       break;
   1117     case DBUS_TYPE_INT64:
   1118     case DBUS_TYPE_UINT64:
   1119     case DBUS_TYPE_DOUBLE:
   1120       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after);
   1121       break;
   1122 
   1123     default:
   1124       _dbus_assert_not_reached ("non fixed type in array write");
   1125       break;
   1126     }
   1127 
   1128   return FALSE;
   1129 }
   1130 
   1131 
   1132 /**
   1133  * Skips over a basic-typed value, reporting the following position.
   1134  *
   1135  * @param str the string containing the data
   1136  * @param type type of value to read
   1137  * @param byte_order the byte order
   1138  * @param pos pointer to position in the string,
   1139  *            updated on return to new position
   1140  **/
   1141 void
   1142 _dbus_marshal_skip_basic (const DBusString      *str,
   1143                           int                    type,
   1144                           int                    byte_order,
   1145                           int                   *pos)
   1146 {
   1147   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
   1148                 byte_order == DBUS_BIG_ENDIAN);
   1149 
   1150   switch (type)
   1151     {
   1152     case DBUS_TYPE_BYTE:
   1153       (*pos)++;
   1154       break;
   1155     case DBUS_TYPE_INT16:
   1156     case DBUS_TYPE_UINT16:
   1157       *pos = _DBUS_ALIGN_VALUE (*pos, 2);
   1158       *pos += 2;
   1159       break;
   1160     case DBUS_TYPE_BOOLEAN:
   1161     case DBUS_TYPE_INT32:
   1162     case DBUS_TYPE_UINT32:
   1163     case DBUS_TYPE_UNIX_FD:
   1164       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
   1165       *pos += 4;
   1166       break;
   1167     case DBUS_TYPE_INT64:
   1168     case DBUS_TYPE_UINT64:
   1169     case DBUS_TYPE_DOUBLE:
   1170       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
   1171       *pos += 8;
   1172       break;
   1173     case DBUS_TYPE_STRING:
   1174     case DBUS_TYPE_OBJECT_PATH:
   1175       {
   1176         int len;
   1177 
   1178         len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
   1179 
   1180         *pos += len + 1; /* length plus nul */
   1181       }
   1182       break;
   1183     case DBUS_TYPE_SIGNATURE:
   1184       {
   1185         int len;
   1186 
   1187         len = _dbus_string_get_byte (str, *pos);
   1188 
   1189         *pos += len + 2; /* length byte plus length plus nul */
   1190       }
   1191       break;
   1192     default:
   1193       _dbus_warn ("type %s not a basic type\n",
   1194                   _dbus_type_to_string (type));
   1195       _dbus_assert_not_reached ("not a basic type");
   1196       break;
   1197     }
   1198 }
   1199 
   1200 /**
   1201  * Skips an array, returning the next position.
   1202  *
   1203  * @param str the string containing the data
   1204  * @param element_type the type of array elements
   1205  * @param byte_order the byte order
   1206  * @param pos pointer to position in the string,
   1207  *            updated on return to new position
   1208  */
   1209 void
   1210 _dbus_marshal_skip_array (const DBusString  *str,
   1211                           int                element_type,
   1212                           int                byte_order,
   1213                           int               *pos)
   1214 {
   1215   dbus_uint32_t array_len;
   1216   int i;
   1217   int alignment;
   1218 
   1219   i = _DBUS_ALIGN_VALUE (*pos, 4);
   1220 
   1221   array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
   1222 
   1223   alignment = _dbus_type_get_alignment (element_type);
   1224 
   1225   i = _DBUS_ALIGN_VALUE (i, alignment);
   1226 
   1227   *pos = i + array_len;
   1228 }
   1229 
   1230 /**
   1231  * Gets the alignment requirement for the given type;
   1232  * will be 1, 4, or 8.
   1233  *
   1234  * @param typecode the type
   1235  * @returns alignment of 1, 4, or 8
   1236  */
   1237 int
   1238 _dbus_type_get_alignment (int typecode)
   1239 {
   1240   switch (typecode)
   1241     {
   1242     case DBUS_TYPE_BYTE:
   1243     case DBUS_TYPE_VARIANT:
   1244     case DBUS_TYPE_SIGNATURE:
   1245       return 1;
   1246     case DBUS_TYPE_INT16:
   1247     case DBUS_TYPE_UINT16:
   1248       return 2;
   1249     case DBUS_TYPE_BOOLEAN:
   1250     case DBUS_TYPE_INT32:
   1251     case DBUS_TYPE_UINT32:
   1252     case DBUS_TYPE_UNIX_FD:
   1253       /* this stuff is 4 since it starts with a length */
   1254     case DBUS_TYPE_STRING:
   1255     case DBUS_TYPE_OBJECT_PATH:
   1256     case DBUS_TYPE_ARRAY:
   1257       return 4;
   1258     case DBUS_TYPE_INT64:
   1259     case DBUS_TYPE_UINT64:
   1260     case DBUS_TYPE_DOUBLE:
   1261       /* struct is 8 since it could contain an 8-aligned item
   1262        * and it's simpler to just always align structs to 8;
   1263        * we want the amount of padding in a struct of a given
   1264        * type to be predictable, not location-dependent.
   1265        * DICT_ENTRY is always the same as struct.
   1266        */
   1267     case DBUS_TYPE_STRUCT:
   1268     case DBUS_TYPE_DICT_ENTRY:
   1269       return 8;
   1270 
   1271     default:
   1272       _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
   1273       return 0;
   1274     }
   1275 }
   1276 
   1277 /**
   1278  * Returns a string describing the given type.
   1279  *
   1280  * @param typecode the type to describe
   1281  * @returns a constant string describing the type
   1282  */
   1283 const char *
   1284 _dbus_type_to_string (int typecode)
   1285 {
   1286   switch (typecode)
   1287     {
   1288     case DBUS_TYPE_INVALID:
   1289       return "invalid";
   1290     case DBUS_TYPE_BOOLEAN:
   1291       return "boolean";
   1292     case DBUS_TYPE_BYTE:
   1293       return "byte";
   1294     case DBUS_TYPE_INT16:
   1295       return "int16";
   1296     case DBUS_TYPE_UINT16:
   1297       return "uint16";
   1298     case DBUS_TYPE_INT32:
   1299       return "int32";
   1300     case DBUS_TYPE_UINT32:
   1301       return "uint32";
   1302     case DBUS_TYPE_INT64:
   1303       return "int64";
   1304     case DBUS_TYPE_UINT64:
   1305       return "uint64";
   1306     case DBUS_TYPE_DOUBLE:
   1307       return "double";
   1308     case DBUS_TYPE_STRING:
   1309       return "string";
   1310     case DBUS_TYPE_OBJECT_PATH:
   1311       return "object_path";
   1312     case DBUS_TYPE_SIGNATURE:
   1313       return "signature";
   1314     case DBUS_TYPE_STRUCT:
   1315       return "struct";
   1316     case DBUS_TYPE_DICT_ENTRY:
   1317       return "dict_entry";
   1318     case DBUS_TYPE_ARRAY:
   1319       return "array";
   1320     case DBUS_TYPE_VARIANT:
   1321       return "variant";
   1322     case DBUS_STRUCT_BEGIN_CHAR:
   1323       return "begin_struct";
   1324     case DBUS_STRUCT_END_CHAR:
   1325       return "end_struct";
   1326     case DBUS_DICT_ENTRY_BEGIN_CHAR:
   1327       return "begin_dict_entry";
   1328     case DBUS_DICT_ENTRY_END_CHAR:
   1329       return "end_dict_entry";
   1330     case DBUS_TYPE_UNIX_FD:
   1331       return "unix_fd";
   1332     default:
   1333       return "unknown";
   1334     }
   1335 }
   1336 
   1337 /**
   1338  * If in verbose mode, print a block of binary data.
   1339  *
   1340  * @param data the data
   1341  * @param len the length of the data
   1342  * @param offset where to start counting for byte indexes
   1343  */
   1344 void
   1345 _dbus_verbose_bytes (const unsigned char *data,
   1346                      int                  len,
   1347                      int                  offset)
   1348 {
   1349   int i;
   1350   const unsigned char *aligned;
   1351 
   1352   _dbus_assert (len >= 0);
   1353 
   1354   if (!_dbus_is_verbose())
   1355     return;
   1356 
   1357   /* Print blanks on first row if appropriate */
   1358   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
   1359   if (aligned > data)
   1360     aligned -= 4;
   1361   _dbus_assert (aligned <= data);
   1362 
   1363   if (aligned != data)
   1364     {
   1365       _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
   1366       while (aligned != data)
   1367         {
   1368           _dbus_verbose ("    ");
   1369           ++aligned;
   1370         }
   1371     }
   1372 
   1373   /* now print the bytes */
   1374   i = 0;
   1375   while (i < len)
   1376     {
   1377       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
   1378         {
   1379           _dbus_verbose ("%4d\t%p: ",
   1380                          offset + i, &data[i]);
   1381         }
   1382 
   1383       if (data[i] >= 32 &&
   1384           data[i] <= 126)
   1385         _dbus_verbose (" '%c' ", data[i]);
   1386       else
   1387         _dbus_verbose ("0x%s%x ",
   1388                        data[i] <= 0xf ? "0" : "", data[i]);
   1389 
   1390       ++i;
   1391 
   1392       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
   1393         {
   1394           if (i > 3)
   1395             _dbus_verbose ("BE: %d LE: %d",
   1396                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
   1397                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
   1398 
   1399           if (i > 7 &&
   1400               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
   1401             {
   1402 #ifdef DBUS_INT64_PRINTF_MODIFIER
   1403               _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x",
   1404                              *(dbus_uint64_t*)&data[i-8]);
   1405 #endif
   1406               _dbus_verbose (" dbl: %g",
   1407                              *(double*)&data[i-8]);
   1408             }
   1409 
   1410           _dbus_verbose ("\n");
   1411         }
   1412     }
   1413 
   1414   _dbus_verbose ("\n");
   1415 }
   1416 
   1417 /**
   1418  * Dump the given part of the string to verbose log.
   1419  *
   1420  * @param str the string
   1421  * @param start the start of range to dump
   1422  * @param len length of range
   1423  */
   1424 void
   1425 _dbus_verbose_bytes_of_string (const DBusString    *str,
   1426                                int                  start,
   1427                                int                  len)
   1428 {
   1429   const char *d;
   1430   int real_len;
   1431 
   1432   real_len = _dbus_string_get_length (str);
   1433 
   1434   _dbus_assert (start >= 0);
   1435 
   1436   if (start > real_len)
   1437     {
   1438       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
   1439                      start, len, real_len);
   1440       return;
   1441     }
   1442 
   1443   if ((start + len) > real_len)
   1444     {
   1445       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
   1446                      start, len, real_len);
   1447       len = real_len - start;
   1448     }
   1449 
   1450   d = _dbus_string_get_const_data_len (str, start, len);
   1451 
   1452   _dbus_verbose_bytes (d, len, start);
   1453 }
   1454 
   1455 static int
   1456 map_type_char_to_type (int t)
   1457 {
   1458   if (t == DBUS_STRUCT_BEGIN_CHAR)
   1459     return DBUS_TYPE_STRUCT;
   1460   else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
   1461     return DBUS_TYPE_DICT_ENTRY;
   1462   else
   1463     {
   1464       _dbus_assert (t != DBUS_STRUCT_END_CHAR);
   1465       _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR);
   1466       return t;
   1467     }
   1468 }
   1469 
   1470 /**
   1471  * Get the first type in the signature. The difference between this
   1472  * and just getting the first byte of the signature is that you won't
   1473  * get DBUS_STRUCT_BEGIN_CHAR, you'll get DBUS_TYPE_STRUCT
   1474  * instead.
   1475  *
   1476  * @param str string containing signature
   1477  * @param pos where the signature starts
   1478  * @returns the first type in the signature
   1479  */
   1480 int
   1481 _dbus_first_type_in_signature (const DBusString *str,
   1482                                int               pos)
   1483 {
   1484   return map_type_char_to_type (_dbus_string_get_byte (str, pos));
   1485 }
   1486 
   1487 /**
   1488  * Similar to #_dbus_first_type_in_signature, but operates
   1489  * on a C string buffer.
   1490  *
   1491  * @param str a C string buffer
   1492  * @param pos where the signature starts
   1493  * @returns the first type in the signature
   1494  */
   1495 int
   1496 _dbus_first_type_in_signature_c_str (const char       *str,
   1497 				     int               pos)
   1498 {
   1499   return map_type_char_to_type (str[pos]);
   1500 }
   1501 
   1502 /** @} */
   1503 
   1504 #ifdef DBUS_BUILD_TESTS
   1505 #include "dbus-test.h"
   1506 #include <stdio.h>
   1507 
   1508 /**
   1509  * Reads a block of fixed-length basic values, as an optimization
   1510  * vs. reading each one individually into a new buffer.
   1511  *
   1512  * This function returns the data in-place; it does not make a copy,
   1513  * and it does not swap the bytes.
   1514  *
   1515  * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back
   1516  * and the "value" argument should be a "const double**" and so on.
   1517  *
   1518  * @param str the string to read from
   1519  * @param pos position to read from
   1520  * @param element_type type of array elements
   1521  * @param value place to return the array
   1522  * @param n_elements number of array elements to read
   1523  * @param byte_order the byte order, used to read the array length
   1524  * @param new_pos #NULL or location to store a position after the elements
   1525  */
   1526 void
   1527 _dbus_marshal_read_fixed_multi  (const DBusString *str,
   1528                                  int               pos,
   1529                                  int               element_type,
   1530                                  void             *value,
   1531                                  int               n_elements,
   1532                                  int               byte_order,
   1533                                  int              *new_pos)
   1534 {
   1535   int array_len;
   1536   int alignment;
   1537 
   1538   _dbus_assert (dbus_type_is_fixed (element_type));
   1539   _dbus_assert (dbus_type_is_basic (element_type));
   1540 
   1541 #if 0
   1542   _dbus_verbose ("reading %d elements of %s\n",
   1543                  n_elements, _dbus_type_to_string (element_type));
   1544 #endif
   1545 
   1546   alignment = _dbus_type_get_alignment (element_type);
   1547 
   1548   pos = _DBUS_ALIGN_VALUE (pos, alignment);
   1549 
   1550   array_len = n_elements * alignment;
   1551 
   1552   *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
   1553   if (new_pos)
   1554     *new_pos = pos + array_len;
   1555 }
   1556 
   1557 static void
   1558 swap_test_array (void *array,
   1559                  int   len_bytes,
   1560                  int   byte_order,
   1561                  int   alignment)
   1562 {
   1563   DBusString t;
   1564 
   1565   if (alignment == 1)
   1566     return;
   1567 
   1568   _dbus_string_init_const_len (&t, array, len_bytes);
   1569   swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
   1570 }
   1571 
   1572 #define MARSHAL_BASIC(typename, byte_order, literal)                    \
   1573   do {                                                                  \
   1574      v_##typename = literal;                                            \
   1575      if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename,   \
   1576                                     &v_##typename,                      \
   1577                                     byte_order, NULL))                  \
   1578        _dbus_assert_not_reached ("no memory");                          \
   1579    } while (0)
   1580 
   1581 #define DEMARSHAL_BASIC(typename, byte_order)                                   \
   1582   do {                                                                          \
   1583     _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename,   \
   1584                               byte_order, &pos);                                \
   1585   } while (0)
   1586 
   1587 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \
   1588   do {                                                                                  \
   1589     DEMARSHAL_BASIC (typename, byte_order);                                             \
   1590     if (literal != v_##typename)                                                        \
   1591       {                                                                                 \
   1592         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
   1593                                      _dbus_string_get_length (&str) - dump_pos);        \
   1594         _dbus_assert_not_reached ("demarshaled wrong value");                           \
   1595       }                                                                                 \
   1596   } while (0)
   1597 
   1598 #define MARSHAL_TEST(typename, byte_order, literal)             \
   1599   do {                                                          \
   1600     MARSHAL_BASIC (typename, byte_order, literal);              \
   1601     dump_pos = pos;                                             \
   1602     DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal);  \
   1603   } while (0)
   1604 
   1605 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal)                              \
   1606   do {                                                                                  \
   1607     MARSHAL_BASIC (typename, byte_order, literal);                                      \
   1608     dump_pos = pos;                                                                     \
   1609     DEMARSHAL_BASIC (typename, byte_order);                                             \
   1610     if (strcmp (literal, v_##typename) != 0)                                            \
   1611       {                                                                                 \
   1612         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
   1613                                        _dbus_string_get_length (&str) - dump_pos);      \
   1614         _dbus_warn ("literal '%s'\nvalue  '%s'\n", literal, v_##typename);              \
   1615         _dbus_assert_not_reached ("demarshaled wrong value");                           \
   1616       }                                                                                 \
   1617   } while (0)
   1618 
   1619 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal)                                      \
   1620   do {                                                                                          \
   1621      int next;                                                                                  \
   1622      v_UINT32 = sizeof(literal);                                                                \
   1623      if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32,                    \
   1624                                      byte_order, &next))                                        \
   1625        _dbus_assert_not_reached ("no memory");                                                  \
   1626      v_ARRAY_##typename = literal;                                                              \
   1627      if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename,                    \
   1628                                            &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal),      \
   1629                                            byte_order, NULL))                                   \
   1630        _dbus_assert_not_reached ("no memory");                                                  \
   1631    } while (0)
   1632 
   1633 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order)                                             \
   1634   do {                                                                                          \
   1635     int next;                                                                                   \
   1636     alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename);                                \
   1637     v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next);                   \
   1638     _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename,      \
   1639                                     v_UINT32/alignment,                                         \
   1640                                     byte_order, NULL);                                          \
   1641     swap_test_array (v_ARRAY_##typename, v_UINT32,                                              \
   1642                      byte_order, alignment);                                                    \
   1643   } while (0)
   1644 
   1645 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal)                  \
   1646   do {                                                                                  \
   1647     DEMARSHAL_FIXED_ARRAY (typename, byte_order);                                       \
   1648     if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0))                    \
   1649       {                                                                                 \
   1650         _dbus_verbose ("MARSHALED DATA\n");                                             \
   1651         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
   1652                                       _dbus_string_get_length (&str) - dump_pos);       \
   1653         _dbus_verbose ("LITERAL DATA\n");                                               \
   1654         _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0);                      \
   1655         _dbus_verbose ("READ DATA\n");                                                  \
   1656         _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0);           \
   1657         _dbus_assert_not_reached ("demarshaled wrong fixed array value");               \
   1658       }                                                                                 \
   1659   } while (0)
   1660 
   1661 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal)         \
   1662   do {                                                                  \
   1663     MARSHAL_FIXED_ARRAY (typename, byte_order, literal);                \
   1664     dump_pos = pos;                                                     \
   1665     DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal);    \
   1666   } while (0)
   1667 
   1668 dbus_bool_t
   1669 _dbus_marshal_test (void)
   1670 {
   1671   int alignment;
   1672   DBusString str;
   1673   int pos, dump_pos;
   1674   unsigned char array1[5] = { 3, 4, 0, 1, 9 };
   1675   dbus_int16_t array2[3] = { 124, 457, 780 };
   1676   dbus_int32_t array4[3] = { 123, 456, 789 };
   1677 #ifdef DBUS_HAVE_INT64
   1678   dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
   1679                              DBUS_INT64_CONSTANT (0x456ffffffff),
   1680                              DBUS_INT64_CONSTANT (0x789ffffffff) };
   1681   dbus_int64_t *v_ARRAY_INT64;
   1682 #endif
   1683   unsigned char *v_ARRAY_BYTE;
   1684   dbus_int16_t *v_ARRAY_INT16;
   1685   dbus_uint16_t *v_ARRAY_UINT16;
   1686   dbus_int32_t *v_ARRAY_INT32;
   1687   dbus_uint32_t *v_ARRAY_UINT32;
   1688   DBusString t;
   1689   double v_DOUBLE;
   1690   double t_DOUBLE;
   1691   dbus_int16_t v_INT16;
   1692   dbus_uint16_t v_UINT16;
   1693   dbus_int32_t v_INT32;
   1694   dbus_uint32_t v_UINT32;
   1695   dbus_int64_t v_INT64;
   1696   dbus_uint64_t v_UINT64;
   1697   unsigned char v_BYTE;
   1698   dbus_bool_t v_BOOLEAN;
   1699   const char *v_STRING;
   1700   const char *v_SIGNATURE;
   1701   const char *v_OBJECT_PATH;
   1702   int byte_order;
   1703 
   1704   if (!_dbus_string_init (&str))
   1705     _dbus_assert_not_reached ("failed to init string");
   1706 
   1707   pos = 0;
   1708 
   1709   /* Marshal doubles */
   1710   MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
   1711   DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
   1712   t_DOUBLE = 3.14;
   1713   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
   1714     _dbus_assert_not_reached ("got wrong double value");
   1715 
   1716   MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
   1717   DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
   1718   t_DOUBLE = 3.14;
   1719   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
   1720     _dbus_assert_not_reached ("got wrong double value");
   1721 
   1722   /* Marshal signed 16 integers */
   1723   MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
   1724   MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
   1725 
   1726   /* Marshal unsigned 16 integers */
   1727   MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
   1728   MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
   1729 
   1730   /* Marshal signed integers */
   1731   MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
   1732   MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
   1733 
   1734   /* Marshal unsigned integers */
   1735   MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
   1736   MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
   1737 
   1738 #ifdef DBUS_HAVE_INT64
   1739   /* Marshal signed integers */
   1740   MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
   1741   MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
   1742 
   1743   /* Marshal unsigned integers */
   1744   MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
   1745   MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
   1746 #endif /* DBUS_HAVE_INT64 */
   1747 
   1748   /* Marshal byte */
   1749   MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
   1750   MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
   1751 
   1752   /* Marshal all possible bools! */
   1753   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
   1754   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
   1755   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
   1756   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
   1757 
   1758   /* Marshal strings */
   1759   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
   1760   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
   1761   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
   1762   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
   1763 
   1764   /* object paths */
   1765   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
   1766   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
   1767 
   1768   /* signatures */
   1769   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
   1770   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
   1771   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
   1772   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
   1773 
   1774   /* Arrays */
   1775   MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
   1776   MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
   1777   MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2);
   1778   MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2);
   1779 
   1780   MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
   1781   MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
   1782   MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4);
   1783   MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4);
   1784 
   1785   MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
   1786   MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
   1787 
   1788 #ifdef DBUS_HAVE_INT64
   1789   MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
   1790   MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
   1791 #endif
   1792 
   1793 #if 0
   1794 
   1795   /*
   1796    * FIXME restore the set/pack tests
   1797    */
   1798 
   1799 #ifdef DBUS_HAVE_INT64
   1800   /* set/pack 64-bit integers */
   1801   _dbus_string_set_length (&str, 8);
   1802 
   1803   /* signed little */
   1804   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
   1805                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
   1806 
   1807   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
   1808                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
   1809                                     _dbus_string_get_const_data (&str)));
   1810 
   1811   /* signed big */
   1812   _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
   1813                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
   1814 
   1815   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
   1816                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
   1817                                     _dbus_string_get_const_data (&str)));
   1818 
   1819   /* signed little pack */
   1820   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
   1821                     DBUS_LITTLE_ENDIAN,
   1822                     _dbus_string_get_data (&str));
   1823 
   1824   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
   1825                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
   1826                                     _dbus_string_get_const_data (&str)));
   1827 
   1828   /* signed big pack */
   1829   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
   1830                     DBUS_BIG_ENDIAN,
   1831                     _dbus_string_get_data (&str));
   1832 
   1833   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
   1834                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
   1835                                     _dbus_string_get_const_data (&str)));
   1836 
   1837   /* unsigned little */
   1838   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
   1839                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
   1840 
   1841   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
   1842                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
   1843                                      _dbus_string_get_const_data (&str)));
   1844 
   1845   /* unsigned big */
   1846   _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
   1847                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
   1848 
   1849   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
   1850                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
   1851                                      _dbus_string_get_const_data (&str)));
   1852 
   1853   /* unsigned little pack */
   1854   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
   1855                      DBUS_LITTLE_ENDIAN,
   1856                      _dbus_string_get_data (&str));
   1857 
   1858   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
   1859                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
   1860                                      _dbus_string_get_const_data (&str)));
   1861 
   1862   /* unsigned big pack */
   1863   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
   1864                      DBUS_BIG_ENDIAN,
   1865                      _dbus_string_get_data (&str));
   1866 
   1867   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
   1868                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
   1869                                      _dbus_string_get_const_data (&str)));
   1870 #endif /* DBUS_HAVE_INT64 */
   1871 
   1872   /* set/pack 32-bit integers */
   1873   _dbus_string_set_length (&str, 4);
   1874 
   1875   /* signed little */
   1876   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
   1877                            0, -0x123456);
   1878 
   1879   _dbus_assert (-0x123456 ==
   1880                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
   1881                                     _dbus_string_get_const_data (&str)));
   1882 
   1883   /* signed big */
   1884   _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
   1885                            0, -0x123456);
   1886 
   1887   _dbus_assert (-0x123456 ==
   1888                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
   1889                                     _dbus_string_get_const_data (&str)));
   1890 
   1891   /* signed little pack */
   1892   _dbus_pack_int32 (-0x123456,
   1893                     DBUS_LITTLE_ENDIAN,
   1894                     _dbus_string_get_data (&str));
   1895 
   1896   _dbus_assert (-0x123456 ==
   1897                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
   1898                                     _dbus_string_get_const_data (&str)));
   1899 
   1900   /* signed big pack */
   1901   _dbus_pack_int32 (-0x123456,
   1902                     DBUS_BIG_ENDIAN,
   1903                     _dbus_string_get_data (&str));
   1904 
   1905   _dbus_assert (-0x123456 ==
   1906                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
   1907                                     _dbus_string_get_const_data (&str)));
   1908 
   1909   /* unsigned little */
   1910   _dbus_marshal_set_uint32 (&str,
   1911                             0, 0x123456,
   1912                             DBUS_LITTLE_ENDIAN);
   1913 
   1914   _dbus_assert (0x123456 ==
   1915                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
   1916                                      _dbus_string_get_const_data (&str)));
   1917 
   1918   /* unsigned big */
   1919   _dbus_marshal_set_uint32 (&str,
   1920                             0, 0x123456,
   1921                             DBUS_BIG_ENDIAN);
   1922 
   1923   _dbus_assert (0x123456 ==
   1924                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
   1925                                      _dbus_string_get_const_data (&str)));
   1926 
   1927   /* unsigned little pack */
   1928   _dbus_pack_uint32 (0x123456,
   1929                      DBUS_LITTLE_ENDIAN,
   1930                      _dbus_string_get_data (&str));
   1931 
   1932   _dbus_assert (0x123456 ==
   1933                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
   1934                                      _dbus_string_get_const_data (&str)));
   1935 
   1936   /* unsigned big pack */
   1937   _dbus_pack_uint32 (0x123456,
   1938                      DBUS_BIG_ENDIAN,
   1939                      _dbus_string_get_data (&str));
   1940 
   1941   _dbus_assert (0x123456 ==
   1942                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
   1943                                      _dbus_string_get_const_data (&str)));
   1944 
   1945 #endif /* set/pack tests for integers */
   1946 
   1947   /* Strings in-place set */
   1948   byte_order = DBUS_LITTLE_ENDIAN;
   1949   while (TRUE)
   1950     {
   1951       /* Init a string */
   1952       _dbus_string_set_length (&str, 0);
   1953 
   1954       /* reset pos for the macros */
   1955       pos = 0;
   1956 
   1957       MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
   1958 
   1959       /* Set it to something longer */
   1960       _dbus_string_init_const (&t, "Hello world foo");
   1961 
   1962       v_STRING = _dbus_string_get_const_data (&t);
   1963       _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
   1964                                &v_STRING, byte_order, NULL, NULL);
   1965 
   1966       _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
   1967                                 &v_STRING, byte_order,
   1968                                 NULL);
   1969       _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
   1970 
   1971       /* Set it to something shorter */
   1972       _dbus_string_init_const (&t, "Hello");
   1973 
   1974       v_STRING = _dbus_string_get_const_data (&t);
   1975       _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
   1976                                &v_STRING, byte_order, NULL, NULL);
   1977       _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
   1978                                 &v_STRING, byte_order,
   1979                                 NULL);
   1980       _dbus_assert (strcmp (v_STRING, "Hello") == 0);
   1981 
   1982       /* Do the other byte order */
   1983       if (byte_order == DBUS_LITTLE_ENDIAN)
   1984         byte_order = DBUS_BIG_ENDIAN;
   1985       else
   1986         break;
   1987     }
   1988 
   1989   /* Clean up */
   1990   _dbus_string_free (&str);
   1991 
   1992   return TRUE;
   1993 }
   1994 
   1995 #endif /* DBUS_BUILD_TESTS */
   1996