1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c Marshalling routines
4 * Copyright (C) 2002 CodeFactory AB
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-marshal.h"
25 #include "dbus-internals.h"
31 swap_bytes (unsigned char *data,
34 unsigned char *p1 = data;
35 unsigned char *p2 = data + len - 1;
39 unsigned char tmp = *p1;
49 * @defgroup DBusMarshal marshaling and unmarshaling
50 * @ingroup DBusInternals
51 * @brief functions to marshal/unmarshal data from the wire
53 * Types and functions related to converting primitive data types from
54 * wire format to native machine format, and vice versa.
60 * Unpacks a 32 bit unsigned integer from a data pointer
62 * @param byte_order The byte order to use
63 * @param data the data pointer
64 * @returns the integer
67 _dbus_unpack_uint32 (int byte_order,
68 const unsigned char *data)
70 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
72 if (byte_order == DBUS_LITTLE_ENDIAN)
73 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
75 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
79 * Unpacks a 32 bit signed integer from a data pointer
81 * @param byte_order The byte order to use
82 * @param data the data pointer
83 * @returns the integer
86 _dbus_unpack_int32 (int byte_order,
87 const unsigned char *data)
89 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
91 if (byte_order == DBUS_LITTLE_ENDIAN)
92 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
94 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
98 * Packs a 32 bit unsigned integer into a data pointer.
100 * @param value the value
101 * @param byte_order the byte order to use
102 * @param data the data pointer
105 _dbus_pack_uint32 (dbus_uint32_t value,
109 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
111 if ((byte_order) == DBUS_LITTLE_ENDIAN)
112 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
114 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
118 * Packs a 32 bit signed integer into a data pointer.
120 * @param value the value
121 * @param byte_order the byte order to use
122 * @param data the data pointer
125 _dbus_pack_int32 (dbus_int32_t value,
129 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
131 if ((byte_order) == DBUS_LITTLE_ENDIAN)
132 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);
134 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
138 * Sets the 4 bytes at the given offset to a marshaled signed integer,
139 * replacing anything found there previously.
141 * @param str the string to write the marshalled int to
142 * @param offset the byte offset where int should be written
143 * @param byte_order the byte order to use
144 * @param value the value
148 _dbus_marshal_set_int32 (DBusString *str,
155 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
156 byte_order == DBUS_BIG_ENDIAN);
158 _dbus_string_get_data_len (str, &data, offset, 4);
160 _dbus_pack_int32 (value, byte_order, data);
164 * Sets the 4 bytes at the given offset to a marshaled unsigned
165 * integer, replacing anything found there previously.
167 * @param str the string to write the marshalled int to
168 * @param offset the byte offset where int should be written
169 * @param byte_order the byte order to use
170 * @param value the value
174 _dbus_marshal_set_uint32 (DBusString *str,
181 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
182 byte_order == DBUS_BIG_ENDIAN);
184 _dbus_string_get_data_len (str, &data, offset, 4);
186 _dbus_pack_uint32 (value, byte_order, data);
190 * Sets the existing marshaled string at the given offset with
191 * a new marshaled string. The given offset must point to
192 * an existing string or the wrong length will be deleted
193 * and replaced with the new string.
195 * @param str the string to write the marshalled string to
196 * @param offset the byte offset where string should be written
197 * @param byte_order the byte order to use
198 * @param value the value
199 * @returns #TRUE on success
203 _dbus_marshal_set_string (DBusString *str,
206 const DBusString *value)
211 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
212 byte_order == DBUS_BIG_ENDIAN);
214 old_len = _dbus_demarshal_uint32 (str, byte_order,
217 new_len = _dbus_string_get_length (value);
219 if (!_dbus_string_replace_len (value, 0, new_len,
220 str, offset + 4, old_len))
223 _dbus_marshal_set_uint32 (str, byte_order,
230 * Marshals a double value.
232 * @param str the string to append the marshalled value to
233 * @param byte_order the byte order to use
234 * @param value the value
235 * @returns #TRUE on success
238 _dbus_marshal_double (DBusString *str,
242 _dbus_assert (sizeof (double) == 8);
244 if (!_dbus_string_align_length (str, sizeof (double)))
247 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
248 swap_bytes ((unsigned char *)&value, sizeof (double));
250 return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
254 * Marshals a 32 bit signed integer value.
256 * @param str the string to append the marshalled value to
257 * @param byte_order the byte order to use
258 * @param value the value
259 * @returns #TRUE on success
262 _dbus_marshal_int32 (DBusString *str,
266 if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
269 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
270 value = DBUS_INT32_SWAP_LE_BE (value);
272 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
276 * Marshals a 32 bit unsigned integer value.
278 * @param str the string to append the marshalled value to
279 * @param byte_order the byte order to use
280 * @param value the value
281 * @returns #TRUE on success
284 _dbus_marshal_uint32 (DBusString *str,
288 if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
291 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
292 value = DBUS_UINT32_SWAP_LE_BE (value);
294 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
298 * Marshals a UTF-8 string
300 * @param str the string to append the marshalled value to
301 * @param byte_order the byte order to use
302 * @param value the string
303 * @returns #TRUE on success
306 _dbus_marshal_string (DBusString *str,
310 int len, old_string_len;
312 old_string_len = _dbus_string_get_length (str);
314 len = strlen (value);
316 if (!_dbus_marshal_uint32 (str, byte_order, len))
318 /* Restore the previous length */
319 _dbus_string_set_length (str, old_string_len);
324 return _dbus_string_append_len (str, value, len + 1);
328 * Marshals a byte array
330 * @param str the string to append the marshalled value to
331 * @param byte_order the byte order to use
332 * @param value the array
333 * @param len number of elements in the array
334 * @returns #TRUE on success
337 _dbus_marshal_byte_array (DBusString *str,
339 const unsigned char *value,
344 old_string_len = _dbus_string_get_length (str);
346 if (!_dbus_marshal_uint32 (str, byte_order, len))
348 /* Restore the previous length */
349 _dbus_string_set_length (str, old_string_len);
354 return _dbus_string_append_len (str, value, len);
358 * Marshals a 32 bit signed integer array
360 * @param str the string to append the marshalled value to
361 * @param byte_order the byte order to use
362 * @param value the array
363 * @param len the length of the array
364 * @returns #TRUE on success
367 _dbus_marshal_int32_array (DBusString *str,
369 const dbus_int32_t *value,
372 int i, old_string_len;
374 old_string_len = _dbus_string_get_length (str);
376 if (!_dbus_marshal_uint32 (str, byte_order, len))
379 for (i = 0; i < len; i++)
380 if (!_dbus_marshal_int32 (str, byte_order, value[i]))
386 /* Restore previous length */
387 _dbus_string_set_length (str, old_string_len);
393 * Marshals a 32 bit unsigned integer array
395 * @param str the string to append the marshalled value to
396 * @param byte_order the byte order to use
397 * @param value the array
398 * @param len the length of the array
399 * @returns #TRUE on success
402 _dbus_marshal_uint32_array (DBusString *str,
404 const dbus_uint32_t *value,
407 int i, old_string_len;
409 old_string_len = _dbus_string_get_length (str);
411 if (!_dbus_marshal_uint32 (str, byte_order, len))
414 for (i = 0; i < len; i++)
415 if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
421 /* Restore previous length */
422 _dbus_string_set_length (str, old_string_len);
428 * Marshals a double array
430 * @param str the string to append the marshalled value to
431 * @param byte_order the byte order to use
432 * @param value the array
433 * @param len the length of the array
434 * @returns #TRUE on success
437 _dbus_marshal_double_array (DBusString *str,
442 int i, old_string_len;
444 old_string_len = _dbus_string_get_length (str);
446 if (!_dbus_marshal_uint32 (str, byte_order, len))
449 for (i = 0; i < len; i++)
450 if (!_dbus_marshal_double (str, byte_order, value[i]))
456 /* Restore previous length */
457 _dbus_string_set_length (str, old_string_len);
463 * Marshals a string array
465 * @param str the string to append the marshalled value to
466 * @param byte_order the byte order to use
467 * @param value the array
468 * @param len the length of the array
469 * @returns #TRUE on success
472 _dbus_marshal_string_array (DBusString *str,
477 int i, old_string_len;
479 old_string_len = _dbus_string_get_length (str);
481 if (!_dbus_marshal_uint32 (str, byte_order, len))
484 for (i = 0; i < len; i++)
485 if (!_dbus_marshal_string (str, byte_order, value[i]))
491 /* Restore previous length */
492 _dbus_string_set_length (str, old_string_len);
498 * Demarshals a double.
500 * @param str the string containing the data
501 * @param byte_order the byte order
502 * @param pos the position in the string
503 * @param new_pos the new position of the string
504 * @returns the demarshaled double.
507 _dbus_demarshal_double (const DBusString *str,
515 pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
517 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
519 retval = *(double *)buffer;
521 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
522 swap_bytes ((unsigned char *)&retval, sizeof (double));
525 *new_pos = pos + sizeof (double);
531 * Demarshals a 32 bit signed integer.
533 * @param str the string containing the data
534 * @param byte_order the byte order
535 * @param pos the position in the string
536 * @param new_pos the new position of the string
537 * @returns the demarshaled integer.
540 _dbus_demarshal_int32 (const DBusString *str,
547 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
549 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_int32_t));
552 *new_pos = pos + sizeof (dbus_int32_t);
554 return _dbus_unpack_int32 (byte_order, buffer);
558 * Demarshals a 32 bit unsigned integer.
560 * @param str the string containing the data
561 * @param byte_order the byte order
562 * @param pos the position in the string
563 * @param new_pos the new position of the string
564 * @returns the demarshaled integer.
567 _dbus_demarshal_uint32 (const DBusString *str,
574 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
576 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_uint32_t));
579 *new_pos = pos + sizeof (dbus_uint32_t);
581 return _dbus_unpack_uint32 (byte_order, buffer);
585 * Demarshals an UTF-8 string.
587 * @todo Should we check the string to make sure
588 * that it's valid UTF-8, and maybe "fix" the string
591 * @todo Should probably demarshal to a DBusString,
592 * having memcpy() in here is Evil(tm).
594 * @param str the string containing the data
595 * @param byte_order the byte order
596 * @param pos the position in the string
597 * @param new_pos the new position of the string
598 * @returns the demarshaled string.
601 _dbus_demarshal_string (const DBusString *str,
610 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
612 retval = dbus_malloc (len + 1);
617 _dbus_string_get_const_data_len (str, &data, pos, len);
622 memcpy (retval, data, len + 1);
625 *new_pos = pos + len + 1;
631 * Demarshals a byte array.
633 * @todo Should probably demarshal to a DBusString,
634 * having memcpy() in here is Evil(tm).
636 * @param str the string containing the data
637 * @param byte_order the byte order
638 * @param pos the position in the string
639 * @param new_pos the new position of the string
640 * @param array_len length of the demarshaled data
641 * @returns the demarshaled data.
644 _dbus_demarshal_byte_array (const DBusString *str,
651 unsigned char *retval;
654 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
656 retval = dbus_malloc (len);
661 _dbus_string_get_const_data_len (str, &data, pos, len);
666 memcpy (retval, data, len);
669 *new_pos = pos + len;
678 * Demarshals a 32 bit signed integer array.
680 * @param str the string containing the data
681 * @param byte_order the byte order
682 * @param pos the position in the string
683 * @param new_pos the new position of the string
684 * @param array_len length of the demarshaled data
685 * @returns the demarshaled data.
688 _dbus_demarshal_int32_array (const DBusString *str,
695 dbus_int32_t *retval;
697 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
699 retval = dbus_new (dbus_int32_t, len);
704 for (i = 0; i < len; i++)
705 retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
717 * Demarshals a 32 bit unsigned integer array.
719 * @param str the string containing the data
720 * @param byte_order the byte order
721 * @param pos the position in the string
722 * @param new_pos the new position of the string
723 * @param array_len length of the demarshaled data
724 * @returns the demarshaled data.
727 _dbus_demarshal_uint32_array (const DBusString *str,
734 dbus_uint32_t *retval;
736 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
738 retval = dbus_new (dbus_uint32_t, len);
743 for (i = 0; i < len; i++)
744 retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
756 * Demarshals a double array.
758 * @param str the string containing the data
759 * @param byte_order the byte order
760 * @param pos the position in the string
761 * @param new_pos the new position of the string
762 * @param array_len length of the demarshaled data
763 * @returns the demarshaled data.
766 _dbus_demarshal_double_array (const DBusString *str,
775 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
777 retval = dbus_new (double, len);
782 for (i = 0; i < len; i++)
783 retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
795 * Demarshals a string array.
797 * @param str the string containing the data
798 * @param byte_order the byte order
799 * @param pos the position in the string
800 * @param new_pos the new position of the string
801 * @param array_len length of the demarshaled data
802 * @returns the demarshaled data.
805 _dbus_demarshal_string_array (const DBusString *str,
814 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
816 retval = dbus_new (char *, len + 1);
823 for (i = 0; i < len; i++)
825 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
840 for (j = 0; j < i; j++)
841 dbus_free (retval[i]);
848 * Returns the position right after the end of an argument. PERFORMS
849 * NO VALIDATION WHATSOEVER. The message must have been previously
852 * @param str a string
853 * @param byte_order the byte order to use
854 * @param pos the pos where the arg starts
855 * @param end_pos pointer where the position right
856 * after the end position will follow
857 * @returns TRUE if more data exists after the arg
860 _dbus_marshal_get_arg_end_pos (const DBusString *str,
867 if (pos >= _dbus_string_get_length (str))
870 _dbus_string_get_const_data_len (str, &data, pos, 1);
874 case DBUS_TYPE_INVALID:
882 case DBUS_TYPE_BOOLEAN:
886 case DBUS_TYPE_INT32:
887 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
891 case DBUS_TYPE_UINT32:
892 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
896 case DBUS_TYPE_DOUBLE:
897 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
901 case DBUS_TYPE_STRING:
905 /* Demarshal the length */
906 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
908 *end_pos = pos + len + 1;
912 case DBUS_TYPE_BOOLEAN_ARRAY:
913 case DBUS_TYPE_BYTE_ARRAY:
917 /* Demarshal the length */
918 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
920 *end_pos = pos + len;
924 case DBUS_TYPE_INT32_ARRAY:
928 /* Demarshal the length */
929 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
931 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
932 + (len * sizeof (dbus_int32_t));
936 case DBUS_TYPE_UINT32_ARRAY:
940 /* Demarshal the length */
941 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
943 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
944 + (len * sizeof (dbus_uint32_t));
948 case DBUS_TYPE_DOUBLE_ARRAY:
952 /* Demarshal the length */
953 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
955 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
956 + (len * sizeof (double));
960 case DBUS_TYPE_STRING_ARRAY:
964 /* Demarshal the length */
965 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
967 for (i = 0; i < len; i++)
971 /* Demarshal string length */
972 str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
981 _dbus_warn ("Unknown message arg type %d\n", *data);
982 _dbus_assert_not_reached ("Unknown message argument type\n");
986 if (*end_pos > _dbus_string_get_length (str))
993 * Demarshals and validates a length; returns < 0 if the validation
994 * fails. The length is required to be small enough that
995 * len*sizeof(double) will not overflow, and small enough to fit in a
998 * @param str the string
999 * @param byte_order the byte order
1000 * @param pos the unaligned string position (snap to next aligned)
1001 * @param new_pos return location for new position.
1004 demarshal_and_validate_len (const DBusString *str,
1009 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1012 if ((align_4 + 4) >= _dbus_string_get_length (str))
1014 _dbus_verbose ("not enough room in message for array length\n");
1018 if (!_dbus_string_validate_nul (str, pos,
1021 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1025 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1027 /* note that the len may be a number of doubles, so we need it to be
1028 * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1029 * sane. We end up using ints for most sizes to avoid unsigned mess
1030 * so limit to maximum 32-bit signed int divided by at least 8, more
1031 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1033 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1034 if (len > MAX_ARRAY_LENGTH)
1036 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1037 len, MAX_ARRAY_LENGTH);
1045 validate_string (const DBusString *str,
1047 int len_without_nul,
1050 *end_pos = pos + len_without_nul + 1;
1052 if (*end_pos > _dbus_string_get_length (str))
1054 _dbus_verbose ("string length outside length of the message\n");
1058 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1060 _dbus_verbose ("string arg not nul-terminated\n");
1064 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1066 _dbus_verbose ("string is not valid UTF-8\n");
1074 * Validates an argument, checking that it is well-formed, for example
1075 * no ludicrous length fields, strings are nul-terminated, etc.
1076 * Returns the end position of the argument in end_pos, and
1077 * returns #TRUE if a valid arg begins at "pos"
1079 * @todo security: need to audit this function.
1081 * @param str a string
1082 * @param byte_order the byte order to use
1083 * @param pos the pos where the arg starts (offset of its typecode)
1084 * @param end_pos pointer where the position right
1085 * after the end position will follow
1086 * @returns #TRUE if the arg is valid.
1089 _dbus_marshal_validate_arg (const DBusString *str,
1096 if (pos >= _dbus_string_get_length (str))
1099 _dbus_string_get_const_data_len (str, &data, pos, 1);
1103 case DBUS_TYPE_INVALID:
1111 case DBUS_TYPE_BOOLEAN:
1115 c = _dbus_string_get_byte (str, pos + 1);
1117 if (c != 0 && c != 1)
1119 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1126 case DBUS_TYPE_INT32:
1127 case DBUS_TYPE_UINT32:
1129 int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1131 if (!_dbus_string_validate_nul (str, pos + 1,
1134 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1138 *end_pos = align_4 + 4;
1142 case DBUS_TYPE_DOUBLE:
1144 int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1146 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1148 if (!_dbus_string_validate_nul (str, pos + 1,
1151 _dbus_verbose ("double alignment padding not initialized to nul\n");
1155 *end_pos = align_8 + 8;
1159 case DBUS_TYPE_STRING:
1163 /* Demarshal the length, which does NOT include
1166 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1170 if (!validate_string (str, pos, len, end_pos))
1175 case DBUS_TYPE_BOOLEAN_ARRAY:
1179 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1186 unsigned char c = _dbus_string_get_byte (str, pos + i);
1188 if (c != 0 && c != 1)
1190 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1196 *end_pos = pos + len;
1199 case DBUS_TYPE_BYTE_ARRAY:
1203 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1207 *end_pos = pos + len;
1211 case DBUS_TYPE_INT32_ARRAY:
1212 case DBUS_TYPE_UINT32_ARRAY:
1216 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1220 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1222 *end_pos = pos + len * 4;
1226 case DBUS_TYPE_DOUBLE_ARRAY:
1231 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1235 align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1236 if (!_dbus_string_validate_nul (str, pos,
1239 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1243 *end_pos = align_8 + len * 8;
1247 case DBUS_TYPE_STRING_ARRAY:
1252 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1256 for (i = 0; i < len; i++)
1260 str_len = demarshal_and_validate_len (str, byte_order,
1265 if (!validate_string (str, pos, str_len, &pos))
1274 _dbus_verbose ("Unknown message arg type %d\n", *data);
1278 if (*end_pos > _dbus_string_get_length (str))
1286 * If in verbose mode, print a block of binary data.
1288 * @todo right now it prints even if not in verbose mode
1290 * @param data the data
1291 * @param len the length of the data
1294 _dbus_verbose_bytes (const unsigned char *data,
1298 const unsigned char *aligned;
1300 _dbus_assert (len >= 0);
1302 /* Print blanks on first row if appropriate */
1303 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1306 _dbus_assert (aligned <= data);
1308 if (aligned != data)
1310 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1311 while (aligned != data)
1313 _dbus_verbose (" ");
1318 /* now print the bytes */
1322 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1324 _dbus_verbose ("%4d\t%p: ",
1328 if (data[i] >= 32 &&
1330 _dbus_verbose (" '%c' ", data[i]);
1332 _dbus_verbose ("0x%s%x ",
1333 data[i] <= 0xf ? "0" : "", data[i]);
1337 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1340 _dbus_verbose ("BE: %d LE: %d",
1341 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1342 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1345 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1347 _dbus_verbose (" dbl: %g",
1348 *(double*)&data[i-8]);
1351 _dbus_verbose ("\n");
1355 _dbus_verbose ("\n");
1359 * Dump the given part of the string to verbose log.
1361 * @param str the string
1362 * @param start the start of range to dump
1363 * @param len length of range
1366 _dbus_verbose_bytes_of_string (const DBusString *str,
1373 real_len = _dbus_string_get_length (str);
1375 _dbus_assert (start >= 0);
1377 if (start > real_len)
1379 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1380 start, len, real_len);
1384 if ((start + len) > real_len)
1386 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1387 start, len, real_len);
1388 len = real_len - start;
1392 _dbus_string_get_const_data_len (str, &d, start, len);
1394 _dbus_verbose_bytes (d, len);
1399 #ifdef DBUS_BUILD_TESTS
1400 #include "dbus-test.h"
1404 _dbus_marshal_test (void)
1408 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1411 if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1412 _dbus_assert_not_reached ("failed to init string");
1414 /* Marshal doubles */
1415 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1416 _dbus_assert_not_reached ("could not marshal double value");
1417 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1418 _dbus_assert_not_reached ("demarshal failed");
1420 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1421 _dbus_assert_not_reached ("could not marshal double value");
1422 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1423 _dbus_assert_not_reached ("demarshal failed");
1425 /* Marshal signed integers */
1426 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1427 _dbus_assert_not_reached ("could not marshal signed integer value");
1428 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1429 _dbus_assert_not_reached ("demarshal failed");
1431 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1432 _dbus_assert_not_reached ("could not marshal signed integer value");
1433 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1434 _dbus_assert_not_reached ("demarshal failed");
1436 /* Marshal unsigned integers */
1437 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1438 _dbus_assert_not_reached ("could not marshal signed integer value");
1439 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1440 _dbus_assert_not_reached ("demarshal failed");
1442 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1443 _dbus_assert_not_reached ("could not marshal signed integer value");
1444 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1445 _dbus_assert_not_reached ("demarshal failed");
1447 /* Marshal strings */
1448 tmp1 = "This is the dbus test string";
1449 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1450 _dbus_assert_not_reached ("could not marshal string");
1451 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1452 if (!strcmp (tmp1, tmp2) == 0)
1453 _dbus_assert_not_reached ("demarshal failed");
1456 tmp1 = "This is the dbus test string";
1457 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1458 _dbus_assert_not_reached ("could not marshal string");
1459 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1460 if (!strcmp (tmp1, tmp2) == 0)
1461 _dbus_assert_not_reached ("demarshal failed");
1464 /* Marshal signed integer arrays */
1465 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1466 _dbus_assert_not_reached ("could not marshal integer array");
1467 array2 = _dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &len);
1470 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1475 _dbus_string_free (&str);
1481 #endif /* DBUS_BUILD_TESTS */