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