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