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 swap_8_octets (DBusOctets8 *value,
201 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
203 #ifdef DBUS_HAVE_INT64
204 value->u = DBUS_UINT64_SWAP_LE_BE (value->u);
206 swap_bytes ((unsigned char *)value, 8);
212 pack_8_octets (DBusOctets8 value,
216 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
218 #ifdef DBUS_HAVE_INT64
219 if ((byte_order) == DBUS_LITTLE_ENDIAN)
220 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
222 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
224 memcpy (data, &value, 8);
225 swap_8_octets ((DBusOctets8*)data, byte_order);
230 * Packs a 32 bit unsigned integer into a data pointer.
232 * @param value the value
233 * @param byte_order the byte order to use
234 * @param data the data pointer
237 _dbus_pack_uint32 (dbus_uint32_t value,
241 pack_4_octets (value, byte_order, data);
245 * Packs a 32 bit signed integer into a data pointer.
247 * @param value the value
248 * @param byte_order the byte order to use
249 * @param data the data pointer
252 _dbus_pack_int32 (dbus_int32_t value,
256 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
259 #ifdef DBUS_HAVE_INT64
261 * Packs a 64 bit unsigned integer into a data pointer.
263 * @param value the value
264 * @param byte_order the byte order to use
265 * @param data the data pointer
268 _dbus_pack_uint64 (dbus_uint64_t value,
274 pack_8_octets (r, byte_order, data);
278 * Packs a 64 bit signed integer into a data pointer.
280 * @param value the value
281 * @param byte_order the byte order to use
282 * @param data the data pointer
285 _dbus_pack_int64 (dbus_int64_t value,
291 pack_8_octets (r, byte_order, data);
293 #endif /* DBUS_HAVE_INT64 */
296 set_4_octets (DBusString *str,
303 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
304 byte_order == DBUS_BIG_ENDIAN);
306 data = _dbus_string_get_data_len (str, offset, 4);
308 _dbus_pack_uint32 (value, byte_order, data);
312 set_8_octets (DBusString *str,
319 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
320 byte_order == DBUS_BIG_ENDIAN);
322 data = _dbus_string_get_data_len (str, offset, 8);
324 pack_8_octets (value, byte_order, data);
328 * Sets the 4 bytes at the given offset to a marshaled signed integer,
329 * replacing anything found there previously.
331 * @param str the string to write the marshalled int to
332 * @param offset the byte offset where int should be written
333 * @param byte_order the byte order to use
334 * @param value the value
338 _dbus_marshal_set_int32 (DBusString *str,
343 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
347 * Sets the 4 bytes at the given offset to a marshaled unsigned
348 * integer, replacing anything found there previously.
350 * @param str the string to write the marshalled int to
351 * @param offset the byte offset where int should be written
352 * @param byte_order the byte order to use
353 * @param value the value
357 _dbus_marshal_set_uint32 (DBusString *str,
362 set_4_octets (str, byte_order, offset, value);
365 #ifdef DBUS_HAVE_INT64
368 * Sets the 8 bytes at the given offset to a marshaled signed integer,
369 * replacing anything found there previously.
371 * @param str the string to write the marshalled int to
372 * @param offset the byte offset where int should be written
373 * @param byte_order the byte order to use
374 * @param value the value
378 _dbus_marshal_set_int64 (DBusString *str,
385 set_8_octets (str, byte_order, offset, r);
389 * Sets the 8 bytes at the given offset to a marshaled unsigned
390 * integer, replacing anything found there previously.
392 * @param str the string to write the marshalled int to
393 * @param offset the byte offset where int should be written
394 * @param byte_order the byte order to use
395 * @param value the value
399 _dbus_marshal_set_uint64 (DBusString *str,
406 set_8_octets (str, byte_order, offset, r);
408 #endif /* DBUS_HAVE_INT64 */
411 * Sets the existing marshaled string at the given offset with
412 * a new marshaled string. The given offset must point to
413 * an existing string or the wrong length will be deleted
414 * and replaced with the new string.
416 * Note: no attempt is made by this function to re-align
417 * any data which has been already marshalled after this
418 * string. Use with caution.
420 * @param str the string to write the marshalled string to
421 * @param offset the byte offset where string should be written
422 * @param byte_order the byte order to use
423 * @param value the value
424 * @param len the length to use
425 * @returns #TRUE on success
429 _dbus_marshal_set_string (DBusString *str,
432 const DBusString *value,
437 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
438 byte_order == DBUS_BIG_ENDIAN);
440 old_len = _dbus_demarshal_uint32 (str, byte_order,
443 if (!_dbus_string_replace_len (value, 0, len,
444 str, offset + 4, old_len))
447 _dbus_marshal_set_uint32 (str, byte_order,
454 * Sets the existing marshaled object path at the given offset to a new
455 * value. The given offset must point to an existing object path or this
456 * function doesn't make sense.
458 * @todo implement this function
460 * @param str the string to write the marshalled path to
461 * @param offset the byte offset where path should be written
462 * @param byte_order the byte order to use
463 * @param path the new path
464 * @param path_len number of elements in the path
467 _dbus_marshal_set_object_path (DBusString *str,
478 marshal_4_octets (DBusString *str,
483 _dbus_assert (sizeof (value) == 4);
485 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
486 value = DBUS_UINT32_SWAP_LE_BE (value);
488 return _dbus_string_insert_4_aligned (str, insert_at,
489 (const unsigned char *)&value);
493 marshal_8_octets (DBusString *str,
498 _dbus_assert (sizeof (value) == 8);
500 swap_8_octets (&value, byte_order);
502 return _dbus_string_insert_8_aligned (str, insert_at,
503 (const unsigned char *)&value);
507 * Marshals a double value.
509 * @param str the string to append the marshalled value to
510 * @param byte_order the byte order to use
511 * @param value the value
512 * @returns #TRUE on success
515 _dbus_marshal_double (DBusString *str,
521 return marshal_8_octets (str, _dbus_string_get_length (str),
526 * Marshals a 32 bit signed integer value.
528 * @param str the string to append the marshalled value to
529 * @param byte_order the byte order to use
530 * @param value the value
531 * @returns #TRUE on success
534 _dbus_marshal_int32 (DBusString *str,
538 return marshal_4_octets (str, _dbus_string_get_length (str),
539 byte_order, (dbus_uint32_t) value);
543 * Marshals a 32 bit unsigned integer value.
545 * @param str the string to append the marshalled value to
546 * @param byte_order the byte order to use
547 * @param value the value
548 * @returns #TRUE on success
551 _dbus_marshal_uint32 (DBusString *str,
555 return marshal_4_octets (str, _dbus_string_get_length (str),
560 #ifdef DBUS_HAVE_INT64
562 * Marshals a 64 bit signed integer value.
564 * @param str the string to append the marshalled value to
565 * @param byte_order the byte order to use
566 * @param value the value
567 * @returns #TRUE on success
570 _dbus_marshal_int64 (DBusString *str,
576 return marshal_8_octets (str, _dbus_string_get_length (str),
581 * Marshals a 64 bit unsigned integer value.
583 * @param str the string to append the marshalled value to
584 * @param byte_order the byte order to use
585 * @param value the value
586 * @returns #TRUE on success
589 _dbus_marshal_uint64 (DBusString *str,
595 return marshal_8_octets (str, _dbus_string_get_length (str),
599 #endif /* DBUS_HAVE_INT64 */
602 * Marshals a UTF-8 string
604 * @todo: If the string append fails we need to restore
605 * the old length. (also for other marshallers)
607 * @param str the string to append the marshalled value to
608 * @param byte_order the byte order to use
609 * @param value the string
610 * @returns #TRUE on success
613 _dbus_marshal_string (DBusString *str,
617 int len, old_string_len;
619 old_string_len = _dbus_string_get_length (str);
621 len = strlen (value);
623 if (!_dbus_marshal_uint32 (str, byte_order, len))
625 /* Restore the previous length */
626 _dbus_string_set_length (str, old_string_len);
631 return _dbus_string_append_len (str, value, len + 1);
635 * Marshals a UTF-8 string
637 * @todo: If the string append fails we need to restore
638 * the old length. (also for other marshallers)
640 * @param str the string to append the marshalled value to
641 * @param byte_order the byte order to use
642 * @param value the string
643 * @param len length of string to marshal in bytes
644 * @returns #TRUE on success
647 _dbus_marshal_string_len (DBusString *str,
654 old_string_len = _dbus_string_get_length (str);
656 if (!_dbus_marshal_uint32 (str, byte_order, len))
658 /* Restore the previous length */
659 _dbus_string_set_length (str, old_string_len);
664 if (!_dbus_string_append_len (str, value, len))
668 if (!_dbus_string_lengthen (str, 1))
675 * Marshals a byte array
677 * @param str the string to append the marshalled value to
678 * @param byte_order the byte order to use
679 * @param value the array
680 * @param len number of elements in the array
681 * @returns #TRUE on success
684 _dbus_marshal_byte_array (DBusString *str,
686 const unsigned char *value,
691 old_string_len = _dbus_string_get_length (str);
693 if (!_dbus_marshal_uint32 (str, byte_order, len))
695 /* Restore the previous length */
696 _dbus_string_set_length (str, old_string_len);
704 return _dbus_string_append_len (str, value, len);
708 marshal_4_octets_array (DBusString *str,
710 const dbus_uint32_t *value,
716 old_string_len = _dbus_string_get_length (str);
718 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
721 array_start = _dbus_string_get_length (str);
723 if (!_dbus_string_append_len (str, (const unsigned char*) value,
727 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
729 const unsigned char *d;
730 const unsigned char *end;
732 d = _dbus_string_get_data (str) + array_start;
736 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
744 /* Restore previous length */
745 _dbus_string_set_length (str, old_string_len);
751 marshal_8_octets_array (DBusString *str,
753 const DBusOctets8 *value,
759 old_string_len = _dbus_string_get_length (str);
761 /* The array length is the length in bytes of the array,
762 * *excluding* alignment padding.
764 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
767 array_start = _dbus_string_get_length (str);
769 /* Note that we do alignment padding unconditionally
770 * even if the array is empty; this means that
771 * padding + len is always equal to the number of bytes
775 if (!_dbus_string_align_length (str, 8))
778 if (!_dbus_string_append_len (str, (const unsigned char*) value,
782 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
784 const unsigned char *d;
785 const unsigned char *end;
787 d = _dbus_string_get_data (str) + array_start;
791 #ifdef DBUS_HAVE_INT64
792 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
794 swap_bytes ((unsigned char*) d, 8);
803 /* Restore previous length */
804 _dbus_string_set_length (str, old_string_len);
810 * Marshals a 32 bit signed integer array
812 * @param str the string to append the marshalled value to
813 * @param byte_order the byte order to use
814 * @param value the array
815 * @param len the length of the array
816 * @returns #TRUE on success
819 _dbus_marshal_int32_array (DBusString *str,
821 const dbus_int32_t *value,
824 return marshal_4_octets_array (str, byte_order,
825 (const dbus_uint32_t*) value,
830 * Marshals a 32 bit unsigned integer array
832 * @param str the string to append the marshalled value to
833 * @param byte_order the byte order to use
834 * @param value the array
835 * @param len the length of the array
836 * @returns #TRUE on success
839 _dbus_marshal_uint32_array (DBusString *str,
841 const dbus_uint32_t *value,
844 return marshal_4_octets_array (str, byte_order,
849 #ifdef DBUS_HAVE_INT64
852 * Marshals a 64 bit signed integer array
854 * @param str the string to append the marshalled value to
855 * @param byte_order the byte order to use
856 * @param value the array
857 * @param len the length of the array
858 * @returns #TRUE on success
861 _dbus_marshal_int64_array (DBusString *str,
863 const dbus_int64_t *value,
866 return marshal_8_octets_array (str, byte_order,
867 (const DBusOctets8*) value,
872 * Marshals a 64 bit unsigned integer array
874 * @param str the string to append the marshalled value to
875 * @param byte_order the byte order to use
876 * @param value the array
877 * @param len the length of the array
878 * @returns #TRUE on success
881 _dbus_marshal_uint64_array (DBusString *str,
883 const dbus_uint64_t *value,
886 return marshal_8_octets_array (str, byte_order,
887 (const DBusOctets8*) value,
891 #endif /* DBUS_HAVE_INT64 */
894 * Marshals a double array
896 * @param str the string to append the marshalled value to
897 * @param byte_order the byte order to use
898 * @param value the array
899 * @param len the length of the array
900 * @returns #TRUE on success
903 _dbus_marshal_double_array (DBusString *str,
908 return marshal_8_octets_array (str, byte_order,
909 (const DBusOctets8*) value,
914 * Marshals a string array
916 * @param str the string to append the marshalled value to
917 * @param byte_order the byte order to use
918 * @param value the array
919 * @param len the length of the array
920 * @returns #TRUE on success
923 _dbus_marshal_string_array (DBusString *str,
928 int i, old_string_len, array_start;
930 old_string_len = _dbus_string_get_length (str);
932 /* Set the length to 0 temporarily */
933 if (!_dbus_marshal_uint32 (str, byte_order, 0))
936 array_start = _dbus_string_get_length (str);
938 for (i = 0; i < len; i++)
939 if (!_dbus_marshal_string (str, byte_order, value[i]))
942 /* Write the length now that we know it */
943 _dbus_marshal_set_uint32 (str, byte_order,
944 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
945 _dbus_string_get_length (str) - array_start);
950 /* Restore previous length */
951 _dbus_string_set_length (str, old_string_len);
957 * Marshals an object path value.
959 * @param str the string to append the marshalled value to
960 * @param byte_order the byte order to use
961 * @param path the path
962 * @param path_len length of the path
963 * @returns #TRUE on success
966 _dbus_marshal_object_path (DBusString *str,
971 int array_start, old_string_len;
974 old_string_len = _dbus_string_get_length (str);
976 /* Set the length to 0 temporarily */
977 if (!_dbus_marshal_uint32 (str, byte_order, 0))
980 array_start = _dbus_string_get_length (str);
985 if (!_dbus_string_append_byte (str, '/'))
988 if (!_dbus_string_append (str, path[0]))
994 /* Write the length now that we know it */
995 _dbus_marshal_set_uint32 (str, byte_order,
996 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
997 _dbus_string_get_length (str) - array_start);
1002 /* Restore the previous length */
1003 _dbus_string_set_length (str, old_string_len);
1008 static dbus_uint32_t
1009 demarshal_4_octets (const DBusString *str,
1014 const DBusRealString *real = (const DBusRealString*) str;
1016 pos = _DBUS_ALIGN_VALUE (pos, 4);
1021 return unpack_4_octets (byte_order, real->str + pos);
1025 demarshal_8_octets (const DBusString *str,
1030 const DBusRealString *real = (const DBusRealString*) str;
1032 pos = _DBUS_ALIGN_VALUE (pos, 8);
1037 return unpack_8_octets (byte_order, real->str + pos);
1041 * Demarshals a double.
1043 * @param str the string containing the data
1044 * @param byte_order the byte order
1045 * @param pos the position in the string
1046 * @param new_pos the new position of the string
1047 * @returns the demarshaled double.
1050 _dbus_demarshal_double (const DBusString *str,
1057 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1063 * Demarshals a 32 bit signed integer.
1065 * @param str the string containing the data
1066 * @param byte_order the byte order
1067 * @param pos the position in the string
1068 * @param new_pos the new position of the string
1069 * @returns the demarshaled integer.
1072 _dbus_demarshal_int32 (const DBusString *str,
1077 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
1081 * Demarshals a 32 bit unsigned integer.
1083 * @param str the string containing the data
1084 * @param byte_order the byte order
1085 * @param pos the position in the string
1086 * @param new_pos the new position of the string
1087 * @returns the demarshaled integer.
1090 _dbus_demarshal_uint32 (const DBusString *str,
1095 return demarshal_4_octets (str, byte_order, pos, new_pos);
1098 #ifdef DBUS_HAVE_INT64
1101 * Demarshals a 64 bit signed integer.
1103 * @param str the string containing the data
1104 * @param byte_order the byte order
1105 * @param pos the position in the string
1106 * @param new_pos the new position of the string
1107 * @returns the demarshaled integer.
1110 _dbus_demarshal_int64 (const DBusString *str,
1117 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1123 * Demarshals a 64 bit unsigned integer.
1125 * @param str the string containing the data
1126 * @param byte_order the byte order
1127 * @param pos the position in the string
1128 * @param new_pos the new position of the string
1129 * @returns the demarshaled integer.
1132 _dbus_demarshal_uint64 (const DBusString *str,
1139 r = demarshal_8_octets (str, byte_order, pos, new_pos);
1144 #endif /* DBUS_HAVE_INT64 */
1147 * Demarshals a basic type
1149 * @param str the string containing the data
1150 * @param type type of value to demarshal
1151 * @param value pointer to return value data
1152 * @param byte_order the byte order
1153 * @param pos pointer to position in the string,
1154 * updated on return to new position
1157 _dbus_demarshal_basic_type (const DBusString *str,
1163 const char *str_data = _dbus_string_get_const_data (str);
1167 case DBUS_TYPE_BYTE:
1168 case DBUS_TYPE_BOOLEAN:
1169 *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
1172 case DBUS_TYPE_INT32:
1173 case DBUS_TYPE_UINT32:
1174 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1175 *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
1176 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1177 *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
1180 #ifdef DBUS_HAVE_INT64
1181 case DBUS_TYPE_INT64:
1182 case DBUS_TYPE_UINT64:
1183 #endif /* DBUS_HAVE_INT64 */
1184 case DBUS_TYPE_DOUBLE:
1185 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1186 memcpy (value, str_data + *pos, 8);
1187 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1188 #ifdef DBUS_HAVE_INT64
1189 *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
1191 swap_bytes (value, 8);
1195 case DBUS_TYPE_STRING:
1196 _dbus_assert_not_reached ("FIXME string is a basic type");
1198 case DBUS_TYPE_OBJECT_PATH:
1199 _dbus_assert_not_reached ("FIXME object path is a basic type");
1202 _dbus_verbose ("type %s not a basic type\n",
1203 _dbus_type_to_string (type));
1204 _dbus_assert_not_reached ("not a basic type");
1210 * Demarshals an UTF-8 string.
1212 * @todo Should we check the string to make sure
1213 * that it's valid UTF-8, and maybe "fix" the string
1216 * @todo Should probably demarshal to a DBusString,
1217 * having memcpy() in here is Evil(tm).
1219 * @param str the string containing the data
1220 * @param byte_order the byte order
1221 * @param pos the position in the string
1222 * @param new_pos the new position of the string
1223 * @returns the demarshaled string.
1226 _dbus_demarshal_string (const DBusString *str,
1235 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1237 retval = dbus_malloc (len + 1);
1242 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1247 memcpy (retval, data, len + 1);
1250 *new_pos = pos + len + 1;
1256 * Demarshals a byte array.
1258 * @todo Should probably demarshal to a DBusString,
1259 * having memcpy() in here is Evil(tm).
1261 * @param str the string containing the data
1262 * @param byte_order the byte order
1263 * @param pos the position in the string
1264 * @param new_pos the new position of the string
1265 * @param array the array
1266 * @param array_len length of the demarshaled data
1268 * @returns #TRUE on success
1271 _dbus_demarshal_byte_array (const DBusString *str,
1275 unsigned char **array,
1279 unsigned char *retval;
1282 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1295 retval = dbus_malloc (len);
1300 data = _dbus_string_get_const_data_len (str, pos, len);
1308 memcpy (retval, data, len);
1311 *new_pos = pos + len;
1320 demarshal_4_octets_array (const DBusString *str,
1324 dbus_uint32_t **array,
1328 dbus_uint32_t *retval;
1331 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1345 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1349 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1351 for (i = 0; i < len; i++)
1352 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
1356 *new_pos = pos + byte_len;
1365 demarshal_8_octets_array (const DBusString *str,
1369 DBusOctets8 **array,
1373 DBusOctets8 *retval;
1376 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1378 pos = _DBUS_ALIGN_VALUE (pos, 8);
1393 if (!_dbus_string_copy_data_len (str, (char**) &retval,
1397 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
1399 for (i = 0; i < len; i++)
1401 #ifdef DBUS_HAVE_INT64
1402 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
1404 swap_bytes ((unsigned char *) &retval[i], 8);
1410 *new_pos = pos + byte_len;
1419 * Demarshals a 32 bit signed integer array.
1421 * @param str the string containing the data
1422 * @param byte_order the byte order
1423 * @param pos the position in the string
1424 * @param new_pos the new position of the string
1425 * @param array the array
1426 * @param array_len length of the demarshaled data
1427 * @returns #TRUE on success
1430 _dbus_demarshal_int32_array (const DBusString *str,
1434 dbus_int32_t **array,
1437 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1438 (dbus_uint32_t**) array, array_len);
1442 * Demarshals a 32 bit unsigned integer array.
1444 * @param str the string containing the data
1445 * @param byte_order the byte order
1446 * @param pos the position in the string
1447 * @param new_pos the new position of the string
1448 * @param array the array
1449 * @param array_len length of the demarshaled data
1450 * @returns #TRUE on success
1453 _dbus_demarshal_uint32_array (const DBusString *str,
1457 dbus_uint32_t **array,
1460 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
1464 #ifdef DBUS_HAVE_INT64
1467 * Demarshals a 64 bit signed integer array.
1469 * @param str the string containing the data
1470 * @param byte_order the byte order
1471 * @param pos the position in the string
1472 * @param new_pos the new position of the string
1473 * @param array the array
1474 * @param array_len length of the demarshaled data
1475 * @returns #TRUE on success
1478 _dbus_demarshal_int64_array (const DBusString *str,
1482 dbus_int64_t **array,
1485 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1486 (DBusOctets8**) array, array_len);
1490 * Demarshals a 64 bit unsigned integer array.
1492 * @param str the string containing the data
1493 * @param byte_order the byte order
1494 * @param pos the position in the string
1495 * @param new_pos the new position of the string
1496 * @param array the array
1497 * @param array_len length of the demarshaled data
1498 * @returns #TRUE on success
1501 _dbus_demarshal_uint64_array (const DBusString *str,
1505 dbus_uint64_t **array,
1508 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1509 (DBusOctets8**) array, array_len);
1512 #endif /* DBUS_HAVE_INT64 */
1515 * Demarshals a double array.
1517 * @param str the string containing the data
1518 * @param byte_order the byte order
1519 * @param pos the position in the string
1520 * @param new_pos the new position of the string
1521 * @param array the array
1522 * @param array_len length of the demarshaled data
1523 * @returns #TRUE on success
1526 _dbus_demarshal_double_array (const DBusString *str,
1533 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
1534 (DBusOctets8**) array, array_len);
1539 * Demarshals an array of basic types
1541 * @param str the string containing the data
1542 * @param element_type type of array elements to demarshal
1543 * @param array pointer to pointer to array data
1544 * @param array_len pointer to array length
1545 * @param byte_order the byte order
1546 * @param pos pointer to position in the string,
1547 * updated on return to new position
1550 _dbus_demarshal_basic_type_array (const DBusString *str,
1557 switch (element_type)
1559 case DBUS_TYPE_BOOLEAN:
1560 /* FIXME: do we want to post-normalize these ? */
1561 case DBUS_TYPE_BYTE:
1562 return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
1563 (unsigned char **)array, array_len);
1565 case DBUS_TYPE_INT32:
1566 case DBUS_TYPE_UINT32:
1567 return demarshal_4_octets_array (str, byte_order, *pos, pos,
1568 (dbus_uint32_t **)array, array_len);
1570 #ifdef DBUS_HAVE_INT64
1571 case DBUS_TYPE_INT64:
1572 case DBUS_TYPE_UINT64:
1573 #endif /* DBUS_HAVE_INT64 */
1574 case DBUS_TYPE_DOUBLE:
1575 return demarshal_8_octets_array (str, byte_order, *pos, pos,
1576 (DBusOctets8**) array, array_len);
1578 _dbus_assert_not_reached ("not a basic type");
1585 * Demarshals a string array.
1587 * @param str the string containing the data
1588 * @param byte_order the byte order
1589 * @param pos the position in the string
1590 * @param new_pos the new position of the string
1591 * @param array the array
1592 * @param array_len location for length of the demarshaled data or NULL
1593 * @returns #TRUE on success
1596 _dbus_demarshal_string_array (const DBusString *str,
1608 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1623 end_pos = pos + bytes_len;
1625 retval = dbus_new (char *, allocated);
1630 while (pos < end_pos)
1632 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1634 if (retval[len] == NULL)
1639 if (len >= allocated - 1) /* -1 for NULL termination */
1642 newp = dbus_realloc (retval,
1643 sizeof (char*) * allocated * 2);
1663 for (i = 0; i < len; i++)
1664 dbus_free (retval[i]);
1670 /** Set to 1 to get a bunch of spew about disassembling the path string */
1671 #define VERBOSE_DECOMPOSE 0
1674 * Decompose an object path. A path of just "/" is
1675 * represented as an empty vector of strings.
1677 * @param data the path data
1678 * @param len the length of the path string
1679 * @param path address to store new object path
1680 * @param path_len length of stored path
1683 _dbus_decompose_path (const char* data,
1692 _dbus_assert (data != NULL);
1694 #if VERBOSE_DECOMPOSE
1695 _dbus_verbose ("Decomposing path \"%s\"\n",
1708 retval = dbus_new0 (char*, n_components + 1);
1721 while (j < len && data[j] != '/')
1724 /* Now [i, j) is the path component */
1725 _dbus_assert (i < j);
1726 _dbus_assert (data[i] != '/');
1727 _dbus_assert (j == len || data[j] == '/');
1729 #if VERBOSE_DECOMPOSE
1730 _dbus_verbose (" (component in [%d,%d))\n",
1734 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
1735 if (retval[comp] == NULL)
1737 dbus_free_string_array (retval);
1740 retval[comp][j-i] = '\0';
1741 #if VERBOSE_DECOMPOSE
1742 _dbus_verbose (" (component %d = \"%s\")\n",
1743 comp, retval[comp]);
1749 _dbus_assert (i == len);
1753 *path_len = n_components;
1759 * Demarshals an object path. A path of just "/" is
1760 * represented as an empty vector of strings.
1762 * @param str the string containing the data
1763 * @param byte_order the byte order
1764 * @param pos the position in the string
1765 * @param new_pos the new position of the string
1766 * @param path address to store new object path
1767 * @param path_len length of stored path
1770 _dbus_demarshal_object_path (const DBusString *str,
1780 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1781 data = _dbus_string_get_const_data_len (str, pos, len + 1);
1783 if (!_dbus_decompose_path (data, len, path, path_len))
1787 *new_pos = pos + len + 1;
1793 * Skips over a basic type, reporting the following position.
1795 * @param str the string containing the data
1796 * @param type type of value to demarshal
1797 * @param byte_order the byte order
1798 * @param pos pointer to position in the string,
1799 * updated on return to new position
1802 _dbus_marshal_skip_basic_type (const DBusString *str,
1809 case DBUS_TYPE_BYTE:
1810 case DBUS_TYPE_BOOLEAN:
1813 case DBUS_TYPE_INT32:
1814 case DBUS_TYPE_UINT32:
1815 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1818 #ifdef DBUS_HAVE_INT64
1819 case DBUS_TYPE_INT64:
1820 case DBUS_TYPE_UINT64:
1821 #endif /* DBUS_HAVE_INT64 */
1822 case DBUS_TYPE_DOUBLE:
1823 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1826 case DBUS_TYPE_STRING:
1827 _dbus_assert_not_reached ("FIXME string is a basic type");
1829 case DBUS_TYPE_OBJECT_PATH:
1830 _dbus_assert_not_reached ("FIXME object path is a basic type");
1833 _dbus_verbose ("type %s not a basic type\n",
1834 _dbus_type_to_string (type));
1835 _dbus_assert_not_reached ("not a basic type");
1841 * Skips an array, returning the next position.
1843 * @param str the string containing the data
1844 * @param byte_order the byte order
1845 * @param pos pointer to position in the string,
1846 * updated on return to new position
1849 _dbus_marshal_skip_array (const DBusString *str,
1855 len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
1857 /* FIXME we need to insert alignment padding according to array type */
1863 * Returns the position right after the end of an argument. PERFORMS
1864 * NO VALIDATION WHATSOEVER. The message must have been previously
1867 * @param str a string
1868 * @param byte_order the byte order to use
1869 * @param type the type of the argument
1870 * @param pos the pos where the arg starts
1871 * @param end_pos pointer where the position right
1872 * after the end position will follow
1873 * @returns TRUE if more data exists after the arg
1876 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1882 if (pos >= _dbus_string_get_length (str))
1887 case DBUS_TYPE_INVALID:
1891 case DBUS_TYPE_BYTE:
1895 case DBUS_TYPE_BOOLEAN:
1899 case DBUS_TYPE_INT32:
1900 case DBUS_TYPE_UINT32:
1901 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
1904 case DBUS_TYPE_INT64:
1905 case DBUS_TYPE_UINT64:
1906 case DBUS_TYPE_DOUBLE:
1908 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
1911 case DBUS_TYPE_OBJECT_PATH:
1912 case DBUS_TYPE_STRING:
1916 /* Demarshal the length */
1917 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1919 *end_pos = pos + len + 1;
1923 case DBUS_TYPE_ARRAY:
1927 /* Demarshal the length */
1928 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1930 /* FIXME needs to align to the right boundary for the array type */
1931 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + len;
1936 _dbus_warn ("Unknown message arg type %d\n", type);
1937 _dbus_assert_not_reached ("Unknown message argument type\n");
1941 if (*end_pos > _dbus_string_get_length (str))
1948 * Demarshals and validates a length; returns < 0 if the validation
1949 * fails. The length is required to be small enough that
1950 * len*sizeof(double) will not overflow, and small enough to fit in a
1951 * signed integer. DOES NOT check whether the length points
1952 * beyond the end of the string, because it doesn't know the
1953 * size of array elements.
1955 * @param str the string
1956 * @param byte_order the byte order
1957 * @param pos the unaligned string position (snap to next aligned)
1958 * @param new_pos return location for new position.
1961 demarshal_and_validate_len (const DBusString *str,
1966 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1969 _dbus_assert (new_pos != NULL);
1971 if ((align_4 + 4) > _dbus_string_get_length (str))
1973 _dbus_verbose ("not enough room in message for array length\n");
1977 if (!_dbus_string_validate_nul (str, pos,
1980 _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
1984 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1986 /* note that the len is the number of bytes, so we need it to be
1987 * at least SIZE_T_MAX, but make it smaller just to keep things
1988 * sane. We end up using ints for most sizes to avoid unsigned mess
1989 * so limit to maximum 32-bit signed int divided by at least 8, more
1990 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1992 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1993 if (len > MAX_ARRAY_LENGTH)
1995 _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
1996 len, MAX_ARRAY_LENGTH, pos);
2004 validate_string (const DBusString *str,
2006 int len_without_nul,
2009 *end_pos = pos + len_without_nul + 1;
2011 if (*end_pos > _dbus_string_get_length (str))
2013 _dbus_verbose ("string length outside length of the message\n");
2017 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
2019 _dbus_verbose ("string arg not nul-terminated\n");
2023 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
2025 _dbus_verbose ("string is not valid UTF-8\n");
2033 * Validates and returns a typecode at a specific position
2036 * @param str a string
2037 * @param type the type of the argument
2038 * @param pos the pos where the typecode starts
2039 * @param end_pos pointer where the position right
2040 * after the end position will follow
2041 * @returns #TRUE if the type is valid.
2044 _dbus_marshal_validate_type (const DBusString *str,
2051 if (pos >= _dbus_string_get_length (str))
2054 data = _dbus_string_get_const_data_len (str, pos, 1);
2056 if (_dbus_type_is_valid (*data))
2059 if (end_pos != NULL)
2064 _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
2069 /* Faster validator for array data that doesn't call
2070 * validate_arg for each value
2073 validate_array_data (const DBusString *str,
2084 case DBUS_TYPE_INVALID:
2088 case DBUS_TYPE_OBJECT_PATH:
2089 case DBUS_TYPE_STRING:
2090 case DBUS_TYPE_ARRAY:
2091 /* This clean recursion to validate_arg is what we
2092 * are doing logically for all types, but we don't
2093 * really want to call validate_arg for every byte
2094 * in a byte array, so the primitive types are
2099 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2100 type, array_type_pos, pos, &pos))
2105 case DBUS_TYPE_BYTE:
2109 case DBUS_TYPE_BOOLEAN:
2114 c = _dbus_string_get_byte (str, pos);
2116 if (!(c == 0 || c == 1))
2118 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2126 case DBUS_TYPE_INT32:
2127 case DBUS_TYPE_UINT32:
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, 4);
2137 case DBUS_TYPE_INT64:
2138 case DBUS_TYPE_UINT64:
2139 case DBUS_TYPE_DOUBLE:
2140 /* Call validate arg one time to check alignment padding
2143 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
2144 type, array_type_pos, pos, &pos))
2146 pos = _DBUS_ALIGN_VALUE (end, 8);
2150 _dbus_verbose ("Unknown message arg type %d\n", type);
2160 * Validates an argument of a specific type, checking that it
2161 * is well-formed, for example no ludicrous length fields, strings
2162 * are nul-terminated, etc.
2163 * Returns the end position of the argument in end_pos, and
2164 * returns #TRUE if a valid arg begins at "pos"
2166 * @todo security: need to audit this function.
2168 * @param str a string
2169 * @param byte_order the byte order to use
2170 * @param depth current recursion depth, to prevent excessive recursion
2171 * @param type the type of the argument
2172 * @param array_type_pos the position of the current array type, or
2173 * -1 if not in an array
2174 * @param pos the pos where the arg starts
2175 * @param end_pos pointer where the position right
2176 * after the end position will follow
2177 * @returns #TRUE if the arg is valid.
2180 _dbus_marshal_validate_arg (const DBusString *str,
2188 if (pos > _dbus_string_get_length (str))
2190 _dbus_verbose ("Validation went off the end of the message\n");
2194 #define MAX_VALIDATION_DEPTH 32
2196 if (depth > MAX_VALIDATION_DEPTH)
2198 _dbus_verbose ("Maximum recursion depth reached validating message\n");
2204 case DBUS_TYPE_INVALID:
2208 case DBUS_TYPE_BYTE:
2209 if (1 > _dbus_string_get_length (str) - pos)
2211 _dbus_verbose ("no room for byte value\n");
2218 case DBUS_TYPE_BOOLEAN:
2222 if (1 > _dbus_string_get_length (str) - pos)
2224 _dbus_verbose ("no room for boolean value\n");
2228 c = _dbus_string_get_byte (str, pos);
2230 if (!(c == 0 || c == 1))
2232 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
2240 case DBUS_TYPE_INT32:
2241 case DBUS_TYPE_UINT32:
2243 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
2245 if (!_dbus_string_validate_nul (str, pos,
2248 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
2252 *end_pos = align_4 + 4;
2256 case DBUS_TYPE_INT64:
2257 case DBUS_TYPE_UINT64:
2258 case DBUS_TYPE_DOUBLE:
2260 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
2262 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
2264 if (!_dbus_string_validate_nul (str, pos,
2267 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
2271 *end_pos = align_8 + 8;
2275 case DBUS_TYPE_OBJECT_PATH:
2276 case DBUS_TYPE_STRING:
2280 /* Demarshal the length, which does NOT include
2283 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2287 if (!validate_string (str, pos, len, end_pos))
2290 if (type == DBUS_TYPE_OBJECT_PATH)
2292 if (!_dbus_string_validate_path (str, pos, len))
2298 case DBUS_TYPE_ARRAY:
2304 if (array_type_pos == -1)
2306 array_type_pos = pos;
2310 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
2312 _dbus_verbose ("invalid array type\n");
2316 while (array_type == DBUS_TYPE_ARRAY);
2321 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
2323 _dbus_verbose ("invalid array type\n");
2327 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
2330 _dbus_verbose ("invalid array length (<0)\n");
2334 if (len > _dbus_string_get_length (str) - pos)
2336 _dbus_verbose ("array length outside length of the message\n");
2342 if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
2343 array_type, array_type_pos,
2346 _dbus_verbose ("invalid array data\n");
2352 /* This should not be able to happen, as long as validate_arg moves forward;
2353 * but the check is here just to be paranoid.
2355 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
2362 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
2371 _dbus_verbose ("Unknown message arg type %d\n", type);
2375 if (*end_pos > _dbus_string_get_length (str))
2382 * Return #TRUE if the typecode is a valid typecode
2384 * @returns #TRUE if valid
2387 _dbus_type_is_valid (int typecode)
2391 case DBUS_TYPE_BYTE:
2392 case DBUS_TYPE_BOOLEAN:
2393 case DBUS_TYPE_INT32:
2394 case DBUS_TYPE_UINT32:
2395 case DBUS_TYPE_INT64:
2396 case DBUS_TYPE_UINT64:
2397 case DBUS_TYPE_DOUBLE:
2398 case DBUS_TYPE_STRING:
2399 case DBUS_TYPE_OBJECT_PATH:
2400 case DBUS_TYPE_ARRAY:
2401 case DBUS_TYPE_STRUCT:
2402 case DBUS_TYPE_VARIANT:
2411 * Gets the alignment requirement for the given type;
2412 * will be 1, 4, or 8.
2414 * @param typecode the type
2415 * @returns alignment of 1, 4, or 8
2418 _dbus_type_get_alignment (int typecode)
2422 case DBUS_TYPE_BYTE:
2423 case DBUS_TYPE_BOOLEAN:
2424 case DBUS_TYPE_VARIANT:
2425 case DBUS_TYPE_SIGNATURE:
2427 case DBUS_TYPE_INT32:
2428 case DBUS_TYPE_UINT32:
2429 /* this stuff is 4 since it starts with a length */
2430 case DBUS_TYPE_STRING:
2431 case DBUS_TYPE_OBJECT_PATH:
2432 case DBUS_TYPE_ARRAY:
2434 case DBUS_TYPE_INT64:
2435 case DBUS_TYPE_UINT64:
2436 case DBUS_TYPE_DOUBLE:
2437 /* struct is 8 since it could contain an 8-aligned item
2438 * and it's simpler to just always align structs to 8;
2439 * we want the amount of padding in a struct of a given
2440 * type to be predictable, not location-dependent.
2442 case DBUS_TYPE_STRUCT:
2446 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
2452 * If in verbose mode, print a block of binary data.
2454 * @todo right now it prints even if not in verbose mode
2456 * @param data the data
2457 * @param len the length of the data
2458 * @param offset where to start counting for byte indexes
2461 _dbus_verbose_bytes (const unsigned char *data,
2466 const unsigned char *aligned;
2468 _dbus_assert (len >= 0);
2470 /* Print blanks on first row if appropriate */
2471 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
2474 _dbus_assert (aligned <= data);
2476 if (aligned != data)
2478 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
2479 while (aligned != data)
2481 _dbus_verbose (" ");
2486 /* now print the bytes */
2490 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2492 _dbus_verbose ("%4d\t%p: ",
2493 offset + i, &data[i]);
2496 if (data[i] >= 32 &&
2498 _dbus_verbose (" '%c' ", data[i]);
2500 _dbus_verbose ("0x%s%x ",
2501 data[i] <= 0xf ? "0" : "", data[i]);
2505 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
2508 _dbus_verbose ("BE: %d LE: %d",
2509 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
2510 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
2513 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
2515 _dbus_verbose (" dbl: %g",
2516 *(double*)&data[i-8]);
2519 _dbus_verbose ("\n");
2523 _dbus_verbose ("\n");
2527 * Dump the given part of the string to verbose log.
2529 * @param str the string
2530 * @param start the start of range to dump
2531 * @param len length of range
2534 _dbus_verbose_bytes_of_string (const DBusString *str,
2541 real_len = _dbus_string_get_length (str);
2543 _dbus_assert (start >= 0);
2545 if (start > real_len)
2547 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
2548 start, len, real_len);
2552 if ((start + len) > real_len)
2554 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
2555 start, len, real_len);
2556 len = real_len - start;
2559 d = _dbus_string_get_const_data_len (str, start, len);
2561 _dbus_verbose_bytes (d, len, start);
2565 * Marshals a basic type
2567 * @param str string to marshal to
2568 * @param insert_at where to insert the value
2569 * @param type type of value
2570 * @param value pointer to value
2571 * @param byte_order byte order
2572 * @returns #TRUE on success
2575 _dbus_marshal_basic_type (DBusString *str,
2585 case DBUS_TYPE_BYTE:
2586 case DBUS_TYPE_BOOLEAN:
2587 retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
2589 case DBUS_TYPE_INT32:
2590 case DBUS_TYPE_UINT32:
2591 return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
2593 #ifdef DBUS_HAVE_INT64
2594 case DBUS_TYPE_INT64:
2595 case DBUS_TYPE_UINT64:
2598 r.u = *(const dbus_uint64_t *)value;
2599 retval = marshal_8_octets (str, insert_at, byte_order, r);
2602 #endif /* DBUS_HAVE_INT64 */
2603 case DBUS_TYPE_DOUBLE:
2606 r.d = *(const double *)value;
2607 retval = marshal_8_octets (str, insert_at, byte_order, r);
2611 _dbus_assert_not_reached ("not a basic type");
2619 * Marshals a basic type array
2621 * @param str string to marshal to
2622 * @param insert_at where to insert the value
2623 * @param element_type type of array elements
2624 * @param value pointer to value
2625 * @param len length of value data in elements
2626 * @param byte_order byte order
2627 * @returns #TRUE on success
2630 _dbus_marshal_basic_type_array (DBusString *str,
2637 /* FIXME use the insert_at arg */
2639 switch (element_type)
2641 case DBUS_TYPE_BOOLEAN:
2642 /* FIXME: we canonicalize to 0 or 1 for the single boolean case
2643 * should we here too ? */
2644 case DBUS_TYPE_BYTE:
2645 return _dbus_marshal_byte_array (str, byte_order, value, len);
2647 case DBUS_TYPE_INT32:
2648 case DBUS_TYPE_UINT32:
2649 return marshal_4_octets_array (str, byte_order, value, len);
2651 #ifdef DBUS_HAVE_INT64
2652 case DBUS_TYPE_INT64:
2653 case DBUS_TYPE_UINT64:
2654 #endif /* DBUS_HAVE_INT64 */
2655 case DBUS_TYPE_DOUBLE:
2656 return marshal_8_octets_array (str, byte_order, value, len);
2659 _dbus_assert_not_reached ("non basic type in array");
2667 #ifdef DBUS_BUILD_TESTS
2668 #include "dbus-test.h"
2672 _dbus_marshal_test (void)
2677 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
2678 #ifdef DBUS_HAVE_INT64
2679 dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
2680 DBUS_INT64_CONSTANT (0x456ffffffff),
2681 DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
2686 if (!_dbus_string_init (&str))
2687 _dbus_assert_not_reached ("failed to init string");
2689 /* Marshal doubles */
2690 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2691 _dbus_assert_not_reached ("could not marshal double value");
2692 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2693 _dbus_assert_not_reached ("demarshal failed");
2695 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2696 _dbus_assert_not_reached ("could not marshal double value");
2697 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2698 _dbus_assert_not_reached ("demarshal failed");
2700 /* Marshal signed integers */
2701 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2702 _dbus_assert_not_reached ("could not marshal signed integer value");
2703 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2704 _dbus_assert_not_reached ("demarshal failed");
2706 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2707 _dbus_assert_not_reached ("could not marshal signed integer value");
2708 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2709 _dbus_assert_not_reached ("demarshal failed");
2711 /* Marshal unsigned integers */
2712 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2713 _dbus_assert_not_reached ("could not marshal signed integer value");
2714 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2715 _dbus_assert_not_reached ("demarshal failed");
2717 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2718 _dbus_assert_not_reached ("could not marshal signed integer value");
2719 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2720 _dbus_assert_not_reached ("demarshal failed");
2722 #ifdef DBUS_HAVE_INT64
2723 /* Marshal signed integers */
2724 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2725 _dbus_assert_not_reached ("could not marshal signed integer value");
2726 if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2727 _dbus_assert_not_reached ("demarshal failed");
2729 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
2730 _dbus_assert_not_reached ("could not marshal signed integer value");
2731 if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
2732 _dbus_assert_not_reached ("demarshal failed");
2734 /* Marshal unsigned integers */
2735 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2736 _dbus_assert_not_reached ("could not marshal signed integer value");
2737 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2738 _dbus_assert_not_reached ("demarshal failed");
2740 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
2741 _dbus_assert_not_reached ("could not marshal signed integer value");
2742 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
2743 _dbus_assert_not_reached ("demarshal failed");
2744 #endif /* DBUS_HAVE_INT64 */
2746 /* Marshal strings */
2747 tmp1 = "This is the dbus test string";
2748 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2749 _dbus_assert_not_reached ("could not marshal string");
2750 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2751 if (!strcmp (tmp1, tmp2) == 0)
2752 _dbus_assert_not_reached ("demarshal failed");
2755 tmp1 = "This is the dbus test string";
2756 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2757 _dbus_assert_not_reached ("could not marshal string");
2758 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2759 if (!strcmp (tmp1, tmp2) == 0)
2760 _dbus_assert_not_reached ("demarshal failed");
2763 /* Marshal signed integer arrays */
2764 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2765 _dbus_assert_not_reached ("could not marshal integer array");
2766 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2767 _dbus_assert_not_reached ("could not demarshal integer array");
2770 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2773 #ifdef DBUS_HAVE_INT64
2774 /* Marshal 64-bit signed integer arrays */
2775 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
2776 _dbus_assert_not_reached ("could not marshal integer array");
2777 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
2778 _dbus_assert_not_reached ("could not demarshal integer array");
2781 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2784 /* set/pack 64-bit integers */
2785 _dbus_string_set_length (&str, 8);
2788 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
2789 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2791 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2792 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2793 _dbus_string_get_const_data (&str)));
2796 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
2797 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
2799 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2800 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2801 _dbus_string_get_const_data (&str)));
2803 /* signed little pack */
2804 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2806 _dbus_string_get_data (&str));
2808 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2809 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
2810 _dbus_string_get_const_data (&str)));
2812 /* signed big pack */
2813 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
2815 _dbus_string_get_data (&str));
2817 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
2818 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
2819 _dbus_string_get_const_data (&str)));
2821 /* unsigned little */
2822 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
2823 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2825 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2826 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2827 _dbus_string_get_const_data (&str)));
2830 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
2831 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
2833 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2834 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2835 _dbus_string_get_const_data (&str)));
2837 /* unsigned little pack */
2838 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2840 _dbus_string_get_data (&str));
2842 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2843 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
2844 _dbus_string_get_const_data (&str)));
2846 /* unsigned big pack */
2847 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
2849 _dbus_string_get_data (&str));
2851 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
2852 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
2853 _dbus_string_get_const_data (&str)));
2857 /* set/pack 32-bit integers */
2858 _dbus_string_set_length (&str, 4);
2861 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
2864 _dbus_assert (-0x123456 ==
2865 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2866 _dbus_string_get_const_data (&str)));
2869 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
2872 _dbus_assert (-0x123456 ==
2873 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2874 _dbus_string_get_const_data (&str)));
2876 /* signed little pack */
2877 _dbus_pack_int32 (-0x123456,
2879 _dbus_string_get_data (&str));
2881 _dbus_assert (-0x123456 ==
2882 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
2883 _dbus_string_get_const_data (&str)));
2885 /* signed big pack */
2886 _dbus_pack_int32 (-0x123456,
2888 _dbus_string_get_data (&str));
2890 _dbus_assert (-0x123456 ==
2891 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
2892 _dbus_string_get_const_data (&str)));
2894 /* unsigned little */
2895 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
2898 _dbus_assert (0x123456 ==
2899 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2900 _dbus_string_get_const_data (&str)));
2903 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
2906 _dbus_assert (0x123456 ==
2907 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2908 _dbus_string_get_const_data (&str)));
2910 /* unsigned little pack */
2911 _dbus_pack_uint32 (0x123456,
2913 _dbus_string_get_data (&str));
2915 _dbus_assert (0x123456 ==
2916 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
2917 _dbus_string_get_const_data (&str)));
2919 /* unsigned big pack */
2920 _dbus_pack_uint32 (0x123456,
2922 _dbus_string_get_data (&str));
2924 _dbus_assert (0x123456 ==
2925 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
2926 _dbus_string_get_const_data (&str)));
2931 _dbus_string_set_length (&str, 0);
2933 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
2936 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2937 _dbus_assert (strcmp (s, "Hello world") == 0);
2940 _dbus_string_init_const (&t, "Hello world foo");
2942 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2943 &t, _dbus_string_get_length (&t));
2945 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2946 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2949 _dbus_string_init_const (&t, "Hello");
2951 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
2952 &t, _dbus_string_get_length (&t));
2954 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
2955 _dbus_assert (strcmp (s, "Hello") == 0);
2958 /* Strings (big endian) */
2960 _dbus_string_set_length (&str, 0);
2962 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
2965 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2966 _dbus_assert (strcmp (s, "Hello world") == 0);
2969 _dbus_string_init_const (&t, "Hello world foo");
2971 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2972 &t, _dbus_string_get_length (&t));
2974 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2975 _dbus_assert (strcmp (s, "Hello world foo") == 0);
2978 _dbus_string_init_const (&t, "Hello");
2980 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
2981 &t, _dbus_string_get_length (&t));
2983 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
2984 _dbus_assert (strcmp (s, "Hello") == 0);
2987 _dbus_string_free (&str);
2992 #endif /* DBUS_BUILD_TESTS */