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 */
78 #ifdef DBUS_HAVE_INT64
86 unpack_8_octets (int byte_order,
87 const unsigned char *data)
91 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
92 _dbus_assert (sizeof (r) == 8);
94 #ifdef DBUS_HAVE_INT64
95 if (byte_order == DBUS_LITTLE_ENDIAN)
96 r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
98 r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
100 r.d = *(double*)data;
101 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
102 swap_bytes ((unsigned char*) &r, sizeof (r));
109 * Unpacks a 32 bit unsigned integer from a data pointer
111 * @param byte_order The byte order to use
112 * @param data the data pointer
113 * @returns the integer
116 _dbus_unpack_uint32 (int byte_order,
117 const unsigned char *data)
119 return unpack_4_octets (byte_order, data);
123 * Unpacks a 32 bit signed integer from a data pointer
125 * @param byte_order The byte order to use
126 * @param data the data pointer
127 * @returns the integer
130 _dbus_unpack_int32 (int byte_order,
131 const unsigned char *data)
133 return (dbus_int32_t) unpack_4_octets (byte_order, data);
136 #ifdef DBUS_HAVE_INT64
138 * Unpacks a 64 bit unsigned integer from a data pointer
140 * @param byte_order The byte order to use
141 * @param data the data pointer
142 * @returns the integer
145 _dbus_unpack_uint64 (int byte_order,
146 const unsigned char *data)
150 r = unpack_8_octets (byte_order, data);
156 * Unpacks a 64 bit signed integer from a data pointer
158 * @param byte_order The byte order to use
159 * @param data the data pointer
160 * @returns the integer
163 _dbus_unpack_int64 (int byte_order,
164 const unsigned char *data)
168 r = unpack_8_octets (byte_order, data);
173 #endif /* DBUS_HAVE_INT64 */
176 pack_4_octets (dbus_uint32_t value,
180 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
182 if ((byte_order) == DBUS_LITTLE_ENDIAN)
183 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
185 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
189 pack_8_octets (DBusOctets8 value,
193 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
195 #ifdef DBUS_HAVE_INT64
196 if ((byte_order) == DBUS_LITTLE_ENDIAN)
197 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
199 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
201 memcpy (data, &value, 8);
202 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
203 swap_bytes ((unsigned char *)data, 8);
208 * Packs a 32 bit unsigned integer into a data pointer.
210 * @param value the value
211 * @param byte_order the byte order to use
212 * @param data the data pointer
215 _dbus_pack_uint32 (dbus_uint32_t value,
219 pack_4_octets (value, byte_order, data);
223 * Packs a 32 bit signed integer into a data pointer.
225 * @param value the value
226 * @param byte_order the byte order to use
227 * @param data the data pointer
230 _dbus_pack_int32 (dbus_int32_t value,
234 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
237 #ifdef DBUS_HAVE_INT64
239 * Packs a 64 bit unsigned integer into a data pointer.
241 * @param value the value
242 * @param byte_order the byte order to use
243 * @param data the data pointer
246 _dbus_pack_uint64 (dbus_uint64_t value,
252 pack_8_octets (r, byte_order, data);
256 * Packs a 64 bit signed integer into a data pointer.
258 * @param value the value
259 * @param byte_order the byte order to use
260 * @param data the data pointer
263 _dbus_pack_int64 (dbus_int64_t value,
269 pack_8_octets (r, byte_order, data);
271 #endif /* DBUS_HAVE_INT64 */
274 set_4_octets (DBusString *str,
281 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
282 byte_order == DBUS_BIG_ENDIAN);
284 data = _dbus_string_get_data_len (str, offset, 4);
286 _dbus_pack_uint32 (value, byte_order, data);
290 set_8_octets (DBusString *str,
297 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
298 byte_order == DBUS_BIG_ENDIAN);
300 data = _dbus_string_get_data_len (str, offset, 8);
302 pack_8_octets (value, byte_order, data);
306 * Sets the 4 bytes at the given offset to a marshaled signed integer,
307 * replacing anything found there previously.
309 * @param str the string to write the marshalled int to
310 * @param offset the byte offset where int should be written
311 * @param byte_order the byte order to use
312 * @param value the value
316 _dbus_marshal_set_int32 (DBusString *str,
321 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
325 * Sets the 4 bytes at the given offset to a marshaled unsigned
326 * integer, replacing anything found there previously.
328 * @param str the string to write the marshalled int to
329 * @param offset the byte offset where int should be written
330 * @param byte_order the byte order to use
331 * @param value the value
335 _dbus_marshal_set_uint32 (DBusString *str,
340 set_4_octets (str, byte_order, offset, value);
343 #ifdef DBUS_HAVE_INT64
346 * Sets the 8 bytes at the given offset to a marshaled signed integer,
347 * replacing anything found there previously.
349 * @param str the string to write the marshalled int to
350 * @param offset the byte offset where int should be written
351 * @param byte_order the byte order to use
352 * @param value the value
356 _dbus_marshal_set_int64 (DBusString *str,
363 set_8_octets (str, byte_order, offset, r);
367 * Sets the 8 bytes at the given offset to a marshaled unsigned
368 * integer, replacing anything found there previously.
370 * @param str the string to write the marshalled int to
371 * @param offset the byte offset where int should be written
372 * @param byte_order the byte order to use
373 * @param value the value
377 _dbus_marshal_set_uint64 (DBusString *str,
384 set_8_octets (str, byte_order, offset, r);
386 #endif /* DBUS_HAVE_INT64 */
389 * Sets the existing marshaled string at the given offset with
390 * a new marshaled string. The given offset must point to
391 * an existing string or the wrong length will be deleted
392 * and replaced with the new string.
394 * @param str the string to write the marshalled string to
395 * @param offset the byte offset where string should be written
396 * @param byte_order the byte order to use
397 * @param value the value
398 * @param len the length to use
399 * @returns #TRUE on success
403 _dbus_marshal_set_string (DBusString *str,
406 const DBusString *value,
411 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
412 byte_order == DBUS_BIG_ENDIAN);
414 old_len = _dbus_demarshal_uint32 (str, byte_order,
417 if (!_dbus_string_replace_len (value, 0, len,
418 str, offset + 4, old_len))
421 _dbus_marshal_set_uint32 (str, byte_order,
428 * Sets the existing marshaled object path at the given offset to a new
429 * value. The given offset must point to an existing object path or this
430 * function doesn't make sense.
432 * @todo implement this function
434 * @param str the string to write the marshalled path to
435 * @param offset the byte offset where path should be written
436 * @param byte_order the byte order to use
437 * @param path the new path
438 * @param path_len number of elements in the path
441 _dbus_marshal_set_object_path (DBusString *str,
452 marshal_4_octets (DBusString *str,
456 _dbus_assert (sizeof (value) == 4);
458 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
459 value = DBUS_UINT32_SWAP_LE_BE (value);
461 return _dbus_string_append_4_aligned (str,
462 (const unsigned char *)&value);
466 marshal_8_octets (DBusString *str,
470 _dbus_assert (sizeof (value) == 8);
472 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
473 pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
475 return _dbus_string_append_8_aligned (str,
476 (const unsigned char *)&value);
480 * Marshals a double value.
482 * @param str the string to append the marshalled value to
483 * @param byte_order the byte order to use
484 * @param value the value
485 * @returns #TRUE on success
488 _dbus_marshal_double (DBusString *str,
494 return marshal_8_octets (str, byte_order, r);
498 * Marshals a 32 bit signed integer value.
500 * @param str the string to append the marshalled value to
501 * @param byte_order the byte order to use
502 * @param value the value
503 * @returns #TRUE on success
506 _dbus_marshal_int32 (DBusString *str,
510 return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
514 * Marshals a 32 bit unsigned integer value.
516 * @param str the string to append the marshalled value to
517 * @param byte_order the byte order to use
518 * @param value the value
519 * @returns #TRUE on success
522 _dbus_marshal_uint32 (DBusString *str,
526 return marshal_4_octets (str, byte_order, value);
530 #ifdef DBUS_HAVE_INT64
532 * Marshals a 64 bit signed integer value.
534 * @param str the string to append the marshalled value to
535 * @param byte_order the byte order to use
536 * @param value the value
537 * @returns #TRUE on success
540 _dbus_marshal_int64 (DBusString *str,
546 return marshal_8_octets (str, byte_order, r);
550 * Marshals a 64 bit unsigned integer value.
552 * @param str the string to append the marshalled value to
553 * @param byte_order the byte order to use
554 * @param value the value
555 * @returns #TRUE on success
558 _dbus_marshal_uint64 (DBusString *str,
564 return marshal_8_octets (str, byte_order, r);
567 #endif /* DBUS_HAVE_INT64 */
570 * Marshals a UTF-8 string
572 * @todo: If the string append fails we need to restore
573 * the old length. (also for other marshallers)
575 * @param str the string to append the marshalled value to
576 * @param byte_order the byte order to use
577 * @param value the string
578 * @returns #TRUE on success
581 _dbus_marshal_string (DBusString *str,
585 int len, old_string_len;
587 old_string_len = _dbus_string_get_length (str);
589 len = strlen (value);
591 if (!_dbus_marshal_uint32 (str, byte_order, len))
593 /* Restore the previous length */
594 _dbus_string_set_length (str, old_string_len);
599 return _dbus_string_append_len (str, value, len + 1);
603 * Marshals a byte array
605 * @param str the string to append the marshalled value to
606 * @param byte_order the byte order to use
607 * @param value the array
608 * @param len number of elements in the array
609 * @returns #TRUE on success
612 _dbus_marshal_byte_array (DBusString *str,
614 const unsigned char *value,
619 old_string_len = _dbus_string_get_length (str);
621 if (!_dbus_marshal_uint32 (str, byte_order, len))
623 /* Restore the previous length */
624 _dbus_string_set_length (str, old_string_len);
632 return _dbus_string_append_len (str, value, len);
636 marshal_4_octets_array (DBusString *str,
638 const dbus_uint32_t *value,
644 old_string_len = _dbus_string_get_length (str);
646 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
649 array_start = _dbus_string_get_length (str);
651 if (!_dbus_string_append_len (str, (const unsigned char*) value,
655 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
657 const unsigned char *d;
658 const unsigned char *end;
660 d = _dbus_string_get_data (str) + array_start;
664 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
672 /* Restore previous length */
673 _dbus_string_set_length (str, old_string_len);
679 marshal_8_octets_array (DBusString *str,
681 const DBusOctets8 *value,
687 old_string_len = _dbus_string_get_length (str);
689 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
692 array_start = _dbus_string_get_length (str);
694 if (!_dbus_string_append_len (str, (const unsigned char*) value,
698 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
700 const unsigned char *d;
701 const unsigned char *end;
703 d = _dbus_string_get_data (str) + array_start;
707 #ifdef DBUS_HAVE_INT64
708 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
710 swap_bytes ((unsigned char*) d, 8);
719 /* Restore previous length */
720 _dbus_string_set_length (str, old_string_len);
726 * Marshals a 32 bit signed integer array
728 * @param str the string to append the marshalled value to
729 * @param byte_order the byte order to use
730 * @param value the array
731 * @param len the length of the array
732 * @returns #TRUE on success
735 _dbus_marshal_int32_array (DBusString *str,
737 const dbus_int32_t *value,
740 return marshal_4_octets_array (str, byte_order,
741 (const dbus_uint32_t*) value,
746 * Marshals a 32 bit unsigned integer array
748 * @param str the string to append the marshalled value to
749 * @param byte_order the byte order to use
750 * @param value the array
751 * @param len the length of the array
752 * @returns #TRUE on success
755 _dbus_marshal_uint32_array (DBusString *str,
757 const dbus_uint32_t *value,
760 return marshal_4_octets_array (str, byte_order,
765 #ifdef DBUS_HAVE_INT64
768 * Marshals a 64 bit signed integer array
770 * @param str the string to append the marshalled value to
771 * @param byte_order the byte order to use
772 * @param value the array
773 * @param len the length of the array
774 * @returns #TRUE on success
777 _dbus_marshal_int64_array (DBusString *str,
779 const dbus_int64_t *value,
782 return marshal_8_octets_array (str, byte_order,
783 (const DBusOctets8*) value,
788 * Marshals a 64 bit unsigned integer array
790 * @param str the string to append the marshalled value to
791 * @param byte_order the byte order to use
792 * @param value the array
793 * @param len the length of the array
794 * @returns #TRUE on success
797 _dbus_marshal_uint64_array (DBusString *str,
799 const dbus_uint64_t *value,
802 return marshal_8_octets_array (str, byte_order,
803 (const DBusOctets8*) value,
807 #endif /* DBUS_HAVE_INT64 */
810 * Marshals a double array
812 * @param str the string to append the marshalled value to
813 * @param byte_order the byte order to use
814 * @param value the array
815 * @param len the length of the array
816 * @returns #TRUE on success
819 _dbus_marshal_double_array (DBusString *str,
824 return marshal_8_octets_array (str, byte_order,
825 (const DBusOctets8*) value,
830 * Marshals a string array
832 * @param str the string to append the marshalled value to
833 * @param byte_order the byte order to use
834 * @param value the array
835 * @param len the length of the array
836 * @returns #TRUE on success
839 _dbus_marshal_string_array (DBusString *str,
844 int i, old_string_len, array_start;
846 old_string_len = _dbus_string_get_length (str);
848 /* Set the length to 0 temporarily */
849 if (!_dbus_marshal_uint32 (str, byte_order, 0))
852 array_start = _dbus_string_get_length (str);
854 for (i = 0; i < len; i++)
855 if (!_dbus_marshal_string (str, byte_order, value[i]))
858 /* Write the length now that we know it */
859 _dbus_marshal_set_uint32 (str, byte_order,
860 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
861 _dbus_string_get_length (str) - array_start);
866 /* Restore previous length */
867 _dbus_string_set_length (str, old_string_len);
873 * Marshals an object path value.
875 * @param str the string to append the marshalled value to
876 * @param byte_order the byte order to use
877 * @param path the path
878 * @param path_len length of the path
879 * @returns #TRUE on success
882 _dbus_marshal_object_path (DBusString *str,
887 int array_start, old_string_len;
890 old_string_len = _dbus_string_get_length (str);
892 /* Set the length to 0 temporarily */
893 if (!_dbus_marshal_uint32 (str, byte_order, 0))
896 array_start = _dbus_string_get_length (str);
901 if (!_dbus_string_append_byte (str, '/'))
904 if (!_dbus_string_append (str, path[0]))
910 /* Write the length now that we know it */
911 _dbus_marshal_set_uint32 (str, byte_order,
912 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
913 _dbus_string_get_length (str) - array_start);
918 /* Restore the previous length */
919 _dbus_string_set_length (str, old_string_len);
925 demarshal_4_octets (const DBusString *str,
930 const DBusRealString *real = (const DBusRealString*) str;
932 pos = _DBUS_ALIGN_VALUE (pos, 4);
937 return unpack_4_octets (byte_order, real->str + pos);
941 demarshal_8_octets (const DBusString *str,
946 const DBusRealString *real = (const DBusRealString*) str;
948 pos = _DBUS_ALIGN_VALUE (pos, 8);
953 return unpack_8_octets (byte_order, real->str + pos);
957 * Demarshals a double.
959 * @param str the string containing the data
960 * @param byte_order the byte order
961 * @param pos the position in the string
962 * @param new_pos the new position of the string
963 * @returns the demarshaled double.
966 _dbus_demarshal_double (const DBusString *str,
973 r = demarshal_8_octets (str, byte_order, pos, new_pos);
979 * Demarshals a 32 bit signed integer.
981 * @param str the string containing the data
982 * @param byte_order the byte order
983 * @param pos the position in the string
984 * @param new_pos the new position of the string
985 * @returns the demarshaled integer.
988 _dbus_demarshal_int32 (const DBusString *str,
993 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
997 * Demarshals a 32 bit unsigned integer.
999 * @param str the string containing the data
1000 * @param byte_order the byte order
1001 * @param pos the position in the string
1002 * @param new_pos the new position of the string
1003 * @returns the demarshaled integer.
1006 _dbus_demarshal_uint32 (const DBusString *str,
1011 return demarshal_4_octets (str, byte_order, pos, new_pos);
1014 #ifdef DBUS_HAVE_INT64
1017 * Demarshals a 64 bit signed integer.
1019 * @param str the string containing the data
1020 * @param byte_order the byte order
1021 * @param pos the position in the string
1022 * @param new_pos the new position of the string
1023 * @returns the demarshaled integer.
1026 _dbus_demarshal_int64 (const DBusString *str,
1033 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1039 * Demarshals a 64 bit unsigned integer.
1041 * @param str the string containing the data
1042 * @param byte_order the byte order
1043 * @param pos the position in the string
1044 * @param new_pos the new position of the string
1045 * @returns the demarshaled integer.
1048 _dbus_demarshal_uint64 (const DBusString *str,
1055 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1060 #endif /* DBUS_HAVE_INT64 */
1063 * Demarshals an UTF-8 string.
1065 * @todo Should we check the string to make sure
1066 * that it's valid UTF-8, and maybe "fix" the string
1069 * @todo Should probably demarshal to a DBusString,
1070 * having memcpy() in here is Evil(tm).
1072 * @param str the string containing the data
1073 * @param byte_order the byte order
1074 * @param pos the position in the string
1075 * @param new_pos the new position of the string
1076 * @returns the demarshaled string.
1079 _dbus_demarshal_string (const DBusString *str,
1088 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1090 retval = dbus_malloc (len + 1);
1095 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1100 memcpy (retval, data, len + 1);
1103 *new_pos = pos + len + 1;
1109 * Demarshals a byte array.
1111 * @todo Should probably demarshal to a DBusString,
1112 * having memcpy() in here is Evil(tm).
1114 * @param str the string containing the data
1115 * @param byte_order the byte order
1116 * @param pos the position in the string
1117 * @param new_pos the new position of the string
1118 * @param array the array
1119 * @param array_len length of the demarshaled data
1121 * @returns #TRUE on success
1124 _dbus_demarshal_byte_array (const DBusString *str,
1128 unsigned char **array,
1132 unsigned char *retval;
1135 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1148 retval = dbus_malloc (len);
1153 data = _dbus_string_get_const_data_len (str, pos, len);
1161 memcpy (retval, data, len);
1164 *new_pos = pos + len;
1173 demarshal_4_octets_array (const DBusString *str,
1177 dbus_uint32_t **array,
1181 dbus_uint32_t *retval;
1184 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1198 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1202 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1204 for (i = 0; i < len; i++)
1205 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1209 *new_pos = pos + byte_len;
1218 demarshal_8_octets_array (const DBusString *str,
1222 DBusOctets8 **array,
1226 DBusOctets8 *retval;
1229 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1243 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1247 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1249 for (i = 0; i < len; i++)
1251 #ifdef DBUS_HAVE_INT64
1252 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1254 swap_bytes ((unsigned char *) &retval[i], 8);
1260 *new_pos = pos + byte_len;
1269 * Demarshals a 32 bit signed integer array.
1271 * @param str the string containing the data
1272 * @param byte_order the byte order
1273 * @param pos the position in the string
1274 * @param new_pos the new position of the string
1275 * @param array the array
1276 * @param array_len length of the demarshaled data
1277 * @returns #TRUE on success
1280 _dbus_demarshal_int32_array (const DBusString *str,
1284 dbus_int32_t **array,
1287 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1288 (dbus_uint32_t**) array, array_len);
1292 * Demarshals a 32 bit unsigned integer array.
1294 * @param str the string containing the data
1295 * @param byte_order the byte order
1296 * @param pos the position in the string
1297 * @param new_pos the new position of the string
1298 * @param array the array
1299 * @param array_len length of the demarshaled data
1300 * @returns #TRUE on success
1303 _dbus_demarshal_uint32_array (const DBusString *str,
1307 dbus_uint32_t **array,
1310 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1314 #ifdef DBUS_HAVE_INT64
1317 * Demarshals a 64 bit signed integer array.
1319 * @param str the string containing the data
1320 * @param byte_order the byte order
1321 * @param pos the position in the string
1322 * @param new_pos the new position of the string
1323 * @param array the array
1324 * @param array_len length of the demarshaled data
1325 * @returns #TRUE on success
1328 _dbus_demarshal_int64_array (const DBusString *str,
1332 dbus_int64_t **array,
1335 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1336 (DBusOctets8**) array, array_len);
1340 * Demarshals a 64 bit unsigned integer array.
1342 * @param str the string containing the data
1343 * @param byte_order the byte order
1344 * @param pos the position in the string
1345 * @param new_pos the new position of the string
1346 * @param array the array
1347 * @param array_len length of the demarshaled data
1348 * @returns #TRUE on success
1351 _dbus_demarshal_uint64_array (const DBusString *str,
1355 dbus_uint64_t **array,
1358 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1359 (DBusOctets8**) array, array_len);
1362 #endif /* DBUS_HAVE_INT64 */
1365 * Demarshals a double array.
1367 * @param str the string containing the data
1368 * @param byte_order the byte order
1369 * @param pos the position in the string
1370 * @param new_pos the new position of the string
1371 * @param array the array
1372 * @param array_len length of the demarshaled data
1373 * @returns #TRUE on success
1376 _dbus_demarshal_double_array (const DBusString *str,
1383 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1384 (DBusOctets8**) array, array_len);
1388 * Demarshals a string array.
1390 * @param str the string containing the data
1391 * @param byte_order the byte order
1392 * @param pos the position in the string
1393 * @param new_pos the new position of the string
1394 * @param array the array
1395 * @param array_len length of the demarshaled data
1396 * @returns #TRUE on success
1399 _dbus_demarshal_string_array (const DBusString *str,
1411 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1426 end_pos = pos + bytes_len;
1428 retval = dbus_new (char *, allocated);
1433 while (pos < end_pos)
1435 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1437 if (retval[len] == NULL)
1442 if (len >= allocated - 1) /* -1 for NULL termination */
1445 newp = dbus_realloc (retval,
1446 sizeof (char*) * allocated * 2);
1466 for (i = 0; i < len; i++)
1467 dbus_free (retval[i]);
1473 #define VERBOSE_DECOMPOSE 0
1476 * Demarshals an object path. A path of just "/" is
1477 * represented as an empty vector of strings.
1479 * @param str the string containing the data
1480 * @param byte_order the byte order
1481 * @param pos the position in the string
1482 * @param new_pos the new position of the string
1483 * @param path address to store new object path
1484 * @param path_len length of stored path
1487 _dbus_demarshal_object_path (const DBusString *str,
1500 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1501 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1502 _dbus_assert (data != NULL);
1504 #if VERBOSE_DECOMPOSE
1505 _dbus_verbose ("Decomposing path \"%s\"\n",
1518 retval = dbus_new0 (char*, n_components + 1);
1531 while (j < len && data[j] != '/')
1534 /* Now [i, j) is the path component */
1535 _dbus_assert (i < j);
1536 _dbus_assert (data[i] != '/');
1537 _dbus_assert (j == len || data[j] == '/');
1539 #if VERBOSE_DECOMPOSE
1540 _dbus_verbose (" (component in [%d,%d))\n",
1544 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1545 if (retval[comp] == NULL)
1547 dbus_free_string_array (retval);
1550 retval[comp][j-i] = '\0';
1551 #if VERBOSE_DECOMPOSE
1552 _dbus_verbose (" (component %d = \"%s\")\n",
1553 comp, retval[comp]);
1559 _dbus_assert (i == len);
1563 *path_len = n_components;
1566 *new_pos = pos + len + 1;
1572 * Returns the position right after the end of an argument. PERFORMS
1573 * NO VALIDATION WHATSOEVER. The message must have been previously
1576 * @param str a string
1577 * @param byte_order the byte order to use
1578 * @param type the type of the argument
1579 * @param pos the pos where the arg starts
1580 * @param end_pos pointer where the position right
1581 * after the end position will follow
1582 * @returns TRUE if more data exists after the arg
1585 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1591 if (pos >= _dbus_string_get_length (str))
1596 case DBUS_TYPE_INVALID:
1604 case DBUS_TYPE_BYTE:
1608 case DBUS_TYPE_BOOLEAN:
1612 case DBUS_TYPE_INT32:
1613 case DBUS_TYPE_UINT32:
1614 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1617 case DBUS_TYPE_INT64:
1618 case DBUS_TYPE_UINT64:
1619 case DBUS_TYPE_DOUBLE:
1621 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1624 case DBUS_TYPE_OBJECT_PATH:
1625 case DBUS_TYPE_STRING:
1629 /* Demarshal the length */
1630 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1632 *end_pos = pos + len + 1;
1636 case DBUS_TYPE_NAMED:
1640 /* Demarshal the string length */
1641 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1643 *end_pos = pos + len + 1;
1645 /* Demarshal the data length */
1646 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1648 *end_pos = pos + len;
1652 case DBUS_TYPE_ARRAY:
1656 /* Demarshal the length */
1657 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1659 *end_pos = pos + len;
1663 case DBUS_TYPE_DICT:
1667 /* Demarshal the length */
1668 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1670 *end_pos = pos + len;
1675 _dbus_warn ("Unknown message arg type %d\n", type);
1676 _dbus_assert_not_reached ("Unknown message argument type\n");
1680 if (*end_pos > _dbus_string_get_length (str))
1687 * Demarshals and validates a length; returns < 0 if the validation
1688 * fails. The length is required to be small enough that
1689 * len*sizeof(double) will not overflow, and small enough to fit in a
1690 * signed integer. DOES NOT check whether the length points
1691 * beyond the end of the string, because it doesn't know the
1692 * size of array elements.
1694 * @param str the string
1695 * @param byte_order the byte order
1696 * @param pos the unaligned string position (snap to next aligned)
1697 * @param new_pos return location for new position.
1700 demarshal_and_validate_len (const DBusString *str,
1705 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1708 _dbus_assert (new_pos != NULL);
1710 if ((align_4 + 4) > _dbus_string_get_length (str))
1712 _dbus_verbose ("not enough room in message for array length\n");
1716 if (!_dbus_string_validate_nul (str, pos,
1719 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1723 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1725 /* note that the len is the number of bytes, so we need it to be
1726 * at least SIZE_T_MAX, but make it smaller just to keep things
1727 * sane. We end up using ints for most sizes to avoid unsigned mess
1728 * so limit to maximum 32-bit signed int divided by at least 8, more
1729 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1731 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1732 if (len > MAX_ARRAY_LENGTH)
1734 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1735 len, MAX_ARRAY_LENGTH);
1743 validate_string (const DBusString *str,
1745 int len_without_nul,
1748 *end_pos = pos + len_without_nul + 1;
1750 if (*end_pos > _dbus_string_get_length (str))
1752 _dbus_verbose ("string length outside length of the message\n");
1756 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1758 _dbus_verbose ("string arg not nul-terminated\n");
1762 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1764 _dbus_verbose ("string is not valid UTF-8\n");
1772 * Validates and returns a typecode at a specific position
1775 * @param str a string
1776 * @param type the type of the argument
1777 * @param pos the pos where the typecode starts
1778 * @param end_pos pointer where the position right
1779 * after the end position will follow
1780 * @returns #TRUE if the type is valid.
1783 _dbus_marshal_validate_type (const DBusString *str,
1790 if (pos >= _dbus_string_get_length (str))
1793 data = _dbus_string_get_const_data_len (str, pos, 1);
1795 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1798 if (end_pos != NULL)
1806 /* Faster validator for array data that doesn't call
1807 * validate_arg for each value
1810 validate_array_data (const DBusString *str,
1821 case DBUS_TYPE_INVALID:
1828 case DBUS_TYPE_OBJECT_PATH:
1829 case DBUS_TYPE_STRING:
1830 case DBUS_TYPE_NAMED:
1831 case DBUS_TYPE_ARRAY:
1832 case DBUS_TYPE_DICT:
1833 /* This clean recursion to validate_arg is what we
1834 * are doing logically for all types, but we don't
1835 * really want to call validate_arg for every byte
1836 * in a byte array, so the primitive types are
1841 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1842 type, array_type_pos, pos, &pos))
1847 case DBUS_TYPE_BYTE:
1851 case DBUS_TYPE_BOOLEAN:
1856 c = _dbus_string_get_byte (str, pos);
1858 if (!(c == 0 || c == 1))
1860 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1868 case DBUS_TYPE_INT32:
1869 case DBUS_TYPE_UINT32:
1870 /* Call validate arg one time to check alignment padding
1873 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1874 type, array_type_pos, pos, &pos))
1876 pos = _DBUS_ALIGN_VALUE (end, 4);
1879 case DBUS_TYPE_INT64:
1880 case DBUS_TYPE_UINT64:
1881 case DBUS_TYPE_DOUBLE:
1882 /* Call validate arg one time to check alignment padding
1885 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1886 type, array_type_pos, pos, &pos))
1888 pos = _DBUS_ALIGN_VALUE (end, 8);
1892 _dbus_verbose ("Unknown message arg type %d\n", type);
1902 * Validates an argument of a specific type, checking that it
1903 * is well-formed, for example no ludicrous length fields, strings
1904 * are nul-terminated, etc.
1905 * Returns the end position of the argument in end_pos, and
1906 * returns #TRUE if a valid arg begins at "pos"
1908 * @todo security: need to audit this function.
1910 * @param str a string
1911 * @param byte_order the byte order to use
1912 * @param depth current recursion depth, to prevent excessive recursion
1913 * @param type the type of the argument
1914 * @param array_type_pos the position of the current array type, or
1915 * -1 if not in an array
1916 * @param pos the pos where the arg starts
1917 * @param end_pos pointer where the position right
1918 * after the end position will follow
1919 * @returns #TRUE if the arg is valid.
1922 _dbus_marshal_validate_arg (const DBusString *str,
1930 if (pos > _dbus_string_get_length (str))
1932 _dbus_verbose ("Validation went off the end of the message\n");
1936 #define MAX_VALIDATION_DEPTH 32
1938 if (depth > MAX_VALIDATION_DEPTH)
1940 _dbus_verbose ("Maximum recursion depth reached validating message\n");
1946 case DBUS_TYPE_INVALID:
1954 case DBUS_TYPE_BYTE:
1955 if (1 > _dbus_string_get_length (str) - pos)
1957 _dbus_verbose ("no room for byte value\n");
1964 case DBUS_TYPE_BOOLEAN:
1968 if (1 > _dbus_string_get_length (str) - pos)
1970 _dbus_verbose ("no room for boolean value\n");
1974 c = _dbus_string_get_byte (str, pos);
1976 if (!(c == 0 || c == 1))
1978 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1986 case DBUS_TYPE_INT32:
1987 case DBUS_TYPE_UINT32:
1989 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1991 if (!_dbus_string_validate_nul (str, pos,
1994 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1998 *end_pos = align_4 + 4;
2002 case DBUS_TYPE_INT64:
2003 case DBUS_TYPE_UINT64:
2004 case DBUS_TYPE_DOUBLE:
2006 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2008 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2010 if (!_dbus_string_validate_nul (str, pos,
2013 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
2017 *end_pos = align_8 + 8;
2021 case DBUS_TYPE_OBJECT_PATH:
2022 case DBUS_TYPE_STRING:
2026 /* Demarshal the length, which does NOT include
2029 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2033 if (!validate_string (str, pos, len, end_pos))
2036 if (type == DBUS_TYPE_OBJECT_PATH)
2038 if (!_dbus_string_validate_path (str, pos, len))
2044 case DBUS_TYPE_NAMED:
2048 /* Demarshal the string length, which does NOT include
2051 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2055 if (!validate_string (str, pos, len, &pos))
2059 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2063 *end_pos = pos + len;
2067 case DBUS_TYPE_ARRAY:
2073 if (array_type_pos == -1)
2075 array_type_pos = pos;
2079 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2081 _dbus_verbose ("invalid array type\n");
2085 /* NIL values take up no space, so you couldn't iterate over an array of them.
2086 * array of nil seems useless anyway; the useful thing might be array of
2087 * (nil OR string) but we have no framework for that.
2089 if (array_type == DBUS_TYPE_NIL)
2091 _dbus_verbose ("array of NIL is not allowed\n");
2095 while (array_type == DBUS_TYPE_ARRAY);
2100 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2102 _dbus_verbose ("invalid array type\n");
2106 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2110 if (len > _dbus_string_get_length (str) - pos)
2112 _dbus_verbose ("array length outside length of the message\n");
2118 if (!validate_array_data (str, byte_order, depth + 1,
2119 array_type, array_type_pos,
2125 /* This should not be able to happen, as long as validate_arg moves forward;
2126 * but the check is here just to be paranoid.
2128 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2135 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2143 case DBUS_TYPE_DICT:
2149 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2153 if (len > _dbus_string_get_length (str) - pos)
2155 _dbus_verbose ("dict length outside length of the message\n");
2164 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2165 DBUS_TYPE_STRING, -1, pos, &pos))
2168 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
2170 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
2174 /* Validate element */
2175 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2176 dict_type, -1, pos, &pos))
2182 _dbus_verbose ("dict contents exceed stated dict length\n");
2191 _dbus_verbose ("Unknown message arg type %d\n", type);
2195 if (*end_pos > _dbus_string_get_length (str))
2203 * If in verbose mode, print a block of binary data.
2205 * @todo right now it prints even if not in verbose mode
2207 * @param data the data
2208 * @param len the length of the data
2211 _dbus_verbose_bytes (const unsigned char *data,
2215 const unsigned char *aligned;
2217 _dbus_assert (len >= 0);
2219 /* Print blanks on first row if appropriate */
2220 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2223 _dbus_assert (aligned <= data);
2225 if (aligned != data)
2227 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
2228 while (aligned != data)
2230 _dbus_verbose (" ");
2235 /* now print the bytes */
2239 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2241 _dbus_verbose ("%4d\t%p: ",
2245 if (data[i] >= 32 &&
2247 _dbus_verbose (" '%c' ", data[i]);
2249 _dbus_verbose ("0x%s%x ",
2250 data[i] <= 0xf ? "0" : "", data[i]);
2254 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2257 _dbus_verbose ("BE: %d LE: %d",
2258 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2259 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2262 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2264 _dbus_verbose (" dbl: %g",
2265 *(double*)&data[i-8]);
2268 _dbus_verbose ("\n");
2272 _dbus_verbose ("\n");
2276 * Dump the given part of the string to verbose log.
2278 * @param str the string
2279 * @param start the start of range to dump
2280 * @param len length of range
2283 _dbus_verbose_bytes_of_string (const DBusString *str,
2290 real_len = _dbus_string_get_length (str);
2292 _dbus_assert (start >= 0);
2294 if (start > real_len)
2296 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
2297 start, len, real_len);
2301 if ((start + len) > real_len)
2303 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
2304 start, len, real_len);
2305 len = real_len - start;
2308 d = _dbus_string_get_const_data_len (str, start, len);
2310 _dbus_verbose_bytes (d, len);
2315 #ifdef DBUS_BUILD_TESTS
2316 #include "dbus-test.h"
2320 _dbus_marshal_test (void)
2325 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2326 #ifdef DBUS_HAVE_INT64
2327 dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
2332 if (!_dbus_string_init (&str))
2333 _dbus_assert_not_reached ("failed to init string");
2335 /* Marshal doubles */
2336 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2337 _dbus_assert_not_reached ("could not marshal double value");
2338 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2339 _dbus_assert_not_reached ("demarshal failed");
2341 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2342 _dbus_assert_not_reached ("could not marshal double value");
2343 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2344 _dbus_assert_not_reached ("demarshal failed");
2346 /* Marshal signed integers */
2347 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2348 _dbus_assert_not_reached ("could not marshal signed integer value");
2349 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2350 _dbus_assert_not_reached ("demarshal failed");
2352 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2353 _dbus_assert_not_reached ("could not marshal signed integer value");
2354 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2355 _dbus_assert_not_reached ("demarshal failed");
2357 /* Marshal unsigned integers */
2358 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2359 _dbus_assert_not_reached ("could not marshal signed integer value");
2360 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2361 _dbus_assert_not_reached ("demarshal failed");
2363 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2364 _dbus_assert_not_reached ("could not marshal signed integer value");
2365 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2366 _dbus_assert_not_reached ("demarshal failed");
2368 #ifdef DBUS_HAVE_INT64
2369 /* Marshal signed integers */
2370 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2371 _dbus_assert_not_reached ("could not marshal signed integer value");
2372 if (!_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2373 _dbus_assert_not_reached ("demarshal failed");
2375 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2376 _dbus_assert_not_reached ("could not marshal signed integer value");
2377 if (!_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2378 _dbus_assert_not_reached ("demarshal failed");
2380 /* Marshal unsigned integers */
2381 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2382 _dbus_assert_not_reached ("could not marshal signed integer value");
2383 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2384 _dbus_assert_not_reached ("demarshal failed");
2386 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2387 _dbus_assert_not_reached ("could not marshal signed integer value");
2388 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2389 _dbus_assert_not_reached ("demarshal failed");
2390 #endif /* DBUS_HAVE_INT64 */
2392 /* Marshal strings */
2393 tmp1 = "This is the dbus test string";
2394 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2395 _dbus_assert_not_reached ("could not marshal string");
2396 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2397 if (!strcmp (tmp1, tmp2) == 0)
2398 _dbus_assert_not_reached ("demarshal failed");
2401 tmp1 = "This is the dbus test string";
2402 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2403 _dbus_assert_not_reached ("could not marshal string");
2404 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2405 if (!strcmp (tmp1, tmp2) == 0)
2406 _dbus_assert_not_reached ("demarshal failed");
2409 /* Marshal signed integer arrays */
2410 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2411 _dbus_assert_not_reached ("could not marshal integer array");
2412 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2413 _dbus_assert_not_reached ("could not demarshal integer array");
2416 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2419 #ifdef DBUS_HAVE_INT64
2420 /* Marshal 64-bit signed integer arrays */
2421 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2422 _dbus_assert_not_reached ("could not marshal integer array");
2423 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2424 _dbus_assert_not_reached ("could not demarshal integer array");
2427 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2430 /* set/pack 64-bit integers */
2431 _dbus_string_set_length (&str, 8);
2434 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2435 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2437 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2438 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2439 _dbus_string_get_const_data (&str)));
2442 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2443 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2445 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2446 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2447 _dbus_string_get_const_data (&str)));
2449 /* signed little pack */
2450 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2452 _dbus_string_get_data (&str));
2454 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2455 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2456 _dbus_string_get_const_data (&str)));
2458 /* signed big pack */
2459 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2461 _dbus_string_get_data (&str));
2463 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2464 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2465 _dbus_string_get_const_data (&str)));
2467 /* unsigned little */
2468 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2469 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2471 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2472 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2473 _dbus_string_get_const_data (&str)));
2476 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2477 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2479 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2480 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2481 _dbus_string_get_const_data (&str)));
2483 /* unsigned little pack */
2484 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2486 _dbus_string_get_data (&str));
2488 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2489 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2490 _dbus_string_get_const_data (&str)));
2492 /* unsigned big pack */
2493 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2495 _dbus_string_get_data (&str));
2497 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2498 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2499 _dbus_string_get_const_data (&str)));
2503 /* set/pack 32-bit integers */
2504 _dbus_string_set_length (&str, 4);
2507 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2510 _dbus_assert (-0x123456 ==
2511 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2512 _dbus_string_get_const_data (&str)));
2515 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2518 _dbus_assert (-0x123456 ==
2519 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2520 _dbus_string_get_const_data (&str)));
2522 /* signed little pack */
2523 _dbus_pack_int32 (-0x123456,
2525 _dbus_string_get_data (&str));
2527 _dbus_assert (-0x123456 ==
2528 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2529 _dbus_string_get_const_data (&str)));
2531 /* signed big pack */
2532 _dbus_pack_int32 (-0x123456,
2534 _dbus_string_get_data (&str));
2536 _dbus_assert (-0x123456 ==
2537 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2538 _dbus_string_get_const_data (&str)));
2540 /* unsigned little */
2541 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2544 _dbus_assert (0x123456 ==
2545 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2546 _dbus_string_get_const_data (&str)));
2549 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2552 _dbus_assert (0x123456 ==
2553 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2554 _dbus_string_get_const_data (&str)));
2556 /* unsigned little pack */
2557 _dbus_pack_uint32 (0x123456,
2559 _dbus_string_get_data (&str));
2561 _dbus_assert (0x123456 ==
2562 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2563 _dbus_string_get_const_data (&str)));
2565 /* unsigned big pack */
2566 _dbus_pack_uint32 (0x123456,
2568 _dbus_string_get_data (&str));
2570 _dbus_assert (0x123456 ==
2571 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2572 _dbus_string_get_const_data (&str)));
2577 _dbus_string_set_length (&str, 0);
2579 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2582 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2583 _dbus_assert (strcmp (s, "Hello world") == 0);
2586 _dbus_string_init_const (&t, "Hello world foo");
2588 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2589 &t, _dbus_string_get_length (&t));
2591 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2592 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2595 _dbus_string_init_const (&t, "Hello");
2597 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2598 &t, _dbus_string_get_length (&t));
2600 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2601 _dbus_assert (strcmp (s, "Hello") == 0);
2604 /* Strings (big endian) */
2606 _dbus_string_set_length (&str, 0);
2608 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
2611 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2612 _dbus_assert (strcmp (s, "Hello world") == 0);
2615 _dbus_string_init_const (&t, "Hello world foo");
2617 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2618 &t, _dbus_string_get_length (&t));
2620 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2621 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2624 _dbus_string_init_const (&t, "Hello");
2626 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2627 &t, _dbus_string_get_length (&t));
2629 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2630 _dbus_assert (strcmp (s, "Hello") == 0);
2633 _dbus_string_free (&str);
2638 #endif /* DBUS_BUILD_TESTS */