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 swap_bytes (&r, sizeof (r));
108 * Unpacks a 32 bit unsigned integer from a data pointer
110 * @param byte_order The byte order to use
111 * @param data the data pointer
112 * @returns the integer
115 _dbus_unpack_uint32 (int byte_order,
116 const unsigned char *data)
118 return unpack_4_octets (byte_order, data);
122 * Unpacks a 32 bit signed integer from a data pointer
124 * @param byte_order The byte order to use
125 * @param data the data pointer
126 * @returns the integer
129 _dbus_unpack_int32 (int byte_order,
130 const unsigned char *data)
132 return (dbus_int32_t) unpack_4_octets (byte_order, data);
135 #ifdef DBUS_HAVE_INT64
137 * Unpacks a 64 bit unsigned integer from a data pointer
139 * @param byte_order The byte order to use
140 * @param data the data pointer
141 * @returns the integer
144 _dbus_unpack_uint64 (int byte_order,
145 const unsigned char *data)
149 r = unpack_8_octets (byte_order, data);
155 * Unpacks a 64 bit signed integer from a data pointer
157 * @param byte_order The byte order to use
158 * @param data the data pointer
159 * @returns the integer
162 _dbus_unpack_int64 (int byte_order,
163 const unsigned char *data)
167 r = unpack_8_octets (byte_order, data);
172 #endif /* DBUS_HAVE_INT64 */
175 pack_4_octets (dbus_uint32_t value,
179 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
181 if ((byte_order) == DBUS_LITTLE_ENDIAN)
182 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
184 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
188 pack_8_octets (DBusOctets8 value,
192 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
194 #ifdef DBUS_HAVE_INT64
195 if ((byte_order) == DBUS_LITTLE_ENDIAN)
196 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
198 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
200 memcpy (data, &value, 8);
201 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
202 swap_bytes ((unsigned char *)data, 8);
207 * Packs a 32 bit unsigned integer into a data pointer.
209 * @param value the value
210 * @param byte_order the byte order to use
211 * @param data the data pointer
214 _dbus_pack_uint32 (dbus_uint32_t value,
218 pack_4_octets (value, byte_order, data);
222 * Packs a 32 bit signed integer into a data pointer.
224 * @param value the value
225 * @param byte_order the byte order to use
226 * @param data the data pointer
229 _dbus_pack_int32 (dbus_int32_t value,
233 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
236 #ifdef DBUS_HAVE_INT64
238 * Packs a 64 bit unsigned integer into a data pointer.
240 * @param value the value
241 * @param byte_order the byte order to use
242 * @param data the data pointer
245 _dbus_pack_uint64 (dbus_uint64_t value,
251 pack_8_octets (r, byte_order, data);
255 * Packs a 64 bit signed integer into a data pointer.
257 * @param value the value
258 * @param byte_order the byte order to use
259 * @param data the data pointer
262 _dbus_pack_int64 (dbus_int64_t value,
268 pack_8_octets (r, byte_order, data);
270 #endif /* DBUS_HAVE_INT64 */
273 set_4_octets (DBusString *str,
280 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
281 byte_order == DBUS_BIG_ENDIAN);
283 data = _dbus_string_get_data_len (str, offset, 4);
285 _dbus_pack_uint32 (value, byte_order, data);
289 set_8_octets (DBusString *str,
296 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
297 byte_order == DBUS_BIG_ENDIAN);
299 data = _dbus_string_get_data_len (str, offset, 8);
301 pack_8_octets (value, byte_order, data);
305 * Sets the 4 bytes at the given offset to a marshaled signed integer,
306 * replacing anything found there previously.
308 * @param str the string to write the marshalled int to
309 * @param offset the byte offset where int should be written
310 * @param byte_order the byte order to use
311 * @param value the value
315 _dbus_marshal_set_int32 (DBusString *str,
320 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
324 * Sets the 4 bytes at the given offset to a marshaled unsigned
325 * integer, replacing anything found there previously.
327 * @param str the string to write the marshalled int to
328 * @param offset the byte offset where int should be written
329 * @param byte_order the byte order to use
330 * @param value the value
334 _dbus_marshal_set_uint32 (DBusString *str,
339 set_4_octets (str, byte_order, offset, value);
342 #ifdef DBUS_HAVE_INT64
345 * Sets the 8 bytes at the given offset to a marshaled signed integer,
346 * replacing anything found there previously.
348 * @param str the string to write the marshalled int to
349 * @param offset the byte offset where int should be written
350 * @param byte_order the byte order to use
351 * @param value the value
355 _dbus_marshal_set_int64 (DBusString *str,
362 set_8_octets (str, byte_order, offset, r);
366 * Sets the 8 bytes at the given offset to a marshaled unsigned
367 * integer, replacing anything found there previously.
369 * @param str the string to write the marshalled int to
370 * @param offset the byte offset where int should be written
371 * @param byte_order the byte order to use
372 * @param value the value
376 _dbus_marshal_set_uint64 (DBusString *str,
383 set_8_octets (str, byte_order, offset, r);
385 #endif /* DBUS_HAVE_INT64 */
388 * Sets the existing marshaled string at the given offset with
389 * a new marshaled string. The given offset must point to
390 * an existing string or the wrong length will be deleted
391 * and replaced with the new string.
393 * @param str the string to write the marshalled string to
394 * @param offset the byte offset where string should be written
395 * @param byte_order the byte order to use
396 * @param value the value
397 * @param len the length to use
398 * @returns #TRUE on success
402 _dbus_marshal_set_string (DBusString *str,
405 const DBusString *value,
410 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
411 byte_order == DBUS_BIG_ENDIAN);
413 old_len = _dbus_demarshal_uint32 (str, byte_order,
416 if (!_dbus_string_replace_len (value, 0, len,
417 str, offset + 4, old_len))
420 _dbus_marshal_set_uint32 (str, byte_order,
427 marshal_4_octets (DBusString *str,
431 _dbus_assert (sizeof (value) == 4);
433 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
434 value = DBUS_UINT32_SWAP_LE_BE (value);
436 return _dbus_string_append_4_aligned (str,
437 (const unsigned char *)&value);
441 marshal_8_octets (DBusString *str,
445 _dbus_assert (sizeof (value) == 8);
447 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
448 pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
450 return _dbus_string_append_8_aligned (str,
451 (const unsigned char *)&value);
455 * Marshals a double value.
457 * @param str the string to append the marshalled value to
458 * @param byte_order the byte order to use
459 * @param value the value
460 * @returns #TRUE on success
463 _dbus_marshal_double (DBusString *str,
469 return marshal_8_octets (str, byte_order, r);
473 * Marshals a 32 bit signed integer value.
475 * @param str the string to append the marshalled value to
476 * @param byte_order the byte order to use
477 * @param value the value
478 * @returns #TRUE on success
481 _dbus_marshal_int32 (DBusString *str,
485 return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
489 * Marshals a 32 bit unsigned integer value.
491 * @param str the string to append the marshalled value to
492 * @param byte_order the byte order to use
493 * @param value the value
494 * @returns #TRUE on success
497 _dbus_marshal_uint32 (DBusString *str,
501 return marshal_4_octets (str, byte_order, value);
505 #ifdef DBUS_HAVE_INT64
507 * Marshals a 64 bit signed integer value.
509 * @param str the string to append the marshalled value to
510 * @param byte_order the byte order to use
511 * @param value the value
512 * @returns #TRUE on success
515 _dbus_marshal_int64 (DBusString *str,
521 return marshal_8_octets (str, byte_order, r);
525 * Marshals a 64 bit unsigned integer value.
527 * @param str the string to append the marshalled value to
528 * @param byte_order the byte order to use
529 * @param value the value
530 * @returns #TRUE on success
533 _dbus_marshal_uint64 (DBusString *str,
539 return marshal_8_octets (str, byte_order, r);
542 #endif /* DBUS_HAVE_INT64 */
545 * Marshals a UTF-8 string
547 * @todo: If the string append fails we need to restore
548 * the old length. (also for other marshallers)
550 * @param str the string to append the marshalled value to
551 * @param byte_order the byte order to use
552 * @param value the string
553 * @returns #TRUE on success
556 _dbus_marshal_string (DBusString *str,
560 int len, old_string_len;
562 old_string_len = _dbus_string_get_length (str);
564 len = strlen (value);
566 if (!_dbus_marshal_uint32 (str, byte_order, len))
568 /* Restore the previous length */
569 _dbus_string_set_length (str, old_string_len);
574 return _dbus_string_append_len (str, value, len + 1);
578 * Marshals a byte array
580 * @param str the string to append the marshalled value to
581 * @param byte_order the byte order to use
582 * @param value the array
583 * @param len number of elements in the array
584 * @returns #TRUE on success
587 _dbus_marshal_byte_array (DBusString *str,
589 const unsigned char *value,
594 old_string_len = _dbus_string_get_length (str);
596 if (!_dbus_marshal_uint32 (str, byte_order, len))
598 /* Restore the previous length */
599 _dbus_string_set_length (str, old_string_len);
607 return _dbus_string_append_len (str, value, len);
611 marshal_4_octets_array (DBusString *str,
613 const dbus_uint32_t *value,
619 old_string_len = _dbus_string_get_length (str);
621 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
624 array_start = _dbus_string_get_length (str);
626 if (!_dbus_string_append_len (str, (const unsigned char*) value,
630 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
632 const unsigned char *d;
633 const unsigned char *end;
635 d = _dbus_string_get_data (str) + array_start;
639 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
647 /* Restore previous length */
648 _dbus_string_set_length (str, old_string_len);
654 marshal_8_octets_array (DBusString *str,
656 const DBusOctets8 *value,
662 old_string_len = _dbus_string_get_length (str);
664 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
667 array_start = _dbus_string_get_length (str);
669 if (!_dbus_string_append_len (str, (const unsigned char*) value,
673 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
675 const unsigned char *d;
676 const unsigned char *end;
678 d = _dbus_string_get_data (str) + array_start;
682 #ifdef DBUS_HAVE_INT64
683 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
694 /* Restore previous length */
695 _dbus_string_set_length (str, old_string_len);
701 * Marshals a 32 bit signed integer array
703 * @param str the string to append the marshalled value to
704 * @param byte_order the byte order to use
705 * @param value the array
706 * @param len the length of the array
707 * @returns #TRUE on success
710 _dbus_marshal_int32_array (DBusString *str,
712 const dbus_int32_t *value,
715 return marshal_4_octets_array (str, byte_order,
716 (const dbus_uint32_t*) value,
721 * Marshals a 32 bit unsigned integer array
723 * @param str the string to append the marshalled value to
724 * @param byte_order the byte order to use
725 * @param value the array
726 * @param len the length of the array
727 * @returns #TRUE on success
730 _dbus_marshal_uint32_array (DBusString *str,
732 const dbus_uint32_t *value,
735 return marshal_4_octets_array (str, byte_order,
740 #ifdef DBUS_HAVE_INT64
743 * Marshals a 64 bit signed integer array
745 * @param str the string to append the marshalled value to
746 * @param byte_order the byte order to use
747 * @param value the array
748 * @param len the length of the array
749 * @returns #TRUE on success
752 _dbus_marshal_int64_array (DBusString *str,
754 const dbus_int64_t *value,
757 return marshal_8_octets_array (str, byte_order,
758 (const DBusOctets8*) value,
763 * Marshals a 64 bit unsigned integer array
765 * @param str the string to append the marshalled value to
766 * @param byte_order the byte order to use
767 * @param value the array
768 * @param len the length of the array
769 * @returns #TRUE on success
772 _dbus_marshal_uint64_array (DBusString *str,
774 const dbus_uint64_t *value,
777 return marshal_8_octets_array (str, byte_order,
778 (const DBusOctets8*) value,
782 #endif /* DBUS_HAVE_INT64 */
785 * Marshals a double array
787 * @param str the string to append the marshalled value to
788 * @param byte_order the byte order to use
789 * @param value the array
790 * @param len the length of the array
791 * @returns #TRUE on success
794 _dbus_marshal_double_array (DBusString *str,
799 return marshal_8_octets_array (str, byte_order,
800 (const DBusOctets8*) value,
805 * Marshals a string array
807 * @param str the string to append the marshalled value to
808 * @param byte_order the byte order to use
809 * @param value the array
810 * @param len the length of the array
811 * @returns #TRUE on success
814 _dbus_marshal_string_array (DBusString *str,
819 int i, old_string_len, array_start;
821 old_string_len = _dbus_string_get_length (str);
823 /* Set the length to 0 temporarily */
824 if (!_dbus_marshal_uint32 (str, byte_order, 0))
827 array_start = _dbus_string_get_length (str);
829 for (i = 0; i < len; i++)
830 if (!_dbus_marshal_string (str, byte_order, value[i]))
833 /* Write the length now that we know it */
834 _dbus_marshal_set_uint32 (str, byte_order,
835 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
836 _dbus_string_get_length (str) - array_start);
841 /* Restore previous length */
842 _dbus_string_set_length (str, old_string_len);
848 demarshal_4_octets (const DBusString *str,
853 const DBusRealString *real = (const DBusRealString*) str;
855 pos = _DBUS_ALIGN_VALUE (pos, 4);
860 return unpack_4_octets (byte_order, real->str + pos);
864 demarshal_8_octets (const DBusString *str,
869 const DBusRealString *real = (const DBusRealString*) str;
871 pos = _DBUS_ALIGN_VALUE (pos, 8);
876 return unpack_8_octets (byte_order, real->str + pos);
880 * Demarshals a double.
882 * @param str the string containing the data
883 * @param byte_order the byte order
884 * @param pos the position in the string
885 * @param new_pos the new position of the string
886 * @returns the demarshaled double.
889 _dbus_demarshal_double (const DBusString *str,
896 r = demarshal_8_octets (str, byte_order, pos, new_pos);
902 * Demarshals a 32 bit signed integer.
904 * @param str the string containing the data
905 * @param byte_order the byte order
906 * @param pos the position in the string
907 * @param new_pos the new position of the string
908 * @returns the demarshaled integer.
911 _dbus_demarshal_int32 (const DBusString *str,
916 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
920 * Demarshals a 32 bit unsigned integer.
922 * @param str the string containing the data
923 * @param byte_order the byte order
924 * @param pos the position in the string
925 * @param new_pos the new position of the string
926 * @returns the demarshaled integer.
929 _dbus_demarshal_uint32 (const DBusString *str,
934 return demarshal_4_octets (str, byte_order, pos, new_pos);
937 #ifdef DBUS_HAVE_INT64
940 * Demarshals a 64 bit signed integer.
942 * @param str the string containing the data
943 * @param byte_order the byte order
944 * @param pos the position in the string
945 * @param new_pos the new position of the string
946 * @returns the demarshaled integer.
949 _dbus_demarshal_int64 (const DBusString *str,
956 r = demarshal_8_octets (str, byte_order, pos, new_pos);
962 * Demarshals a 64 bit unsigned integer.
964 * @param str the string containing the data
965 * @param byte_order the byte order
966 * @param pos the position in the string
967 * @param new_pos the new position of the string
968 * @returns the demarshaled integer.
971 _dbus_demarshal_uint64 (const DBusString *str,
978 r = demarshal_8_octets (str, byte_order, pos, new_pos);
983 #endif /* DBUS_HAVE_INT64 */
986 * Demarshals an UTF-8 string.
988 * @todo Should we check the string to make sure
989 * that it's valid UTF-8, and maybe "fix" the string
992 * @todo Should probably demarshal to a DBusString,
993 * having memcpy() in here is Evil(tm).
995 * @param str the string containing the data
996 * @param byte_order the byte order
997 * @param pos the position in the string
998 * @param new_pos the new position of the string
999 * @returns the demarshaled string.
1002 _dbus_demarshal_string (const DBusString *str,
1011 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1013 retval = dbus_malloc (len + 1);
1018 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1023 memcpy (retval, data, len + 1);
1026 *new_pos = pos + len + 1;
1032 * Demarshals a byte array.
1034 * @todo Should probably demarshal to a DBusString,
1035 * having memcpy() in here is Evil(tm).
1037 * @param str the string containing the data
1038 * @param byte_order the byte order
1039 * @param pos the position in the string
1040 * @param new_pos the new position of the string
1041 * @param array the array
1042 * @param array_len length of the demarshaled data
1044 * @returns #TRUE on success
1047 _dbus_demarshal_byte_array (const DBusString *str,
1051 unsigned char **array,
1055 unsigned char *retval;
1058 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1071 retval = dbus_malloc (len);
1076 data = _dbus_string_get_const_data_len (str, pos, len);
1084 memcpy (retval, data, len);
1087 *new_pos = pos + len;
1096 demarshal_4_octets_array (const DBusString *str,
1100 dbus_uint32_t **array,
1104 dbus_uint32_t *retval;
1107 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1121 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1125 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1127 for (i = 0; i < len; i++)
1128 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1132 *new_pos = pos + byte_len;
1141 demarshal_8_octets_array (const DBusString *str,
1145 DBusOctets8 **array,
1149 DBusOctets8 *retval;
1152 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1166 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1170 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1172 for (i = 0; i < len; i++)
1174 #ifdef DBUS_HAVE_INT64
1175 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1177 swap_bytes (&retval[i], 8);
1183 *new_pos = pos + byte_len;
1192 * Demarshals a 32 bit signed integer array.
1194 * @param str the string containing the data
1195 * @param byte_order the byte order
1196 * @param pos the position in the string
1197 * @param new_pos the new position of the string
1198 * @param array the array
1199 * @param array_len length of the demarshaled data
1200 * @returns #TRUE on success
1203 _dbus_demarshal_int32_array (const DBusString *str,
1207 dbus_int32_t **array,
1210 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1211 (dbus_uint32_t**) array, array_len);
1215 * Demarshals a 32 bit unsigned integer array.
1217 * @param str the string containing the data
1218 * @param byte_order the byte order
1219 * @param pos the position in the string
1220 * @param new_pos the new position of the string
1221 * @param array the array
1222 * @param array_len length of the demarshaled data
1223 * @returns #TRUE on success
1226 _dbus_demarshal_uint32_array (const DBusString *str,
1230 dbus_uint32_t **array,
1233 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1237 #ifdef DBUS_HAVE_INT64
1240 * Demarshals a 64 bit signed integer array.
1242 * @param str the string containing the data
1243 * @param byte_order the byte order
1244 * @param pos the position in the string
1245 * @param new_pos the new position of the string
1246 * @param array the array
1247 * @param array_len length of the demarshaled data
1248 * @returns #TRUE on success
1251 _dbus_demarshal_int64_array (const DBusString *str,
1255 dbus_int64_t **array,
1258 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1259 (DBusOctets8**) array, array_len);
1263 * Demarshals a 64 bit unsigned integer array.
1265 * @param str the string containing the data
1266 * @param byte_order the byte order
1267 * @param pos the position in the string
1268 * @param new_pos the new position of the string
1269 * @param array the array
1270 * @param array_len length of the demarshaled data
1271 * @returns #TRUE on success
1274 _dbus_demarshal_uint64_array (const DBusString *str,
1278 dbus_uint64_t **array,
1281 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1282 (DBusOctets8**) array, array_len);
1285 #endif /* DBUS_HAVE_INT64 */
1288 * Demarshals a double array.
1290 * @param str the string containing the data
1291 * @param byte_order the byte order
1292 * @param pos the position in the string
1293 * @param new_pos the new position of the string
1294 * @param array the array
1295 * @param array_len length of the demarshaled data
1296 * @returns #TRUE on success
1299 _dbus_demarshal_double_array (const DBusString *str,
1306 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1307 (DBusOctets8**) array, array_len);
1311 * Demarshals a string array.
1313 * @param str the string containing the data
1314 * @param byte_order the byte order
1315 * @param pos the position in the string
1316 * @param new_pos the new position of the string
1317 * @param array the array
1318 * @param array_len length of the demarshaled data
1319 * @returns #TRUE on success
1322 _dbus_demarshal_string_array (const DBusString *str,
1334 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1349 end_pos = pos + bytes_len;
1351 retval = dbus_new (char *, allocated);
1356 while (pos < end_pos)
1358 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1360 if (retval[len] == NULL)
1365 if (len >= allocated - 1) /* -1 for NULL termination */
1368 newp = dbus_realloc (retval,
1369 sizeof (char*) * allocated * 2);
1389 for (i = 0; i < len; i++)
1390 dbus_free (retval[i]);
1397 * Returns the position right after the end of an argument. PERFORMS
1398 * NO VALIDATION WHATSOEVER. The message must have been previously
1401 * @param str a string
1402 * @param byte_order the byte order to use
1403 * @param type the type of the argument
1404 * @param pos the pos where the arg starts
1405 * @param end_pos pointer where the position right
1406 * after the end position will follow
1407 * @returns TRUE if more data exists after the arg
1410 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1416 if (pos >= _dbus_string_get_length (str))
1421 case DBUS_TYPE_INVALID:
1429 case DBUS_TYPE_BYTE:
1433 case DBUS_TYPE_BOOLEAN:
1437 case DBUS_TYPE_INT32:
1438 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
1442 case DBUS_TYPE_UINT32:
1443 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
1447 #ifdef DBUS_HAVE_INT64
1448 case DBUS_TYPE_INT64:
1449 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int64_t)) + sizeof (dbus_int64_t);
1453 case DBUS_TYPE_UINT64:
1454 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint64_t)) + sizeof (dbus_uint64_t);
1457 #endif /* DBUS_HAVE_INT64 */
1459 case DBUS_TYPE_DOUBLE:
1460 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
1464 case DBUS_TYPE_STRING:
1468 /* Demarshal the length */
1469 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1471 *end_pos = pos + len + 1;
1475 case DBUS_TYPE_NAMED:
1479 /* Demarshal the string length */
1480 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1482 *end_pos = pos + len + 1;
1484 /* Demarshal the data length */
1485 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1487 *end_pos = pos + len;
1491 case DBUS_TYPE_ARRAY:
1495 /* Demarshal the length */
1496 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1498 *end_pos = pos + len;
1502 case DBUS_TYPE_DICT:
1506 /* Demarshal the length */
1507 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1509 *end_pos = pos + len;
1514 _dbus_warn ("Unknown message arg type %d\n", type);
1515 _dbus_assert_not_reached ("Unknown message argument type\n");
1519 if (*end_pos > _dbus_string_get_length (str))
1526 * Demarshals and validates a length; returns < 0 if the validation
1527 * fails. The length is required to be small enough that
1528 * len*sizeof(double) will not overflow, and small enough to fit in a
1529 * signed integer. DOES NOT check whether the length points
1530 * beyond the end of the string, because it doesn't know the
1531 * size of array elements.
1533 * @param str the string
1534 * @param byte_order the byte order
1535 * @param pos the unaligned string position (snap to next aligned)
1536 * @param new_pos return location for new position.
1539 demarshal_and_validate_len (const DBusString *str,
1544 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1547 _dbus_assert (new_pos != NULL);
1549 if ((align_4 + 4) > _dbus_string_get_length (str))
1551 _dbus_verbose ("not enough room in message for array length\n");
1555 if (!_dbus_string_validate_nul (str, pos,
1558 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1562 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1564 /* note that the len is the number of bytes, so we need it to be
1565 * at least SIZE_T_MAX, but make it smaller just to keep things
1566 * sane. We end up using ints for most sizes to avoid unsigned mess
1567 * so limit to maximum 32-bit signed int divided by at least 8, more
1568 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1570 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1571 if (len > MAX_ARRAY_LENGTH)
1573 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1574 len, MAX_ARRAY_LENGTH);
1582 validate_string (const DBusString *str,
1584 int len_without_nul,
1587 *end_pos = pos + len_without_nul + 1;
1589 if (*end_pos > _dbus_string_get_length (str))
1591 _dbus_verbose ("string length outside length of the message\n");
1595 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1597 _dbus_verbose ("string arg not nul-terminated\n");
1601 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1603 _dbus_verbose ("string is not valid UTF-8\n");
1611 * Validates and returns a typecode at a specific position
1614 * @param str a string
1615 * @param type the type of the argument
1616 * @param pos the pos where the typecode starts
1617 * @param end_pos pointer where the position right
1618 * after the end position will follow
1619 * @returns #TRUE if the type is valid.
1622 _dbus_marshal_validate_type (const DBusString *str,
1629 if (pos >= _dbus_string_get_length (str))
1632 data = _dbus_string_get_const_data_len (str, pos, 1);
1634 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1637 if (end_pos != NULL)
1645 /* Faster validator for array data that doesn't call
1646 * validate_arg for each value
1649 validate_array_data (const DBusString *str,
1660 case DBUS_TYPE_INVALID:
1667 case DBUS_TYPE_STRING:
1668 case DBUS_TYPE_NAMED:
1669 case DBUS_TYPE_ARRAY:
1670 case DBUS_TYPE_DICT:
1671 /* This clean recursion to validate_arg is what we
1672 * are doing logically for all types, but we don't
1673 * really want to call validate_arg for every byte
1674 * in a byte array, so the primitive types are
1679 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1680 type, array_type_pos, pos, &pos))
1685 case DBUS_TYPE_BYTE:
1689 case DBUS_TYPE_BOOLEAN:
1694 c = _dbus_string_get_byte (str, pos);
1696 if (!(c == 0 || c == 1))
1698 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1706 case DBUS_TYPE_INT32:
1707 case DBUS_TYPE_UINT32:
1708 /* Call validate arg one time to check alignment padding
1711 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1712 type, array_type_pos, pos, &pos))
1714 pos = _DBUS_ALIGN_VALUE (end, 4);
1717 case DBUS_TYPE_INT64:
1718 case DBUS_TYPE_UINT64:
1719 case DBUS_TYPE_DOUBLE:
1720 /* Call validate arg one time to check alignment padding
1723 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
1724 type, array_type_pos, pos, &pos))
1726 pos = _DBUS_ALIGN_VALUE (end, 8);
1730 _dbus_verbose ("Unknown message arg type %d\n", type);
1740 * Validates an argument of a specific type, checking that it
1741 * is well-formed, for example no ludicrous length fields, strings
1742 * are nul-terminated, etc.
1743 * Returns the end position of the argument in end_pos, and
1744 * returns #TRUE if a valid arg begins at "pos"
1746 * @todo security: need to audit this function.
1748 * @todo For array types that can't be invalid, we should not
1749 * walk the whole array validating it. e.g. just skip all the
1750 * int values in an int array.
1752 * @param str a string
1753 * @param byte_order the byte order to use
1754 * @param depth current recursion depth, to prevent excessive recursion
1755 * @param type the type of the argument
1756 * @param array_type_pos the position of the current array type, or
1757 * -1 if not in an array
1758 * @param pos the pos where the arg starts
1759 * @param end_pos pointer where the position right
1760 * after the end position will follow
1761 * @returns #TRUE if the arg is valid.
1764 _dbus_marshal_validate_arg (const DBusString *str,
1772 if (pos > _dbus_string_get_length (str))
1774 _dbus_verbose ("Validation went off the end of the message\n");
1778 #define MAX_VALIDATION_DEPTH 32
1780 if (depth > MAX_VALIDATION_DEPTH)
1782 _dbus_verbose ("Maximum recursion depth reached validating message\n");
1788 case DBUS_TYPE_INVALID:
1796 case DBUS_TYPE_BYTE:
1797 if (1 > _dbus_string_get_length (str) - pos)
1799 _dbus_verbose ("no room for byte value\n");
1806 case DBUS_TYPE_BOOLEAN:
1810 if (1 > _dbus_string_get_length (str) - pos)
1812 _dbus_verbose ("no room for boolean value\n");
1816 c = _dbus_string_get_byte (str, pos);
1818 if (!(c == 0 || c == 1))
1820 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1828 case DBUS_TYPE_INT32:
1829 case DBUS_TYPE_UINT32:
1831 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1833 if (!_dbus_string_validate_nul (str, pos,
1836 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1840 *end_pos = align_4 + 4;
1844 case DBUS_TYPE_INT64:
1845 case DBUS_TYPE_UINT64:
1847 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1849 if (!_dbus_string_validate_nul (str, pos,
1852 _dbus_verbose ("int64/uint64 alignment padding not initialized to nul\n");
1856 *end_pos = align_8 + 8;
1860 case DBUS_TYPE_DOUBLE:
1862 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1864 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1866 if (!_dbus_string_validate_nul (str, pos,
1869 _dbus_verbose ("double alignment padding not initialized to nul\n");
1873 *end_pos = align_8 + 8;
1877 case DBUS_TYPE_STRING:
1881 /* Demarshal the length, which does NOT include
1884 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1888 if (!validate_string (str, pos, len, end_pos))
1893 case DBUS_TYPE_NAMED:
1897 /* Demarshal the string length, which does NOT include
1900 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1904 if (!validate_string (str, pos, len, &pos))
1908 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1912 *end_pos = pos + len;
1916 case DBUS_TYPE_ARRAY:
1922 if (array_type_pos == -1)
1924 array_type_pos = pos;
1928 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1930 _dbus_verbose ("invalid array type\n");
1934 /* NIL values take up no space, so you couldn't iterate over an array of them.
1935 * array of nil seems useless anyway; the useful thing might be array of
1936 * (nil OR string) but we have no framework for that.
1938 if (array_type == DBUS_TYPE_NIL)
1940 _dbus_verbose ("array of NIL is not allowed\n");
1944 while (array_type == DBUS_TYPE_ARRAY);
1949 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
1951 _dbus_verbose ("invalid array type\n");
1955 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1959 if (len > _dbus_string_get_length (str) - pos)
1961 _dbus_verbose ("array length outside length of the message\n");
1967 if (!validate_array_data (str, byte_order, depth + 1,
1968 array_type, array_type_pos,
1974 /* This should not be able to happen, as long as validate_arg moves forward;
1975 * but the check is here just to be paranoid.
1977 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
1984 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
1992 case DBUS_TYPE_DICT:
1998 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2002 if (len > _dbus_string_get_length (str) - pos)
2004 _dbus_verbose ("dict length outside length of the message\n");
2013 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2014 DBUS_TYPE_STRING, -1, pos, &pos))
2017 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
2019 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
2023 /* Validate element */
2024 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2025 dict_type, -1, pos, &pos))
2031 _dbus_verbose ("dict contents exceed stated dict length\n");
2040 _dbus_verbose ("Unknown message arg type %d\n", type);
2044 if (*end_pos > _dbus_string_get_length (str))
2052 * If in verbose mode, print a block of binary data.
2054 * @todo right now it prints even if not in verbose mode
2056 * @param data the data
2057 * @param len the length of the data
2060 _dbus_verbose_bytes (const unsigned char *data,
2064 const unsigned char *aligned;
2066 _dbus_assert (len >= 0);
2068 /* Print blanks on first row if appropriate */
2069 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2072 _dbus_assert (aligned <= data);
2074 if (aligned != data)
2076 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
2077 while (aligned != data)
2079 _dbus_verbose (" ");
2084 /* now print the bytes */
2088 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2090 _dbus_verbose ("%4d\t%p: ",
2094 if (data[i] >= 32 &&
2096 _dbus_verbose (" '%c' ", data[i]);
2098 _dbus_verbose ("0x%s%x ",
2099 data[i] <= 0xf ? "0" : "", data[i]);
2103 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2106 _dbus_verbose ("BE: %d LE: %d",
2107 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2108 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2111 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2113 _dbus_verbose (" dbl: %g",
2114 *(double*)&data[i-8]);
2117 _dbus_verbose ("\n");
2121 _dbus_verbose ("\n");
2125 * Dump the given part of the string to verbose log.
2127 * @param str the string
2128 * @param start the start of range to dump
2129 * @param len length of range
2132 _dbus_verbose_bytes_of_string (const DBusString *str,
2139 real_len = _dbus_string_get_length (str);
2141 _dbus_assert (start >= 0);
2143 if (start > real_len)
2145 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
2146 start, len, real_len);
2150 if ((start + len) > real_len)
2152 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
2153 start, len, real_len);
2154 len = real_len - start;
2157 d = _dbus_string_get_const_data_len (str, start, len);
2159 _dbus_verbose_bytes (d, len);
2164 #ifdef DBUS_BUILD_TESTS
2165 #include "dbus-test.h"
2169 _dbus_marshal_test (void)
2174 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2175 #ifdef DBUS_HAVE_INT64
2176 dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
2181 if (!_dbus_string_init (&str))
2182 _dbus_assert_not_reached ("failed to init string");
2184 /* Marshal doubles */
2185 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2186 _dbus_assert_not_reached ("could not marshal double value");
2187 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2188 _dbus_assert_not_reached ("demarshal failed");
2190 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2191 _dbus_assert_not_reached ("could not marshal double value");
2192 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2193 _dbus_assert_not_reached ("demarshal failed");
2195 /* Marshal signed integers */
2196 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2197 _dbus_assert_not_reached ("could not marshal signed integer value");
2198 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2199 _dbus_assert_not_reached ("demarshal failed");
2201 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2202 _dbus_assert_not_reached ("could not marshal signed integer value");
2203 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2204 _dbus_assert_not_reached ("demarshal failed");
2206 /* Marshal unsigned integers */
2207 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2208 _dbus_assert_not_reached ("could not marshal signed integer value");
2209 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2210 _dbus_assert_not_reached ("demarshal failed");
2212 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2213 _dbus_assert_not_reached ("could not marshal signed integer value");
2214 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2215 _dbus_assert_not_reached ("demarshal failed");
2217 #ifdef DBUS_HAVE_INT64
2218 /* Marshal signed integers */
2219 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2220 _dbus_assert_not_reached ("could not marshal signed integer value");
2221 if (!_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2222 _dbus_assert_not_reached ("demarshal failed");
2224 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2225 _dbus_assert_not_reached ("could not marshal signed integer value");
2226 if (!_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
2227 _dbus_assert_not_reached ("demarshal failed");
2229 /* Marshal unsigned integers */
2230 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2231 _dbus_assert_not_reached ("could not marshal signed integer value");
2232 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2233 _dbus_assert_not_reached ("demarshal failed");
2235 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2236 _dbus_assert_not_reached ("could not marshal signed integer value");
2237 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2238 _dbus_assert_not_reached ("demarshal failed");
2239 #endif /* DBUS_HAVE_INT64 */
2241 /* Marshal strings */
2242 tmp1 = "This is the dbus test string";
2243 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2244 _dbus_assert_not_reached ("could not marshal string");
2245 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2246 if (!strcmp (tmp1, tmp2) == 0)
2247 _dbus_assert_not_reached ("demarshal failed");
2250 tmp1 = "This is the dbus test string";
2251 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2252 _dbus_assert_not_reached ("could not marshal string");
2253 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2254 if (!strcmp (tmp1, tmp2) == 0)
2255 _dbus_assert_not_reached ("demarshal failed");
2258 /* Marshal signed integer arrays */
2259 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2260 _dbus_assert_not_reached ("could not marshal integer array");
2261 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2262 _dbus_assert_not_reached ("could not demarshal integer array");
2265 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2268 #ifdef DBUS_HAVE_INT64
2269 /* Marshal 64-bit signed integer arrays */
2270 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2271 _dbus_assert_not_reached ("could not marshal integer array");
2272 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2273 _dbus_assert_not_reached ("could not demarshal integer array");
2276 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2279 /* set/pack 64-bit integers */
2280 _dbus_string_set_length (&str, 8);
2283 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2284 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2286 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2287 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2288 _dbus_string_get_const_data (&str)));
2291 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2292 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2294 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2295 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2296 _dbus_string_get_const_data (&str)));
2298 /* signed little pack */
2299 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2301 _dbus_string_get_data (&str));
2303 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2304 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2305 _dbus_string_get_const_data (&str)));
2307 /* signed big pack */
2308 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2310 _dbus_string_get_data (&str));
2312 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2313 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2314 _dbus_string_get_const_data (&str)));
2316 /* unsigned little */
2317 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2318 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2320 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2321 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2322 _dbus_string_get_const_data (&str)));
2325 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2326 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2328 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2329 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2330 _dbus_string_get_const_data (&str)));
2332 /* unsigned little pack */
2333 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2335 _dbus_string_get_data (&str));
2337 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2338 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2339 _dbus_string_get_const_data (&str)));
2341 /* unsigned big pack */
2342 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2344 _dbus_string_get_data (&str));
2346 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2347 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2348 _dbus_string_get_const_data (&str)));
2352 /* set/pack 32-bit integers */
2353 _dbus_string_set_length (&str, 4);
2356 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2359 _dbus_assert (-0x123456 ==
2360 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2361 _dbus_string_get_const_data (&str)));
2364 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2367 _dbus_assert (-0x123456 ==
2368 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2369 _dbus_string_get_const_data (&str)));
2371 /* signed little pack */
2372 _dbus_pack_int32 (-0x123456,
2374 _dbus_string_get_data (&str));
2376 _dbus_assert (-0x123456 ==
2377 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2378 _dbus_string_get_const_data (&str)));
2380 /* signed big pack */
2381 _dbus_pack_int32 (-0x123456,
2383 _dbus_string_get_data (&str));
2385 _dbus_assert (-0x123456 ==
2386 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2387 _dbus_string_get_const_data (&str)));
2389 /* unsigned little */
2390 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2393 _dbus_assert (0x123456 ==
2394 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2395 _dbus_string_get_const_data (&str)));
2398 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2401 _dbus_assert (0x123456 ==
2402 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2403 _dbus_string_get_const_data (&str)));
2405 /* unsigned little pack */
2406 _dbus_pack_uint32 (0x123456,
2408 _dbus_string_get_data (&str));
2410 _dbus_assert (0x123456 ==
2411 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2412 _dbus_string_get_const_data (&str)));
2414 /* unsigned big pack */
2415 _dbus_pack_uint32 (0x123456,
2417 _dbus_string_get_data (&str));
2419 _dbus_assert (0x123456 ==
2420 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2421 _dbus_string_get_const_data (&str)));
2426 _dbus_string_set_length (&str, 0);
2428 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2431 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2432 _dbus_assert (strcmp (s, "Hello world") == 0);
2435 _dbus_string_init_const (&t, "Hello world foo");
2437 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2438 &t, _dbus_string_get_length (&t));
2440 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2441 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2444 _dbus_string_init_const (&t, "Hello");
2446 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2447 &t, _dbus_string_get_length (&t));
2449 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2450 _dbus_assert (strcmp (s, "Hello") == 0);
2453 /* Strings (big endian) */
2455 _dbus_string_set_length (&str, 0);
2457 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
2460 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2461 _dbus_assert (strcmp (s, "Hello world") == 0);
2464 _dbus_string_init_const (&t, "Hello world foo");
2466 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2467 &t, _dbus_string_get_length (&t));
2469 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2470 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2473 _dbus_string_init_const (&t, "Hello");
2475 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2476 &t, _dbus_string_get_length (&t));
2478 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2479 _dbus_assert (strcmp (s, "Hello") == 0);
2483 _dbus_string_free (&str);
2488 #endif /* DBUS_BUILD_TESTS */