delete some more noise, put args in consistent order (a big bug trap sadly),
[platform/upstream/dbus.git] / dbus / dbus-marshal-basic.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-basic.c  Marshalling routines for basic (primitive) types
3  *
4  * Copyright (C) 2002 CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-internals.h"
26 #include "dbus-marshal-basic.h"
27
28 #include <string.h>
29
30 /**
31  * @defgroup DBusMarshal marshaling and unmarshaling
32  * @ingroup  DBusInternals
33  * @brief functions to marshal/unmarshal data from the wire
34  *
35  * Types and functions related to converting primitive data types from
36  * wire format to native machine format, and vice versa.
37  *
38  * A signature is just a string with multiple types one after the other.
39  * for example a type is "i" or "(ii)", a signature is "i(ii)"
40  * where i is int and (ii) is struct { int; int; }
41  *
42  * @{
43  */
44
45 static void
46 pack_4_octets (dbus_uint32_t   value,
47                int             byte_order,
48                unsigned char  *data)
49 {
50   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
51
52   if ((byte_order) == DBUS_LITTLE_ENDIAN)
53     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
54   else
55     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
56 }
57
58 static void
59 pack_8_octets (DBusBasicValue     value,
60                int                byte_order,
61                unsigned char     *data)
62 {
63   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
64
65 #ifdef DBUS_HAVE_INT64
66   if ((byte_order) == DBUS_LITTLE_ENDIAN)
67     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
68   else
69     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
70 #else
71   *(DBus8ByteStruct*)data = value.u64;
72   swap_8_octets ((DBusBasicValue*)data, byte_order);
73 #endif
74 }
75
76 /**
77  * Packs a 32 bit unsigned integer into a data pointer.
78  *
79  * @param value the value
80  * @param byte_order the byte order to use
81  * @param data the data pointer
82  */
83 void
84 _dbus_pack_uint32 (dbus_uint32_t   value,
85                    int             byte_order,
86                    unsigned char  *data)
87 {
88   pack_4_octets (value, byte_order, data);
89 }
90
91 /**
92  * Packs a 32 bit signed integer into a data pointer.
93  *
94  * @param value the value
95  * @param byte_order the byte order to use
96  * @param data the data pointer
97  */
98 void
99 _dbus_pack_int32 (dbus_int32_t   value,
100                   int            byte_order,
101                   unsigned char *data)
102 {
103   pack_4_octets ((dbus_uint32_t) value, byte_order, data);
104 }
105
106 static dbus_uint32_t
107 unpack_4_octets (int                  byte_order,
108                  const unsigned char *data)
109 {
110   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
111
112   if (byte_order == DBUS_LITTLE_ENDIAN)
113     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
114   else
115     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
116 }
117
118 #ifndef DBUS_HAVE_INT64
119 /* from ORBit */
120 static void
121 swap_bytes (unsigned char *data,
122             unsigned int   len)
123 {
124   unsigned char *p1 = data;
125   unsigned char *p2 = data + len - 1;
126
127   while (p1 < p2)
128     {
129       unsigned char tmp = *p1;
130       *p1 = *p2;
131       *p2 = tmp;
132
133       --p2;
134       ++p1;
135     }
136 }
137 #endif /* !DBUS_HAVE_INT64 */
138
139 static void
140 swap_8_octets (DBusBasicValue    *value,
141                int                byte_order)
142 {
143   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
144     {
145 #ifdef DBUS_HAVE_INT64
146       value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
147 #else
148       swap_bytes ((unsigned char *)value, 8);
149 #endif
150     }
151 }
152
153 static DBusBasicValue
154 unpack_8_octets (int                  byte_order,
155                  const unsigned char *data)
156 {
157   DBusBasicValue r;
158
159   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
160   _dbus_assert (sizeof (r) == 8);
161
162 #ifdef DBUS_HAVE_INT64
163   if (byte_order == DBUS_LITTLE_ENDIAN)
164     r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
165   else
166     r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
167 #else
168   r.u64 = *(DBus8ByteStruct*)data;
169   swap_8_octets (&r, byte_order);
170 #endif
171
172   return r;
173 }
174
175 /**
176  * Unpacks a 32 bit unsigned integer from a data pointer
177  *
178  * @param byte_order The byte order to use
179  * @param data the data pointer
180  * @returns the integer
181  */
182 dbus_uint32_t
183 _dbus_unpack_uint32 (int                  byte_order,
184                      const unsigned char *data)
185 {
186   return unpack_4_octets (byte_order, data);
187 }
188
189 /**
190  * Unpacks a 32 bit signed integer from a data pointer
191  *
192  * @param byte_order The byte order to use
193  * @param data the data pointer
194  * @returns the integer
195  */
196 dbus_int32_t
197 _dbus_unpack_int32 (int                  byte_order,
198                     const unsigned char *data)
199 {
200   return (dbus_int32_t) unpack_4_octets (byte_order, data);
201 }
202
203 static void
204 set_4_octets (DBusString          *str,
205               int                  offset,
206               dbus_uint32_t        value,
207               int                  byte_order)
208 {
209   char *data;
210
211   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
212                 byte_order == DBUS_BIG_ENDIAN);
213
214   data = _dbus_string_get_data_len (str, offset, 4);
215
216   _dbus_pack_uint32 (value, byte_order, data);
217 }
218
219 static void
220 set_8_octets (DBusString          *str,
221               int                  offset,
222               DBusBasicValue       value,
223               int                  byte_order)
224 {
225   char *data;
226
227   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
228                 byte_order == DBUS_BIG_ENDIAN);
229
230   data = _dbus_string_get_data_len (str, offset, 8);
231
232   pack_8_octets (value, byte_order, data);
233 }
234
235 /**
236  * Sets the 4 bytes at the given offset to a marshaled unsigned
237  * integer, replacing anything found there previously.
238  *
239  * @param str the string to write the marshalled int to
240  * @param pos the byte offset where int should be written
241  * @param value the value
242  * @param byte_order the byte order to use
243  *
244  */
245 void
246 _dbus_marshal_set_uint32 (DBusString          *str,
247                           int                  pos,
248                           dbus_uint32_t        value,
249                           int                  byte_order)
250 {
251   set_4_octets (str, pos, value, byte_order);
252 }
253
254 /**
255  * Sets the existing marshaled string at the given offset with
256  * a new marshaled string. The given offset must point to
257  * an existing string or the wrong length will be deleted
258  * and replaced with the new string.
259  *
260  * Note: no attempt is made by this function to re-align
261  * any data which has been already marshalled after this
262  * string. Use with caution.
263  *
264  * @param str the string to write the marshalled string to
265  * @param pos the position of the marshaled string length
266  * @param value the value
267  * @param byte_order the byte order to use
268  * @param old_end_pos place to store byte after the nul byte of the old value
269  * @param new_end_pos place to store byte after the nul byte of the new value
270  * @returns #TRUE on success, #FALSE if no memory
271  *
272  */
273 static dbus_bool_t
274 set_string (DBusString          *str,
275             int                  pos,
276             const char          *value,
277             int                  byte_order,
278             int                 *old_end_pos,
279             int                 *new_end_pos)
280 {
281   int old_len, new_len;
282   DBusString dstr;
283
284   _dbus_string_init_const (&dstr, value);
285
286   old_len = _dbus_demarshal_uint32 (str, pos, byte_order, NULL);
287
288   new_len = _dbus_string_get_length (&dstr);
289
290   if (!_dbus_string_replace_len (&dstr, 0, new_len,
291                                  str, pos + 4, old_len))
292     return FALSE;
293
294   _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
295
296   if (old_end_pos)
297     *old_end_pos = pos + 4 + old_len + 1;
298   if (new_end_pos)
299     *new_end_pos = pos + 4 + new_len + 1;
300
301   return TRUE;
302 }
303
304 /**
305  * Sets the existing marshaled signature at the given offset to a new
306  * marshaled signature. Same basic ideas as set_string().
307  *
308  * @param str the string to write the marshalled signature to
309  * @param pos the position of the marshaled signature length
310  * @param value the value
311  * @param byte_order the byte order to use
312  * @param old_end_pos place to store byte after the nul byte of the old value
313  * @param new_end_pos place to store byte after the nul byte of the new value
314  * @returns #TRUE on success, #FALSE if no memory
315  *
316  */
317 static dbus_bool_t
318 set_signature (DBusString          *str,
319                int                  pos,
320                const char          *value,
321                int                  byte_order,
322                int                 *old_end_pos,
323                int                 *new_end_pos)
324 {
325   int old_len, new_len;
326   DBusString dstr;
327
328   _dbus_string_init_const (&dstr, value);
329
330   old_len = _dbus_string_get_byte (str, pos);
331   new_len = _dbus_string_get_length (&dstr);
332
333   if (!_dbus_string_replace_len (&dstr, 0, new_len,
334                                  str, pos + 1, old_len))
335     return FALSE;
336
337   _dbus_string_set_byte (str, pos, new_len);
338
339   if (old_end_pos)
340     *old_end_pos = pos + 1 + old_len + 1;
341   if (new_end_pos)
342     *new_end_pos = pos + 1 + new_len + 1;
343
344   return TRUE;
345 }
346
347 /**
348  * Sets an existing basic type value to a new value.
349  * Arguments work the same way as _dbus_marshal_basic_type().
350  *
351  * @param str the string
352  * @param pos location of the current value
353  * @param type the type of the current and new values
354  * @param value the address of the new value
355  * @param byte_order byte order for marshaling
356  * @param old_end_pos location to store end position of the old value, or #NULL
357  * @param new_end_pos location to store end position of the new value, or #NULL
358  * @returns #FALSE if no memory
359  */
360 dbus_bool_t
361 _dbus_marshal_set_basic_type (DBusString       *str,
362                               int               pos,
363                               int               type,
364                               const void       *value,
365                               int               byte_order,
366                               int              *old_end_pos,
367                               int              *new_end_pos)
368 {
369   const DBusBasicValue *vp;
370
371   vp = value;
372
373   switch (type)
374     {
375     case DBUS_TYPE_BYTE:
376     case DBUS_TYPE_BOOLEAN:
377       _dbus_string_set_byte (str, pos, vp->byt);
378       if (old_end_pos)
379         *old_end_pos = pos + 1;
380       if (new_end_pos)
381         *new_end_pos = pos + 1;
382       return TRUE;
383       break;
384     case DBUS_TYPE_INT32:
385     case DBUS_TYPE_UINT32:
386       set_4_octets (str, pos, vp->u32, byte_order);
387       if (old_end_pos)
388         *old_end_pos = pos + 4;
389       if (new_end_pos)
390         *new_end_pos = pos + 4;
391       return TRUE;
392       break;
393     case DBUS_TYPE_INT64:
394     case DBUS_TYPE_UINT64:
395     case DBUS_TYPE_DOUBLE:
396       {
397         set_8_octets (str, pos, *vp, byte_order);
398         if (old_end_pos)
399         *old_end_pos = pos + 8;
400         if (new_end_pos)
401           *new_end_pos = pos + 8;
402         return TRUE;
403       }
404       break;
405     case DBUS_TYPE_STRING:
406     case DBUS_TYPE_OBJECT_PATH:
407       return set_string (str, pos, vp->str, byte_order,
408                          old_end_pos, new_end_pos);
409       break;
410     case DBUS_TYPE_SIGNATURE:
411       return set_signature (str, pos, vp->str, byte_order,
412                             old_end_pos, new_end_pos);
413       break;
414     default:
415       _dbus_assert_not_reached ("not a basic type");
416       return FALSE;
417       break;
418     }
419 }
420
421 static dbus_uint32_t
422 demarshal_4_octets (const DBusString *str,
423                     int               pos,
424                     int               byte_order,
425                     int              *new_pos)
426 {
427   pos = _DBUS_ALIGN_VALUE (pos, 4);
428
429   if (new_pos)
430     *new_pos = pos + 4;
431
432   return unpack_4_octets (byte_order,
433                           _dbus_string_get_const_data (str) + pos);
434 }
435
436 /**
437  * Convenience function to demarshal a 32 bit unsigned integer.
438  *
439  * @param str the string containing the data
440  * @param byte_order the byte order
441  * @param pos the position in the string
442  * @param new_pos the new position of the string
443  * @returns the demarshaled integer.
444  */
445 dbus_uint32_t
446 _dbus_demarshal_uint32  (const DBusString *str,
447                          int               pos,
448                          int               byte_order,
449                          int              *new_pos)
450 {
451   return demarshal_4_octets (str, pos, byte_order, new_pos);
452 }
453
454 /**
455  * Demarshals a basic type. The "value" pointer is always
456  * the address of a variable of the basic type. So e.g.
457  * if the basic type is "double" then the pointer is
458  * a double*, and if it's "char*" then the pointer is
459  * a "char**".
460  *
461  * A value of type #DBusBasicValue is guaranteed to be large enough to
462  * hold any of the types that may be returned, which is handy if you
463  * are trying to do things generically. For example you can pass
464  * a DBusBasicValue* in to this function, and then pass the same
465  * DBusBasicValue* in to _dbus_marshal_basic_type() in order to
466  * move a value from one place to another.
467  *
468  * @param str the string containing the data
469  * @param pos position in the string
470  * @param type type of value to demarshal
471  * @param value pointer to return value data
472  * @param byte_order the byte order
473  * @param new_pos pointer to update with new position, or #NULL
474  **/
475 void
476 _dbus_demarshal_basic_type (const DBusString      *str,
477                             int                    pos,
478                             int                    type,
479                             void                  *value,
480                             int                    byte_order,
481                             int                   *new_pos)
482 {
483   const char *str_data;
484   DBusBasicValue *vp;
485
486   _dbus_assert (_dbus_type_is_basic (type));
487
488   str_data = _dbus_string_get_const_data (str);
489   vp = value;
490
491   switch (type)
492     {
493     case DBUS_TYPE_BYTE:
494     case DBUS_TYPE_BOOLEAN:
495       vp->byt = _dbus_string_get_byte (str, pos);
496       (pos)++;
497       break;
498     case DBUS_TYPE_INT32:
499     case DBUS_TYPE_UINT32:
500       pos = _DBUS_ALIGN_VALUE (pos, 4);
501       vp->u32 = *(dbus_uint32_t *)(str_data + pos);
502       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
503         vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32);
504       pos += 4;
505       break;
506     case DBUS_TYPE_INT64:
507     case DBUS_TYPE_UINT64:
508     case DBUS_TYPE_DOUBLE:
509       pos = _DBUS_ALIGN_VALUE (pos, 8);
510 #ifdef DBUS_HAVE_INT64
511       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
512         vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
513       else
514         vp->u64 = *(dbus_uint64_t*)(str_data + pos);
515 #else
516       vp->u64 = *(DBus8ByteStruct*) (str_data + pos);
517       swap_8_octets (vp, byte_order);
518 #endif
519       pos += 8;
520       break;
521     case DBUS_TYPE_STRING:
522     case DBUS_TYPE_OBJECT_PATH:
523       {
524         int len;
525
526         len = _dbus_demarshal_uint32 (str, pos, byte_order, &pos);
527
528         vp->str = (char*) str_data + pos;
529
530         pos += len + 1; /* length plus nul */
531       }
532       break;
533     case DBUS_TYPE_SIGNATURE:
534       {
535         int len;
536
537         len = _dbus_string_get_byte (str, pos);
538         pos += 1;
539
540         vp->str = (char*) str_data + pos;
541
542         pos += len + 1; /* length plus nul */
543       }
544       break;
545     default:
546       _dbus_warn ("type %s not a basic type\n",
547                   _dbus_type_to_string (type));
548       _dbus_assert_not_reached ("not a basic type");
549       break;
550     }
551
552   if (new_pos)
553     *new_pos = pos;
554 }
555
556 static dbus_bool_t
557 marshal_4_octets (DBusString   *str,
558                   int           insert_at,
559                   dbus_uint32_t value,
560                   int           byte_order,
561                   int          *pos_after)
562 {
563   dbus_bool_t retval;
564   int orig_len;
565
566   _dbus_assert (sizeof (value) == 4);
567
568   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
569     value = DBUS_UINT32_SWAP_LE_BE (value);
570
571   orig_len = _dbus_string_get_length (str);
572
573   retval = _dbus_string_insert_4_aligned (str, insert_at,
574                                           (const unsigned char *)&value);
575
576   if (pos_after)
577     {
578       *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
579       _dbus_assert (*pos_after <= _dbus_string_get_length (str));
580     }
581
582   return retval;
583 }
584
585 static dbus_bool_t
586 marshal_8_octets (DBusString    *str,
587                   int            insert_at,
588                   DBusBasicValue value,
589                   int            byte_order,
590                   int           *pos_after)
591 {
592   dbus_bool_t retval;
593   int orig_len;
594
595   _dbus_assert (sizeof (value) == 8);
596
597   swap_8_octets (&value, byte_order);
598
599   orig_len = _dbus_string_get_length (str);
600
601   retval = _dbus_string_insert_8_aligned (str, insert_at,
602                                           (const unsigned char *)&value);
603
604   if (pos_after)
605     *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
606
607   return retval;
608 }
609
610 enum
611   {
612     MARSHAL_AS_STRING,
613     MARSHAL_AS_SIGNATURE,
614     MARSHAL_AS_BYTE_ARRAY
615   };
616
617 static dbus_bool_t
618 marshal_len_followed_by_bytes (int                  marshal_as,
619                                DBusString          *str,
620                                int                  insert_at,
621                                const unsigned char *value,
622                                int                  data_len, /* doesn't include nul if any */
623                                int                  byte_order,
624                                int                 *pos_after)
625 {
626   int pos;
627   DBusString value_str;
628   int value_len;
629
630   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
631   if (insert_at > _dbus_string_get_length (str))
632     _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
633                 insert_at, _dbus_string_get_length (str), data_len);
634
635   if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
636     value_len = data_len;
637   else
638     value_len = data_len + 1; /* value has a nul */
639
640   /* FIXME this is probably broken for byte arrays because
641    * DBusString wants strings to be nul-terminated?
642    * Maybe I planned on this when writing init_const_len though
643    */
644   _dbus_string_init_const_len (&value_str, value, value_len);
645
646   pos = insert_at;
647
648   if (marshal_as == MARSHAL_AS_SIGNATURE)
649     {
650       if (!_dbus_string_insert_byte (str, pos, data_len))
651         goto oom;
652
653       pos += 1;
654     }
655   else
656     {
657       if (!marshal_4_octets (str, pos, data_len,
658                              byte_order, &pos))
659         goto oom;
660     }
661
662   if (!_dbus_string_copy_len (&value_str, 0, value_len,
663                               str, pos))
664     goto oom;
665
666 #if 1
667   /* too expensive */
668   _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
669                                               str, pos));
670   _dbus_verbose_bytes_of_string (str, pos, value_len);
671 #endif
672
673   pos += value_len;
674
675   if (pos_after)
676     *pos_after = pos;
677
678   return TRUE;
679
680  oom:
681   /* Delete what we've inserted */
682   _dbus_string_delete (str, insert_at, pos - insert_at);
683
684   return FALSE;
685 }
686
687 static dbus_bool_t
688 marshal_string (DBusString    *str,
689                 int            insert_at,
690                 const char    *value,
691                 int            byte_order,
692                 int           *pos_after)
693 {
694   return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
695                                         str, insert_at, value,
696                                         strlen (value),
697                                         byte_order, pos_after);
698 }
699
700 static dbus_bool_t
701 marshal_signature (DBusString    *str,
702                    int            insert_at,
703                    const char    *value,
704                    int           *pos_after)
705 {
706   return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
707                                         str, insert_at, value,
708                                         strlen (value),
709                                         DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
710                                         pos_after);
711 }
712
713 /**
714  * Marshals a basic type. The "value" pointer is always the
715  * address of a variable containing the basic type value.
716  * So for example for int32 it will be dbus_int32_t*, and
717  * for string it will be const char**. This is for symmetry
718  * with _dbus_demarshal_basic_type() and to have a simple
719  * consistent rule.
720  *
721  * @param str string to marshal to
722  * @param insert_at where to insert the value
723  * @param type type of value
724  * @param value pointer to a variable containing the value
725  * @param byte_order byte order
726  * @param pos_after #NULL or the position after the type
727  * @returns #TRUE on success
728  **/
729 dbus_bool_t
730 _dbus_marshal_basic_type (DBusString *str,
731                           int         insert_at,
732                           int         type,
733                           const void *value,
734                           int         byte_order,
735                           int        *pos_after)
736 {
737   const DBusBasicValue *vp;
738
739   _dbus_assert (_dbus_type_is_basic (type));
740
741   vp = value;
742
743   switch (type)
744     {
745     case DBUS_TYPE_BYTE:
746     case DBUS_TYPE_BOOLEAN:
747       if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
748         return FALSE;
749       if (pos_after)
750         *pos_after = insert_at + 1;
751       return TRUE;
752       break;
753     case DBUS_TYPE_INT32:
754     case DBUS_TYPE_UINT32:
755       return marshal_4_octets (str, insert_at, vp->u32,
756                                byte_order, pos_after);
757       break;
758     case DBUS_TYPE_INT64:
759     case DBUS_TYPE_UINT64:
760     case DBUS_TYPE_DOUBLE:
761       return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
762       break;
763
764     case DBUS_TYPE_STRING:
765     case DBUS_TYPE_OBJECT_PATH:
766       return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
767       break;
768     case DBUS_TYPE_SIGNATURE:
769       return marshal_signature (str, insert_at, vp->str, pos_after);
770       break;
771     default:
772       _dbus_assert_not_reached ("not a basic type");
773       return FALSE;
774       break;
775     }
776 }
777
778 static dbus_bool_t
779 marshal_1_octets_array (DBusString          *str,
780                         int                  insert_at,
781                         const unsigned char *value,
782                         int                  len,
783                         int                  byte_order,
784                         int                 *pos_after)
785 {
786   return marshal_len_followed_by_bytes (MARSHAL_AS_BYTE_ARRAY,
787                                         str, insert_at, value, len,
788                                         byte_order, pos_after);
789 }
790
791 static dbus_bool_t
792 marshal_4_octets_array (DBusString          *str,
793                         int                  insert_at,
794                         const dbus_uint32_t *value,
795                         int                  len,
796                         int                  byte_order)
797 {
798   int old_string_len;
799   int array_start;
800
801   _dbus_assert_not_reached ("FIXME insert_at");
802
803   old_string_len = _dbus_string_get_length (str);
804
805   if (!marshal_4_octets (str, insert_at, len*4, byte_order, NULL))
806     goto error;
807
808   array_start = _dbus_string_get_length (str);
809
810   if (!_dbus_string_append_len (str, (const unsigned char*) value,
811                                 len * 4))
812     goto error;
813
814   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
815     {
816       const unsigned char *d;
817       const unsigned char *end;
818
819       d = _dbus_string_get_data (str) + array_start;
820       end = d + len * 4;
821       while (d != end)
822         {
823           *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
824           d += 4;
825         }
826     }
827
828   return TRUE;
829
830  error:
831   /* Restore previous length */
832   _dbus_string_set_length (str, old_string_len);
833
834   return FALSE;
835 }
836
837 static dbus_bool_t
838 marshal_8_octets_array (DBusString           *str,
839                         int                   insert_at,
840                         const DBusBasicValue *value,
841                         int                   len,
842                         int                   byte_order)
843 {
844   int old_string_len;
845   int array_start;
846
847   _dbus_assert_not_reached ("FIXME insert_at");
848
849   old_string_len = _dbus_string_get_length (str);
850
851   /*  The array length is the length in bytes of the array,
852    * *excluding* alignment padding.
853    */
854   if (!marshal_4_octets (str, insert_at, len*8, byte_order, NULL))
855     goto error;
856
857   array_start = _dbus_string_get_length (str);
858
859   /* Note that we do alignment padding unconditionally
860    * even if the array is empty; this means that
861    * padding + len is always equal to the number of bytes
862    * in the array.
863    */
864
865   if (!_dbus_string_align_length (str, 8))
866     goto error;
867
868   if (!_dbus_string_append_len (str, (const unsigned char*) value,
869                                 len * 8))
870     goto error;
871
872   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
873     {
874       const unsigned char *d;
875       const unsigned char *end;
876
877       d = _dbus_string_get_data (str) + array_start;
878       end = d + len * 8;
879       while (d != end)
880         {
881 #ifdef DBUS_HAVE_INT64
882           *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
883 #else
884           swap_8_bytes ((DBusBasicValue*) d);
885 #endif
886           d += 8;
887         }
888     }
889
890   return TRUE;
891
892  error:
893   /* Restore previous length */
894   _dbus_string_set_length (str, old_string_len);
895
896   return FALSE;
897 }
898
899 /**
900  * Marshals a basic type array
901  *
902  * @param str string to marshal to
903  * @param insert_at where to insert the value
904  * @param element_type type of array elements
905  * @param value pointer to value
906  * @param len length of value data in elements
907  * @param byte_order byte order
908  * @param pos_after #NULL or the position after the type
909  * @returns #TRUE on success
910  **/
911 dbus_bool_t
912 _dbus_marshal_basic_type_array (DBusString *str,
913                                 int         insert_at,
914                                 int         element_type,
915                                 const void *value,
916                                 int         len,
917                                 int         byte_order,
918                                 int        *pos_after)
919 {
920   /* FIXME use the insert_at arg and fill in pos_after */
921
922   switch (element_type)
923     {
924     case DBUS_TYPE_BOOLEAN:
925       /* FIXME: we canonicalize to 0 or 1 for the single boolean case
926        * should we here too ? */
927     case DBUS_TYPE_BYTE:
928       return marshal_1_octets_array (str, insert_at, value, len, byte_order, pos_after);
929       break;
930     case DBUS_TYPE_INT32:
931     case DBUS_TYPE_UINT32:
932       return marshal_4_octets_array (str, insert_at, value, len, byte_order);
933       break;
934     case DBUS_TYPE_INT64:
935     case DBUS_TYPE_UINT64:
936     case DBUS_TYPE_DOUBLE:
937       return marshal_8_octets_array (str, insert_at, value, len, byte_order);
938       break;
939
940     case DBUS_TYPE_STRING:
941     case DBUS_TYPE_OBJECT_PATH:
942       _dbus_assert_not_reached ("handle string arrays");
943       break;
944
945     case DBUS_TYPE_SIGNATURE:
946       _dbus_assert_not_reached ("handle signature");
947       break;
948
949     default:
950       _dbus_assert_not_reached ("non basic type in array");
951       break;
952     }
953
954   return FALSE;
955 }
956
957
958 /**
959  * Skips over a basic type, reporting the following position.
960  *
961  * @param str the string containing the data
962  * @param type type of value to demarshal
963  * @param byte_order the byte order
964  * @param pos pointer to position in the string,
965  *            updated on return to new position
966  **/
967 void
968 _dbus_marshal_skip_basic_type (const DBusString      *str,
969                                int                    type,
970                                int                    byte_order,
971                                int                   *pos)
972 {
973   switch (type)
974     {
975     case DBUS_TYPE_BYTE:
976     case DBUS_TYPE_BOOLEAN:
977       (*pos)++;
978       break;
979     case DBUS_TYPE_INT32:
980     case DBUS_TYPE_UINT32:
981       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
982       *pos += 4;
983       break;
984     case DBUS_TYPE_INT64:
985     case DBUS_TYPE_UINT64:
986     case DBUS_TYPE_DOUBLE:
987       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
988       *pos += 8;
989       break;
990     case DBUS_TYPE_STRING:
991     case DBUS_TYPE_OBJECT_PATH:
992       {
993         int len;
994
995         len = _dbus_demarshal_uint32 (str, *pos, byte_order, pos);
996
997         *pos += len + 1; /* length plus nul */
998       }
999       break;
1000     case DBUS_TYPE_SIGNATURE:
1001       {
1002         int len;
1003
1004         len = _dbus_string_get_byte (str, *pos);
1005
1006         *pos += len + 2; /* length byte plus length plus nul */
1007       }
1008       break;
1009     default:
1010       _dbus_warn ("type %s not a basic type\n",
1011                   _dbus_type_to_string (type));
1012       _dbus_assert_not_reached ("not a basic type");
1013       break;
1014     }
1015 }
1016
1017 /**
1018  * Skips an array, returning the next position.
1019  *
1020  * @param str the string containing the data
1021  * @param element_type the type of array elements
1022  * @param byte_order the byte order
1023  * @param pos pointer to position in the string,
1024  *            updated on return to new position
1025  */
1026 void
1027 _dbus_marshal_skip_array (const DBusString  *str,
1028                           int                element_type,
1029                           int                byte_order,
1030                           int               *pos)
1031 {
1032   dbus_uint32_t array_len;
1033   int i;
1034   int alignment;
1035
1036   i = _DBUS_ALIGN_VALUE (*pos, 4);
1037
1038   _dbus_demarshal_basic_type (str,
1039                               i,
1040                               DBUS_TYPE_UINT32,
1041                               &array_len,
1042                               byte_order,
1043                               &i);
1044
1045   alignment = _dbus_type_get_alignment (element_type);
1046
1047   i = _DBUS_ALIGN_VALUE (i, alignment);
1048
1049   *pos = i + array_len;
1050 }
1051
1052 /**
1053  * Gets the alignment requirement for the given type;
1054  * will be 1, 4, or 8.
1055  *
1056  * @param typecode the type
1057  * @returns alignment of 1, 4, or 8
1058  */
1059 int
1060 _dbus_type_get_alignment (int typecode)
1061 {
1062   switch (typecode)
1063     {
1064     case DBUS_TYPE_BYTE:
1065     case DBUS_TYPE_BOOLEAN:
1066     case DBUS_TYPE_VARIANT:
1067     case DBUS_TYPE_SIGNATURE:
1068       return 1;
1069     case DBUS_TYPE_INT32:
1070     case DBUS_TYPE_UINT32:
1071       /* this stuff is 4 since it starts with a length */
1072     case DBUS_TYPE_STRING:
1073     case DBUS_TYPE_OBJECT_PATH:
1074     case DBUS_TYPE_ARRAY:
1075       return 4;
1076     case DBUS_TYPE_INT64:
1077     case DBUS_TYPE_UINT64:
1078     case DBUS_TYPE_DOUBLE:
1079       /* struct is 8 since it could contain an 8-aligned item
1080        * and it's simpler to just always align structs to 8;
1081        * we want the amount of padding in a struct of a given
1082        * type to be predictable, not location-dependent.
1083        */
1084     case DBUS_TYPE_STRUCT:
1085       return 8;
1086
1087     default:
1088       _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1089       return 0;
1090     }
1091 }
1092
1093
1094 /**
1095  * Return #TRUE if the typecode is a valid typecode.
1096  * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and
1097  * random unknown bytes aren't either. This function is safe with
1098  * untrusted data.
1099  *
1100  * @returns #TRUE if valid
1101  */
1102 dbus_bool_t
1103 _dbus_type_is_valid (int typecode)
1104 {
1105   switch (typecode)
1106     {
1107     case DBUS_TYPE_BYTE:
1108     case DBUS_TYPE_BOOLEAN:
1109     case DBUS_TYPE_INT32:
1110     case DBUS_TYPE_UINT32:
1111     case DBUS_TYPE_INT64:
1112     case DBUS_TYPE_UINT64:
1113     case DBUS_TYPE_DOUBLE:
1114     case DBUS_TYPE_STRING:
1115     case DBUS_TYPE_OBJECT_PATH:
1116     case DBUS_TYPE_SIGNATURE:
1117     case DBUS_TYPE_ARRAY:
1118     case DBUS_TYPE_STRUCT:
1119     case DBUS_TYPE_VARIANT:
1120       return TRUE;
1121
1122     default:
1123       return FALSE;
1124     }
1125 }
1126
1127 #define TYPE_IS_CONTAINER(typecode)             \
1128     ((typecode) == DBUS_TYPE_STRUCT ||          \
1129      (typecode) == DBUS_TYPE_VARIANT ||         \
1130      (typecode) == DBUS_TYPE_ARRAY)
1131
1132 /**
1133  * A "container type" can contain basic types, or nested
1134  * container types. #DBUS_TYPE_INVALID is not a container type.
1135  * This function will crash if passed a typecode that isn't
1136  * in dbus-protocol.h
1137  *
1138  * @returns #TRUE if type is a container
1139  */
1140 dbus_bool_t
1141 _dbus_type_is_container (int typecode)
1142 {
1143   /* only reasonable (non-line-noise) typecodes are allowed */
1144   _dbus_assert (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID);
1145   return TYPE_IS_CONTAINER (typecode);
1146 }
1147
1148 /**
1149  * A "basic type" is a somewhat arbitrary concept, but the intent
1150  * is to include those types that are fully-specified by a single
1151  * typecode, with no additional type information or nested
1152  * values. So all numbers and strings are basic types and
1153  * structs, arrays, and variants are not basic types.
1154  * #DBUS_TYPE_INVALID is not a basic type.
1155  *
1156  * This function is defined to return #TRUE for exactly those
1157  * types that can be written with _dbus_marshal_basic_type()
1158  * and read with _dbus_demarshal_basic_type().
1159  *
1160  * This function will crash if passed a typecode that isn't
1161  * in dbus-protocol.h
1162  *
1163  * @returns #TRUE if type is basic
1164  */
1165 dbus_bool_t
1166 _dbus_type_is_basic (int typecode)
1167 {
1168   /* only reasonable (non-line-noise) typecodes are allowed */
1169   _dbus_assert (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID);
1170
1171   /* everything that isn't invalid or a container */
1172   return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
1173 }
1174
1175 /**
1176  * Tells you whether values of this type can change length if you set
1177  * them to some other value. For this purpose, you assume that the
1178  * first byte of the old and new value would be in the same location,
1179  * so alignment padding is not a factor.
1180  *
1181  * @returns #TRUE if the type can occupy different lengths
1182  */
1183 dbus_bool_t
1184 _dbus_type_length_varies (int typecode)
1185 {
1186   switch (typecode)
1187     {
1188     case DBUS_TYPE_BYTE:
1189     case DBUS_TYPE_BOOLEAN:
1190     case DBUS_TYPE_INT32:
1191     case DBUS_TYPE_UINT32:
1192     case DBUS_TYPE_INT64:
1193     case DBUS_TYPE_UINT64:
1194     case DBUS_TYPE_DOUBLE:
1195       return FALSE;
1196     default:
1197       return TRUE;
1198     }
1199 }
1200
1201 /**
1202  * If in verbose mode, print a block of binary data.
1203  *
1204  * @todo right now it prints even if not in verbose mode
1205  *
1206  * @param data the data
1207  * @param len the length of the data
1208  * @param offset where to start counting for byte indexes
1209  */
1210 void
1211 _dbus_verbose_bytes (const unsigned char *data,
1212                      int                  len,
1213                      int                  offset)
1214 {
1215   int i;
1216   const unsigned char *aligned;
1217
1218   _dbus_assert (len >= 0);
1219
1220   /* Print blanks on first row if appropriate */
1221   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1222   if (aligned > data)
1223     aligned -= 4;
1224   _dbus_assert (aligned <= data);
1225
1226   if (aligned != data)
1227     {
1228       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1229       while (aligned != data)
1230         {
1231           _dbus_verbose ("    ");
1232           ++aligned;
1233         }
1234     }
1235
1236   /* now print the bytes */
1237   i = 0;
1238   while (i < len)
1239     {
1240       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1241         {
1242           _dbus_verbose ("%4d\t%p: ",
1243                          offset + i, &data[i]);
1244         }
1245
1246       if (data[i] >= 32 &&
1247           data[i] <= 126)
1248         _dbus_verbose (" '%c' ", data[i]);
1249       else
1250         _dbus_verbose ("0x%s%x ",
1251                        data[i] <= 0xf ? "0" : "", data[i]);
1252
1253       ++i;
1254
1255       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1256         {
1257           if (i > 3)
1258             _dbus_verbose ("BE: %d LE: %d",
1259                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1260                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1261
1262           if (i > 7 &&
1263               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1264             {
1265               _dbus_verbose (" dbl: %g",
1266                              *(double*)&data[i-8]);
1267             }
1268
1269           _dbus_verbose ("\n");
1270         }
1271     }
1272
1273   _dbus_verbose ("\n");
1274 }
1275
1276 /**
1277  * Dump the given part of the string to verbose log.
1278  *
1279  * @param str the string
1280  * @param start the start of range to dump
1281  * @param len length of range
1282  */
1283 void
1284 _dbus_verbose_bytes_of_string (const DBusString    *str,
1285                                int                  start,
1286                                int                  len)
1287 {
1288   const char *d;
1289   int real_len;
1290
1291   real_len = _dbus_string_get_length (str);
1292
1293   _dbus_assert (start >= 0);
1294
1295   if (start > real_len)
1296     {
1297       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1298                      start, len, real_len);
1299       return;
1300     }
1301
1302   if ((start + len) > real_len)
1303     {
1304       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1305                      start, len, real_len);
1306       len = real_len - start;
1307     }
1308
1309   d = _dbus_string_get_const_data_len (str, start, len);
1310
1311   _dbus_verbose_bytes (d, len, start);
1312 }
1313
1314 /** @} */
1315
1316 #ifdef DBUS_BUILD_TESTS
1317 #include "dbus-test.h"
1318 #include <stdio.h>
1319
1320 #define MARSHAL_BASIC(typename, byte_order, literal)                    \
1321   do {                                                                  \
1322      v_##typename = literal;                                            \
1323      if (!_dbus_marshal_basic_type (&str, pos, DBUS_TYPE_##typename,    \
1324                                     &v_##typename,                      \
1325                                     byte_order, NULL))                  \
1326        _dbus_assert_not_reached ("no memory");                          \
1327    } while (0)
1328
1329 #define DEMARSHAL_BASIC(typename, byte_order)                                   \
1330   do {                                                                          \
1331     _dbus_demarshal_basic_type (&str, pos, DBUS_TYPE_##typename, &v_##typename, \
1332                                 byte_order, &pos);                              \
1333   } while (0)
1334
1335 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \
1336   do {                                                                                  \
1337     DEMARSHAL_BASIC (typename, byte_order);                                             \
1338     if (literal != v_##typename)                                                        \
1339       {                                                                                 \
1340         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
1341                                      _dbus_string_get_length (&str) - dump_pos);        \
1342         _dbus_assert_not_reached ("demarshaled wrong value");                           \
1343       }                                                                                 \
1344   } while (0)
1345
1346 #define MARSHAL_TEST(typename, byte_order, literal)             \
1347   do {                                                          \
1348     MARSHAL_BASIC (typename, byte_order, literal);              \
1349     dump_pos = pos;                                             \
1350     DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal);  \
1351   } while (0)
1352
1353 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal)                              \
1354   do {                                                                                  \
1355     MARSHAL_BASIC (typename, byte_order, literal);                                      \
1356     dump_pos = pos;                                                                     \
1357     DEMARSHAL_BASIC (typename, byte_order);                                             \
1358     if (strcmp (literal, v_##typename) != 0)                                            \
1359       {                                                                                 \
1360         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
1361                                        _dbus_string_get_length (&str) - dump_pos);      \
1362         _dbus_warn ("literal '%s'\nvalue  '%s'\n", literal, v_##typename);              \
1363         _dbus_assert_not_reached ("demarshaled wrong value");                           \
1364       }                                                                                 \
1365   } while (0)
1366
1367 dbus_bool_t
1368 _dbus_marshal_test (void)
1369 {
1370   DBusString str;
1371   int pos, dump_pos;
1372 #if 0
1373   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1374 #ifdef DBUS_HAVE_INT64
1375   dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
1376                              DBUS_INT64_CONSTANT (0x456ffffffff),
1377                              DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
1378 #endif
1379 #endif
1380   DBusString t;
1381   double v_DOUBLE;
1382   double t_DOUBLE;
1383   dbus_int32_t v_INT32;
1384   dbus_uint32_t v_UINT32;
1385   dbus_int64_t v_INT64;
1386   dbus_uint64_t v_UINT64;
1387   unsigned char v_BYTE;
1388   unsigned char v_BOOLEAN;
1389   const char *v_STRING;
1390   const char *v_SIGNATURE;
1391   const char *v_OBJECT_PATH;
1392   int byte_order;
1393
1394   if (!_dbus_string_init (&str))
1395     _dbus_assert_not_reached ("failed to init string");
1396
1397   pos = 0;
1398
1399   /* Marshal doubles */
1400   MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
1401   DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
1402   t_DOUBLE = 3.14;
1403   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1404     _dbus_assert_not_reached ("got wrong double value");
1405
1406   MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
1407   DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
1408   t_DOUBLE = 3.14;
1409   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1410     _dbus_assert_not_reached ("got wrong double value");
1411
1412   /* Marshal signed integers */
1413   MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
1414   MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
1415
1416   /* Marshal unsigned integers */
1417   MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
1418   MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
1419
1420 #ifdef DBUS_HAVE_INT64
1421   /* Marshal signed integers */
1422   MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1423   MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1424
1425   /* Marshal unsigned integers */
1426   MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1427   MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1428 #endif /* DBUS_HAVE_INT64 */
1429
1430   /* Marshal byte */
1431   MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
1432   MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
1433
1434   /* Marshal all possible bools! */
1435   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
1436   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
1437   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
1438   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
1439
1440   /* Marshal strings */
1441   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
1442   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
1443   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
1444   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
1445
1446   /* object paths */
1447   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
1448   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
1449
1450   /* signatures */
1451   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
1452   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
1453   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
1454   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
1455
1456 #if 0
1457
1458   /*
1459    * FIXME restore the set/pack tests
1460    */
1461
1462 #ifdef DBUS_HAVE_INT64
1463   /* set/pack 64-bit integers */
1464   _dbus_string_set_length (&str, 8);
1465
1466   /* signed little */
1467   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
1468                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1469
1470   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1471                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1472                                     _dbus_string_get_const_data (&str)));
1473
1474   /* signed big */
1475   _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
1476                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1477
1478   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1479                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1480                                     _dbus_string_get_const_data (&str)));
1481
1482   /* signed little pack */
1483   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1484                     DBUS_LITTLE_ENDIAN,
1485                     _dbus_string_get_data (&str));
1486
1487   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1488                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1489                                     _dbus_string_get_const_data (&str)));
1490
1491   /* signed big pack */
1492   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1493                     DBUS_BIG_ENDIAN,
1494                     _dbus_string_get_data (&str));
1495
1496   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1497                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1498                                     _dbus_string_get_const_data (&str)));
1499
1500   /* unsigned little */
1501   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
1502                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1503
1504   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1505                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1506                                      _dbus_string_get_const_data (&str)));
1507
1508   /* unsigned big */
1509   _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
1510                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1511
1512   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1513                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1514                                      _dbus_string_get_const_data (&str)));
1515
1516   /* unsigned little pack */
1517   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1518                      DBUS_LITTLE_ENDIAN,
1519                      _dbus_string_get_data (&str));
1520
1521   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1522                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1523                                      _dbus_string_get_const_data (&str)));
1524
1525   /* unsigned big pack */
1526   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1527                      DBUS_BIG_ENDIAN,
1528                      _dbus_string_get_data (&str));
1529
1530   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1531                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1532                                      _dbus_string_get_const_data (&str)));
1533 #endif /* DBUS_HAVE_INT64 */
1534
1535   /* set/pack 32-bit integers */
1536   _dbus_string_set_length (&str, 4);
1537
1538   /* signed little */
1539   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
1540                            0, -0x123456);
1541
1542   _dbus_assert (-0x123456 ==
1543                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1544                                     _dbus_string_get_const_data (&str)));
1545
1546   /* signed big */
1547   _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
1548                            0, -0x123456);
1549
1550   _dbus_assert (-0x123456 ==
1551                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1552                                     _dbus_string_get_const_data (&str)));
1553
1554   /* signed little pack */
1555   _dbus_pack_int32 (-0x123456,
1556                     DBUS_LITTLE_ENDIAN,
1557                     _dbus_string_get_data (&str));
1558
1559   _dbus_assert (-0x123456 ==
1560                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1561                                     _dbus_string_get_const_data (&str)));
1562
1563   /* signed big pack */
1564   _dbus_pack_int32 (-0x123456,
1565                     DBUS_BIG_ENDIAN,
1566                     _dbus_string_get_data (&str));
1567
1568   _dbus_assert (-0x123456 ==
1569                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1570                                     _dbus_string_get_const_data (&str)));
1571
1572   /* unsigned little */
1573   _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
1574                             0, 0x123456);
1575
1576   _dbus_assert (0x123456 ==
1577                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
1578                                      _dbus_string_get_const_data (&str)));
1579
1580   /* unsigned big */
1581   _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
1582                             0, 0x123456);
1583
1584   _dbus_assert (0x123456 ==
1585                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
1586                                      _dbus_string_get_const_data (&str)));
1587
1588   /* unsigned little pack */
1589   _dbus_pack_uint32 (0x123456,
1590                      DBUS_LITTLE_ENDIAN,
1591                      _dbus_string_get_data (&str));
1592
1593   _dbus_assert (0x123456 ==
1594                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
1595                                      _dbus_string_get_const_data (&str)));
1596
1597   /* unsigned big pack */
1598   _dbus_pack_uint32 (0x123456,
1599                      DBUS_BIG_ENDIAN,
1600                      _dbus_string_get_data (&str));
1601
1602   _dbus_assert (0x123456 ==
1603                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
1604                                      _dbus_string_get_const_data (&str)));
1605
1606 #endif /* set/pack tests for integers */
1607
1608   /* Strings in-place set */
1609   byte_order = DBUS_LITTLE_ENDIAN;
1610   while (TRUE)
1611     {
1612       /* Init a string */
1613       _dbus_string_set_length (&str, 0);
1614
1615       /* reset pos for the macros */
1616       pos = 0;
1617
1618       MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
1619
1620       /* Set it to something longer */
1621       _dbus_string_init_const (&t, "Hello world foo");
1622
1623       v_STRING = _dbus_string_get_const_data (&t);
1624       _dbus_marshal_set_basic_type (&str, 0, DBUS_TYPE_STRING,
1625                                     &v_STRING, byte_order, NULL, NULL);
1626
1627       _dbus_demarshal_basic_type (&str, 0, DBUS_TYPE_STRING,
1628                                   &v_STRING, byte_order,
1629                                   NULL);
1630       _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
1631
1632       /* Set it to something shorter */
1633       _dbus_string_init_const (&t, "Hello");
1634
1635       v_STRING = _dbus_string_get_const_data (&t);
1636       _dbus_marshal_set_basic_type (&str, 0, DBUS_TYPE_STRING,
1637                                     &v_STRING, byte_order, NULL, NULL);
1638       _dbus_demarshal_basic_type (&str, 0, DBUS_TYPE_STRING,
1639                                   &v_STRING, byte_order,
1640                                   NULL);
1641       _dbus_assert (strcmp (v_STRING, "Hello") == 0);
1642
1643       /* Do the other byte order */
1644       if (byte_order == DBUS_LITTLE_ENDIAN)
1645         byte_order = DBUS_BIG_ENDIAN;
1646       else
1647         break;
1648     }
1649
1650   /* Clean up */
1651   _dbus_string_free (&str);
1652
1653   return TRUE;
1654 }
1655
1656 #endif /* DBUS_BUILD_TESTS */