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