1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c Marshalling routines
4 * Copyright (C) 2002 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the Academic Free License version 1.2
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.
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.
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
25 #include "dbus-marshal.h"
26 #include "dbus-internals.h"
27 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
28 #include "dbus-string-private.h"
33 * @defgroup DBusMarshal marshaling and unmarshaling
34 * @ingroup DBusInternals
35 * @brief functions to marshal/unmarshal data from the wire
37 * Types and functions related to converting primitive data types from
38 * wire format to native machine format, and vice versa.
44 unpack_4_octets (int byte_order,
45 const unsigned char *data)
47 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
49 if (byte_order == DBUS_LITTLE_ENDIAN)
50 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
52 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
55 #ifndef DBUS_HAVE_INT64
58 swap_bytes (unsigned char *data,
61 unsigned char *p1 = data;
62 unsigned char *p2 = data + len - 1;
66 unsigned char tmp = *p1;
74 #endif /* !DBUS_HAVE_INT64 */
77 * Union used to manipulate 8 bytes as if they
82 #ifdef DBUS_HAVE_INT64
83 dbus_int64_t s; /**< 64-bit integer */
84 dbus_uint64_t u; /**< 64-bit unsinged integer */
86 double d; /**< double */
90 unpack_8_octets (int byte_order,
91 const unsigned char *data)
95 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
96 _dbus_assert (sizeof (r) == 8);
98 #ifdef DBUS_HAVE_INT64
99 if (byte_order == DBUS_LITTLE_ENDIAN)
100 r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
102 r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
104 r.d = *(double*)data;
105 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
106 swap_bytes ((unsigned char*) &r, sizeof (r));
113 * Unpacks a 32 bit unsigned integer from a data pointer
115 * @param byte_order The byte order to use
116 * @param data the data pointer
117 * @returns the integer
120 _dbus_unpack_uint32 (int byte_order,
121 const unsigned char *data)
123 return unpack_4_octets (byte_order, data);
127 * Unpacks a 32 bit signed integer from a data pointer
129 * @param byte_order The byte order to use
130 * @param data the data pointer
131 * @returns the integer
134 _dbus_unpack_int32 (int byte_order,
135 const unsigned char *data)
137 return (dbus_int32_t) unpack_4_octets (byte_order, data);
140 #ifdef DBUS_HAVE_INT64
142 * Unpacks a 64 bit unsigned integer from a data pointer
144 * @param byte_order The byte order to use
145 * @param data the data pointer
146 * @returns the integer
149 _dbus_unpack_uint64 (int byte_order,
150 const unsigned char *data)
154 r = unpack_8_octets (byte_order, data);
160 * Unpacks a 64 bit signed integer from a data pointer
162 * @param byte_order The byte order to use
163 * @param data the data pointer
164 * @returns the integer
167 _dbus_unpack_int64 (int byte_order,
168 const unsigned char *data)
172 r = unpack_8_octets (byte_order, data);
177 #endif /* DBUS_HAVE_INT64 */
180 pack_4_octets (dbus_uint32_t value,
184 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
186 if ((byte_order) == DBUS_LITTLE_ENDIAN)
187 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
189 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
193 pack_8_octets (DBusOctets8 value,
197 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
199 #ifdef DBUS_HAVE_INT64
200 if ((byte_order) == DBUS_LITTLE_ENDIAN)
201 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
203 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
205 memcpy (data, &value, 8);
206 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
207 swap_bytes ((unsigned char *)data, 8);
212 * Packs a 32 bit unsigned integer into a data pointer.
214 * @param value the value
215 * @param byte_order the byte order to use
216 * @param data the data pointer
219 _dbus_pack_uint32 (dbus_uint32_t value,
223 pack_4_octets (value, byte_order, data);
227 * Packs a 32 bit signed integer into a data pointer.
229 * @param value the value
230 * @param byte_order the byte order to use
231 * @param data the data pointer
234 _dbus_pack_int32 (dbus_int32_t value,
238 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
241 #ifdef DBUS_HAVE_INT64
243 * Packs a 64 bit unsigned integer into a data pointer.
245 * @param value the value
246 * @param byte_order the byte order to use
247 * @param data the data pointer
250 _dbus_pack_uint64 (dbus_uint64_t value,
256 pack_8_octets (r, byte_order, data);
260 * Packs a 64 bit signed integer into a data pointer.
262 * @param value the value
263 * @param byte_order the byte order to use
264 * @param data the data pointer
267 _dbus_pack_int64 (dbus_int64_t value,
273 pack_8_octets (r, byte_order, data);
275 #endif /* DBUS_HAVE_INT64 */
278 set_4_octets (DBusString *str,
285 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
286 byte_order == DBUS_BIG_ENDIAN);
288 data = _dbus_string_get_data_len (str, offset, 4);
290 _dbus_pack_uint32 (value, byte_order, data);
294 set_8_octets (DBusString *str,
301 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
302 byte_order == DBUS_BIG_ENDIAN);
304 data = _dbus_string_get_data_len (str, offset, 8);
306 pack_8_octets (value, byte_order, data);
310 * Sets the 4 bytes at the given offset to a marshaled signed integer,
311 * replacing anything found there previously.
313 * @param str the string to write the marshalled int to
314 * @param offset the byte offset where int should be written
315 * @param byte_order the byte order to use
316 * @param value the value
320 _dbus_marshal_set_int32 (DBusString *str,
325 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
329 * Sets the 4 bytes at the given offset to a marshaled unsigned
330 * integer, replacing anything found there previously.
332 * @param str the string to write the marshalled int to
333 * @param offset the byte offset where int should be written
334 * @param byte_order the byte order to use
335 * @param value the value
339 _dbus_marshal_set_uint32 (DBusString *str,
344 set_4_octets (str, byte_order, offset, value);
347 #ifdef DBUS_HAVE_INT64
350 * Sets the 8 bytes at the given offset to a marshaled signed integer,
351 * replacing anything found there previously.
353 * @param str the string to write the marshalled int to
354 * @param offset the byte offset where int should be written
355 * @param byte_order the byte order to use
356 * @param value the value
360 _dbus_marshal_set_int64 (DBusString *str,
367 set_8_octets (str, byte_order, offset, r);
371 * Sets the 8 bytes at the given offset to a marshaled unsigned
372 * integer, replacing anything found there previously.
374 * @param str the string to write the marshalled int to
375 * @param offset the byte offset where int should be written
376 * @param byte_order the byte order to use
377 * @param value the value
381 _dbus_marshal_set_uint64 (DBusString *str,
388 set_8_octets (str, byte_order, offset, r);
390 #endif /* DBUS_HAVE_INT64 */
393 * Sets the existing marshaled string at the given offset with
394 * a new marshaled string. The given offset must point to
395 * an existing string or the wrong length will be deleted
396 * and replaced with the new string.
398 * @param str the string to write the marshalled string to
399 * @param offset the byte offset where string should be written
400 * @param byte_order the byte order to use
401 * @param value the value
402 * @param len the length to use
403 * @returns #TRUE on success
407 _dbus_marshal_set_string (DBusString *str,
410 const DBusString *value,
415 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
416 byte_order == DBUS_BIG_ENDIAN);
418 old_len = _dbus_demarshal_uint32 (str, byte_order,
421 if (!_dbus_string_replace_len (value, 0, len,
422 str, offset + 4, old_len))
425 _dbus_marshal_set_uint32 (str, byte_order,
432 * Sets the existing marshaled object path at the given offset to a new
433 * value. The given offset must point to an existing object path or this
434 * function doesn't make sense.
436 * @todo implement this function
438 * @param str the string to write the marshalled path to
439 * @param offset the byte offset where path should be written
440 * @param byte_order the byte order to use
441 * @param path the new path
442 * @param path_len number of elements in the path
445 _dbus_marshal_set_object_path (DBusString *str,
456 marshal_4_octets (DBusString *str,
460 _dbus_assert (sizeof (value) == 4);
462 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
463 value = DBUS_UINT32_SWAP_LE_BE (value);
465 return _dbus_string_append_4_aligned (str,
466 (const unsigned char *)&value);
470 marshal_8_octets (DBusString *str,
474 _dbus_assert (sizeof (value) == 8);
476 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
477 pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
479 return _dbus_string_append_8_aligned (str,
480 (const unsigned char *)&value);
484 * Marshals a double value.
486 * @param str the string to append the marshalled value to
487 * @param byte_order the byte order to use
488 * @param value the value
489 * @returns #TRUE on success
492 _dbus_marshal_double (DBusString *str,
498 return marshal_8_octets (str, byte_order, r);
502 * Marshals a 32 bit signed integer value.
504 * @param str the string to append the marshalled value to
505 * @param byte_order the byte order to use
506 * @param value the value
507 * @returns #TRUE on success
510 _dbus_marshal_int32 (DBusString *str,
514 return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
518 * Marshals a 32 bit unsigned integer value.
520 * @param str the string to append the marshalled value to
521 * @param byte_order the byte order to use
522 * @param value the value
523 * @returns #TRUE on success
526 _dbus_marshal_uint32 (DBusString *str,
530 return marshal_4_octets (str, byte_order, value);
534 #ifdef DBUS_HAVE_INT64
536 * Marshals a 64 bit signed integer value.
538 * @param str the string to append the marshalled value to
539 * @param byte_order the byte order to use
540 * @param value the value
541 * @returns #TRUE on success
544 _dbus_marshal_int64 (DBusString *str,
550 return marshal_8_octets (str, byte_order, r);
554 * Marshals a 64 bit unsigned integer value.
556 * @param str the string to append the marshalled value to
557 * @param byte_order the byte order to use
558 * @param value the value
559 * @returns #TRUE on success
562 _dbus_marshal_uint64 (DBusString *str,
568 return marshal_8_octets (str, byte_order, r);
571 #endif /* DBUS_HAVE_INT64 */
574 * Marshals a UTF-8 string
576 * @todo: If the string append fails we need to restore
577 * the old length. (also for other marshallers)
579 * @param str the string to append the marshalled value to
580 * @param byte_order the byte order to use
581 * @param value the string
582 * @returns #TRUE on success
585 _dbus_marshal_string (DBusString *str,
589 int len, old_string_len;
591 old_string_len = _dbus_string_get_length (str);
593 len = strlen (value);
595 if (!_dbus_marshal_uint32 (str, byte_order, len))
597 /* Restore the previous length */
598 _dbus_string_set_length (str, old_string_len);
603 return _dbus_string_append_len (str, value, len + 1);
607 * Marshals a byte array
609 * @param str the string to append the marshalled value to
610 * @param byte_order the byte order to use
611 * @param value the array
612 * @param len number of elements in the array
613 * @returns #TRUE on success
616 _dbus_marshal_byte_array (DBusString *str,
618 const unsigned char *value,
623 old_string_len = _dbus_string_get_length (str);
625 if (!_dbus_marshal_uint32 (str, byte_order, len))
627 /* Restore the previous length */
628 _dbus_string_set_length (str, old_string_len);
636 return _dbus_string_append_len (str, value, len);
640 marshal_4_octets_array (DBusString *str,
642 const dbus_uint32_t *value,
648 old_string_len = _dbus_string_get_length (str);
650 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
653 array_start = _dbus_string_get_length (str);
655 if (!_dbus_string_append_len (str, (const unsigned char*) value,
659 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
661 const unsigned char *d;
662 const unsigned char *end;
664 d = _dbus_string_get_data (str) + array_start;
668 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
676 /* Restore previous length */
677 _dbus_string_set_length (str, old_string_len);
683 marshal_8_octets_array (DBusString *str,
685 const DBusOctets8 *value,
691 old_string_len = _dbus_string_get_length (str);
693 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
696 array_start = _dbus_string_get_length (str);
698 if (!_dbus_string_append_len (str, (const unsigned char*) value,
702 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
704 const unsigned char *d;
705 const unsigned char *end;
707 d = _dbus_string_get_data (str) + array_start;
711 #ifdef DBUS_HAVE_INT64
712 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
714 swap_bytes ((unsigned char*) d, 8);
723 /* Restore previous length */
724 _dbus_string_set_length (str, old_string_len);
730 * Marshals a 32 bit signed integer array
732 * @param str the string to append the marshalled value to
733 * @param byte_order the byte order to use
734 * @param value the array
735 * @param len the length of the array
736 * @returns #TRUE on success
739 _dbus_marshal_int32_array (DBusString *str,
741 const dbus_int32_t *value,
744 return marshal_4_octets_array (str, byte_order,
745 (const dbus_uint32_t*) value,
750 * Marshals a 32 bit unsigned integer array
752 * @param str the string to append the marshalled value to
753 * @param byte_order the byte order to use
754 * @param value the array
755 * @param len the length of the array
756 * @returns #TRUE on success
759 _dbus_marshal_uint32_array (DBusString *str,
761 const dbus_uint32_t *value,
764 return marshal_4_octets_array (str, byte_order,
769 #ifdef DBUS_HAVE_INT64
772 * Marshals a 64 bit signed integer array
774 * @param str the string to append the marshalled value to
775 * @param byte_order the byte order to use
776 * @param value the array
777 * @param len the length of the array
778 * @returns #TRUE on success
781 _dbus_marshal_int64_array (DBusString *str,
783 const dbus_int64_t *value,
786 return marshal_8_octets_array (str, byte_order,
787 (const DBusOctets8*) value,
792 * Marshals a 64 bit unsigned integer array
794 * @param str the string to append the marshalled value to
795 * @param byte_order the byte order to use
796 * @param value the array
797 * @param len the length of the array
798 * @returns #TRUE on success
801 _dbus_marshal_uint64_array (DBusString *str,
803 const dbus_uint64_t *value,
806 return marshal_8_octets_array (str, byte_order,
807 (const DBusOctets8*) value,
811 #endif /* DBUS_HAVE_INT64 */
814 * Marshals a double array
816 * @param str the string to append the marshalled value to
817 * @param byte_order the byte order to use
818 * @param value the array
819 * @param len the length of the array
820 * @returns #TRUE on success
823 _dbus_marshal_double_array (DBusString *str,
828 return marshal_8_octets_array (str, byte_order,
829 (const DBusOctets8*) value,
834 * Marshals a string array
836 * @param str the string to append the marshalled value to
837 * @param byte_order the byte order to use
838 * @param value the array
839 * @param len the length of the array
840 * @returns #TRUE on success
843 _dbus_marshal_string_array (DBusString *str,
848 int i, old_string_len, array_start;
850 old_string_len = _dbus_string_get_length (str);
852 /* Set the length to 0 temporarily */
853 if (!_dbus_marshal_uint32 (str, byte_order, 0))
856 array_start = _dbus_string_get_length (str);
858 for (i = 0; i < len; i++)
859 if (!_dbus_marshal_string (str, byte_order, value[i]))
862 /* Write the length now that we know it */
863 _dbus_marshal_set_uint32 (str, byte_order,
864 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
865 _dbus_string_get_length (str) - array_start);
870 /* Restore previous length */
871 _dbus_string_set_length (str, old_string_len);
877 * Marshals an object path value.
879 * @param str the string to append the marshalled value to
880 * @param byte_order the byte order to use
881 * @param path the path
882 * @param path_len length of the path
883 * @returns #TRUE on success
886 _dbus_marshal_object_path (DBusString *str,
891 int array_start, old_string_len;
894 old_string_len = _dbus_string_get_length (str);
896 /* Set the length to 0 temporarily */
897 if (!_dbus_marshal_uint32 (str, byte_order, 0))
900 array_start = _dbus_string_get_length (str);
905 if (!_dbus_string_append_byte (str, '/'))
908 if (!_dbus_string_append (str, path[0]))
914 /* Write the length now that we know it */
915 _dbus_marshal_set_uint32 (str, byte_order,
916 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
917 _dbus_string_get_length (str) - array_start);
922 /* Restore the previous length */
923 _dbus_string_set_length (str, old_string_len);
929 demarshal_4_octets (const DBusString *str,
934 const DBusRealString *real = (const DBusRealString*) str;
936 pos = _DBUS_ALIGN_VALUE (pos, 4);
941 return unpack_4_octets (byte_order, real->str + pos);
945 demarshal_8_octets (const DBusString *str,
950 const DBusRealString *real = (const DBusRealString*) str;
952 pos = _DBUS_ALIGN_VALUE (pos, 8);
957 return unpack_8_octets (byte_order, real->str + pos);
961 * Demarshals a double.
963 * @param str the string containing the data
964 * @param byte_order the byte order
965 * @param pos the position in the string
966 * @param new_pos the new position of the string
967 * @returns the demarshaled double.
970 _dbus_demarshal_double (const DBusString *str,
977 r = demarshal_8_octets (str, byte_order, pos, new_pos);
983 * Demarshals a 32 bit signed integer.
985 * @param str the string containing the data
986 * @param byte_order the byte order
987 * @param pos the position in the string
988 * @param new_pos the new position of the string
989 * @returns the demarshaled integer.
992 _dbus_demarshal_int32 (const DBusString *str,
997 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
1001 * Demarshals a 32 bit unsigned integer.
1003 * @param str the string containing the data
1004 * @param byte_order the byte order
1005 * @param pos the position in the string
1006 * @param new_pos the new position of the string
1007 * @returns the demarshaled integer.
1010 _dbus_demarshal_uint32 (const DBusString *str,
1015 return demarshal_4_octets (str, byte_order, pos, new_pos);
1018 #ifdef DBUS_HAVE_INT64
1021 * Demarshals a 64 bit signed integer.
1023 * @param str the string containing the data
1024 * @param byte_order the byte order
1025 * @param pos the position in the string
1026 * @param new_pos the new position of the string
1027 * @returns the demarshaled integer.
1030 _dbus_demarshal_int64 (const DBusString *str,
1037 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1043 * Demarshals a 64 bit unsigned integer.
1045 * @param str the string containing the data
1046 * @param byte_order the byte order
1047 * @param pos the position in the string
1048 * @param new_pos the new position of the string
1049 * @returns the demarshaled integer.
1052 _dbus_demarshal_uint64 (const DBusString *str,
1059 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1064 #endif /* DBUS_HAVE_INT64 */
1067 * Demarshals an UTF-8 string.
1069 * @todo Should we check the string to make sure
1070 * that it's valid UTF-8, and maybe "fix" the string
1073 * @todo Should probably demarshal to a DBusString,
1074 * having memcpy() in here is Evil(tm).
1076 * @param str the string containing the data
1077 * @param byte_order the byte order
1078 * @param pos the position in the string
1079 * @param new_pos the new position of the string
1080 * @returns the demarshaled string.
1083 _dbus_demarshal_string (const DBusString *str,
1092 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1094 retval = dbus_malloc (len + 1);
1099 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1104 memcpy (retval, data, len + 1);
1107 *new_pos = pos + len + 1;
1113 * Demarshals a byte array.
1115 * @todo Should probably demarshal to a DBusString,
1116 * having memcpy() in here is Evil(tm).
1118 * @param str the string containing the data
1119 * @param byte_order the byte order
1120 * @param pos the position in the string
1121 * @param new_pos the new position of the string
1122 * @param array the array
1123 * @param array_len length of the demarshaled data
1125 * @returns #TRUE on success
1128 _dbus_demarshal_byte_array (const DBusString *str,
1132 unsigned char **array,
1136 unsigned char *retval;
1139 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1152 retval = dbus_malloc (len);
1157 data = _dbus_string_get_const_data_len (str, pos, len);
1165 memcpy (retval, data, len);
1168 *new_pos = pos + len;
1177 demarshal_4_octets_array (const DBusString *str,
1181 dbus_uint32_t **array,
1185 dbus_uint32_t *retval;
1188 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1202 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1206 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1208 for (i = 0; i < len; i++)
1209 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1213 *new_pos = pos + byte_len;
1222 demarshal_8_octets_array (const DBusString *str,
1226 DBusOctets8 **array,
1230 DBusOctets8 *retval;
1233 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1247 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1251 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1253 for (i = 0; i < len; i++)
1255 #ifdef DBUS_HAVE_INT64
1256 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1258 swap_bytes ((unsigned char *) &retval[i], 8);
1264 *new_pos = pos + byte_len;
1273 * Demarshals a 32 bit signed integer array.
1275 * @param str the string containing the data
1276 * @param byte_order the byte order
1277 * @param pos the position in the string
1278 * @param new_pos the new position of the string
1279 * @param array the array
1280 * @param array_len length of the demarshaled data
1281 * @returns #TRUE on success
1284 _dbus_demarshal_int32_array (const DBusString *str,
1288 dbus_int32_t **array,
1291 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1292 (dbus_uint32_t**) array, array_len);
1296 * Demarshals a 32 bit unsigned integer array.
1298 * @param str the string containing the data
1299 * @param byte_order the byte order
1300 * @param pos the position in the string
1301 * @param new_pos the new position of the string
1302 * @param array the array
1303 * @param array_len length of the demarshaled data
1304 * @returns #TRUE on success
1307 _dbus_demarshal_uint32_array (const DBusString *str,
1311 dbus_uint32_t **array,
1314 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1318 #ifdef DBUS_HAVE_INT64
1321 * Demarshals a 64 bit signed integer array.
1323 * @param str the string containing the data
1324 * @param byte_order the byte order
1325 * @param pos the position in the string
1326 * @param new_pos the new position of the string
1327 * @param array the array
1328 * @param array_len length of the demarshaled data
1329 * @returns #TRUE on success
1332 _dbus_demarshal_int64_array (const DBusString *str,
1336 dbus_int64_t **array,
1339 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1340 (DBusOctets8**) array, array_len);
1344 * Demarshals a 64 bit unsigned integer array.
1346 * @param str the string containing the data
1347 * @param byte_order the byte order
1348 * @param pos the position in the string
1349 * @param new_pos the new position of the string
1350 * @param array the array
1351 * @param array_len length of the demarshaled data
1352 * @returns #TRUE on success
1355 _dbus_demarshal_uint64_array (const DBusString *str,
1359 dbus_uint64_t **array,
1362 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1363 (DBusOctets8**) array, array_len);
1366 #endif /* DBUS_HAVE_INT64 */
1369 * Demarshals a double array.
1371 * @param str the string containing the data
1372 * @param byte_order the byte order
1373 * @param pos the position in the string
1374 * @param new_pos the new position of the string
1375 * @param array the array
1376 * @param array_len length of the demarshaled data
1377 * @returns #TRUE on success
1380 _dbus_demarshal_double_array (const DBusString *str,
1387 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1388 (DBusOctets8**) array, array_len);
1392 * Demarshals a string array.
1394 * @param str the string containing the data
1395 * @param byte_order the byte order
1396 * @param pos the position in the string
1397 * @param new_pos the new position of the string
1398 * @param array the array
1399 * @param array_len length of the demarshaled data
1400 * @returns #TRUE on success
1403 _dbus_demarshal_string_array (const DBusString *str,
1415 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1430 end_pos = pos + bytes_len;
1432 retval = dbus_new (char *, allocated);
1437 while (pos < end_pos)
1439 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1441 if (retval[len] == NULL)
1446 if (len >= allocated - 1) /* -1 for NULL termination */
1449 newp = dbus_realloc (retval,
1450 sizeof (char*) * allocated * 2);
1470 for (i = 0; i < len; i++)
1471 dbus_free (retval[i]);
1477 /** Set to 1 to get a bunch of spew about disassembling the path string */
1478 #define VERBOSE_DECOMPOSE 0
1481 * Demarshals an object path. A path of just "/" is
1482 * represented as an empty vector of strings.
1484 * @param str the string containing the data
1485 * @param byte_order the byte order
1486 * @param pos the position in the string
1487 * @param new_pos the new position of the string
1488 * @param path address to store new object path
1489 * @param path_len length of stored path
1492 _dbus_demarshal_object_path (const DBusString *str,
1505 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1506 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1507 _dbus_assert (data != NULL);
1509 #if VERBOSE_DECOMPOSE
1510 _dbus_verbose ("Decomposing path \"%s\"\n",
1523 retval = dbus_new0 (char*, n_components + 1);
1536 while (j < len && data[j] != '/')
1539 /* Now [i, j) is the path component */
1540 _dbus_assert (i < j);
1541 _dbus_assert (data[i] != '/');
1542 _dbus_assert (j == len || data[j] == '/');
1544 #if VERBOSE_DECOMPOSE
1545 _dbus_verbose (" (component in [%d,%d))\n",
1549 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1550 if (retval[comp] == NULL)
1552 dbus_free_string_array (retval);
1555 retval[comp][j-i] = '\0';
1556 #if VERBOSE_DECOMPOSE
1557 _dbus_verbose (" (component %d = \"%s\")\n",
1558 comp, retval[comp]);
1564 _dbus_assert (i == len);
1568 *path_len = n_components;
1571 *new_pos = pos + len + 1;
1577 * Returns the position right after the end of an argument. PERFORMS
1578 * NO VALIDATION WHATSOEVER. The message must have been previously
1581 * @param str a string
1582 * @param byte_order the byte order to use
1583 * @param type the type of the argument
1584 * @param pos the pos where the arg starts
1585 * @param end_pos pointer where the position right
1586 * after the end position will follow
1587 * @returns TRUE if more data exists after the arg
1590 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1596 if (pos >= _dbus_string_get_length (str))
1601 case DBUS_TYPE_INVALID:
1609 case DBUS_TYPE_BYTE:
1613 case DBUS_TYPE_BOOLEAN:
1617 case DBUS_TYPE_INT32:
1618 case DBUS_TYPE_UINT32:
1619 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1622 case DBUS_TYPE_INT64:
1623 case DBUS_TYPE_UINT64:
1624 case DBUS_TYPE_DOUBLE:
1626 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1629 case DBUS_TYPE_OBJECT_PATH:
1630 case DBUS_TYPE_STRING:
1634 /* Demarshal the length */
1635 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1637 *end_pos = pos + len + 1;
1641 case DBUS_TYPE_NAMED:
1645 /* Demarshal the string length */
1646 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1648 *end_pos = pos + len + 1;
1650 /* Demarshal the data length */
1651 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1653 *end_pos = pos + len;
1657 case DBUS_TYPE_ARRAY:
1661 /* Demarshal the length */
1662 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1664 *end_pos = pos + len;
1668 case DBUS_TYPE_DICT:
1672 /* Demarshal the length */
1673 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1675 *end_pos = pos + len;
1680 _dbus_warn ("Unknown message arg type %d\n", type);
1681 _dbus_assert_not_reached ("Unknown message argument type\n");
1685 if (*end_pos > _dbus_string_get_length (str))
1692 * Demarshals and validates a length; returns < 0 if the validation
1693 * fails. The length is required to be small enough that
1694 * len*sizeof(double) will not overflow, and small enough to fit in a
1695 * signed integer. DOES NOT check whether the length points
1696 * beyond the end of the string, because it doesn't know the
1697 * size of array elements.
1699 * @param str the string
1700 * @param byte_order the byte order
1701 * @param pos the unaligned string position (snap to next aligned)
1702 * @param new_pos return location for new position.
1705 demarshal_and_validate_len (const DBusString *str,
1710 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1713 _dbus_assert (new_pos != NULL);
1715 if ((align_4 + 4) > _dbus_string_get_length (str))
1717 _dbus_verbose ("not enough room in message for array length\n");
1721 if (!_dbus_string_validate_nul (str, pos,
1724 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1728 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1730 /* note that the len is the number of bytes, so we need it to be
1731 * at least SIZE_T_MAX, but make it smaller just to keep things
1732 * sane. We end up using ints for most sizes to avoid unsigned mess
1733 * so limit to maximum 32-bit signed int divided by at least 8, more
1734 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1736 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1737 if (len > MAX_ARRAY_LENGTH)
1739 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1740 len, MAX_ARRAY_LENGTH);
1748 validate_string (const DBusString *str,
1750 int len_without_nul,
1753 *end_pos = pos + len_without_nul + 1;
1755 if (*end_pos > _dbus_string_get_length (str))
1757 _dbus_verbose ("string length outside length of the message\n");
1761 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1763 _dbus_verbose ("string arg not nul-terminated\n");
1767 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1769 _dbus_verbose ("string is not valid UTF-8\n");
1777 * Validates and returns a typecode at a specific position
1780 * @param str a string
1781 * @param type the type of the argument
1782 * @param pos the pos where the typecode starts
1783 * @param end_pos pointer where the position right
1784 * after the end position will follow
1785 * @returns #TRUE if the type is valid.
1788 _dbus_marshal_validate_type (const DBusString *str,
1795 if (pos >= _dbus_string_get_length (str))
1798 data = _dbus_string_get_const_data_len (str, pos, 1);
1800 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1803 if (end_pos != NULL)
1811 /* Faster validator for array data that doesn't call
1812 * validate_arg for each value
1815 validate_array_data (const DBusString *str,
1826 case DBUS_TYPE_INVALID:
1833 case DBUS_TYPE_OBJECT_PATH:
1834 case DBUS_TYPE_STRING:
1835 case DBUS_TYPE_NAMED:
1836 case DBUS_TYPE_ARRAY:
1837 case DBUS_TYPE_DICT:
1838 /* This clean recursion to validate_arg is what we
1839 * are doing logically for all types, but we don't
1840 * really want to call validate_arg for every byte
1841 * in a byte array, so the primitive types are
1846 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1847 type, array_type_pos, pos, &pos))
1852 case DBUS_TYPE_BYTE:
1856 case DBUS_TYPE_BOOLEAN:
1861 c = _dbus_string_get_byte (str, pos);
1863 if (!(c == 0 || c == 1))
1865 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1873 case DBUS_TYPE_INT32:
1874 case DBUS_TYPE_UINT32:
1875 /* Call validate arg one time to check alignment padding
1878 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1879 type, array_type_pos, pos, &pos))
1881 pos = _DBUS_ALIGN_VALUE (end, 4);
1884 case DBUS_TYPE_INT64:
1885 case DBUS_TYPE_UINT64:
1886 case DBUS_TYPE_DOUBLE:
1887 /* Call validate arg one time to check alignment padding
1890 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1891 type, array_type_pos, pos, &pos))
1893 pos = _DBUS_ALIGN_VALUE (end, 8);
1897 _dbus_verbose ("Unknown message arg type %d\n", type);
1907 * Validates an argument of a specific type, checking that it
1908 * is well-formed, for example no ludicrous length fields, strings
1909 * are nul-terminated, etc.
1910 * Returns the end position of the argument in end_pos, and
1911 * returns #TRUE if a valid arg begins at "pos"
1913 * @todo security: need to audit this function.
1915 * @param str a string
1916 * @param byte_order the byte order to use
1917 * @param depth current recursion depth, to prevent excessive recursion
1918 * @param type the type of the argument
1919 * @param array_type_pos the position of the current array type, or
1920 * -1 if not in an array
1921 * @param pos the pos where the arg starts
1922 * @param end_pos pointer where the position right
1923 * after the end position will follow
1924 * @returns #TRUE if the arg is valid.
1927 _dbus_marshal_validate_arg (const DBusString *str,
1935 if (pos > _dbus_string_get_length (str))
1937 _dbus_verbose ("Validation went off the end of the message\n");
1941 #define MAX_VALIDATION_DEPTH 32
1943 if (depth > MAX_VALIDATION_DEPTH)
1945 _dbus_verbose ("Maximum recursion depth reached validating message\n");
1951 case DBUS_TYPE_INVALID:
1959 case DBUS_TYPE_BYTE:
1960 if (1 > _dbus_string_get_length (str) - pos)
1962 _dbus_verbose ("no room for byte value\n");
1969 case DBUS_TYPE_BOOLEAN:
1973 if (1 > _dbus_string_get_length (str) - pos)
1975 _dbus_verbose ("no room for boolean value\n");
1979 c = _dbus_string_get_byte (str, pos);
1981 if (!(c == 0 || c == 1))
1983 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1991 case DBUS_TYPE_INT32:
1992 case DBUS_TYPE_UINT32:
1994 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1996 if (!_dbus_string_validate_nul (str, pos,
1999 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
2003 *end_pos = align_4 + 4;
2007 case DBUS_TYPE_INT64:
2008 case DBUS_TYPE_UINT64:
2009 case DBUS_TYPE_DOUBLE:
2011 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2013 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2015 if (!_dbus_string_validate_nul (str, pos,
2018 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
2022 *end_pos = align_8 + 8;
2026 case DBUS_TYPE_OBJECT_PATH:
2027 case DBUS_TYPE_STRING:
2031 /* Demarshal the length, which does NOT include
2034 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2038 if (!validate_string (str, pos, len, end_pos))
2041 if (type == DBUS_TYPE_OBJECT_PATH)
2043 if (!_dbus_string_validate_path (str, pos, len))
2049 case DBUS_TYPE_NAMED:
2053 /* Demarshal the string length, which does NOT include
2056 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2060 if (!validate_string (str, pos, len, &pos))
2064 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2068 *end_pos = pos + len;
2072 case DBUS_TYPE_ARRAY:
2078 if (array_type_pos == -1)
2080 array_type_pos = pos;
2084 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2086 _dbus_verbose ("invalid array type\n");
2090 /* NIL values take up no space, so you couldn't iterate over an array of them.
2091 * array of nil seems useless anyway; the useful thing might be array of
2092 * (nil OR string) but we have no framework for that.
2094 if (array_type == DBUS_TYPE_NIL)
2096 _dbus_verbose ("array of NIL is not allowed\n");
2100 while (array_type == DBUS_TYPE_ARRAY);
2105 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2107 _dbus_verbose ("invalid array type\n");
2111 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2115 if (len > _dbus_string_get_length (str) - pos)
2117 _dbus_verbose ("array length outside length of the message\n");
2123 if (!validate_array_data (str, byte_order, depth + 1,
2124 array_type, array_type_pos,
2130 /* This should not be able to happen, as long as validate_arg moves forward;
2131 * but the check is here just to be paranoid.
2133 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2140 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2148 case DBUS_TYPE_DICT:
2154 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2158 if (len > _dbus_string_get_length (str) - pos)
2160 _dbus_verbose ("dict length outside length of the message\n");
2169 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2170 DBUS_TYPE_STRING, -1, pos, &pos))
2173 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
2175 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
2179 /* Validate element */
2180 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2181 dict_type, -1, pos, &pos))
2187 _dbus_verbose ("dict contents exceed stated dict length\n");
2196 _dbus_verbose ("Unknown message arg type %d\n", type);
2200 if (*end_pos > _dbus_string_get_length (str))
2208 * If in verbose mode, print a block of binary data.
2210 * @todo right now it prints even if not in verbose mode
2212 * @param data the data
2213 * @param len the length of the data
2216 _dbus_verbose_bytes (const unsigned char *data,
2220 const unsigned char *aligned;
2222 _dbus_assert (len >= 0);
2224 /* Print blanks on first row if appropriate */
2225 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2228 _dbus_assert (aligned <= data);
2230 if (aligned != data)
2232 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
2233 while (aligned != data)
2235 _dbus_verbose (" ");
2240 /* now print the bytes */
2244 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2246 _dbus_verbose ("%4d\t%p: ",
2250 if (data[i] >= 32 &&
2252 _dbus_verbose (" '%c' ", data[i]);
2254 _dbus_verbose ("0x%s%x ",
2255 data[i] <= 0xf ? "0" : "", data[i]);
2259 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2262 _dbus_verbose ("BE: %d LE: %d",
2263 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2264 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2267 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2269 _dbus_verbose (" dbl: %g",
2270 *(double*)&data[i-8]);
2273 _dbus_verbose ("\n");
2277 _dbus_verbose ("\n");
2281 * Dump the given part of the string to verbose log.
2283 * @param str the string
2284 * @param start the start of range to dump
2285 * @param len length of range
2288 _dbus_verbose_bytes_of_string (const DBusString *str,
2295 real_len = _dbus_string_get_length (str);
2297 _dbus_assert (start >= 0);
2299 if (start > real_len)
2301 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
2302 start, len, real_len);
2306 if ((start + len) > real_len)
2308 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
2309 start, len, real_len);
2310 len = real_len - start;
2313 d = _dbus_string_get_const_data_len (str, start, len);
2315 _dbus_verbose_bytes (d, len);
2320 #ifdef DBUS_BUILD_TESTS
2321 #include "dbus-test.h"
2325 _dbus_marshal_test (void)
2330 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2331 #ifdef DBUS_HAVE_INT64
2332 dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
2337 if (!_dbus_string_init (&str))
2338 _dbus_assert_not_reached ("failed to init string");
2340 /* Marshal doubles */
2341 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2342 _dbus_assert_not_reached ("could not marshal double value");
2343 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2344 _dbus_assert_not_reached ("demarshal failed");
2346 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2347 _dbus_assert_not_reached ("could not marshal double value");
2348 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2349 _dbus_assert_not_reached ("demarshal failed");
2351 /* Marshal signed integers */
2352 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2353 _dbus_assert_not_reached ("could not marshal signed integer value");
2354 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2355 _dbus_assert_not_reached ("demarshal failed");
2357 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2358 _dbus_assert_not_reached ("could not marshal signed integer value");
2359 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2360 _dbus_assert_not_reached ("demarshal failed");
2362 /* Marshal unsigned integers */
2363 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2364 _dbus_assert_not_reached ("could not marshal signed integer value");
2365 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2366 _dbus_assert_not_reached ("demarshal failed");
2368 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2369 _dbus_assert_not_reached ("could not marshal signed integer value");
2370 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2371 _dbus_assert_not_reached ("demarshal failed");
2373 #ifdef DBUS_HAVE_INT64
2374 /* Marshal signed integers */
2375 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2376 _dbus_assert_not_reached ("could not marshal signed integer value");
2377 if (!_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2378 _dbus_assert_not_reached ("demarshal failed");
2380 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2381 _dbus_assert_not_reached ("could not marshal signed integer value");
2382 if (!_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2383 _dbus_assert_not_reached ("demarshal failed");
2385 /* Marshal unsigned integers */
2386 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2387 _dbus_assert_not_reached ("could not marshal signed integer value");
2388 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2389 _dbus_assert_not_reached ("demarshal failed");
2391 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2392 _dbus_assert_not_reached ("could not marshal signed integer value");
2393 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2394 _dbus_assert_not_reached ("demarshal failed");
2395 #endif /* DBUS_HAVE_INT64 */
2397 /* Marshal strings */
2398 tmp1 = "This is the dbus test string";
2399 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2400 _dbus_assert_not_reached ("could not marshal string");
2401 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2402 if (!strcmp (tmp1, tmp2) == 0)
2403 _dbus_assert_not_reached ("demarshal failed");
2406 tmp1 = "This is the dbus test string";
2407 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2408 _dbus_assert_not_reached ("could not marshal string");
2409 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2410 if (!strcmp (tmp1, tmp2) == 0)
2411 _dbus_assert_not_reached ("demarshal failed");
2414 /* Marshal signed integer arrays */
2415 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2416 _dbus_assert_not_reached ("could not marshal integer array");
2417 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2418 _dbus_assert_not_reached ("could not demarshal integer array");
2421 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2424 #ifdef DBUS_HAVE_INT64
2425 /* Marshal 64-bit signed integer arrays */
2426 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2427 _dbus_assert_not_reached ("could not marshal integer array");
2428 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2429 _dbus_assert_not_reached ("could not demarshal integer array");
2432 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2435 /* set/pack 64-bit integers */
2436 _dbus_string_set_length (&str, 8);
2439 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2440 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2442 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2443 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2444 _dbus_string_get_const_data (&str)));
2447 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2448 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2450 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2451 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2452 _dbus_string_get_const_data (&str)));
2454 /* signed little pack */
2455 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2457 _dbus_string_get_data (&str));
2459 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2460 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2461 _dbus_string_get_const_data (&str)));
2463 /* signed big pack */
2464 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2466 _dbus_string_get_data (&str));
2468 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2469 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2470 _dbus_string_get_const_data (&str)));
2472 /* unsigned little */
2473 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2474 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2476 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2477 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2478 _dbus_string_get_const_data (&str)));
2481 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2482 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2484 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2485 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2486 _dbus_string_get_const_data (&str)));
2488 /* unsigned little pack */
2489 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2491 _dbus_string_get_data (&str));
2493 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2494 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2495 _dbus_string_get_const_data (&str)));
2497 /* unsigned big pack */
2498 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2500 _dbus_string_get_data (&str));
2502 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2503 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2504 _dbus_string_get_const_data (&str)));
2508 /* set/pack 32-bit integers */
2509 _dbus_string_set_length (&str, 4);
2512 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2515 _dbus_assert (-0x123456 ==
2516 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2517 _dbus_string_get_const_data (&str)));
2520 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2523 _dbus_assert (-0x123456 ==
2524 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2525 _dbus_string_get_const_data (&str)));
2527 /* signed little pack */
2528 _dbus_pack_int32 (-0x123456,
2530 _dbus_string_get_data (&str));
2532 _dbus_assert (-0x123456 ==
2533 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2534 _dbus_string_get_const_data (&str)));
2536 /* signed big pack */
2537 _dbus_pack_int32 (-0x123456,
2539 _dbus_string_get_data (&str));
2541 _dbus_assert (-0x123456 ==
2542 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2543 _dbus_string_get_const_data (&str)));
2545 /* unsigned little */
2546 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2549 _dbus_assert (0x123456 ==
2550 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2551 _dbus_string_get_const_data (&str)));
2554 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2557 _dbus_assert (0x123456 ==
2558 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2559 _dbus_string_get_const_data (&str)));
2561 /* unsigned little pack */
2562 _dbus_pack_uint32 (0x123456,
2564 _dbus_string_get_data (&str));
2566 _dbus_assert (0x123456 ==
2567 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2568 _dbus_string_get_const_data (&str)));
2570 /* unsigned big pack */
2571 _dbus_pack_uint32 (0x123456,
2573 _dbus_string_get_data (&str));
2575 _dbus_assert (0x123456 ==
2576 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2577 _dbus_string_get_const_data (&str)));
2582 _dbus_string_set_length (&str, 0);
2584 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2587 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2588 _dbus_assert (strcmp (s, "Hello world") == 0);
2591 _dbus_string_init_const (&t, "Hello world foo");
2593 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2594 &t, _dbus_string_get_length (&t));
2596 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2597 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2600 _dbus_string_init_const (&t, "Hello");
2602 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2603 &t, _dbus_string_get_length (&t));
2605 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2606 _dbus_assert (strcmp (s, "Hello") == 0);
2609 /* Strings (big endian) */
2611 _dbus_string_set_length (&str, 0);
2613 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
2616 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2617 _dbus_assert (strcmp (s, "Hello world") == 0);
2620 _dbus_string_init_const (&t, "Hello world foo");
2622 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2623 &t, _dbus_string_get_length (&t));
2625 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2626 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2629 _dbus_string_init_const (&t, "Hello");
2631 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2632 &t, _dbus_string_get_length (&t));
2634 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2635 _dbus_assert (strcmp (s, "Hello") == 0);
2638 _dbus_string_free (&str);
2643 #endif /* DBUS_BUILD_TESTS */