2003-03-26 Anders Carlsson <andersca@codefactory.se>
[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 new_pos the new position of the string
833  * @param array the array
834  * @param array_len length of the demarshaled data
835  
836  * @returns #TRUE on success
837  */
838 dbus_bool_t
839 _dbus_demarshal_byte_array (const DBusString  *str,
840                             int                byte_order,
841                             int                pos,
842                             int               *new_pos,
843                             unsigned char    **array,
844                             int               *array_len)
845 {
846   int len;
847   unsigned char *retval;
848   const char *data;
849
850   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
851
852   if (len == 0)
853     {
854       *array_len = len;
855       *array = NULL;
856
857       if (new_pos)
858         *new_pos = pos;
859       
860       return TRUE;
861     }
862   
863   retval = dbus_malloc (len);
864
865   if (!retval)
866     return FALSE;
867
868   _dbus_string_get_const_data_len (str, &data, pos, len);
869
870   if (!data)
871     {
872       dbus_free (retval);
873       return FALSE;
874     }
875
876   memcpy (retval, data, len);
877
878   if (new_pos)
879     *new_pos = pos + len;
880
881   *array = retval;
882   *array_len = len;
883   
884   return TRUE;
885 }
886
887 /**
888  * Demarshals a 32 bit signed integer array.
889  *
890  * @param str the string containing the data
891  * @param byte_order the byte order
892  * @param pos the position in the string
893  * @param new_pos the new position of the string
894  * @param array the array
895  * @param array_len length of the demarshaled data
896  * @returns #TRUE on success
897  */
898 dbus_bool_t
899 _dbus_demarshal_int32_array (const DBusString  *str,
900                              int                byte_order,
901                              int                pos,
902                              int               *new_pos,
903                              dbus_int32_t     **array,
904                              int               *array_len)
905 {
906   int len, i;
907   dbus_int32_t *retval;
908   
909   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
910
911   if (len == 0)
912     {
913       *array_len = 0;
914       *array = NULL;
915
916       if (new_pos)
917         *new_pos = pos;
918       
919       return TRUE;
920     }
921   
922   retval = dbus_new (dbus_int32_t, len);
923   
924   if (!retval)
925     return FALSE;
926
927   for (i = 0; i < len; i++)
928     retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
929
930   if (new_pos)
931     *new_pos = pos;
932
933   *array_len = len;
934   *array = retval;
935   
936   return TRUE;
937 }
938
939 /**
940  * Demarshals a 32 bit unsigned integer array.
941  *
942  * @param str the string containing the data
943  * @param byte_order the byte order
944  * @param pos the position in the string
945  * @param new_pos the new position of the string
946  * @param array the array
947  * @param array_len length of the demarshaled data
948  * @returns #TRUE on success
949  */
950 dbus_bool_t
951 _dbus_demarshal_uint32_array (const DBusString  *str,
952                               int                byte_order,
953                               int                pos,
954                               int               *new_pos,
955                               dbus_uint32_t    **array,
956                               int               *array_len)
957 {
958   int len, i;
959   dbus_uint32_t *retval;
960   
961   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
962
963   if (len == 0)
964     {
965       *array_len = 0;
966       *array = NULL;
967
968       if (new_pos)
969         *new_pos = pos;
970       
971       return TRUE;
972     }
973   
974   retval = dbus_new (dbus_uint32_t, len);
975
976   if (!retval)
977     return FALSE;
978
979   for (i = 0; i < len; i++)
980     retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
981
982   if (new_pos)
983     *new_pos = pos;
984
985   *array_len = len;
986   *array = retval;
987   
988   return TRUE;  
989 }
990
991 /**
992  * Demarshals a double array.
993  *
994  * @param str the string containing the data
995  * @param byte_order the byte order
996  * @param pos the position in the string
997  * @param new_pos the new position of the string
998  * @param array the array
999  * @param array_len length of the demarshaled data
1000  * @returns #TRUE on success
1001  */
1002 dbus_bool_t
1003 _dbus_demarshal_double_array (const DBusString  *str,
1004                               int                byte_order,
1005                               int                pos,
1006                               int               *new_pos,
1007                               double           **array,
1008                               int               *array_len)
1009 {
1010   int len, i;
1011   double *retval;
1012   
1013   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1014
1015   if (len == 0)
1016     {
1017       *array_len = 0;
1018       *array = NULL;
1019
1020       if (new_pos)
1021         *new_pos = pos;
1022       
1023       return TRUE;
1024     }
1025   
1026   retval = dbus_new (double, len);
1027
1028   if (!retval)
1029     return FALSE;
1030
1031   for (i = 0; i < len; i++)
1032     retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
1033
1034   if (new_pos)
1035     *new_pos = pos;
1036
1037   *array_len = len;
1038   *array = retval;
1039   
1040   return TRUE; 
1041 }
1042
1043 /**
1044  * Demarshals a string array.
1045  *
1046  * @param str the string containing the data
1047  * @param byte_order the byte order
1048  * @param pos the position in the string
1049  * @param new_pos the new position of the string
1050  * @param array the array
1051  * @param array_len length of the demarshaled data
1052  * @returns #TRUE on success
1053  */
1054 dbus_bool_t
1055 _dbus_demarshal_string_array (const DBusString   *str,
1056                               int                 byte_order,
1057                               int                 pos,
1058                               int                *new_pos,
1059                               char             ***array,
1060                               int                *array_len)
1061 {
1062   int len, i, j;
1063   char **retval;
1064
1065   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1066
1067   if (len == 0)
1068     {
1069       *array_len = 0;
1070       *array = NULL;
1071
1072       if (new_pos)
1073         *new_pos = pos;
1074       
1075       return TRUE;
1076     }
1077   
1078   retval = dbus_new (char *, len + 1);
1079
1080   if (!retval)
1081     return FALSE;
1082
1083   retval[len] = NULL;
1084   
1085   for (i = 0; i < len; i++)
1086     {
1087       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1088
1089       if (retval[i] == 0)
1090         goto error;
1091     }
1092
1093  if (new_pos)
1094     *new_pos = pos;
1095
1096  *array = retval;
1097  *array_len = len;
1098   
1099   return TRUE;
1100
1101  error:
1102   for (j = 0; j < i; j++)
1103     dbus_free (retval[i]);
1104   dbus_free (retval);
1105
1106   return FALSE;
1107 }
1108
1109 /**
1110  * Demarshals a dict
1111  *
1112  * @param str the string containing the data
1113  * @param byte_order the byte order
1114  * @param pos the position in the string
1115  * @param new_pos the new position in the string
1116  * @param dict the dict
1117  * @returns #TRUE on success.
1118  */
1119 dbus_bool_t
1120 _dbus_demarshal_dict (const DBusString *str,
1121                       int               byte_order,
1122                       int               pos,
1123                       int              *new_pos,
1124                       DBusDict       **dict)
1125 {
1126   char **keys;
1127   int i, len;
1128   
1129   *dict = dbus_dict_new ();
1130   if (!*dict)
1131     return FALSE;
1132
1133   if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &keys, &len))
1134     goto error;
1135
1136   for (i = 0; i < len; i++)
1137     {
1138       int value_type;
1139       
1140       switch ((value_type = _dbus_string_get_byte (str, pos ++)))
1141         {
1142         case DBUS_TYPE_BOOLEAN:
1143           {
1144             dbus_bool_t value;
1145
1146             value = _dbus_string_get_byte (str, pos ++);
1147
1148             if (!dbus_dict_set_boolean (*dict, keys[i], value))
1149               goto error;
1150             break;
1151           }
1152         case DBUS_TYPE_INT32:
1153           {
1154             dbus_int32_t value;
1155
1156             value = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
1157
1158             if (!dbus_dict_set_int32 (*dict, keys[i], value))
1159               goto error;
1160             
1161             break;
1162           }
1163         case DBUS_TYPE_UINT32:
1164           {
1165             dbus_uint32_t value;
1166
1167             value = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1168
1169             if (!dbus_dict_set_uint32 (*dict, keys[i], value))
1170               goto error;
1171             
1172             break;
1173           }
1174         case DBUS_TYPE_DOUBLE:
1175           {
1176             double value;
1177
1178             value = _dbus_demarshal_double (str, byte_order, pos, &pos);
1179
1180             if (!dbus_dict_set_double (*dict, keys[i], value))
1181               goto error;
1182             
1183             break;
1184           }
1185         case DBUS_TYPE_STRING:
1186           {
1187             char *value;
1188
1189             value = _dbus_demarshal_string (str, byte_order, pos, &pos);
1190
1191             if (!value)
1192               goto error;
1193
1194             if (!dbus_dict_set_string (*dict, keys[i], value))
1195               {
1196                 dbus_free (value);
1197                 goto error;
1198               }
1199
1200             dbus_free (value);
1201             
1202             break;
1203           }
1204         case DBUS_TYPE_BOOLEAN_ARRAY:
1205           {
1206             unsigned char *value;
1207             int len;
1208             
1209             if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1210               goto error;
1211
1212             if (!dbus_dict_set_boolean_array (*dict, keys[i], value, len))
1213               {
1214                 dbus_free (value);
1215                 goto error;
1216               }
1217
1218             dbus_free (value);
1219             break;
1220           }
1221         case DBUS_TYPE_INT32_ARRAY:
1222           {
1223             dbus_int32_t *value;
1224             int len;
1225             
1226             if (!_dbus_demarshal_int32_array (str, byte_order, pos, &pos, &value, &len))
1227               goto error;
1228
1229             if (!dbus_dict_set_int32_array (*dict, keys[i], value, len))
1230               {
1231                 dbus_free (value);
1232                 goto error;
1233               }
1234
1235             dbus_free (value);
1236             break;
1237           }
1238         case DBUS_TYPE_UINT32_ARRAY:
1239           {
1240             dbus_uint32_t *value;
1241             int len;
1242             
1243             if (!_dbus_demarshal_uint32_array (str, byte_order, pos, &pos, &value, &len))
1244               goto error;
1245
1246             if (!dbus_dict_set_uint32_array (*dict, keys[i], value, len))
1247               {
1248                 dbus_free (value);
1249                 goto error;
1250               }
1251
1252             dbus_free (value);
1253             break;
1254           }
1255         case DBUS_TYPE_DOUBLE_ARRAY:
1256           {
1257             double *value;
1258             int len;
1259             
1260             if (!_dbus_demarshal_double_array (str, byte_order, pos, &pos, &value, &len))
1261               goto error;
1262
1263             if (!dbus_dict_set_double_array (*dict, keys[i], value, len))
1264               {
1265                 dbus_free (value);
1266                 goto error;
1267               }
1268
1269             dbus_free (value);
1270             break;
1271           }
1272         case DBUS_TYPE_BYTE_ARRAY:
1273           {
1274             unsigned char *value;
1275             int len;
1276             
1277             if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1278               goto error;
1279
1280             if (!dbus_dict_set_byte_array (*dict, keys[i], value, len))
1281               {
1282                 dbus_free (value);
1283                 goto error;
1284               }
1285
1286             dbus_free (value);
1287             break;
1288           }
1289         case DBUS_TYPE_STRING_ARRAY:
1290           {
1291             char **value;
1292             int len;
1293             
1294             if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &value, &len))
1295               goto error;
1296
1297             if (!dbus_dict_set_string_array (*dict, keys[i], (const char **)value, len))
1298               {
1299                 dbus_free_string_array (value);
1300                 goto error;
1301               }
1302
1303             dbus_free_string_array (value);
1304             break;
1305           }
1306         default:
1307           _dbus_warn ("unknown value type %d\n", value_type);
1308           _dbus_assert_not_reached ("unknown value arg");
1309         }
1310     }
1311   
1312   dbus_free_string_array (keys);
1313   return TRUE;
1314   
1315  error:
1316   dbus_free_string_array (keys);
1317   dbus_dict_unref (*dict);
1318   
1319   return FALSE;
1320 }
1321
1322 /** 
1323  * Returns the position right after the end of an argument.  PERFORMS
1324  * NO VALIDATION WHATSOEVER. The message must have been previously
1325  * validated.
1326  *
1327  * @param str a string
1328  * @param byte_order the byte order to use
1329  * @param pos the pos where the arg starts
1330  * @param end_pos pointer where the position right
1331  * after the end position will follow
1332  * @returns TRUE if more data exists after the arg
1333  */
1334 dbus_bool_t
1335 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1336                                int               byte_order,
1337                                int               pos,
1338                                int              *end_pos)
1339 {
1340   const char *data;
1341
1342   if (pos >= _dbus_string_get_length (str))
1343     return FALSE;
1344
1345   _dbus_string_get_const_data_len (str, &data, pos, 1);
1346   
1347   switch (*data)
1348     {
1349     case DBUS_TYPE_INVALID:
1350       return FALSE;
1351       break;
1352
1353     case DBUS_TYPE_NIL:
1354       *end_pos = pos + 1;
1355       break;
1356
1357     case DBUS_TYPE_BOOLEAN:
1358       *end_pos = pos + 2;
1359       break;
1360       
1361     case DBUS_TYPE_INT32:
1362       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
1363
1364       break;
1365
1366     case DBUS_TYPE_UINT32:
1367       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
1368
1369       break;
1370
1371     case DBUS_TYPE_DOUBLE:
1372       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
1373
1374       break;
1375
1376     case DBUS_TYPE_STRING:
1377       {
1378         int len;
1379
1380         /* Demarshal the length */
1381         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1382
1383         *end_pos = pos + len + 1;
1384       }
1385       break;
1386
1387     case DBUS_TYPE_BOOLEAN_ARRAY:
1388     case DBUS_TYPE_BYTE_ARRAY:
1389       {
1390         int len;
1391
1392         /* Demarshal the length */
1393         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1394         
1395         *end_pos = pos + len;
1396       }
1397       break;
1398
1399     case DBUS_TYPE_INT32_ARRAY:
1400       {
1401         int len, new_pos;
1402
1403         /* Demarshal the length */
1404         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1405         
1406         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
1407           + (len * sizeof (dbus_int32_t));
1408       }
1409       break;
1410
1411     case DBUS_TYPE_UINT32_ARRAY:
1412       {
1413         int len, new_pos;
1414
1415         /* Demarshal the length */
1416         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1417
1418         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
1419           + (len * sizeof (dbus_uint32_t));
1420       }
1421       break;
1422
1423     case DBUS_TYPE_DOUBLE_ARRAY:
1424       {
1425         int len, new_pos;
1426         
1427         /* Demarshal the length */
1428         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1429
1430         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
1431           + (len * sizeof (double));
1432       }
1433       break;
1434       
1435     case DBUS_TYPE_STRING_ARRAY:
1436       {
1437         int len, i;
1438         
1439         /* Demarshal the length */
1440         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1441
1442         for (i = 0; i < len; i++)
1443           {
1444             int str_len;
1445             
1446             /* Demarshal string length */
1447             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1448             pos += str_len + 1;
1449           }
1450
1451         *end_pos = pos;
1452       }
1453       break;
1454
1455     case DBUS_TYPE_DICT:
1456       {
1457         int len, i;
1458
1459         /* Demarshal the length */
1460         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1461
1462         for (i = 0; i < len; i++)
1463           {
1464             int str_len;
1465             
1466             /* Demarshal string length */
1467             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1468             pos += str_len + 1;
1469           }
1470
1471         /* Now check the values */
1472         for (i = 0; i < len; i++)
1473           {
1474             if (!_dbus_marshal_get_arg_end_pos (str, byte_order, pos, &pos))
1475                 return FALSE;
1476           }
1477
1478         *end_pos = pos;
1479         
1480         break;
1481       }
1482     default:
1483       _dbus_warn ("Unknown message arg type %d\n", *data);
1484       _dbus_assert_not_reached ("Unknown message argument type\n");
1485       return FALSE;
1486     }
1487
1488   if (*end_pos > _dbus_string_get_length (str))
1489     return FALSE;
1490   
1491   return TRUE;
1492 }
1493
1494 /**
1495  * Demarshals and validates a length; returns < 0 if the validation
1496  * fails. The length is required to be small enough that
1497  * len*sizeof(double) will not overflow, and small enough to fit in a
1498  * signed integer. DOES NOT check whether the length points
1499  * beyond the end of the string, because it doesn't know the
1500  * size of array elements.
1501  *
1502  * @param str the string
1503  * @param byte_order the byte order
1504  * @param pos the unaligned string position (snap to next aligned)
1505  * @param new_pos return location for new position.
1506  */
1507 static int
1508 demarshal_and_validate_len (const DBusString *str,
1509                             int               byte_order,
1510                             int               pos,
1511                             int              *new_pos)
1512 {
1513   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1514   unsigned int len;
1515
1516   _dbus_assert (new_pos != NULL);
1517   
1518   if ((align_4 + 4) > _dbus_string_get_length (str))
1519     {
1520       _dbus_verbose ("not enough room in message for array length\n");
1521       return -1;
1522     }
1523   
1524   if (!_dbus_string_validate_nul (str, pos,
1525                                   align_4 - pos))
1526     {
1527       _dbus_verbose ("array length alignment padding not initialized to nul\n");
1528       return -1;
1529     }
1530
1531   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1532
1533   /* note that the len may be a number of doubles, so we need it to be
1534    * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1535    * sane.  We end up using ints for most sizes to avoid unsigned mess
1536    * so limit to maximum 32-bit signed int divided by at least 8, more
1537    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1538    */  
1539 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1540   if (len > MAX_ARRAY_LENGTH)
1541     {
1542       _dbus_verbose ("array length %u exceeds maximum of %u\n",
1543                      len, MAX_ARRAY_LENGTH);
1544       return -1;
1545     }
1546   else
1547     return (int) len;
1548 }
1549
1550 static dbus_bool_t
1551 validate_string (const DBusString *str,
1552                  int               pos,
1553                  int               len_without_nul,
1554                  int              *end_pos)
1555 {
1556   *end_pos = pos + len_without_nul + 1;
1557   
1558   if (*end_pos > _dbus_string_get_length (str))
1559     {
1560       _dbus_verbose ("string length outside length of the message\n");
1561       return FALSE;
1562     }
1563   
1564   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1565     {
1566       _dbus_verbose ("string arg not nul-terminated\n");
1567       return FALSE;
1568     }
1569   
1570   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1571     {
1572       _dbus_verbose ("string is not valid UTF-8\n");
1573       return FALSE;
1574     }
1575
1576   return TRUE;
1577 }   
1578
1579 /** 
1580  * Validates an argument, checking that it is well-formed, for example
1581  * no ludicrous length fields, strings are nul-terminated, etc.
1582  * Returns the end position of the argument in end_pos, and
1583  * returns #TRUE if a valid arg begins at "pos"
1584  *
1585  * @todo security: need to audit this function.
1586  * 
1587  * @param str a string
1588  * @param byte_order the byte order to use
1589  * @param pos the pos where the arg starts (offset of its typecode)
1590  * @param end_pos pointer where the position right
1591  * after the end position will follow
1592  * @returns #TRUE if the arg is valid.
1593  */
1594 dbus_bool_t
1595 _dbus_marshal_validate_arg (const DBusString *str,
1596                             int               byte_order,
1597                             int               pos,
1598                             int              *end_pos)
1599 {
1600   const char *data;
1601
1602   if (pos >= _dbus_string_get_length (str))
1603     return FALSE;
1604
1605   _dbus_string_get_const_data_len (str, &data, pos, 1);
1606   
1607   switch (*data)
1608     {
1609     case DBUS_TYPE_INVALID:
1610       return FALSE;
1611       break;
1612
1613     case DBUS_TYPE_NIL:
1614       *end_pos = pos + 1;
1615       break;
1616
1617     case DBUS_TYPE_BOOLEAN:
1618       {
1619         unsigned char c;
1620
1621         if (2 > _dbus_string_get_length (str) - pos)
1622           {
1623             _dbus_verbose ("no room for boolean value\n");
1624             return FALSE;
1625           }
1626         
1627         c = _dbus_string_get_byte (str, pos + 1);
1628
1629         if (c != 0 && c != 1)
1630           {
1631             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1632             return FALSE;
1633           }
1634         
1635       *end_pos = pos + 2;
1636       break;
1637       }
1638     case DBUS_TYPE_INT32:
1639     case DBUS_TYPE_UINT32:
1640       {
1641         int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1642         
1643         if (!_dbus_string_validate_nul (str, pos + 1,
1644                                         align_4 - pos - 1))
1645           {
1646             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1647             return FALSE;
1648           }
1649
1650         *end_pos = align_4 + 4;
1651       }
1652       break;
1653
1654     case DBUS_TYPE_DOUBLE:
1655       {
1656         int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1657
1658         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1659         
1660         if (!_dbus_string_validate_nul (str, pos + 1,
1661                                         align_8 - pos - 1))
1662           {
1663             _dbus_verbose ("double alignment padding not initialized to nul\n");
1664             return FALSE;
1665           }
1666
1667         *end_pos = align_8 + 8;
1668       }
1669       break;
1670
1671     case DBUS_TYPE_STRING:
1672       {
1673         int len;
1674
1675         /* Demarshal the length, which does NOT include
1676          * nul termination
1677          */
1678         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1679         if (len < 0)
1680           return FALSE;
1681
1682         if (!validate_string (str, pos, len, end_pos))
1683           return FALSE;
1684       }
1685       break;
1686
1687     case DBUS_TYPE_BOOLEAN_ARRAY:
1688       {
1689         int len, i;
1690
1691         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1692         if (len < 0)
1693           return FALSE;
1694
1695         if (len > _dbus_string_get_length (str) - pos)
1696           {
1697             _dbus_verbose ("boolean array length outside length of the message\n");
1698             return FALSE;
1699           }
1700         
1701         i = 0;
1702         while (i < len)
1703           {
1704             unsigned char c = _dbus_string_get_byte (str, pos + i);
1705
1706             if (c != 0 && c != 1)
1707               {
1708                 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1709                 return FALSE;
1710               }
1711
1712             i++;
1713           }
1714         *end_pos = pos + len;
1715         break;
1716       }
1717     case DBUS_TYPE_BYTE_ARRAY:
1718       {
1719         int len;
1720
1721         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1722         if (len < 0)
1723           return FALSE;
1724         
1725         *end_pos = pos + len;
1726       }
1727       break;
1728
1729     case DBUS_TYPE_INT32_ARRAY:
1730     case DBUS_TYPE_UINT32_ARRAY:
1731       {
1732         int len;
1733
1734         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1735         if (len < 0)
1736           return FALSE;
1737
1738         _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1739         
1740         *end_pos = pos + len * 4;
1741       }
1742       break;
1743
1744     case DBUS_TYPE_DOUBLE_ARRAY:
1745       {
1746         int len;
1747         int align_8;
1748
1749         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1750         if (len < 0)
1751           return FALSE;
1752
1753         if (len == 0)
1754           *end_pos = pos;
1755         else
1756           {
1757             align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1758             if (!_dbus_string_validate_nul (str, pos,
1759                                             align_8 - pos))
1760               {
1761                 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1762                 return FALSE;
1763               }
1764
1765             *end_pos = align_8 + len * 8;
1766           }
1767       }
1768       break;
1769       
1770     case DBUS_TYPE_STRING_ARRAY:
1771       {
1772         int len;
1773         int i;
1774         
1775         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1776         if (len < 0)
1777           return FALSE;
1778
1779         for (i = 0; i < len; i++)
1780           {
1781             int str_len;
1782             
1783             str_len = demarshal_and_validate_len (str, byte_order,
1784                                                   pos, &pos);
1785             if (str_len < 0)
1786               return FALSE;
1787
1788             if (!validate_string (str, pos, str_len, &pos))
1789               return FALSE;            
1790           }
1791
1792         *end_pos = pos;
1793       }
1794       break;
1795
1796       case DBUS_TYPE_DICT:
1797         {
1798           int len;
1799           int i;
1800
1801           len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1802           if (len < 0)
1803             return FALSE;
1804           
1805           for (i = 0; i < len; i++)
1806             {
1807               int str_len;
1808               
1809               str_len = demarshal_and_validate_len (str, byte_order,
1810                                                     pos, &pos);
1811               if (str_len < 0)
1812                 return FALSE;
1813               
1814               if (!validate_string (str, pos, str_len, &pos))
1815                 return FALSE;            
1816             }
1817
1818           /* Now validate each argument */
1819           for (i = 0; i < len; i++)
1820             {
1821               if (pos >= _dbus_string_get_length (str))
1822                 {
1823                   _dbus_verbose ("not enough values in dict\n");
1824                   return FALSE;
1825                 }
1826
1827               if (_dbus_string_get_byte (str, pos) == DBUS_TYPE_NIL)
1828                 {
1829                   _dbus_verbose ("can't have NIL values in dicts\n");
1830                   return FALSE;
1831                 }
1832               
1833               if (!_dbus_marshal_validate_arg (str, byte_order, pos, &pos))
1834                 return FALSE;
1835             }
1836
1837           *end_pos = pos;
1838
1839           break;
1840         }
1841         
1842     default:
1843       _dbus_verbose ("Unknown message arg type %d\n", *data);
1844       return FALSE;
1845     }
1846
1847   if (*end_pos > _dbus_string_get_length (str))
1848     return FALSE;
1849   
1850   return TRUE;
1851 }
1852
1853
1854 /**
1855  * If in verbose mode, print a block of binary data.
1856  *
1857  * @todo right now it prints even if not in verbose mode
1858  * 
1859  * @param data the data
1860  * @param len the length of the data
1861  */
1862 void
1863 _dbus_verbose_bytes (const unsigned char *data,
1864                      int                  len)
1865 {
1866   int i;
1867   const unsigned char *aligned;
1868
1869   _dbus_assert (len >= 0);
1870   
1871   /* Print blanks on first row if appropriate */
1872   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1873   if (aligned > data)
1874     aligned -= 4;
1875   _dbus_assert (aligned <= data);
1876
1877   if (aligned != data)
1878     {
1879       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1880       while (aligned != data)
1881         {
1882           _dbus_verbose ("    ");
1883           ++aligned;
1884         }
1885     }
1886
1887   /* now print the bytes */
1888   i = 0;
1889   while (i < len)
1890     {
1891       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1892         {
1893           _dbus_verbose ("%4d\t%p: ",
1894                    i, &data[i]);
1895         }
1896       
1897       if (data[i] >= 32 &&
1898           data[i] <= 126)
1899         _dbus_verbose (" '%c' ", data[i]);
1900       else
1901         _dbus_verbose ("0x%s%x ",
1902                  data[i] <= 0xf ? "0" : "", data[i]);
1903
1904       ++i;
1905
1906       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1907         {
1908           if (i > 3)
1909             _dbus_verbose ("BE: %d LE: %d",
1910                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1911                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1912
1913           if (i > 7 && 
1914               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1915             {
1916               _dbus_verbose (" dbl: %g",
1917                              *(double*)&data[i-8]);
1918             }
1919           
1920           _dbus_verbose ("\n");
1921         }
1922     }
1923
1924   _dbus_verbose ("\n");
1925 }
1926
1927 /**
1928  * Dump the given part of the string to verbose log.
1929  *
1930  * @param str the string
1931  * @param start the start of range to dump
1932  * @param len length of range
1933  */
1934 void
1935 _dbus_verbose_bytes_of_string (const DBusString    *str,
1936                                int                  start,
1937                                int                  len)
1938 {
1939   const char *d;
1940   int real_len;
1941
1942   real_len = _dbus_string_get_length (str);
1943
1944   _dbus_assert (start >= 0);
1945   
1946   if (start > real_len)
1947     {
1948       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1949                      start, len, real_len);
1950       return;
1951     }
1952
1953   if ((start + len) > real_len)
1954     {
1955       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1956                      start, len, real_len);
1957       len = real_len - start;
1958     }
1959   
1960   
1961   _dbus_string_get_const_data_len (str, &d, start, len);
1962
1963   _dbus_verbose_bytes (d, len);
1964 }
1965
1966 /** @} */
1967
1968 #ifdef DBUS_BUILD_TESTS
1969 #include "dbus-test.h"
1970 #include <stdio.h>
1971
1972 dbus_bool_t
1973 _dbus_marshal_test (void)
1974 {
1975   DBusString str;
1976   char *tmp1, *tmp2;
1977   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1978   int pos = 0, i, len;
1979   dbus_bool_t our_bool;
1980   dbus_int32_t our_int;
1981   dbus_uint32_t our_uint;
1982   double our_double;
1983   const char *our_string;
1984   const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
1985   const unsigned char *our_boolean_array;
1986   const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
1987   const dbus_int32_t *our_int32_array;
1988   const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
1989   const dbus_uint32_t *our_uint32_array;
1990   const double double_array[] = { 3.14159, 1.2345, 6.7890 };
1991   const double *our_double_array;
1992   const char *string_array[] = { "This", "Is", "A", "Test" };
1993   const char **our_string_array;
1994   DBusDict *dict;
1995   
1996   if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1997     _dbus_assert_not_reached ("failed to init string");
1998
1999   /* Marshal doubles */
2000   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2001     _dbus_assert_not_reached ("could not marshal double value");
2002   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2003     _dbus_assert_not_reached ("demarshal failed");
2004
2005   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2006     _dbus_assert_not_reached ("could not marshal double value");
2007   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2008     _dbus_assert_not_reached ("demarshal failed");
2009   
2010   /* Marshal signed integers */
2011   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2012     _dbus_assert_not_reached ("could not marshal signed integer value");
2013   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2014     _dbus_assert_not_reached ("demarshal failed");
2015
2016   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2017     _dbus_assert_not_reached ("could not marshal signed integer value");
2018   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2019     _dbus_assert_not_reached ("demarshal failed");
2020   
2021   /* Marshal unsigned integers */
2022   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2023     _dbus_assert_not_reached ("could not marshal signed integer value");
2024   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2025     _dbus_assert_not_reached ("demarshal failed");
2026   
2027   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2028     _dbus_assert_not_reached ("could not marshal signed integer value");
2029   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2030     _dbus_assert_not_reached ("demarshal failed");
2031
2032   /* Marshal strings */
2033   tmp1 = "This is the dbus test string";
2034   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2035     _dbus_assert_not_reached ("could not marshal string");
2036   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2037   if (!strcmp (tmp1, tmp2) == 0)
2038     _dbus_assert_not_reached ("demarshal failed");
2039   dbus_free (tmp2);
2040
2041   tmp1 = "This is the dbus test string";
2042   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2043     _dbus_assert_not_reached ("could not marshal string");
2044   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2045   if (!strcmp (tmp1, tmp2) == 0)
2046     _dbus_assert_not_reached ("demarshal failed");
2047   dbus_free (tmp2);
2048
2049   /* Marshal signed integer arrays */
2050   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2051     _dbus_assert_not_reached ("could not marshal integer array");
2052   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2053     _dbus_assert_not_reached ("could not demarshal integer array");
2054
2055   if (len != 3)
2056     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2057   dbus_free (array2);
2058   
2059
2060   /* Marshal dicts */
2061   dict = dbus_dict_new ();
2062
2063   if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
2064     _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
2065   
2066   if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
2067     _dbus_assert_not_reached ("could not add boolean value");
2068
2069   if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
2070     _dbus_assert_not_reached ("could not add int32 value");
2071
2072   if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
2073     _dbus_assert_not_reached ("could not add uint32 value");
2074
2075   if (!dbus_dict_set_double (dict, "double", 3.14159))
2076     _dbus_assert_not_reached ("could not add double value");
2077
2078   if (!dbus_dict_set_string (dict, "string", "test string"))
2079     _dbus_assert_not_reached ("could not add string value");
2080
2081   if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
2082     _dbus_assert_not_reached ("could not add boolean array");
2083
2084   if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
2085     _dbus_assert_not_reached ("could not add int32 array");
2086
2087   if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
2088     _dbus_assert_not_reached ("could not add uint32 array");
2089
2090   if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
2091     _dbus_assert_not_reached ("could not add double array");
2092
2093   if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
2094     _dbus_assert_not_reached ("could not add string array");
2095
2096   if (!_dbus_marshal_dict (&str, DBUS_BIG_ENDIAN, dict))
2097     _dbus_assert_not_reached ("could not marshal dict");
2098   
2099   dbus_dict_unref (dict);
2100   
2101   if (!_dbus_demarshal_dict (&str, DBUS_BIG_ENDIAN, pos, &pos, &dict))
2102     _dbus_assert_not_reached ("could not demarshal dict");
2103
2104   if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
2105       !our_bool)
2106     _dbus_assert_not_reached ("could not get boolean value");
2107
2108   if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
2109     _dbus_assert_not_reached ("could not get int32 value or int32 values differ");
2110   
2111   if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
2112     _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
2113
2114   if (!dbus_dict_get_double (dict, "double", &our_double)
2115       || our_double != 3.14159)
2116      _dbus_assert_not_reached ("could not get double value or double values differ");
2117
2118   if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
2119     _dbus_assert_not_reached ("could not get string value or string values differ");
2120
2121   if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
2122       len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
2123     _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
2124
2125   if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
2126       len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
2127     _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
2128
2129   if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
2130       len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
2131     _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
2132
2133   if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
2134       len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
2135     _dbus_assert_not_reached ("could not get double array value or double array values differ");
2136
2137   if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
2138     _dbus_assert_not_reached ("could not get string array value");
2139
2140   if (len != 4)
2141     _dbus_assert_not_reached ("string array lengths differ");
2142
2143   for (i = 0; i < len; i++)
2144     {
2145       if (strcmp (our_string_array[i], string_array[i]) != 0)
2146         _dbus_assert_not_reached ("string array fields differ");
2147     }
2148   
2149   dbus_dict_unref (dict);
2150   
2151   _dbus_string_free (&str);
2152   
2153       
2154   return TRUE;
2155 }
2156
2157 #endif /* DBUS_BUILD_TESTS */