added dbus support
[monky] / src / dbus / dbus-marshal-basic.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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 #include "dbus-signature.h"
28
29 #include <string.h>
30
31 /**
32  * @defgroup DBusMarshal marshaling and unmarshaling
33  * @ingroup  DBusInternals
34  * @brief functions to marshal/unmarshal data from the wire
35  *
36  * Types and functions related to converting primitive data types from
37  * wire format to native machine format, and vice versa.
38  *
39  * A signature is just a string with multiple types one after the other.
40  * for example a type is "i" or "(ii)", a signature is "i(ii)"
41  * where i is int and (ii) is struct { int; int; }
42  *
43  * @{
44  */
45
46 static void
47 pack_2_octets (dbus_uint16_t   value,
48                int             byte_order,
49                unsigned char  *data)
50 {
51   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
52
53   if ((byte_order) == DBUS_LITTLE_ENDIAN)
54     *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
55   else
56     *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
57 }
58
59 static void
60 pack_4_octets (dbus_uint32_t   value,
61                int             byte_order,
62                unsigned char  *data)
63 {
64   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
65
66   if ((byte_order) == DBUS_LITTLE_ENDIAN)
67     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
68   else
69     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
70 }
71
72 static void
73 pack_8_octets (DBusBasicValue     value,
74                int                byte_order,
75                unsigned char     *data)
76 {
77   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
78
79 #ifdef DBUS_HAVE_INT64
80   if ((byte_order) == DBUS_LITTLE_ENDIAN)
81     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
82   else
83     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
84 #else
85   *(DBus8ByteStruct*)data = value.u64;
86   swap_8_octets ((DBusBasicValue*)data, byte_order);
87 #endif
88 }
89
90 /**
91  * Packs a 32 bit unsigned integer into a data pointer.
92  *
93  * @param value the value
94  * @param byte_order the byte order to use
95  * @param data the data pointer
96  */
97 void
98 _dbus_pack_uint32 (dbus_uint32_t   value,
99                    int             byte_order,
100                    unsigned char  *data)
101 {
102   pack_4_octets (value, byte_order, data);
103 }
104
105 #ifndef DBUS_HAVE_INT64
106 /* from ORBit */
107 static void
108 swap_bytes (unsigned char *data,
109             unsigned int   len)
110 {
111   unsigned char *p1 = data;
112   unsigned char *p2 = data + len - 1;
113
114   while (p1 < p2)
115     {
116       unsigned char tmp = *p1;
117       *p1 = *p2;
118       *p2 = tmp;
119
120       --p2;
121       ++p1;
122     }
123 }
124 #endif /* !DBUS_HAVE_INT64 */
125
126 static void
127 swap_8_octets (DBusBasicValue    *value,
128                int                byte_order)
129 {
130   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
131     {
132 #ifdef DBUS_HAVE_INT64
133       value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
134 #else
135       swap_bytes ((unsigned char *)value, 8);
136 #endif
137     }
138 }
139
140 #if 0
141 static DBusBasicValue
142 unpack_8_octets (int                  byte_order,
143                  const unsigned char *data)
144 {
145   DBusBasicValue r;
146
147   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
148   _dbus_assert (sizeof (r) == 8);
149
150 #ifdef DBUS_HAVE_INT64
151   if (byte_order == DBUS_LITTLE_ENDIAN)
152     r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
153   else
154     r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
155 #else
156   r.u64 = *(DBus8ByteStruct*)data;
157   swap_8_octets (&r, byte_order);
158 #endif
159
160   return r;
161 }
162 #endif
163
164 #ifndef _dbus_unpack_uint16
165 /**
166  * Unpacks a 16 bit unsigned integer from a data pointer
167  *
168  * @param byte_order The byte order to use
169  * @param data the data pointer
170  * @returns the integer
171  */
172 dbus_uint16_t
173 _dbus_unpack_uint16 (int                  byte_order,
174                      const unsigned char *data)
175 {
176   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
177
178   if (byte_order == DBUS_LITTLE_ENDIAN)
179     return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
180   else
181     return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
182 }
183 #endif /* _dbus_unpack_uint16 */
184
185 #ifndef _dbus_unpack_uint32
186 /**
187  * Unpacks a 32 bit unsigned integer from a data pointer
188  *
189  * @param byte_order The byte order to use
190  * @param data the data pointer
191  * @returns the integer
192  */
193 dbus_uint32_t
194 _dbus_unpack_uint32 (int                  byte_order,
195                      const unsigned char *data)
196 {
197   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
198
199   if (byte_order == DBUS_LITTLE_ENDIAN)
200     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
201   else
202     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
203 }
204 #endif /* _dbus_unpack_uint32 */
205
206 static void
207 set_2_octets (DBusString          *str,
208               int                  offset,
209               dbus_uint16_t        value,
210               int                  byte_order)
211 {
212   char *data;
213
214   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
215                 byte_order == DBUS_BIG_ENDIAN);
216
217   data = _dbus_string_get_data_len (str, offset, 2);
218
219   pack_2_octets (value, byte_order, data);
220 }
221
222 static void
223 set_4_octets (DBusString          *str,
224               int                  offset,
225               dbus_uint32_t        value,
226               int                  byte_order)
227 {
228   char *data;
229
230   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
231                 byte_order == DBUS_BIG_ENDIAN);
232
233   data = _dbus_string_get_data_len (str, offset, 4);
234
235   pack_4_octets (value, byte_order, data);
236 }
237
238 static void
239 set_8_octets (DBusString          *str,
240               int                  offset,
241               DBusBasicValue       value,
242               int                  byte_order)
243 {
244   char *data;
245
246   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
247                 byte_order == DBUS_BIG_ENDIAN);
248
249   data = _dbus_string_get_data_len (str, offset, 8);
250
251   pack_8_octets (value, byte_order, data);
252 }
253
254 /**
255  * Sets the 4 bytes at the given offset to a marshaled unsigned
256  * integer, replacing anything found there previously.
257  *
258  * @param str the string to write the marshalled int to
259  * @param pos the byte offset where int should be written
260  * @param value the value
261  * @param byte_order the byte order to use
262  *
263  */
264 void
265 _dbus_marshal_set_uint32 (DBusString          *str,
266                           int                  pos,
267                           dbus_uint32_t        value,
268                           int                  byte_order)
269 {
270   set_4_octets (str, pos, value, byte_order);
271 }
272
273 /**
274  * Sets the existing marshaled string at the given offset with
275  * a new marshaled string. The given offset must point to
276  * an existing string or the wrong length will be deleted
277  * and replaced with the new string.
278  *
279  * Note: no attempt is made by this function to re-align
280  * any data which has been already marshalled after this
281  * string. Use with caution.
282  *
283  * @param str the string to write the marshalled string to
284  * @param pos the position of the marshaled string length
285  * @param value the value
286  * @param byte_order the byte order to use
287  * @param old_end_pos place to store byte after the nul byte of the old value
288  * @param new_end_pos place to store byte after the nul byte of the new value
289  * @returns #TRUE on success, #FALSE if no memory
290  *
291  */
292 static dbus_bool_t
293 set_string (DBusString          *str,
294             int                  pos,
295             const char          *value,
296             int                  byte_order,
297             int                 *old_end_pos,
298             int                 *new_end_pos)
299 {
300   int old_len, new_len;
301   DBusString dstr;
302
303   _dbus_string_init_const (&dstr, value);
304
305   _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
306   old_len = _dbus_unpack_uint32 (byte_order,
307                                  _dbus_string_get_const_data_len (str, pos, 4));
308
309   new_len = _dbus_string_get_length (&dstr);
310
311   if (!_dbus_string_replace_len (&dstr, 0, new_len,
312                                  str, pos + 4, old_len))
313     return FALSE;
314
315   _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
316
317   if (old_end_pos)
318     *old_end_pos = pos + 4 + old_len + 1;
319   if (new_end_pos)
320     *new_end_pos = pos + 4 + new_len + 1;
321
322   return TRUE;
323 }
324
325 /**
326  * Sets the existing marshaled signature at the given offset to a new
327  * marshaled signature. Same basic ideas as set_string().
328  *
329  * @param str the string to write the marshalled signature to
330  * @param pos the position of the marshaled signature length
331  * @param value the value
332  * @param byte_order the byte order to use
333  * @param old_end_pos place to store byte after the nul byte of the old value
334  * @param new_end_pos place to store byte after the nul byte of the new value
335  * @returns #TRUE on success, #FALSE if no memory
336  *
337  */
338 static dbus_bool_t
339 set_signature (DBusString          *str,
340                int                  pos,
341                const char          *value,
342                int                  byte_order,
343                int                 *old_end_pos,
344                int                 *new_end_pos)
345 {
346   int old_len, new_len;
347   DBusString dstr;
348
349   _dbus_string_init_const (&dstr, value);
350
351   old_len = _dbus_string_get_byte (str, pos);
352   new_len = _dbus_string_get_length (&dstr);
353
354   if (!_dbus_string_replace_len (&dstr, 0, new_len,
355                                  str, pos + 1, old_len))
356     return FALSE;
357
358   _dbus_string_set_byte (str, pos, new_len);
359
360   if (old_end_pos)
361     *old_end_pos = pos + 1 + old_len + 1;
362   if (new_end_pos)
363     *new_end_pos = pos + 1 + new_len + 1;
364
365   return TRUE;
366 }
367
368 /**
369  * Sets an existing basic type value to a new value.
370  * Arguments work the same way as _dbus_marshal_basic_type().
371  *
372  * @param str the string
373  * @param pos location of the current value
374  * @param type the type of the current and new values
375  * @param value the address of the new value
376  * @param byte_order byte order for marshaling
377  * @param old_end_pos location to store end position of the old value, or #NULL
378  * @param new_end_pos location to store end position of the new value, or #NULL
379  * @returns #FALSE if no memory
380  */
381 dbus_bool_t
382 _dbus_marshal_set_basic (DBusString       *str,
383                          int               pos,
384                          int               type,
385                          const void       *value,
386                          int               byte_order,
387                          int              *old_end_pos,
388                          int              *new_end_pos)
389 {
390   const DBusBasicValue *vp;
391
392   vp = value;
393
394   switch (type)
395     {
396     case DBUS_TYPE_BYTE:
397       _dbus_string_set_byte (str, pos, vp->byt);
398       if (old_end_pos)
399         *old_end_pos = pos + 1;
400       if (new_end_pos)
401         *new_end_pos = pos + 1;
402       return TRUE;
403       break;
404     case DBUS_TYPE_INT16:
405     case DBUS_TYPE_UINT16:
406       pos = _DBUS_ALIGN_VALUE (pos, 2);
407       set_2_octets (str, pos, vp->u16, byte_order);
408       if (old_end_pos)
409         *old_end_pos = pos + 2;
410       if (new_end_pos)
411         *new_end_pos = pos + 2;
412       return TRUE;
413       break;
414     case DBUS_TYPE_BOOLEAN:
415     case DBUS_TYPE_INT32:
416     case DBUS_TYPE_UINT32:
417       pos = _DBUS_ALIGN_VALUE (pos, 4);
418       set_4_octets (str, pos, vp->u32, byte_order);
419       if (old_end_pos)
420         *old_end_pos = pos + 4;
421       if (new_end_pos)
422         *new_end_pos = pos + 4;
423       return TRUE;
424       break;
425     case DBUS_TYPE_INT64:
426     case DBUS_TYPE_UINT64:
427     case DBUS_TYPE_DOUBLE:
428       pos = _DBUS_ALIGN_VALUE (pos, 8);
429       set_8_octets (str, pos, *vp, byte_order);
430       if (old_end_pos)
431         *old_end_pos = pos + 8;
432       if (new_end_pos)
433         *new_end_pos = pos + 8;
434       return TRUE;
435       break;
436     case DBUS_TYPE_STRING:
437     case DBUS_TYPE_OBJECT_PATH:
438       pos = _DBUS_ALIGN_VALUE (pos, 4);
439       _dbus_assert (vp->str != NULL);
440       return set_string (str, pos, vp->str, byte_order,
441                          old_end_pos, new_end_pos);
442       break;
443     case DBUS_TYPE_SIGNATURE:
444       _dbus_assert (vp->str != NULL);
445       return set_signature (str, pos, vp->str, byte_order,
446                             old_end_pos, new_end_pos);
447       break;
448     default:
449       _dbus_assert_not_reached ("not a basic type");
450       return FALSE;
451       break;
452     }
453 }
454
455 /**
456  * Convenience function to demarshal a 32 bit unsigned integer.
457  *
458  * @param str the string containing the data
459  * @param byte_order the byte order
460  * @param pos the position in the string
461  * @param new_pos the new position of the string
462  * @returns the demarshaled integer.
463  */
464 dbus_uint32_t
465 _dbus_marshal_read_uint32  (const DBusString *str,
466                             int               pos,
467                             int               byte_order,
468                             int              *new_pos)
469 {
470   pos = _DBUS_ALIGN_VALUE (pos, 4);
471
472   if (new_pos)
473     *new_pos = pos + 4;
474
475   _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
476   
477   return _dbus_unpack_uint32 (byte_order,
478                               _dbus_string_get_const_data (str) + pos);
479 }
480
481 /**
482  * Demarshals a basic-typed value. The "value" pointer is always
483  * the address of a variable of the basic type. So e.g.
484  * if the basic type is "double" then the pointer is
485  * a double*, and if it's "char*" then the pointer is
486  * a "char**".
487  *
488  * A value of type #DBusBasicValue is guaranteed to be large enough to
489  * hold any of the types that may be returned, which is handy if you
490  * are trying to do things generically. For example you can pass
491  * a DBusBasicValue* in to this function, and then pass the same
492  * DBusBasicValue* in to _dbus_marshal_basic_type() in order to
493  * move a value from one place to another.
494  *
495  * @param str the string containing the data
496  * @param pos position in the string
497  * @param type type of value to demarshal
498  * @param value pointer to return value data
499  * @param byte_order the byte order
500  * @param new_pos pointer to update with new position, or #NULL
501  **/
502 void
503 _dbus_marshal_read_basic (const DBusString      *str,
504                           int                    pos,
505                           int                    type,
506                           void                  *value,
507                           int                    byte_order,
508                           int                   *new_pos)
509 {
510   const char *str_data;
511
512   _dbus_assert (dbus_type_is_basic (type));
513
514   str_data = _dbus_string_get_const_data (str);
515
516   /* Below we volatile types to avoid aliasing issues;
517    * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
518    */
519   
520   switch (type)
521     {
522     case DBUS_TYPE_BYTE:
523       {
524       volatile unsigned char *vp = value;
525       *vp = (unsigned char) _dbus_string_get_byte (str, pos);
526       (pos)++;
527       }
528       break;
529     case DBUS_TYPE_INT16:
530     case DBUS_TYPE_UINT16:
531       {
532       volatile dbus_uint16_t *vp = value;
533       pos = _DBUS_ALIGN_VALUE (pos, 2);
534       *vp = *(dbus_uint16_t *)(str_data + pos);
535       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
536         *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
537       pos += 2;
538       }
539       break;
540     case DBUS_TYPE_INT32:
541     case DBUS_TYPE_UINT32:
542     case DBUS_TYPE_BOOLEAN:
543       {
544       volatile dbus_uint32_t *vp = value;
545       pos = _DBUS_ALIGN_VALUE (pos, 4);
546       *vp = *(dbus_uint32_t *)(str_data + pos);
547       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
548         *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
549       pos += 4;
550       }
551       break;
552     case DBUS_TYPE_INT64:
553     case DBUS_TYPE_UINT64:
554     case DBUS_TYPE_DOUBLE:
555       {
556       volatile dbus_uint64_t *vp = value;
557       pos = _DBUS_ALIGN_VALUE (pos, 8);
558 #ifdef DBUS_HAVE_INT64
559       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
560         *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
561       else
562         *vp = *(dbus_uint64_t*)(str_data + pos);
563 #else
564       *vp = *(DBus8ByteStruct*) (str_data + pos);
565       swap_8_octets (vp, byte_order);
566 #endif
567       pos += 8;
568       }
569       break;
570     case DBUS_TYPE_STRING:
571     case DBUS_TYPE_OBJECT_PATH:
572       {
573         int len;
574         volatile char **vp = value;
575
576         len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
577
578         *vp = (char*) str_data + pos;
579
580         pos += len + 1; /* length plus nul */
581       }
582       break;
583     case DBUS_TYPE_SIGNATURE:
584       {
585         int len;
586         volatile char **vp = value;
587
588         len = _dbus_string_get_byte (str, pos);
589         pos += 1;
590
591         *vp = (char*) str_data + pos;
592
593         pos += len + 1; /* length plus nul */
594       }
595       break;
596     default:
597       _dbus_warn_check_failed ("type %s %d not a basic type\n",
598                                _dbus_type_to_string (type), type);
599       _dbus_assert_not_reached ("not a basic type");
600       break;
601     }
602
603   if (new_pos)
604     *new_pos = pos;
605 }
606
607 static dbus_bool_t
608 marshal_2_octets (DBusString   *str,
609                   int           insert_at,
610                   dbus_uint16_t value,
611                   int           byte_order,
612                   int          *pos_after)
613 {
614   dbus_bool_t retval;
615   int orig_len;
616
617   _dbus_assert (sizeof (value) == 2);
618
619   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
620     value = DBUS_UINT16_SWAP_LE_BE (value);
621
622   orig_len = _dbus_string_get_length (str);
623
624   retval = _dbus_string_insert_2_aligned (str, insert_at,
625                                           (const unsigned char *)&value);
626
627   if (pos_after)
628     {
629       *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
630       _dbus_assert (*pos_after <= _dbus_string_get_length (str));
631     }
632
633   return retval;
634 }
635
636 static dbus_bool_t
637 marshal_4_octets (DBusString   *str,
638                   int           insert_at,
639                   dbus_uint32_t value,
640                   int           byte_order,
641                   int          *pos_after)
642 {
643   dbus_bool_t retval;
644   int orig_len;
645
646   _dbus_assert (sizeof (value) == 4);
647
648   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
649     value = DBUS_UINT32_SWAP_LE_BE (value);
650
651   orig_len = _dbus_string_get_length (str);
652
653   retval = _dbus_string_insert_4_aligned (str, insert_at,
654                                           (const unsigned char *)&value);
655
656   if (pos_after)
657     {
658       *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
659       _dbus_assert (*pos_after <= _dbus_string_get_length (str));
660     }
661
662   return retval;
663 }
664
665 static dbus_bool_t
666 marshal_8_octets (DBusString    *str,
667                   int            insert_at,
668                   DBusBasicValue value,
669                   int            byte_order,
670                   int           *pos_after)
671 {
672   dbus_bool_t retval;
673   int orig_len;
674
675   _dbus_assert (sizeof (value) == 8);
676
677   swap_8_octets (&value, byte_order);
678
679   orig_len = _dbus_string_get_length (str);
680
681   retval = _dbus_string_insert_8_aligned (str, insert_at,
682                                           (const unsigned char *)&value);
683
684   if (pos_after)
685     *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
686
687   return retval;
688 }
689
690 enum
691   {
692     MARSHAL_AS_STRING,
693     MARSHAL_AS_SIGNATURE,
694     MARSHAL_AS_BYTE_ARRAY
695   };
696
697 static dbus_bool_t
698 marshal_len_followed_by_bytes (int                  marshal_as,
699                                DBusString          *str,
700                                int                  insert_at,
701                                const unsigned char *value,
702                                int                  data_len, /* doesn't include nul if any */
703                                int                  byte_order,
704                                int                 *pos_after)
705 {
706   int pos;
707   DBusString value_str;
708   int value_len;
709
710   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
711   if (insert_at > _dbus_string_get_length (str))
712     _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
713                 insert_at, _dbus_string_get_length (str), data_len);
714   
715   if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
716     value_len = data_len;
717   else
718     value_len = data_len + 1; /* value has a nul */
719
720   _dbus_string_init_const_len (&value_str, value, value_len);
721
722   pos = insert_at;
723
724   if (marshal_as == MARSHAL_AS_SIGNATURE)
725     {
726       _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
727       _dbus_assert (data_len <= 255); /* same as max sig len right now */
728       
729       if (!_dbus_string_insert_byte (str, pos, data_len))
730         goto oom;
731
732       pos += 1;
733     }
734   else
735     {
736       if (!marshal_4_octets (str, pos, data_len,
737                              byte_order, &pos))
738         goto oom;
739     }
740
741   if (!_dbus_string_copy_len (&value_str, 0, value_len,
742                               str, pos))
743     goto oom;
744
745 #if 0
746   /* too expensive */
747   _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
748                                               str, pos));
749   _dbus_verbose_bytes_of_string (str, pos, value_len);
750 #endif
751
752   pos += value_len;
753
754   if (pos_after)
755     *pos_after = pos;
756
757   return TRUE;
758
759  oom:
760   /* Delete what we've inserted */
761   _dbus_string_delete (str, insert_at, pos - insert_at);
762
763   return FALSE;
764 }
765
766 static dbus_bool_t
767 marshal_string (DBusString    *str,
768                 int            insert_at,
769                 const char    *value,
770                 int            byte_order,
771                 int           *pos_after)
772 {
773   return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
774                                         str, insert_at, value,
775                                         strlen (value),
776                                         byte_order, pos_after);
777 }
778
779 static dbus_bool_t
780 marshal_signature (DBusString    *str,
781                    int            insert_at,
782                    const char    *value,
783                    int           *pos_after)
784 {
785   return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
786                                         str, insert_at, value,
787                                         strlen (value),
788                                         DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
789                                         pos_after);
790 }
791
792 /**
793  * Marshals a basic-typed value. The "value" pointer is always the
794  * address of a variable containing the basic type value.
795  * So for example for int32 it will be dbus_int32_t*, and
796  * for string it will be const char**. This is for symmetry
797  * with _dbus_marshal_read_basic() and to have a simple
798  * consistent rule.
799  *
800  * @param str string to marshal to
801  * @param insert_at where to insert the value
802  * @param type type of value
803  * @param value pointer to a variable containing the value
804  * @param byte_order byte order
805  * @param pos_after #NULL or the position after the type
806  * @returns #TRUE on success
807  **/
808 dbus_bool_t
809 _dbus_marshal_write_basic (DBusString *str,
810                            int         insert_at,
811                            int         type,
812                            const void *value,
813                            int         byte_order,
814                            int        *pos_after)
815 {
816   const DBusBasicValue *vp;
817
818   _dbus_assert (dbus_type_is_basic (type));
819
820   vp = value;
821
822   switch (type)
823     {
824     case DBUS_TYPE_BYTE:
825       if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
826         return FALSE;
827       if (pos_after)
828         *pos_after = insert_at + 1;
829       return TRUE;
830       break;
831     case DBUS_TYPE_INT16:
832     case DBUS_TYPE_UINT16:
833       return marshal_2_octets (str, insert_at, vp->u16,
834                                byte_order, pos_after);
835       break;
836     case DBUS_TYPE_BOOLEAN:
837       return marshal_4_octets (str, insert_at, vp->u32 != FALSE,
838                                byte_order, pos_after);
839       break;
840     case DBUS_TYPE_INT32:
841     case DBUS_TYPE_UINT32:
842       return marshal_4_octets (str, insert_at, vp->u32,
843                                byte_order, pos_after);
844       break;
845     case DBUS_TYPE_INT64:
846     case DBUS_TYPE_UINT64:
847     case DBUS_TYPE_DOUBLE:
848       return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
849       break;
850
851     case DBUS_TYPE_STRING:
852     case DBUS_TYPE_OBJECT_PATH:
853       _dbus_assert (vp->str != NULL);
854       return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
855       break;
856     case DBUS_TYPE_SIGNATURE:
857       _dbus_assert (vp->str != NULL);
858       return marshal_signature (str, insert_at, vp->str, pos_after);
859       break;
860     default:
861       _dbus_assert_not_reached ("not a basic type");
862       return FALSE;
863       break;
864     }
865 }
866
867 static dbus_bool_t
868 marshal_1_octets_array (DBusString          *str,
869                         int                  insert_at,
870                         const unsigned char *value,
871                         int                  n_elements,
872                         int                  byte_order,
873                         int                 *pos_after)
874 {
875   int pos;
876   DBusString value_str;
877
878   _dbus_string_init_const_len (&value_str, value, n_elements);
879
880   pos = insert_at;
881
882   if (!_dbus_string_copy_len (&value_str, 0, n_elements,
883                               str, pos))
884     return FALSE;
885
886   pos += n_elements;
887
888   if (pos_after)
889     *pos_after = pos;
890
891   return TRUE;
892 }
893
894 /**
895  * Swaps the elements of an array to the opposite byte order
896  *
897  * @param data start of array
898  * @param n_elements number of elements
899  * @param alignment size of each element
900  */
901 void
902 _dbus_swap_array (unsigned char *data,
903                   int            n_elements,
904                   int            alignment)
905 {
906   unsigned char *d;
907   unsigned char *end;
908
909   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
910
911   /* we use const_data and cast it off so DBusString can be a const string
912    * for the unit tests. don't ask.
913    */
914   d = data;
915   end = d + (n_elements * alignment);
916   
917   if (alignment == 8)
918     {
919       while (d != end)
920         {
921 #ifdef DBUS_HAVE_INT64
922           *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
923 #else
924           swap_8_bytes ((DBusBasicValue*) d);
925 #endif
926           d += 8;
927         }
928     }
929   else if (alignment == 4)
930     {
931       while (d != end)
932         {
933           *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
934           d += 4;
935         }
936     }
937   else
938     {
939       _dbus_assert (alignment == 2);
940       
941       while (d != end)
942         {
943           *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
944           d += 2;
945         }
946     }
947 }
948
949 static void
950 swap_array (DBusString *str,
951             int         array_start,
952             int         n_elements,
953             int         byte_order,
954             int         alignment)
955 {
956   _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
957
958   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
959     {
960       /* we use const_data and cast it off so DBusString can be a const string
961        * for the unit tests. don't ask.
962        */
963       _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
964                         n_elements, alignment);
965     }
966 }
967
968 static dbus_bool_t
969 marshal_fixed_multi (DBusString           *str,
970                      int                   insert_at,
971                      const DBusBasicValue *value,
972                      int                   n_elements,
973                      int                   byte_order,
974                      int                   alignment,
975                      int                  *pos_after)
976 {
977   int old_string_len;
978   int array_start;
979   DBusString t;
980   int len_in_bytes;
981
982   _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
983   
984   old_string_len = _dbus_string_get_length (str);
985
986   len_in_bytes = n_elements * alignment;
987   array_start = insert_at;
988   
989   /* Note that we do alignment padding unconditionally
990    * even if the array is empty; this means that
991    * padding + len is always equal to the number of bytes
992    * in the array.
993    */
994
995   if (!_dbus_string_insert_alignment (str, &array_start, alignment))
996     goto error;
997
998   _dbus_string_init_const_len (&t,
999                                (const unsigned char*) value,
1000                                len_in_bytes);
1001
1002   if (!_dbus_string_copy (&t, 0,
1003                           str, array_start))
1004     goto error;
1005
1006   swap_array (str, array_start, n_elements, byte_order, alignment);
1007
1008   if (pos_after)
1009     *pos_after = array_start + len_in_bytes;
1010   
1011   return TRUE;
1012
1013  error:
1014   _dbus_string_delete (str, insert_at,
1015                        _dbus_string_get_length (str) - old_string_len);
1016
1017   return FALSE;
1018 }
1019
1020 /**
1021  * Marshals a block of values of fixed-length type all at once, as an
1022  * optimization.  dbus_type_is_fixed() returns #TRUE for fixed-length
1023  * types, which are the basic types minus the string-like types.
1024  *
1025  * The value argument should be the adddress of an
1026  * array, so e.g. "const dbus_uint32_t**"
1027  *
1028  * @param str string to marshal to
1029  * @param insert_at where to insert the value
1030  * @param element_type type of array elements
1031  * @param value address of an array to marshal
1032  * @param n_elements number of elements in the array
1033  * @param byte_order byte order
1034  * @param pos_after #NULL or the position after the type
1035  * @returns #TRUE on success
1036  **/
1037 dbus_bool_t
1038 _dbus_marshal_write_fixed_multi (DBusString *str,
1039                                  int         insert_at,
1040                                  int         element_type,
1041                                  const void *value,
1042                                  int         n_elements,
1043                                  int         byte_order,
1044                                  int        *pos_after)
1045 {
1046   const void* vp = *(const DBusBasicValue**)value;
1047   
1048   _dbus_assert (dbus_type_is_fixed (element_type));
1049   _dbus_assert (n_elements >= 0);
1050
1051 #if 0
1052   _dbus_verbose ("writing %d elements of %s\n",
1053                  n_elements, _dbus_type_to_string (element_type));
1054 #endif
1055   
1056   switch (element_type)
1057     {
1058     case DBUS_TYPE_BYTE:
1059       return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after);
1060       break;
1061     case DBUS_TYPE_INT16:
1062     case DBUS_TYPE_UINT16:
1063       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
1064       /* FIXME: we canonicalize to 0 or 1 for the single boolean case
1065        * should we here too ? */
1066     case DBUS_TYPE_BOOLEAN:
1067     case DBUS_TYPE_INT32:
1068     case DBUS_TYPE_UINT32:
1069       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
1070       break;
1071     case DBUS_TYPE_INT64:
1072     case DBUS_TYPE_UINT64:
1073     case DBUS_TYPE_DOUBLE:
1074       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after);
1075       break;
1076
1077     default:
1078       _dbus_assert_not_reached ("non fixed type in array write");
1079       break;
1080     }
1081
1082   return FALSE;
1083 }
1084
1085
1086 /**
1087  * Skips over a basic-typed value, reporting the following position.
1088  *
1089  * @param str the string containing the data
1090  * @param type type of value to read
1091  * @param byte_order the byte order
1092  * @param pos pointer to position in the string,
1093  *            updated on return to new position
1094  **/
1095 void
1096 _dbus_marshal_skip_basic (const DBusString      *str,
1097                           int                    type,
1098                           int                    byte_order,
1099                           int                   *pos)
1100 {
1101   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
1102                 byte_order == DBUS_BIG_ENDIAN);
1103   
1104   switch (type)
1105     {
1106     case DBUS_TYPE_BYTE:
1107       (*pos)++;
1108       break;
1109     case DBUS_TYPE_INT16:
1110     case DBUS_TYPE_UINT16:
1111       *pos = _DBUS_ALIGN_VALUE (*pos, 2);
1112       *pos += 2;
1113       break;
1114     case DBUS_TYPE_BOOLEAN:
1115     case DBUS_TYPE_INT32:
1116     case DBUS_TYPE_UINT32:
1117       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1118       *pos += 4;
1119       break;
1120     case DBUS_TYPE_INT64:
1121     case DBUS_TYPE_UINT64:
1122     case DBUS_TYPE_DOUBLE:
1123       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1124       *pos += 8;
1125       break;
1126     case DBUS_TYPE_STRING:
1127     case DBUS_TYPE_OBJECT_PATH:
1128       {
1129         int len;
1130
1131         len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
1132         
1133         *pos += len + 1; /* length plus nul */
1134       }
1135       break;
1136     case DBUS_TYPE_SIGNATURE:
1137       {
1138         int len;
1139
1140         len = _dbus_string_get_byte (str, *pos);
1141
1142         *pos += len + 2; /* length byte plus length plus nul */
1143       }
1144       break;
1145     default:
1146       _dbus_warn ("type %s not a basic type\n",
1147                   _dbus_type_to_string (type));
1148       _dbus_assert_not_reached ("not a basic type");
1149       break;
1150     }
1151 }
1152
1153 /**
1154  * Skips an array, returning the next position.
1155  *
1156  * @param str the string containing the data
1157  * @param element_type the type of array elements
1158  * @param byte_order the byte order
1159  * @param pos pointer to position in the string,
1160  *            updated on return to new position
1161  */
1162 void
1163 _dbus_marshal_skip_array (const DBusString  *str,
1164                           int                element_type,
1165                           int                byte_order,
1166                           int               *pos)
1167 {
1168   dbus_uint32_t array_len;
1169   int i;
1170   int alignment;
1171
1172   i = _DBUS_ALIGN_VALUE (*pos, 4);
1173
1174   array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
1175
1176   alignment = _dbus_type_get_alignment (element_type);
1177
1178   i = _DBUS_ALIGN_VALUE (i, alignment);
1179
1180   *pos = i + array_len;
1181 }
1182
1183 /**
1184  * Gets the alignment requirement for the given type;
1185  * will be 1, 4, or 8.
1186  *
1187  * @param typecode the type
1188  * @returns alignment of 1, 4, or 8
1189  */
1190 int
1191 _dbus_type_get_alignment (int typecode)
1192 {
1193   switch (typecode)
1194     {
1195     case DBUS_TYPE_BYTE:
1196     case DBUS_TYPE_VARIANT:
1197     case DBUS_TYPE_SIGNATURE:
1198       return 1;
1199     case DBUS_TYPE_INT16:
1200     case DBUS_TYPE_UINT16:
1201       return 2;
1202     case DBUS_TYPE_BOOLEAN:
1203     case DBUS_TYPE_INT32:
1204     case DBUS_TYPE_UINT32:
1205       /* this stuff is 4 since it starts with a length */
1206     case DBUS_TYPE_STRING:
1207     case DBUS_TYPE_OBJECT_PATH:
1208     case DBUS_TYPE_ARRAY:
1209       return 4;
1210     case DBUS_TYPE_INT64:
1211     case DBUS_TYPE_UINT64:
1212     case DBUS_TYPE_DOUBLE:
1213       /* struct is 8 since it could contain an 8-aligned item
1214        * and it's simpler to just always align structs to 8;
1215        * we want the amount of padding in a struct of a given
1216        * type to be predictable, not location-dependent.
1217        * DICT_ENTRY is always the same as struct.
1218        */
1219     case DBUS_TYPE_STRUCT:
1220     case DBUS_TYPE_DICT_ENTRY:
1221       return 8;
1222
1223     default:
1224       _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1225       return 0;
1226     }
1227 }
1228
1229
1230 /**
1231  * Return #TRUE if the typecode is a valid typecode.
1232  * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and
1233  * random unknown bytes aren't either. This function is safe with
1234  * untrusted data.
1235  *
1236  * @returns #TRUE if valid
1237  */
1238 dbus_bool_t
1239 _dbus_type_is_valid (int typecode)
1240 {
1241   switch (typecode)
1242     {
1243     case DBUS_TYPE_BYTE:
1244     case DBUS_TYPE_BOOLEAN:
1245     case DBUS_TYPE_INT16:
1246     case DBUS_TYPE_UINT16:
1247     case DBUS_TYPE_INT32:
1248     case DBUS_TYPE_UINT32:
1249     case DBUS_TYPE_INT64:
1250     case DBUS_TYPE_UINT64:
1251     case DBUS_TYPE_DOUBLE:
1252     case DBUS_TYPE_STRING:
1253     case DBUS_TYPE_OBJECT_PATH:
1254     case DBUS_TYPE_SIGNATURE:
1255     case DBUS_TYPE_ARRAY:
1256     case DBUS_TYPE_STRUCT:
1257     case DBUS_TYPE_DICT_ENTRY:
1258     case DBUS_TYPE_VARIANT:
1259       return TRUE;
1260
1261     default:
1262       return FALSE;
1263     }
1264 }
1265
1266 /**
1267  * Returns a string describing the given type.
1268  *
1269  * @param typecode the type to describe
1270  * @returns a constant string describing the type
1271  */
1272 const char *
1273 _dbus_type_to_string (int typecode)
1274 {
1275   switch (typecode)
1276     {
1277     case DBUS_TYPE_INVALID:
1278       return "invalid";
1279     case DBUS_TYPE_BOOLEAN:
1280       return "boolean";
1281     case DBUS_TYPE_BYTE:
1282       return "byte";
1283     case DBUS_TYPE_INT16:
1284       return "int16";
1285     case DBUS_TYPE_UINT16:
1286       return "uint16";
1287     case DBUS_TYPE_INT32:
1288       return "int32";
1289     case DBUS_TYPE_UINT32:
1290       return "uint32";
1291     case DBUS_TYPE_INT64:
1292       return "int64";
1293     case DBUS_TYPE_UINT64:
1294       return "uint64";      
1295     case DBUS_TYPE_DOUBLE:
1296       return "double";
1297     case DBUS_TYPE_STRING:
1298       return "string";
1299     case DBUS_TYPE_OBJECT_PATH:
1300       return "object_path";
1301     case DBUS_TYPE_SIGNATURE:
1302       return "signature";
1303     case DBUS_TYPE_STRUCT:
1304       return "struct";
1305     case DBUS_TYPE_DICT_ENTRY:
1306       return "dict_entry";
1307     case DBUS_TYPE_ARRAY:
1308       return "array";
1309     case DBUS_TYPE_VARIANT:
1310       return "variant";
1311     case DBUS_STRUCT_BEGIN_CHAR:
1312       return "begin_struct";
1313     case DBUS_STRUCT_END_CHAR:
1314       return "end_struct";
1315     case DBUS_DICT_ENTRY_BEGIN_CHAR:
1316       return "begin_dict_entry";
1317     case DBUS_DICT_ENTRY_END_CHAR:
1318       return "end_dict_entry";
1319     default:
1320       return "unknown";
1321     }
1322 }
1323
1324 /**
1325  * If in verbose mode, print a block of binary data.
1326  *
1327  * @param data the data
1328  * @param len the length of the data
1329  * @param offset where to start counting for byte indexes
1330  */
1331 void
1332 _dbus_verbose_bytes (const unsigned char *data,
1333                      int                  len,
1334                      int                  offset)
1335 {
1336   int i;
1337   const unsigned char *aligned;
1338
1339   _dbus_assert (len >= 0);
1340
1341   if (!_dbus_is_verbose())
1342     return;
1343
1344   /* Print blanks on first row if appropriate */
1345   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1346   if (aligned > data)
1347     aligned -= 4;
1348   _dbus_assert (aligned <= data);
1349
1350   if (aligned != data)
1351     {
1352       _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
1353       while (aligned != data)
1354         {
1355           _dbus_verbose ("    ");
1356           ++aligned;
1357         }
1358     }
1359
1360   /* now print the bytes */
1361   i = 0;
1362   while (i < len)
1363     {
1364       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1365         {
1366           _dbus_verbose ("%4d\t%p: ",
1367                          offset + i, &data[i]);
1368         }
1369
1370       if (data[i] >= 32 &&
1371           data[i] <= 126)
1372         _dbus_verbose (" '%c' ", data[i]);
1373       else
1374         _dbus_verbose ("0x%s%x ",
1375                        data[i] <= 0xf ? "0" : "", data[i]);
1376
1377       ++i;
1378
1379       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1380         {
1381           if (i > 3)
1382             _dbus_verbose ("BE: %d LE: %d",
1383                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1384                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1385
1386           if (i > 7 &&
1387               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1388             {
1389 #ifdef DBUS_HAVE_INT64
1390               /* I think I probably mean "GNU libc printf" and not "GNUC"
1391                * but we'll wait until someone complains. If you hit this,
1392                * just turn off verbose mode as a workaround.
1393                */
1394 #if __GNUC__
1395               _dbus_verbose (" u64: 0x%llx",
1396                              *(dbus_uint64_t*)&data[i-8]);
1397 #endif
1398 #endif
1399               _dbus_verbose (" dbl: %g",
1400                              *(double*)&data[i-8]);
1401             }
1402
1403           _dbus_verbose ("\n");
1404         }
1405     }
1406
1407   _dbus_verbose ("\n");
1408 }
1409
1410 /**
1411  * Dump the given part of the string to verbose log.
1412  *
1413  * @param str the string
1414  * @param start the start of range to dump
1415  * @param len length of range
1416  */
1417 void
1418 _dbus_verbose_bytes_of_string (const DBusString    *str,
1419                                int                  start,
1420                                int                  len)
1421 {
1422   const char *d;
1423   int real_len;
1424
1425   real_len = _dbus_string_get_length (str);
1426
1427   _dbus_assert (start >= 0);
1428
1429   if (start > real_len)
1430     {
1431       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1432                      start, len, real_len);
1433       return;
1434     }
1435
1436   if ((start + len) > real_len)
1437     {
1438       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1439                      start, len, real_len);
1440       len = real_len - start;
1441     }
1442
1443   d = _dbus_string_get_const_data_len (str, start, len);
1444
1445   _dbus_verbose_bytes (d, len, start);
1446 }
1447
1448 static int
1449 map_type_char_to_type (int t)
1450 {
1451   if (t == DBUS_STRUCT_BEGIN_CHAR)
1452     return DBUS_TYPE_STRUCT;
1453   else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
1454     return DBUS_TYPE_DICT_ENTRY;
1455   else
1456     {
1457       _dbus_assert (t != DBUS_STRUCT_END_CHAR);
1458       _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR);
1459       return t;
1460     }
1461 }
1462
1463 /**
1464  * Get the first type in the signature. The difference between this
1465  * and just getting the first byte of the signature is that you won't
1466  * get DBUS_STRUCT_BEGIN_CHAR, you'll get DBUS_TYPE_STRUCT
1467  * instead.
1468  *
1469  * @param str string containing signature
1470  * @param pos where the signature starts
1471  * @returns the first type in the signature
1472  */
1473 int
1474 _dbus_first_type_in_signature (const DBusString *str,
1475                                int               pos)
1476 {
1477   return map_type_char_to_type (_dbus_string_get_byte (str, pos));
1478 }
1479
1480 /**
1481  * Similar to #_dbus_first_type_in_signature, but operates
1482  * on a C string buffer.
1483  *
1484  * @param str a C string buffer
1485  * @param pos where the signature starts
1486  * @returns the first type in the signature
1487  */
1488 int
1489 _dbus_first_type_in_signature_c_str (const char       *str,
1490                                      int               pos)
1491 {
1492   return map_type_char_to_type (str[pos]);
1493 }
1494
1495 /** @} */
1496
1497 #ifdef DBUS_BUILD_TESTS
1498 #include "dbus-test.h"
1499 #include <stdio.h>
1500
1501 /**
1502  * Reads a block of fixed-length basic values, as an optimization
1503  * vs. reading each one individually into a new buffer.
1504  *
1505  * This function returns the data in-place; it does not make a copy,
1506  * and it does not swap the bytes.
1507  *
1508  * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back
1509  * and the "value" argument should be a "const double**" and so on.
1510  *
1511  * @param str the string to read from
1512  * @param pos position to read from
1513  * @param element_type type of array elements
1514  * @param value place to return the array
1515  * @param n_elements number of array elements to read
1516  * @param byte_order the byte order, used to read the array length
1517  * @param new_pos #NULL or location to store a position after the elements
1518  */
1519 void
1520 _dbus_marshal_read_fixed_multi  (const DBusString *str,
1521                                  int               pos,
1522                                  int               element_type,
1523                                  void             *value,
1524                                  int               n_elements,
1525                                  int               byte_order,
1526                                  int              *new_pos)
1527 {
1528   int array_len;
1529   int alignment;
1530
1531   _dbus_assert (dbus_type_is_fixed (element_type));
1532   _dbus_assert (dbus_type_is_basic (element_type));
1533
1534 #if 0
1535   _dbus_verbose ("reading %d elements of %s\n",
1536                  n_elements, _dbus_type_to_string (element_type));
1537 #endif
1538   
1539   alignment = _dbus_type_get_alignment (element_type);
1540
1541   pos = _DBUS_ALIGN_VALUE (pos, alignment);
1542   
1543   array_len = n_elements * alignment;
1544
1545   *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
1546   if (new_pos)
1547     *new_pos = pos + array_len;
1548 }
1549
1550 static void
1551 swap_test_array (void *array,
1552                  int   len_bytes,
1553                  int   byte_order,
1554                  int   alignment)
1555 {
1556   DBusString t;
1557
1558   if (alignment == 1)
1559     return;
1560   
1561   _dbus_string_init_const_len (&t, array, len_bytes);
1562   swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
1563 }
1564
1565 #define MARSHAL_BASIC(typename, byte_order, literal)                    \
1566   do {                                                                  \
1567      v_##typename = literal;                                            \
1568      if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename,   \
1569                                     &v_##typename,                      \
1570                                     byte_order, NULL))                  \
1571        _dbus_assert_not_reached ("no memory");                          \
1572    } while (0)
1573
1574 #define DEMARSHAL_BASIC(typename, byte_order)                                   \
1575   do {                                                                          \
1576     _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename,   \
1577                               byte_order, &pos);                                \
1578   } while (0)
1579
1580 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \
1581   do {                                                                                  \
1582     DEMARSHAL_BASIC (typename, byte_order);                                             \
1583     if (literal != v_##typename)                                                        \
1584       {                                                                                 \
1585         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
1586                                      _dbus_string_get_length (&str) - dump_pos);        \
1587         _dbus_assert_not_reached ("demarshaled wrong value");                           \
1588       }                                                                                 \
1589   } while (0)
1590
1591 #define MARSHAL_TEST(typename, byte_order, literal)             \
1592   do {                                                          \
1593     MARSHAL_BASIC (typename, byte_order, literal);              \
1594     dump_pos = pos;                                             \
1595     DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal);  \
1596   } while (0)
1597
1598 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal)                              \
1599   do {                                                                                  \
1600     MARSHAL_BASIC (typename, byte_order, literal);                                      \
1601     dump_pos = pos;                                                                     \
1602     DEMARSHAL_BASIC (typename, byte_order);                                             \
1603     if (strcmp (literal, v_##typename) != 0)                                            \
1604       {                                                                                 \
1605         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
1606                                        _dbus_string_get_length (&str) - dump_pos);      \
1607         _dbus_warn ("literal '%s'\nvalue  '%s'\n", literal, v_##typename);              \
1608         _dbus_assert_not_reached ("demarshaled wrong value");                           \
1609       }                                                                                 \
1610   } while (0)
1611
1612 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal)                                      \
1613   do {                                                                                          \
1614      int next;                                                                                  \
1615      v_UINT32 = sizeof(literal);                                                                \
1616      if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32,                    \
1617                                      byte_order, &next))                                        \
1618        _dbus_assert_not_reached ("no memory");                                                  \
1619      v_ARRAY_##typename = literal;                                                              \
1620      if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename,                    \
1621                                            &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal),      \
1622                                            byte_order, NULL))                                   \
1623        _dbus_assert_not_reached ("no memory");                                                  \
1624    } while (0)
1625
1626 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order)                                             \
1627   do {                                                                                          \
1628     int next;                                                                                   \
1629     alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename);                                \
1630     v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next);                   \
1631     _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename,      \
1632                                     v_UINT32/alignment,                                         \
1633                                     byte_order, NULL);                                          \
1634     swap_test_array (v_ARRAY_##typename, v_UINT32,                                              \
1635                      byte_order, alignment);                                                    \
1636   } while (0)
1637
1638 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal)                  \
1639   do {                                                                                  \
1640     DEMARSHAL_FIXED_ARRAY (typename, byte_order);                                       \
1641     if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0))                    \
1642       {                                                                                 \
1643         _dbus_verbose ("MARSHALED DATA\n");                                             \
1644         _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
1645                                       _dbus_string_get_length (&str) - dump_pos);       \
1646         _dbus_verbose ("LITERAL DATA\n");                                               \
1647         _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0);                      \
1648         _dbus_verbose ("READ DATA\n");                                                  \
1649         _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0);           \
1650         _dbus_assert_not_reached ("demarshaled wrong fixed array value");               \
1651       }                                                                                 \
1652   } while (0)
1653
1654 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal)         \
1655   do {                                                                  \
1656     MARSHAL_FIXED_ARRAY (typename, byte_order, literal);                \
1657     dump_pos = pos;                                                     \
1658     DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal);    \
1659   } while (0)
1660
1661 dbus_bool_t
1662 _dbus_marshal_test (void)
1663 {
1664   int alignment;
1665   DBusString str;
1666   int pos, dump_pos;
1667   unsigned char array1[5] = { 3, 4, 0, 1, 9 };
1668   dbus_int16_t array2[3] = { 124, 457, 780 };
1669   dbus_int32_t array4[3] = { 123, 456, 789 };
1670 #ifdef DBUS_HAVE_INT64
1671   dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
1672                              DBUS_INT64_CONSTANT (0x456ffffffff),
1673                              DBUS_INT64_CONSTANT (0x789ffffffff) };
1674   dbus_int64_t *v_ARRAY_INT64;
1675 #endif
1676   unsigned char *v_ARRAY_BYTE;
1677   dbus_int16_t *v_ARRAY_INT16;
1678   dbus_uint16_t *v_ARRAY_UINT16;
1679   dbus_int32_t *v_ARRAY_INT32;
1680   dbus_uint32_t *v_ARRAY_UINT32;
1681   DBusString t;
1682   double v_DOUBLE;
1683   double t_DOUBLE;
1684   dbus_int16_t v_INT16;
1685   dbus_uint16_t v_UINT16;
1686   dbus_int32_t v_INT32;
1687   dbus_uint32_t v_UINT32;
1688   dbus_int64_t v_INT64;
1689   dbus_uint64_t v_UINT64;
1690   unsigned char v_BYTE;
1691   dbus_bool_t v_BOOLEAN;
1692   const char *v_STRING;
1693   const char *v_SIGNATURE;
1694   const char *v_OBJECT_PATH;
1695   int byte_order;
1696
1697   if (!_dbus_string_init (&str))
1698     _dbus_assert_not_reached ("failed to init string");
1699
1700   pos = 0;
1701
1702   /* Marshal doubles */
1703   MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
1704   DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
1705   t_DOUBLE = 3.14;
1706   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1707     _dbus_assert_not_reached ("got wrong double value");
1708
1709   MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
1710   DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
1711   t_DOUBLE = 3.14;
1712   if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1713     _dbus_assert_not_reached ("got wrong double value");
1714
1715   /* Marshal signed 16 integers */
1716   MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
1717   MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
1718
1719   /* Marshal unsigned 16 integers */
1720   MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
1721   MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
1722   
1723   /* Marshal signed integers */
1724   MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
1725   MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
1726
1727   /* Marshal unsigned integers */
1728   MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
1729   MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
1730
1731 #ifdef DBUS_HAVE_INT64
1732   /* Marshal signed integers */
1733   MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1734   MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1735
1736   /* Marshal unsigned integers */
1737   MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1738   MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1739 #endif /* DBUS_HAVE_INT64 */
1740
1741   /* Marshal byte */
1742   MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
1743   MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
1744
1745   /* Marshal all possible bools! */
1746   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
1747   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
1748   MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
1749   MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
1750
1751   /* Marshal strings */
1752   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
1753   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
1754   MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
1755   MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
1756
1757   /* object paths */
1758   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
1759   MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
1760
1761   /* signatures */
1762   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
1763   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
1764   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
1765   MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
1766
1767   /* Arrays */
1768   MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
1769   MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
1770   MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2);
1771   MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2);
1772   
1773   MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
1774   MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
1775   MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4);
1776   MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4);
1777
1778   MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
1779   MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
1780   
1781 #ifdef DBUS_HAVE_INT64
1782   MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
1783   MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
1784 #endif
1785
1786 #if 0
1787
1788   /*
1789    * FIXME restore the set/pack tests
1790    */
1791
1792 #ifdef DBUS_HAVE_INT64
1793   /* set/pack 64-bit integers */
1794   _dbus_string_set_length (&str, 8);
1795
1796   /* signed little */
1797   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
1798                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1799
1800   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1801                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1802                                     _dbus_string_get_const_data (&str)));
1803
1804   /* signed big */
1805   _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
1806                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1807
1808   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1809                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1810                                     _dbus_string_get_const_data (&str)));
1811
1812   /* signed little pack */
1813   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1814                     DBUS_LITTLE_ENDIAN,
1815                     _dbus_string_get_data (&str));
1816
1817   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1818                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1819                                     _dbus_string_get_const_data (&str)));
1820
1821   /* signed big pack */
1822   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1823                     DBUS_BIG_ENDIAN,
1824                     _dbus_string_get_data (&str));
1825
1826   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1827                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1828                                     _dbus_string_get_const_data (&str)));
1829
1830   /* unsigned little */
1831   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
1832                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1833
1834   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1835                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1836                                      _dbus_string_get_const_data (&str)));
1837
1838   /* unsigned big */
1839   _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
1840                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1841
1842   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1843                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1844                                      _dbus_string_get_const_data (&str)));
1845
1846   /* unsigned little pack */
1847   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1848                      DBUS_LITTLE_ENDIAN,
1849                      _dbus_string_get_data (&str));
1850
1851   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1852                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1853                                      _dbus_string_get_const_data (&str)));
1854
1855   /* unsigned big pack */
1856   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1857                      DBUS_BIG_ENDIAN,
1858                      _dbus_string_get_data (&str));
1859
1860   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1861                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1862                                      _dbus_string_get_const_data (&str)));
1863 #endif /* DBUS_HAVE_INT64 */
1864
1865   /* set/pack 32-bit integers */
1866   _dbus_string_set_length (&str, 4);
1867
1868   /* signed little */
1869   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
1870                            0, -0x123456);
1871
1872   _dbus_assert (-0x123456 ==
1873                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1874                                     _dbus_string_get_const_data (&str)));
1875
1876   /* signed big */
1877   _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
1878                            0, -0x123456);
1879
1880   _dbus_assert (-0x123456 ==
1881                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1882                                     _dbus_string_get_const_data (&str)));
1883
1884   /* signed little pack */
1885   _dbus_pack_int32 (-0x123456,
1886                     DBUS_LITTLE_ENDIAN,
1887                     _dbus_string_get_data (&str));
1888
1889   _dbus_assert (-0x123456 ==
1890                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1891                                     _dbus_string_get_const_data (&str)));
1892
1893   /* signed big pack */
1894   _dbus_pack_int32 (-0x123456,
1895                     DBUS_BIG_ENDIAN,
1896                     _dbus_string_get_data (&str));
1897
1898   _dbus_assert (-0x123456 ==
1899                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1900                                     _dbus_string_get_const_data (&str)));
1901
1902   /* unsigned little */
1903   _dbus_marshal_set_uint32 (&str,
1904                             0, 0x123456,
1905                             DBUS_LITTLE_ENDIAN);
1906
1907   _dbus_assert (0x123456 ==
1908                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
1909                                      _dbus_string_get_const_data (&str)));
1910
1911   /* unsigned big */
1912   _dbus_marshal_set_uint32 (&str,
1913                             0, 0x123456,
1914                             DBUS_BIG_ENDIAN);
1915
1916   _dbus_assert (0x123456 ==
1917                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
1918                                      _dbus_string_get_const_data (&str)));
1919
1920   /* unsigned little pack */
1921   _dbus_pack_uint32 (0x123456,
1922                      DBUS_LITTLE_ENDIAN,
1923                      _dbus_string_get_data (&str));
1924
1925   _dbus_assert (0x123456 ==
1926                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
1927                                      _dbus_string_get_const_data (&str)));
1928
1929   /* unsigned big pack */
1930   _dbus_pack_uint32 (0x123456,
1931                      DBUS_BIG_ENDIAN,
1932                      _dbus_string_get_data (&str));
1933
1934   _dbus_assert (0x123456 ==
1935                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
1936                                      _dbus_string_get_const_data (&str)));
1937
1938 #endif /* set/pack tests for integers */
1939
1940   /* Strings in-place set */
1941   byte_order = DBUS_LITTLE_ENDIAN;
1942   while (TRUE)
1943     {
1944       /* Init a string */
1945       _dbus_string_set_length (&str, 0);
1946
1947       /* reset pos for the macros */
1948       pos = 0;
1949
1950       MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
1951
1952       /* Set it to something longer */
1953       _dbus_string_init_const (&t, "Hello world foo");
1954
1955       v_STRING = _dbus_string_get_const_data (&t);
1956       _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
1957                                &v_STRING, byte_order, NULL, NULL);
1958
1959       _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
1960                                 &v_STRING, byte_order,
1961                                 NULL);
1962       _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
1963
1964       /* Set it to something shorter */
1965       _dbus_string_init_const (&t, "Hello");
1966
1967       v_STRING = _dbus_string_get_const_data (&t);
1968       _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
1969                                &v_STRING, byte_order, NULL, NULL);
1970       _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
1971                                 &v_STRING, byte_order,
1972                                 NULL);
1973       _dbus_assert (strcmp (v_STRING, "Hello") == 0);
1974
1975       /* Do the other byte order */
1976       if (byte_order == DBUS_LITTLE_ENDIAN)
1977         byte_order = DBUS_BIG_ENDIAN;
1978       else
1979         break;
1980     }
1981
1982   /* Clean up */
1983   _dbus_string_free (&str);
1984
1985   return TRUE;
1986 }
1987
1988 #endif /* DBUS_BUILD_TESTS */