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 /* The array length is the length in bytes of the array,
750 * *excluding* alignment padding.
752 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
755 array_start = _dbus_string_get_length (str);
757 /* Note that we do alignment padding unconditionally
758 * even if the array is empty; this means that
759 * padding + len is always equal to the number of bytes
763 if (!_dbus_string_align_length (str, 8))
766 if (!_dbus_string_append_len (str, (const unsigned char*) value,
770 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
772 const unsigned char *d;
773 const unsigned char *end;
775 d = _dbus_string_get_data (str) + array_start;
779 #ifdef DBUS_HAVE_INT64
780 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
782 swap_bytes ((unsigned char*) d, 8);
791 /* Restore previous length */
792 _dbus_string_set_length (str, old_string_len);
798 * Marshals a 32 bit signed integer array
800 * @param str the string to append the marshalled value to
801 * @param byte_order the byte order to use
802 * @param value the array
803 * @param len the length of the array
804 * @returns #TRUE on success
807 _dbus_marshal_int32_array (DBusString *str,
809 const dbus_int32_t *value,
812 return marshal_4_octets_array (str, byte_order,
813 (const dbus_uint32_t*) value,
818 * Marshals a 32 bit unsigned integer array
820 * @param str the string to append the marshalled value to
821 * @param byte_order the byte order to use
822 * @param value the array
823 * @param len the length of the array
824 * @returns #TRUE on success
827 _dbus_marshal_uint32_array (DBusString *str,
829 const dbus_uint32_t *value,
832 return marshal_4_octets_array (str, byte_order,
837 #ifdef DBUS_HAVE_INT64
840 * Marshals a 64 bit signed integer array
842 * @param str the string to append the marshalled value to
843 * @param byte_order the byte order to use
844 * @param value the array
845 * @param len the length of the array
846 * @returns #TRUE on success
849 _dbus_marshal_int64_array (DBusString *str,
851 const dbus_int64_t *value,
854 return marshal_8_octets_array (str, byte_order,
855 (const DBusOctets8*) value,
860 * Marshals a 64 bit unsigned integer array
862 * @param str the string to append the marshalled value to
863 * @param byte_order the byte order to use
864 * @param value the array
865 * @param len the length of the array
866 * @returns #TRUE on success
869 _dbus_marshal_uint64_array (DBusString *str,
871 const dbus_uint64_t *value,
874 return marshal_8_octets_array (str, byte_order,
875 (const DBusOctets8*) value,
879 #endif /* DBUS_HAVE_INT64 */
882 * Marshals a double array
884 * @param str the string to append the marshalled value to
885 * @param byte_order the byte order to use
886 * @param value the array
887 * @param len the length of the array
888 * @returns #TRUE on success
891 _dbus_marshal_double_array (DBusString *str,
896 return marshal_8_octets_array (str, byte_order,
897 (const DBusOctets8*) value,
902 * Marshals a string array
904 * @param str the string to append the marshalled value to
905 * @param byte_order the byte order to use
906 * @param value the array
907 * @param len the length of the array
908 * @returns #TRUE on success
911 _dbus_marshal_string_array (DBusString *str,
916 int i, old_string_len, array_start;
918 old_string_len = _dbus_string_get_length (str);
920 /* Set the length to 0 temporarily */
921 if (!_dbus_marshal_uint32 (str, byte_order, 0))
924 array_start = _dbus_string_get_length (str);
926 for (i = 0; i < len; i++)
927 if (!_dbus_marshal_string (str, byte_order, value[i]))
930 /* Write the length now that we know it */
931 _dbus_marshal_set_uint32 (str, byte_order,
932 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
933 _dbus_string_get_length (str) - array_start);
938 /* Restore previous length */
939 _dbus_string_set_length (str, old_string_len);
945 * Marshals an object path value.
947 * @param str the string to append the marshalled value to
948 * @param byte_order the byte order to use
949 * @param path the path
950 * @param path_len length of the path
951 * @returns #TRUE on success
954 _dbus_marshal_object_path (DBusString *str,
959 int array_start, old_string_len;
962 old_string_len = _dbus_string_get_length (str);
964 /* Set the length to 0 temporarily */
965 if (!_dbus_marshal_uint32 (str, byte_order, 0))
968 array_start = _dbus_string_get_length (str);
973 if (!_dbus_string_append_byte (str, '/'))
976 if (!_dbus_string_append (str, path[0]))
982 /* Write the length now that we know it */
983 _dbus_marshal_set_uint32 (str, byte_order,
984 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
985 _dbus_string_get_length (str) - array_start);
990 /* Restore the previous length */
991 _dbus_string_set_length (str, old_string_len);
997 demarshal_4_octets (const DBusString *str,
1002 const DBusRealString *real = (const DBusRealString*) str;
1004 pos = _DBUS_ALIGN_VALUE (pos, 4);
1009 return unpack_4_octets (byte_order, real->str + pos);
1013 demarshal_8_octets (const DBusString *str,
1018 const DBusRealString *real = (const DBusRealString*) str;
1020 pos = _DBUS_ALIGN_VALUE (pos, 8);
1025 return unpack_8_octets (byte_order, real->str + pos);
1029 * Demarshals a double.
1031 * @param str the string containing the data
1032 * @param byte_order the byte order
1033 * @param pos the position in the string
1034 * @param new_pos the new position of the string
1035 * @returns the demarshaled double.
1038 _dbus_demarshal_double (const DBusString *str,
1045 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1051 * Demarshals a 32 bit signed integer.
1053 * @param str the string containing the data
1054 * @param byte_order the byte order
1055 * @param pos the position in the string
1056 * @param new_pos the new position of the string
1057 * @returns the demarshaled integer.
1060 _dbus_demarshal_int32 (const DBusString *str,
1065 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
1069 * Demarshals a 32 bit unsigned integer.
1071 * @param str the string containing the data
1072 * @param byte_order the byte order
1073 * @param pos the position in the string
1074 * @param new_pos the new position of the string
1075 * @returns the demarshaled integer.
1078 _dbus_demarshal_uint32 (const DBusString *str,
1083 return demarshal_4_octets (str, byte_order, pos, new_pos);
1086 #ifdef DBUS_HAVE_INT64
1089 * Demarshals a 64 bit signed integer.
1091 * @param str the string containing the data
1092 * @param byte_order the byte order
1093 * @param pos the position in the string
1094 * @param new_pos the new position of the string
1095 * @returns the demarshaled integer.
1098 _dbus_demarshal_int64 (const DBusString *str,
1105 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1111 * Demarshals a 64 bit unsigned integer.
1113 * @param str the string containing the data
1114 * @param byte_order the byte order
1115 * @param pos the position in the string
1116 * @param new_pos the new position of the string
1117 * @returns the demarshaled integer.
1120 _dbus_demarshal_uint64 (const DBusString *str,
1127 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1132 #endif /* DBUS_HAVE_INT64 */
1135 * Demarshals a basic type
1137 * @param str the string containing the data
1138 * @param type type of value to demarshal
1139 * @param value pointer to return value data
1140 * @param byte_order the byte order
1141 * @param pos pointer to position in the string,
1142 * updated on return to new position
1145 _dbus_demarshal_basic_type (const DBusString *str,
1151 const char *str_data = _dbus_string_get_const_data (str);
1155 case DBUS_TYPE_BYTE:
1156 case DBUS_TYPE_BOOLEAN:
1157 *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
1160 case DBUS_TYPE_INT32:
1161 case DBUS_TYPE_UINT32:
1162 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1163 *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
1164 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1165 *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
1168 #ifdef DBUS_HAVE_INT64
1169 case DBUS_TYPE_INT64:
1170 case DBUS_TYPE_UINT64:
1171 #endif /* DBUS_HAVE_INT64 */
1172 case DBUS_TYPE_DOUBLE:
1173 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1174 memcpy (value, str_data + *pos, 8);
1175 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1176 #ifdef DBUS_HAVE_INT64
1177 *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
1179 swap_bytes (value, 8);
1183 case DBUS_TYPE_STRING:
1184 _dbus_assert_not_reached ("FIXME string is a basic type");
1186 case DBUS_TYPE_OBJECT_PATH:
1187 _dbus_assert_not_reached ("FIXME object path is a basic type");
1190 _dbus_verbose ("type %s not a basic type\n",
1191 _dbus_type_to_string (type));
1192 _dbus_assert_not_reached ("not a basic type");
1198 * Demarshals an UTF-8 string.
1200 * @todo Should we check the string to make sure
1201 * that it's valid UTF-8, and maybe "fix" the string
1204 * @todo Should probably demarshal to a DBusString,
1205 * having memcpy() in here is Evil(tm).
1207 * @param str the string containing the data
1208 * @param byte_order the byte order
1209 * @param pos the position in the string
1210 * @param new_pos the new position of the string
1211 * @returns the demarshaled string.
1214 _dbus_demarshal_string (const DBusString *str,
1223 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1225 retval = dbus_malloc (len + 1);
1230 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1235 memcpy (retval, data, len + 1);
1238 *new_pos = pos + len + 1;
1244 * Demarshals a byte array.
1246 * @todo Should probably demarshal to a DBusString,
1247 * having memcpy() in here is Evil(tm).
1249 * @param str the string containing the data
1250 * @param byte_order the byte order
1251 * @param pos the position in the string
1252 * @param new_pos the new position of the string
1253 * @param array the array
1254 * @param array_len length of the demarshaled data
1256 * @returns #TRUE on success
1259 _dbus_demarshal_byte_array (const DBusString *str,
1263 unsigned char **array,
1267 unsigned char *retval;
1270 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1283 retval = dbus_malloc (len);
1288 data = _dbus_string_get_const_data_len (str, pos, len);
1296 memcpy (retval, data, len);
1299 *new_pos = pos + len;
1308 demarshal_4_octets_array (const DBusString *str,
1312 dbus_uint32_t **array,
1316 dbus_uint32_t *retval;
1319 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1333 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1337 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1339 for (i = 0; i < len; i++)
1340 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1344 *new_pos = pos + byte_len;
1353 demarshal_8_octets_array (const DBusString *str,
1357 DBusOctets8 **array,
1361 DBusOctets8 *retval;
1364 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1366 pos = _DBUS_ALIGN_VALUE (pos, 8);
1381 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1385 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1387 for (i = 0; i < len; i++)
1389 #ifdef DBUS_HAVE_INT64
1390 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1392 swap_bytes ((unsigned char *) &retval[i], 8);
1398 *new_pos = pos + byte_len;
1407 * Demarshals a 32 bit signed integer array.
1409 * @param str the string containing the data
1410 * @param byte_order the byte order
1411 * @param pos the position in the string
1412 * @param new_pos the new position of the string
1413 * @param array the array
1414 * @param array_len length of the demarshaled data
1415 * @returns #TRUE on success
1418 _dbus_demarshal_int32_array (const DBusString *str,
1422 dbus_int32_t **array,
1425 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1426 (dbus_uint32_t**) array, array_len);
1430 * Demarshals a 32 bit unsigned integer array.
1432 * @param str the string containing the data
1433 * @param byte_order the byte order
1434 * @param pos the position in the string
1435 * @param new_pos the new position of the string
1436 * @param array the array
1437 * @param array_len length of the demarshaled data
1438 * @returns #TRUE on success
1441 _dbus_demarshal_uint32_array (const DBusString *str,
1445 dbus_uint32_t **array,
1448 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1452 #ifdef DBUS_HAVE_INT64
1455 * Demarshals a 64 bit signed integer array.
1457 * @param str the string containing the data
1458 * @param byte_order the byte order
1459 * @param pos the position in the string
1460 * @param new_pos the new position of the string
1461 * @param array the array
1462 * @param array_len length of the demarshaled data
1463 * @returns #TRUE on success
1466 _dbus_demarshal_int64_array (const DBusString *str,
1470 dbus_int64_t **array,
1473 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1474 (DBusOctets8**) array, array_len);
1478 * Demarshals a 64 bit unsigned integer array.
1480 * @param str the string containing the data
1481 * @param byte_order the byte order
1482 * @param pos the position in the string
1483 * @param new_pos the new position of the string
1484 * @param array the array
1485 * @param array_len length of the demarshaled data
1486 * @returns #TRUE on success
1489 _dbus_demarshal_uint64_array (const DBusString *str,
1493 dbus_uint64_t **array,
1496 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1497 (DBusOctets8**) array, array_len);
1500 #endif /* DBUS_HAVE_INT64 */
1503 * Demarshals a double array.
1505 * @param str the string containing the data
1506 * @param byte_order the byte order
1507 * @param pos the position in the string
1508 * @param new_pos the new position of the string
1509 * @param array the array
1510 * @param array_len length of the demarshaled data
1511 * @returns #TRUE on success
1514 _dbus_demarshal_double_array (const DBusString *str,
1521 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1522 (DBusOctets8**) array, array_len);
1527 * Demarshals an array of basic types
1529 * @param str the string containing the data
1530 * @param element_type type of array elements to demarshal
1531 * @param array pointer to pointer to array data
1532 * @param array_len pointer to array length
1533 * @param byte_order the byte order
1534 * @param pos pointer to position in the string,
1535 * updated on return to new position
1538 _dbus_demarshal_basic_type_array (const DBusString *str,
1545 switch (element_type)
1547 case DBUS_TYPE_BOOLEAN:
1548 /* FIXME: do we want to post-normalize these ? */
1549 case DBUS_TYPE_BYTE:
1550 return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
1551 (unsigned char **)array, array_len);
1553 case DBUS_TYPE_INT32:
1554 case DBUS_TYPE_UINT32:
1555 return demarshal_4_octets_array (str, byte_order, *pos, pos,
1556 (dbus_uint32_t **)array, array_len);
1558 #ifdef DBUS_HAVE_INT64
1559 case DBUS_TYPE_INT64:
1560 case DBUS_TYPE_UINT64:
1561 #endif /* DBUS_HAVE_INT64 */
1562 case DBUS_TYPE_DOUBLE:
1563 return demarshal_8_octets_array (str, byte_order, *pos, pos,
1564 (DBusOctets8**) array, array_len);
1566 _dbus_assert_not_reached ("not a basic type");
1573 * Demarshals a string array.
1575 * @param str the string containing the data
1576 * @param byte_order the byte order
1577 * @param pos the position in the string
1578 * @param new_pos the new position of the string
1579 * @param array the array
1580 * @param array_len location for length of the demarshaled data or NULL
1581 * @returns #TRUE on success
1584 _dbus_demarshal_string_array (const DBusString *str,
1596 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1611 end_pos = pos + bytes_len;
1613 retval = dbus_new (char *, allocated);
1618 while (pos < end_pos)
1620 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1622 if (retval[len] == NULL)
1627 if (len >= allocated - 1) /* -1 for NULL termination */
1630 newp = dbus_realloc (retval,
1631 sizeof (char*) * allocated * 2);
1651 for (i = 0; i < len; i++)
1652 dbus_free (retval[i]);
1658 /** Set to 1 to get a bunch of spew about disassembling the path string */
1659 #define VERBOSE_DECOMPOSE 0
1662 * Decompose an object path. A path of just "/" is
1663 * represented as an empty vector of strings.
1665 * @param data the path data
1666 * @param len the length of the path string
1667 * @param path address to store new object path
1668 * @param path_len length of stored path
1671 _dbus_decompose_path (const char* data,
1680 _dbus_assert (data != NULL);
1682 #if VERBOSE_DECOMPOSE
1683 _dbus_verbose ("Decomposing path \"%s\"\n",
1696 retval = dbus_new0 (char*, n_components + 1);
1709 while (j < len && data[j] != '/')
1712 /* Now [i, j) is the path component */
1713 _dbus_assert (i < j);
1714 _dbus_assert (data[i] != '/');
1715 _dbus_assert (j == len || data[j] == '/');
1717 #if VERBOSE_DECOMPOSE
1718 _dbus_verbose (" (component in [%d,%d))\n",
1722 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1723 if (retval[comp] == NULL)
1725 dbus_free_string_array (retval);
1728 retval[comp][j-i] = '\0';
1729 #if VERBOSE_DECOMPOSE
1730 _dbus_verbose (" (component %d = \"%s\")\n",
1731 comp, retval[comp]);
1737 _dbus_assert (i == len);
1741 *path_len = n_components;
1747 * Demarshals an object path. A path of just "/" is
1748 * represented as an empty vector of strings.
1750 * @param str the string containing the data
1751 * @param byte_order the byte order
1752 * @param pos the position in the string
1753 * @param new_pos the new position of the string
1754 * @param path address to store new object path
1755 * @param path_len length of stored path
1758 _dbus_demarshal_object_path (const DBusString *str,
1768 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1769 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1771 if (!_dbus_decompose_path (data, len, path, path_len))
1775 *new_pos = pos + len + 1;
1781 * Skips over a basic type, reporting the following position.
1783 * @param str the string containing the data
1784 * @param type type of value to demarshal
1785 * @param byte_order the byte order
1786 * @param pos pointer to position in the string,
1787 * updated on return to new position
1790 _dbus_marshal_skip_basic_type (const DBusString *str,
1797 case DBUS_TYPE_BYTE:
1798 case DBUS_TYPE_BOOLEAN:
1801 case DBUS_TYPE_INT32:
1802 case DBUS_TYPE_UINT32:
1803 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1806 #ifdef DBUS_HAVE_INT64
1807 case DBUS_TYPE_INT64:
1808 case DBUS_TYPE_UINT64:
1809 #endif /* DBUS_HAVE_INT64 */
1810 case DBUS_TYPE_DOUBLE:
1811 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1814 case DBUS_TYPE_STRING:
1815 _dbus_assert_not_reached ("FIXME string is a basic type");
1817 case DBUS_TYPE_OBJECT_PATH:
1818 _dbus_assert_not_reached ("FIXME object path is a basic type");
1821 _dbus_verbose ("type %s not a basic type\n",
1822 _dbus_type_to_string (type));
1823 _dbus_assert_not_reached ("not a basic type");
1829 * Skips an array, returning the next position.
1831 * @param str the string containing the data
1832 * @param byte_order the byte order
1833 * @param pos pointer to position in the string,
1834 * updated on return to new position
1837 _dbus_marshal_skip_array (const DBusString *str,
1843 len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1845 /* FIXME we need to insert alignment padding according to array type */
1851 * Returns the position right after the end of an argument. PERFORMS
1852 * NO VALIDATION WHATSOEVER. The message must have been previously
1855 * @param str a string
1856 * @param byte_order the byte order to use
1857 * @param type the type of the argument
1858 * @param pos the pos where the arg starts
1859 * @param end_pos pointer where the position right
1860 * after the end position will follow
1861 * @returns TRUE if more data exists after the arg
1864 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1870 if (pos >= _dbus_string_get_length (str))
1875 case DBUS_TYPE_INVALID:
1879 case DBUS_TYPE_BYTE:
1883 case DBUS_TYPE_BOOLEAN:
1887 case DBUS_TYPE_INT32:
1888 case DBUS_TYPE_UINT32:
1889 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1892 case DBUS_TYPE_INT64:
1893 case DBUS_TYPE_UINT64:
1894 case DBUS_TYPE_DOUBLE:
1896 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1899 case DBUS_TYPE_OBJECT_PATH:
1900 case DBUS_TYPE_STRING:
1904 /* Demarshal the length */
1905 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1907 *end_pos = pos + len + 1;
1911 case DBUS_TYPE_ARRAY:
1915 /* Demarshal the length */
1916 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1918 /* FIXME needs to align to the right boundary for the array type */
1919 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + len;
1924 _dbus_warn ("Unknown message arg type %d\n", type);
1925 _dbus_assert_not_reached ("Unknown message argument type\n");
1929 if (*end_pos > _dbus_string_get_length (str))
1936 * Demarshals and validates a length; returns < 0 if the validation
1937 * fails. The length is required to be small enough that
1938 * len*sizeof(double) will not overflow, and small enough to fit in a
1939 * signed integer. DOES NOT check whether the length points
1940 * beyond the end of the string, because it doesn't know the
1941 * size of array elements.
1943 * @param str the string
1944 * @param byte_order the byte order
1945 * @param pos the unaligned string position (snap to next aligned)
1946 * @param new_pos return location for new position.
1949 demarshal_and_validate_len (const DBusString *str,
1954 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1957 _dbus_assert (new_pos != NULL);
1959 if ((align_4 + 4) > _dbus_string_get_length (str))
1961 _dbus_verbose ("not enough room in message for array length\n");
1965 if (!_dbus_string_validate_nul (str, pos,
1968 _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
1972 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1974 /* note that the len is the number of bytes, so we need it to be
1975 * at least SIZE_T_MAX, but make it smaller just to keep things
1976 * sane. We end up using ints for most sizes to avoid unsigned mess
1977 * so limit to maximum 32-bit signed int divided by at least 8, more
1978 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1980 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1981 if (len > MAX_ARRAY_LENGTH)
1983 _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
1984 len, MAX_ARRAY_LENGTH, pos);
1992 validate_string (const DBusString *str,
1994 int len_without_nul,
1997 *end_pos = pos + len_without_nul + 1;
1999 if (*end_pos > _dbus_string_get_length (str))
2001 _dbus_verbose ("string length outside length of the message\n");
2005 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
2007 _dbus_verbose ("string arg not nul-terminated\n");
2011 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
2013 _dbus_verbose ("string is not valid UTF-8\n");
2021 * Validates and returns a typecode at a specific position
2024 * @param str a string
2025 * @param type the type of the argument
2026 * @param pos the pos where the typecode starts
2027 * @param end_pos pointer where the position right
2028 * after the end position will follow
2029 * @returns #TRUE if the type is valid.
2032 _dbus_marshal_validate_type (const DBusString *str,
2039 if (pos >= _dbus_string_get_length (str))
2042 data = _dbus_string_get_const_data_len (str, pos, 1);
2044 if (_dbus_type_is_valid (*data))
2047 if (end_pos != NULL)
2052 _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
2057 /* Faster validator for array data that doesn't call
2058 * validate_arg for each value
2061 validate_array_data (const DBusString *str,
2072 case DBUS_TYPE_INVALID:
2076 case DBUS_TYPE_OBJECT_PATH:
2077 case DBUS_TYPE_STRING:
2078 case DBUS_TYPE_ARRAY:
2079 /* This clean recursion to validate_arg is what we
2080 * are doing logically for all types, but we don't
2081 * really want to call validate_arg for every byte
2082 * in a byte array, so the primitive types are
2087 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2088 type, array_type_pos, pos, &pos))
2093 case DBUS_TYPE_BYTE:
2097 case DBUS_TYPE_BOOLEAN:
2102 c = _dbus_string_get_byte (str, pos);
2104 if (!(c == 0 || c == 1))
2106 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2114 case DBUS_TYPE_INT32:
2115 case DBUS_TYPE_UINT32:
2116 /* Call validate arg one time to check alignment padding
2119 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2120 type, array_type_pos, pos, &pos))
2122 pos = _DBUS_ALIGN_VALUE (end, 4);
2125 case DBUS_TYPE_INT64:
2126 case DBUS_TYPE_UINT64:
2127 case DBUS_TYPE_DOUBLE:
2128 /* Call validate arg one time to check alignment padding
2131 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2132 type, array_type_pos, pos, &pos))
2134 pos = _DBUS_ALIGN_VALUE (end, 8);
2138 _dbus_verbose ("Unknown message arg type %d\n", type);
2148 * Validates an argument of a specific type, checking that it
2149 * is well-formed, for example no ludicrous length fields, strings
2150 * are nul-terminated, etc.
2151 * Returns the end position of the argument in end_pos, and
2152 * returns #TRUE if a valid arg begins at "pos"
2154 * @todo security: need to audit this function.
2156 * @param str a string
2157 * @param byte_order the byte order to use
2158 * @param depth current recursion depth, to prevent excessive recursion
2159 * @param type the type of the argument
2160 * @param array_type_pos the position of the current array type, or
2161 * -1 if not in an array
2162 * @param pos the pos where the arg starts
2163 * @param end_pos pointer where the position right
2164 * after the end position will follow
2165 * @returns #TRUE if the arg is valid.
2168 _dbus_marshal_validate_arg (const DBusString *str,
2176 if (pos > _dbus_string_get_length (str))
2178 _dbus_verbose ("Validation went off the end of the message\n");
2182 #define MAX_VALIDATION_DEPTH 32
2184 if (depth > MAX_VALIDATION_DEPTH)
2186 _dbus_verbose ("Maximum recursion depth reached validating message\n");
2192 case DBUS_TYPE_INVALID:
2196 case DBUS_TYPE_BYTE:
2197 if (1 > _dbus_string_get_length (str) - pos)
2199 _dbus_verbose ("no room for byte value\n");
2206 case DBUS_TYPE_BOOLEAN:
2210 if (1 > _dbus_string_get_length (str) - pos)
2212 _dbus_verbose ("no room for boolean value\n");
2216 c = _dbus_string_get_byte (str, pos);
2218 if (!(c == 0 || c == 1))
2220 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2228 case DBUS_TYPE_INT32:
2229 case DBUS_TYPE_UINT32:
2231 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
2233 if (!_dbus_string_validate_nul (str, pos,
2236 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
2240 *end_pos = align_4 + 4;
2244 case DBUS_TYPE_INT64:
2245 case DBUS_TYPE_UINT64:
2246 case DBUS_TYPE_DOUBLE:
2248 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2250 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2252 if (!_dbus_string_validate_nul (str, pos,
2255 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
2259 *end_pos = align_8 + 8;
2263 case DBUS_TYPE_OBJECT_PATH:
2264 case DBUS_TYPE_STRING:
2268 /* Demarshal the length, which does NOT include
2271 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2275 if (!validate_string (str, pos, len, end_pos))
2278 if (type == DBUS_TYPE_OBJECT_PATH)
2280 if (!_dbus_string_validate_path (str, pos, len))
2286 case DBUS_TYPE_ARRAY:
2292 if (array_type_pos == -1)
2294 array_type_pos = pos;
2298 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2300 _dbus_verbose ("invalid array type\n");
2304 while (array_type == DBUS_TYPE_ARRAY);
2309 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2311 _dbus_verbose ("invalid array type\n");
2315 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2318 _dbus_verbose ("invalid array length (<0)\n");
2322 if (len > _dbus_string_get_length (str) - pos)
2324 _dbus_verbose ("array length outside length of the message\n");
2330 if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
2331 array_type, array_type_pos,
2334 _dbus_verbose ("invalid array data\n");
2340 /* This should not be able to happen, as long as validate_arg moves forward;
2341 * but the check is here just to be paranoid.
2343 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2350 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2359 _dbus_verbose ("Unknown message arg type %d\n", type);
2363 if (*end_pos > _dbus_string_get_length (str))
2370 * Return #TRUE if the typecode is a valid typecode
2372 * @returns #TRUE if valid
2375 _dbus_type_is_valid (int typecode)
2379 case DBUS_TYPE_BYTE:
2380 case DBUS_TYPE_BOOLEAN:
2381 case DBUS_TYPE_INT32:
2382 case DBUS_TYPE_UINT32:
2383 case DBUS_TYPE_INT64:
2384 case DBUS_TYPE_UINT64:
2385 case DBUS_TYPE_DOUBLE:
2386 case DBUS_TYPE_STRING:
2387 case DBUS_TYPE_OBJECT_PATH:
2388 case DBUS_TYPE_ARRAY:
2389 case DBUS_TYPE_STRUCT:
2390 case DBUS_TYPE_VARIANT:
2399 * Gets the alignment requirement for the given type;
2400 * will be 1, 4, or 8.
2402 * @param typecode the type
2403 * @returns alignment of 1, 4, or 8
2406 _dbus_type_get_alignment (int typecode)
2410 case DBUS_TYPE_BYTE:
2411 case DBUS_TYPE_BOOLEAN:
2412 case DBUS_TYPE_VARIANT:
2413 case DBUS_TYPE_SIGNATURE:
2415 case DBUS_TYPE_INT32:
2416 case DBUS_TYPE_UINT32:
2417 /* this stuff is 4 since it starts with a length */
2418 case DBUS_TYPE_STRING:
2419 case DBUS_TYPE_OBJECT_PATH:
2420 case DBUS_TYPE_ARRAY:
2422 case DBUS_TYPE_INT64:
2423 case DBUS_TYPE_UINT64:
2424 case DBUS_TYPE_DOUBLE:
2425 /* struct is 8 since it could contain an 8-aligned item
2426 * and it's simpler to just always align structs to 8;
2427 * we want the amount of padding in a struct of a given
2428 * type to be predictable, not location-dependent.
2430 case DBUS_TYPE_STRUCT:
2434 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
2440 * If in verbose mode, print a block of binary data.
2442 * @todo right now it prints even if not in verbose mode
2444 * @param data the data
2445 * @param len the length of the data
2446 * @param offset where to start counting for byte indexes
2449 _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: ",
2481 offset + i, &data[i]);
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, start);
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 */