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