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"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
33 swap_bytes (unsigned char *data,
36 unsigned char *p1 = data;
37 unsigned char *p2 = data + len - 1;
41 unsigned char tmp = *p1;
51 * @defgroup DBusMarshal marshaling and unmarshaling
52 * @ingroup DBusInternals
53 * @brief functions to marshal/unmarshal data from the wire
55 * Types and functions related to converting primitive data types from
56 * wire format to native machine format, and vice versa.
62 * Unpacks a 32 bit unsigned integer from a data pointer
64 * @param byte_order The byte order to use
65 * @param data the data pointer
66 * @returns the integer
69 _dbus_unpack_uint32 (int byte_order,
70 const unsigned char *data)
72 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
74 if (byte_order == DBUS_LITTLE_ENDIAN)
75 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
77 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
81 * Unpacks a 32 bit signed integer from a data pointer
83 * @param byte_order The byte order to use
84 * @param data the data pointer
85 * @returns the integer
88 _dbus_unpack_int32 (int byte_order,
89 const unsigned char *data)
91 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
93 if (byte_order == DBUS_LITTLE_ENDIAN)
94 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
96 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
100 * Packs a 32 bit unsigned integer into a data pointer.
102 * @param value the value
103 * @param byte_order the byte order to use
104 * @param data the data pointer
107 _dbus_pack_uint32 (dbus_uint32_t value,
111 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
113 if ((byte_order) == DBUS_LITTLE_ENDIAN)
114 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
116 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
120 * Packs a 32 bit signed integer into a data pointer.
122 * @param value the value
123 * @param byte_order the byte order to use
124 * @param data the data pointer
127 _dbus_pack_int32 (dbus_int32_t value,
131 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
133 if ((byte_order) == DBUS_LITTLE_ENDIAN)
134 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);
136 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
140 * Sets the 4 bytes at the given offset to a marshaled signed integer,
141 * replacing anything found there previously.
143 * @param str the string to write the marshalled int to
144 * @param offset the byte offset where int should be written
145 * @param byte_order the byte order to use
146 * @param value the value
150 _dbus_marshal_set_int32 (DBusString *str,
157 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
158 byte_order == DBUS_BIG_ENDIAN);
160 _dbus_string_get_data_len (str, &data, offset, 4);
162 _dbus_pack_int32 (value, byte_order, data);
166 * Sets the 4 bytes at the given offset to a marshaled unsigned
167 * integer, replacing anything found there previously.
169 * @param str the string to write the marshalled int to
170 * @param offset the byte offset where int should be written
171 * @param byte_order the byte order to use
172 * @param value the value
176 _dbus_marshal_set_uint32 (DBusString *str,
183 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
184 byte_order == DBUS_BIG_ENDIAN);
186 _dbus_string_get_data_len (str, &data, offset, 4);
188 _dbus_pack_uint32 (value, byte_order, data);
192 * Sets the existing marshaled string at the given offset with
193 * a new marshaled string. The given offset must point to
194 * an existing string or the wrong length will be deleted
195 * and replaced with the new string.
197 * @param str the string to write the marshalled string to
198 * @param offset the byte offset where string should be written
199 * @param byte_order the byte order to use
200 * @param value the value
201 * @returns #TRUE on success
205 _dbus_marshal_set_string (DBusString *str,
208 const DBusString *value)
213 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
214 byte_order == DBUS_BIG_ENDIAN);
216 old_len = _dbus_demarshal_uint32 (str, byte_order,
219 new_len = _dbus_string_get_length (value);
221 if (!_dbus_string_replace_len (value, 0, new_len,
222 str, offset + 4, old_len))
225 _dbus_marshal_set_uint32 (str, byte_order,
232 * Marshals a double value.
234 * @param str the string to append the marshalled value to
235 * @param byte_order the byte order to use
236 * @param value the value
237 * @returns #TRUE on success
240 _dbus_marshal_double (DBusString *str,
244 _dbus_assert (sizeof (double) == 8);
246 if (!_dbus_string_align_length (str, sizeof (double)))
249 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
250 swap_bytes ((unsigned char *)&value, sizeof (double));
252 return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
256 * Marshals a 32 bit signed integer value.
258 * @param str the string to append the marshalled value to
259 * @param byte_order the byte order to use
260 * @param value the value
261 * @returns #TRUE on success
264 _dbus_marshal_int32 (DBusString *str,
268 if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
271 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
272 value = DBUS_INT32_SWAP_LE_BE (value);
274 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
278 * Marshals a 32 bit unsigned integer value.
280 * @param str the string to append the marshalled value to
281 * @param byte_order the byte order to use
282 * @param value the value
283 * @returns #TRUE on success
286 _dbus_marshal_uint32 (DBusString *str,
290 if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
293 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
294 value = DBUS_UINT32_SWAP_LE_BE (value);
296 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
300 * Marshals a UTF-8 string
302 * @param str the string to append the marshalled value to
303 * @param byte_order the byte order to use
304 * @param value the string
305 * @returns #TRUE on success
308 _dbus_marshal_string (DBusString *str,
312 int len, old_string_len;
314 old_string_len = _dbus_string_get_length (str);
316 len = strlen (value);
318 if (!_dbus_marshal_uint32 (str, byte_order, len))
320 /* Restore the previous length */
321 _dbus_string_set_length (str, old_string_len);
326 return _dbus_string_append_len (str, value, len + 1);
330 * Marshals a byte array
332 * @param str the string to append the marshalled value to
333 * @param byte_order the byte order to use
334 * @param value the array
335 * @param len number of elements in the array
336 * @returns #TRUE on success
339 _dbus_marshal_byte_array (DBusString *str,
341 const unsigned char *value,
346 old_string_len = _dbus_string_get_length (str);
348 if (!_dbus_marshal_uint32 (str, byte_order, len))
350 /* Restore the previous length */
351 _dbus_string_set_length (str, old_string_len);
356 return _dbus_string_append_len (str, value, len);
360 * Marshals a 32 bit signed integer array
362 * @param str the string to append the marshalled value to
363 * @param byte_order the byte order to use
364 * @param value the array
365 * @param len the length of the array
366 * @returns #TRUE on success
369 _dbus_marshal_int32_array (DBusString *str,
371 const dbus_int32_t *value,
374 int i, old_string_len;
376 old_string_len = _dbus_string_get_length (str);
378 if (!_dbus_marshal_uint32 (str, byte_order, len))
381 for (i = 0; i < len; i++)
382 if (!_dbus_marshal_int32 (str, byte_order, value[i]))
388 /* Restore previous length */
389 _dbus_string_set_length (str, old_string_len);
395 * Marshals a 32 bit unsigned integer array
397 * @param str the string to append the marshalled value to
398 * @param byte_order the byte order to use
399 * @param value the array
400 * @param len the length of the array
401 * @returns #TRUE on success
404 _dbus_marshal_uint32_array (DBusString *str,
406 const dbus_uint32_t *value,
409 int i, old_string_len;
411 old_string_len = _dbus_string_get_length (str);
413 if (!_dbus_marshal_uint32 (str, byte_order, len))
416 for (i = 0; i < len; i++)
417 if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
423 /* Restore previous length */
424 _dbus_string_set_length (str, old_string_len);
430 * Marshals a double array
432 * @param str the string to append the marshalled value to
433 * @param byte_order the byte order to use
434 * @param value the array
435 * @param len the length of the array
436 * @returns #TRUE on success
439 _dbus_marshal_double_array (DBusString *str,
444 int i, old_string_len;
446 old_string_len = _dbus_string_get_length (str);
448 if (!_dbus_marshal_uint32 (str, byte_order, len))
451 for (i = 0; i < len; i++)
452 if (!_dbus_marshal_double (str, byte_order, value[i]))
458 /* Restore previous length */
459 _dbus_string_set_length (str, old_string_len);
465 * Marshals a string array
467 * @param str the string to append the marshalled value to
468 * @param byte_order the byte order to use
469 * @param value the array
470 * @param len the length of the array
471 * @returns #TRUE on success
474 _dbus_marshal_string_array (DBusString *str,
479 int i, old_string_len;
481 old_string_len = _dbus_string_get_length (str);
483 if (!_dbus_marshal_uint32 (str, byte_order, len))
486 for (i = 0; i < len; i++)
487 if (!_dbus_marshal_string (str, byte_order, value[i]))
493 /* Restore previous length */
494 _dbus_string_set_length (str, old_string_len);
500 * Demarshals a double.
502 * @param str the string containing the data
503 * @param byte_order the byte order
504 * @param pos the position in the string
505 * @param new_pos the new position of the string
506 * @returns the demarshaled double.
509 _dbus_demarshal_double (const DBusString *str,
517 pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
519 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
521 retval = *(double *)buffer;
523 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
524 swap_bytes ((unsigned char *)&retval, sizeof (double));
527 *new_pos = pos + sizeof (double);
533 * Demarshals a 32 bit signed integer.
535 * @param str the string containing the data
536 * @param byte_order the byte order
537 * @param pos the position in the string
538 * @param new_pos the new position of the string
539 * @returns the demarshaled integer.
542 _dbus_demarshal_int32 (const DBusString *str,
547 const DBusRealString *real = (const DBusRealString*) str;
549 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
552 *new_pos = pos + sizeof (dbus_int32_t);
554 if (byte_order == DBUS_LITTLE_ENDIAN)
555 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
557 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
561 * Demarshals a 32 bit unsigned integer.
563 * @param str the string containing the data
564 * @param byte_order the byte order
565 * @param pos the position in the string
566 * @param new_pos the new position of the string
567 * @returns the demarshaled integer.
570 _dbus_demarshal_uint32 (const DBusString *str,
575 const DBusRealString *real = (const DBusRealString*) str;
577 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
580 *new_pos = pos + sizeof (dbus_uint32_t);
582 if (byte_order == DBUS_LITTLE_ENDIAN)
583 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
585 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
589 * Demarshals an UTF-8 string.
591 * @todo Should we check the string to make sure
592 * that it's valid UTF-8, and maybe "fix" the string
595 * @todo Should probably demarshal to a DBusString,
596 * having memcpy() in here is Evil(tm).
598 * @param str the string containing the data
599 * @param byte_order the byte order
600 * @param pos the position in the string
601 * @param new_pos the new position of the string
602 * @returns the demarshaled string.
605 _dbus_demarshal_string (const DBusString *str,
614 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
616 retval = dbus_malloc (len + 1);
621 _dbus_string_get_const_data_len (str, &data, pos, len);
626 memcpy (retval, data, len + 1);
629 *new_pos = pos + len + 1;
635 * Demarshals a byte array.
637 * @todo Should probably demarshal to a DBusString,
638 * having memcpy() in here is Evil(tm).
640 * @param str the string containing the data
641 * @param byte_order the byte order
642 * @param pos the position in the string
643 * @param new_pos the new position of the string
644 * @param array_len length of the demarshaled data
645 * @returns the demarshaled data.
648 _dbus_demarshal_byte_array (const DBusString *str,
655 unsigned char *retval;
658 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
660 retval = dbus_malloc (len);
665 _dbus_string_get_const_data_len (str, &data, pos, len);
670 memcpy (retval, data, len);
673 *new_pos = pos + len;
682 * Demarshals a 32 bit signed integer array.
684 * @param str the string containing the data
685 * @param byte_order the byte order
686 * @param pos the position in the string
687 * @param new_pos the new position of the string
688 * @param array_len length of the demarshaled data
689 * @returns the demarshaled data.
692 _dbus_demarshal_int32_array (const DBusString *str,
699 dbus_int32_t *retval;
701 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
703 retval = dbus_new (dbus_int32_t, len);
708 for (i = 0; i < len; i++)
709 retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
721 * Demarshals a 32 bit unsigned integer array.
723 * @param str the string containing the data
724 * @param byte_order the byte order
725 * @param pos the position in the string
726 * @param new_pos the new position of the string
727 * @param array_len length of the demarshaled data
728 * @returns the demarshaled data.
731 _dbus_demarshal_uint32_array (const DBusString *str,
738 dbus_uint32_t *retval;
740 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
742 retval = dbus_new (dbus_uint32_t, len);
747 for (i = 0; i < len; i++)
748 retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
760 * Demarshals a double array.
762 * @param str the string containing the data
763 * @param byte_order the byte order
764 * @param pos the position in the string
765 * @param new_pos the new position of the string
766 * @param array_len length of the demarshaled data
767 * @returns the demarshaled data.
770 _dbus_demarshal_double_array (const DBusString *str,
779 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
781 retval = dbus_new (double, len);
786 for (i = 0; i < len; i++)
787 retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
799 * Demarshals a string array.
801 * @param str the string containing the data
802 * @param byte_order the byte order
803 * @param pos the position in the string
804 * @param new_pos the new position of the string
805 * @param array_len length of the demarshaled data
806 * @returns the demarshaled data.
809 _dbus_demarshal_string_array (const DBusString *str,
818 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
820 retval = dbus_new (char *, len + 1);
827 for (i = 0; i < len; i++)
829 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
844 for (j = 0; j < i; j++)
845 dbus_free (retval[i]);
852 * Returns the position right after the end of an argument. PERFORMS
853 * NO VALIDATION WHATSOEVER. The message must have been previously
856 * @param str a string
857 * @param byte_order the byte order to use
858 * @param pos the pos where the arg starts
859 * @param end_pos pointer where the position right
860 * after the end position will follow
861 * @returns TRUE if more data exists after the arg
864 _dbus_marshal_get_arg_end_pos (const DBusString *str,
871 if (pos >= _dbus_string_get_length (str))
874 _dbus_string_get_const_data_len (str, &data, pos, 1);
878 case DBUS_TYPE_INVALID:
886 case DBUS_TYPE_BOOLEAN:
890 case DBUS_TYPE_INT32:
891 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
895 case DBUS_TYPE_UINT32:
896 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
900 case DBUS_TYPE_DOUBLE:
901 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
905 case DBUS_TYPE_STRING:
909 /* Demarshal the length */
910 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
912 *end_pos = pos + len + 1;
916 case DBUS_TYPE_BOOLEAN_ARRAY:
917 case DBUS_TYPE_BYTE_ARRAY:
921 /* Demarshal the length */
922 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
924 *end_pos = pos + len;
928 case DBUS_TYPE_INT32_ARRAY:
932 /* Demarshal the length */
933 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
935 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
936 + (len * sizeof (dbus_int32_t));
940 case DBUS_TYPE_UINT32_ARRAY:
944 /* Demarshal the length */
945 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
947 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
948 + (len * sizeof (dbus_uint32_t));
952 case DBUS_TYPE_DOUBLE_ARRAY:
956 /* Demarshal the length */
957 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
959 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
960 + (len * sizeof (double));
964 case DBUS_TYPE_STRING_ARRAY:
968 /* Demarshal the length */
969 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
971 for (i = 0; i < len; i++)
975 /* Demarshal string length */
976 str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
985 _dbus_warn ("Unknown message arg type %d\n", *data);
986 _dbus_assert_not_reached ("Unknown message argument type\n");
990 if (*end_pos > _dbus_string_get_length (str))
997 * Demarshals and validates a length; returns < 0 if the validation
998 * fails. The length is required to be small enough that
999 * len*sizeof(double) will not overflow, and small enough to fit in a
1002 * @param str the string
1003 * @param byte_order the byte order
1004 * @param pos the unaligned string position (snap to next aligned)
1005 * @param new_pos return location for new position.
1008 demarshal_and_validate_len (const DBusString *str,
1013 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1016 if ((align_4 + 4) >= _dbus_string_get_length (str))
1018 _dbus_verbose ("not enough room in message for array length\n");
1022 if (!_dbus_string_validate_nul (str, pos,
1025 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1029 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1031 /* note that the len may be a number of doubles, so we need it to be
1032 * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1033 * sane. We end up using ints for most sizes to avoid unsigned mess
1034 * so limit to maximum 32-bit signed int divided by at least 8, more
1035 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1037 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1038 if (len > MAX_ARRAY_LENGTH)
1040 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1041 len, MAX_ARRAY_LENGTH);
1049 validate_string (const DBusString *str,
1051 int len_without_nul,
1054 *end_pos = pos + len_without_nul + 1;
1056 if (*end_pos > _dbus_string_get_length (str))
1058 _dbus_verbose ("string length outside length of the message\n");
1062 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1064 _dbus_verbose ("string arg not nul-terminated\n");
1068 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1070 _dbus_verbose ("string is not valid UTF-8\n");
1078 * Validates an argument, checking that it is well-formed, for example
1079 * no ludicrous length fields, strings are nul-terminated, etc.
1080 * Returns the end position of the argument in end_pos, and
1081 * returns #TRUE if a valid arg begins at "pos"
1083 * @todo security: need to audit this function.
1085 * @param str a string
1086 * @param byte_order the byte order to use
1087 * @param pos the pos where the arg starts (offset of its typecode)
1088 * @param end_pos pointer where the position right
1089 * after the end position will follow
1090 * @returns #TRUE if the arg is valid.
1093 _dbus_marshal_validate_arg (const DBusString *str,
1100 if (pos >= _dbus_string_get_length (str))
1103 _dbus_string_get_const_data_len (str, &data, pos, 1);
1107 case DBUS_TYPE_INVALID:
1115 case DBUS_TYPE_BOOLEAN:
1119 c = _dbus_string_get_byte (str, pos + 1);
1121 if (c != 0 && c != 1)
1123 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1130 case DBUS_TYPE_INT32:
1131 case DBUS_TYPE_UINT32:
1133 int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1135 if (!_dbus_string_validate_nul (str, pos + 1,
1138 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1142 *end_pos = align_4 + 4;
1146 case DBUS_TYPE_DOUBLE:
1148 int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1150 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1152 if (!_dbus_string_validate_nul (str, pos + 1,
1155 _dbus_verbose ("double alignment padding not initialized to nul\n");
1159 *end_pos = align_8 + 8;
1163 case DBUS_TYPE_STRING:
1167 /* Demarshal the length, which does NOT include
1170 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1174 if (!validate_string (str, pos, len, end_pos))
1179 case DBUS_TYPE_BOOLEAN_ARRAY:
1183 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1190 unsigned char c = _dbus_string_get_byte (str, pos + i);
1192 if (c != 0 && c != 1)
1194 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1200 *end_pos = pos + len;
1203 case DBUS_TYPE_BYTE_ARRAY:
1207 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1211 *end_pos = pos + len;
1215 case DBUS_TYPE_INT32_ARRAY:
1216 case DBUS_TYPE_UINT32_ARRAY:
1220 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1224 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1226 *end_pos = pos + len * 4;
1230 case DBUS_TYPE_DOUBLE_ARRAY:
1235 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1239 align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1240 if (!_dbus_string_validate_nul (str, pos,
1243 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1247 *end_pos = align_8 + len * 8;
1251 case DBUS_TYPE_STRING_ARRAY:
1256 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1260 for (i = 0; i < len; i++)
1264 str_len = demarshal_and_validate_len (str, byte_order,
1269 if (!validate_string (str, pos, str_len, &pos))
1278 _dbus_verbose ("Unknown message arg type %d\n", *data);
1282 if (*end_pos > _dbus_string_get_length (str))
1290 * If in verbose mode, print a block of binary data.
1292 * @todo right now it prints even if not in verbose mode
1294 * @param data the data
1295 * @param len the length of the data
1298 _dbus_verbose_bytes (const unsigned char *data,
1302 const unsigned char *aligned;
1304 _dbus_assert (len >= 0);
1306 /* Print blanks on first row if appropriate */
1307 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1310 _dbus_assert (aligned <= data);
1312 if (aligned != data)
1314 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1315 while (aligned != data)
1317 _dbus_verbose (" ");
1322 /* now print the bytes */
1326 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1328 _dbus_verbose ("%4d\t%p: ",
1332 if (data[i] >= 32 &&
1334 _dbus_verbose (" '%c' ", data[i]);
1336 _dbus_verbose ("0x%s%x ",
1337 data[i] <= 0xf ? "0" : "", data[i]);
1341 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1344 _dbus_verbose ("BE: %d LE: %d",
1345 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1346 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1349 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1351 _dbus_verbose (" dbl: %g",
1352 *(double*)&data[i-8]);
1355 _dbus_verbose ("\n");
1359 _dbus_verbose ("\n");
1363 * Dump the given part of the string to verbose log.
1365 * @param str the string
1366 * @param start the start of range to dump
1367 * @param len length of range
1370 _dbus_verbose_bytes_of_string (const DBusString *str,
1377 real_len = _dbus_string_get_length (str);
1379 _dbus_assert (start >= 0);
1381 if (start > real_len)
1383 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1384 start, len, real_len);
1388 if ((start + len) > real_len)
1390 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1391 start, len, real_len);
1392 len = real_len - start;
1396 _dbus_string_get_const_data_len (str, &d, start, len);
1398 _dbus_verbose_bytes (d, len);
1403 #ifdef DBUS_BUILD_TESTS
1404 #include "dbus-test.h"
1408 _dbus_marshal_test (void)
1412 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1415 if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1416 _dbus_assert_not_reached ("failed to init string");
1418 /* Marshal doubles */
1419 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1420 _dbus_assert_not_reached ("could not marshal double value");
1421 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1422 _dbus_assert_not_reached ("demarshal failed");
1424 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1425 _dbus_assert_not_reached ("could not marshal double value");
1426 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1427 _dbus_assert_not_reached ("demarshal failed");
1429 /* Marshal signed integers */
1430 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1431 _dbus_assert_not_reached ("could not marshal signed integer value");
1432 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1433 _dbus_assert_not_reached ("demarshal failed");
1435 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1436 _dbus_assert_not_reached ("could not marshal signed integer value");
1437 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1438 _dbus_assert_not_reached ("demarshal failed");
1440 /* Marshal unsigned integers */
1441 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1442 _dbus_assert_not_reached ("could not marshal signed integer value");
1443 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1444 _dbus_assert_not_reached ("demarshal failed");
1446 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1447 _dbus_assert_not_reached ("could not marshal signed integer value");
1448 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1449 _dbus_assert_not_reached ("demarshal failed");
1451 /* Marshal strings */
1452 tmp1 = "This is the dbus test string";
1453 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1454 _dbus_assert_not_reached ("could not marshal string");
1455 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1456 if (!strcmp (tmp1, tmp2) == 0)
1457 _dbus_assert_not_reached ("demarshal failed");
1460 tmp1 = "This is the dbus test string";
1461 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1462 _dbus_assert_not_reached ("could not marshal string");
1463 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1464 if (!strcmp (tmp1, tmp2) == 0)
1465 _dbus_assert_not_reached ("demarshal failed");
1468 /* Marshal signed integer arrays */
1469 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1470 _dbus_assert_not_reached ("could not marshal integer array");
1471 array2 = _dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &len);
1474 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1479 _dbus_string_free (&str);
1485 #endif /* DBUS_BUILD_TESTS */