all types now unit tested and working.
[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 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 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
28
29 #include "dbus-marshal-basic.h"
30
31 #include <string.h>
32
33 /**
34  * @defgroup DBusMarshal marshaling and unmarshaling
35  * @ingroup  DBusInternals
36  * @brief functions to marshal/unmarshal data from the wire
37  *
38  * Types and functions related to converting primitive data types from
39  * wire format to native machine format, and vice versa.
40  *
41  * A signature is just a string with multiple types one after the other.
42  * for example a type is "i" or "(ii)", a signature is "i(ii)"
43  * where i is int and (ii) is struct { int; int; }
44  *
45  * @{
46  */
47
48 static dbus_uint32_t
49 unpack_4_octets (int                  byte_order,
50                  const unsigned char *data)
51 {
52   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
53   
54   if (byte_order == DBUS_LITTLE_ENDIAN)
55     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
56   else
57     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
58 }
59
60 #ifndef DBUS_HAVE_INT64
61 /* from ORBit */
62 static void
63 swap_bytes (unsigned char *data,
64             unsigned int   len)
65 {
66   unsigned char *p1 = data;
67   unsigned char *p2 = data + len - 1;
68
69   while (p1 < p2)
70     {
71       unsigned char tmp = *p1;
72       *p1 = *p2;
73       *p2 = tmp;
74
75       --p2;
76       ++p1;
77     }
78 }
79 #endif /* !DBUS_HAVE_INT64 */
80
81 /**
82  * Union used to manipulate 8 bytes as if they
83  * were various types. 
84  */
85 typedef union
86 {
87 #ifdef DBUS_HAVE_INT64
88   dbus_int64_t  s; /**< 64-bit integer */
89   dbus_uint64_t u; /**< 64-bit unsigned integer */
90 #endif
91   double d;        /**< double */
92 } DBusOctets8;
93
94 static DBusOctets8
95 unpack_8_octets (int                  byte_order,
96                  const unsigned char *data)
97 {
98   DBusOctets8 r;
99   
100   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
101   _dbus_assert (sizeof (r) == 8);
102   
103 #ifdef DBUS_HAVE_INT64
104   if (byte_order == DBUS_LITTLE_ENDIAN)
105     r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
106   else
107     r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
108 #else
109   r.d = *(double*)data;
110   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
111     swap_bytes ((unsigned char*) &r, sizeof (r));
112 #endif
113   
114   return r;
115 }
116
117 /**
118  * Unpacks a 32 bit unsigned integer from a data pointer
119  *
120  * @param byte_order The byte order to use
121  * @param data the data pointer
122  * @returns the integer
123  */
124 dbus_uint32_t
125 _dbus_unpack_uint32 (int                  byte_order,
126                      const unsigned char *data)
127 {
128   return unpack_4_octets (byte_order, data);
129 }  
130
131 /**
132  * Unpacks a 32 bit signed integer from a data pointer
133  *
134  * @param byte_order The byte order to use
135  * @param data the data pointer
136  * @returns the integer
137  */
138 dbus_int32_t
139 _dbus_unpack_int32 (int                  byte_order,
140                     const unsigned char *data)
141 {
142   return (dbus_int32_t) unpack_4_octets (byte_order, data);
143 }
144
145 #ifdef DBUS_HAVE_INT64
146 /**
147  * Unpacks a 64 bit unsigned integer from a data pointer
148  *
149  * @param byte_order The byte order to use
150  * @param data the data pointer
151  * @returns the integer
152  */
153 dbus_uint64_t
154 _dbus_unpack_uint64 (int                  byte_order,
155                      const unsigned char *data)
156 {
157   DBusOctets8 r;
158   
159   r = unpack_8_octets (byte_order, data);
160
161   return r.u;
162 }  
163
164 /**
165  * Unpacks a 64 bit signed 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_int64_t
172 _dbus_unpack_int64 (int                  byte_order,
173                     const unsigned char *data)
174 {
175   DBusOctets8 r;
176   
177   r = unpack_8_octets (byte_order, data);
178
179   return r.s;
180 }
181
182 #endif /* DBUS_HAVE_INT64 */
183
184 static void
185 pack_4_octets (dbus_uint32_t   value,
186                int             byte_order,
187                unsigned char  *data)
188 {
189   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
190   
191   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
192     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
193   else
194     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
195 }
196
197 static void
198 swap_8_octets (DBusOctets8    *value,
199                int             byte_order)
200 {
201   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
202     {
203 #ifdef DBUS_HAVE_INT64
204       value->u = DBUS_UINT64_SWAP_LE_BE (value->u);
205 #else
206       swap_bytes ((unsigned char *)value, 8);
207 #endif
208     }
209 }
210
211 static void
212 pack_8_octets (DBusOctets8     value,
213                int             byte_order,
214                unsigned char  *data)
215 {
216   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
217
218 #ifdef DBUS_HAVE_INT64
219   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
220     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u); 
221   else
222     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
223 #else
224   memcpy (data, &value, 8);
225   swap_8_octets ((DBusOctets8*)data, byte_order);
226 #endif
227 }
228
229 /**
230  * Packs a 32 bit unsigned integer into a data pointer.
231  *
232  * @param value the value
233  * @param byte_order the byte order to use
234  * @param data the data pointer
235  */
236 void
237 _dbus_pack_uint32 (dbus_uint32_t   value,
238                    int             byte_order,
239                    unsigned char  *data)
240 {
241   pack_4_octets (value, byte_order, data);
242 }
243
244 /**
245  * Packs a 32 bit signed integer into a data pointer.
246  *
247  * @param value the value
248  * @param byte_order the byte order to use
249  * @param data the data pointer
250  */
251 void
252 _dbus_pack_int32 (dbus_int32_t   value,
253                   int            byte_order,
254                   unsigned char *data)
255 {
256   pack_4_octets ((dbus_uint32_t) value, byte_order, data);
257 }
258
259 #ifdef DBUS_HAVE_INT64
260 /**
261  * Packs a 64 bit unsigned integer into a data pointer.
262  *
263  * @param value the value
264  * @param byte_order the byte order to use
265  * @param data the data pointer
266  */
267 void
268 _dbus_pack_uint64 (dbus_uint64_t   value,
269                    int             byte_order,
270                    unsigned char  *data)
271 {
272   DBusOctets8 r;
273   r.u = value;
274   pack_8_octets (r, byte_order, data);
275 }
276
277 /**
278  * Packs a 64 bit signed integer into a data pointer.
279  *
280  * @param value the value
281  * @param byte_order the byte order to use
282  * @param data the data pointer
283  */
284 void
285 _dbus_pack_int64 (dbus_int64_t   value,
286                   int            byte_order,
287                   unsigned char *data)
288 {
289   DBusOctets8 r;
290   r.s = value;
291   pack_8_octets (r, byte_order, data);
292 }
293 #endif /* DBUS_HAVE_INT64 */
294
295 static void
296 set_4_octets (DBusString          *str,
297               int                  byte_order,
298               int                  offset,
299               dbus_uint32_t        value)
300 {
301   char *data;
302   
303   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
304                 byte_order == DBUS_BIG_ENDIAN);
305   
306   data = _dbus_string_get_data_len (str, offset, 4);
307
308   _dbus_pack_uint32 (value, byte_order, data);
309 }
310
311 static void
312 set_8_octets (DBusString          *str,
313               int                  byte_order,
314               int                  offset,
315               DBusOctets8          value)
316 {
317   char *data;
318   
319   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
320                 byte_order == DBUS_BIG_ENDIAN);
321   
322   data = _dbus_string_get_data_len (str, offset, 8);
323
324   pack_8_octets (value, byte_order, data);
325 }
326
327 /**
328  * Sets the 4 bytes at the given offset to a marshaled signed integer,
329  * replacing anything found there previously.
330  *
331  * @param str the string to write the marshalled int to
332  * @param offset the byte offset where int should be written
333  * @param byte_order the byte order to use
334  * @param value the value
335  * 
336  */
337 void
338 _dbus_marshal_set_int32 (DBusString          *str,
339                          int                  byte_order,
340                          int                  offset,
341                          dbus_int32_t         value)
342 {
343   set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
344 }
345
346 /**
347  * Sets the 4 bytes at the given offset to a marshaled unsigned
348  * integer, replacing anything found there previously.
349  *
350  * @param str the string to write the marshalled int to
351  * @param offset the byte offset where int should be written
352  * @param byte_order the byte order to use
353  * @param value the value
354  * 
355  */
356 void
357 _dbus_marshal_set_uint32 (DBusString          *str,
358                           int                  byte_order,
359                           int                  offset,
360                           dbus_uint32_t        value)
361 {
362   set_4_octets (str, byte_order, offset, value);
363 }
364
365 #ifdef DBUS_HAVE_INT64
366
367 /**
368  * Sets the 8 bytes at the given offset to a marshaled signed integer,
369  * replacing anything found there previously.
370  *
371  * @param str the string to write the marshalled int to
372  * @param offset the byte offset where int should be written
373  * @param byte_order the byte order to use
374  * @param value the value
375  * 
376  */
377 void
378 _dbus_marshal_set_int64 (DBusString          *str,
379                          int                  byte_order,
380                          int                  offset,
381                          dbus_int64_t         value)
382 {
383   DBusOctets8 r;
384   r.s = value;
385   set_8_octets (str, byte_order, offset, r);
386 }
387
388 /**
389  * Sets the 8 bytes at the given offset to a marshaled unsigned
390  * integer, replacing anything found there previously.
391  *
392  * @param str the string to write the marshalled int to
393  * @param offset the byte offset where int should be written
394  * @param byte_order the byte order to use
395  * @param value the value
396  * 
397  */
398 void
399 _dbus_marshal_set_uint64 (DBusString          *str,
400                           int                  byte_order,
401                           int                  offset,
402                           dbus_uint64_t        value)
403 {
404   DBusOctets8 r;
405   r.u = value;
406   set_8_octets (str, byte_order, offset, r);
407 }
408 #endif /* DBUS_HAVE_INT64 */
409
410 /**
411  * Sets the existing marshaled string at the given offset with
412  * a new marshaled string. The given offset must point to
413  * an existing string or the wrong length will be deleted
414  * and replaced with the new string.
415  *
416  * Note: no attempt is made by this function to re-align
417  * any data which has been already marshalled after this
418  * string. Use with caution.
419  *
420  * @param str the string to write the marshalled string to
421  * @param offset the byte offset where string should be written
422  * @param byte_order the byte order to use
423  * @param value the value
424  * @param len the length to use
425  * @returns #TRUE on success
426  * 
427  */
428 dbus_bool_t
429 _dbus_marshal_set_string (DBusString          *str,
430                           int                  byte_order,
431                           int                  offset,
432                           const DBusString    *value,
433                           int                  len)
434 {
435   int old_len;
436   
437   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
438                 byte_order == DBUS_BIG_ENDIAN);
439   
440   old_len = _dbus_demarshal_uint32 (str, byte_order,
441                                     offset, NULL);
442
443   if (!_dbus_string_replace_len (value, 0, len,
444                                  str, offset + 4, old_len))
445     return FALSE;
446
447   _dbus_marshal_set_uint32 (str, byte_order,
448                             offset, len);
449
450   return TRUE;
451 }
452
453 /**
454  * Sets the existing marshaled object path at the given offset to a new
455  * value. The given offset must point to an existing object path or this
456  * function doesn't make sense.
457  *
458  * @todo implement this function
459  *
460  * @param str the string to write the marshalled path to
461  * @param offset the byte offset where path should be written
462  * @param byte_order the byte order to use
463  * @param path the new path
464  * @param path_len number of elements in the path
465  */
466 void
467 _dbus_marshal_set_object_path (DBusString         *str,
468                                int                 byte_order,
469                                int                 offset,
470                                const char        **path,
471                                int                 path_len)
472 {
473
474   /* FIXME */
475 }
476
477 static dbus_bool_t
478 marshal_4_octets (DBusString   *str,
479                   int           insert_at,
480                   int           byte_order,
481                   dbus_uint32_t value)
482 {
483   _dbus_assert (sizeof (value) == 4);
484   
485   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
486     value = DBUS_UINT32_SWAP_LE_BE (value);
487
488   return _dbus_string_insert_4_aligned (str, insert_at,
489                                         (const unsigned char *)&value);
490 }
491
492 static dbus_bool_t
493 marshal_8_octets (DBusString *str,
494                   int         insert_at,
495                   int         byte_order,
496                   DBusOctets8 value)
497 {
498   _dbus_assert (sizeof (value) == 8);
499
500   swap_8_octets (&value, byte_order);
501   
502   return _dbus_string_insert_8_aligned (str, insert_at,
503                                         (const unsigned char *)&value);
504 }
505
506 /**
507  * Marshals a double value.
508  *
509  * @param str the string to append the marshalled value to
510  * @param byte_order the byte order to use
511  * @param value the value
512  * @returns #TRUE on success
513  */
514 dbus_bool_t
515 _dbus_marshal_double (DBusString *str,
516                       int         byte_order,
517                       double      value)
518 {
519   DBusOctets8 r;
520   r.d = value;
521   return marshal_8_octets (str, _dbus_string_get_length (str),
522                            byte_order, r);
523 }
524
525 /**
526  * Marshals a 32 bit signed integer value.
527  *
528  * @param str the string to append the marshalled value to
529  * @param byte_order the byte order to use
530  * @param value the value
531  * @returns #TRUE on success
532  */
533 dbus_bool_t
534 _dbus_marshal_int32  (DBusString   *str,
535                       int           byte_order,
536                       dbus_int32_t  value)
537 {
538   return marshal_4_octets (str, _dbus_string_get_length (str),
539                            byte_order, (dbus_uint32_t) value);
540 }
541
542 /**
543  * Marshals a 32 bit unsigned integer value.
544  *
545  * @param str the string to append the marshalled value to
546  * @param byte_order the byte order to use
547  * @param value the value
548  * @returns #TRUE on success
549  */
550 dbus_bool_t
551 _dbus_marshal_uint32 (DBusString   *str,
552                       int           byte_order,
553                       dbus_uint32_t value)
554 {
555   return marshal_4_octets (str, _dbus_string_get_length (str),
556                            byte_order, value);
557 }
558
559
560 #ifdef DBUS_HAVE_INT64
561 /**
562  * Marshals a 64 bit signed integer value.
563  *
564  * @param str the string to append the marshalled value to
565  * @param byte_order the byte order to use
566  * @param value the value
567  * @returns #TRUE on success
568  */
569 dbus_bool_t
570 _dbus_marshal_int64  (DBusString   *str,
571                       int           byte_order,
572                       dbus_int64_t  value)
573 {
574   DBusOctets8 r;
575   r.s = value;
576   return marshal_8_octets (str, _dbus_string_get_length (str),
577                            byte_order, r);
578 }
579
580 /**
581  * Marshals a 64 bit unsigned integer value.
582  *
583  * @param str the string to append the marshalled value to
584  * @param byte_order the byte order to use
585  * @param value the value
586  * @returns #TRUE on success
587  */
588 dbus_bool_t
589 _dbus_marshal_uint64 (DBusString    *str,
590                       int            byte_order,
591                       dbus_uint64_t  value)
592 {
593   DBusOctets8 r;
594   r.u = value;
595   return marshal_8_octets (str, _dbus_string_get_length (str),
596                            byte_order, r);
597 }
598
599 #endif /* DBUS_HAVE_INT64 */
600
601 /**
602  * Marshals a UTF-8 string
603  *
604  * @todo: If the string append fails we need to restore
605  * the old length. (also for other marshallers)
606  * 
607  * @param str the string to append the marshalled value to
608  * @param byte_order the byte order to use
609  * @param value the string
610  * @returns #TRUE on success
611  */
612 dbus_bool_t
613 _dbus_marshal_string (DBusString    *str,
614                       int            byte_order,
615                       const char    *value)
616 {
617   int len, old_string_len;
618
619   old_string_len = _dbus_string_get_length (str);
620   
621   len = strlen (value);
622
623   if (!_dbus_marshal_uint32 (str, byte_order, len))
624     {
625       /* Restore the previous length */
626       _dbus_string_set_length (str, old_string_len);
627
628       return FALSE;
629     }
630
631   return _dbus_string_append_len (str, value, len + 1);
632 }
633
634 /**
635  * Marshals a UTF-8 string
636  *
637  * @todo: If the string append fails we need to restore
638  * the old length. (also for other marshallers)
639  * 
640  * @param str the string to append the marshalled value to
641  * @param byte_order the byte order to use
642  * @param value the string
643  * @param len length of string to marshal in bytes
644  * @returns #TRUE on success
645  */
646 dbus_bool_t
647 _dbus_marshal_string_len (DBusString    *str,
648                           int            byte_order,
649                           const char    *value,
650                           int            len)
651 {
652   int old_string_len;
653
654   old_string_len = _dbus_string_get_length (str);
655
656   if (!_dbus_marshal_uint32 (str, byte_order, len))
657     {
658       /* Restore the previous length */
659       _dbus_string_set_length (str, old_string_len);
660
661       return FALSE;
662     }
663
664   if (!_dbus_string_append_len (str, value, len))
665     return FALSE;
666
667   /* add a nul byte */
668   if (!_dbus_string_lengthen (str, 1))
669     return FALSE;
670
671   return TRUE;
672 }
673
674 static dbus_bool_t
675 _dbus_marshal_signature (DBusString    *str,
676                          const char    *value)
677 {
678   int len, old_string_len;
679
680   old_string_len = _dbus_string_get_length (str);
681   
682   len = strlen (value);
683
684   _dbus_assert (len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
685   
686   if (!_dbus_string_append_byte (str, len))
687     {
688       /* Restore the previous length */
689       _dbus_string_set_length (str, old_string_len);
690
691       return FALSE;
692     }
693
694   return _dbus_string_append_len (str, value, len + 1);
695 }
696
697 /**
698  * Marshals a byte array
699  *
700  * @param str the string to append the marshalled value to
701  * @param byte_order the byte order to use
702  * @param value the array
703  * @param len number of elements in the array
704  * @returns #TRUE on success
705  */
706 dbus_bool_t
707 _dbus_marshal_byte_array (DBusString          *str,
708                           int                  byte_order,
709                           const unsigned char *value,
710                           int                  len)
711 {
712   int old_string_len;
713
714   old_string_len = _dbus_string_get_length (str);
715   
716   if (!_dbus_marshal_uint32 (str, byte_order, len))
717     {
718       /* Restore the previous length */
719       _dbus_string_set_length (str, old_string_len);
720
721       return FALSE;
722     }
723
724   if (len == 0)
725     return TRUE;
726   else
727     return _dbus_string_append_len (str, value, len);
728 }
729
730 static dbus_bool_t
731 marshal_4_octets_array (DBusString          *str,
732                         int                  byte_order,
733                         const dbus_uint32_t *value,
734                         int                  len)
735 {
736   int old_string_len;
737   int array_start;
738
739   old_string_len = _dbus_string_get_length (str);
740
741   if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
742     goto error;
743
744   array_start = _dbus_string_get_length (str);
745   
746   if (!_dbus_string_append_len (str, (const unsigned char*) value,
747                                 len * 4))
748     goto error;
749   
750   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
751     {
752       const unsigned char *d;
753       const unsigned char *end;
754       
755       d = _dbus_string_get_data (str) + array_start;
756       end = d + len * 4;
757       while (d != end)
758         {
759           *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
760           d += 4;
761         }
762     }
763
764   return TRUE;
765   
766  error:
767   /* Restore previous length */
768   _dbus_string_set_length (str, old_string_len);
769   
770   return FALSE;  
771 }
772
773 static dbus_bool_t
774 marshal_8_octets_array (DBusString          *str,
775                         int                  byte_order,
776                         const DBusOctets8   *value,
777                         int                  len)
778 {
779   int old_string_len;
780   int array_start;
781   
782   old_string_len = _dbus_string_get_length (str);
783
784   /*  The array length is the length in bytes of the array,
785    * *excluding* alignment padding.
786    */
787   if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
788     goto error;
789
790   array_start = _dbus_string_get_length (str);
791
792   /* Note that we do alignment padding unconditionally
793    * even if the array is empty; this means that
794    * padding + len is always equal to the number of bytes
795    * in the array.
796    */
797   
798   if (!_dbus_string_align_length (str, 8))
799     goto error;
800   
801   if (!_dbus_string_append_len (str, (const unsigned char*) value,
802                                 len * 8))
803     goto error;
804   
805   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
806     {
807       const unsigned char *d;
808       const unsigned char *end;
809       
810       d = _dbus_string_get_data (str) + array_start;
811       end = d + len * 8;
812       while (d != end)
813         {
814 #ifdef DBUS_HAVE_INT64
815           *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
816 #else
817           swap_bytes ((unsigned char*) d, 8);
818 #endif
819           d += 8;
820         }
821     }
822
823   return TRUE;
824   
825  error:
826   /* Restore previous length */
827   _dbus_string_set_length (str, old_string_len);
828   
829   return FALSE;  
830 }
831
832 /**
833  * Marshals a 32 bit signed integer array
834  *
835  * @param str the string to append the marshalled value to
836  * @param byte_order the byte order to use
837  * @param value the array
838  * @param len the length of the array
839  * @returns #TRUE on success
840  */
841 dbus_bool_t
842 _dbus_marshal_int32_array (DBusString         *str,
843                            int                 byte_order,
844                            const dbus_int32_t *value,
845                            int                 len)
846 {
847   return marshal_4_octets_array (str, byte_order,
848                                  (const dbus_uint32_t*) value,
849                                  len);
850 }
851
852 /**
853  * Marshals a 32 bit unsigned integer array
854  *
855  * @param str the string to append the marshalled value to
856  * @param byte_order the byte order to use
857  * @param value the array
858  * @param len the length of the array
859  * @returns #TRUE on success
860  */
861 dbus_bool_t
862 _dbus_marshal_uint32_array (DBusString          *str,
863                             int                  byte_order,
864                             const dbus_uint32_t  *value,
865                             int                  len)
866 {
867   return marshal_4_octets_array (str, byte_order,
868                                  value,
869                                  len);
870 }
871
872 #ifdef DBUS_HAVE_INT64
873
874 /**
875  * Marshals a 64 bit signed integer array
876  *
877  * @param str the string to append the marshalled value to
878  * @param byte_order the byte order to use
879  * @param value the array
880  * @param len the length of the array
881  * @returns #TRUE on success
882  */
883 dbus_bool_t
884 _dbus_marshal_int64_array (DBusString         *str,
885                            int                 byte_order,
886                            const dbus_int64_t *value,
887                            int                 len)
888 {
889   return marshal_8_octets_array (str, byte_order,
890                                  (const DBusOctets8*) value,
891                                  len);
892 }
893
894 /**
895  * Marshals a 64 bit unsigned integer array
896  *
897  * @param str the string to append the marshalled value to
898  * @param byte_order the byte order to use
899  * @param value the array
900  * @param len the length of the array
901  * @returns #TRUE on success
902  */
903 dbus_bool_t
904 _dbus_marshal_uint64_array (DBusString          *str,
905                             int                  byte_order,
906                             const dbus_uint64_t  *value,
907                             int                  len)
908 {
909   return marshal_8_octets_array (str, byte_order,
910                                  (const DBusOctets8*) value,
911                                  len);
912 }
913
914 #endif /* DBUS_HAVE_INT64 */
915
916 /**
917  * Marshals a double array
918  *
919  * @param str the string to append the marshalled value to
920  * @param byte_order the byte order to use
921  * @param value the array
922  * @param len the length of the array
923  * @returns #TRUE on success
924  */
925 dbus_bool_t
926 _dbus_marshal_double_array (DBusString          *str,
927                             int                  byte_order,
928                             const double        *value,
929                             int                  len)
930 {
931   return marshal_8_octets_array (str, byte_order,
932                                  (const DBusOctets8*) value,
933                                  len);
934 }
935
936 /**
937  * Marshals a string array
938  *
939  * @param str the string to append the marshalled value to
940  * @param byte_order the byte order to use
941  * @param value the array
942  * @param len the length of the array
943  * @returns #TRUE on success
944  */
945 dbus_bool_t
946 _dbus_marshal_string_array (DBusString  *str,
947                             int          byte_order,
948                             const char **value,
949                             int          len)
950 {
951   int i, old_string_len, array_start;
952
953   old_string_len = _dbus_string_get_length (str);
954
955   /* Set the length to 0 temporarily */
956   if (!_dbus_marshal_uint32 (str, byte_order, 0))
957     goto error;
958
959   array_start = _dbus_string_get_length (str);
960   
961   for (i = 0; i < len; i++)
962     if (!_dbus_marshal_string (str, byte_order, value[i]))
963       goto error;
964
965   /* Write the length now that we know it */
966   _dbus_marshal_set_uint32 (str, byte_order,
967                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
968                             _dbus_string_get_length (str) - array_start);
969   
970   return TRUE;
971   
972  error:
973   /* Restore previous length */
974   _dbus_string_set_length (str, old_string_len);
975   
976   return FALSE;      
977 }
978
979 /**
980  * Marshals an object path value.
981  * 
982  * @param str the string to append the marshalled value to
983  * @param byte_order the byte order to use
984  * @param path the path
985  * @param path_len length of the path
986  * @returns #TRUE on success
987  */
988 static dbus_bool_t
989 _dbus_marshal_object_path (DBusString            *str,
990                            int                    byte_order,
991                            const char           **path,
992                            int                    path_len)
993 {
994   int array_start, old_string_len;
995   int i;
996   
997   old_string_len = _dbus_string_get_length (str);
998   
999   /* Set the length to 0 temporarily */
1000   if (!_dbus_marshal_uint32 (str, byte_order, 0))
1001     goto nomem;
1002
1003   array_start = _dbus_string_get_length (str);
1004   
1005   i = 0;
1006   while (i < path_len)
1007     {
1008       if (!_dbus_string_append_byte (str, '/'))
1009         goto nomem;
1010       
1011       if (!_dbus_string_append (str, path[0]))
1012         goto nomem;
1013
1014       ++i;
1015     }
1016
1017   /* Write the length now that we know it */
1018   _dbus_marshal_set_uint32 (str, byte_order,
1019                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
1020                             _dbus_string_get_length (str) - array_start);  
1021
1022   return TRUE;
1023
1024  nomem:
1025   /* Restore the previous length */
1026   _dbus_string_set_length (str, old_string_len);
1027   
1028   return FALSE;
1029 }
1030
1031 static dbus_uint32_t
1032 demarshal_4_octets (const DBusString *str,
1033                     int               byte_order,
1034                     int               pos,
1035                     int              *new_pos)
1036 {
1037   const DBusRealString *real = (const DBusRealString*) str;
1038   
1039   pos = _DBUS_ALIGN_VALUE (pos, 4);
1040   
1041   if (new_pos)
1042     *new_pos = pos + 4;
1043
1044   return unpack_4_octets (byte_order, real->str + pos);
1045 }
1046
1047 static DBusOctets8
1048 demarshal_8_octets (const DBusString *str,
1049                     int               byte_order,
1050                     int               pos,
1051                     int              *new_pos)
1052 {
1053   const DBusRealString *real = (const DBusRealString*) str;
1054   
1055   pos = _DBUS_ALIGN_VALUE (pos, 8);
1056   
1057   if (new_pos)
1058     *new_pos = pos + 8;
1059
1060   return unpack_8_octets (byte_order, real->str + pos);
1061 }
1062
1063 /**
1064  * Demarshals a double.
1065  *
1066  * @param str the string containing the data
1067  * @param byte_order the byte order
1068  * @param pos the position in the string
1069  * @param new_pos the new position of the string
1070  * @returns the demarshaled double.
1071  */
1072 double
1073 _dbus_demarshal_double (const DBusString  *str,
1074                         int                byte_order,
1075                         int                pos,
1076                         int               *new_pos)
1077 {
1078   DBusOctets8 r;
1079
1080   r = demarshal_8_octets (str, byte_order, pos, new_pos);
1081
1082   return r.d;
1083 }
1084
1085 /**
1086  * Demarshals a 32 bit signed integer.
1087  *
1088  * @param str the string containing the data
1089  * @param byte_order the byte order
1090  * @param pos the position in the string
1091  * @param new_pos the new position of the string
1092  * @returns the demarshaled integer.
1093  */
1094 dbus_int32_t
1095 _dbus_demarshal_int32  (const DBusString *str,
1096                         int               byte_order,
1097                         int               pos,
1098                         int              *new_pos)
1099 {
1100   return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
1101 }
1102
1103 /**
1104  * Demarshals a 32 bit unsigned integer.
1105  *
1106  * @param str the string containing the data
1107  * @param byte_order the byte order
1108  * @param pos the position in the string
1109  * @param new_pos the new position of the string
1110  * @returns the demarshaled integer.
1111  */
1112 dbus_uint32_t
1113 _dbus_demarshal_uint32  (const DBusString *str,
1114                          int         byte_order,
1115                          int         pos,
1116                          int        *new_pos)
1117 {
1118   return demarshal_4_octets (str, byte_order, pos, new_pos);
1119 }
1120
1121 #ifdef DBUS_HAVE_INT64
1122
1123 /**
1124  * Demarshals a 64 bit signed integer.
1125  *
1126  * @param str the string containing the data
1127  * @param byte_order the byte order
1128  * @param pos the position in the string
1129  * @param new_pos the new position of the string
1130  * @returns the demarshaled integer.
1131  */
1132 dbus_int64_t
1133 _dbus_demarshal_int64  (const DBusString *str,
1134                         int               byte_order,
1135                         int               pos,
1136                         int              *new_pos)
1137 {
1138   DBusOctets8 r;
1139
1140   r = demarshal_8_octets (str, byte_order, pos, new_pos);
1141
1142   return r.s;
1143 }
1144
1145 /**
1146  * Demarshals a 64 bit unsigned integer.
1147  *
1148  * @param str the string containing the data
1149  * @param byte_order the byte order
1150  * @param pos the position in the string
1151  * @param new_pos the new position of the string
1152  * @returns the demarshaled integer.
1153  */
1154 dbus_uint64_t
1155 _dbus_demarshal_uint64  (const DBusString *str,
1156                          int         byte_order,
1157                          int         pos,
1158                          int        *new_pos)
1159 {
1160   DBusOctets8 r;
1161
1162   r = demarshal_8_octets (str, byte_order, pos, new_pos);
1163
1164   return r.u;
1165 }
1166
1167 #endif /* DBUS_HAVE_INT64 */
1168
1169 /**
1170  * Demarshals a basic type
1171  *
1172  * @param str the string containing the data
1173  * @param type type of value to demarshal
1174  * @param value pointer to return value data
1175  * @param byte_order the byte order
1176  * @param pos pointer to position in the string,
1177  *            updated on return to new position
1178  **/
1179 void
1180 _dbus_demarshal_basic_type (const DBusString      *str,
1181                             int                    type,
1182                             void                  *value,
1183                             int                    byte_order,
1184                             int                   *pos)
1185 {
1186   const char *str_data = _dbus_string_get_const_data (str);
1187
1188   switch (type)
1189     {
1190     case DBUS_TYPE_BYTE:
1191     case DBUS_TYPE_BOOLEAN:
1192       *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
1193       (*pos)++;
1194       break;
1195     case DBUS_TYPE_INT32:
1196     case DBUS_TYPE_UINT32:
1197       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1198       *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
1199       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1200         *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
1201       *pos += 4;
1202       break;
1203 #ifdef DBUS_HAVE_INT64
1204     case DBUS_TYPE_INT64:
1205     case DBUS_TYPE_UINT64: 
1206 #endif /* DBUS_HAVE_INT64 */
1207     case DBUS_TYPE_DOUBLE:
1208       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1209       memcpy (value, str_data + *pos, 8);
1210       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1211 #ifdef DBUS_HAVE_INT64
1212         *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
1213 #else   
1214         swap_bytes (value, 8);
1215 #endif
1216       *pos += 8;
1217       break;
1218     case DBUS_TYPE_STRING:
1219     case DBUS_TYPE_OBJECT_PATH:
1220       {
1221         int len;
1222         
1223         len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1224         
1225         *(const char**) value = str_data + *pos;
1226
1227         *pos += len + 1; /* length plus nul */
1228       }
1229       break;
1230     case DBUS_TYPE_SIGNATURE:
1231       {
1232         int len;
1233         
1234         len = _dbus_string_get_byte (str, *pos);
1235         *pos += 1;
1236         
1237         *(const char**) value = str_data + *pos;
1238
1239         *pos += len + 1; /* length plus nul */
1240       }
1241       break;
1242     default:
1243       _dbus_verbose ("type %s not a basic type\n",
1244                      _dbus_type_to_string (type));
1245       _dbus_assert_not_reached ("not a basic type");
1246       break;
1247     }
1248 }
1249
1250 /**
1251  * Demarshals an UTF-8 string.
1252  *
1253  * @todo Should we check the string to make sure
1254  * that it's  valid UTF-8, and maybe "fix" the string
1255  * if it's broken?
1256  *
1257  * @todo Should probably demarshal to a DBusString,
1258  * having memcpy() in here is Evil(tm).
1259  *
1260  * @param str the string containing the data
1261  * @param byte_order the byte order
1262  * @param pos the position in the string
1263  * @param new_pos the new position of the string
1264  * @returns the demarshaled string.
1265  */
1266 char *
1267 _dbus_demarshal_string (const DBusString *str,
1268                         int               byte_order,
1269                         int               pos,
1270                         int              *new_pos)
1271 {
1272   int len;
1273   char *retval;
1274   const char *data;
1275   
1276   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1277
1278   retval = dbus_malloc (len + 1);
1279
1280   if (!retval)
1281     return NULL;
1282
1283   data = _dbus_string_get_const_data_len (str, pos, len + 1);
1284
1285   if (!data)
1286     return NULL;
1287
1288   memcpy (retval, data, len + 1);
1289
1290   if (new_pos)
1291     *new_pos = pos + len + 1;
1292   
1293   return retval;
1294 }
1295
1296 /**
1297  * Demarshals a byte array.
1298  *
1299  * @todo Should probably demarshal to a DBusString,
1300  * having memcpy() in here is Evil(tm).
1301  *
1302  * @param str the string containing the data
1303  * @param byte_order the byte order
1304  * @param pos the position in the string
1305  * @param new_pos the new position of the string
1306  * @param array the array
1307  * @param array_len length of the demarshaled data
1308  
1309  * @returns #TRUE on success
1310  */
1311 dbus_bool_t
1312 _dbus_demarshal_byte_array (const DBusString  *str,
1313                             int                byte_order,
1314                             int                pos,
1315                             int               *new_pos,
1316                             unsigned char    **array,
1317                             int               *array_len)
1318 {
1319   int len;
1320   unsigned char *retval;
1321   const char *data;
1322
1323   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1324
1325   if (len == 0)
1326     {
1327       *array_len = len;
1328       *array = NULL;
1329
1330       if (new_pos)
1331         *new_pos = pos;
1332       
1333       return TRUE;
1334     }
1335   
1336   retval = dbus_malloc (len);
1337
1338   if (!retval)
1339     return FALSE;
1340
1341   data = _dbus_string_get_const_data_len (str, pos, len);
1342
1343   if (!data)
1344     {
1345       dbus_free (retval);
1346       return FALSE;
1347     }
1348
1349   memcpy (retval, data, len);
1350
1351   if (new_pos)
1352     *new_pos = pos + len;
1353
1354   *array = retval;
1355   *array_len = len;
1356   
1357   return TRUE;
1358 }
1359
1360 static dbus_bool_t
1361 demarshal_4_octets_array (const DBusString  *str,
1362                           int                byte_order,
1363                           int                pos,
1364                           int               *new_pos,
1365                           dbus_uint32_t    **array,
1366                           int               *array_len)
1367 {
1368   int len, i;
1369   dbus_uint32_t *retval;
1370   int byte_len;
1371   
1372   byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1373   len = byte_len / 4;
1374
1375   if (len == 0)
1376     {
1377       *array_len = 0;
1378       *array = NULL;
1379
1380       if (new_pos)
1381         *new_pos = pos;
1382       
1383       return TRUE;
1384     }
1385
1386   if (!_dbus_string_copy_data_len (str, (char**) &retval,
1387                                    pos, byte_len))
1388     return FALSE;
1389   
1390   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1391     {
1392       for (i = 0; i < len; i++)
1393         retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1394     }
1395
1396   if (new_pos)
1397     *new_pos = pos + byte_len;
1398
1399   *array_len = len;
1400   *array = retval;
1401   
1402   return TRUE;  
1403 }
1404
1405 static dbus_bool_t
1406 demarshal_8_octets_array (const DBusString  *str,
1407                           int                byte_order,
1408                           int                pos,
1409                           int               *new_pos,
1410                           DBusOctets8      **array,
1411                           int               *array_len)
1412 {
1413   int len, i;
1414   DBusOctets8 *retval;
1415   int byte_len;
1416   
1417   byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1418
1419   pos = _DBUS_ALIGN_VALUE (pos, 8);
1420   
1421   len = byte_len / 8;
1422
1423   if (len == 0)
1424     {
1425       *array_len = 0;
1426       *array = NULL;
1427
1428       if (new_pos)
1429         *new_pos = pos;
1430       
1431       return TRUE;
1432     }
1433
1434   if (!_dbus_string_copy_data_len (str, (char**) &retval,
1435                                    pos, byte_len))
1436     return FALSE;
1437   
1438   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1439     {
1440       for (i = 0; i < len; i++)
1441         {
1442 #ifdef DBUS_HAVE_INT64
1443           retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1444 #else
1445           swap_bytes ((unsigned char *) &retval[i], 8);
1446 #endif
1447         }
1448     }
1449
1450   if (new_pos)
1451     *new_pos = pos + byte_len;
1452
1453   *array_len = len;
1454   *array = retval;
1455   
1456   return TRUE;  
1457 }
1458
1459 /**
1460  * Demarshals a 32 bit signed integer array.
1461  *
1462  * @param str the string containing the data
1463  * @param byte_order the byte order
1464  * @param pos the position in the string
1465  * @param new_pos the new position of the string
1466  * @param array the array
1467  * @param array_len length of the demarshaled data
1468  * @returns #TRUE on success
1469  */
1470 dbus_bool_t
1471 _dbus_demarshal_int32_array (const DBusString  *str,
1472                              int                byte_order,
1473                              int                pos,
1474                              int               *new_pos,
1475                              dbus_int32_t     **array,
1476                              int               *array_len)
1477 {
1478   return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1479                                    (dbus_uint32_t**) array, array_len);
1480 }
1481
1482 /**
1483  * Demarshals a 32 bit unsigned integer array.
1484  *
1485  * @param str the string containing the data
1486  * @param byte_order the byte order
1487  * @param pos the position in the string
1488  * @param new_pos the new position of the string
1489  * @param array the array
1490  * @param array_len length of the demarshaled data
1491  * @returns #TRUE on success
1492  */
1493 dbus_bool_t
1494 _dbus_demarshal_uint32_array (const DBusString  *str,
1495                               int                byte_order,
1496                               int                pos,
1497                               int               *new_pos,
1498                               dbus_uint32_t    **array,
1499                               int               *array_len)
1500 {
1501   return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1502                                    array, array_len);
1503 }
1504
1505 #ifdef DBUS_HAVE_INT64
1506
1507 /**
1508  * Demarshals a 64 bit signed integer array.
1509  *
1510  * @param str the string containing the data
1511  * @param byte_order the byte order
1512  * @param pos the position in the string
1513  * @param new_pos the new position of the string
1514  * @param array the array
1515  * @param array_len length of the demarshaled data
1516  * @returns #TRUE on success
1517  */
1518 dbus_bool_t
1519 _dbus_demarshal_int64_array (const DBusString  *str,
1520                              int                byte_order,
1521                              int                pos,
1522                              int               *new_pos,
1523                              dbus_int64_t     **array,
1524                              int               *array_len)
1525 {
1526   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1527                                    (DBusOctets8**) array, array_len);
1528 }
1529
1530 /**
1531  * Demarshals a 64 bit unsigned integer array.
1532  *
1533  * @param str the string containing the data
1534  * @param byte_order the byte order
1535  * @param pos the position in the string
1536  * @param new_pos the new position of the string
1537  * @param array the array
1538  * @param array_len length of the demarshaled data
1539  * @returns #TRUE on success
1540  */
1541 dbus_bool_t
1542 _dbus_demarshal_uint64_array (const DBusString  *str,
1543                               int                byte_order,
1544                               int                pos,
1545                               int               *new_pos,
1546                               dbus_uint64_t    **array,
1547                               int               *array_len)
1548 {
1549   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1550                                    (DBusOctets8**) array, array_len);
1551 }
1552
1553 #endif /* DBUS_HAVE_INT64 */
1554
1555 /**
1556  * Demarshals a double array.
1557  *
1558  * @param str the string containing the data
1559  * @param byte_order the byte order
1560  * @param pos the position in the string
1561  * @param new_pos the new position of the string
1562  * @param array the array
1563  * @param array_len length of the demarshaled data
1564  * @returns #TRUE on success
1565  */
1566 dbus_bool_t
1567 _dbus_demarshal_double_array (const DBusString  *str,
1568                               int                byte_order,
1569                               int                pos,
1570                               int               *new_pos,
1571                               double           **array,
1572                               int               *array_len)
1573 {
1574   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1575                                    (DBusOctets8**) array, array_len);
1576 }
1577
1578
1579 /**
1580  * Demarshals an array of basic types
1581  *
1582  * @param str the string containing the data
1583  * @param element_type type of array elements to demarshal
1584  * @param array pointer to pointer to array data
1585  * @param array_len pointer to array length
1586  * @param byte_order the byte order
1587  * @param pos pointer to position in the string,
1588  *            updated on return to new position
1589  **/
1590 dbus_bool_t
1591 _dbus_demarshal_basic_type_array (const DBusString      *str,
1592                                   int                    element_type,
1593                                   void                 **array,
1594                                   int                   *array_len,
1595                                   int                    byte_order,
1596                                   int                   *pos)
1597 {
1598   switch (element_type)
1599     {
1600     case DBUS_TYPE_BOOLEAN:
1601       /* FIXME: do we want to post-normalize these ? */
1602     case DBUS_TYPE_BYTE:
1603       return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
1604                                          (unsigned char **)array, array_len);
1605       break;
1606     case DBUS_TYPE_INT32:
1607     case DBUS_TYPE_UINT32:
1608       return demarshal_4_octets_array (str, byte_order, *pos, pos,
1609                                        (dbus_uint32_t **)array, array_len);
1610       break;
1611 #ifdef DBUS_HAVE_INT64
1612     case DBUS_TYPE_INT64:
1613     case DBUS_TYPE_UINT64: 
1614 #endif /* DBUS_HAVE_INT64 */
1615     case DBUS_TYPE_DOUBLE:
1616       return demarshal_8_octets_array (str, byte_order, *pos, pos,
1617                                        (DBusOctets8**) array, array_len);
1618     default:
1619       _dbus_assert_not_reached ("not a basic type");
1620       break;
1621     }
1622   return FALSE;
1623 }
1624
1625 /**
1626  * Demarshals a string array.
1627  *
1628  * @param str the string containing the data
1629  * @param byte_order the byte order
1630  * @param pos the position in the string
1631  * @param new_pos the new position of the string
1632  * @param array the array
1633  * @param array_len location for length of the demarshaled data or NULL
1634  * @returns #TRUE on success
1635  */
1636 dbus_bool_t
1637 _dbus_demarshal_string_array (const DBusString   *str,
1638                               int                 byte_order,
1639                               int                 pos,
1640                               int                *new_pos,
1641                               char             ***array,
1642                               int                *array_len)
1643 {
1644   int bytes_len, i;
1645   int len, allocated;
1646   int end_pos;
1647   char **retval;
1648   
1649   bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1650   
1651   if (bytes_len == 0)
1652     {
1653       *array_len = 0;
1654       *array = NULL;
1655
1656       if (new_pos)
1657         *new_pos = pos;
1658       
1659       return TRUE;
1660     }
1661
1662   len = 0;
1663   allocated = 4;
1664   end_pos = pos + bytes_len;
1665   
1666   retval = dbus_new (char *, allocated);
1667
1668   if (!retval)
1669     return FALSE;
1670
1671   while (pos < end_pos)
1672     {
1673       retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1674       
1675       if (retval[len] == NULL)
1676         goto error;
1677       
1678       len += 1;
1679
1680       if (len >= allocated - 1) /* -1 for NULL termination */
1681         {
1682           char **newp;
1683           newp = dbus_realloc (retval,
1684                                sizeof (char*) * allocated * 2);
1685           if (newp == NULL)
1686             goto error;
1687
1688           allocated *= 2;
1689           retval = newp;
1690         }
1691     }
1692       
1693   retval[len] = NULL;
1694
1695   if (new_pos)
1696     *new_pos = pos;
1697   
1698   *array = retval;
1699   *array_len = len;
1700   
1701   return TRUE;
1702
1703  error:
1704   for (i = 0; i < len; i++)
1705     dbus_free (retval[i]);
1706   dbus_free (retval);
1707
1708   return FALSE;
1709 }
1710
1711 /** Set to 1 to get a bunch of spew about disassembling the path string */
1712 #define VERBOSE_DECOMPOSE 0
1713
1714 /**
1715  * Decompose an object path.  A path of just "/" is
1716  * represented as an empty vector of strings.
1717  * 
1718  * @param data the path data
1719  * @param len  the length of the path string
1720  * @param path address to store new object path
1721  * @param path_len length of stored path
1722  */
1723 dbus_bool_t
1724 _dbus_decompose_path (const char*     data,
1725                       int             len,
1726                       char         ***path,
1727                       int            *path_len)
1728 {
1729   char **retval;
1730   int n_components;
1731   int i, j, comp;
1732
1733   _dbus_assert (data != NULL);
1734
1735 #if VERBOSE_DECOMPOSE
1736   _dbus_verbose ("Decomposing path \"%s\"\n",
1737                  data);
1738 #endif
1739   
1740   n_components = 0;
1741   i = 0;
1742   while (i < len)
1743     {
1744       if (data[i] == '/')
1745         n_components += 1;
1746       ++i;
1747     }
1748   
1749   retval = dbus_new0 (char*, n_components + 1);
1750
1751   if (retval == NULL)
1752     return FALSE;
1753
1754   comp = 0;
1755   i = 0;
1756   while (i < len)
1757     {
1758       if (data[i] == '/')
1759         ++i;
1760       j = i;
1761
1762       while (j < len && data[j] != '/')
1763         ++j;
1764
1765       /* Now [i, j) is the path component */
1766       _dbus_assert (i < j);
1767       _dbus_assert (data[i] != '/');
1768       _dbus_assert (j == len || data[j] == '/');
1769
1770 #if VERBOSE_DECOMPOSE
1771       _dbus_verbose ("  (component in [%d,%d))\n",
1772                      i, j);
1773 #endif
1774       
1775       retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1776       if (retval[comp] == NULL)
1777         {
1778           dbus_free_string_array (retval);
1779           return FALSE;
1780         }
1781       retval[comp][j-i] = '\0';
1782 #if VERBOSE_DECOMPOSE
1783       _dbus_verbose ("  (component %d = \"%s\")\n",
1784                      comp, retval[comp]);
1785 #endif
1786
1787       ++comp;
1788       i = j;
1789     }
1790   _dbus_assert (i == len);
1791   
1792   *path = retval;
1793   if (path_len)
1794     *path_len = n_components;
1795   
1796   return TRUE;
1797 }
1798
1799 /**
1800  * Demarshals an object path.  A path of just "/" is
1801  * represented as an empty vector of strings.
1802  * 
1803  * @param str the string containing the data
1804  * @param byte_order the byte order
1805  * @param pos the position in the string
1806  * @param new_pos the new position of the string
1807  * @param path address to store new object path
1808  * @param path_len length of stored path
1809  */
1810 dbus_bool_t
1811 _dbus_demarshal_object_path (const DBusString *str,
1812                              int               byte_order,
1813                              int               pos,
1814                              int              *new_pos,
1815                              char           ***path,
1816                              int              *path_len)
1817 {
1818   int len;
1819   const char *data;
1820   
1821   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1822   data = _dbus_string_get_const_data_len (str, pos, len + 1);
1823
1824   if (!_dbus_decompose_path (data, len, path, path_len))
1825     return FALSE;
1826
1827   if (new_pos)
1828     *new_pos = pos + len + 1;
1829
1830   return TRUE;
1831 }
1832
1833 /**
1834  * Skips over a basic type, reporting the following position.
1835  *
1836  * @param str the string containing the data
1837  * @param type type of value to demarshal
1838  * @param byte_order the byte order
1839  * @param pos pointer to position in the string,
1840  *            updated on return to new position
1841  **/
1842 void
1843 _dbus_marshal_skip_basic_type (const DBusString      *str,
1844                                int                    type,
1845                                int                    byte_order,
1846                                int                   *pos)
1847 {
1848   switch (type)
1849     {
1850     case DBUS_TYPE_BYTE:
1851     case DBUS_TYPE_BOOLEAN:
1852       (*pos)++;
1853       break;
1854     case DBUS_TYPE_INT32:
1855     case DBUS_TYPE_UINT32:
1856       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1857       *pos += 4;
1858       break;
1859 #ifdef DBUS_HAVE_INT64
1860     case DBUS_TYPE_INT64:
1861     case DBUS_TYPE_UINT64: 
1862 #endif /* DBUS_HAVE_INT64 */
1863     case DBUS_TYPE_DOUBLE:
1864       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1865       *pos += 8;
1866       break;
1867     case DBUS_TYPE_STRING:
1868     case DBUS_TYPE_OBJECT_PATH:
1869       {
1870         int len;
1871         
1872         len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1873         
1874         *pos += len + 1; /* length plus nul */
1875       }
1876       break;
1877     case DBUS_TYPE_SIGNATURE:
1878       {
1879         int len;
1880         
1881         len = _dbus_string_get_byte (str, *pos);
1882         
1883         *pos += len + 2; /* length byte plus length plus nul */
1884       }
1885       break;
1886     default:
1887       _dbus_verbose ("type %s not a basic type\n",
1888                      _dbus_type_to_string (type));
1889       _dbus_assert_not_reached ("not a basic type");
1890       break;
1891     }
1892 }
1893
1894 /**
1895  * Skips an array, returning the next position.
1896  *
1897  * @param str the string containing the data
1898  * @param byte_order the byte order
1899  * @param pos pointer to position in the string,
1900  *            updated on return to new position
1901  */
1902 void
1903 _dbus_marshal_skip_array (const DBusString  *str,
1904                           int                byte_order,
1905                           int               *pos)
1906 {
1907   int len;
1908
1909   len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1910
1911   /* FIXME we need to insert alignment padding according to array type */
1912   
1913   *pos += len;
1914 }
1915
1916 /** 
1917  * Returns the position right after the end of an argument.  PERFORMS
1918  * NO VALIDATION WHATSOEVER. The message must have been previously
1919  * validated.
1920  *
1921  * @param str a string
1922  * @param byte_order the byte order to use
1923  * @param type the type of the argument
1924  * @param pos the pos where the arg starts
1925  * @param end_pos pointer where the position right
1926  * after the end position will follow
1927  * @returns TRUE if more data exists after the arg
1928  */
1929 dbus_bool_t
1930 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1931                                int               byte_order,
1932                                int               type,
1933                                int               pos,
1934                                int              *end_pos)
1935 {
1936   if (pos >= _dbus_string_get_length (str))
1937     return FALSE;
1938
1939   switch (type)
1940     {
1941     case DBUS_TYPE_INVALID:
1942       return FALSE;
1943       break;
1944
1945     case DBUS_TYPE_BYTE:
1946       *end_pos = pos + 1;
1947       break;
1948       
1949     case DBUS_TYPE_BOOLEAN:
1950       *end_pos = pos + 1;
1951       break;
1952
1953     case DBUS_TYPE_INT32:
1954     case DBUS_TYPE_UINT32:
1955       *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1956       break;
1957
1958     case DBUS_TYPE_INT64:
1959     case DBUS_TYPE_UINT64:
1960     case DBUS_TYPE_DOUBLE:
1961       
1962       *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1963       break;
1964
1965     case DBUS_TYPE_OBJECT_PATH:
1966     case DBUS_TYPE_STRING:
1967       {
1968         int len;
1969         
1970         /* Demarshal the length */
1971         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1972
1973         *end_pos = pos + len + 1;
1974       }
1975       break;
1976       
1977     case DBUS_TYPE_ARRAY:
1978       {
1979         int len;
1980
1981         /* Demarshal the length  */
1982         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1983
1984         /* FIXME needs to align to the right boundary for the array type */
1985         *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + len;
1986       }
1987       break;
1988       
1989     default:
1990       _dbus_warn ("Unknown message arg type %d\n", type);
1991       _dbus_assert_not_reached ("Unknown message argument type\n");
1992       return FALSE;
1993     }
1994
1995   if (*end_pos > _dbus_string_get_length (str))
1996     return FALSE;
1997   
1998   return TRUE;
1999 }
2000
2001 /**
2002  * Demarshals and validates a length; returns < 0 if the validation
2003  * fails. The length is required to be small enough that
2004  * len*sizeof(double) will not overflow, and small enough to fit in a
2005  * signed integer. DOES NOT check whether the length points
2006  * beyond the end of the string, because it doesn't know the
2007  * size of array elements.
2008  *
2009  * @param str the string
2010  * @param byte_order the byte order
2011  * @param pos the unaligned string position (snap to next aligned)
2012  * @param new_pos return location for new position.
2013  */
2014 static int
2015 demarshal_and_validate_len (const DBusString *str,
2016                             int               byte_order,
2017                             int               pos,
2018                             int              *new_pos)
2019 {
2020   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
2021   unsigned int len;
2022
2023   _dbus_assert (new_pos != NULL);
2024   
2025   if ((align_4 + 4) > _dbus_string_get_length (str))
2026     {
2027       _dbus_verbose ("not enough room in message for array length\n");
2028       return -1;
2029     }
2030   
2031   if (!_dbus_string_validate_nul (str, pos,
2032                                   align_4 - pos))
2033     {
2034       _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
2035       return -1;
2036     }
2037
2038   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
2039
2040   /* note that the len is the number of bytes, so we need it to be
2041    * at least SIZE_T_MAX, but make it smaller just to keep things
2042    * sane.  We end up using ints for most sizes to avoid unsigned mess
2043    * so limit to maximum 32-bit signed int divided by at least 8, more
2044    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
2045    */  
2046 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
2047   if (len > MAX_ARRAY_LENGTH)
2048     {
2049       _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
2050                      len, MAX_ARRAY_LENGTH, pos);
2051       return -1;
2052     }
2053   else
2054     return (int) len;
2055 }
2056
2057 static dbus_bool_t
2058 validate_string (const DBusString *str,
2059                  int               pos,
2060                  int               len_without_nul,
2061                  int              *end_pos)
2062 {
2063   *end_pos = pos + len_without_nul + 1;
2064   
2065   if (*end_pos > _dbus_string_get_length (str))
2066     {
2067       _dbus_verbose ("string length outside length of the message\n");
2068       return FALSE;
2069     }
2070   
2071   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
2072     {
2073       _dbus_verbose ("string arg not nul-terminated\n");
2074       return FALSE;
2075     }
2076   
2077   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
2078     {
2079       _dbus_verbose ("string is not valid UTF-8\n");
2080       return FALSE;
2081     }
2082
2083   return TRUE;
2084 }   
2085
2086 /**
2087  * Validates and returns a typecode at a specific position
2088  * in the message
2089  *
2090  * @param str a string
2091  * @param type the type of the argument
2092  * @param pos the pos where the typecode starts
2093  * @param end_pos pointer where the position right
2094  * after the end position will follow
2095  * @returns #TRUE if the type is valid.
2096  */
2097 dbus_bool_t
2098 _dbus_marshal_validate_type   (const DBusString *str,
2099                                int               pos,
2100                                int              *type,
2101                                int              *end_pos)
2102 {
2103   const char *data;
2104   
2105   if (pos >= _dbus_string_get_length (str))
2106     return FALSE;
2107
2108   data = _dbus_string_get_const_data_len (str, pos, 1);
2109
2110   if (_dbus_type_is_valid (*data))
2111     {
2112       *type = *data;
2113       if (end_pos != NULL)
2114         *end_pos = pos + 1;
2115       return TRUE;
2116     }
2117
2118   _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
2119   
2120   return FALSE;
2121 }
2122
2123 /* Faster validator for array data that doesn't call
2124  * validate_arg for each value
2125  */
2126 static dbus_bool_t
2127 validate_array_data (const DBusString *str,
2128                      int               byte_order,
2129                      int               depth,
2130                      int               type,
2131                      int               array_type_pos,
2132                      int               pos,
2133                      int              *new_pos,
2134                      int               end)
2135 {
2136   switch (type)
2137     {
2138     case DBUS_TYPE_INVALID:
2139       return FALSE;
2140       break;
2141
2142     case DBUS_TYPE_OBJECT_PATH:
2143     case DBUS_TYPE_STRING:
2144     case DBUS_TYPE_ARRAY:
2145       /* This clean recursion to validate_arg is what we
2146        * are doing logically for all types, but we don't
2147        * really want to call validate_arg for every byte
2148        * in a byte array, so the primitive types are
2149        * special-cased.
2150        */
2151       while (pos < end)
2152         {
2153           if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2154                                            type, array_type_pos, pos, &pos))
2155             return FALSE;
2156         }
2157       break;
2158       
2159     case DBUS_TYPE_BYTE:
2160       pos = end;
2161       break;
2162       
2163     case DBUS_TYPE_BOOLEAN:
2164       while (pos < end)
2165         {
2166           unsigned char c;
2167           
2168           c = _dbus_string_get_byte (str, pos);
2169           
2170           if (!(c == 0 || c == 1))
2171             {
2172               _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2173               return FALSE;
2174             }
2175           
2176           ++pos;
2177         }
2178       break;
2179       
2180     case DBUS_TYPE_INT32:
2181     case DBUS_TYPE_UINT32:
2182       /* Call validate arg one time to check alignment padding
2183        * at start of array
2184        */
2185       if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2186                                        type, array_type_pos, pos, &pos))
2187         return FALSE;
2188       pos = _DBUS_ALIGN_VALUE (end, 4);
2189       break;
2190
2191     case DBUS_TYPE_INT64:
2192     case DBUS_TYPE_UINT64:
2193     case DBUS_TYPE_DOUBLE:
2194       /* Call validate arg one time to check alignment padding
2195        * at start of array
2196        */
2197       if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2198                                        type, array_type_pos, pos, &pos))
2199         return FALSE;
2200       pos = _DBUS_ALIGN_VALUE (end, 8);
2201       break;
2202       
2203     default:
2204       _dbus_verbose ("Unknown message arg type %d\n", type);
2205       return FALSE;
2206     }
2207
2208   *new_pos = pos;
2209
2210   return TRUE;
2211 }
2212
2213 /** 
2214  * Validates an argument of a specific type, checking that it
2215  * is well-formed, for example no ludicrous length fields, strings
2216  * are nul-terminated, etc.
2217  * Returns the end position of the argument in end_pos, and
2218  * returns #TRUE if a valid arg begins at "pos"
2219  *
2220  * @todo security: need to audit this function.
2221  * 
2222  * @param str a string
2223  * @param byte_order the byte order to use
2224  * @param depth current recursion depth, to prevent excessive recursion
2225  * @param type the type of the argument
2226  * @param array_type_pos the position of the current array type, or
2227  *        -1 if not in an array
2228  * @param pos the pos where the arg starts
2229  * @param end_pos pointer where the position right
2230  * after the end position will follow
2231  * @returns #TRUE if the arg is valid.
2232  */
2233 dbus_bool_t
2234 _dbus_marshal_validate_arg (const DBusString *str,
2235                             int               byte_order,
2236                             int               depth,
2237                             int               type,
2238                             int               array_type_pos,
2239                             int               pos,
2240                             int              *end_pos)
2241 {
2242   if (pos > _dbus_string_get_length (str))
2243     {
2244       _dbus_verbose ("Validation went off the end of the message\n");
2245       return FALSE;
2246     }
2247
2248 #define MAX_VALIDATION_DEPTH 32
2249   
2250   if (depth > MAX_VALIDATION_DEPTH)
2251     {
2252       _dbus_verbose ("Maximum recursion depth reached validating message\n");
2253       return FALSE;
2254     }
2255   
2256   switch (type)
2257     {
2258     case DBUS_TYPE_INVALID:
2259       return FALSE;
2260       break;
2261
2262     case DBUS_TYPE_BYTE:
2263       if (1 > _dbus_string_get_length (str) - pos)
2264         {
2265           _dbus_verbose ("no room for byte value\n");
2266           return FALSE;
2267         }
2268         
2269       *end_pos = pos + 1;
2270       break;
2271       
2272     case DBUS_TYPE_BOOLEAN:
2273       {
2274         unsigned char c;
2275
2276         if (1 > _dbus_string_get_length (str) - pos)
2277           {
2278             _dbus_verbose ("no room for boolean value\n");
2279             return FALSE;
2280           }
2281         
2282         c = _dbus_string_get_byte (str, pos);
2283
2284         if (!(c == 0 || c == 1))
2285           {
2286             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2287             return FALSE;
2288           }
2289         
2290         *end_pos = pos + 1;
2291       }
2292       break;
2293       
2294     case DBUS_TYPE_INT32:
2295     case DBUS_TYPE_UINT32:
2296       {
2297         int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
2298         
2299         if (!_dbus_string_validate_nul (str, pos,
2300                                         align_4 - pos))
2301           {
2302             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
2303             return FALSE;
2304           }
2305
2306         *end_pos = align_4 + 4;
2307       }
2308       break;
2309
2310     case DBUS_TYPE_INT64:
2311     case DBUS_TYPE_UINT64:      
2312     case DBUS_TYPE_DOUBLE:
2313       {
2314         int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2315
2316         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2317         
2318         if (!_dbus_string_validate_nul (str, pos,
2319                                         align_8 - pos))
2320           {
2321             _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
2322             return FALSE;
2323           }
2324
2325         *end_pos = align_8 + 8;
2326       }
2327       break;
2328
2329     case DBUS_TYPE_OBJECT_PATH:
2330     case DBUS_TYPE_STRING:
2331       {
2332         int len;
2333
2334         /* Demarshal the length, which does NOT include
2335          * nul termination
2336          */
2337         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2338         if (len < 0)
2339           return FALSE;
2340
2341         if (!validate_string (str, pos, len, end_pos))
2342           return FALSE;
2343
2344         if (type == DBUS_TYPE_OBJECT_PATH)
2345           {
2346             if (!_dbus_string_validate_path (str, pos, len))
2347               return FALSE;
2348           }
2349       }
2350       break;
2351       
2352     case DBUS_TYPE_ARRAY:
2353       {
2354         int len;
2355         int end;
2356         int array_type;
2357
2358         if (array_type_pos == -1)
2359           {
2360             array_type_pos = pos;
2361
2362             do
2363               {
2364                 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2365                   {
2366                     _dbus_verbose ("invalid array type\n");
2367                     return FALSE;
2368                   }
2369               }
2370             while (array_type == DBUS_TYPE_ARRAY);
2371           }
2372         else
2373           array_type_pos++;
2374
2375         if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2376           {
2377             _dbus_verbose ("invalid array type\n");
2378             return FALSE;
2379           }
2380         
2381         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2382         if (len < 0)
2383           {
2384             _dbus_verbose ("invalid array length (<0)\n");
2385             return FALSE;
2386           }
2387
2388         if (len > _dbus_string_get_length (str) - pos)
2389           {
2390             _dbus_verbose ("array length outside length of the message\n");
2391             return FALSE;
2392           }
2393         
2394         end = pos + len;
2395
2396         if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
2397                                              array_type, array_type_pos,
2398                                              pos, &pos, end))
2399           {
2400             _dbus_verbose ("invalid array data\n");
2401             return FALSE;
2402           }
2403
2404         if (pos < end)
2405           {
2406             /* This should not be able to happen, as long as validate_arg moves forward;
2407              * but the check is here just to be paranoid.
2408              */
2409             _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2410                            len, end - pos);
2411             return FALSE;
2412           }
2413         
2414         if (pos > end)
2415           {
2416             _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2417             return FALSE;
2418           }
2419
2420         *end_pos = pos;
2421       }
2422       break;
2423       
2424     default:
2425       _dbus_verbose ("Unknown message arg type %d\n", type);
2426       return FALSE;
2427     }
2428
2429   if (*end_pos > _dbus_string_get_length (str))
2430     return FALSE;
2431   
2432   return TRUE;
2433 }
2434
2435 /**
2436  * Return #TRUE if the typecode is a valid typecode
2437  *
2438  * @returns #TRUE if valid
2439  */
2440 dbus_bool_t
2441 _dbus_type_is_valid (int typecode)
2442 {
2443   switch (typecode)
2444     {
2445     case DBUS_TYPE_BYTE:
2446     case DBUS_TYPE_BOOLEAN:
2447     case DBUS_TYPE_INT32:
2448     case DBUS_TYPE_UINT32:
2449     case DBUS_TYPE_INT64:
2450     case DBUS_TYPE_UINT64:
2451     case DBUS_TYPE_DOUBLE:
2452     case DBUS_TYPE_STRING:
2453     case DBUS_TYPE_OBJECT_PATH:
2454     case DBUS_TYPE_ARRAY:
2455     case DBUS_TYPE_STRUCT:
2456     case DBUS_TYPE_VARIANT:
2457       return TRUE;
2458       
2459     default:
2460       return FALSE;
2461     }
2462 }
2463
2464 /**
2465  * Gets the alignment requirement for the given type;
2466  * will be 1, 4, or 8.
2467  *
2468  * @param typecode the type
2469  * @returns alignment of 1, 4, or 8
2470  */
2471 int
2472 _dbus_type_get_alignment (int typecode)
2473 {
2474   switch (typecode)
2475     {
2476     case DBUS_TYPE_BYTE:
2477     case DBUS_TYPE_BOOLEAN:
2478     case DBUS_TYPE_VARIANT:
2479     case DBUS_TYPE_SIGNATURE:
2480       return 1;
2481     case DBUS_TYPE_INT32:
2482     case DBUS_TYPE_UINT32:
2483       /* this stuff is 4 since it starts with a length */
2484     case DBUS_TYPE_STRING:
2485     case DBUS_TYPE_OBJECT_PATH:
2486     case DBUS_TYPE_ARRAY:
2487       return 4;
2488     case DBUS_TYPE_INT64:
2489     case DBUS_TYPE_UINT64:
2490     case DBUS_TYPE_DOUBLE:
2491       /* struct is 8 since it could contain an 8-aligned item
2492        * and it's simpler to just always align structs to 8;
2493        * we want the amount of padding in a struct of a given
2494        * type to be predictable, not location-dependent.
2495        */
2496     case DBUS_TYPE_STRUCT:
2497       return 8;
2498       
2499     default:
2500       _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
2501       return 0;
2502     }
2503 }
2504
2505 /**
2506  * If in verbose mode, print a block of binary data.
2507  *
2508  * @todo right now it prints even if not in verbose mode
2509  * 
2510  * @param data the data
2511  * @param len the length of the data
2512  * @param offset where to start counting for byte indexes
2513  */
2514 void
2515 _dbus_verbose_bytes (const unsigned char *data,
2516                      int                  len,
2517                      int                  offset)
2518 {
2519   int i;
2520   const unsigned char *aligned;
2521
2522   _dbus_assert (len >= 0);
2523   
2524   /* Print blanks on first row if appropriate */
2525   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2526   if (aligned > data)
2527     aligned -= 4;
2528   _dbus_assert (aligned <= data);
2529
2530   if (aligned != data)
2531     {
2532       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
2533       while (aligned != data)
2534         {
2535           _dbus_verbose ("    ");
2536           ++aligned;
2537         }
2538     }
2539
2540   /* now print the bytes */
2541   i = 0;
2542   while (i < len)
2543     {
2544       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2545         {
2546           _dbus_verbose ("%4d\t%p: ",
2547                          offset + i, &data[i]);
2548         }
2549       
2550       if (data[i] >= 32 &&
2551           data[i] <= 126)
2552         _dbus_verbose (" '%c' ", data[i]);
2553       else
2554         _dbus_verbose ("0x%s%x ",
2555                        data[i] <= 0xf ? "0" : "", data[i]);
2556
2557       ++i;
2558
2559       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2560         {
2561           if (i > 3)
2562             _dbus_verbose ("BE: %d LE: %d",
2563                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2564                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2565
2566           if (i > 7 && 
2567               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2568             {
2569               _dbus_verbose (" dbl: %g",
2570                              *(double*)&data[i-8]);
2571             }
2572           
2573           _dbus_verbose ("\n");
2574         }
2575     }
2576
2577   _dbus_verbose ("\n");
2578 }
2579
2580 /**
2581  * Dump the given part of the string to verbose log.
2582  *
2583  * @param str the string
2584  * @param start the start of range to dump
2585  * @param len length of range
2586  */
2587 void
2588 _dbus_verbose_bytes_of_string (const DBusString    *str,
2589                                int                  start,
2590                                int                  len)
2591 {
2592   const char *d;
2593   int real_len;
2594
2595   real_len = _dbus_string_get_length (str);
2596
2597   _dbus_assert (start >= 0);
2598   
2599   if (start > real_len)
2600     {
2601       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
2602                      start, len, real_len);
2603       return;
2604     }
2605
2606   if ((start + len) > real_len)
2607     {
2608       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
2609                      start, len, real_len);
2610       len = real_len - start;
2611     }
2612   
2613   d = _dbus_string_get_const_data_len (str, start, len);
2614
2615   _dbus_verbose_bytes (d, len, start);
2616 }
2617
2618 /**
2619  * Marshals a basic type
2620  *
2621  * @param str string to marshal to
2622  * @param insert_at where to insert the value
2623  * @param type type of value
2624  * @param value pointer to value
2625  * @param byte_order byte order
2626  * @returns #TRUE on success
2627  **/
2628 dbus_bool_t
2629 _dbus_marshal_basic_type (DBusString *str,
2630                           int         insert_at,
2631                           char        type,
2632                           const void *value,
2633                           int         byte_order)
2634 {
2635   dbus_bool_t retval;
2636
2637   switch (type)
2638     {
2639     case DBUS_TYPE_BYTE:
2640     case DBUS_TYPE_BOOLEAN:
2641       retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
2642       break;
2643     case DBUS_TYPE_INT32:
2644     case DBUS_TYPE_UINT32:
2645       return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
2646       break;
2647 #ifdef DBUS_HAVE_INT64
2648     case DBUS_TYPE_INT64:
2649     case DBUS_TYPE_UINT64:
2650       {
2651         DBusOctets8 r;
2652         r.u = *(const dbus_uint64_t *)value;
2653         retval = marshal_8_octets (str, insert_at, byte_order, r);
2654       }
2655       break;
2656 #endif /* DBUS_HAVE_INT64 */
2657     case DBUS_TYPE_DOUBLE:
2658       {
2659         DBusOctets8 r;
2660         r.d = *(const double *)value;
2661         retval = marshal_8_octets (str, insert_at, byte_order, r);
2662       }
2663       break;
2664     case DBUS_TYPE_STRING:
2665     case DBUS_TYPE_OBJECT_PATH:
2666       retval = _dbus_marshal_string (str, byte_order, (const char*) value);
2667       break;
2668     case DBUS_TYPE_SIGNATURE:
2669       retval = _dbus_marshal_signature (str, (const char*) value);
2670       break;
2671     default:
2672       _dbus_assert_not_reached ("not a basic type");
2673       retval = FALSE;
2674       break;
2675     }
2676   return retval;
2677 }
2678
2679 /**
2680  * Marshals a basic type array
2681  *
2682  * @param str string to marshal to
2683  * @param insert_at where to insert the value
2684  * @param element_type type of array elements
2685  * @param value pointer to value
2686  * @param len length of value data in elements
2687  * @param byte_order byte order
2688  * @returns #TRUE on success
2689  **/
2690 dbus_bool_t
2691 _dbus_marshal_basic_type_array (DBusString *str,
2692                                 int         insert_at,
2693                                 char        element_type,
2694                                 const void *value,
2695                                 int         len,
2696                                 int         byte_order)
2697 {
2698   /* FIXME use the insert_at arg */
2699   
2700   switch (element_type)
2701     {
2702     case DBUS_TYPE_BOOLEAN:
2703       /* FIXME: we canonicalize to 0 or 1 for the single boolean case 
2704        * should we here too ? */
2705     case DBUS_TYPE_BYTE:
2706       return _dbus_marshal_byte_array (str, byte_order, value, len);
2707       break;
2708     case DBUS_TYPE_INT32:
2709     case DBUS_TYPE_UINT32:
2710       return marshal_4_octets_array (str, byte_order, value, len);
2711       break;
2712 #ifdef DBUS_HAVE_INT64
2713     case DBUS_TYPE_INT64:
2714     case DBUS_TYPE_UINT64: 
2715 #endif /* DBUS_HAVE_INT64 */
2716     case DBUS_TYPE_DOUBLE:
2717       return marshal_8_octets_array (str, byte_order, value, len);
2718       break;
2719     default:
2720       _dbus_assert_not_reached ("non basic type in array");
2721       break;
2722     }
2723   return FALSE;
2724 }
2725
2726 /** @} */
2727
2728 #ifdef DBUS_BUILD_TESTS
2729 #include "dbus-test.h"
2730 #include <stdio.h>
2731
2732 dbus_bool_t
2733 _dbus_marshal_test (void)
2734 {
2735   DBusString str;
2736   char *tmp1, *tmp2;
2737   int pos = 0, len;
2738   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2739 #ifdef DBUS_HAVE_INT64
2740   dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 
2741                              DBUS_INT64_CONSTANT (0x456ffffffff), 
2742                              DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
2743 #endif
2744   char *s;
2745   DBusString t;
2746   
2747   if (!_dbus_string_init (&str))
2748     _dbus_assert_not_reached ("failed to init string");
2749
2750   /* Marshal doubles */
2751   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2752     _dbus_assert_not_reached ("could not marshal double value");
2753   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2754     _dbus_assert_not_reached ("demarshal failed");
2755
2756   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2757     _dbus_assert_not_reached ("could not marshal double value");
2758   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2759     _dbus_assert_not_reached ("demarshal failed");
2760   
2761   /* Marshal signed integers */
2762   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2763     _dbus_assert_not_reached ("could not marshal signed integer value");
2764   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2765     _dbus_assert_not_reached ("demarshal failed");
2766
2767   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2768     _dbus_assert_not_reached ("could not marshal signed integer value");
2769   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2770     _dbus_assert_not_reached ("demarshal failed");
2771   
2772   /* Marshal unsigned integers */
2773   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2774     _dbus_assert_not_reached ("could not marshal signed integer value");
2775   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2776     _dbus_assert_not_reached ("demarshal failed");
2777   
2778   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2779     _dbus_assert_not_reached ("could not marshal signed integer value");
2780   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2781     _dbus_assert_not_reached ("demarshal failed");
2782
2783 #ifdef DBUS_HAVE_INT64
2784   /* Marshal signed integers */
2785   if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2786     _dbus_assert_not_reached ("could not marshal signed integer value");
2787   if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2788     _dbus_assert_not_reached ("demarshal failed");
2789
2790   if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2791     _dbus_assert_not_reached ("could not marshal signed integer value");
2792   if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2793     _dbus_assert_not_reached ("demarshal failed");
2794   
2795   /* Marshal unsigned integers */
2796   if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2797     _dbus_assert_not_reached ("could not marshal signed integer value");
2798   if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2799     _dbus_assert_not_reached ("demarshal failed");
2800   
2801   if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2802     _dbus_assert_not_reached ("could not marshal signed integer value");
2803   if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2804     _dbus_assert_not_reached ("demarshal failed");
2805 #endif /* DBUS_HAVE_INT64 */
2806   
2807   /* Marshal strings */
2808   tmp1 = "This is the dbus test string";
2809   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2810     _dbus_assert_not_reached ("could not marshal string");
2811   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2812   if (!strcmp (tmp1, tmp2) == 0)
2813     _dbus_assert_not_reached ("demarshal failed");
2814   dbus_free (tmp2);
2815
2816   tmp1 = "This is the dbus test string";
2817   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2818     _dbus_assert_not_reached ("could not marshal string");
2819   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2820   if (!strcmp (tmp1, tmp2) == 0)
2821     _dbus_assert_not_reached ("demarshal failed");
2822   dbus_free (tmp2);
2823
2824   /* Marshal signed integer arrays */
2825   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2826     _dbus_assert_not_reached ("could not marshal integer array");
2827   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2828     _dbus_assert_not_reached ("could not demarshal integer array");
2829
2830   if (len != 3)
2831     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2832   dbus_free (array2);
2833
2834 #ifdef DBUS_HAVE_INT64
2835   /* Marshal 64-bit signed integer arrays */
2836   if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2837     _dbus_assert_not_reached ("could not marshal integer array");
2838   if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2839     _dbus_assert_not_reached ("could not demarshal integer array");
2840
2841   if (len != 3)
2842     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2843   dbus_free (array4);
2844
2845   /* set/pack 64-bit integers */
2846   _dbus_string_set_length (&str, 8);
2847
2848   /* signed little */
2849   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2850                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2851   
2852   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2853                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2854                                     _dbus_string_get_const_data (&str)));
2855
2856   /* signed big */
2857   _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2858                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2859
2860   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2861                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2862                                     _dbus_string_get_const_data (&str)));
2863
2864   /* signed little pack */
2865   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2866                     DBUS_LITTLE_ENDIAN,
2867                     _dbus_string_get_data (&str));
2868   
2869   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2870                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2871                                     _dbus_string_get_const_data (&str)));
2872
2873   /* signed big pack */
2874   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2875                     DBUS_BIG_ENDIAN,
2876                     _dbus_string_get_data (&str));
2877
2878   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2879                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2880                                     _dbus_string_get_const_data (&str)));
2881
2882   /* unsigned little */
2883   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2884                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2885   
2886   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2887                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2888                                      _dbus_string_get_const_data (&str)));
2889
2890   /* unsigned big */
2891   _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2892                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2893
2894   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2895                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2896                                      _dbus_string_get_const_data (&str)));
2897
2898   /* unsigned little pack */
2899   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2900                      DBUS_LITTLE_ENDIAN,
2901                      _dbus_string_get_data (&str));
2902   
2903   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2904                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2905                                      _dbus_string_get_const_data (&str)));
2906
2907   /* unsigned big pack */
2908   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2909                      DBUS_BIG_ENDIAN,
2910                      _dbus_string_get_data (&str));
2911
2912   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2913                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2914                                      _dbus_string_get_const_data (&str)));
2915   
2916 #endif
2917
2918   /* set/pack 32-bit integers */
2919   _dbus_string_set_length (&str, 4);
2920
2921   /* signed little */
2922   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2923                            0, -0x123456);
2924   
2925   _dbus_assert (-0x123456 ==
2926                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2927                                     _dbus_string_get_const_data (&str)));
2928
2929   /* signed big */
2930   _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2931                            0, -0x123456);
2932
2933   _dbus_assert (-0x123456 ==
2934                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2935                                     _dbus_string_get_const_data (&str)));
2936
2937   /* signed little pack */
2938   _dbus_pack_int32 (-0x123456,
2939                     DBUS_LITTLE_ENDIAN,
2940                     _dbus_string_get_data (&str));
2941   
2942   _dbus_assert (-0x123456 ==
2943                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2944                                     _dbus_string_get_const_data (&str)));
2945
2946   /* signed big pack */
2947   _dbus_pack_int32 (-0x123456,
2948                     DBUS_BIG_ENDIAN,
2949                     _dbus_string_get_data (&str));
2950
2951   _dbus_assert (-0x123456 ==
2952                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2953                                     _dbus_string_get_const_data (&str)));
2954
2955   /* unsigned little */
2956   _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2957                             0, 0x123456);
2958   
2959   _dbus_assert (0x123456 ==
2960                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2961                                      _dbus_string_get_const_data (&str)));
2962
2963   /* unsigned big */
2964   _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2965                             0, 0x123456);
2966
2967   _dbus_assert (0x123456 ==
2968                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2969                                      _dbus_string_get_const_data (&str)));
2970
2971   /* unsigned little pack */
2972   _dbus_pack_uint32 (0x123456,
2973                      DBUS_LITTLE_ENDIAN,
2974                      _dbus_string_get_data (&str));
2975   
2976   _dbus_assert (0x123456 ==
2977                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2978                                      _dbus_string_get_const_data (&str)));
2979
2980   /* unsigned big pack */
2981   _dbus_pack_uint32 (0x123456,
2982                      DBUS_BIG_ENDIAN,
2983                      _dbus_string_get_data (&str));
2984
2985   _dbus_assert (0x123456 ==
2986                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2987                                      _dbus_string_get_const_data (&str)));
2988
2989
2990   /* Strings */
2991   
2992   _dbus_string_set_length (&str, 0);
2993
2994   _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2995                         "Hello world");
2996   
2997   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2998   _dbus_assert (strcmp (s, "Hello world") == 0);
2999   dbus_free (s);
3000
3001   _dbus_string_init_const (&t, "Hello world foo");
3002   
3003   _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
3004                             &t, _dbus_string_get_length (&t));
3005   
3006   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
3007   _dbus_assert (strcmp (s, "Hello world foo") == 0);
3008   dbus_free (s);
3009
3010   _dbus_string_init_const (&t, "Hello");
3011   
3012   _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
3013                             &t, _dbus_string_get_length (&t));
3014   
3015   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
3016   _dbus_assert (strcmp (s, "Hello") == 0);
3017   dbus_free (s);
3018
3019   /* Strings (big endian) */
3020   
3021   _dbus_string_set_length (&str, 0);
3022
3023   _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
3024                         "Hello world");
3025   
3026   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
3027   _dbus_assert (strcmp (s, "Hello world") == 0);
3028   dbus_free (s);
3029
3030   _dbus_string_init_const (&t, "Hello world foo");
3031   
3032   _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
3033                             &t, _dbus_string_get_length (&t));
3034   
3035   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
3036   _dbus_assert (strcmp (s, "Hello world foo") == 0);
3037   dbus_free (s);
3038
3039   _dbus_string_init_const (&t, "Hello");
3040   
3041   _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
3042                             &t, _dbus_string_get_length (&t));
3043   
3044   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
3045   _dbus_assert (strcmp (s, "Hello") == 0);
3046   dbus_free (s);
3047   
3048   _dbus_string_free (&str);
3049       
3050   return TRUE;
3051 }
3052
3053 #endif /* DBUS_BUILD_TESTS */