b1eb6fc75ffb374b25f044517982e76e93cd471d
[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 (element type is at pos + 0 */
1031         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &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       *end_pos = pos + 1;
1173       return TRUE;
1174     }
1175   
1176   return FALSE;
1177 }
1178
1179
1180 /** 
1181  * Validates an argument of a specific type, checking that it
1182  * is well-formed, for example no ludicrous length fields, strings
1183  * are nul-terminated, etc.
1184  * Returns the end position of the argument in end_pos, and
1185  * returns #TRUE if a valid arg begins at "pos"
1186  *
1187  * @todo security: need to audit this function.
1188  *
1189  * @todo For array types that can't be invalid, we should not
1190  * walk the whole array validating it. e.g. just skip all the
1191  * int values in an int array.
1192  * 
1193  * @param str a string
1194  * @param byte_order the byte order to use
1195  * @param depth current recursion depth, to prevent excessive recursion
1196  * @param type the type of the argument
1197  * @param pos the pos where the arg starts
1198  * @param end_pos pointer where the position right
1199  * after the end position will follow
1200  * @returns #TRUE if the arg is valid.
1201  */
1202 dbus_bool_t
1203 _dbus_marshal_validate_arg (const DBusString *str,
1204                             int               byte_order,
1205                             int               depth,
1206                             int               type,
1207                             int               pos,
1208                             int              *end_pos)
1209 {
1210   if (pos > _dbus_string_get_length (str))
1211     {
1212       _dbus_verbose ("Validation went off the end of the message\n");
1213       return FALSE;
1214     }
1215
1216 #define MAX_VALIDATION_DEPTH 32
1217   
1218   if (depth > MAX_VALIDATION_DEPTH)
1219     {
1220       _dbus_verbose ("Maximum recursion depth reached validating message\n");
1221       return FALSE;
1222     }
1223   
1224   switch (type)
1225     {
1226     case DBUS_TYPE_INVALID:
1227       return FALSE;
1228       break;
1229
1230     case DBUS_TYPE_NIL:
1231       *end_pos = pos;
1232       break;
1233
1234     case DBUS_TYPE_BYTE:
1235       if (1 > _dbus_string_get_length (str) - pos)
1236         {
1237           _dbus_verbose ("no room for byte value\n");
1238           return FALSE;
1239         }
1240         
1241       *end_pos = pos + 1;
1242       break;
1243       
1244     case DBUS_TYPE_BOOLEAN:
1245       {
1246         unsigned char c;
1247
1248         if (1 > _dbus_string_get_length (str) - pos)
1249           {
1250             _dbus_verbose ("no room for boolean value\n");
1251             return FALSE;
1252           }
1253         
1254         c = _dbus_string_get_byte (str, pos);
1255
1256         if (c != 0 && c != 1)
1257           {
1258             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1259             return FALSE;
1260           }
1261         
1262       *end_pos = pos + 1;
1263       break;
1264       }
1265     case DBUS_TYPE_INT32:
1266     case DBUS_TYPE_UINT32:
1267       {
1268         int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1269         
1270         if (!_dbus_string_validate_nul (str, pos,
1271                                         align_4 - pos))
1272           {
1273             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1274             return FALSE;
1275           }
1276
1277         *end_pos = align_4 + 4;
1278       }
1279       break;
1280
1281     case DBUS_TYPE_DOUBLE:
1282       {
1283         int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1284
1285         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1286         
1287         if (!_dbus_string_validate_nul (str, pos,
1288                                         align_8 - pos))
1289           {
1290             _dbus_verbose ("double alignment padding not initialized to nul\n");
1291             return FALSE;
1292           }
1293
1294         *end_pos = align_8 + 8;
1295       }
1296       break;
1297
1298     case DBUS_TYPE_STRING:
1299       {
1300         int len;
1301
1302         /* Demarshal the length, which does NOT include
1303          * nul termination
1304          */
1305         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1306         if (len < 0)
1307           return FALSE;
1308
1309         if (!validate_string (str, pos, len, end_pos))
1310           return FALSE;
1311       }
1312       break;
1313
1314     case DBUS_TYPE_NAMED:
1315       {
1316         int len;
1317
1318         /* Demarshal the string length, which does NOT include
1319          * nul termination
1320          */
1321         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1322         if (len < 0)
1323           return FALSE;
1324
1325         if (!validate_string (str, pos, len, &pos))
1326           return FALSE;
1327
1328         /* Validate data */
1329         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1330         if (len < 0)
1331           return FALSE;
1332
1333         *end_pos = pos + len;
1334       }
1335       break;
1336       
1337     case DBUS_TYPE_ARRAY:
1338       {
1339         int len;
1340         int end;
1341         int array_type;
1342
1343         if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1344           {
1345             _dbus_verbose ("invalid array type\n");
1346             return FALSE;
1347           }
1348
1349         /* NIL values take up no space, so you couldn't iterate over an array of them.
1350          * array of nil seems useless anyway; the useful thing might be array of
1351          * (nil OR string) but we have no framework for that.
1352          */
1353         if (array_type == DBUS_TYPE_NIL)
1354           {
1355             _dbus_verbose ("array of NIL is not allowed\n");
1356             return FALSE;
1357           }
1358         
1359         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1360         if (len < 0)
1361           return FALSE;
1362
1363         if (len > _dbus_string_get_length (str) - pos)
1364           {
1365             _dbus_verbose ("array length outside length of the message\n");
1366             return FALSE;
1367           }
1368         
1369         end = pos + len;
1370         
1371         while (pos < end)
1372           {
1373             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1374                                              array_type, pos, &pos))
1375               return FALSE;
1376           }
1377
1378         if (pos < end)
1379           {
1380             /* This should not be able to happen, as long as validate_arg moves forward;
1381              * but the check is here just to be paranoid.
1382              */
1383             _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
1384                     len, end - pos);
1385             return FALSE;
1386           }
1387         
1388         if (pos > end)
1389           {
1390             _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
1391             return FALSE;
1392           }
1393
1394         *end_pos = pos;
1395       }
1396       break;
1397
1398     case DBUS_TYPE_DICT:
1399       {
1400         int dict_type;
1401         int len;
1402         int end;
1403         
1404         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1405         if (len < 0)
1406           return FALSE;
1407
1408         if (len > _dbus_string_get_length (str) - pos)
1409           {
1410             _dbus_verbose ("dict length outside length of the message\n");
1411             return FALSE;
1412           }
1413         
1414         end = pos + len;
1415         
1416         while (pos < end)
1417           {
1418             /* Validate name */
1419             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1420                                              DBUS_TYPE_STRING, pos, &pos))
1421               return FALSE;
1422             
1423             if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
1424               {
1425                 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
1426                 return FALSE;
1427               }
1428             
1429             /* Validate element */
1430             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1431                                              dict_type, pos, &pos))
1432               return FALSE;
1433           }
1434         
1435         if (pos > end)
1436           {
1437             _dbus_verbose ("dict contents exceed stated dict length\n");
1438             return FALSE;
1439           }
1440         
1441         *end_pos = pos;
1442       }
1443       break;
1444       
1445     default:
1446       _dbus_verbose ("Unknown message arg type %d\n", type);
1447       return FALSE;
1448     }
1449
1450   if (*end_pos > _dbus_string_get_length (str))
1451     return FALSE;
1452   
1453   return TRUE;
1454 }
1455
1456
1457 /**
1458  * If in verbose mode, print a block of binary data.
1459  *
1460  * @todo right now it prints even if not in verbose mode
1461  * 
1462  * @param data the data
1463  * @param len the length of the data
1464  */
1465 void
1466 _dbus_verbose_bytes (const unsigned char *data,
1467                      int                  len)
1468 {
1469   int i;
1470   const unsigned char *aligned;
1471
1472   _dbus_assert (len >= 0);
1473   
1474   /* Print blanks on first row if appropriate */
1475   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1476   if (aligned > data)
1477     aligned -= 4;
1478   _dbus_assert (aligned <= data);
1479
1480   if (aligned != data)
1481     {
1482       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1483       while (aligned != data)
1484         {
1485           _dbus_verbose ("    ");
1486           ++aligned;
1487         }
1488     }
1489
1490   /* now print the bytes */
1491   i = 0;
1492   while (i < len)
1493     {
1494       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1495         {
1496           _dbus_verbose ("%4d\t%p: ",
1497                    i, &data[i]);
1498         }
1499       
1500       if (data[i] >= 32 &&
1501           data[i] <= 126)
1502         _dbus_verbose (" '%c' ", data[i]);
1503       else
1504         _dbus_verbose ("0x%s%x ",
1505                  data[i] <= 0xf ? "0" : "", data[i]);
1506
1507       ++i;
1508
1509       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1510         {
1511           if (i > 3)
1512             _dbus_verbose ("BE: %d LE: %d",
1513                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1514                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1515
1516           if (i > 7 && 
1517               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1518             {
1519               _dbus_verbose (" dbl: %g",
1520                              *(double*)&data[i-8]);
1521             }
1522           
1523           _dbus_verbose ("\n");
1524         }
1525     }
1526
1527   _dbus_verbose ("\n");
1528 }
1529
1530 /**
1531  * Dump the given part of the string to verbose log.
1532  *
1533  * @param str the string
1534  * @param start the start of range to dump
1535  * @param len length of range
1536  */
1537 void
1538 _dbus_verbose_bytes_of_string (const DBusString    *str,
1539                                int                  start,
1540                                int                  len)
1541 {
1542   const char *d;
1543   int real_len;
1544
1545   real_len = _dbus_string_get_length (str);
1546
1547   _dbus_assert (start >= 0);
1548   
1549   if (start > real_len)
1550     {
1551       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1552                      start, len, real_len);
1553       return;
1554     }
1555
1556   if ((start + len) > real_len)
1557     {
1558       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1559                      start, len, real_len);
1560       len = real_len - start;
1561     }
1562   
1563   d = _dbus_string_get_const_data_len (str, start, len);
1564
1565   _dbus_verbose_bytes (d, len);
1566 }
1567
1568 /** @} */
1569
1570 #ifdef DBUS_BUILD_TESTS
1571 #include "dbus-test.h"
1572 #include <stdio.h>
1573
1574 dbus_bool_t
1575 _dbus_marshal_test (void)
1576 {
1577   DBusString str;
1578   char *tmp1, *tmp2;
1579   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1580   int pos = 0, len;
1581   
1582   if (!_dbus_string_init (&str))
1583     _dbus_assert_not_reached ("failed to init string");
1584
1585   /* Marshal doubles */
1586   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1587     _dbus_assert_not_reached ("could not marshal double value");
1588   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1589     _dbus_assert_not_reached ("demarshal failed");
1590
1591   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1592     _dbus_assert_not_reached ("could not marshal double value");
1593   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1594     _dbus_assert_not_reached ("demarshal failed");
1595   
1596   /* Marshal signed integers */
1597   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1598     _dbus_assert_not_reached ("could not marshal signed integer value");
1599   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1600     _dbus_assert_not_reached ("demarshal failed");
1601
1602   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1603     _dbus_assert_not_reached ("could not marshal signed integer value");
1604   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1605     _dbus_assert_not_reached ("demarshal failed");
1606   
1607   /* Marshal unsigned integers */
1608   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1609     _dbus_assert_not_reached ("could not marshal signed integer value");
1610   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1611     _dbus_assert_not_reached ("demarshal failed");
1612   
1613   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1614     _dbus_assert_not_reached ("could not marshal signed integer value");
1615   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1616     _dbus_assert_not_reached ("demarshal failed");
1617
1618   /* Marshal strings */
1619   tmp1 = "This is the dbus test string";
1620   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1621     _dbus_assert_not_reached ("could not marshal string");
1622   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1623   if (!strcmp (tmp1, tmp2) == 0)
1624     _dbus_assert_not_reached ("demarshal failed");
1625   dbus_free (tmp2);
1626
1627   tmp1 = "This is the dbus test string";
1628   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1629     _dbus_assert_not_reached ("could not marshal string");
1630   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1631   if (!strcmp (tmp1, tmp2) == 0)
1632     _dbus_assert_not_reached ("demarshal failed");
1633   dbus_free (tmp2);
1634
1635   /* Marshal signed integer arrays */
1636   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1637     _dbus_assert_not_reached ("could not marshal integer array");
1638   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
1639     _dbus_assert_not_reached ("could not demarshal integer array");
1640
1641   if (len != 3)
1642     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1643   dbus_free (array2);
1644   
1645   _dbus_string_free (&str);
1646   
1647       
1648   return TRUE;
1649 }
1650
1651 #endif /* DBUS_BUILD_TESTS */