2003-03-10 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   return _dbus_string_append_len (str, value, len);
356 }
357
358 /**
359  * Marshals a 32 bit signed integer array
360  *
361  * @param str the string to append the marshalled value to
362  * @param byte_order the byte order to use
363  * @param value the array
364  * @param len the length of the array
365  * @returns #TRUE on success
366  */
367 dbus_bool_t
368 _dbus_marshal_int32_array (DBusString         *str,
369                            int                 byte_order,
370                            const dbus_int32_t *value,
371                            int                 len)
372 {
373   int i, old_string_len;
374
375   old_string_len = _dbus_string_get_length (str);
376
377   if (!_dbus_marshal_uint32 (str, byte_order, len))
378     goto error;
379
380   for (i = 0; i < len; i++)
381     if (!_dbus_marshal_int32 (str, byte_order, value[i]))
382       goto error;
383
384   return TRUE;
385   
386  error:
387   /* Restore previous length */
388   _dbus_string_set_length (str, old_string_len);
389   
390   return FALSE;
391 }
392
393 /**
394  * Marshals a 32 bit unsigned integer array
395  *
396  * @param str the string to append the marshalled value to
397  * @param byte_order the byte order to use
398  * @param value the array
399  * @param len the length of the array
400  * @returns #TRUE on success
401  */
402 dbus_bool_t
403 _dbus_marshal_uint32_array (DBusString          *str,
404                             int                  byte_order,
405                             const dbus_uint32_t  *value,
406                             int                  len)
407 {
408   int i, old_string_len;
409
410   old_string_len = _dbus_string_get_length (str);
411
412   if (!_dbus_marshal_uint32 (str, byte_order, len))
413     goto error;
414
415   for (i = 0; i < len; i++)
416     if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
417       goto error;
418
419   return TRUE;
420   
421  error:
422   /* Restore previous length */
423   _dbus_string_set_length (str, old_string_len);
424   
425   return FALSE;  
426 }
427
428 /**
429  * Marshals a double array
430  *
431  * @param str the string to append the marshalled value to
432  * @param byte_order the byte order to use
433  * @param value the array
434  * @param len the length of the array
435  * @returns #TRUE on success
436  */
437 dbus_bool_t
438 _dbus_marshal_double_array (DBusString          *str,
439                             int                  byte_order,
440                             const double        *value,
441                             int                  len)
442 {
443   int i, old_string_len;
444
445   old_string_len = _dbus_string_get_length (str);
446
447   if (!_dbus_marshal_uint32 (str, byte_order, len))
448     goto error;
449
450   for (i = 0; i < len; i++)
451     if (!_dbus_marshal_double (str, byte_order, value[i]))
452       goto error;
453
454   return TRUE;
455   
456  error:
457   /* Restore previous length */
458   _dbus_string_set_length (str, old_string_len);
459   
460   return FALSE;    
461 }
462
463 /**
464  * Marshals a string array
465  *
466  * @param str the string to append the marshalled value to
467  * @param byte_order the byte order to use
468  * @param value the array
469  * @param len the length of the array
470  * @returns #TRUE on success
471  */
472 dbus_bool_t
473 _dbus_marshal_string_array (DBusString  *str,
474                             int          byte_order,
475                             const char **value,
476                             int          len)
477 {
478   int i, old_string_len;
479
480   old_string_len = _dbus_string_get_length (str);
481
482   if (!_dbus_marshal_uint32 (str, byte_order, len))
483     goto error;
484
485   for (i = 0; i < len; i++)
486     if (!_dbus_marshal_string (str, byte_order, value[i]))
487       goto error;
488
489   return TRUE;
490   
491  error:
492   /* Restore previous length */
493   _dbus_string_set_length (str, old_string_len);
494   
495   return FALSE;      
496 }
497
498
499 /**
500  * Marshals a dict
501  * @param str the string to append the marshalled value to
502  * @param byte_order the byte order to use
503  * @param dict the dict
504  * @returns #TRUE on success
505  */
506 dbus_bool_t
507 _dbus_marshal_dict (DBusString *str,
508                     int         byte_order,
509                     DBusDict   *dict)
510 {
511   int old_string_len;
512   int i, len;
513   char **keys;
514   
515   old_string_len = _dbus_string_get_length (str);
516
517   if (!dbus_dict_get_keys (dict, &keys, &len))
518     goto error;
519
520   if (len == 0)
521     return TRUE;
522
523   if (!_dbus_marshal_string_array (str, byte_order,
524                                    keys, len))
525     goto error;
526
527   for (i = 0; i < len; i++)
528     {
529       int value_type;
530
531       value_type = dbus_dict_get_value_type (dict, keys[i]);
532
533       if (!_dbus_string_append_byte (str, value_type))
534         goto error;
535       
536       switch (dbus_dict_get_value_type (dict, keys[i]))
537         {
538         case DBUS_TYPE_BOOLEAN:
539           {
540             dbus_bool_t value;
541
542             if (!dbus_dict_get_boolean (dict, keys[i], &value))
543               goto error;
544             
545             if (!_dbus_string_append_byte (str, (value != FALSE)))
546               goto error;
547
548             break;
549           }
550           
551         case DBUS_TYPE_INT32:
552           {
553             dbus_int32_t value;
554             
555             if (!dbus_dict_get_int32 (dict, keys[i], &value))
556               goto error;
557             
558             if (!_dbus_marshal_int32 (str, byte_order, value))
559               goto error;
560
561             break;
562           }
563         case DBUS_TYPE_UINT32:
564           {
565             dbus_uint32_t value;
566             
567             if (!dbus_dict_get_uint32 (dict, keys[i], &value))
568               goto error;
569             
570             if (!_dbus_marshal_uint32 (str, byte_order, value))
571               goto error;
572
573             break;
574           }
575         case DBUS_TYPE_DOUBLE:
576           {
577             double value;
578             
579             if (!dbus_dict_get_double (dict, keys[i], &value))
580               goto error;
581
582             if (!_dbus_marshal_double (str, byte_order, value))
583               goto error;
584
585             break;
586           }
587         case DBUS_TYPE_INT32_ARRAY:
588           {
589             const dbus_int32_t *value;
590             int len;
591
592             if (!dbus_dict_get_int32_array (dict, keys[i], &value, &len))
593               goto error;
594
595             if (!_dbus_marshal_int32_array (str, byte_order, value, len))
596               goto error;
597             
598             break;
599           }
600         case DBUS_TYPE_STRING:
601           {
602             const char *value;
603
604             if (!dbus_dict_get_string (dict, keys[i], &value))
605               goto error;
606
607             if (!_dbus_marshal_string (str, byte_order, value))
608               goto error;
609             
610             break;
611           }       
612         case DBUS_TYPE_BOOLEAN_ARRAY:
613           {
614             const unsigned char *value;
615             int len;
616
617             if (!dbus_dict_get_boolean_array (dict, keys[i], &value, &len))
618               goto error;
619
620             if (!_dbus_marshal_byte_array (str, byte_order, value, len))
621               goto error;
622             
623             break;
624           }       
625         case DBUS_TYPE_UINT32_ARRAY:
626           {
627             const dbus_uint32_t *value;
628             int len;
629
630             if (!dbus_dict_get_uint32_array (dict, keys[i], &value, &len))
631               goto error;
632
633             if (!_dbus_marshal_uint32_array (str, byte_order, value, len))
634               goto error;
635             
636             break;
637           }       
638         case DBUS_TYPE_DOUBLE_ARRAY:
639           {
640             const double *value;
641             int len;
642
643             if (!dbus_dict_get_double_array (dict, keys[i], &value, &len))
644               goto error;
645
646             if (!_dbus_marshal_double_array (str, byte_order, value, len))
647               goto error;
648             
649             break;
650           }
651         case DBUS_TYPE_STRING_ARRAY:
652           {
653             const char **value;
654             int len;
655
656             if (!dbus_dict_get_string_array (dict, keys[i], &value, &len))
657               goto error;
658
659             if (!_dbus_marshal_string_array (str, byte_order, value, len))
660               goto error;
661             
662             break;
663           }
664         default:
665           _dbus_warn ("unknwon value type %d\n", dbus_dict_get_value_type (dict, keys[i]));
666           _dbus_assert_not_reached ("unknown value type in dict");
667         }
668     }
669
670   dbus_free_string_array (keys);
671
672   return TRUE;
673   
674  error:
675   
676   dbus_free_string_array (keys);
677   
678   /* Restore previous length */
679   _dbus_string_set_length (str, old_string_len);
680
681   return FALSE;
682 }
683
684
685 /**
686  * Demarshals a double.
687  *
688  * @param str the string containing the data
689  * @param byte_order the byte order
690  * @param pos the position in the string
691  * @param new_pos the new position of the string
692  * @returns the demarshaled double.
693  */
694 double
695 _dbus_demarshal_double (const DBusString  *str,
696                         int          byte_order,
697                         int          pos,
698                         int         *new_pos)
699 {
700   double retval;
701   const char *buffer;
702
703   pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
704
705   _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
706
707   retval = *(double *)buffer;
708   
709   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
710     swap_bytes ((unsigned char *)&retval, sizeof (double));
711
712   if (new_pos)
713     *new_pos = pos + sizeof (double);
714   
715   return retval;  
716 }
717
718 /**
719  * Demarshals a 32 bit signed integer.
720  *
721  * @param str the string containing the data
722  * @param byte_order the byte order
723  * @param pos the position in the string
724  * @param new_pos the new position of the string
725  * @returns the demarshaled integer.
726  */
727 dbus_int32_t
728 _dbus_demarshal_int32  (const DBusString *str,
729                         int               byte_order,
730                         int               pos,
731                         int              *new_pos)
732 {
733   const DBusRealString *real = (const DBusRealString*) str;
734   
735   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
736   
737   if (new_pos)
738     *new_pos = pos + sizeof (dbus_int32_t);
739
740   if (byte_order == DBUS_LITTLE_ENDIAN)
741     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
742   else
743     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
744 }
745
746 /**
747  * Demarshals a 32 bit unsigned integer.
748  *
749  * @param str the string containing the data
750  * @param byte_order the byte order
751  * @param pos the position in the string
752  * @param new_pos the new position of the string
753  * @returns the demarshaled integer.
754  */
755 dbus_uint32_t
756 _dbus_demarshal_uint32  (const DBusString *str,
757                          int         byte_order,
758                          int         pos,
759                          int        *new_pos)
760 {
761   const DBusRealString *real = (const DBusRealString*) str;
762   
763   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
764   
765   if (new_pos)
766     *new_pos = pos + sizeof (dbus_uint32_t);
767
768   if (byte_order == DBUS_LITTLE_ENDIAN)
769     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
770   else
771     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
772 }
773
774 /**
775  * Demarshals an UTF-8 string.
776  *
777  * @todo Should we check the string to make sure
778  * that it's  valid UTF-8, and maybe "fix" the string
779  * if it's broken?
780  *
781  * @todo Should probably demarshal to a DBusString,
782  * having memcpy() in here is Evil(tm).
783  *
784  * @param str the string containing the data
785  * @param byte_order the byte order
786  * @param pos the position in the string
787  * @param new_pos the new position of the string
788  * @returns the demarshaled string.
789  */
790 char *
791 _dbus_demarshal_string (const DBusString *str,
792                         int         byte_order,
793                         int         pos,
794                         int        *new_pos)
795 {
796   int len;
797   char *retval;
798   const char *data;
799   
800   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
801
802   retval = dbus_malloc (len + 1);
803
804   if (!retval)
805     return NULL;
806
807   _dbus_string_get_const_data_len (str, &data, pos, len);
808
809   if (!data)
810     return NULL;
811
812   memcpy (retval, data, len + 1);
813
814   if (new_pos)
815     *new_pos = pos + len + 1;
816   
817   return retval;
818 }
819
820 /**
821  * Demarshals a byte array.
822  *
823  * @todo Should probably demarshal to a DBusString,
824  * having memcpy() in here is Evil(tm).
825  *
826  * @param str the string containing the data
827  * @param byte_order the byte order
828  * @param pos the position in the string
829  * @param new_pos the new position of the string
830  * @param array_len length of the demarshaled data
831  * @returns the demarshaled data.
832  */
833 unsigned char *
834 _dbus_demarshal_byte_array (const DBusString *str,
835                             int         byte_order,
836                             int         pos,
837                             int        *new_pos,
838                             int        *array_len)
839 {
840   int len;
841   unsigned char *retval;
842   const char *data;
843
844   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
845
846   retval = dbus_malloc (len);
847
848   if (!retval)
849     return NULL;
850
851   _dbus_string_get_const_data_len (str, &data, pos, len);
852
853   if (!data)
854     return NULL;
855
856   memcpy (retval, data, len);
857
858   if (new_pos)
859     *new_pos = pos + len;
860
861   if (array_len)
862     *array_len = len;
863
864   return retval;
865 }
866
867 /**
868  * Demarshals a 32 bit signed integer array.
869  *
870  * @param str the string containing the data
871  * @param byte_order the byte order
872  * @param pos the position in the string
873  * @param new_pos the new position of the string
874  * @param array_len length of the demarshaled data
875  * @returns the demarshaled data.
876  */
877 dbus_int32_t *
878 _dbus_demarshal_int32_array (const DBusString *str,
879                              int         byte_order,
880                              int         pos,
881                              int        *new_pos,
882                              int        *array_len)
883 {
884   int len, i;
885   dbus_int32_t *retval;
886   
887   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
888
889   retval = dbus_new (dbus_int32_t, len);
890
891   if (!retval)
892     return NULL;
893
894   for (i = 0; i < len; i++)
895     retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
896
897   if (new_pos)
898     *new_pos = pos;
899
900   if (array_len)
901     *array_len = len;
902   
903   return retval;
904 }
905
906 /**
907  * Demarshals a 32 bit unsigned integer array.
908  *
909  * @param str the string containing the data
910  * @param byte_order the byte order
911  * @param pos the position in the string
912  * @param new_pos the new position of the string
913  * @param array_len length of the demarshaled data
914  * @returns the demarshaled data.
915  */
916 dbus_uint32_t *
917 _dbus_demarshal_uint32_array (const DBusString *str,
918                               int         byte_order,
919                               int         pos,
920                               int        *new_pos,
921                               int        *array_len)
922 {
923   int len, i;
924   dbus_uint32_t *retval;
925   
926   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
927
928   retval = dbus_new (dbus_uint32_t, len);
929
930   if (!retval)
931     return NULL;
932
933   for (i = 0; i < len; i++)
934     retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
935
936   if (new_pos)
937     *new_pos = pos;
938
939   if (array_len)
940     *array_len = len;
941   
942   return retval;  
943 }
944
945 /**
946  * Demarshals a double array.
947  *
948  * @param str the string containing the data
949  * @param byte_order the byte order
950  * @param pos the position in the string
951  * @param new_pos the new position of the string
952  * @param array_len length of the demarshaled data
953  * @returns the demarshaled data.
954  */
955 double *
956 _dbus_demarshal_double_array (const DBusString *str,
957                               int         byte_order,
958                               int         pos,
959                               int        *new_pos,
960                               int        *array_len)
961 {
962   int len, i;
963   double *retval;
964   
965   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
966
967   retval = dbus_new (double, len);
968
969   if (!retval)
970     return NULL;
971
972   for (i = 0; i < len; i++)
973     retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
974
975   if (new_pos)
976     *new_pos = pos;
977
978   if (array_len)
979     *array_len = len;
980   
981   return retval;  
982 }
983
984 /**
985  * Demarshals a string array.
986  *
987  * @param str the string containing the data
988  * @param byte_order the byte order
989  * @param pos the position in the string
990  * @param new_pos the new position of the string
991  * @param array_len length of the demarshaled data
992  * @returns the demarshaled data.
993  */
994 char **
995 _dbus_demarshal_string_array (const DBusString *str,
996                               int         byte_order,
997                               int         pos,
998                               int        *new_pos,
999                               int        *array_len)
1000 {
1001   int len, i, j;
1002   char **retval;
1003
1004   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1005
1006   retval = dbus_new (char *, len + 1);
1007
1008   if (!retval)
1009     return NULL;
1010
1011   retval[len] = NULL;
1012   
1013   for (i = 0; i < len; i++)
1014     {
1015       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1016
1017       if (retval[i] == 0)
1018         goto error;
1019     }
1020
1021  if (new_pos)
1022     *new_pos = pos;
1023
1024   if (array_len)
1025     *array_len = len;
1026   
1027   return retval;
1028
1029  error:
1030   for (j = 0; j < i; j++)
1031     dbus_free (retval[i]);
1032   dbus_free (retval);
1033
1034   return NULL;
1035 }
1036
1037 /**
1038  * Demarshals a dict
1039  *
1040  * @param str the string containing the data
1041  * @param byte_order the byte order
1042  * @param pos the position in the string
1043  * @param new_pos the new position in the string
1044  * @returns the demarshalled dict
1045  */
1046 DBusDict *
1047 _dbus_demarshal_dict (const DBusString *str,
1048                       int               byte_order,
1049                       int               pos,
1050                       int              *new_pos)
1051 {
1052   char **keys;
1053   int i, len;
1054   DBusDict *dict;
1055   
1056   dict = dbus_dict_new ();
1057   if (!dict)
1058     return NULL;
1059
1060   keys = _dbus_demarshal_string_array (str, byte_order, pos, &pos, &len);
1061   
1062   if (!keys)
1063     goto error;
1064
1065   for (i = 0; i < len; i++)
1066     {
1067       int value_type;
1068       
1069       switch ((value_type = _dbus_string_get_byte (str, pos ++)))
1070         {
1071         case DBUS_TYPE_BOOLEAN:
1072           {
1073             dbus_bool_t value;
1074
1075             value = _dbus_string_get_byte (str, pos ++);
1076
1077             if (!dbus_dict_set_boolean (dict, keys[i], value))
1078               goto error;
1079             break;
1080           }
1081         case DBUS_TYPE_INT32:
1082           {
1083             dbus_int32_t value;
1084
1085             value = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
1086
1087             if (!dbus_dict_set_int32 (dict, keys[i], value))
1088               goto error;
1089             
1090             break;
1091           }
1092         case DBUS_TYPE_UINT32:
1093           {
1094             dbus_uint32_t value;
1095
1096             value = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1097
1098             if (!dbus_dict_set_uint32 (dict, keys[i], value))
1099               goto error;
1100             
1101             break;
1102           }
1103         case DBUS_TYPE_DOUBLE:
1104           {
1105             double value;
1106
1107             value = _dbus_demarshal_double (str, byte_order, pos, &pos);
1108
1109             if (!dbus_dict_set_double (dict, keys[i], value))
1110               goto error;
1111             
1112             break;
1113           }
1114         case DBUS_TYPE_STRING:
1115           {
1116             char *value;
1117
1118             value = _dbus_demarshal_string (str, byte_order, pos, &pos);
1119
1120             if (!value)
1121               goto error;
1122
1123             if (!dbus_dict_set_string (dict, keys[i], value))
1124               {
1125                 dbus_free (value);
1126                 goto error;
1127               }
1128
1129             dbus_free (value);
1130             
1131             break;
1132           }
1133         case DBUS_TYPE_BOOLEAN_ARRAY:
1134           {
1135             unsigned char *value;
1136             int len;
1137             
1138             value = _dbus_demarshal_byte_array (str, byte_order, pos, &pos, &len);
1139
1140             if (!value)
1141               goto error;
1142
1143             if (!dbus_dict_set_boolean_array (dict, keys[i], value, len))
1144               {
1145                 dbus_free (value);
1146                 goto error;
1147               }
1148
1149             dbus_free (value);
1150             break;
1151           }
1152         case DBUS_TYPE_INT32_ARRAY:
1153           {
1154             dbus_int32_t *value;
1155             int len;
1156             
1157             value = _dbus_demarshal_int32_array (str, byte_order, pos, &pos, &len);
1158
1159             if (!value)
1160               goto error;
1161
1162             if (!dbus_dict_set_int32_array (dict, keys[i], value, len))
1163               {
1164                 dbus_free (value);
1165                 goto error;
1166               }
1167
1168             dbus_free (value);
1169             break;
1170           }
1171         case DBUS_TYPE_UINT32_ARRAY:
1172           {
1173             dbus_uint32_t *value;
1174             int len;
1175             
1176             value = _dbus_demarshal_uint32_array (str, byte_order, pos, &pos, &len);
1177
1178             if (!value)
1179               goto error;
1180
1181             if (!dbus_dict_set_uint32_array (dict, keys[i], value, len))
1182               {
1183                 dbus_free (value);
1184                 goto error;
1185               }
1186
1187             dbus_free (value);
1188             break;
1189           }
1190         case DBUS_TYPE_DOUBLE_ARRAY:
1191           {
1192             double *value;
1193             int len;
1194             
1195             value = _dbus_demarshal_double_array (str, byte_order, pos, &pos, &len);
1196
1197             if (!value)
1198               goto error;
1199
1200             if (!dbus_dict_set_double_array (dict, keys[i], value, len))
1201               {
1202                 dbus_free (value);
1203                 goto error;
1204               }
1205
1206             dbus_free (value);
1207             break;
1208           }
1209         case DBUS_TYPE_STRING_ARRAY:
1210           {
1211             char **value;
1212             int len;
1213             
1214             value = _dbus_demarshal_string_array (str, byte_order, pos, &pos, &len);
1215
1216             if (!value)
1217               goto error;
1218
1219             if (!dbus_dict_set_string_array (dict, keys[i], value, len))
1220               {
1221                 dbus_free_string_array (value);
1222                 goto error;
1223               }
1224
1225             dbus_free_string_array (value);
1226             break;
1227           }
1228         default:
1229           _dbus_warn ("unknown value type %d\n", value_type);
1230           _dbus_assert_not_reached ("unknown value arg");
1231         }
1232     }
1233   
1234   dbus_free_string_array (keys);
1235   return dict;
1236   
1237  error:
1238   dbus_free_string_array (keys);
1239   dbus_dict_unref (dict);
1240   return NULL;
1241 }
1242
1243 /** 
1244  * Returns the position right after the end of an argument.  PERFORMS
1245  * NO VALIDATION WHATSOEVER. The message must have been previously
1246  * validated.
1247  *
1248  * @param str a string
1249  * @param byte_order the byte order to use
1250  * @param pos the pos where the arg starts
1251  * @param end_pos pointer where the position right
1252  * after the end position will follow
1253  * @returns TRUE if more data exists after the arg
1254  */
1255 dbus_bool_t
1256 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1257                                int               byte_order,
1258                                int               pos,
1259                                int              *end_pos)
1260 {
1261   const char *data;
1262
1263   if (pos >= _dbus_string_get_length (str))
1264     return FALSE;
1265
1266   _dbus_string_get_const_data_len (str, &data, pos, 1);
1267   
1268   switch (*data)
1269     {
1270     case DBUS_TYPE_INVALID:
1271       return FALSE;
1272       break;
1273
1274     case DBUS_TYPE_NIL:
1275       *end_pos = pos + 1;
1276       break;
1277
1278     case DBUS_TYPE_BOOLEAN:
1279       *end_pos = pos + 2;
1280       break;
1281       
1282     case DBUS_TYPE_INT32:
1283       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
1284
1285       break;
1286
1287     case DBUS_TYPE_UINT32:
1288       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
1289
1290       break;
1291
1292     case DBUS_TYPE_DOUBLE:
1293       *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
1294
1295       break;
1296
1297     case DBUS_TYPE_STRING:
1298       {
1299         int len;
1300
1301         /* Demarshal the length */
1302         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1303
1304         *end_pos = pos + len + 1;
1305       }
1306       break;
1307
1308     case DBUS_TYPE_BOOLEAN_ARRAY:
1309     case DBUS_TYPE_BYTE_ARRAY:
1310       {
1311         int len;
1312
1313         /* Demarshal the length */
1314         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1315         
1316         *end_pos = pos + len;
1317       }
1318       break;
1319
1320     case DBUS_TYPE_INT32_ARRAY:
1321       {
1322         int len, new_pos;
1323
1324         /* Demarshal the length */
1325         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1326         
1327         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
1328           + (len * sizeof (dbus_int32_t));
1329       }
1330       break;
1331
1332     case DBUS_TYPE_UINT32_ARRAY:
1333       {
1334         int len, new_pos;
1335
1336         /* Demarshal the length */
1337         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1338
1339         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
1340           + (len * sizeof (dbus_uint32_t));
1341       }
1342       break;
1343
1344     case DBUS_TYPE_DOUBLE_ARRAY:
1345       {
1346         int len, new_pos;
1347         
1348         /* Demarshal the length */
1349         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1350
1351         *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
1352           + (len * sizeof (double));
1353       }
1354       break;
1355       
1356     case DBUS_TYPE_STRING_ARRAY:
1357       {
1358         int len, i;
1359         
1360         /* Demarshal the length */
1361         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1362
1363         for (i = 0; i < len; i++)
1364           {
1365             int str_len;
1366             
1367             /* Demarshal string length */
1368             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1369             pos += str_len + 1;
1370           }
1371
1372         *end_pos = pos;
1373       }
1374       break;
1375
1376     case DBUS_TYPE_DICT:
1377       {
1378         int len, i;
1379
1380         /* Demarshal the length */
1381         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1382
1383         for (i = 0; i < len; i++)
1384           {
1385             int str_len;
1386             
1387             /* Demarshal string length */
1388             str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1389             pos += str_len + 1;
1390           }
1391
1392         /* Now check the values */
1393         for (i = 0; i < len; i++)
1394           {
1395             if (!_dbus_marshal_get_arg_end_pos (str, byte_order, pos, &pos))
1396                 return FALSE;
1397           }
1398
1399         *end_pos = pos;
1400         
1401         break;
1402       }
1403     default:
1404       _dbus_warn ("Unknown message arg type %d\n", *data);
1405       _dbus_assert_not_reached ("Unknown message argument type\n");
1406       return FALSE;
1407     }
1408
1409   if (*end_pos > _dbus_string_get_length (str))
1410     return FALSE;
1411   
1412   return TRUE;
1413 }
1414
1415 /**
1416  * Demarshals and validates a length; returns < 0 if the validation
1417  * fails. The length is required to be small enough that
1418  * len*sizeof(double) will not overflow, and small enough to fit in a
1419  * signed integer. DOES NOT check whether the length points
1420  * beyond the end of the string, because it doesn't know the
1421  * size of array elements.
1422  *
1423  * @param str the string
1424  * @param byte_order the byte order
1425  * @param pos the unaligned string position (snap to next aligned)
1426  * @param new_pos return location for new position.
1427  */
1428 static int
1429 demarshal_and_validate_len (const DBusString *str,
1430                             int               byte_order,
1431                             int               pos,
1432                             int              *new_pos)
1433 {
1434   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1435   unsigned int len;
1436
1437   _dbus_assert (new_pos != NULL);
1438   
1439   if ((align_4 + 4) >= _dbus_string_get_length (str))
1440     {
1441       _dbus_verbose ("not enough room in message for array length\n");
1442       return -1;
1443     }
1444   
1445   if (!_dbus_string_validate_nul (str, pos,
1446                                   align_4 - pos))
1447     {
1448       _dbus_verbose ("array length alignment padding not initialized to nul\n");
1449       return -1;
1450     }
1451
1452   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1453
1454   /* note that the len may be a number of doubles, so we need it to be
1455    * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1456    * sane.  We end up using ints for most sizes to avoid unsigned mess
1457    * so limit to maximum 32-bit signed int divided by at least 8, more
1458    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1459    */  
1460 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1461   if (len > MAX_ARRAY_LENGTH)
1462     {
1463       _dbus_verbose ("array length %u exceeds maximum of %u\n",
1464                      len, MAX_ARRAY_LENGTH);
1465       return -1;
1466     }
1467   else
1468     return (int) len;
1469 }
1470
1471 static dbus_bool_t
1472 validate_string (const DBusString *str,
1473                  int               pos,
1474                  int               len_without_nul,
1475                  int              *end_pos)
1476 {
1477   *end_pos = pos + len_without_nul + 1;
1478   
1479   if (*end_pos > _dbus_string_get_length (str))
1480     {
1481       _dbus_verbose ("string length outside length of the message\n");
1482       return FALSE;
1483     }
1484   
1485   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1486     {
1487       _dbus_verbose ("string arg not nul-terminated\n");
1488       return FALSE;
1489     }
1490   
1491   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1492     {
1493       _dbus_verbose ("string is not valid UTF-8\n");
1494       return FALSE;
1495     }
1496
1497   return TRUE;
1498 }   
1499
1500 /** 
1501  * Validates an argument, checking that it is well-formed, for example
1502  * no ludicrous length fields, strings are nul-terminated, etc.
1503  * Returns the end position of the argument in end_pos, and
1504  * returns #TRUE if a valid arg begins at "pos"
1505  *
1506  * @todo security: need to audit this function.
1507  * 
1508  * @param str a string
1509  * @param byte_order the byte order to use
1510  * @param pos the pos where the arg starts (offset of its typecode)
1511  * @param end_pos pointer where the position right
1512  * after the end position will follow
1513  * @returns #TRUE if the arg is valid.
1514  */
1515 dbus_bool_t
1516 _dbus_marshal_validate_arg (const DBusString *str,
1517                             int               byte_order,
1518                             int               pos,
1519                             int              *end_pos)
1520 {
1521   const char *data;
1522
1523   if (pos >= _dbus_string_get_length (str))
1524     return FALSE;
1525
1526   _dbus_string_get_const_data_len (str, &data, pos, 1);
1527   
1528   switch (*data)
1529     {
1530     case DBUS_TYPE_INVALID:
1531       return FALSE;
1532       break;
1533
1534     case DBUS_TYPE_NIL:
1535       *end_pos = pos + 1;
1536       break;
1537
1538     case DBUS_TYPE_BOOLEAN:
1539       {
1540         unsigned char c;
1541
1542         if (2 > _dbus_string_get_length (str) - pos)
1543           {
1544             _dbus_verbose ("no room for boolean value\n");
1545             return FALSE;
1546           }
1547         
1548         c = _dbus_string_get_byte (str, pos + 1);
1549
1550         if (c != 0 && c != 1)
1551           {
1552             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1553             return FALSE;
1554           }
1555         
1556       *end_pos = pos + 2;
1557       break;
1558       }
1559     case DBUS_TYPE_INT32:
1560     case DBUS_TYPE_UINT32:
1561       {
1562         int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1563         
1564         if (!_dbus_string_validate_nul (str, pos + 1,
1565                                         align_4 - pos - 1))
1566           {
1567             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1568             return FALSE;
1569           }
1570
1571         *end_pos = align_4 + 4;
1572       }
1573       break;
1574
1575     case DBUS_TYPE_DOUBLE:
1576       {
1577         int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1578
1579         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1580         
1581         if (!_dbus_string_validate_nul (str, pos + 1,
1582                                         align_8 - pos - 1))
1583           {
1584             _dbus_verbose ("double alignment padding not initialized to nul\n");
1585             return FALSE;
1586           }
1587
1588         *end_pos = align_8 + 8;
1589       }
1590       break;
1591
1592     case DBUS_TYPE_STRING:
1593       {
1594         int len;
1595
1596         /* Demarshal the length, which does NOT include
1597          * nul termination
1598          */
1599         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1600         if (len < 0)
1601           return FALSE;
1602
1603         if (!validate_string (str, pos, len, end_pos))
1604           return FALSE;
1605       }
1606       break;
1607
1608     case DBUS_TYPE_BOOLEAN_ARRAY:
1609       {
1610         int len, i;
1611
1612         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1613         if (len < 0)
1614           return FALSE;
1615
1616         if (len > _dbus_string_get_length (str) - pos)
1617           {
1618             _dbus_verbose ("boolean array length outside length of the message\n");
1619             return FALSE;
1620           }
1621         
1622         i = 0;
1623         while (i < len)
1624           {
1625             unsigned char c = _dbus_string_get_byte (str, pos + i);
1626
1627             if (c != 0 && c != 1)
1628               {
1629                 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1630                 return FALSE;
1631               }
1632
1633             i++;
1634           }
1635         *end_pos = pos + len;
1636         break;
1637       }
1638     case DBUS_TYPE_BYTE_ARRAY:
1639       {
1640         int len;
1641
1642         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1643         if (len < 0)
1644           return FALSE;
1645         
1646         *end_pos = pos + len;
1647       }
1648       break;
1649
1650     case DBUS_TYPE_INT32_ARRAY:
1651     case DBUS_TYPE_UINT32_ARRAY:
1652       {
1653         int len;
1654
1655         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1656         if (len < 0)
1657           return FALSE;
1658
1659         _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1660         
1661         *end_pos = pos + len * 4;
1662       }
1663       break;
1664
1665     case DBUS_TYPE_DOUBLE_ARRAY:
1666       {
1667         int len;
1668         int align_8;
1669
1670         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1671         if (len < 0)
1672           return FALSE;
1673
1674         align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1675         if (!_dbus_string_validate_nul (str, pos,
1676                                         align_8 - pos))
1677           {
1678             _dbus_verbose ("double array alignment padding not initialized to nul\n");
1679             return FALSE;
1680           }
1681         
1682         *end_pos = align_8 + len * 8;
1683       }
1684       break;
1685       
1686     case DBUS_TYPE_STRING_ARRAY:
1687       {
1688         int len;
1689         int i;
1690         
1691         len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1692         if (len < 0)
1693           return FALSE;
1694
1695         for (i = 0; i < len; i++)
1696           {
1697             int str_len;
1698             
1699             str_len = demarshal_and_validate_len (str, byte_order,
1700                                                   pos, &pos);
1701             if (str_len < 0)
1702               return FALSE;
1703
1704             if (!validate_string (str, pos, str_len, &pos))
1705               return FALSE;            
1706           }
1707
1708         *end_pos = pos;
1709       }
1710       break;
1711
1712       case DBUS_TYPE_DICT:
1713         {
1714           int len;
1715           int i;
1716
1717           len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1718           if (len < 0)
1719             return FALSE;
1720           
1721           for (i = 0; i < len; i++)
1722             {
1723               int str_len;
1724               
1725               str_len = demarshal_and_validate_len (str, byte_order,
1726                                                     pos, &pos);
1727               if (str_len < 0)
1728                 return FALSE;
1729               
1730               if (!validate_string (str, pos, str_len, &pos))
1731                 return FALSE;            
1732             }
1733
1734           /* Now validate each argument */
1735           for (i = 0; i < len; i++)
1736             {
1737               if (pos >= _dbus_string_get_length (str))
1738                 {
1739                   _dbus_verbose ("not enough values in dict\n");
1740                   return FALSE;
1741                 }
1742
1743               if (_dbus_string_get_byte (str, pos) == DBUS_TYPE_NIL)
1744                 {
1745                   _dbus_verbose ("can't have NIL values in dicts\n");
1746                   return FALSE;
1747                 }
1748               
1749               if (!_dbus_marshal_validate_arg (str, byte_order, pos, &pos))
1750                 return FALSE;
1751             }
1752
1753           *end_pos = pos;
1754
1755           break;
1756         }
1757         
1758     default:
1759       _dbus_verbose ("Unknown message arg type %d\n", *data);
1760       return FALSE;
1761     }
1762
1763   if (*end_pos > _dbus_string_get_length (str))
1764     return FALSE;
1765   
1766   return TRUE;
1767 }
1768
1769
1770 /**
1771  * If in verbose mode, print a block of binary data.
1772  *
1773  * @todo right now it prints even if not in verbose mode
1774  * 
1775  * @param data the data
1776  * @param len the length of the data
1777  */
1778 void
1779 _dbus_verbose_bytes (const unsigned char *data,
1780                      int                  len)
1781 {
1782   int i;
1783   const unsigned char *aligned;
1784
1785   _dbus_assert (len >= 0);
1786   
1787   /* Print blanks on first row if appropriate */
1788   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1789   if (aligned > data)
1790     aligned -= 4;
1791   _dbus_assert (aligned <= data);
1792
1793   if (aligned != data)
1794     {
1795       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1796       while (aligned != data)
1797         {
1798           _dbus_verbose ("    ");
1799           ++aligned;
1800         }
1801     }
1802
1803   /* now print the bytes */
1804   i = 0;
1805   while (i < len)
1806     {
1807       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1808         {
1809           _dbus_verbose ("%4d\t%p: ",
1810                    i, &data[i]);
1811         }
1812       
1813       if (data[i] >= 32 &&
1814           data[i] <= 126)
1815         _dbus_verbose (" '%c' ", data[i]);
1816       else
1817         _dbus_verbose ("0x%s%x ",
1818                  data[i] <= 0xf ? "0" : "", data[i]);
1819
1820       ++i;
1821
1822       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1823         {
1824           if (i > 3)
1825             _dbus_verbose ("BE: %d LE: %d",
1826                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1827                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1828
1829           if (i > 7 && 
1830               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1831             {
1832               _dbus_verbose (" dbl: %g",
1833                              *(double*)&data[i-8]);
1834             }
1835           
1836           _dbus_verbose ("\n");
1837         }
1838     }
1839
1840   _dbus_verbose ("\n");
1841 }
1842
1843 /**
1844  * Dump the given part of the string to verbose log.
1845  *
1846  * @param str the string
1847  * @param start the start of range to dump
1848  * @param len length of range
1849  */
1850 void
1851 _dbus_verbose_bytes_of_string (const DBusString    *str,
1852                                int                  start,
1853                                int                  len)
1854 {
1855   const char *d;
1856   int real_len;
1857
1858   real_len = _dbus_string_get_length (str);
1859
1860   _dbus_assert (start >= 0);
1861   
1862   if (start > real_len)
1863     {
1864       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1865                      start, len, real_len);
1866       return;
1867     }
1868
1869   if ((start + len) > real_len)
1870     {
1871       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1872                      start, len, real_len);
1873       len = real_len - start;
1874     }
1875   
1876   
1877   _dbus_string_get_const_data_len (str, &d, start, len);
1878
1879   _dbus_verbose_bytes (d, len);
1880 }
1881
1882 /** @} */
1883
1884 #ifdef DBUS_BUILD_TESTS
1885 #include "dbus-test.h"
1886 #include <stdio.h>
1887
1888 dbus_bool_t
1889 _dbus_marshal_test (void)
1890 {
1891   DBusString str;
1892   char *tmp1, *tmp2;
1893   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1894   int pos = 0, i, len;
1895   dbus_bool_t our_bool;
1896   dbus_int32_t our_int;
1897   dbus_uint32_t our_uint;
1898   double our_double;
1899   const char *our_string;
1900   const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
1901   const unsigned char *our_boolean_array;
1902   const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
1903   const dbus_int32_t *our_int32_array;
1904   const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
1905   const dbus_uint32_t *our_uint32_array;
1906   const double double_array[] = { 3.14159, 1.2345, 6.7890 };
1907   const double *our_double_array;
1908   const char *string_array[] = { "This", "Is", "A", "Test" };
1909   const char **our_string_array;
1910   DBusDict *dict;
1911   
1912   if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1913     _dbus_assert_not_reached ("failed to init string");
1914
1915   /* Marshal doubles */
1916   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1917     _dbus_assert_not_reached ("could not marshal double value");
1918   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1919     _dbus_assert_not_reached ("demarshal failed");
1920
1921   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1922     _dbus_assert_not_reached ("could not marshal double value");
1923   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1924     _dbus_assert_not_reached ("demarshal failed");
1925   
1926   /* Marshal signed integers */
1927   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1928     _dbus_assert_not_reached ("could not marshal signed integer value");
1929   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1930     _dbus_assert_not_reached ("demarshal failed");
1931
1932   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1933     _dbus_assert_not_reached ("could not marshal signed integer value");
1934   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1935     _dbus_assert_not_reached ("demarshal failed");
1936   
1937   /* Marshal unsigned integers */
1938   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1939     _dbus_assert_not_reached ("could not marshal signed integer value");
1940   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1941     _dbus_assert_not_reached ("demarshal failed");
1942   
1943   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1944     _dbus_assert_not_reached ("could not marshal signed integer value");
1945   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1946     _dbus_assert_not_reached ("demarshal failed");
1947
1948   /* Marshal strings */
1949   tmp1 = "This is the dbus test string";
1950   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1951     _dbus_assert_not_reached ("could not marshal string");
1952   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1953   if (!strcmp (tmp1, tmp2) == 0)
1954     _dbus_assert_not_reached ("demarshal failed");
1955   dbus_free (tmp2);
1956
1957   tmp1 = "This is the dbus test string";
1958   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1959     _dbus_assert_not_reached ("could not marshal string");
1960   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1961   if (!strcmp (tmp1, tmp2) == 0)
1962     _dbus_assert_not_reached ("demarshal failed");
1963   dbus_free (tmp2);
1964
1965   /* Marshal signed integer arrays */
1966   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1967     _dbus_assert_not_reached ("could not marshal integer array");
1968   array2 = _dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &len);
1969
1970   if (len != 3)
1971     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1972   dbus_free (array2);
1973   
1974
1975   /* Marshal dicts */
1976   dict = dbus_dict_new ();
1977
1978   if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
1979     _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
1980   
1981   if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
1982     _dbus_assert_not_reached ("could not add boolean value");
1983
1984   if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
1985     _dbus_assert_not_reached ("could not add int32 value");
1986
1987   if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
1988     _dbus_assert_not_reached ("could not add uint32 value");
1989
1990   if (!dbus_dict_set_double (dict, "double", 3.14159))
1991     _dbus_assert_not_reached ("could not add double value");
1992
1993   if (!dbus_dict_set_string (dict, "string", "test string"))
1994     _dbus_assert_not_reached ("could not add string value");
1995
1996   if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
1997     _dbus_assert_not_reached ("could not add boolean array");
1998
1999   if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
2000     _dbus_assert_not_reached ("could not add int32 array");
2001
2002   if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
2003     _dbus_assert_not_reached ("could not add uint32 array");
2004
2005   if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
2006     _dbus_assert_not_reached ("could not add double array");
2007
2008   if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
2009     _dbus_assert_not_reached ("could not add string array");
2010
2011   if (!_dbus_marshal_dict (&str, DBUS_BIG_ENDIAN, dict))
2012     _dbus_assert_not_reached ("could not marshal dict");
2013   
2014   dbus_dict_unref (dict);
2015   
2016   dict = _dbus_demarshal_dict (&str, DBUS_BIG_ENDIAN, pos, &pos);
2017
2018   if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
2019       !our_bool)
2020     _dbus_assert_not_reached ("could not get boolean value");
2021
2022   if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
2023     _dbus_assert_not_reached ("could not get int32 value or int32 values differ");
2024   
2025   if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
2026     _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
2027
2028   if (!dbus_dict_get_double (dict, "double", &our_double)
2029       || our_double != 3.14159)
2030      _dbus_assert_not_reached ("could not get double value or double values differ");
2031
2032   if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
2033     _dbus_assert_not_reached ("could not get string value or string values differ");
2034
2035   if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
2036       len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
2037     _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
2038
2039   if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
2040       len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
2041     _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
2042
2043   if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
2044       len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
2045     _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
2046
2047   if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
2048       len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
2049     _dbus_assert_not_reached ("could not get double array value or double array values differ");
2050
2051   if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
2052     _dbus_assert_not_reached ("could not get string array value");
2053
2054   if (len != 4)
2055     _dbus_assert_not_reached ("string array lengths differ");
2056
2057   for (i = 0; i < len; i++)
2058     {
2059       if (strcmp (our_string_array[i], string_array[i]) != 0)
2060         _dbus_assert_not_reached ("string array fields differ");
2061     }
2062   
2063   dbus_dict_unref (dict);
2064   
2065   _dbus_string_free (&str);
2066   
2067       
2068   return TRUE;
2069 }
2070
2071 #endif /* DBUS_BUILD_TESTS */