1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-basic.c Marshalling routines for basic (primitive) types
4 * Copyright (C) 2002 CodeFactory AB
5 * Copyright (C) 2003, 2004 Red Hat, Inc.
7 * Licensed under the Academic Free License version 2.1
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-internals.h"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
29 #include "dbus-marshal-basic.h"
34 * @defgroup DBusMarshal marshaling and unmarshaling
35 * @ingroup DBusInternals
36 * @brief functions to marshal/unmarshal data from the wire
38 * Types and functions related to converting primitive data types from
39 * wire format to native machine format, and vice versa.
41 * A signature is just a string with multiple types one after the other.
42 * for example a type is "i" or "(ii)", a signature is "i(ii)"
43 * where i is int and (ii) is struct { int; int; }
49 unpack_4_octets (int byte_order,
50 const unsigned char *data)
52 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
54 if (byte_order == DBUS_LITTLE_ENDIAN)
55 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
57 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
60 #ifndef DBUS_HAVE_INT64
63 swap_bytes (unsigned char *data,
66 unsigned char *p1 = data;
67 unsigned char *p2 = data + len - 1;
71 unsigned char tmp = *p1;
79 #endif /* !DBUS_HAVE_INT64 */
82 * Union used to manipulate 8 bytes as if they
87 #ifdef DBUS_HAVE_INT64
88 dbus_int64_t s; /**< 64-bit integer */
89 dbus_uint64_t u; /**< 64-bit unsigned integer */
91 double d; /**< double */
95 unpack_8_octets (int byte_order,
96 const unsigned char *data)
100 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
101 _dbus_assert (sizeof (r) == 8);
103 #ifdef DBUS_HAVE_INT64
104 if (byte_order == DBUS_LITTLE_ENDIAN)
105 r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
107 r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
109 r.d = *(double*)data;
110 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
111 swap_bytes ((unsigned char*) &r, sizeof (r));
118 * Unpacks a 32 bit unsigned integer from a data pointer
120 * @param byte_order The byte order to use
121 * @param data the data pointer
122 * @returns the integer
125 _dbus_unpack_uint32 (int byte_order,
126 const unsigned char *data)
128 return unpack_4_octets (byte_order, data);
132 * Unpacks a 32 bit signed integer from a data pointer
134 * @param byte_order The byte order to use
135 * @param data the data pointer
136 * @returns the integer
139 _dbus_unpack_int32 (int byte_order,
140 const unsigned char *data)
142 return (dbus_int32_t) unpack_4_octets (byte_order, data);
145 #ifdef DBUS_HAVE_INT64
147 * Unpacks a 64 bit unsigned integer from a data pointer
149 * @param byte_order The byte order to use
150 * @param data the data pointer
151 * @returns the integer
154 _dbus_unpack_uint64 (int byte_order,
155 const unsigned char *data)
159 r = unpack_8_octets (byte_order, data);
165 * Unpacks a 64 bit signed integer from a data pointer
167 * @param byte_order The byte order to use
168 * @param data the data pointer
169 * @returns the integer
172 _dbus_unpack_int64 (int byte_order,
173 const unsigned char *data)
177 r = unpack_8_octets (byte_order, data);
182 #endif /* DBUS_HAVE_INT64 */
185 pack_4_octets (dbus_uint32_t value,
189 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
191 if ((byte_order) == DBUS_LITTLE_ENDIAN)
192 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
194 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
198 pack_8_octets (DBusOctets8 value,
202 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
204 #ifdef DBUS_HAVE_INT64
205 if ((byte_order) == DBUS_LITTLE_ENDIAN)
206 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
208 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
210 memcpy (data, &value, 8);
211 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
212 swap_bytes ((unsigned char *)data, 8);
217 * Packs a 32 bit unsigned integer into a data pointer.
219 * @param value the value
220 * @param byte_order the byte order to use
221 * @param data the data pointer
224 _dbus_pack_uint32 (dbus_uint32_t value,
228 pack_4_octets (value, byte_order, data);
232 * Packs a 32 bit signed integer into a data pointer.
234 * @param value the value
235 * @param byte_order the byte order to use
236 * @param data the data pointer
239 _dbus_pack_int32 (dbus_int32_t value,
243 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
246 #ifdef DBUS_HAVE_INT64
248 * Packs a 64 bit unsigned integer into a data pointer.
250 * @param value the value
251 * @param byte_order the byte order to use
252 * @param data the data pointer
255 _dbus_pack_uint64 (dbus_uint64_t value,
261 pack_8_octets (r, byte_order, data);
265 * Packs a 64 bit signed integer into a data pointer.
267 * @param value the value
268 * @param byte_order the byte order to use
269 * @param data the data pointer
272 _dbus_pack_int64 (dbus_int64_t value,
278 pack_8_octets (r, byte_order, data);
280 #endif /* DBUS_HAVE_INT64 */
283 set_4_octets (DBusString *str,
290 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
291 byte_order == DBUS_BIG_ENDIAN);
293 data = _dbus_string_get_data_len (str, offset, 4);
295 _dbus_pack_uint32 (value, byte_order, data);
299 set_8_octets (DBusString *str,
306 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
307 byte_order == DBUS_BIG_ENDIAN);
309 data = _dbus_string_get_data_len (str, offset, 8);
311 pack_8_octets (value, byte_order, data);
315 * Sets the 4 bytes at the given offset to a marshaled signed integer,
316 * replacing anything found there previously.
318 * @param str the string to write the marshalled int to
319 * @param offset the byte offset where int should be written
320 * @param byte_order the byte order to use
321 * @param value the value
325 _dbus_marshal_set_int32 (DBusString *str,
330 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
334 * Sets the 4 bytes at the given offset to a marshaled unsigned
335 * integer, replacing anything found there previously.
337 * @param str the string to write the marshalled int to
338 * @param offset the byte offset where int should be written
339 * @param byte_order the byte order to use
340 * @param value the value
344 _dbus_marshal_set_uint32 (DBusString *str,
349 set_4_octets (str, byte_order, offset, value);
352 #ifdef DBUS_HAVE_INT64
355 * Sets the 8 bytes at the given offset to a marshaled signed integer,
356 * replacing anything found there previously.
358 * @param str the string to write the marshalled int to
359 * @param offset the byte offset where int should be written
360 * @param byte_order the byte order to use
361 * @param value the value
365 _dbus_marshal_set_int64 (DBusString *str,
372 set_8_octets (str, byte_order, offset, r);
376 * Sets the 8 bytes at the given offset to a marshaled unsigned
377 * integer, replacing anything found there previously.
379 * @param str the string to write the marshalled int to
380 * @param offset the byte offset where int should be written
381 * @param byte_order the byte order to use
382 * @param value the value
386 _dbus_marshal_set_uint64 (DBusString *str,
393 set_8_octets (str, byte_order, offset, r);
395 #endif /* DBUS_HAVE_INT64 */
398 * Sets the existing marshaled string at the given offset with
399 * a new marshaled string. The given offset must point to
400 * an existing string or the wrong length will be deleted
401 * and replaced with the new string.
403 * Note: no attempt is made by this function to re-align
404 * any data which has been already marshalled after this
405 * string. Use with caution.
407 * @param str the string to write the marshalled string to
408 * @param offset the byte offset where string should be written
409 * @param byte_order the byte order to use
410 * @param value the value
411 * @param len the length to use
412 * @returns #TRUE on success
416 _dbus_marshal_set_string (DBusString *str,
419 const DBusString *value,
424 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
425 byte_order == DBUS_BIG_ENDIAN);
427 old_len = _dbus_demarshal_uint32 (str, byte_order,
430 if (!_dbus_string_replace_len (value, 0, len,
431 str, offset + 4, old_len))
434 _dbus_marshal_set_uint32 (str, byte_order,
441 * Sets the existing marshaled object path at the given offset to a new
442 * value. The given offset must point to an existing object path or this
443 * function doesn't make sense.
445 * @todo implement this function
447 * @param str the string to write the marshalled path to
448 * @param offset the byte offset where path should be written
449 * @param byte_order the byte order to use
450 * @param path the new path
451 * @param path_len number of elements in the path
454 _dbus_marshal_set_object_path (DBusString *str,
465 marshal_4_octets (DBusString *str,
470 _dbus_assert (sizeof (value) == 4);
472 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
473 value = DBUS_UINT32_SWAP_LE_BE (value);
475 return _dbus_string_insert_4_aligned (str, insert_at,
476 (const unsigned char *)&value);
480 marshal_8_octets (DBusString *str,
485 _dbus_assert (sizeof (value) == 8);
487 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
488 pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
490 return _dbus_string_insert_8_aligned (str, insert_at,
491 (const unsigned char *)&value);
495 * Marshals a double value.
497 * @param str the string to append the marshalled value to
498 * @param byte_order the byte order to use
499 * @param value the value
500 * @returns #TRUE on success
503 _dbus_marshal_double (DBusString *str,
509 return marshal_8_octets (str, _dbus_string_get_length (str),
514 * Marshals a 32 bit signed integer value.
516 * @param str the string to append the marshalled value to
517 * @param byte_order the byte order to use
518 * @param value the value
519 * @returns #TRUE on success
522 _dbus_marshal_int32 (DBusString *str,
526 return marshal_4_octets (str, _dbus_string_get_length (str),
527 byte_order, (dbus_uint32_t) value);
531 * Marshals a 32 bit unsigned integer value.
533 * @param str the string to append the marshalled value to
534 * @param byte_order the byte order to use
535 * @param value the value
536 * @returns #TRUE on success
539 _dbus_marshal_uint32 (DBusString *str,
543 return marshal_4_octets (str, _dbus_string_get_length (str),
548 #ifdef DBUS_HAVE_INT64
550 * Marshals a 64 bit signed integer value.
552 * @param str the string to append the marshalled value to
553 * @param byte_order the byte order to use
554 * @param value the value
555 * @returns #TRUE on success
558 _dbus_marshal_int64 (DBusString *str,
564 return marshal_8_octets (str, _dbus_string_get_length (str),
569 * Marshals a 64 bit unsigned integer value.
571 * @param str the string to append the marshalled value to
572 * @param byte_order the byte order to use
573 * @param value the value
574 * @returns #TRUE on success
577 _dbus_marshal_uint64 (DBusString *str,
583 return marshal_8_octets (str, _dbus_string_get_length (str),
587 #endif /* DBUS_HAVE_INT64 */
590 * Marshals a UTF-8 string
592 * @todo: If the string append fails we need to restore
593 * the old length. (also for other marshallers)
595 * @param str the string to append the marshalled value to
596 * @param byte_order the byte order to use
597 * @param value the string
598 * @returns #TRUE on success
601 _dbus_marshal_string (DBusString *str,
605 int len, old_string_len;
607 old_string_len = _dbus_string_get_length (str);
609 len = strlen (value);
611 if (!_dbus_marshal_uint32 (str, byte_order, len))
613 /* Restore the previous length */
614 _dbus_string_set_length (str, old_string_len);
619 return _dbus_string_append_len (str, value, len + 1);
623 * Marshals a UTF-8 string
625 * @todo: If the string append fails we need to restore
626 * the old length. (also for other marshallers)
628 * @param str the string to append the marshalled value to
629 * @param byte_order the byte order to use
630 * @param value the string
631 * @param len length of string to marshal in bytes
632 * @returns #TRUE on success
635 _dbus_marshal_string_len (DBusString *str,
642 old_string_len = _dbus_string_get_length (str);
644 if (!_dbus_marshal_uint32 (str, byte_order, len))
646 /* Restore the previous length */
647 _dbus_string_set_length (str, old_string_len);
652 if (!_dbus_string_append_len (str, value, len))
656 if (!_dbus_string_lengthen (str, 1))
663 * Marshals a byte array
665 * @param str the string to append the marshalled value to
666 * @param byte_order the byte order to use
667 * @param value the array
668 * @param len number of elements in the array
669 * @returns #TRUE on success
672 _dbus_marshal_byte_array (DBusString *str,
674 const unsigned char *value,
679 old_string_len = _dbus_string_get_length (str);
681 if (!_dbus_marshal_uint32 (str, byte_order, len))
683 /* Restore the previous length */
684 _dbus_string_set_length (str, old_string_len);
692 return _dbus_string_append_len (str, value, len);
696 marshal_4_octets_array (DBusString *str,
698 const dbus_uint32_t *value,
704 old_string_len = _dbus_string_get_length (str);
706 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
709 array_start = _dbus_string_get_length (str);
711 if (!_dbus_string_append_len (str, (const unsigned char*) value,
715 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
717 const unsigned char *d;
718 const unsigned char *end;
720 d = _dbus_string_get_data (str) + array_start;
724 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
732 /* Restore previous length */
733 _dbus_string_set_length (str, old_string_len);
739 marshal_8_octets_array (DBusString *str,
741 const DBusOctets8 *value,
747 old_string_len = _dbus_string_get_length (str);
749 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
752 array_start = _dbus_string_get_length (str);
754 if (!_dbus_string_append_len (str, (const unsigned char*) value,
758 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
760 const unsigned char *d;
761 const unsigned char *end;
763 d = _dbus_string_get_data (str) + array_start;
767 #ifdef DBUS_HAVE_INT64
768 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
770 swap_bytes ((unsigned char*) d, 8);
779 /* Restore previous length */
780 _dbus_string_set_length (str, old_string_len);
786 * Marshals a 32 bit signed integer array
788 * @param str the string to append the marshalled value to
789 * @param byte_order the byte order to use
790 * @param value the array
791 * @param len the length of the array
792 * @returns #TRUE on success
795 _dbus_marshal_int32_array (DBusString *str,
797 const dbus_int32_t *value,
800 return marshal_4_octets_array (str, byte_order,
801 (const dbus_uint32_t*) value,
806 * Marshals a 32 bit unsigned integer array
808 * @param str the string to append the marshalled value to
809 * @param byte_order the byte order to use
810 * @param value the array
811 * @param len the length of the array
812 * @returns #TRUE on success
815 _dbus_marshal_uint32_array (DBusString *str,
817 const dbus_uint32_t *value,
820 return marshal_4_octets_array (str, byte_order,
825 #ifdef DBUS_HAVE_INT64
828 * Marshals a 64 bit signed integer array
830 * @param str the string to append the marshalled value to
831 * @param byte_order the byte order to use
832 * @param value the array
833 * @param len the length of the array
834 * @returns #TRUE on success
837 _dbus_marshal_int64_array (DBusString *str,
839 const dbus_int64_t *value,
842 return marshal_8_octets_array (str, byte_order,
843 (const DBusOctets8*) value,
848 * Marshals a 64 bit unsigned integer array
850 * @param str the string to append the marshalled value to
851 * @param byte_order the byte order to use
852 * @param value the array
853 * @param len the length of the array
854 * @returns #TRUE on success
857 _dbus_marshal_uint64_array (DBusString *str,
859 const dbus_uint64_t *value,
862 return marshal_8_octets_array (str, byte_order,
863 (const DBusOctets8*) value,
867 #endif /* DBUS_HAVE_INT64 */
870 * Marshals a double array
872 * @param str the string to append the marshalled value to
873 * @param byte_order the byte order to use
874 * @param value the array
875 * @param len the length of the array
876 * @returns #TRUE on success
879 _dbus_marshal_double_array (DBusString *str,
884 return marshal_8_octets_array (str, byte_order,
885 (const DBusOctets8*) value,
890 * Marshals a string array
892 * @param str the string to append the marshalled value to
893 * @param byte_order the byte order to use
894 * @param value the array
895 * @param len the length of the array
896 * @returns #TRUE on success
899 _dbus_marshal_string_array (DBusString *str,
904 int i, old_string_len, array_start;
906 old_string_len = _dbus_string_get_length (str);
908 /* Set the length to 0 temporarily */
909 if (!_dbus_marshal_uint32 (str, byte_order, 0))
912 array_start = _dbus_string_get_length (str);
914 for (i = 0; i < len; i++)
915 if (!_dbus_marshal_string (str, byte_order, value[i]))
918 /* Write the length now that we know it */
919 _dbus_marshal_set_uint32 (str, byte_order,
920 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
921 _dbus_string_get_length (str) - array_start);
926 /* Restore previous length */
927 _dbus_string_set_length (str, old_string_len);
933 * Marshals an object path value.
935 * @param str the string to append the marshalled value to
936 * @param byte_order the byte order to use
937 * @param path the path
938 * @param path_len length of the path
939 * @returns #TRUE on success
942 _dbus_marshal_object_path (DBusString *str,
947 int array_start, old_string_len;
950 old_string_len = _dbus_string_get_length (str);
952 /* Set the length to 0 temporarily */
953 if (!_dbus_marshal_uint32 (str, byte_order, 0))
956 array_start = _dbus_string_get_length (str);
961 if (!_dbus_string_append_byte (str, '/'))
964 if (!_dbus_string_append (str, path[0]))
970 /* Write the length now that we know it */
971 _dbus_marshal_set_uint32 (str, byte_order,
972 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
973 _dbus_string_get_length (str) - array_start);
978 /* Restore the previous length */
979 _dbus_string_set_length (str, old_string_len);
985 demarshal_4_octets (const DBusString *str,
990 const DBusRealString *real = (const DBusRealString*) str;
992 pos = _DBUS_ALIGN_VALUE (pos, 4);
997 return unpack_4_octets (byte_order, real->str + pos);
1001 demarshal_8_octets (const DBusString *str,
1006 const DBusRealString *real = (const DBusRealString*) str;
1008 pos = _DBUS_ALIGN_VALUE (pos, 8);
1013 return unpack_8_octets (byte_order, real->str + pos);
1017 * Demarshals a double.
1019 * @param str the string containing the data
1020 * @param byte_order the byte order
1021 * @param pos the position in the string
1022 * @param new_pos the new position of the string
1023 * @returns the demarshaled double.
1026 _dbus_demarshal_double (const DBusString *str,
1033 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1039 * Demarshals a 32 bit signed integer.
1041 * @param str the string containing the data
1042 * @param byte_order the byte order
1043 * @param pos the position in the string
1044 * @param new_pos the new position of the string
1045 * @returns the demarshaled integer.
1048 _dbus_demarshal_int32 (const DBusString *str,
1053 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
1057 * Demarshals a 32 bit unsigned integer.
1059 * @param str the string containing the data
1060 * @param byte_order the byte order
1061 * @param pos the position in the string
1062 * @param new_pos the new position of the string
1063 * @returns the demarshaled integer.
1066 _dbus_demarshal_uint32 (const DBusString *str,
1071 return demarshal_4_octets (str, byte_order, pos, new_pos);
1074 #ifdef DBUS_HAVE_INT64
1077 * Demarshals a 64 bit signed integer.
1079 * @param str the string containing the data
1080 * @param byte_order the byte order
1081 * @param pos the position in the string
1082 * @param new_pos the new position of the string
1083 * @returns the demarshaled integer.
1086 _dbus_demarshal_int64 (const DBusString *str,
1093 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1099 * Demarshals a 64 bit unsigned integer.
1101 * @param str the string containing the data
1102 * @param byte_order the byte order
1103 * @param pos the position in the string
1104 * @param new_pos the new position of the string
1105 * @returns the demarshaled integer.
1108 _dbus_demarshal_uint64 (const DBusString *str,
1115 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1120 #endif /* DBUS_HAVE_INT64 */
1123 * Demarshals a basic type
1125 * @param str the string containing the data
1126 * @param type type of value to demarshal
1127 * @param value pointer to return value data
1128 * @param byte_order the byte order
1129 * @param pos pointer to position in the string,
1130 * updated on return to new position
1133 _dbus_demarshal_basic_type (const DBusString *str,
1139 const char *str_data = _dbus_string_get_const_data (str);
1143 case DBUS_TYPE_BYTE:
1144 case DBUS_TYPE_BOOLEAN:
1145 *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
1148 case DBUS_TYPE_INT32:
1149 case DBUS_TYPE_UINT32:
1150 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1151 *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
1152 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1153 *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
1156 #ifdef DBUS_HAVE_INT64
1157 case DBUS_TYPE_INT64:
1158 case DBUS_TYPE_UINT64:
1159 #endif /* DBUS_HAVE_INT64 */
1160 case DBUS_TYPE_DOUBLE:
1161 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1162 memcpy (value, str_data + *pos, 8);
1163 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1164 #ifdef DBUS_HAVE_INT64
1165 *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
1167 swap_bytes (value, 8);
1171 case DBUS_TYPE_STRING:
1172 _dbus_assert_not_reached ("FIXME string is a basic type");
1174 case DBUS_TYPE_OBJECT_PATH:
1175 _dbus_assert_not_reached ("FIXME object path is a basic type");
1178 _dbus_verbose ("type %s not a basic type\n",
1179 _dbus_type_to_string (type));
1180 _dbus_assert_not_reached ("not a basic type");
1186 * Demarshals an UTF-8 string.
1188 * @todo Should we check the string to make sure
1189 * that it's valid UTF-8, and maybe "fix" the string
1192 * @todo Should probably demarshal to a DBusString,
1193 * having memcpy() in here is Evil(tm).
1195 * @param str the string containing the data
1196 * @param byte_order the byte order
1197 * @param pos the position in the string
1198 * @param new_pos the new position of the string
1199 * @returns the demarshaled string.
1202 _dbus_demarshal_string (const DBusString *str,
1211 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1213 retval = dbus_malloc (len + 1);
1218 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1223 memcpy (retval, data, len + 1);
1226 *new_pos = pos + len + 1;
1232 * Demarshals a byte array.
1234 * @todo Should probably demarshal to a DBusString,
1235 * having memcpy() in here is Evil(tm).
1237 * @param str the string containing the data
1238 * @param byte_order the byte order
1239 * @param pos the position in the string
1240 * @param new_pos the new position of the string
1241 * @param array the array
1242 * @param array_len length of the demarshaled data
1244 * @returns #TRUE on success
1247 _dbus_demarshal_byte_array (const DBusString *str,
1251 unsigned char **array,
1255 unsigned char *retval;
1258 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1271 retval = dbus_malloc (len);
1276 data = _dbus_string_get_const_data_len (str, pos, len);
1284 memcpy (retval, data, len);
1287 *new_pos = pos + len;
1296 demarshal_4_octets_array (const DBusString *str,
1300 dbus_uint32_t **array,
1304 dbus_uint32_t *retval;
1307 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1321 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1325 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1327 for (i = 0; i < len; i++)
1328 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1332 *new_pos = pos + byte_len;
1341 demarshal_8_octets_array (const DBusString *str,
1345 DBusOctets8 **array,
1349 DBusOctets8 *retval;
1352 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1366 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1370 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1372 for (i = 0; i < len; i++)
1374 #ifdef DBUS_HAVE_INT64
1375 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1377 swap_bytes ((unsigned char *) &retval[i], 8);
1383 *new_pos = pos + byte_len;
1392 * Demarshals a 32 bit signed integer array.
1394 * @param str the string containing the data
1395 * @param byte_order the byte order
1396 * @param pos the position in the string
1397 * @param new_pos the new position of the string
1398 * @param array the array
1399 * @param array_len length of the demarshaled data
1400 * @returns #TRUE on success
1403 _dbus_demarshal_int32_array (const DBusString *str,
1407 dbus_int32_t **array,
1410 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1411 (dbus_uint32_t**) array, array_len);
1415 * Demarshals a 32 bit unsigned integer array.
1417 * @param str the string containing the data
1418 * @param byte_order the byte order
1419 * @param pos the position in the string
1420 * @param new_pos the new position of the string
1421 * @param array the array
1422 * @param array_len length of the demarshaled data
1423 * @returns #TRUE on success
1426 _dbus_demarshal_uint32_array (const DBusString *str,
1430 dbus_uint32_t **array,
1433 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1437 #ifdef DBUS_HAVE_INT64
1440 * Demarshals a 64 bit signed integer array.
1442 * @param str the string containing the data
1443 * @param byte_order the byte order
1444 * @param pos the position in the string
1445 * @param new_pos the new position of the string
1446 * @param array the array
1447 * @param array_len length of the demarshaled data
1448 * @returns #TRUE on success
1451 _dbus_demarshal_int64_array (const DBusString *str,
1455 dbus_int64_t **array,
1458 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1459 (DBusOctets8**) array, array_len);
1463 * Demarshals a 64 bit unsigned integer array.
1465 * @param str the string containing the data
1466 * @param byte_order the byte order
1467 * @param pos the position in the string
1468 * @param new_pos the new position of the string
1469 * @param array the array
1470 * @param array_len length of the demarshaled data
1471 * @returns #TRUE on success
1474 _dbus_demarshal_uint64_array (const DBusString *str,
1478 dbus_uint64_t **array,
1481 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1482 (DBusOctets8**) array, array_len);
1485 #endif /* DBUS_HAVE_INT64 */
1488 * Demarshals a double array.
1490 * @param str the string containing the data
1491 * @param byte_order the byte order
1492 * @param pos the position in the string
1493 * @param new_pos the new position of the string
1494 * @param array the array
1495 * @param array_len length of the demarshaled data
1496 * @returns #TRUE on success
1499 _dbus_demarshal_double_array (const DBusString *str,
1506 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1507 (DBusOctets8**) array, array_len);
1512 * Demarshals an array of basic types
1514 * @param str the string containing the data
1515 * @param element_type type of array elements to demarshal
1516 * @param array pointer to pointer to array data
1517 * @param array_len pointer to array length
1518 * @param byte_order the byte order
1519 * @param pos pointer to position in the string,
1520 * updated on return to new position
1523 _dbus_demarshal_basic_type_array (const DBusString *str,
1530 switch (element_type)
1532 case DBUS_TYPE_BOOLEAN:
1533 /* FIXME: do we want to post-normalize these ? */
1534 case DBUS_TYPE_BYTE:
1535 return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
1536 (unsigned char **)array, array_len);
1538 case DBUS_TYPE_INT32:
1539 case DBUS_TYPE_UINT32:
1540 return demarshal_4_octets_array (str, byte_order, *pos, pos,
1541 (dbus_uint32_t **)array, array_len);
1543 #ifdef DBUS_HAVE_INT64
1544 case DBUS_TYPE_INT64:
1545 case DBUS_TYPE_UINT64:
1546 #endif /* DBUS_HAVE_INT64 */
1547 case DBUS_TYPE_DOUBLE:
1548 return demarshal_8_octets_array (str, byte_order, *pos, pos,
1549 (DBusOctets8**) array, array_len);
1551 _dbus_assert_not_reached ("not a basic type");
1558 * Demarshals a string array.
1560 * @param str the string containing the data
1561 * @param byte_order the byte order
1562 * @param pos the position in the string
1563 * @param new_pos the new position of the string
1564 * @param array the array
1565 * @param array_len location for length of the demarshaled data or NULL
1566 * @returns #TRUE on success
1569 _dbus_demarshal_string_array (const DBusString *str,
1581 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1596 end_pos = pos + bytes_len;
1598 retval = dbus_new (char *, allocated);
1603 while (pos < end_pos)
1605 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1607 if (retval[len] == NULL)
1612 if (len >= allocated - 1) /* -1 for NULL termination */
1615 newp = dbus_realloc (retval,
1616 sizeof (char*) * allocated * 2);
1636 for (i = 0; i < len; i++)
1637 dbus_free (retval[i]);
1643 /** Set to 1 to get a bunch of spew about disassembling the path string */
1644 #define VERBOSE_DECOMPOSE 0
1647 * Decompose an object path. A path of just "/" is
1648 * represented as an empty vector of strings.
1650 * @param data the path data
1651 * @param len the length of the path string
1652 * @param path address to store new object path
1653 * @param path_len length of stored path
1656 _dbus_decompose_path (const char* data,
1665 _dbus_assert (data != NULL);
1667 #if VERBOSE_DECOMPOSE
1668 _dbus_verbose ("Decomposing path \"%s\"\n",
1681 retval = dbus_new0 (char*, n_components + 1);
1694 while (j < len && data[j] != '/')
1697 /* Now [i, j) is the path component */
1698 _dbus_assert (i < j);
1699 _dbus_assert (data[i] != '/');
1700 _dbus_assert (j == len || data[j] == '/');
1702 #if VERBOSE_DECOMPOSE
1703 _dbus_verbose (" (component in [%d,%d))\n",
1707 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1708 if (retval[comp] == NULL)
1710 dbus_free_string_array (retval);
1713 retval[comp][j-i] = '\0';
1714 #if VERBOSE_DECOMPOSE
1715 _dbus_verbose (" (component %d = \"%s\")\n",
1716 comp, retval[comp]);
1722 _dbus_assert (i == len);
1726 *path_len = n_components;
1732 * Demarshals an object path. A path of just "/" is
1733 * represented as an empty vector of strings.
1735 * @param str the string containing the data
1736 * @param byte_order the byte order
1737 * @param pos the position in the string
1738 * @param new_pos the new position of the string
1739 * @param path address to store new object path
1740 * @param path_len length of stored path
1743 _dbus_demarshal_object_path (const DBusString *str,
1753 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1754 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1756 if (!_dbus_decompose_path (data, len, path, path_len))
1760 *new_pos = pos + len + 1;
1766 * Skips over a basic type, reporting the following position.
1768 * @param str the string containing the data
1769 * @param type type of value to demarshal
1770 * @param byte_order the byte order
1771 * @param pos pointer to position in the string,
1772 * updated on return to new position
1775 _dbus_marshal_skip_basic_type (const DBusString *str,
1782 case DBUS_TYPE_BYTE:
1783 case DBUS_TYPE_BOOLEAN:
1786 case DBUS_TYPE_INT32:
1787 case DBUS_TYPE_UINT32:
1788 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1791 #ifdef DBUS_HAVE_INT64
1792 case DBUS_TYPE_INT64:
1793 case DBUS_TYPE_UINT64:
1794 #endif /* DBUS_HAVE_INT64 */
1795 case DBUS_TYPE_DOUBLE:
1796 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1799 case DBUS_TYPE_STRING:
1800 _dbus_assert_not_reached ("FIXME string is a basic type");
1802 case DBUS_TYPE_OBJECT_PATH:
1803 _dbus_assert_not_reached ("FIXME object path is a basic type");
1806 _dbus_verbose ("type %s not a basic type\n",
1807 _dbus_type_to_string (type));
1808 _dbus_assert_not_reached ("not a basic type");
1814 * Skips an array, returning the next position.
1816 * @param str the string containing the data
1817 * @param byte_order the byte order
1818 * @param pos pointer to position in the string,
1819 * updated on return to new position
1822 _dbus_marshal_skip_array (const DBusString *str,
1828 len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1834 * Returns the position right after the end of an argument. PERFORMS
1835 * NO VALIDATION WHATSOEVER. The message must have been previously
1838 * @param str a string
1839 * @param byte_order the byte order to use
1840 * @param type the type of the argument
1841 * @param pos the pos where the arg starts
1842 * @param end_pos pointer where the position right
1843 * after the end position will follow
1844 * @returns TRUE if more data exists after the arg
1847 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1853 if (pos >= _dbus_string_get_length (str))
1858 case DBUS_TYPE_INVALID:
1862 case DBUS_TYPE_BYTE:
1866 case DBUS_TYPE_BOOLEAN:
1870 case DBUS_TYPE_INT32:
1871 case DBUS_TYPE_UINT32:
1872 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1875 case DBUS_TYPE_INT64:
1876 case DBUS_TYPE_UINT64:
1877 case DBUS_TYPE_DOUBLE:
1879 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1882 case DBUS_TYPE_OBJECT_PATH:
1883 case DBUS_TYPE_STRING:
1887 /* Demarshal the length */
1888 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1890 *end_pos = pos + len + 1;
1894 case DBUS_TYPE_ARRAY:
1898 /* Demarshal the length */
1899 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1901 *end_pos = pos + len;
1905 case DBUS_TYPE_DICT:
1909 /* Demarshal the length */
1910 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1912 *end_pos = pos + len;
1917 _dbus_warn ("Unknown message arg type %d\n", type);
1918 _dbus_assert_not_reached ("Unknown message argument type\n");
1922 if (*end_pos > _dbus_string_get_length (str))
1929 * Demarshals and validates a length; returns < 0 if the validation
1930 * fails. The length is required to be small enough that
1931 * len*sizeof(double) will not overflow, and small enough to fit in a
1932 * signed integer. DOES NOT check whether the length points
1933 * beyond the end of the string, because it doesn't know the
1934 * size of array elements.
1936 * @param str the string
1937 * @param byte_order the byte order
1938 * @param pos the unaligned string position (snap to next aligned)
1939 * @param new_pos return location for new position.
1942 demarshal_and_validate_len (const DBusString *str,
1947 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1950 _dbus_assert (new_pos != NULL);
1952 if ((align_4 + 4) > _dbus_string_get_length (str))
1954 _dbus_verbose ("not enough room in message for array length\n");
1958 if (!_dbus_string_validate_nul (str, pos,
1961 _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
1965 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1967 /* note that the len is the number of bytes, so we need it to be
1968 * at least SIZE_T_MAX, but make it smaller just to keep things
1969 * sane. We end up using ints for most sizes to avoid unsigned mess
1970 * so limit to maximum 32-bit signed int divided by at least 8, more
1971 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1973 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1974 if (len > MAX_ARRAY_LENGTH)
1976 _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
1977 len, MAX_ARRAY_LENGTH, pos);
1985 validate_string (const DBusString *str,
1987 int len_without_nul,
1990 *end_pos = pos + len_without_nul + 1;
1992 if (*end_pos > _dbus_string_get_length (str))
1994 _dbus_verbose ("string length outside length of the message\n");
1998 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
2000 _dbus_verbose ("string arg not nul-terminated\n");
2004 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
2006 _dbus_verbose ("string is not valid UTF-8\n");
2014 * Validates and returns a typecode at a specific position
2017 * @param str a string
2018 * @param type the type of the argument
2019 * @param pos the pos where the typecode starts
2020 * @param end_pos pointer where the position right
2021 * after the end position will follow
2022 * @returns #TRUE if the type is valid.
2025 _dbus_marshal_validate_type (const DBusString *str,
2032 if (pos >= _dbus_string_get_length (str))
2035 data = _dbus_string_get_const_data_len (str, pos, 1);
2037 if (_dbus_type_is_valid (*data))
2040 if (end_pos != NULL)
2045 _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
2050 /* Faster validator for array data that doesn't call
2051 * validate_arg for each value
2054 validate_array_data (const DBusString *str,
2065 case DBUS_TYPE_INVALID:
2069 case DBUS_TYPE_OBJECT_PATH:
2070 case DBUS_TYPE_STRING:
2071 case DBUS_TYPE_ARRAY:
2072 case DBUS_TYPE_DICT:
2073 /* This clean recursion to validate_arg is what we
2074 * are doing logically for all types, but we don't
2075 * really want to call validate_arg for every byte
2076 * in a byte array, so the primitive types are
2081 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2082 type, array_type_pos, pos, &pos))
2087 case DBUS_TYPE_BYTE:
2091 case DBUS_TYPE_BOOLEAN:
2096 c = _dbus_string_get_byte (str, pos);
2098 if (!(c == 0 || c == 1))
2100 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2108 case DBUS_TYPE_INT32:
2109 case DBUS_TYPE_UINT32:
2110 /* Call validate arg one time to check alignment padding
2113 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2114 type, array_type_pos, pos, &pos))
2116 pos = _DBUS_ALIGN_VALUE (end, 4);
2119 case DBUS_TYPE_INT64:
2120 case DBUS_TYPE_UINT64:
2121 case DBUS_TYPE_DOUBLE:
2122 /* Call validate arg one time to check alignment padding
2125 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2126 type, array_type_pos, pos, &pos))
2128 pos = _DBUS_ALIGN_VALUE (end, 8);
2132 _dbus_verbose ("Unknown message arg type %d\n", type);
2142 * Validates an argument of a specific type, checking that it
2143 * is well-formed, for example no ludicrous length fields, strings
2144 * are nul-terminated, etc.
2145 * Returns the end position of the argument in end_pos, and
2146 * returns #TRUE if a valid arg begins at "pos"
2148 * @todo security: need to audit this function.
2150 * @param str a string
2151 * @param byte_order the byte order to use
2152 * @param depth current recursion depth, to prevent excessive recursion
2153 * @param type the type of the argument
2154 * @param array_type_pos the position of the current array type, or
2155 * -1 if not in an array
2156 * @param pos the pos where the arg starts
2157 * @param end_pos pointer where the position right
2158 * after the end position will follow
2159 * @returns #TRUE if the arg is valid.
2162 _dbus_marshal_validate_arg (const DBusString *str,
2170 if (pos > _dbus_string_get_length (str))
2172 _dbus_verbose ("Validation went off the end of the message\n");
2176 #define MAX_VALIDATION_DEPTH 32
2178 if (depth > MAX_VALIDATION_DEPTH)
2180 _dbus_verbose ("Maximum recursion depth reached validating message\n");
2186 case DBUS_TYPE_INVALID:
2190 case DBUS_TYPE_BYTE:
2191 if (1 > _dbus_string_get_length (str) - pos)
2193 _dbus_verbose ("no room for byte value\n");
2200 case DBUS_TYPE_BOOLEAN:
2204 if (1 > _dbus_string_get_length (str) - pos)
2206 _dbus_verbose ("no room for boolean value\n");
2210 c = _dbus_string_get_byte (str, pos);
2212 if (!(c == 0 || c == 1))
2214 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2222 case DBUS_TYPE_INT32:
2223 case DBUS_TYPE_UINT32:
2225 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
2227 if (!_dbus_string_validate_nul (str, pos,
2230 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
2234 *end_pos = align_4 + 4;
2238 case DBUS_TYPE_INT64:
2239 case DBUS_TYPE_UINT64:
2240 case DBUS_TYPE_DOUBLE:
2242 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2244 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2246 if (!_dbus_string_validate_nul (str, pos,
2249 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
2253 *end_pos = align_8 + 8;
2257 case DBUS_TYPE_OBJECT_PATH:
2258 case DBUS_TYPE_STRING:
2262 /* Demarshal the length, which does NOT include
2265 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2269 if (!validate_string (str, pos, len, end_pos))
2272 if (type == DBUS_TYPE_OBJECT_PATH)
2274 if (!_dbus_string_validate_path (str, pos, len))
2280 case DBUS_TYPE_ARRAY:
2286 if (array_type_pos == -1)
2288 array_type_pos = pos;
2292 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2294 _dbus_verbose ("invalid array type\n");
2298 while (array_type == DBUS_TYPE_ARRAY);
2303 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2305 _dbus_verbose ("invalid array type\n");
2309 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2312 _dbus_verbose ("invalid array length (<0)\n");
2316 if (len > _dbus_string_get_length (str) - pos)
2318 _dbus_verbose ("array length outside length of the message\n");
2324 if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
2325 array_type, array_type_pos,
2328 _dbus_verbose ("invalid array data\n");
2334 /* This should not be able to happen, as long as validate_arg moves forward;
2335 * but the check is here just to be paranoid.
2337 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2344 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2352 case DBUS_TYPE_DICT:
2358 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2362 if (len > _dbus_string_get_length (str) - pos)
2364 _dbus_verbose ("dict length outside length of the message\n");
2373 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2374 DBUS_TYPE_STRING, -1, pos, &pos))
2377 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
2379 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
2383 /* Validate element */
2384 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
2385 dict_type, -1, pos, &pos))
2387 _dbus_verbose ("dict arg invalid at offset %d\n", pos);
2394 _dbus_verbose ("dict contents exceed stated dict length\n");
2403 _dbus_verbose ("Unknown message arg type %d\n", type);
2407 if (*end_pos > _dbus_string_get_length (str))
2414 * Return #TRUE if the typecode is a valid typecode
2416 * @returns #TRUE if valid
2419 _dbus_type_is_valid (int typecode)
2423 case DBUS_TYPE_BYTE:
2424 case DBUS_TYPE_BOOLEAN:
2425 case DBUS_TYPE_INT32:
2426 case DBUS_TYPE_UINT32:
2427 case DBUS_TYPE_INT64:
2428 case DBUS_TYPE_UINT64:
2429 case DBUS_TYPE_DOUBLE:
2430 case DBUS_TYPE_STRING:
2431 case DBUS_TYPE_ARRAY:
2432 case DBUS_TYPE_DICT:
2433 case DBUS_TYPE_OBJECT_PATH:
2442 * If in verbose mode, print a block of binary data.
2444 * @todo right now it prints even if not in verbose mode
2446 * @param data the data
2447 * @param len the length of the data
2450 _dbus_verbose_bytes (const unsigned char *data,
2454 const unsigned char *aligned;
2456 _dbus_assert (len >= 0);
2458 /* Print blanks on first row if appropriate */
2459 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2462 _dbus_assert (aligned <= data);
2464 if (aligned != data)
2466 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
2467 while (aligned != data)
2469 _dbus_verbose (" ");
2474 /* now print the bytes */
2478 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2480 _dbus_verbose ("%4d\t%p: ",
2484 if (data[i] >= 32 &&
2486 _dbus_verbose (" '%c' ", data[i]);
2488 _dbus_verbose ("0x%s%x ",
2489 data[i] <= 0xf ? "0" : "", data[i]);
2493 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2496 _dbus_verbose ("BE: %d LE: %d",
2497 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2498 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2501 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2503 _dbus_verbose (" dbl: %g",
2504 *(double*)&data[i-8]);
2507 _dbus_verbose ("\n");
2511 _dbus_verbose ("\n");
2515 * Dump the given part of the string to verbose log.
2517 * @param str the string
2518 * @param start the start of range to dump
2519 * @param len length of range
2522 _dbus_verbose_bytes_of_string (const DBusString *str,
2529 real_len = _dbus_string_get_length (str);
2531 _dbus_assert (start >= 0);
2533 if (start > real_len)
2535 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
2536 start, len, real_len);
2540 if ((start + len) > real_len)
2542 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
2543 start, len, real_len);
2544 len = real_len - start;
2547 d = _dbus_string_get_const_data_len (str, start, len);
2549 _dbus_verbose_bytes (d, len);
2553 * Marshals a basic type
2555 * @param str string to marshal to
2556 * @param insert_at where to insert the value
2557 * @param type type of value
2558 * @param value pointer to value
2559 * @param byte_order byte order
2560 * @returns #TRUE on success
2563 _dbus_marshal_basic_type (DBusString *str,
2573 case DBUS_TYPE_BYTE:
2574 case DBUS_TYPE_BOOLEAN:
2575 retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
2577 case DBUS_TYPE_INT32:
2578 case DBUS_TYPE_UINT32:
2579 return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
2581 #ifdef DBUS_HAVE_INT64
2582 case DBUS_TYPE_INT64:
2583 case DBUS_TYPE_UINT64:
2586 r.u = *(const dbus_uint64_t *)value;
2587 retval = marshal_8_octets (str, insert_at, byte_order, r);
2590 #endif /* DBUS_HAVE_INT64 */
2591 case DBUS_TYPE_DOUBLE:
2594 r.d = *(const double *)value;
2595 retval = marshal_8_octets (str, insert_at, byte_order, r);
2599 _dbus_assert_not_reached ("not a basic type");
2607 * Marshals a basic type array
2609 * @param str string to marshal to
2610 * @param insert_at where to insert the value
2611 * @param element_type type of array elements
2612 * @param value pointer to value
2613 * @param len length of value data in elements
2614 * @param byte_order byte order
2615 * @returns #TRUE on success
2618 _dbus_marshal_basic_type_array (DBusString *str,
2625 /* FIXME use the insert_at arg */
2627 switch (element_type)
2629 case DBUS_TYPE_BOOLEAN:
2630 /* FIXME: we canonicalize to 0 or 1 for the single boolean case
2631 * should we here too ? */
2632 case DBUS_TYPE_BYTE:
2633 return _dbus_marshal_byte_array (str, byte_order, value, len);
2635 case DBUS_TYPE_INT32:
2636 case DBUS_TYPE_UINT32:
2637 return marshal_4_octets_array (str, byte_order, value, len);
2639 #ifdef DBUS_HAVE_INT64
2640 case DBUS_TYPE_INT64:
2641 case DBUS_TYPE_UINT64:
2642 #endif /* DBUS_HAVE_INT64 */
2643 case DBUS_TYPE_DOUBLE:
2644 return marshal_8_octets_array (str, byte_order, value, len);
2647 _dbus_assert_not_reached ("non basic type in array");
2655 #ifdef DBUS_BUILD_TESTS
2656 #include "dbus-test.h"
2660 _dbus_marshal_test (void)
2665 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2666 #ifdef DBUS_HAVE_INT64
2667 dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
2668 DBUS_INT64_CONSTANT (0x456ffffffff),
2669 DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
2674 if (!_dbus_string_init (&str))
2675 _dbus_assert_not_reached ("failed to init string");
2677 /* Marshal doubles */
2678 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2679 _dbus_assert_not_reached ("could not marshal double value");
2680 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2681 _dbus_assert_not_reached ("demarshal failed");
2683 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2684 _dbus_assert_not_reached ("could not marshal double value");
2685 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2686 _dbus_assert_not_reached ("demarshal failed");
2688 /* Marshal signed integers */
2689 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2690 _dbus_assert_not_reached ("could not marshal signed integer value");
2691 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2692 _dbus_assert_not_reached ("demarshal failed");
2694 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2695 _dbus_assert_not_reached ("could not marshal signed integer value");
2696 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2697 _dbus_assert_not_reached ("demarshal failed");
2699 /* Marshal unsigned integers */
2700 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2701 _dbus_assert_not_reached ("could not marshal signed integer value");
2702 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2703 _dbus_assert_not_reached ("demarshal failed");
2705 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2706 _dbus_assert_not_reached ("could not marshal signed integer value");
2707 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2708 _dbus_assert_not_reached ("demarshal failed");
2710 #ifdef DBUS_HAVE_INT64
2711 /* Marshal signed integers */
2712 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2713 _dbus_assert_not_reached ("could not marshal signed integer value");
2714 if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2715 _dbus_assert_not_reached ("demarshal failed");
2717 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2718 _dbus_assert_not_reached ("could not marshal signed integer value");
2719 if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2720 _dbus_assert_not_reached ("demarshal failed");
2722 /* Marshal unsigned integers */
2723 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2724 _dbus_assert_not_reached ("could not marshal signed integer value");
2725 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2726 _dbus_assert_not_reached ("demarshal failed");
2728 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2729 _dbus_assert_not_reached ("could not marshal signed integer value");
2730 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2731 _dbus_assert_not_reached ("demarshal failed");
2732 #endif /* DBUS_HAVE_INT64 */
2734 /* Marshal strings */
2735 tmp1 = "This is the dbus test string";
2736 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2737 _dbus_assert_not_reached ("could not marshal string");
2738 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2739 if (!strcmp (tmp1, tmp2) == 0)
2740 _dbus_assert_not_reached ("demarshal failed");
2743 tmp1 = "This is the dbus test string";
2744 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2745 _dbus_assert_not_reached ("could not marshal string");
2746 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2747 if (!strcmp (tmp1, tmp2) == 0)
2748 _dbus_assert_not_reached ("demarshal failed");
2751 /* Marshal signed integer arrays */
2752 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2753 _dbus_assert_not_reached ("could not marshal integer array");
2754 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2755 _dbus_assert_not_reached ("could not demarshal integer array");
2758 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2761 #ifdef DBUS_HAVE_INT64
2762 /* Marshal 64-bit signed integer arrays */
2763 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2764 _dbus_assert_not_reached ("could not marshal integer array");
2765 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2766 _dbus_assert_not_reached ("could not demarshal integer array");
2769 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2772 /* set/pack 64-bit integers */
2773 _dbus_string_set_length (&str, 8);
2776 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2777 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2779 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2780 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2781 _dbus_string_get_const_data (&str)));
2784 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2785 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2787 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2788 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2789 _dbus_string_get_const_data (&str)));
2791 /* signed little pack */
2792 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2794 _dbus_string_get_data (&str));
2796 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2797 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2798 _dbus_string_get_const_data (&str)));
2800 /* signed big pack */
2801 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2803 _dbus_string_get_data (&str));
2805 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2806 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2807 _dbus_string_get_const_data (&str)));
2809 /* unsigned little */
2810 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2811 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2813 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2814 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2815 _dbus_string_get_const_data (&str)));
2818 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2819 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2821 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2822 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2823 _dbus_string_get_const_data (&str)));
2825 /* unsigned little pack */
2826 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2828 _dbus_string_get_data (&str));
2830 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2831 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2832 _dbus_string_get_const_data (&str)));
2834 /* unsigned big pack */
2835 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2837 _dbus_string_get_data (&str));
2839 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2840 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2841 _dbus_string_get_const_data (&str)));
2845 /* set/pack 32-bit integers */
2846 _dbus_string_set_length (&str, 4);
2849 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2852 _dbus_assert (-0x123456 ==
2853 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2854 _dbus_string_get_const_data (&str)));
2857 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2860 _dbus_assert (-0x123456 ==
2861 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2862 _dbus_string_get_const_data (&str)));
2864 /* signed little pack */
2865 _dbus_pack_int32 (-0x123456,
2867 _dbus_string_get_data (&str));
2869 _dbus_assert (-0x123456 ==
2870 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2871 _dbus_string_get_const_data (&str)));
2873 /* signed big pack */
2874 _dbus_pack_int32 (-0x123456,
2876 _dbus_string_get_data (&str));
2878 _dbus_assert (-0x123456 ==
2879 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2880 _dbus_string_get_const_data (&str)));
2882 /* unsigned little */
2883 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2886 _dbus_assert (0x123456 ==
2887 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2888 _dbus_string_get_const_data (&str)));
2891 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2894 _dbus_assert (0x123456 ==
2895 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2896 _dbus_string_get_const_data (&str)));
2898 /* unsigned little pack */
2899 _dbus_pack_uint32 (0x123456,
2901 _dbus_string_get_data (&str));
2903 _dbus_assert (0x123456 ==
2904 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2905 _dbus_string_get_const_data (&str)));
2907 /* unsigned big pack */
2908 _dbus_pack_uint32 (0x123456,
2910 _dbus_string_get_data (&str));
2912 _dbus_assert (0x123456 ==
2913 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2914 _dbus_string_get_const_data (&str)));
2919 _dbus_string_set_length (&str, 0);
2921 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2924 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2925 _dbus_assert (strcmp (s, "Hello world") == 0);
2928 _dbus_string_init_const (&t, "Hello world foo");
2930 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2931 &t, _dbus_string_get_length (&t));
2933 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2934 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2937 _dbus_string_init_const (&t, "Hello");
2939 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2940 &t, _dbus_string_get_length (&t));
2942 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2943 _dbus_assert (strcmp (s, "Hello") == 0);
2946 /* Strings (big endian) */
2948 _dbus_string_set_length (&str, 0);
2950 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
2953 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2954 _dbus_assert (strcmp (s, "Hello world") == 0);
2957 _dbus_string_init_const (&t, "Hello world foo");
2959 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2960 &t, _dbus_string_get_length (&t));
2962 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2963 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2966 _dbus_string_init_const (&t, "Hello");
2968 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2969 &t, _dbus_string_get_length (&t));
2971 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2972 _dbus_assert (strcmp (s, "Hello") == 0);
2975 _dbus_string_free (&str);
2980 #endif /* DBUS_BUILD_TESTS */