2003-03-23 Havoc Pennington <hp@pobox.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  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-marshal.h"
25 #include "dbus-internals.h"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
28
29 #include <string.h>
30
31 /* from ORBit */
32 static void
33 swap_bytes (unsigned char *data,
34             unsigned int   len)
35 {
36   unsigned char *p1 = data;
37   unsigned char *p2 = data + len - 1;
38
39   while (p1 < p2)
40     {
41       unsigned char tmp = *p1;
42       *p1 = *p2;
43       *p2 = tmp;
44
45       --p2;
46       ++p1;
47     }
48 }
49
50 /**
51  * @defgroup DBusMarshal marshaling and unmarshaling
52  * @ingroup  DBusInternals
53  * @brief functions to marshal/unmarshal data from the wire
54  *
55  * Types and functions related to converting primitive data types from
56  * wire format to native machine format, and vice versa.
57  *
58  * @{
59  */
60
61 /**
62  * Unpacks a 32 bit unsigned integer from a data pointer
63  *
64  * @param byte_order The byte order to use
65  * @param data the data pointer
66  * @returns the integer
67  */
68 dbus_uint32_t
69 _dbus_unpack_uint32 (int                  byte_order,
70                      const unsigned char *data)
71 {
72   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
73   
74   if (byte_order == DBUS_LITTLE_ENDIAN)
75     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
76   else
77     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
78 }  
79
80 /**
81  * Unpacks a 32 bit signed integer from a data pointer
82  *
83  * @param byte_order The byte order to use
84  * @param data the data pointer
85  * @returns the integer
86  */
87 dbus_int32_t
88 _dbus_unpack_int32 (int                  byte_order,
89                     const unsigned char *data)
90 {
91   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
92   
93   if (byte_order == DBUS_LITTLE_ENDIAN)
94     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
95   else
96     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
97 }
98
99 /**
100  * Packs a 32 bit unsigned integer into a data pointer.
101  *
102  * @param value the value
103  * @param byte_order the byte order to use
104  * @param data the data pointer
105  */
106 void
107 _dbus_pack_uint32 (dbus_uint32_t   value,
108                    int             byte_order,
109                    unsigned char  *data)
110 {
111   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
112   
113   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
114     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
115   else
116     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
117 }
118
119 /**
120  * Packs a 32 bit signed integer into a data pointer.
121  *
122  * @param value the value
123  * @param byte_order the byte order to use
124  * @param data the data pointer
125  */
126 void
127 _dbus_pack_int32 (dbus_int32_t   value,
128                   int            byte_order,
129                   unsigned char *data)
130 {
131   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
132   
133   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
134     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);       
135   else
136     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
137 }
138
139 /**
140  * Sets the 4 bytes at the given offset to a marshaled signed integer,
141  * replacing anything found there previously.
142  *
143  * @param str the string to write the marshalled int to
144  * @param offset the byte offset where int should be written
145  * @param byte_order the byte order to use
146  * @param value the value
147  * 
148  */
149 void
150 _dbus_marshal_set_int32 (DBusString          *str,
151                          int                  byte_order,
152                          int                  offset,
153                          dbus_int32_t         value)
154 {
155   char *data;
156   
157   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
158                 byte_order == DBUS_BIG_ENDIAN);
159   
160   _dbus_string_get_data_len (str, &data, offset, 4);
161
162   _dbus_pack_int32 (value, byte_order, data);
163 }
164
165 /**
166  * Sets the 4 bytes at the given offset to a marshaled unsigned
167  * integer, replacing anything found there previously.
168  *
169  * @param str the string to write the marshalled int to
170  * @param offset the byte offset where int should be written
171  * @param byte_order the byte order to use
172  * @param value the value
173  * 
174  */
175 void
176 _dbus_marshal_set_uint32 (DBusString          *str,
177                           int                  byte_order,
178                           int                  offset,
179                           dbus_uint32_t        value)
180 {
181   char *data;
182   
183   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
184                 byte_order == DBUS_BIG_ENDIAN);
185   
186   _dbus_string_get_data_len (str, &data, offset, 4);
187
188   _dbus_pack_uint32 (value, byte_order, data);
189 }
190
191 /**
192  * Sets the existing marshaled string at the given offset with
193  * a new marshaled string. The given offset must point to
194  * an existing string or the wrong length will be deleted
195  * and replaced with the new string.
196  *
197  * @param str the string to write the marshalled string to
198  * @param offset the byte offset where string should be written
199  * @param byte_order the byte order to use
200  * @param value the value
201  * @param len the length to use
202  * @returns #TRUE on success
203  * 
204  */
205 dbus_bool_t
206 _dbus_marshal_set_string (DBusString          *str,
207                           int                  byte_order,
208                           int                  offset,
209                           const DBusString    *value,
210                           int                  len)
211 {
212   int old_len;
213   
214   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
215                 byte_order == DBUS_BIG_ENDIAN);
216   
217   old_len = _dbus_demarshal_uint32 (str, byte_order,
218                                     offset, NULL);
219
220   if (!_dbus_string_replace_len (value, 0, len,
221                                  str, offset + 4, old_len))
222     return FALSE;
223
224   _dbus_marshal_set_uint32 (str, byte_order,
225                             offset, len);
226
227   return TRUE;
228 }
229
230 /**
231  * Marshals a double value.
232  *
233  * @param str the string to append the marshalled value to
234  * @param byte_order the byte order to use
235  * @param value the value
236  * @returns #TRUE on success
237  */
238 dbus_bool_t
239 _dbus_marshal_double (DBusString *str,
240                       int         byte_order,
241                       double      value)
242 {
243   _dbus_assert (sizeof (double) == 8);
244
245   if (!_dbus_string_align_length (str, sizeof (double)))
246     return FALSE;
247   
248   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
249     swap_bytes ((unsigned char *)&value, sizeof (double));
250
251   return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
252 }
253
254 /**
255  * Marshals a 32 bit signed integer value.
256  *
257  * @param str the string to append the marshalled value to
258  * @param byte_order the byte order to use
259  * @param value the value
260  * @returns #TRUE on success
261  */
262 dbus_bool_t
263 _dbus_marshal_int32  (DBusString   *str,
264                       int           byte_order,
265                       dbus_int32_t  value)
266 {
267   if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
268     return FALSE;
269   
270   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
271     value = DBUS_INT32_SWAP_LE_BE (value);
272
273   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
274 }
275
276 /**
277  * Marshals a 32 bit unsigned integer value.
278  *
279  * @param str the string to append the marshalled value to
280  * @param byte_order the byte order to use
281  * @param value the value
282  * @returns #TRUE on success
283  */
284 dbus_bool_t
285 _dbus_marshal_uint32 (DBusString    *str,
286                       int            byte_order,
287                       dbus_uint32_t  value)
288 {
289   if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
290     return FALSE;
291   
292   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
293     value = DBUS_UINT32_SWAP_LE_BE (value);
294
295   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
296 }
297
298 /**
299  * Marshals a UTF-8 string
300  *
301  * @param str the string to append the marshalled value to
302  * @param byte_order the byte order to use
303  * @param value the string
304  * @returns #TRUE on success
305  */
306 dbus_bool_t
307 _dbus_marshal_string (DBusString    *str,
308                       int            byte_order,
309                       const char    *value)
310 {
311   int len, old_string_len;
312
313   old_string_len = _dbus_string_get_length (str);
314   
315   len = strlen (value);
316
317   if (!_dbus_marshal_uint32 (str, byte_order, len))
318     {
319       /* Restore the previous length */
320       _dbus_string_set_length (str, old_string_len);
321
322       return FALSE;
323     }
324
325   return _dbus_string_append_len (str, value, len + 1);
326 }
327
328 /**
329  * Marshals a byte array
330  *
331  * @param str the string to append the marshalled value to
332  * @param byte_order the byte order to use
333  * @param value the array
334  * @param len number of elements in the array
335  * @returns #TRUE on success
336  */
337 dbus_bool_t
338 _dbus_marshal_byte_array (DBusString          *str,
339                           int                  byte_order,
340                           const unsigned char *value,
341                           int                  len)
342 {
343   int old_string_len;
344
345   old_string_len = _dbus_string_get_length (str);
346   
347   if (!_dbus_marshal_uint32 (str, byte_order, len))
348     {
349       /* Restore the previous length */
350       _dbus_string_set_length (str, old_string_len);
351
352       return FALSE;
353     }
354
355   if (len == 0)
356     return TRUE;
357   else
358     return _dbus_string_append_len (str, value, len);
359 }
360
361 /**
362  * Marshals a 32 bit signed integer array
363  *
364  * @param str the string to append the marshalled value to
365  * @param byte_order the byte order to use
366  * @param value the array
367  * @param len the length of the array
368  * @returns #TRUE on success
369  */
370 dbus_bool_t
371 _dbus_marshal_int32_array (DBusString         *str,
372                            int                 byte_order,
373                            const dbus_int32_t *value,
374                            int                 len)
375 {
376   int i, old_string_len;
377
378   old_string_len = _dbus_string_get_length (str);
379
380   if (!_dbus_marshal_uint32 (str, byte_order, len))
381     goto error;
382
383   for (i = 0; i < len; i++)
384     if (!_dbus_marshal_int32 (str, byte_order, value[i]))
385       goto error;
386
387   return TRUE;
388   
389  error:
390   /* Restore previous length */
391   _dbus_string_set_length (str, old_string_len);
392   
393   return FALSE;
394 }
395
396 /**
397  * Marshals a 32 bit unsigned integer array
398  *
399  * @param str the string to append the marshalled value to
400  * @param byte_order the byte order to use
401  * @param value the array
402  * @param len the length of the array
403  * @returns #TRUE on success
404  */
405 dbus_bool_t
406 _dbus_marshal_uint32_array (DBusString          *str,
407                             int                  byte_order,
408                             const dbus_uint32_t  *value,
409                             int                  len)
410 {
411   int i, old_string_len;
412
413   old_string_len = _dbus_string_get_length (str);
414
415   if (!_dbus_marshal_uint32 (str, byte_order, len))
416     goto error;
417
418   for (i = 0; i < len; i++)
419     if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
420       goto error;
421
422   return TRUE;
423   
424  error:
425   /* Restore previous length */
426   _dbus_string_set_length (str, old_string_len);
427   
428   return FALSE;  
429 }
430
431 /**
432  * Marshals a double array
433  *
434  * @param str the string to append the marshalled value to
435  * @param byte_order the byte order to use
436  * @param value the array
437  * @param len the length of the array
438  * @returns #TRUE on success
439  */
440 dbus_bool_t
441 _dbus_marshal_double_array (DBusString          *str,
442                             int                  byte_order,
443                             const double        *value,
444                             int                  len)
445 {
446   int i, old_string_len;
447
448   old_string_len = _dbus_string_get_length (str);
449
450   if (!_dbus_marshal_uint32 (str, byte_order, len))
451     goto error;
452
453   for (i = 0; i < len; i++)
454     if (!_dbus_marshal_double (str, byte_order, value[i]))
455       goto error;
456
457   return TRUE;
458   
459  error:
460   /* Restore previous length */
461   _dbus_string_set_length (str, old_string_len);
462   
463   return FALSE;    
464 }
465
466 /**
467  * Marshals a string array
468  *
469  * @param str the string to append the marshalled value to
470  * @param byte_order the byte order to use
471  * @param value the array
472  * @param len the length of the array
473  * @returns #TRUE on success
474  */
475 dbus_bool_t
476 _dbus_marshal_string_array (DBusString  *str,
477                             int          byte_order,
478                             const char **value,
479                             int          len)
480 {
481   int i, old_string_len;
482
483   old_string_len = _dbus_string_get_length (str);
484
485   if (!_dbus_marshal_uint32 (str, byte_order, len))
486     goto error;
487
488   for (i = 0; i < len; i++)
489     if (!_dbus_marshal_string (str, byte_order, value[i]))
490       goto error;
491
492   return TRUE;
493   
494  error:
495   /* Restore previous length */
496   _dbus_string_set_length (str, old_string_len);
497   
498   return FALSE;      
499 }
500
501
502 /**
503  * Marshals a dict
504  * @param str the string to append the marshalled value to
505  * @param byte_order the byte order to use
506  * @param dict the dict
507  * @returns #TRUE on success
508  */
509 dbus_bool_t
510 _dbus_marshal_dict (DBusString *str,
511                     int         byte_order,
512                     DBusDict   *dict)
513 {
514   int old_string_len;
515   int i, len;
516   char **keys;
517   
518   old_string_len = _dbus_string_get_length (str);
519
520   if (!dbus_dict_get_keys (dict, &keys, &len))
521     goto error;
522
523   if (len == 0)
524     return TRUE;
525
526   if (!_dbus_marshal_string_array (str, byte_order,
527                                    (const char **)keys, len))
528     goto error;
529
530   for (i = 0; i < len; i++)
531     {
532       int value_type;
533
534       value_type = dbus_dict_get_value_type (dict, keys[i]);
535
536       if (!_dbus_string_append_byte (str, value_type))
537         goto error;
538       
539       switch (dbus_dict_get_value_type (dict, keys[i]))
540         {
541         case DBUS_TYPE_BOOLEAN:
542           {
543             dbus_bool_t value;
544
545             if (!dbus_dict_get_boolean (dict, keys[i], &value))
546               goto error;
547             
548             if (!_dbus_string_append_byte (str, (value != FALSE)))
549               goto error;
550
551             break;
552           }
553           
554         case DBUS_TYPE_INT32:
555           {
556             dbus_int32_t value;
557             
558             if (!dbus_dict_get_int32 (dict, keys[i], &value))
559               goto error;
560             
561             if (!_dbus_marshal_int32 (str, byte_order, value))
562               goto error;
563
564             break;
565           }
566         case DBUS_TYPE_UINT32:
567           {
568             dbus_uint32_t value;
569             
570             if (!dbus_dict_get_uint32 (dict, keys[i], &value))
571               goto error;
572             
573             if (!_dbus_marshal_uint32 (str, byte_order, value))
574               goto error;
575
576             break;
577           }
578         case DBUS_TYPE_DOUBLE:
579           {
580             double value;
581             
582             if (!dbus_dict_get_double (dict, keys[i], &value))
583               goto error;
584
585             if (!_dbus_marshal_double (str, byte_order, value))
586               goto error;
587
588             break;
589           }
590         case DBUS_TYPE_INT32_ARRAY:
591           {
592             const dbus_int32_t *value;
593             int len;
594
595             if (!dbus_dict_get_int32_array (dict, keys[i], &value, &len))
596               goto error;
597
598             if (!_dbus_marshal_int32_array (str, byte_order, value, len))
599               goto error;
600             
601             break;
602           }
603         case DBUS_TYPE_STRING:
604           {
605             const char *value;
606
607             if (!dbus_dict_get_string (dict, keys[i], &value))
608               goto error;
609
610             if (!_dbus_marshal_string (str, byte_order, value))
611               goto error;
612             
613             break;
614           }       
615         case DBUS_TYPE_BOOLEAN_ARRAY:
616           {
617             const unsigned char *value;
618             int len;
619
620             if (!dbus_dict_get_boolean_array (dict, keys[i], &value, &len))
621               goto error;
622
623             if (!_dbus_marshal_byte_array (str, byte_order, value, len))
624               goto error;
625             
626             break;
627           }       
628         case DBUS_TYPE_UINT32_ARRAY:
629           {
630             const dbus_uint32_t *value;
631             int len;
632
633             if (!dbus_dict_get_uint32_array (dict, keys[i], &value, &len))
634               goto error;
635
636             if (!_dbus_marshal_uint32_array (str, byte_order, value, len))
637               goto error;
638             
639             break;
640           }       
641         case DBUS_TYPE_DOUBLE_ARRAY:
642           {
643             const double *value;
644             int len;
645
646             if (!dbus_dict_get_double_array (dict, keys[i], &value, &len))
647               goto error;
648
649             if (!_dbus_marshal_double_array (str, byte_order, value, len))
650               goto error;
651             
652             break;
653           }
654         case DBUS_TYPE_STRING_ARRAY:
655           {
656             const char **value;
657             int len;
658
659             if (!dbus_dict_get_string_array (dict, keys[i], &value, &len))
660               goto error;
661
662             if (!_dbus_marshal_string_array (str, byte_order, (const char **)value, len))
663               goto error;
664             
665             break;
666           }
667         default:
668           _dbus_warn ("unkown value type %d\n", dbus_dict_get_value_type (dict, keys[i]));
669           _dbus_assert_not_reached ("unknown value type in dict");
670         }
671     }
672
673   dbus_free_string_array (keys);
674
675   return TRUE;
676   
677  error:
678   
679   dbus_free_string_array (keys);
680   
681   /* Restore previous length */
682   _dbus_string_set_length (str, old_string_len);
683
684   return FALSE;
685 }
686
687
688 /**
689  * Demarshals a double.
690  *
691  * @param str the string containing the data
692  * @param byte_order the byte order
693  * @param pos the position in the string
694  * @param new_pos the new position of the string
695  * @returns the demarshaled double.
696  */
697 double
698 _dbus_demarshal_double (const DBusString  *str,
699                         int          byte_order,
700                         int          pos,
701                         int         *new_pos)
702 {
703   double retval;
704   const char *buffer;
705
706   pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
707
708   _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
709
710   retval = *(double *)buffer;
711   
712   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
713     swap_bytes ((unsigned char *)&retval, sizeof (double));
714
715   if (new_pos)
716     *new_pos = pos + sizeof (double);
717   
718   return retval;  
719 }
720
721 /**
722  * Demarshals a 32 bit signed integer.
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  * @returns the demarshaled integer.
729  */
730 dbus_int32_t
731 _dbus_demarshal_int32  (const DBusString *str,
732                         int               byte_order,
733                         int               pos,
734                         int              *new_pos)
735 {
736   const DBusRealString *real = (const DBusRealString*) str;
737   
738   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
739   
740   if (new_pos)
741     *new_pos = pos + sizeof (dbus_int32_t);
742
743   if (byte_order == DBUS_LITTLE_ENDIAN)
744     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
745   else
746     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
747 }
748
749 /**
750  * Demarshals a 32 bit unsigned integer.
751  *
752  * @param str the string containing the data
753  * @param byte_order the byte order
754  * @param pos the position in the string
755  * @param new_pos the new position of the string
756  * @returns the demarshaled integer.
757  */
758 dbus_uint32_t
759 _dbus_demarshal_uint32  (const DBusString *str,
760                          int         byte_order,
761                          int         pos,
762                          int        *new_pos)
763 {
764   const DBusRealString *real = (const DBusRealString*) str;
765   
766   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
767   
768   if (new_pos)
769     *new_pos = pos + sizeof (dbus_uint32_t);
770
771   if (byte_order == DBUS_LITTLE_ENDIAN)
772     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
773   else
774     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
775 }
776
777 /**
778  * Demarshals an UTF-8 string.
779  *
780  * @todo Should we check the string to make sure
781  * that it's  valid UTF-8, and maybe "fix" the string
782  * if it's broken?
783  *
784  * @todo Should probably demarshal to a DBusString,
785  * having memcpy() in here is Evil(tm).
786  *
787  * @param str the string containing the data
788  * @param byte_order the byte order
789  * @param pos the position in the string
790  * @param new_pos the new position of the string
791  * @returns the demarshaled string.
792  */
793 char *
794 _dbus_demarshal_string (const DBusString *str,
795                         int         byte_order,
796                         int         pos,
797                         int        *new_pos)
798 {
799   int len;
800   char *retval;
801   const char *data;
802   
803   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
804
805   retval = dbus_malloc (len + 1);
806
807   if (!retval)
808     return NULL;
809
810   _dbus_string_get_const_data_len (str, &data, pos, len);
811
812   if (!data)
813     return NULL;
814
815   memcpy (retval, data, len + 1);
816
817   if (new_pos)
818     *new_pos = pos + len + 1;
819   
820   return retval;
821 }
822
823 /**
824  * Demarshals a byte array.
825  *
826  * @todo Should probably demarshal to a DBusString,
827  * having memcpy() in here is Evil(tm).
828  *
829  * @param str the string containing the data
830  * @param byte_order the byte order
831  * @param pos the position in the string
832  * @param array the array
833  * @param array_len length of the demarshaled data
834  
835  * @returns #TRUE on success
836  */
837 dbus_bool_t
838 _dbus_demarshal_byte_array (const DBusString  *str,
839                             int                byte_order,
840                             int                pos,
841                             int               *new_pos,
842                             unsigned char    **array,
843                             int               *array_len)
844 {
845   int len;
846   unsigned char *retval;
847   const char *data;
848
849   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
850
851   if (len == 0)
852     {
853       *array_len = len;
854       *array = NULL;
855
856       if (new_pos)
857         *new_pos = pos;
858       
859       return TRUE;
860     }
861   
862   retval = dbus_malloc (len);
863
864   if (!retval)
865     return FALSE;
866
867   _dbus_string_get_const_data_len (str, &data, pos, len);
868
869   if (!data)
870     {
871       dbus_free (retval);
872       return FALSE;
873     }
874
875   memcpy (retval, data, len);
876
877   if (new_pos)
878     *new_pos = pos + len;
879
880   *array = retval;
881   *array_len = len;
882   
883   return TRUE;
884 }
885
886 /**
887  * Demarshals a 32 bit signed integer array.
888  *
889  * @param str the string containing the data
890  * @param byte_order the byte order
891  * @param pos the position in the string
892  * @param new_pos the new position of the string
893  * @param array the array
894  * @param array_len length of the demarshaled data
895  * @returns #TRUE on success
896  */
897 dbus_bool_t
898 _dbus_demarshal_int32_array (const DBusString  *str,
899                              int                byte_order,
900                              int                pos,
901                              int               *new_pos,
902                              dbus_int32_t     **array,
903                              int               *array_len)
904 {
905   int len, i;
906   dbus_int32_t *retval;
907   
908   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
909
910   if (len == 0)
911     {
912       *array_len = 0;
913       *array = NULL;
914
915       if (new_pos)
916         *new_pos = pos;
917       
918       return TRUE;
919     }
920   
921   retval = dbus_new (dbus_int32_t, len);
922   
923   if (!retval)
924     return FALSE;
925
926   for (i = 0; i < len; i++)
927     retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
928
929   if (new_pos)
930     *new_pos = pos;
931
932   *array_len = len;
933   *array = retval;
934   
935   return TRUE;
936 }
937
938 /**
939  * Demarshals a 32 bit unsigned integer array.
940  *
941  * @param str the string containing the data
942  * @param byte_order the byte order
943  * @param pos the position in the string
944  * @param new_pos the new position of the string
945  * @param array the array
946  * @param array_len length of the demarshaled data
947  * @returns #TRUE on success
948  */
949 dbus_bool_t
950 _dbus_demarshal_uint32_array (const DBusString  *str,
951                               int                byte_order,
952                               int                pos,
953                               int               *new_pos,
954                               dbus_uint32_t    **array,
955                               int               *array_len)
956 {
957   int len, i;
958   dbus_uint32_t *retval;
959   
960   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
961
962   if (len == 0)
963     {
964       *array_len = 0;
965       *array = NULL;
966
967       if (new_pos)
968         *new_pos = pos;
969       
970       return TRUE;
971     }
972   
973   retval = dbus_new (dbus_uint32_t, len);
974
975   if (!retval)
976     return FALSE;
977
978   for (i = 0; i < len; i++)
979     retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
980
981   if (new_pos)
982     *new_pos = pos;
983
984   *array_len = len;
985   *array = retval;
986   
987   return TRUE;  
988 }
989
990 /**
991  * Demarshals a double array.
992  *
993  * @param str the string containing the data
994  * @param byte_order the byte order
995  * @param pos the position in the string
996  * @param new_pos the new position of the string
997  * @param array the array
998  * @param array_len length of the demarshaled data
999  * @returns #TRUE on success
1000  */
1001 dbus_bool_t
1002 _dbus_demarshal_double_array (const DBusString  *str,
1003                               int                byte_order,
1004                               int                pos,
1005                               int               *new_pos,
1006                               double           **array,
1007                               int               *array_len)
1008 {
1009   int len, i;
1010   double *retval;
1011   
1012   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1013
1014   if (len == 0)
1015     {
1016       *array_len = 0;
1017       *array = NULL;
1018
1019       if (new_pos)
1020         *new_pos = pos;
1021       
1022       return TRUE;
1023     }
1024   
1025   retval = dbus_new (double, len);
1026
1027   if (!retval)
1028     return FALSE;
1029
1030   for (i = 0; i < len; i++)
1031     retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
1032
1033   if (new_pos)
1034     *new_pos = pos;
1035
1036   *array_len = len;
1037   *array = retval;
1038   
1039   return TRUE; 
1040 }
1041
1042 /**
1043  * Demarshals a string array.
1044  *
1045  * @param str the string containing the data
1046  * @param byte_order the byte order
1047  * @param pos the position in the string
1048  * @param new_pos the new position of the string
1049  * @param array the array
1050  * @param array_len length of the demarshaled data
1051  * @returns #TRUE on success
1052  */
1053 dbus_bool_t
1054 _dbus_demarshal_string_array (const DBusString   *str,
1055                               int                 byte_order,
1056                               int                 pos,
1057                               int                *new_pos,
1058                               char             ***array,
1059                               int                *array_len)
1060 {
1061   int len, i, j;
1062   char **retval;
1063
1064   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1065
1066   if (len == 0)
1067     {
1068       *array_len = 0;
1069       *array = NULL;
1070
1071       if (new_pos)
1072         *new_pos = pos;
1073       
1074       return TRUE;
1075     }
1076   
1077   retval = dbus_new (char *, len + 1);
1078
1079   if (!retval)
1080     return FALSE;
1081
1082   retval[len] = NULL;
1083   
1084   for (i = 0; i < len; i++)
1085     {
1086       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1087
1088       if (retval[i] == 0)
1089         goto error;
1090     }
1091
1092  if (new_pos)
1093     *new_pos = pos;
1094
1095  *array = retval;
1096  *array_len = len;
1097   
1098   return TRUE;
1099
1100  error:
1101   for (j = 0; j < i; j++)
1102     dbus_free (retval[i]);
1103   dbus_free (retval);
1104
1105   return FALSE;
1106 }
1107
1108 /**
1109  * Demarshals a dict
1110  *
1111  * @param str the string containing the data
1112  * @param byte_order the byte order
1113  * @param pos the position in the string
1114  * @param new_pos the new position in the string
1115  * @param dict the dict
1116  * @returns #TRUE on success.
1117  */
1118 dbus_bool_t
1119 _dbus_demarshal_dict (const DBusString *str,
1120                       int               byte_order,
1121                       int               pos,
1122                       int              *new_pos,
1123                       DBusDict       **dict)
1124 {
1125   char **keys;
1126   int i, len;
1127   
1128   *dict = dbus_dict_new ();
1129   if (!*dict)
1130     return FALSE;
1131
1132   if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &keys, &len))
1133     goto error;
1134
1135   for (i = 0; i < len; i++)
1136     {
1137       int value_type;
1138       
1139       switch ((value_type = _dbus_string_get_byte (str, pos ++)))
1140         {
1141         case DBUS_TYPE_BOOLEAN:
1142           {
1143             dbus_bool_t value;
1144
1145             value = _dbus_string_get_byte (str, pos ++);
1146
1147             if (!dbus_dict_set_boolean (*dict, keys[i], value))
1148               goto error;
1149             break;
1150           }
1151         case DBUS_TYPE_INT32:
1152           {
1153             dbus_int32_t value;
1154
1155             value = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
1156
1157             if (!dbus_dict_set_int32 (*dict, keys[i], value))
1158               goto error;
1159             
1160             break;
1161           }
1162         case DBUS_TYPE_UINT32:
1163           {
1164             dbus_uint32_t value;
1165
1166             value = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1167
1168             if (!dbus_dict_set_uint32 (*dict, keys[i], value))
1169               goto error;
1170             
1171             break;
1172           }
1173         case DBUS_TYPE_DOUBLE:
1174           {
1175             double value;
1176
1177             value = _dbus_demarshal_double (str, byte_order, pos, &pos);
1178
1179             if (!dbus_dict_set_double (*dict, keys[i], value))
1180               goto error;
1181             
1182             break;
1183           }
1184         case DBUS_TYPE_STRING:
1185           {
1186             char *value;
1187
1188             value = _dbus_demarshal_string (str, byte_order, pos, &pos);
1189
1190             if (!value)
1191               goto error;
1192
1193             if (!dbus_dict_set_string (*dict, keys[i], value))
1194               {
1195                 dbus_free (value);
1196                 goto error;
1197               }
1198
1199             dbus_free (value);
1200             
1201             break;
1202           }
1203         case DBUS_TYPE_BOOLEAN_ARRAY:
1204           {
1205             unsigned char *value;
1206             int len;
1207             
1208             if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1209               goto error;
1210
1211             if (!dbus_dict_set_boolean_array (*dict, keys[i], value, len))
1212               {
1213                 dbus_free (value);
1214                 goto error;
1215               }
1216
1217             dbus_free (value);
1218             break;
1219           }
1220         case DBUS_TYPE_INT32_ARRAY:
1221           {
1222             dbus_int32_t *value;
1223             int len;
1224             
1225             if (!_dbus_demarshal_int32_array (str, byte_order, pos, &pos, &value, &len))
1226               goto error;
1227
1228             if (!dbus_dict_set_int32_array (*dict, keys[i], value, len))
1229               {
1230                 dbus_free (value);
1231                 goto error;
1232               }
1233
1234             dbus_free (value);
1235             break;
1236           }
1237         case DBUS_TYPE_UINT32_ARRAY:
1238           {
1239             dbus_uint32_t *value;
1240             int len;
1241             
1242             if (!_dbus_demarshal_uint32_array (str, byte_order, pos, &pos, &value, &len))
1243               goto error;
1244
1245             if (!dbus_dict_set_uint32_array (*dict, keys[i], value, len))
1246               {
1247                 dbus_free (value);
1248                 goto error;
1249               }
1250
1251             dbus_free (value);
1252             break;
1253           }
1254         case DBUS_TYPE_DOUBLE_ARRAY:
1255           {
1256             double *value;
1257             int len;
1258             
1259             if (!_dbus_demarshal_double_array (str, byte_order, pos, &pos, &value, &len))
1260               goto error;
1261
1262             if (!dbus_dict_set_double_array (*dict, keys[i], value, len))
1263               {
1264                 dbus_free (value);
1265                 goto error;
1266               }
1267
1268             dbus_free (value);
1269             break;
1270           }
1271         case DBUS_TYPE_BYTE_ARRAY:
1272           {
1273             unsigned char *value;
1274             int len;
1275             
1276             if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1277               goto error;
1278
1279             if (!dbus_dict_set_byte_array (*dict, keys[i], value, len))
1280               {
1281                 dbus_free (value);
1282                 goto error;
1283               }
1284
1285             dbus_free (value);
1286             break;
1287           }
1288         case DBUS_TYPE_STRING_ARRAY:
1289           {
1290             char **value;
1291             int len;
1292             
1293             if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &value, &len))
1294               goto error;
1295
1296             if (!dbus_dict_set_string_array (*dict, keys[i], (const char **)value, len))
1297               {
1298                 dbus_free_string_array (value);
1299                 goto error;
1300               }
1301
1302             dbus_free_string_array (value);
1303             break;
1304           }
1305         default:
1306           _dbus_warn ("unknown value type %d\n", value_type);
1307           _dbus_assert_not_reached ("unknown value arg");
1308         }
1309     }
1310   
1311   dbus_free_string_array (keys);
1312   return TRUE;
1313   
1314  error:
1315   dbus_free_string_array (keys);
1316   dbus_dict_unref (*dict);
1317   
1318   return FALSE;
1319 }
1320
1321 /** 
1322  * Returns the position right after the end of an argument.  PERFORMS
1323  * NO VALIDATION WHATSOEVER. The message must have been previously
1324  * validated.
1325  *
1326  * @param str a string
1327  * @param byte_order the byte order to use
1328  * @param pos the pos where the arg starts
1329  * @param end_pos pointer where the position right
1330  * after the end position will follow
1331  * @returns TRUE if more data exists after the arg
1332  */
1333 dbus_bool_t
1334 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1335                                int               byte_order,
1336                                int               pos,
1337                                int              *end_pos)
1338 {
1339   const char *data;
1340
1341   if (pos >= _dbus_string_get_length (str))
1342     return FALSE;
1343
1344   _dbus_string_get_const_data_len (str, &data, pos, 1);
1345   
1346   switch (*data)
1347     {
1348     case DBUS_TYPE_INVALID:
1349       return FALSE;
1350       break;
1351
1352     case DBUS_TYPE_NIL:
1353       *end_pos = pos + 1;
1354       break;
1355
1356     case DBUS_TYPE_BOOLEAN:
1357       *end_pos = pos + 2;
1358       break;
1359       
1360     case DBUS_TYPE_INT32:
1361       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
1362
1363       break;
1364
1365     case DBUS_TYPE_UINT32:
1366       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
1367
1368       break;
1369
1370     case DBUS_TYPE_DOUBLE:
1371       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
1372
1373       break;
1374
1375     case DBUS_TYPE_STRING:
1376       {
1377         int len;
1378
1379         /* Demarshal the length */
1380         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1381
1382         *end_pos = pos + len + 1;
1383       }
1384       break;
1385
1386     case DBUS_TYPE_BOOLEAN_ARRAY:
1387     case DBUS_TYPE_BYTE_ARRAY:
1388       {
1389         int len;
1390
1391         /* Demarshal the length */
1392         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1393         
1394         *end_pos = pos + len;
1395       }
1396       break;
1397
1398     case DBUS_TYPE_INT32_ARRAY:
1399       {
1400         int len, new_pos;
1401
1402         /* Demarshal the length */
1403         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1404         
1405         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
1406           + (len * sizeof (dbus_int32_t));
1407       }
1408       break;
1409
1410     case DBUS_TYPE_UINT32_ARRAY:
1411       {
1412         int len, new_pos;
1413
1414         /* Demarshal the length */
1415         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1416
1417         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
1418           + (len * sizeof (dbus_uint32_t));
1419       }
1420       break;
1421
1422     case DBUS_TYPE_DOUBLE_ARRAY:
1423       {
1424         int len, new_pos;
1425         
1426         /* Demarshal the length */
1427         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1428
1429         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
1430           + (len * sizeof (double));
1431       }
1432       break;
1433       
1434     case DBUS_TYPE_STRING_ARRAY:
1435       {
1436         int len, i;
1437         
1438         /* Demarshal the length */
1439         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1440
1441         for (i = 0; i < len; i++)
1442           {
1443             int str_len;
1444             
1445             /* Demarshal string length */
1446             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1447             pos += str_len + 1;
1448           }
1449
1450         *end_pos = pos;
1451       }
1452       break;
1453
1454     case DBUS_TYPE_DICT:
1455       {
1456         int len, i;
1457
1458         /* Demarshal the length */
1459         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1460
1461         for (i = 0; i < len; i++)
1462           {
1463             int str_len;
1464             
1465             /* Demarshal string length */
1466             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1467             pos += str_len + 1;
1468           }
1469
1470         /* Now check the values */
1471         for (i = 0; i < len; i++)
1472           {
1473             if (!_dbus_marshal_get_arg_end_pos (str, byte_order, pos, &pos))
1474                 return FALSE;
1475           }
1476
1477         *end_pos = pos;
1478         
1479         break;
1480       }
1481     default:
1482       _dbus_warn ("Unknown message arg type %d\n", *data);
1483       _dbus_assert_not_reached ("Unknown message argument type\n");
1484       return FALSE;
1485     }
1486
1487   if (*end_pos > _dbus_string_get_length (str))
1488     return FALSE;
1489   
1490   return TRUE;
1491 }
1492
1493 /**
1494  * Demarshals and validates a length; returns < 0 if the validation
1495  * fails. The length is required to be small enough that
1496  * len*sizeof(double) will not overflow, and small enough to fit in a
1497  * signed integer. DOES NOT check whether the length points
1498  * beyond the end of the string, because it doesn't know the
1499  * size of array elements.
1500  *
1501  * @param str the string
1502  * @param byte_order the byte order
1503  * @param pos the unaligned string position (snap to next aligned)
1504  * @param new_pos return location for new position.
1505  */
1506 static int
1507 demarshal_and_validate_len (const DBusString *str,
1508                             int               byte_order,
1509                             int               pos,
1510                             int              *new_pos)
1511 {
1512   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1513   unsigned int len;
1514
1515   _dbus_assert (new_pos != NULL);
1516   
1517   if ((align_4 + 4) > _dbus_string_get_length (str))
1518     {
1519       _dbus_verbose ("not enough room in message for array length\n");
1520       return -1;
1521     }
1522   
1523   if (!_dbus_string_validate_nul (str, pos,
1524                                   align_4 - pos))
1525     {
1526       _dbus_verbose ("array length alignment padding not initialized to nul\n");
1527       return -1;
1528     }
1529
1530   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1531
1532   /* note that the len may be a number of doubles, so we need it to be
1533    * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1534    * sane.  We end up using ints for most sizes to avoid unsigned mess
1535    * so limit to maximum 32-bit signed int divided by at least 8, more
1536    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1537    */  
1538 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1539   if (len > MAX_ARRAY_LENGTH)
1540     {
1541       _dbus_verbose ("array length %u exceeds maximum of %u\n",
1542                      len, MAX_ARRAY_LENGTH);
1543       return -1;
1544     }
1545   else
1546     return (int) len;
1547 }
1548
1549 static dbus_bool_t
1550 validate_string (const DBusString *str,
1551                  int               pos,
1552                  int               len_without_nul,
1553                  int              *end_pos)
1554 {
1555   *end_pos = pos + len_without_nul + 1;
1556   
1557   if (*end_pos > _dbus_string_get_length (str))
1558     {
1559       _dbus_verbose ("string length outside length of the message\n");
1560       return FALSE;
1561     }
1562   
1563   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1564     {
1565       _dbus_verbose ("string arg not nul-terminated\n");
1566       return FALSE;
1567     }
1568   
1569   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1570     {
1571       _dbus_verbose ("string is not valid UTF-8\n");
1572       return FALSE;
1573     }
1574
1575   return TRUE;
1576 }   
1577
1578 /** 
1579  * Validates an argument, checking that it is well-formed, for example
1580  * no ludicrous length fields, strings are nul-terminated, etc.
1581  * Returns the end position of the argument in end_pos, and
1582  * returns #TRUE if a valid arg begins at "pos"
1583  *
1584  * @todo security: need to audit this function.
1585  * 
1586  * @param str a string
1587  * @param byte_order the byte order to use
1588  * @param pos the pos where the arg starts (offset of its typecode)
1589  * @param end_pos pointer where the position right
1590  * after the end position will follow
1591  * @returns #TRUE if the arg is valid.
1592  */
1593 dbus_bool_t
1594 _dbus_marshal_validate_arg (const DBusString *str,
1595                             int               byte_order,
1596                             int               pos,
1597                             int              *end_pos)
1598 {
1599   const char *data;
1600
1601   if (pos >= _dbus_string_get_length (str))
1602     return FALSE;
1603
1604   _dbus_string_get_const_data_len (str, &data, pos, 1);
1605   
1606   switch (*data)
1607     {
1608     case DBUS_TYPE_INVALID:
1609       return FALSE;
1610       break;
1611
1612     case DBUS_TYPE_NIL:
1613       *end_pos = pos + 1;
1614       break;
1615
1616     case DBUS_TYPE_BOOLEAN:
1617       {
1618         unsigned char c;
1619
1620         if (2 > _dbus_string_get_length (str) - pos)
1621           {
1622             _dbus_verbose ("no room for boolean value\n");
1623             return FALSE;
1624           }
1625         
1626         c = _dbus_string_get_byte (str, pos + 1);
1627
1628         if (c != 0 && c != 1)
1629           {
1630             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1631             return FALSE;
1632           }
1633         
1634       *end_pos = pos + 2;
1635       break;
1636       }
1637     case DBUS_TYPE_INT32:
1638     case DBUS_TYPE_UINT32:
1639       {
1640         int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1641         
1642         if (!_dbus_string_validate_nul (str, pos + 1,
1643                                         align_4 - pos - 1))
1644           {
1645             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1646             return FALSE;
1647           }
1648
1649         *end_pos = align_4 + 4;
1650       }
1651       break;
1652
1653     case DBUS_TYPE_DOUBLE:
1654       {
1655         int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1656
1657         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1658         
1659         if (!_dbus_string_validate_nul (str, pos + 1,
1660                                         align_8 - pos - 1))
1661           {
1662             _dbus_verbose ("double alignment padding not initialized to nul\n");
1663             return FALSE;
1664           }
1665
1666         *end_pos = align_8 + 8;
1667       }
1668       break;
1669
1670     case DBUS_TYPE_STRING:
1671       {
1672         int len;
1673
1674         /* Demarshal the length, which does NOT include
1675          * nul termination
1676          */
1677         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1678         if (len < 0)
1679           return FALSE;
1680
1681         if (!validate_string (str, pos, len, end_pos))
1682           return FALSE;
1683       }
1684       break;
1685
1686     case DBUS_TYPE_BOOLEAN_ARRAY:
1687       {
1688         int len, i;
1689
1690         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1691         if (len < 0)
1692           return FALSE;
1693
1694         if (len > _dbus_string_get_length (str) - pos)
1695           {
1696             _dbus_verbose ("boolean array length outside length of the message\n");
1697             return FALSE;
1698           }
1699         
1700         i = 0;
1701         while (i < len)
1702           {
1703             unsigned char c = _dbus_string_get_byte (str, pos + i);
1704
1705             if (c != 0 && c != 1)
1706               {
1707                 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1708                 return FALSE;
1709               }
1710
1711             i++;
1712           }
1713         *end_pos = pos + len;
1714         break;
1715       }
1716     case DBUS_TYPE_BYTE_ARRAY:
1717       {
1718         int len;
1719
1720         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1721         if (len < 0)
1722           return FALSE;
1723         
1724         *end_pos = pos + len;
1725       }
1726       break;
1727
1728     case DBUS_TYPE_INT32_ARRAY:
1729     case DBUS_TYPE_UINT32_ARRAY:
1730       {
1731         int len;
1732
1733         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1734         if (len < 0)
1735           return FALSE;
1736
1737         _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1738         
1739         *end_pos = pos + len * 4;
1740       }
1741       break;
1742
1743     case DBUS_TYPE_DOUBLE_ARRAY:
1744       {
1745         int len;
1746         int align_8;
1747
1748         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1749         if (len < 0)
1750           return FALSE;
1751
1752         if (len == 0)
1753           *end_pos = pos;
1754         else
1755           {
1756             align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1757             if (!_dbus_string_validate_nul (str, pos,
1758                                             align_8 - pos))
1759               {
1760                 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1761                 return FALSE;
1762               }
1763
1764             *end_pos = align_8 + len * 8;
1765           }
1766       }
1767       break;
1768       
1769     case DBUS_TYPE_STRING_ARRAY:
1770       {
1771         int len;
1772         int i;
1773         
1774         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1775         if (len < 0)
1776           return FALSE;
1777
1778         for (i = 0; i < len; i++)
1779           {
1780             int str_len;
1781             
1782             str_len = demarshal_and_validate_len (str, byte_order,
1783                                                   pos, &pos);
1784             if (str_len < 0)
1785               return FALSE;
1786
1787             if (!validate_string (str, pos, str_len, &pos))
1788               return FALSE;            
1789           }
1790
1791         *end_pos = pos;
1792       }
1793       break;
1794
1795       case DBUS_TYPE_DICT:
1796         {
1797           int len;
1798           int i;
1799
1800           len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1801           if (len < 0)
1802             return FALSE;
1803           
1804           for (i = 0; i < len; i++)
1805             {
1806               int str_len;
1807               
1808               str_len = demarshal_and_validate_len (str, byte_order,
1809                                                     pos, &pos);
1810               if (str_len < 0)
1811                 return FALSE;
1812               
1813               if (!validate_string (str, pos, str_len, &pos))
1814                 return FALSE;            
1815             }
1816
1817           /* Now validate each argument */
1818           for (i = 0; i < len; i++)
1819             {
1820               if (pos >= _dbus_string_get_length (str))
1821                 {
1822                   _dbus_verbose ("not enough values in dict\n");
1823                   return FALSE;
1824                 }
1825
1826               if (_dbus_string_get_byte (str, pos) == DBUS_TYPE_NIL)
1827                 {
1828                   _dbus_verbose ("can't have NIL values in dicts\n");
1829                   return FALSE;
1830                 }
1831               
1832               if (!_dbus_marshal_validate_arg (str, byte_order, pos, &pos))
1833                 return FALSE;
1834             }
1835
1836           *end_pos = pos;
1837
1838           break;
1839         }
1840         
1841     default:
1842       _dbus_verbose ("Unknown message arg type %d\n", *data);
1843       return FALSE;
1844     }
1845
1846   if (*end_pos > _dbus_string_get_length (str))
1847     return FALSE;
1848   
1849   return TRUE;
1850 }
1851
1852
1853 /**
1854  * If in verbose mode, print a block of binary data.
1855  *
1856  * @todo right now it prints even if not in verbose mode
1857  * 
1858  * @param data the data
1859  * @param len the length of the data
1860  */
1861 void
1862 _dbus_verbose_bytes (const unsigned char *data,
1863                      int                  len)
1864 {
1865   int i;
1866   const unsigned char *aligned;
1867
1868   _dbus_assert (len >= 0);
1869   
1870   /* Print blanks on first row if appropriate */
1871   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1872   if (aligned > data)
1873     aligned -= 4;
1874   _dbus_assert (aligned <= data);
1875
1876   if (aligned != data)
1877     {
1878       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1879       while (aligned != data)
1880         {
1881           _dbus_verbose ("    ");
1882           ++aligned;
1883         }
1884     }
1885
1886   /* now print the bytes */
1887   i = 0;
1888   while (i < len)
1889     {
1890       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1891         {
1892           _dbus_verbose ("%4d\t%p: ",
1893                    i, &data[i]);
1894         }
1895       
1896       if (data[i] >= 32 &&
1897           data[i] <= 126)
1898         _dbus_verbose (" '%c' ", data[i]);
1899       else
1900         _dbus_verbose ("0x%s%x ",
1901                  data[i] <= 0xf ? "0" : "", data[i]);
1902
1903       ++i;
1904
1905       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1906         {
1907           if (i > 3)
1908             _dbus_verbose ("BE: %d LE: %d",
1909                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1910                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1911
1912           if (i > 7 && 
1913               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1914             {
1915               _dbus_verbose (" dbl: %g",
1916                              *(double*)&data[i-8]);
1917             }
1918           
1919           _dbus_verbose ("\n");
1920         }
1921     }
1922
1923   _dbus_verbose ("\n");
1924 }
1925
1926 /**
1927  * Dump the given part of the string to verbose log.
1928  *
1929  * @param str the string
1930  * @param start the start of range to dump
1931  * @param len length of range
1932  */
1933 void
1934 _dbus_verbose_bytes_of_string (const DBusString    *str,
1935                                int                  start,
1936                                int                  len)
1937 {
1938   const char *d;
1939   int real_len;
1940
1941   real_len = _dbus_string_get_length (str);
1942
1943   _dbus_assert (start >= 0);
1944   
1945   if (start > real_len)
1946     {
1947       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1948                      start, len, real_len);
1949       return;
1950     }
1951
1952   if ((start + len) > real_len)
1953     {
1954       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1955                      start, len, real_len);
1956       len = real_len - start;
1957     }
1958   
1959   
1960   _dbus_string_get_const_data_len (str, &d, start, len);
1961
1962   _dbus_verbose_bytes (d, len);
1963 }
1964
1965 /** @} */
1966
1967 #ifdef DBUS_BUILD_TESTS
1968 #include "dbus-test.h"
1969 #include <stdio.h>
1970
1971 dbus_bool_t
1972 _dbus_marshal_test (void)
1973 {
1974   DBusString str;
1975   char *tmp1, *tmp2;
1976   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1977   int pos = 0, i, len;
1978   dbus_bool_t our_bool;
1979   dbus_int32_t our_int;
1980   dbus_uint32_t our_uint;
1981   double our_double;
1982   const char *our_string;
1983   const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
1984   const unsigned char *our_boolean_array;
1985   const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
1986   const dbus_int32_t *our_int32_array;
1987   const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
1988   const dbus_uint32_t *our_uint32_array;
1989   const double double_array[] = { 3.14159, 1.2345, 6.7890 };
1990   const double *our_double_array;
1991   const char *string_array[] = { "This", "Is", "A", "Test" };
1992   const char **our_string_array;
1993   DBusDict *dict;
1994   
1995   if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1996     _dbus_assert_not_reached ("failed to init string");
1997
1998   /* Marshal doubles */
1999   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2000     _dbus_assert_not_reached ("could not marshal double value");
2001   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2002     _dbus_assert_not_reached ("demarshal failed");
2003
2004   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2005     _dbus_assert_not_reached ("could not marshal double value");
2006   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2007     _dbus_assert_not_reached ("demarshal failed");
2008   
2009   /* Marshal signed integers */
2010   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2011     _dbus_assert_not_reached ("could not marshal signed integer value");
2012   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2013     _dbus_assert_not_reached ("demarshal failed");
2014
2015   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2016     _dbus_assert_not_reached ("could not marshal signed integer value");
2017   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2018     _dbus_assert_not_reached ("demarshal failed");
2019   
2020   /* Marshal unsigned integers */
2021   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2022     _dbus_assert_not_reached ("could not marshal signed integer value");
2023   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2024     _dbus_assert_not_reached ("demarshal failed");
2025   
2026   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2027     _dbus_assert_not_reached ("could not marshal signed integer value");
2028   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2029     _dbus_assert_not_reached ("demarshal failed");
2030
2031   /* Marshal strings */
2032   tmp1 = "This is the dbus test string";
2033   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2034     _dbus_assert_not_reached ("could not marshal string");
2035   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2036   if (!strcmp (tmp1, tmp2) == 0)
2037     _dbus_assert_not_reached ("demarshal failed");
2038   dbus_free (tmp2);
2039
2040   tmp1 = "This is the dbus test string";
2041   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2042     _dbus_assert_not_reached ("could not marshal string");
2043   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2044   if (!strcmp (tmp1, tmp2) == 0)
2045     _dbus_assert_not_reached ("demarshal failed");
2046   dbus_free (tmp2);
2047
2048   /* Marshal signed integer arrays */
2049   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2050     _dbus_assert_not_reached ("could not marshal integer array");
2051   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2052     _dbus_assert_not_reached ("could not demarshal integer array");
2053
2054   if (len != 3)
2055     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2056   dbus_free (array2);
2057   
2058
2059   /* Marshal dicts */
2060   dict = dbus_dict_new ();
2061
2062   if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
2063     _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
2064   
2065   if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
2066     _dbus_assert_not_reached ("could not add boolean value");
2067
2068   if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
2069     _dbus_assert_not_reached ("could not add int32 value");
2070
2071   if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
2072     _dbus_assert_not_reached ("could not add uint32 value");
2073
2074   if (!dbus_dict_set_double (dict, "double", 3.14159))
2075     _dbus_assert_not_reached ("could not add double value");
2076
2077   if (!dbus_dict_set_string (dict, "string", "test string"))
2078     _dbus_assert_not_reached ("could not add string value");
2079
2080   if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
2081     _dbus_assert_not_reached ("could not add boolean array");
2082
2083   if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
2084     _dbus_assert_not_reached ("could not add int32 array");
2085
2086   if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
2087     _dbus_assert_not_reached ("could not add uint32 array");
2088
2089   if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
2090     _dbus_assert_not_reached ("could not add double array");
2091
2092   if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
2093     _dbus_assert_not_reached ("could not add string array");
2094
2095   if (!_dbus_marshal_dict (&str, DBUS_BIG_ENDIAN, dict))
2096     _dbus_assert_not_reached ("could not marshal dict");
2097   
2098   dbus_dict_unref (dict);
2099   
2100   if (!_dbus_demarshal_dict (&str, DBUS_BIG_ENDIAN, pos, &pos, &dict))
2101     _dbus_assert_not_reached ("could not demarshal dict");
2102
2103   if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
2104       !our_bool)
2105     _dbus_assert_not_reached ("could not get boolean value");
2106
2107   if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
2108     _dbus_assert_not_reached ("could not get int32 value or int32 values differ");
2109   
2110   if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
2111     _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
2112
2113   if (!dbus_dict_get_double (dict, "double", &our_double)
2114       || our_double != 3.14159)
2115      _dbus_assert_not_reached ("could not get double value or double values differ");
2116
2117   if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
2118     _dbus_assert_not_reached ("could not get string value or string values differ");
2119
2120   if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
2121       len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
2122     _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
2123
2124   if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
2125       len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
2126     _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
2127
2128   if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
2129       len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
2130     _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
2131
2132   if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
2133       len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
2134     _dbus_assert_not_reached ("could not get double array value or double array values differ");
2135
2136   if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
2137     _dbus_assert_not_reached ("could not get string array value");
2138
2139   if (len != 4)
2140     _dbus_assert_not_reached ("string array lengths differ");
2141
2142   for (i = 0; i < len; i++)
2143     {
2144       if (strcmp (our_string_array[i], string_array[i]) != 0)
2145         _dbus_assert_not_reached ("string array fields differ");
2146     }
2147   
2148   dbus_dict_unref (dict);
2149   
2150   _dbus_string_free (&str);
2151   
2152       
2153   return TRUE;
2154 }
2155
2156 #endif /* DBUS_BUILD_TESTS */