2003-04-10 Alexander Larsson <alexl@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-marshal.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c  Marshalling routines
3  *
4  * Copyright (C) 2002 CodeFactory AB
5  * Copyright (C) 2003 Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 1.2
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-marshal.h"
26 #include "dbus-internals.h"
27 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
28 #include "dbus-string-private.h"
29
30 #include <string.h>
31
32 /* from ORBit */
33 static void
34 swap_bytes (unsigned char *data,
35             unsigned int   len)
36 {
37   unsigned char *p1 = data;
38   unsigned char *p2 = data + len - 1;
39
40   while (p1 < p2)
41     {
42       unsigned char tmp = *p1;
43       *p1 = *p2;
44       *p2 = tmp;
45
46       --p2;
47       ++p1;
48     }
49 }
50
51 /**
52  * @defgroup DBusMarshal marshaling and unmarshaling
53  * @ingroup  DBusInternals
54  * @brief functions to marshal/unmarshal data from the wire
55  *
56  * Types and functions related to converting primitive data types from
57  * wire format to native machine format, and vice versa.
58  *
59  * @{
60  */
61
62 /**
63  * Unpacks a 32 bit unsigned integer from a data pointer
64  *
65  * @param byte_order The byte order to use
66  * @param data the data pointer
67  * @returns the integer
68  */
69 dbus_uint32_t
70 _dbus_unpack_uint32 (int                  byte_order,
71                      const unsigned char *data)
72 {
73   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
74   
75   if (byte_order == DBUS_LITTLE_ENDIAN)
76     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
77   else
78     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
79 }  
80
81 /**
82  * Unpacks a 32 bit signed integer from a data pointer
83  *
84  * @param byte_order The byte order to use
85  * @param data the data pointer
86  * @returns the integer
87  */
88 dbus_int32_t
89 _dbus_unpack_int32 (int                  byte_order,
90                     const unsigned char *data)
91 {
92   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
93   
94   if (byte_order == DBUS_LITTLE_ENDIAN)
95     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
96   else
97     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
98 }
99
100 /**
101  * Packs a 32 bit unsigned integer into a data pointer.
102  *
103  * @param value the value
104  * @param byte_order the byte order to use
105  * @param data the data pointer
106  */
107 void
108 _dbus_pack_uint32 (dbus_uint32_t   value,
109                    int             byte_order,
110                    unsigned char  *data)
111 {
112   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
113   
114   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
115     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
116   else
117     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
118 }
119
120 /**
121  * Packs a 32 bit signed integer into a data pointer.
122  *
123  * @param value the value
124  * @param byte_order the byte order to use
125  * @param data the data pointer
126  */
127 void
128 _dbus_pack_int32 (dbus_int32_t   value,
129                   int            byte_order,
130                   unsigned char *data)
131 {
132   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
133   
134   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
135     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);       
136   else
137     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
138 }
139
140 /**
141  * Sets the 4 bytes at the given offset to a marshaled signed integer,
142  * replacing anything found there previously.
143  *
144  * @param str the string to write the marshalled int to
145  * @param offset the byte offset where int should be written
146  * @param byte_order the byte order to use
147  * @param value the value
148  * 
149  */
150 void
151 _dbus_marshal_set_int32 (DBusString          *str,
152                          int                  byte_order,
153                          int                  offset,
154                          dbus_int32_t         value)
155 {
156   char *data;
157   
158   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
159                 byte_order == DBUS_BIG_ENDIAN);
160   
161   data = _dbus_string_get_data_len (str, offset, 4);
162
163   _dbus_pack_int32 (value, byte_order, data);
164 }
165
166 /**
167  * Sets the 4 bytes at the given offset to a marshaled unsigned
168  * integer, replacing anything found there previously.
169  *
170  * @param str the string to write the marshalled int to
171  * @param offset the byte offset where int should be written
172  * @param byte_order the byte order to use
173  * @param value the value
174  * 
175  */
176 void
177 _dbus_marshal_set_uint32 (DBusString          *str,
178                           int                  byte_order,
179                           int                  offset,
180                           dbus_uint32_t        value)
181 {
182   char *data;
183   
184   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
185                 byte_order == DBUS_BIG_ENDIAN);
186   
187   data = _dbus_string_get_data_len (str, offset, 4);
188
189   _dbus_pack_uint32 (value, byte_order, data);
190 }
191
192 /**
193  * Sets the existing marshaled string at the given offset with
194  * a new marshaled string. The given offset must point to
195  * an existing string or the wrong length will be deleted
196  * and replaced with the new string.
197  *
198  * @param str the string to write the marshalled string to
199  * @param offset the byte offset where string should be written
200  * @param byte_order the byte order to use
201  * @param value the value
202  * @param len the length to use
203  * @returns #TRUE on success
204  * 
205  */
206 dbus_bool_t
207 _dbus_marshal_set_string (DBusString          *str,
208                           int                  byte_order,
209                           int                  offset,
210                           const DBusString    *value,
211                           int                  len)
212 {
213   int old_len;
214   
215   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
216                 byte_order == DBUS_BIG_ENDIAN);
217   
218   old_len = _dbus_demarshal_uint32 (str, byte_order,
219                                     offset, NULL);
220
221   if (!_dbus_string_replace_len (value, 0, len,
222                                  str, offset + 4, old_len))
223     return FALSE;
224
225   _dbus_marshal_set_uint32 (str, byte_order,
226                             offset, len);
227
228   return TRUE;
229 }
230
231 /**
232  * Marshals a double value.
233  *
234  * @param str the string to append the marshalled value to
235  * @param byte_order the byte order to use
236  * @param value the value
237  * @returns #TRUE on success
238  */
239 dbus_bool_t
240 _dbus_marshal_double (DBusString *str,
241                       int         byte_order,
242                       double      value)
243 {
244   _dbus_assert (sizeof (double) == 8);
245
246   if (!_dbus_string_align_length (str, sizeof (double)))
247     return FALSE;
248   
249   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
250     swap_bytes ((unsigned char *)&value, sizeof (double));
251
252   return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
253 }
254
255 /**
256  * Marshals a 32 bit signed integer value.
257  *
258  * @param str the string to append the marshalled value to
259  * @param byte_order the byte order to use
260  * @param value the value
261  * @returns #TRUE on success
262  */
263 dbus_bool_t
264 _dbus_marshal_int32  (DBusString   *str,
265                       int           byte_order,
266                       dbus_int32_t  value)
267 {
268   if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
269     return FALSE;
270   
271   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
272     value = DBUS_INT32_SWAP_LE_BE (value);
273
274   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
275 }
276
277 /**
278  * Marshals a 32 bit unsigned integer value.
279  *
280  * @param str the string to append the marshalled value to
281  * @param byte_order the byte order to use
282  * @param value the value
283  * @returns #TRUE on success
284  */
285 dbus_bool_t
286 _dbus_marshal_uint32 (DBusString    *str,
287                       int            byte_order,
288                       dbus_uint32_t  value)
289 {
290   if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
291     return FALSE;
292   
293   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
294     value = DBUS_UINT32_SWAP_LE_BE (value);
295
296   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
297 }
298
299 /**
300  * Marshals a UTF-8 string
301  *
302  * @todo: If the string append fails we need to restore
303  * the old length. (also for other marshallers)
304  * 
305  * @param str the string to append the marshalled value to
306  * @param byte_order the byte order to use
307  * @param value the string
308  * @returns #TRUE on success
309  */
310 dbus_bool_t
311 _dbus_marshal_string (DBusString    *str,
312                       int            byte_order,
313                       const char    *value)
314 {
315   int len, old_string_len;
316
317   old_string_len = _dbus_string_get_length (str);
318   
319   len = strlen (value);
320
321   if (!_dbus_marshal_uint32 (str, byte_order, len))
322     {
323       /* Restore the previous length */
324       _dbus_string_set_length (str, old_string_len);
325
326       return FALSE;
327     }
328
329   return _dbus_string_append_len (str, value, len + 1);
330 }
331
332 /**
333  * Marshals a byte array
334  *
335  * @param str the string to append the marshalled value to
336  * @param byte_order the byte order to use
337  * @param value the array
338  * @param len number of elements in the array
339  * @returns #TRUE on success
340  */
341 dbus_bool_t
342 _dbus_marshal_byte_array (DBusString          *str,
343                           int                  byte_order,
344                           const unsigned char *value,
345                           int                  len)
346 {
347   int old_string_len;
348
349   old_string_len = _dbus_string_get_length (str);
350   
351   if (!_dbus_marshal_uint32 (str, byte_order, len))
352     {
353       /* Restore the previous length */
354       _dbus_string_set_length (str, old_string_len);
355
356       return FALSE;
357     }
358
359   if (len == 0)
360     return TRUE;
361   else
362     return _dbus_string_append_len (str, value, len);
363 }
364
365 /**
366  * Marshals a 32 bit signed integer array
367  *
368  * @param str the string to append the marshalled value to
369  * @param byte_order the byte order to use
370  * @param value the array
371  * @param len the length of the array
372  * @returns #TRUE on success
373  */
374 dbus_bool_t
375 _dbus_marshal_int32_array (DBusString         *str,
376                            int                 byte_order,
377                            const dbus_int32_t *value,
378                            int                 len)
379 {
380   int i, old_string_len;
381
382   old_string_len = _dbus_string_get_length (str);
383
384   if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_int32_t)))
385     goto error;
386
387   for (i = 0; i < len; i++)
388     if (!_dbus_marshal_int32 (str, byte_order, value[i]))
389       goto error;
390
391   return TRUE;
392   
393  error:
394   /* Restore previous length */
395   _dbus_string_set_length (str, old_string_len);
396   
397   return FALSE;
398 }
399
400 /**
401  * Marshals a 32 bit unsigned integer array
402  *
403  * @param str the string to append the marshalled value to
404  * @param byte_order the byte order to use
405  * @param value the array
406  * @param len the length of the array
407  * @returns #TRUE on success
408  */
409 dbus_bool_t
410 _dbus_marshal_uint32_array (DBusString          *str,
411                             int                  byte_order,
412                             const dbus_uint32_t  *value,
413                             int                  len)
414 {
415   int i, old_string_len;
416
417   old_string_len = _dbus_string_get_length (str);
418
419   if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_uint32_t)))
420     goto error;
421
422   for (i = 0; i < len; i++)
423     if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
424       goto error;
425
426   return TRUE;
427   
428  error:
429   /* Restore previous length */
430   _dbus_string_set_length (str, old_string_len);
431   
432   return FALSE;  
433 }
434
435 /**
436  * Marshals a double array
437  *
438  * @param str the string to append the marshalled value to
439  * @param byte_order the byte order to use
440  * @param value the array
441  * @param len the length of the array
442  * @returns #TRUE on success
443  */
444 dbus_bool_t
445 _dbus_marshal_double_array (DBusString          *str,
446                             int                  byte_order,
447                             const double        *value,
448                             int                  len)
449 {
450   int i, old_string_len, array_start;
451
452   old_string_len = _dbus_string_get_length (str);
453
454   /* Set the length to 0 temporarily */
455   if (!_dbus_marshal_uint32 (str, byte_order, 0))
456     goto error;
457       
458   array_start = _dbus_string_get_length (str);
459       
460   for (i = 0; i < len; i++)
461     if (!_dbus_marshal_double (str, byte_order, value[i]))
462       goto error;
463
464   /* Write the length now that we know it */
465   _dbus_marshal_set_uint32 (str, byte_order,
466                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
467                             _dbus_string_get_length (str) - array_start);
468   
469   return TRUE;
470   
471  error:
472   /* Restore previous length */
473   _dbus_string_set_length (str, old_string_len);
474   
475   return FALSE;    
476 }
477
478 /**
479  * Marshals a string array
480  *
481  * @param str the string to append the marshalled value to
482  * @param byte_order the byte order to use
483  * @param value the array
484  * @param len the length of the array
485  * @returns #TRUE on success
486  */
487 dbus_bool_t
488 _dbus_marshal_string_array (DBusString  *str,
489                             int          byte_order,
490                             const char **value,
491                             int          len)
492 {
493   int i, old_string_len, array_start;
494
495   old_string_len = _dbus_string_get_length (str);
496
497   /* Set the length to 0 temporarily */
498   if (!_dbus_marshal_uint32 (str, byte_order, 0))
499     goto error;
500
501   array_start = _dbus_string_get_length (str);
502   
503   for (i = 0; i < len; i++)
504     if (!_dbus_marshal_string (str, byte_order, value[i]))
505       goto error;
506
507   /* Write the length now that we know it */
508   _dbus_marshal_set_uint32 (str, byte_order,
509                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
510                             _dbus_string_get_length (str) - array_start);
511   
512   return TRUE;
513   
514  error:
515   /* Restore previous length */
516   _dbus_string_set_length (str, old_string_len);
517   
518   return FALSE;      
519 }
520
521
522 /**
523  * Demarshals a double.
524  *
525  * @param str the string containing the data
526  * @param byte_order the byte order
527  * @param pos the position in the string
528  * @param new_pos the new position of the string
529  * @returns the demarshaled double.
530  */
531 double
532 _dbus_demarshal_double (const DBusString  *str,
533                         int          byte_order,
534                         int          pos,
535                         int         *new_pos)
536 {
537   double retval;
538   const char *buffer;
539
540   pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
541
542   buffer = _dbus_string_get_const_data_len (str, pos, sizeof (double));
543
544   retval = *(double *)buffer;
545   
546   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
547     swap_bytes ((unsigned char *)&retval, sizeof (double));
548
549   if (new_pos)
550     *new_pos = pos + sizeof (double);
551   
552   return retval;  
553 }
554
555 /**
556  * Demarshals a 32 bit signed integer.
557  *
558  * @param str the string containing the data
559  * @param byte_order the byte order
560  * @param pos the position in the string
561  * @param new_pos the new position of the string
562  * @returns the demarshaled integer.
563  */
564 dbus_int32_t
565 _dbus_demarshal_int32  (const DBusString *str,
566                         int               byte_order,
567                         int               pos,
568                         int              *new_pos)
569 {
570   const DBusRealString *real = (const DBusRealString*) str;
571   
572   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
573   
574   if (new_pos)
575     *new_pos = pos + sizeof (dbus_int32_t);
576
577   if (byte_order == DBUS_LITTLE_ENDIAN)
578     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
579   else
580     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
581 }
582
583 /**
584  * Demarshals a 32 bit unsigned integer.
585  *
586  * @param str the string containing the data
587  * @param byte_order the byte order
588  * @param pos the position in the string
589  * @param new_pos the new position of the string
590  * @returns the demarshaled integer.
591  */
592 dbus_uint32_t
593 _dbus_demarshal_uint32  (const DBusString *str,
594                          int         byte_order,
595                          int         pos,
596                          int        *new_pos)
597 {
598   const DBusRealString *real = (const DBusRealString*) str;
599   
600   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
601   
602   if (new_pos)
603     *new_pos = pos + sizeof (dbus_uint32_t);
604
605   if (byte_order == DBUS_LITTLE_ENDIAN)
606     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
607   else
608     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
609 }
610
611 /**
612  * Demarshals an UTF-8 string.
613  *
614  * @todo Should we check the string to make sure
615  * that it's  valid UTF-8, and maybe "fix" the string
616  * if it's broken?
617  *
618  * @todo Should probably demarshal to a DBusString,
619  * having memcpy() in here is Evil(tm).
620  *
621  * @param str the string containing the data
622  * @param byte_order the byte order
623  * @param pos the position in the string
624  * @param new_pos the new position of the string
625  * @returns the demarshaled string.
626  */
627 char *
628 _dbus_demarshal_string (const DBusString *str,
629                         int         byte_order,
630                         int         pos,
631                         int        *new_pos)
632 {
633   int len;
634   char *retval;
635   const char *data;
636   
637   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
638
639   retval = dbus_malloc (len + 1);
640
641   if (!retval)
642     return NULL;
643
644   data = _dbus_string_get_const_data_len (str, pos, len + 1);
645
646   if (!data)
647     return NULL;
648
649   memcpy (retval, data, len + 1);
650
651   if (new_pos)
652     *new_pos = pos + len + 1;
653   
654   return retval;
655 }
656
657 /**
658  * Demarshals a byte array.
659  *
660  * @todo Should probably demarshal to a DBusString,
661  * having memcpy() in here is Evil(tm).
662  *
663  * @param str the string containing the data
664  * @param byte_order the byte order
665  * @param pos the position in the string
666  * @param new_pos the new position of the string
667  * @param array the array
668  * @param array_len length of the demarshaled data
669  
670  * @returns #TRUE on success
671  */
672 dbus_bool_t
673 _dbus_demarshal_byte_array (const DBusString  *str,
674                             int                byte_order,
675                             int                pos,
676                             int               *new_pos,
677                             unsigned char    **array,
678                             int               *array_len)
679 {
680   int len;
681   unsigned char *retval;
682   const char *data;
683
684   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
685
686   if (len == 0)
687     {
688       *array_len = len;
689       *array = NULL;
690
691       if (new_pos)
692         *new_pos = pos;
693       
694       return TRUE;
695     }
696   
697   retval = dbus_malloc (len);
698
699   if (!retval)
700     return FALSE;
701
702   data = _dbus_string_get_const_data_len (str, pos, len);
703
704   if (!data)
705     {
706       dbus_free (retval);
707       return FALSE;
708     }
709
710   memcpy (retval, data, len);
711
712   if (new_pos)
713     *new_pos = pos + len;
714
715   *array = retval;
716   *array_len = len;
717   
718   return TRUE;
719 }
720
721 /**
722  * Demarshals a 32 bit signed integer array.
723  *
724  * @param str the string containing the data
725  * @param byte_order the byte order
726  * @param pos the position in the string
727  * @param new_pos the new position of the string
728  * @param array the array
729  * @param array_len length of the demarshaled data
730  * @returns #TRUE on success
731  */
732 dbus_bool_t
733 _dbus_demarshal_int32_array (const DBusString  *str,
734                              int                byte_order,
735                              int                pos,
736                              int               *new_pos,
737                              dbus_int32_t     **array,
738                              int               *array_len)
739 {
740   int len, i;
741   dbus_int32_t *retval;
742   
743   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos)  / sizeof (dbus_int32_t);
744
745   if (len == 0)
746     {
747       *array_len = 0;
748       *array = NULL;
749
750       if (new_pos)
751         *new_pos = pos;
752       
753       return TRUE;
754     }
755   
756   retval = dbus_new (dbus_int32_t, len);
757   
758   if (!retval)
759     return FALSE;
760
761   for (i = 0; i < len; i++)
762     retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
763
764   if (new_pos)
765     *new_pos = pos;
766
767   *array_len = len;
768   *array = retval;
769   
770   return TRUE;
771 }
772
773 /**
774  * Demarshals a 32 bit unsigned integer array.
775  *
776  * @param str the string containing the data
777  * @param byte_order the byte order
778  * @param pos the position in the string
779  * @param new_pos the new position of the string
780  * @param array the array
781  * @param array_len length of the demarshaled data
782  * @returns #TRUE on success
783  */
784 dbus_bool_t
785 _dbus_demarshal_uint32_array (const DBusString  *str,
786                               int                byte_order,
787                               int                pos,
788                               int               *new_pos,
789                               dbus_uint32_t    **array,
790                               int               *array_len)
791 {
792   int len, i;
793   dbus_uint32_t *retval;
794   
795   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_uint32_t);
796
797   if (len == 0)
798     {
799       *array_len = 0;
800       *array = NULL;
801
802       if (new_pos)
803         *new_pos = pos;
804       
805       return TRUE;
806     }
807   
808   retval = dbus_new (dbus_uint32_t, len);
809
810   if (!retval)
811     return FALSE;
812
813   for (i = 0; i < len; i++)
814     retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
815
816   if (new_pos)
817     *new_pos = pos;
818
819   *array_len = len;
820   *array = retval;
821   
822   return TRUE;  
823 }
824
825 /**
826  * Demarshals a double array.
827  *
828  * @param str the string containing the data
829  * @param byte_order the byte order
830  * @param pos the position in the string
831  * @param new_pos the new position of the string
832  * @param array the array
833  * @param array_len length of the demarshaled data
834  * @returns #TRUE on success
835  */
836 dbus_bool_t
837 _dbus_demarshal_double_array (const DBusString  *str,
838                               int                byte_order,
839                               int                pos,
840                               int               *new_pos,
841                               double           **array,
842                               int               *array_len)
843 {
844   int len, i;
845   double *retval;
846   
847   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (double);
848
849   if (len == 0)
850     {
851       *array_len = 0;
852       *array = NULL;
853
854       if (new_pos)
855         *new_pos = pos;
856       
857       return TRUE;
858     }
859   
860   retval = dbus_new (double, len);
861
862   if (!retval)
863     return FALSE;
864
865   for (i = 0; i < len; i++)
866     retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
867
868   if (new_pos)
869     *new_pos = pos;
870
871   *array_len = len;
872   *array = retval;
873   
874   return TRUE; 
875 }
876
877 /**
878  * Demarshals a string array.
879  *
880  * @param str the string containing the data
881  * @param byte_order the byte order
882  * @param pos the position in the string
883  * @param new_pos the new position of the string
884  * @param array the array
885  * @param array_len length of the demarshaled data
886  * @returns #TRUE on success
887  */
888 dbus_bool_t
889 _dbus_demarshal_string_array (const DBusString   *str,
890                               int                 byte_order,
891                               int                 pos,
892                               int                *new_pos,
893                               char             ***array,
894                               int                *array_len)
895 {
896   int len, i, j;
897   char **retval;
898
899   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
900
901   if (len == 0)
902     {
903       *array_len = 0;
904       *array = NULL;
905
906       if (new_pos)
907         *new_pos = pos;
908       
909       return TRUE;
910     }
911   
912   retval = dbus_new (char *, len + 1);
913
914   if (!retval)
915     return FALSE;
916
917   retval[len] = NULL;
918   
919   for (i = 0; i < len; i++)
920     {
921       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
922
923       if (retval[i] == 0)
924         goto error;
925     }
926
927  if (new_pos)
928     *new_pos = pos;
929
930  *array = retval;
931  *array_len = len;
932   
933   return TRUE;
934
935  error:
936   for (j = 0; j < i; j++)
937     dbus_free (retval[i]);
938   dbus_free (retval);
939
940   return FALSE;
941 }
942
943 /** 
944  * Returns the position right after the end of an argument.  PERFORMS
945  * NO VALIDATION WHATSOEVER. The message must have been previously
946  * validated.
947  *
948  * @param str a string
949  * @param byte_order the byte order to use
950  * @param type the type of the argument
951  * @param pos the pos where the arg starts
952  * @param end_pos pointer where the position right
953  * after the end position will follow
954  * @returns TRUE if more data exists after the arg
955  */
956 dbus_bool_t
957 _dbus_marshal_get_arg_end_pos (const DBusString *str,
958                                int               byte_order,
959                                int               type,
960                                int               pos,
961                                int              *end_pos)
962 {
963   if (pos >= _dbus_string_get_length (str))
964     return FALSE;
965
966   switch (type)
967     {
968     case DBUS_TYPE_INVALID:
969       return FALSE;
970       break;
971
972     case DBUS_TYPE_NIL:
973       *end_pos = pos;
974       break;
975
976     case DBUS_TYPE_BYTE:
977       *end_pos = pos + 1;
978       break;
979       
980     case DBUS_TYPE_BOOLEAN:
981       *end_pos = pos + 1;
982       break;
983
984     case DBUS_TYPE_INT32:
985       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
986
987       break;
988
989     case DBUS_TYPE_UINT32:
990       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
991
992       break;
993
994     case DBUS_TYPE_DOUBLE:
995       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
996
997       break;
998
999     case DBUS_TYPE_STRING:
1000       {
1001         int len;
1002         
1003         /* Demarshal the length */
1004         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1005
1006         *end_pos = pos + len + 1;
1007       }
1008       break;
1009
1010     case DBUS_TYPE_NAMED:
1011       {
1012         int len;
1013         
1014         /* Demarshal the string length */
1015         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1016
1017         *end_pos = pos + len + 1;
1018         
1019         /* Demarshal the data length */
1020         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1021
1022         *end_pos = pos + len;
1023       }
1024       break;
1025       
1026     case DBUS_TYPE_ARRAY:
1027       {
1028         int len;
1029
1030         /* Demarshal the length  */
1031         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1032         
1033         *end_pos = pos + len;
1034       }
1035       break;
1036
1037     case DBUS_TYPE_DICT:
1038       {
1039         int len;
1040
1041         /* Demarshal the length */
1042         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1043         
1044         *end_pos = pos + len;
1045       }
1046       break;
1047       
1048     default:
1049       _dbus_warn ("Unknown message arg type %d\n", type);
1050       _dbus_assert_not_reached ("Unknown message argument type\n");
1051       return FALSE;
1052     }
1053
1054   if (*end_pos > _dbus_string_get_length (str))
1055     return FALSE;
1056   
1057   return TRUE;
1058 }
1059
1060 /**
1061  * Demarshals and validates a length; returns < 0 if the validation
1062  * fails. The length is required to be small enough that
1063  * len*sizeof(double) will not overflow, and small enough to fit in a
1064  * signed integer. DOES NOT check whether the length points
1065  * beyond the end of the string, because it doesn't know the
1066  * size of array elements.
1067  *
1068  * @param str the string
1069  * @param byte_order the byte order
1070  * @param pos the unaligned string position (snap to next aligned)
1071  * @param new_pos return location for new position.
1072  */
1073 static int
1074 demarshal_and_validate_len (const DBusString *str,
1075                             int               byte_order,
1076                             int               pos,
1077                             int              *new_pos)
1078 {
1079   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1080   unsigned int len;
1081
1082   _dbus_assert (new_pos != NULL);
1083   
1084   if ((align_4 + 4) > _dbus_string_get_length (str))
1085     {
1086       _dbus_verbose ("not enough room in message for array length\n");
1087       return -1;
1088     }
1089   
1090   if (!_dbus_string_validate_nul (str, pos,
1091                                   align_4 - pos))
1092     {
1093       _dbus_verbose ("array length alignment padding not initialized to nul\n");
1094       return -1;
1095     }
1096
1097   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1098
1099   /* note that the len is the number of bytes, so we need it to be
1100    * at least SIZE_T_MAX, but make it smaller just to keep things
1101    * sane.  We end up using ints for most sizes to avoid unsigned mess
1102    * so limit to maximum 32-bit signed int divided by at least 8, more
1103    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1104    */  
1105 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1106   if (len > MAX_ARRAY_LENGTH)
1107     {
1108       _dbus_verbose ("array length %u exceeds maximum of %u\n",
1109                      len, MAX_ARRAY_LENGTH);
1110       return -1;
1111     }
1112   else
1113     return (int) len;
1114 }
1115
1116 static dbus_bool_t
1117 validate_string (const DBusString *str,
1118                  int               pos,
1119                  int               len_without_nul,
1120                  int              *end_pos)
1121 {
1122   *end_pos = pos + len_without_nul + 1;
1123   
1124   if (*end_pos > _dbus_string_get_length (str))
1125     {
1126       _dbus_verbose ("string length outside length of the message\n");
1127       return FALSE;
1128     }
1129   
1130   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1131     {
1132       _dbus_verbose ("string arg not nul-terminated\n");
1133       return FALSE;
1134     }
1135   
1136   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1137     {
1138       _dbus_verbose ("string is not valid UTF-8\n");
1139       return FALSE;
1140     }
1141
1142   return TRUE;
1143 }   
1144
1145 /**
1146  * Validates and returns a typecode at a specific position
1147  * in the message
1148  *
1149  * @param str a string
1150  * @param type the type of the argument
1151  * @param pos the pos where the typecode starts
1152  * @param end_pos pointer where the position right
1153  * after the end position will follow
1154  * @returns #TRUE if the type is valid.
1155  */
1156 dbus_bool_t
1157 _dbus_marshal_validate_type   (const DBusString *str,
1158                                int               pos,
1159                                int              *type,
1160                                int              *end_pos)
1161 {
1162   const char *data;
1163   
1164   if (pos >= _dbus_string_get_length (str))
1165     return FALSE;
1166
1167   data = _dbus_string_get_const_data_len (str, pos, 1);
1168
1169   if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1170     {
1171       *type = *data;
1172       if (end_pos != NULL)
1173         *end_pos = pos + 1;
1174       return TRUE;
1175     }
1176   
1177   return FALSE;
1178 }
1179
1180
1181 /** 
1182  * Validates an argument of a specific type, checking that it
1183  * is well-formed, for example no ludicrous length fields, strings
1184  * are nul-terminated, etc.
1185  * Returns the end position of the argument in end_pos, and
1186  * returns #TRUE if a valid arg begins at "pos"
1187  *
1188  * @todo security: need to audit this function.
1189  *
1190  * @todo For array types that can't be invalid, we should not
1191  * walk the whole array validating it. e.g. just skip all the
1192  * int values in an int array.
1193  * 
1194  * @param str a string
1195  * @param byte_order the byte order to use
1196  * @param depth current recursion depth, to prevent excessive recursion
1197  * @param type the type of the argument
1198  * @param array_type_pos the position of the current array type, or
1199  *        -1 if not in an array
1200  * @param pos the pos where the arg starts
1201  * @param end_pos pointer where the position right
1202  * after the end position will follow
1203  * @returns #TRUE if the arg is valid.
1204  */
1205 dbus_bool_t
1206 _dbus_marshal_validate_arg (const DBusString *str,
1207                             int               byte_order,
1208                             int               depth,
1209                             int               type,
1210                             int               array_type_pos,
1211                             int               pos,
1212                             int              *end_pos)
1213 {
1214   if (pos > _dbus_string_get_length (str))
1215     {
1216       _dbus_verbose ("Validation went off the end of the message\n");
1217       return FALSE;
1218     }
1219
1220 #define MAX_VALIDATION_DEPTH 32
1221   
1222   if (depth > MAX_VALIDATION_DEPTH)
1223     {
1224       _dbus_verbose ("Maximum recursion depth reached validating message\n");
1225       return FALSE;
1226     }
1227   
1228   switch (type)
1229     {
1230     case DBUS_TYPE_INVALID:
1231       return FALSE;
1232       break;
1233
1234     case DBUS_TYPE_NIL:
1235       *end_pos = pos;
1236       break;
1237
1238     case DBUS_TYPE_BYTE:
1239       if (1 > _dbus_string_get_length (str) - pos)
1240         {
1241           _dbus_verbose ("no room for byte value\n");
1242           return FALSE;
1243         }
1244         
1245       *end_pos = pos + 1;
1246       break;
1247       
1248     case DBUS_TYPE_BOOLEAN:
1249       {
1250         unsigned char c;
1251
1252         if (1 > _dbus_string_get_length (str) - pos)
1253           {
1254             _dbus_verbose ("no room for boolean value\n");
1255             return FALSE;
1256           }
1257         
1258         c = _dbus_string_get_byte (str, pos);
1259
1260         if (c != 0 && c != 1)
1261           {
1262             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1263             return FALSE;
1264           }
1265         
1266       *end_pos = pos + 1;
1267       break;
1268       }
1269     case DBUS_TYPE_INT32:
1270     case DBUS_TYPE_UINT32:
1271       {
1272         int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1273         
1274         if (!_dbus_string_validate_nul (str, pos,
1275                                         align_4 - pos))
1276           {
1277             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1278             return FALSE;
1279           }
1280
1281         *end_pos = align_4 + 4;
1282       }
1283       break;
1284
1285     case DBUS_TYPE_DOUBLE:
1286       {
1287         int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1288
1289         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1290         
1291         if (!_dbus_string_validate_nul (str, pos,
1292                                         align_8 - pos))
1293           {
1294             _dbus_verbose ("double alignment padding not initialized to nul\n");
1295             return FALSE;
1296           }
1297
1298         *end_pos = align_8 + 8;
1299       }
1300       break;
1301
1302     case DBUS_TYPE_STRING:
1303       {
1304         int len;
1305
1306         /* Demarshal the length, which does NOT include
1307          * nul termination
1308          */
1309         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1310         if (len < 0)
1311           return FALSE;
1312
1313         if (!validate_string (str, pos, len, end_pos))
1314           return FALSE;
1315       }
1316       break;
1317
1318     case DBUS_TYPE_NAMED:
1319       {
1320         int len;
1321
1322         /* Demarshal the string length, which does NOT include
1323          * nul termination
1324          */
1325         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1326         if (len < 0)
1327           return FALSE;
1328
1329         if (!validate_string (str, pos, len, &pos))
1330           return FALSE;
1331
1332         /* Validate data */
1333         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1334         if (len < 0)
1335           return FALSE;
1336
1337         *end_pos = pos + len;
1338       }
1339       break;
1340       
1341     case DBUS_TYPE_ARRAY:
1342       {
1343         int len;
1344         int end;
1345         int array_type;
1346
1347         if (array_type_pos == -1)
1348           {
1349             array_type_pos = pos;
1350
1351             do
1352               {
1353                 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1354                   {
1355                     _dbus_verbose ("invalid array type\n");
1356                     return FALSE;
1357                   }
1358                 
1359                 /* NIL values take up no space, so you couldn't iterate over an array of them.
1360                  * array of nil seems useless anyway; the useful thing might be array of
1361                  * (nil OR string) but we have no framework for that.
1362                  */
1363                 if (array_type == DBUS_TYPE_NIL)
1364                   {
1365                     _dbus_verbose ("array of NIL is not allowed\n");
1366                     return FALSE;
1367                   }
1368               }
1369             while (array_type == DBUS_TYPE_ARRAY);
1370           }
1371         else
1372           array_type_pos++;
1373
1374         if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
1375           {
1376             _dbus_verbose ("invalid array type\n");
1377             return FALSE;
1378           }
1379         
1380         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1381         if (len < 0)
1382           return FALSE;
1383
1384         if (len > _dbus_string_get_length (str) - pos)
1385           {
1386             _dbus_verbose ("array length outside length of the message\n");
1387             return FALSE;
1388           }
1389         
1390         end = pos + len;
1391         
1392         while (pos < end)
1393           {
1394             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1395                                              array_type, array_type_pos, pos, &pos))
1396               return FALSE;
1397           }
1398
1399         if (pos < end)
1400           {
1401             /* This should not be able to happen, as long as validate_arg moves forward;
1402              * but the check is here just to be paranoid.
1403              */
1404             _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
1405                     len, end - pos);
1406             return FALSE;
1407           }
1408         
1409         if (pos > end)
1410           {
1411             _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
1412             return FALSE;
1413           }
1414
1415         *end_pos = pos;
1416       }
1417       break;
1418
1419     case DBUS_TYPE_DICT:
1420       {
1421         int dict_type;
1422         int len;
1423         int end;
1424         
1425         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1426         if (len < 0)
1427           return FALSE;
1428
1429         if (len > _dbus_string_get_length (str) - pos)
1430           {
1431             _dbus_verbose ("dict length outside length of the message\n");
1432             return FALSE;
1433           }
1434         
1435         end = pos + len;
1436         
1437         while (pos < end)
1438           {
1439             /* Validate name */
1440             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1441                                              DBUS_TYPE_STRING, -1, pos, &pos))
1442               return FALSE;
1443             
1444             if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
1445               {
1446                 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
1447                 return FALSE;
1448               }
1449             
1450             /* Validate element */
1451             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1452                                              dict_type, -1, pos, &pos))
1453               return FALSE;
1454           }
1455         
1456         if (pos > end)
1457           {
1458             _dbus_verbose ("dict contents exceed stated dict length\n");
1459             return FALSE;
1460           }
1461         
1462         *end_pos = pos;
1463       }
1464       break;
1465       
1466     default:
1467       _dbus_verbose ("Unknown message arg type %d\n", type);
1468       return FALSE;
1469     }
1470
1471   if (*end_pos > _dbus_string_get_length (str))
1472     return FALSE;
1473   
1474   return TRUE;
1475 }
1476
1477
1478 /**
1479  * If in verbose mode, print a block of binary data.
1480  *
1481  * @todo right now it prints even if not in verbose mode
1482  * 
1483  * @param data the data
1484  * @param len the length of the data
1485  */
1486 void
1487 _dbus_verbose_bytes (const unsigned char *data,
1488                      int                  len)
1489 {
1490   int i;
1491   const unsigned char *aligned;
1492
1493   _dbus_assert (len >= 0);
1494   
1495   /* Print blanks on first row if appropriate */
1496   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1497   if (aligned > data)
1498     aligned -= 4;
1499   _dbus_assert (aligned <= data);
1500
1501   if (aligned != data)
1502     {
1503       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1504       while (aligned != data)
1505         {
1506           _dbus_verbose ("    ");
1507           ++aligned;
1508         }
1509     }
1510
1511   /* now print the bytes */
1512   i = 0;
1513   while (i < len)
1514     {
1515       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1516         {
1517           _dbus_verbose ("%4d\t%p: ",
1518                    i, &data[i]);
1519         }
1520       
1521       if (data[i] >= 32 &&
1522           data[i] <= 126)
1523         _dbus_verbose (" '%c' ", data[i]);
1524       else
1525         _dbus_verbose ("0x%s%x ",
1526                  data[i] <= 0xf ? "0" : "", data[i]);
1527
1528       ++i;
1529
1530       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1531         {
1532           if (i > 3)
1533             _dbus_verbose ("BE: %d LE: %d",
1534                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1535                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1536
1537           if (i > 7 && 
1538               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1539             {
1540               _dbus_verbose (" dbl: %g",
1541                              *(double*)&data[i-8]);
1542             }
1543           
1544           _dbus_verbose ("\n");
1545         }
1546     }
1547
1548   _dbus_verbose ("\n");
1549 }
1550
1551 /**
1552  * Dump the given part of the string to verbose log.
1553  *
1554  * @param str the string
1555  * @param start the start of range to dump
1556  * @param len length of range
1557  */
1558 void
1559 _dbus_verbose_bytes_of_string (const DBusString    *str,
1560                                int                  start,
1561                                int                  len)
1562 {
1563   const char *d;
1564   int real_len;
1565
1566   real_len = _dbus_string_get_length (str);
1567
1568   _dbus_assert (start >= 0);
1569   
1570   if (start > real_len)
1571     {
1572       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1573                      start, len, real_len);
1574       return;
1575     }
1576
1577   if ((start + len) > real_len)
1578     {
1579       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1580                      start, len, real_len);
1581       len = real_len - start;
1582     }
1583   
1584   d = _dbus_string_get_const_data_len (str, start, len);
1585
1586   _dbus_verbose_bytes (d, len);
1587 }
1588
1589 /** @} */
1590
1591 #ifdef DBUS_BUILD_TESTS
1592 #include "dbus-test.h"
1593 #include <stdio.h>
1594
1595 dbus_bool_t
1596 _dbus_marshal_test (void)
1597 {
1598   DBusString str;
1599   char *tmp1, *tmp2;
1600   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1601   int pos = 0, len;
1602   
1603   if (!_dbus_string_init (&str))
1604     _dbus_assert_not_reached ("failed to init string");
1605
1606   /* Marshal doubles */
1607   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1608     _dbus_assert_not_reached ("could not marshal double value");
1609   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1610     _dbus_assert_not_reached ("demarshal failed");
1611
1612   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1613     _dbus_assert_not_reached ("could not marshal double value");
1614   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1615     _dbus_assert_not_reached ("demarshal failed");
1616   
1617   /* Marshal signed integers */
1618   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1619     _dbus_assert_not_reached ("could not marshal signed integer value");
1620   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1621     _dbus_assert_not_reached ("demarshal failed");
1622
1623   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1624     _dbus_assert_not_reached ("could not marshal signed integer value");
1625   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1626     _dbus_assert_not_reached ("demarshal failed");
1627   
1628   /* Marshal unsigned integers */
1629   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1630     _dbus_assert_not_reached ("could not marshal signed integer value");
1631   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1632     _dbus_assert_not_reached ("demarshal failed");
1633   
1634   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1635     _dbus_assert_not_reached ("could not marshal signed integer value");
1636   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1637     _dbus_assert_not_reached ("demarshal failed");
1638
1639   /* Marshal strings */
1640   tmp1 = "This is the dbus test string";
1641   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1642     _dbus_assert_not_reached ("could not marshal string");
1643   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1644   if (!strcmp (tmp1, tmp2) == 0)
1645     _dbus_assert_not_reached ("demarshal failed");
1646   dbus_free (tmp2);
1647
1648   tmp1 = "This is the dbus test string";
1649   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1650     _dbus_assert_not_reached ("could not marshal string");
1651   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1652   if (!strcmp (tmp1, tmp2) == 0)
1653     _dbus_assert_not_reached ("demarshal failed");
1654   dbus_free (tmp2);
1655
1656   /* Marshal signed integer arrays */
1657   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1658     _dbus_assert_not_reached ("could not marshal integer array");
1659   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
1660     _dbus_assert_not_reached ("could not demarshal integer array");
1661
1662   if (len != 3)
1663     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1664   dbus_free (array2);
1665   
1666   _dbus_string_free (&str);
1667   
1668       
1669   return TRUE;
1670 }
1671
1672 #endif /* DBUS_BUILD_TESTS */