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);
821 for (i = 0; i < len; i++)
823 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
838 for (j = 0; j < i; j++)
839 dbus_free (retval[i]);
846 * Returns the position right after the end of an argument. PERFORMS
847 * NO VALIDATION WHATSOEVER. The message must have been previously
850 * @param str a string
851 * @param byte_order the byte order to use
852 * @param pos the pos where the arg starts
853 * @param end_pos pointer where the position right
854 * after the end position will follow
855 * @returns TRUE if more data exists after the arg
858 _dbus_marshal_get_arg_end_pos (const DBusString *str,
865 if (pos >= _dbus_string_get_length (str))
868 _dbus_string_get_const_data_len (str, &data, pos, 1);
872 case DBUS_TYPE_INVALID:
880 case DBUS_TYPE_INT32:
881 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
885 case DBUS_TYPE_UINT32:
886 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
890 case DBUS_TYPE_DOUBLE:
891 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
895 case DBUS_TYPE_STRING:
899 /* Demarshal the length */
900 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
902 *end_pos = pos + len + 1;
906 case DBUS_TYPE_BYTE_ARRAY:
910 /* Demarshal the length */
911 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
913 *end_pos = pos + len;
917 case DBUS_TYPE_INT32_ARRAY:
921 /* Demarshal the length */
922 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
924 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
925 + (len * sizeof (dbus_int32_t));
929 case DBUS_TYPE_UINT32_ARRAY:
933 /* Demarshal the length */
934 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
936 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
937 + (len * sizeof (dbus_uint32_t));
941 case DBUS_TYPE_DOUBLE_ARRAY:
945 /* Demarshal the length */
946 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
948 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
949 + (len * sizeof (double));
953 case DBUS_TYPE_STRING_ARRAY:
957 /* Demarshal the length */
958 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
960 for (i = 0; i < len; i++)
964 /* Demarshal string length */
965 str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
974 _dbus_warn ("Unknown message arg type %d\n", *data);
975 _dbus_assert_not_reached ("Unknown message argument type\n");
979 if (*end_pos > _dbus_string_get_length (str))
986 * Demarshals and validates a length; returns < 0 if the validation
987 * fails. The length is required to be small enough that
988 * len*sizeof(double) will not overflow, and small enough to fit in a
991 * @param str the string
992 * @param byte_order the byte order
993 * @param pos the unaligned string position (snap to next aligned)
994 * @param new_pos return location for new position.
997 demarshal_and_validate_len (const DBusString *str,
1002 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1005 if ((align_4 + 4) >= _dbus_string_get_length (str))
1007 _dbus_verbose ("not enough room in message for array length\n");
1011 if (!_dbus_string_validate_nul (str, pos,
1014 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1018 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1020 /* note that the len may be a number of doubles, so we need it to be
1021 * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1022 * sane. We end up using ints for most sizes to avoid unsigned mess
1023 * so limit to maximum 32-bit signed int divided by at least 8, more
1024 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1026 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1027 if (len > MAX_ARRAY_LENGTH)
1029 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1030 len, MAX_ARRAY_LENGTH);
1038 validate_string (const DBusString *str,
1040 int len_without_nul,
1043 *end_pos = pos + len_without_nul + 1;
1045 if (*end_pos > _dbus_string_get_length (str))
1047 _dbus_verbose ("string length outside length of the message\n");
1051 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1053 _dbus_verbose ("string arg not nul-terminated\n");
1057 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1059 _dbus_verbose ("string is not valid UTF-8\n");
1067 * Validates an argument, checking that it is well-formed, for example
1068 * no ludicrous length fields, strings are nul-terminated, etc.
1069 * Returns the end position of the argument in end_pos, and
1070 * returns #TRUE if a valid arg begins at "pos"
1072 * @todo security: need to audit this function.
1074 * @param str a string
1075 * @param byte_order the byte order to use
1076 * @param pos the pos where the arg starts (offset of its typecode)
1077 * @param end_pos pointer where the position right
1078 * after the end position will follow
1079 * @returns #TRUE if the arg is valid.
1082 _dbus_marshal_validate_arg (const DBusString *str,
1089 if (pos >= _dbus_string_get_length (str))
1092 _dbus_string_get_const_data_len (str, &data, pos, 1);
1096 case DBUS_TYPE_INVALID:
1104 case DBUS_TYPE_INT32:
1105 case DBUS_TYPE_UINT32:
1107 int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1109 if (!_dbus_string_validate_nul (str, pos + 1,
1112 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1116 *end_pos = align_4 + 4;
1120 case DBUS_TYPE_DOUBLE:
1122 int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1124 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1126 if (!_dbus_string_validate_nul (str, pos + 1,
1129 _dbus_verbose ("double alignment padding not initialized to nul\n");
1133 *end_pos = align_8 + 8;
1137 case DBUS_TYPE_STRING:
1141 /* Demarshal the length, which does NOT include
1144 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1148 if (!validate_string (str, pos, len, end_pos))
1153 case DBUS_TYPE_BYTE_ARRAY:
1157 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1161 *end_pos = pos + len;
1165 case DBUS_TYPE_INT32_ARRAY:
1166 case DBUS_TYPE_UINT32_ARRAY:
1170 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1174 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1176 *end_pos = pos + len * 4;
1180 case DBUS_TYPE_DOUBLE_ARRAY:
1185 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1189 align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1190 if (!_dbus_string_validate_nul (str, pos,
1193 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1197 *end_pos = align_8 + len * 8;
1201 case DBUS_TYPE_STRING_ARRAY:
1206 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1210 for (i = 0; i < len; i++)
1214 str_len = demarshal_and_validate_len (str, byte_order,
1219 if (!validate_string (str, pos, str_len, &pos))
1228 _dbus_verbose ("Unknown message arg type %d\n", *data);
1232 if (*end_pos > _dbus_string_get_length (str))
1240 * If in verbose mode, print a block of binary data.
1242 * @todo right now it prints even if not in verbose mode
1244 * @param data the data
1245 * @param len the length of the data
1248 _dbus_verbose_bytes (const unsigned char *data,
1252 const unsigned char *aligned;
1254 _dbus_assert (len >= 0);
1256 /* Print blanks on first row if appropriate */
1257 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1260 _dbus_assert (aligned <= data);
1262 if (aligned != data)
1264 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1265 while (aligned != data)
1267 _dbus_verbose (" ");
1272 /* now print the bytes */
1276 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1278 _dbus_verbose ("%4d\t%p: ",
1282 if (data[i] >= 32 &&
1284 _dbus_verbose (" '%c' ", data[i]);
1286 _dbus_verbose ("0x%s%x ",
1287 data[i] <= 0xf ? "0" : "", data[i]);
1291 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1294 _dbus_verbose ("BE: %d LE: %d",
1295 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1296 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1299 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1301 _dbus_verbose (" dbl: %g",
1302 *(double*)&data[i-8]);
1305 _dbus_verbose ("\n");
1309 _dbus_verbose ("\n");
1313 * Dump the given part of the string to verbose log.
1315 * @param str the string
1316 * @param start the start of range to dump
1317 * @param len length of range
1320 _dbus_verbose_bytes_of_string (const DBusString *str,
1327 real_len = _dbus_string_get_length (str);
1329 _dbus_assert (start >= 0);
1331 if (start > real_len)
1333 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1334 start, len, real_len);
1338 if ((start + len) > real_len)
1340 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1341 start, len, real_len);
1342 len = real_len - start;
1346 _dbus_string_get_const_data_len (str, &d, start, len);
1348 _dbus_verbose_bytes (d, len);
1353 #ifdef DBUS_BUILD_TESTS
1354 #include "dbus-test.h"
1358 _dbus_marshal_test (void)
1362 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1365 if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1366 _dbus_assert_not_reached ("failed to init string");
1368 /* Marshal doubles */
1369 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1370 _dbus_assert_not_reached ("could not marshal double value");
1371 _dbus_assert (_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14);
1373 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1374 _dbus_assert_not_reached ("could not marshal double value");
1375 _dbus_assert (_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14);
1377 /* Marshal signed integers */
1378 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1379 _dbus_assert_not_reached ("could not marshal signed integer value");
1380 _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678);
1382 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1383 _dbus_assert_not_reached ("could not marshal signed integer value");
1384 _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678);
1386 /* Marshal unsigned integers */
1387 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1388 _dbus_assert_not_reached ("could not marshal signed integer value");
1389 _dbus_assert (_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678);
1391 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1392 _dbus_assert_not_reached ("could not marshal signed integer value");
1393 _dbus_assert (_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678);
1395 /* Marshal strings */
1396 tmp1 = "This is the dbus test string";
1397 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1398 _dbus_assert_not_reached ("could not marshal string");
1399 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1400 _dbus_assert (strcmp (tmp1, tmp2) == 0);
1403 tmp1 = "This is the dbus test string";
1404 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1405 _dbus_assert_not_reached ("could not marshal string");
1406 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1407 _dbus_assert (strcmp (tmp1, tmp2) == 0);
1410 /* Marshal signed integer arrays */
1411 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1412 _dbus_assert_not_reached ("could not marshal integer array");
1413 array2 = _dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &len);
1416 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1421 _dbus_string_free (&str);
1427 #endif /* DBUS_BUILD_TESTS */