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