D-Bus 1.14.10
dbus-marshal-basic.c
1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2/* dbus-marshal-basic.c Marshalling routines for basic (primitive) types
3 *
4 * Copyright (C) 2002 CodeFactory AB
5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
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.
13 *
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.
18 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include <config.h>
26#include "dbus-internals.h"
27#include "dbus-marshal-basic.h"
28#include "dbus-signature.h"
29#include <dbus/dbus-test-tap.h>
30
31#include <string.h>
32
33#if !defined(PRIx64) && defined(DBUS_WIN)
34#define PRIx64 "I64x"
35#endif
36
37#if defined(__GNUC__) && (__GNUC__ >= 4)
38# define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
39 _DBUS_STATIC_ASSERT (__extension__ __alignof__ (type) op val)
40# define _DBUS_ASSERT_CMP_ALIGNMENT(left, op, right) \
41 _DBUS_STATIC_ASSERT (__extension__ __alignof__ (left) op __extension__ __alignof__ (right))
42#else
43 /* not gcc, so probably no alignof operator: just use a no-op statement
44 * that's valid in the same contexts */
45# define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
46 _DBUS_STATIC_ASSERT (TRUE)
47# define _DBUS_ASSERT_CMP_ALIGNMENT(left, op, right) \
48 _DBUS_STATIC_ASSERT (TRUE)
49#endif
50
51/* True by definition, but just for completeness... */
52_DBUS_STATIC_ASSERT (sizeof (char) == 1);
53_DBUS_ASSERT_ALIGNMENT (char, ==, 1);
54
55_DBUS_STATIC_ASSERT (sizeof (dbus_int16_t) == 2);
56_DBUS_ASSERT_ALIGNMENT (dbus_int16_t, <=, 2);
57_DBUS_STATIC_ASSERT (sizeof (dbus_uint16_t) == 2);
58_DBUS_ASSERT_ALIGNMENT (dbus_uint16_t, <=, 2);
59_DBUS_ASSERT_CMP_ALIGNMENT (dbus_uint16_t, ==, dbus_int16_t);
60
61_DBUS_STATIC_ASSERT (sizeof (dbus_int32_t) == 4);
62_DBUS_ASSERT_ALIGNMENT (dbus_int32_t, <=, 4);
63_DBUS_STATIC_ASSERT (sizeof (dbus_uint32_t) == 4);
64_DBUS_ASSERT_ALIGNMENT (dbus_uint32_t, <=, 4);
65_DBUS_ASSERT_CMP_ALIGNMENT (dbus_uint32_t, ==, dbus_int32_t);
66_DBUS_STATIC_ASSERT (sizeof (dbus_bool_t) == 4);
67_DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4);
68_DBUS_ASSERT_CMP_ALIGNMENT (dbus_uint32_t, ==, dbus_bool_t);
69
70_DBUS_STATIC_ASSERT (sizeof (double) == 8);
71_DBUS_ASSERT_ALIGNMENT (double, <=, 8);
72/* Doubles might sometimes be more strictly aligned than int64, but we
73 * assume they are no less strictly aligned. This means every (double *)
74 * has enough alignment to be treated as though it was a
75 * (dbus_uint64_t *). */
76_DBUS_ASSERT_CMP_ALIGNMENT (dbus_uint64_t, <=, double);
77
78_DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8);
79_DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8);
80_DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8);
81_DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8);
82_DBUS_ASSERT_CMP_ALIGNMENT (dbus_uint64_t, ==, dbus_int64_t);
83
84_DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8);
85/* The alignment of a DBusBasicValue might conceivably be > 8 because of the
86 * pointer, so we don't assert about it */
87
88_DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8);
89_DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8);
90
106static void
107pack_2_octets (dbus_uint16_t value,
108 int byte_order,
109 unsigned char *data)
110{
111 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
112
113 if ((byte_order) == DBUS_LITTLE_ENDIAN)
114 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
115 else
116 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
117}
118
119static void
120pack_4_octets (dbus_uint32_t value,
121 int byte_order,
122 unsigned char *data)
123{
124 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
125
126 if ((byte_order) == DBUS_LITTLE_ENDIAN)
127 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
128 else
129 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
130}
131
132static void
133pack_8_octets (dbus_uint64_t value,
134 int byte_order,
135 unsigned char *data)
136{
137 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
138
139 if ((byte_order) == DBUS_LITTLE_ENDIAN)
140 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value);
141 else
142 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value);
143}
144
152void
153_dbus_pack_uint32 (dbus_uint32_t value,
154 int byte_order,
155 unsigned char *data)
156{
157 pack_4_octets (value, byte_order, data);
158}
159
160static void
161swap_8_octets (dbus_uint64_t *value,
162 int byte_order)
163{
164 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
165 {
166 *value = DBUS_UINT64_SWAP_LE_BE (*value);
167 }
168}
169
170#ifndef _dbus_unpack_uint16
178dbus_uint16_t
179_dbus_unpack_uint16 (int byte_order,
180 const unsigned char *data)
181{
182 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
183
184 if (byte_order == DBUS_LITTLE_ENDIAN)
185 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
186 else
187 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
188}
189#endif /* _dbus_unpack_uint16 */
190
191#ifndef _dbus_unpack_uint32
199dbus_uint32_t
200_dbus_unpack_uint32 (int byte_order,
201 const unsigned char *data)
202{
203 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
204
205 if (byte_order == DBUS_LITTLE_ENDIAN)
206 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
207 else
208 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
209}
210#endif /* _dbus_unpack_uint32 */
211
212static void
213set_2_octets (DBusString *str,
214 int offset,
215 dbus_uint16_t value,
216 int byte_order)
217{
218 char *data;
219
220 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
221 byte_order == DBUS_BIG_ENDIAN);
222
223 data = _dbus_string_get_data_len (str, offset, 2);
224
225 pack_2_octets (value, byte_order, (unsigned char *) data);
226}
227
228static void
229set_4_octets (DBusString *str,
230 int offset,
231 dbus_uint32_t value,
232 int byte_order)
233{
234 char *data;
235
236 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
237 byte_order == DBUS_BIG_ENDIAN);
238
239 data = _dbus_string_get_data_len (str, offset, 4);
240
241 pack_4_octets (value, byte_order, (unsigned char *) data);
242}
243
244static void
245set_8_octets (DBusString *str,
246 int offset,
247 dbus_uint64_t value,
248 int byte_order)
249{
250 char *data;
251
252 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
253 byte_order == DBUS_BIG_ENDIAN);
254
255 data = _dbus_string_get_data_len (str, offset, 8);
256
257 pack_8_octets (value, byte_order, (unsigned char *) data);
258}
259
270void
272 int pos,
273 dbus_uint32_t value,
274 int byte_order)
275{
276 set_4_octets (str, pos, value, byte_order);
277}
278
298static dbus_bool_t
299set_string (DBusString *str,
300 int pos,
301 const char *value,
302 int byte_order,
303 int *old_end_pos,
304 int *new_end_pos)
305{
306 int old_len, new_len;
307 DBusString dstr;
308
309 _dbus_string_init_const (&dstr, value);
310
311 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
312 old_len = _dbus_unpack_uint32 (byte_order,
313 _dbus_string_get_const_udata_len (str, pos, 4));
314
315 new_len = _dbus_string_get_length (&dstr);
316
317 if (!_dbus_string_replace_len (&dstr, 0, new_len,
318 str, pos + 4, old_len))
319 return FALSE;
320
321 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
322
323 if (old_end_pos)
324 *old_end_pos = pos + 4 + old_len + 1;
325 if (new_end_pos)
326 *new_end_pos = pos + 4 + new_len + 1;
327
328 return TRUE;
329}
330
344static dbus_bool_t
345set_signature (DBusString *str,
346 int pos,
347 const char *value,
348 int byte_order,
349 int *old_end_pos,
350 int *new_end_pos)
351{
352 int old_len, new_len;
353 DBusString dstr;
354
355 _dbus_string_init_const (&dstr, value);
356
357 old_len = _dbus_string_get_byte (str, pos);
358 new_len = _dbus_string_get_length (&dstr);
359
360 if (!_dbus_string_replace_len (&dstr, 0, new_len,
361 str, pos + 1, old_len))
362 return FALSE;
363
364 _dbus_string_set_byte (str, pos, new_len);
365
366 if (old_end_pos)
367 *old_end_pos = pos + 1 + old_len + 1;
368 if (new_end_pos)
369 *new_end_pos = pos + 1 + new_len + 1;
370
371 return TRUE;
372}
373
389 int pos,
390 int type,
391 const void *value,
392 int byte_order,
393 int *old_end_pos,
394 int *new_end_pos)
395{
396 /* Static assertions near the top of this file assert that signed and
397 * unsigned 16- and 32-bit quantities have the same alignment, and that
398 * doubles have alignment at least as strict as unsigned int64, so we
399 * don't have to distinguish further: every (double *)
400 * has strong enough alignment to be treated as though it was a
401 * (dbus_uint64_t *). Going via a (void *) means the compiler should
402 * know that pointers can alias each other. */
403 const unsigned char *u8_p;
404 const dbus_uint16_t *u16_p;
405 const dbus_uint32_t *u32_p;
406 const dbus_uint64_t *u64_p;
407 const char * const *string_p;
408
409 switch (type)
410 {
411 case DBUS_TYPE_BYTE:
412 u8_p = value;
413 _dbus_string_set_byte (str, pos, *u8_p);
414 if (old_end_pos)
415 *old_end_pos = pos + 1;
416 if (new_end_pos)
417 *new_end_pos = pos + 1;
418 return TRUE;
419 break;
420 case DBUS_TYPE_INT16:
421 case DBUS_TYPE_UINT16:
422 u16_p = value;
423 pos = _DBUS_ALIGN_VALUE (pos, 2);
424 set_2_octets (str, pos, *u16_p, byte_order);
425 if (old_end_pos)
426 *old_end_pos = pos + 2;
427 if (new_end_pos)
428 *new_end_pos = pos + 2;
429 return TRUE;
430 break;
432 case DBUS_TYPE_INT32:
433 case DBUS_TYPE_UINT32:
435 u32_p = value;
436 pos = _DBUS_ALIGN_VALUE (pos, 4);
437 set_4_octets (str, pos, *u32_p, byte_order);
438 if (old_end_pos)
439 *old_end_pos = pos + 4;
440 if (new_end_pos)
441 *new_end_pos = pos + 4;
442 return TRUE;
443 break;
444 case DBUS_TYPE_INT64:
445 case DBUS_TYPE_UINT64:
446 case DBUS_TYPE_DOUBLE:
447 u64_p = value;
448 pos = _DBUS_ALIGN_VALUE (pos, 8);
449 set_8_octets (str, pos, *u64_p, byte_order);
450 if (old_end_pos)
451 *old_end_pos = pos + 8;
452 if (new_end_pos)
453 *new_end_pos = pos + 8;
454 return TRUE;
455 break;
456 case DBUS_TYPE_STRING:
458 string_p = value;
459 pos = _DBUS_ALIGN_VALUE (pos, 4);
460 _dbus_assert (*string_p != NULL);
461 return set_string (str, pos, *string_p, byte_order,
462 old_end_pos, new_end_pos);
463 break;
465 string_p = value;
466 _dbus_assert (*string_p != NULL);
467 return set_signature (str, pos, *string_p, byte_order,
468 old_end_pos, new_end_pos);
469 break;
470 default:
471 _dbus_assert_not_reached ("not a basic type");
472 return FALSE;
473 break;
474 }
475}
476
486dbus_uint32_t
488 int pos,
489 int byte_order,
490 int *new_pos)
491{
492 pos = _DBUS_ALIGN_VALUE (pos, 4);
493
494 if (new_pos)
495 *new_pos = pos + 4;
496
497 _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
498
499 return _dbus_unpack_uint32 (byte_order,
500 _dbus_string_get_const_udata (str) + pos);
501}
502
524void
526 int pos,
527 int type,
528 void *value,
529 int byte_order,
530 int *new_pos)
531{
532 const char *str_data;
533
535
536 str_data = _dbus_string_get_const_data (str);
537
538 /* Below we volatile types to avoid aliasing issues;
539 * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
540 */
541
542 switch (type)
543 {
544 case DBUS_TYPE_BYTE:
545 {
546 volatile unsigned char *vp = value;
547 *vp = (unsigned char) _dbus_string_get_byte (str, pos);
548 (pos)++;
549 }
550 break;
551 case DBUS_TYPE_INT16:
552 case DBUS_TYPE_UINT16:
553 {
554 volatile dbus_uint16_t *vp = value;
555 pos = _DBUS_ALIGN_VALUE (pos, 2);
556 *vp = *(dbus_uint16_t *)(str_data + pos);
557 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
558 *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
559 pos += 2;
560 }
561 break;
562 case DBUS_TYPE_INT32:
563 case DBUS_TYPE_UINT32:
566 {
567 volatile dbus_uint32_t *vp = value;
568 pos = _DBUS_ALIGN_VALUE (pos, 4);
569 *vp = *(dbus_uint32_t *)(str_data + pos);
570 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
571 *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
572 pos += 4;
573 }
574 break;
575 case DBUS_TYPE_INT64:
576 case DBUS_TYPE_UINT64:
577 case DBUS_TYPE_DOUBLE:
578 {
579 volatile dbus_uint64_t *vp = value;
580 pos = _DBUS_ALIGN_VALUE (pos, 8);
581 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
582 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
583 else
584 *vp = *(dbus_uint64_t*)(str_data + pos);
585 pos += 8;
586 }
587 break;
588 case DBUS_TYPE_STRING:
590 {
591 int len;
592 volatile char **vp = value;
593
594 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
595
596 *vp = (char*) str_data + pos;
597
598 pos += len + 1; /* length plus nul */
599 }
600 break;
602 {
603 int len;
604 volatile char **vp = value;
605
606 len = _dbus_string_get_byte (str, pos);
607 pos += 1;
608
609 *vp = (char*) str_data + pos;
610
611 pos += len + 1; /* length plus nul */
612 }
613 break;
614 default:
615 _dbus_warn_check_failed ("type %s %d not a basic type",
616 _dbus_type_to_string (type), type);
617 _dbus_assert_not_reached ("not a basic type");
618 break;
619 }
620
621 if (new_pos)
622 *new_pos = pos;
623}
624
625static dbus_bool_t
626marshal_2_octets (DBusString *str,
627 int insert_at,
628 dbus_uint16_t value,
629 int byte_order,
630 int *pos_after)
631{
632 dbus_bool_t retval;
633 int orig_len;
634
635 _DBUS_STATIC_ASSERT (sizeof (value) == 2);
636
637 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
638 value = DBUS_UINT16_SWAP_LE_BE (value);
639
640 orig_len = _dbus_string_get_length (str);
641
642 retval = _dbus_string_insert_2_aligned (str, insert_at,
643 (const unsigned char *)&value);
644
645 if (pos_after)
646 {
647 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
648 _dbus_assert (*pos_after <= _dbus_string_get_length (str));
649 }
650
651 return retval;
652}
653
654static dbus_bool_t
655marshal_4_octets (DBusString *str,
656 int insert_at,
657 dbus_uint32_t value,
658 int byte_order,
659 int *pos_after)
660{
661 dbus_bool_t retval;
662 int orig_len;
663
664 _DBUS_STATIC_ASSERT (sizeof (value) == 4);
665
666 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
667 value = DBUS_UINT32_SWAP_LE_BE (value);
668
669 orig_len = _dbus_string_get_length (str);
670
671 retval = _dbus_string_insert_4_aligned (str, insert_at,
672 (const unsigned char *)&value);
673
674 if (pos_after)
675 {
676 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
677 _dbus_assert (*pos_after <= _dbus_string_get_length (str));
678 }
679
680 return retval;
681}
682
683static dbus_bool_t
684marshal_8_octets (DBusString *str,
685 int insert_at,
686 dbus_uint64_t value,
687 int byte_order,
688 int *pos_after)
689{
690 dbus_bool_t retval;
691 int orig_len;
692
693 _DBUS_STATIC_ASSERT (sizeof (value) == 8);
694
695 swap_8_octets (&value, byte_order);
696
697 orig_len = _dbus_string_get_length (str);
698
699 retval = _dbus_string_insert_8_aligned (str, insert_at,
700 (const unsigned char *)&value);
701
702 if (pos_after)
703 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
704
705 return retval;
706}
707
708enum
709 {
710 MARSHAL_AS_STRING,
711 MARSHAL_AS_SIGNATURE,
712 MARSHAL_AS_BYTE_ARRAY
713 };
714
715static dbus_bool_t
716marshal_len_followed_by_bytes (int marshal_as,
717 DBusString *str,
718 int insert_at,
719 const unsigned char *value,
720 int data_len, /* doesn't include nul if any */
721 int byte_order,
722 int *pos_after)
723{
724 int pos;
725 DBusString value_str;
726 int value_len;
727
728 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
729 if (insert_at > _dbus_string_get_length (str))
730 _dbus_warn ("insert_at = %d string len = %d data_len = %d",
731 insert_at, _dbus_string_get_length (str), data_len);
732
733 if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
734 value_len = data_len;
735 else
736 value_len = data_len + 1; /* value has a nul */
737
738 _dbus_string_init_const_len (&value_str, (const char *) value, value_len);
739
740 pos = insert_at;
741
742 if (marshal_as == MARSHAL_AS_SIGNATURE)
743 {
745 _dbus_assert (data_len <= 255); /* same as max sig len right now */
746
747 if (!_dbus_string_insert_byte (str, pos, data_len))
748 goto oom;
749
750 pos += 1;
751 }
752 else
753 {
754 if (!marshal_4_octets (str, pos, data_len,
755 byte_order, &pos))
756 goto oom;
757 }
758
759 if (!_dbus_string_copy_len (&value_str, 0, value_len,
760 str, pos))
761 goto oom;
762
763#if 0
764 /* too expensive */
765 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
766 str, pos));
767 _dbus_verbose_bytes_of_string (str, pos, value_len);
768#endif
769
770 pos += value_len;
771
772 if (pos_after)
773 *pos_after = pos;
774
775 return TRUE;
776
777 oom:
778 /* Delete what we've inserted */
779 _dbus_string_delete (str, insert_at, pos - insert_at);
780
781 return FALSE;
782}
783
784static dbus_bool_t
785marshal_string (DBusString *str,
786 int insert_at,
787 const char *value,
788 int byte_order,
789 int *pos_after)
790{
791 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
792 str, insert_at, (const unsigned char *) value,
793 strlen (value),
794 byte_order, pos_after);
795}
796
797static dbus_bool_t
798marshal_signature (DBusString *str,
799 int insert_at,
800 const char *value,
801 int *pos_after)
802{
803 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
804 str, insert_at, (const unsigned char *) value,
805 strlen (value),
806 DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
807 pos_after);
808}
809
828 int insert_at,
829 int type,
830 const void *value,
831 int byte_order,
832 int *pos_after)
833{
834 /* Static assertions near the top of this file assert that signed and
835 * unsigned 16- and 32-bit quantities have the same alignment, and that
836 * doubles have alignment at least as strict as unsigned int64, so we
837 * don't have to distinguish further: every (double *)
838 * has strong enough alignment to be treated as though it was a
839 * (dbus_uint64_t *). Going via a (void *) means the compiler should
840 * know that pointers can alias each other. */
841 const unsigned char *u8_p;
842 const dbus_uint16_t *u16_p;
843 const dbus_uint32_t *u32_p;
844 const dbus_uint64_t *u64_p;
845 const char * const *string_p;
846
848
849 switch (type)
850 {
851 case DBUS_TYPE_BYTE:
852 u8_p = value;
853 if (!_dbus_string_insert_byte (str, insert_at, *u8_p))
854 return FALSE;
855 if (pos_after)
856 *pos_after = insert_at + 1;
857 return TRUE;
858 break;
859 case DBUS_TYPE_INT16:
860 case DBUS_TYPE_UINT16:
861 u16_p = value;
862 return marshal_2_octets (str, insert_at, *u16_p,
863 byte_order, pos_after);
864 break;
866 u32_p = value;
867 return marshal_4_octets (str, insert_at, (*u32_p != FALSE),
868 byte_order, pos_after);
869 break;
870 case DBUS_TYPE_INT32:
871 case DBUS_TYPE_UINT32:
873 u32_p = value;
874 return marshal_4_octets (str, insert_at, *u32_p,
875 byte_order, pos_after);
876 break;
877 case DBUS_TYPE_INT64:
878 case DBUS_TYPE_UINT64:
879 case DBUS_TYPE_DOUBLE:
880 u64_p = value;
881 return marshal_8_octets (str, insert_at, *u64_p, byte_order, pos_after);
882 break;
883
884 case DBUS_TYPE_STRING:
886 string_p = value;
887 _dbus_assert (*string_p != NULL);
888 return marshal_string (str, insert_at, *string_p, byte_order, pos_after);
889 break;
891 string_p = value;
892 _dbus_assert (*string_p != NULL);
893 return marshal_signature (str, insert_at, *string_p, pos_after);
894 break;
895 default:
896 _dbus_assert_not_reached ("not a basic type");
897 return FALSE;
898 break;
899 }
900}
901
902static dbus_bool_t
903marshal_1_octets_array (DBusString *str,
904 int insert_at,
905 const unsigned char *value,
906 int n_elements,
907 int byte_order,
908 int *pos_after)
909{
910 int pos;
911 DBusString value_str;
912
913 _dbus_string_init_const_len (&value_str, (const char *) value, n_elements);
914
915 pos = insert_at;
916
917 if (!_dbus_string_copy_len (&value_str, 0, n_elements,
918 str, pos))
919 return FALSE;
920
921 pos += n_elements;
922
923 if (pos_after)
924 *pos_after = pos;
925
926 return TRUE;
927}
928
936void
937_dbus_swap_array (unsigned char *data,
938 int n_elements,
939 int alignment)
940{
941 unsigned char *d;
942 unsigned char *end;
943
944 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
945
946 /* we use const_data and cast it off so DBusString can be a const string
947 * for the unit tests. don't ask.
948 */
949 d = data;
950 end = d + (n_elements * alignment);
951
952 if (alignment == 8)
953 {
954 while (d != end)
955 {
956 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
957 d += 8;
958 }
959 }
960 else if (alignment == 4)
961 {
962 while (d != end)
963 {
964 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
965 d += 4;
966 }
967 }
968 else
969 {
970 _dbus_assert (alignment == 2);
971
972 while (d != end)
973 {
974 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
975 d += 2;
976 }
977 }
978}
979
980static void
981swap_array (DBusString *str,
982 int array_start,
983 int n_elements,
984 int byte_order,
985 int alignment)
986{
987 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
988
989 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
990 {
991 /* we use const_data and cast it off so DBusString can be a const string
992 * for the unit tests. don't ask.
993 */
994 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
995 n_elements, alignment);
996 }
997}
998
999static dbus_bool_t
1000marshal_fixed_multi (DBusString *str,
1001 int insert_at,
1002 const void *value,
1003 int n_elements,
1004 int byte_order,
1005 int alignment,
1006 int *pos_after)
1007{
1008 int old_string_len;
1009 int array_start;
1010 DBusString t;
1011 int len_in_bytes;
1012
1013 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
1014
1015 old_string_len = _dbus_string_get_length (str);
1016
1017 len_in_bytes = n_elements * alignment;
1018 array_start = insert_at;
1019
1020 /* Note that we do alignment padding unconditionally
1021 * even if the array is empty; this means that
1022 * padding + len is always equal to the number of bytes
1023 * in the array.
1024 */
1025
1026 if (!_dbus_string_insert_alignment (str, &array_start, alignment))
1027 goto error;
1028
1030 (const char *) value,
1031 len_in_bytes);
1032
1033 if (!_dbus_string_copy (&t, 0,
1034 str, array_start))
1035 goto error;
1036
1037 swap_array (str, array_start, n_elements, byte_order, alignment);
1038
1039 if (pos_after)
1040 *pos_after = array_start + len_in_bytes;
1041
1042 return TRUE;
1043
1044 error:
1045 _dbus_string_delete (str, insert_at,
1046 _dbus_string_get_length (str) - old_string_len);
1047
1048 return FALSE;
1049}
1050
1070 int insert_at,
1071 int element_type,
1072 const void *value,
1073 int n_elements,
1074 int byte_order,
1075 int *pos_after)
1076{
1077 /* Static assertions near the top of this file assert that signed and
1078 * unsigned 16- and 32-bit quantities have the same alignment, and that
1079 * doubles have alignment at least as strict as unsigned int64, so we
1080 * don't have to distinguish further: every (double *)
1081 * has strong enough alignment to be treated as though it was a
1082 * (dbus_uint64_t *). Going via a (void *) means the compiler should
1083 * know that pointers can alias each other. */
1084 const unsigned char * const *u8_pp;
1085 const dbus_uint16_t * const *u16_pp;
1086 const dbus_uint32_t * const *u32_pp;
1087 const dbus_uint64_t * const *u64_pp;
1088
1089 _dbus_assert (dbus_type_is_fixed (element_type));
1090 _dbus_assert (n_elements >= 0);
1091
1092#if 0
1093 _dbus_verbose ("writing %d elements of %s\n",
1094 n_elements, _dbus_type_to_string (element_type));
1095#endif
1096
1097 switch (element_type)
1098 {
1099 case DBUS_TYPE_BYTE:
1100 u8_pp = value;
1101 return marshal_1_octets_array (str, insert_at, *u8_pp, n_elements, byte_order, pos_after);
1102 break;
1103 case DBUS_TYPE_INT16:
1104 case DBUS_TYPE_UINT16:
1105 u16_pp = value;
1106 return marshal_fixed_multi (str, insert_at, *u16_pp, n_elements, byte_order, 2, pos_after);
1107 case DBUS_TYPE_BOOLEAN:
1108 case DBUS_TYPE_INT32:
1109 case DBUS_TYPE_UINT32:
1110 case DBUS_TYPE_UNIX_FD:
1111 u32_pp = value;
1112 return marshal_fixed_multi (str, insert_at, *u32_pp, n_elements, byte_order, 4, pos_after);
1113 break;
1114 case DBUS_TYPE_INT64:
1115 case DBUS_TYPE_UINT64:
1116 case DBUS_TYPE_DOUBLE:
1117 u64_pp = value;
1118 return marshal_fixed_multi (str, insert_at, *u64_pp, n_elements, byte_order, 8, pos_after);
1119 break;
1120
1121 default:
1122 _dbus_assert_not_reached ("non fixed type in array write");
1123 break;
1124 }
1125
1126 return FALSE;
1127}
1128
1129
1139void
1141 int type,
1142 int byte_order,
1143 int *pos)
1144{
1145 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
1146 byte_order == DBUS_BIG_ENDIAN);
1147
1148 switch (type)
1149 {
1150 case DBUS_TYPE_BYTE:
1151 (*pos)++;
1152 break;
1153 case DBUS_TYPE_INT16:
1154 case DBUS_TYPE_UINT16:
1155 *pos = _DBUS_ALIGN_VALUE (*pos, 2);
1156 *pos += 2;
1157 break;
1158 case DBUS_TYPE_BOOLEAN:
1159 case DBUS_TYPE_INT32:
1160 case DBUS_TYPE_UINT32:
1161 case DBUS_TYPE_UNIX_FD:
1162 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1163 *pos += 4;
1164 break;
1165 case DBUS_TYPE_INT64:
1166 case DBUS_TYPE_UINT64:
1167 case DBUS_TYPE_DOUBLE:
1168 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1169 *pos += 8;
1170 break;
1171 case DBUS_TYPE_STRING:
1173 {
1174 int len;
1175
1176 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
1177
1178 *pos += len + 1; /* length plus nul */
1179 }
1180 break;
1182 {
1183 int len;
1184
1185 len = _dbus_string_get_byte (str, *pos);
1186
1187 *pos += len + 2; /* length byte plus length plus nul */
1188 }
1189 break;
1190 default:
1191 _dbus_warn ("type %s not a basic type",
1192 _dbus_type_to_string (type));
1193 _dbus_assert_not_reached ("not a basic type");
1194 break;
1195 }
1196}
1197
1207void
1209 int element_type,
1210 int byte_order,
1211 int *pos)
1212{
1213 dbus_uint32_t array_len;
1214 int i;
1215 int alignment;
1216
1217 i = _DBUS_ALIGN_VALUE (*pos, 4);
1218
1219 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
1220
1221 alignment = _dbus_type_get_alignment (element_type);
1222
1223 i = _DBUS_ALIGN_VALUE (i, alignment);
1224
1225 *pos = i + array_len;
1226}
1227
1235int
1237{
1238 switch (typecode)
1239 {
1240 case DBUS_TYPE_BYTE:
1241 case DBUS_TYPE_VARIANT:
1243 return 1;
1244 case DBUS_TYPE_INT16:
1245 case DBUS_TYPE_UINT16:
1246 return 2;
1247 case DBUS_TYPE_BOOLEAN:
1248 case DBUS_TYPE_INT32:
1249 case DBUS_TYPE_UINT32:
1250 case DBUS_TYPE_UNIX_FD:
1251 /* this stuff is 4 since it starts with a length */
1252 case DBUS_TYPE_STRING:
1254 case DBUS_TYPE_ARRAY:
1255 return 4;
1256 case DBUS_TYPE_INT64:
1257 case DBUS_TYPE_UINT64:
1258 case DBUS_TYPE_DOUBLE:
1259 /* struct is 8 since it could contain an 8-aligned item
1260 * and it's simpler to just always align structs to 8;
1261 * we want the amount of padding in a struct of a given
1262 * type to be predictable, not location-dependent.
1263 * DICT_ENTRY is always the same as struct.
1264 */
1265 case DBUS_TYPE_STRUCT:
1267 return 8;
1268
1269 default:
1270 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1271 return 0;
1272 }
1273}
1274
1281const char *
1283{
1284 switch (typecode)
1285 {
1286 case DBUS_TYPE_INVALID:
1287 return "invalid";
1288 case DBUS_TYPE_BOOLEAN:
1289 return "boolean";
1290 case DBUS_TYPE_BYTE:
1291 return "byte";
1292 case DBUS_TYPE_INT16:
1293 return "int16";
1294 case DBUS_TYPE_UINT16:
1295 return "uint16";
1296 case DBUS_TYPE_INT32:
1297 return "int32";
1298 case DBUS_TYPE_UINT32:
1299 return "uint32";
1300 case DBUS_TYPE_INT64:
1301 return "int64";
1302 case DBUS_TYPE_UINT64:
1303 return "uint64";
1304 case DBUS_TYPE_DOUBLE:
1305 return "double";
1306 case DBUS_TYPE_STRING:
1307 return "string";
1309 return "object_path";
1311 return "signature";
1312 case DBUS_TYPE_STRUCT:
1313 return "struct";
1315 return "dict_entry";
1316 case DBUS_TYPE_ARRAY:
1317 return "array";
1318 case DBUS_TYPE_VARIANT:
1319 return "variant";
1321 return "begin_struct";
1323 return "end_struct";
1325 return "begin_dict_entry";
1327 return "end_dict_entry";
1328 case DBUS_TYPE_UNIX_FD:
1329 return "unix_fd";
1330 default:
1331 return "unknown";
1332 }
1333}
1334
1342void
1343_dbus_verbose_bytes (const unsigned char *data,
1344 int len,
1345 int offset)
1346{
1347 int i;
1348 const unsigned char *aligned;
1349
1350 _dbus_assert (len >= 0);
1351
1352 if (!_dbus_is_verbose())
1353 return;
1354
1355 /* Print blanks on first row if appropriate */
1356 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1357 if (aligned > data)
1358 aligned -= 4;
1359 _dbus_assert (aligned <= data);
1360
1361 if (aligned != data)
1362 {
1363 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
1364 while (aligned != data)
1365 {
1366 _dbus_verbose (" ");
1367 ++aligned;
1368 }
1369 }
1370
1371 /* now print the bytes */
1372 i = 0;
1373 while (i < len)
1374 {
1375 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1376 {
1377 _dbus_verbose ("%4d\t%p: ",
1378 offset + i, &data[i]);
1379 }
1380
1381 if (data[i] >= 32 &&
1382 data[i] <= 126)
1383 _dbus_verbose (" '%c' ", data[i]);
1384 else
1385 _dbus_verbose ("0x%s%x ",
1386 data[i] <= 0xf ? "0" : "", data[i]);
1387
1388 ++i;
1389
1390 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1391 {
1392 if (i > 3)
1393 _dbus_verbose ("BE: %d LE: %d",
1396
1397 if (i > 7 &&
1398 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1399 {
1400 _dbus_verbose (" u64: 0x%" PRIx64,
1401 *(dbus_uint64_t*)&data[i-8]);
1402 _dbus_verbose (" dbl: %g",
1403 *(double*)&data[i-8]);
1404 }
1405
1406 _dbus_verbose ("\n");
1407 }
1408 }
1409
1410 _dbus_verbose ("\n");
1411}
1412
1420void
1422 int start,
1423 int len)
1424{
1425 const char *d;
1426 int real_len;
1427
1428 real_len = _dbus_string_get_length (str);
1429
1430 _dbus_assert (start >= 0);
1431
1432 if (start > real_len)
1433 {
1434 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1435 start, len, real_len);
1436 return;
1437 }
1438
1439 if ((start + len) > real_len)
1440 {
1441 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1442 start, len, real_len);
1443 len = real_len - start;
1444 }
1445
1446 d = _dbus_string_get_const_data_len (str, start, len);
1447
1448 _dbus_verbose_bytes ((const unsigned char *) d, len, start);
1449}
1450
1451static int
1452map_type_char_to_type (int t)
1453{
1454 if (t == DBUS_STRUCT_BEGIN_CHAR)
1455 return DBUS_TYPE_STRUCT;
1456 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
1457 return DBUS_TYPE_DICT_ENTRY;
1458 else
1459 {
1462 return t;
1463 }
1464}
1465
1476int
1478 int pos)
1479{
1480 return map_type_char_to_type (_dbus_string_get_byte (str, pos));
1481}
1482
1491int
1493 int pos)
1494{
1495 return map_type_char_to_type (str[pos]);
1496}
1497
1500#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1501#include "dbus-test.h"
1502#include <stdio.h>
1503
1522void
1523_dbus_marshal_read_fixed_multi (const DBusString *str,
1524 int pos,
1525 int element_type,
1526 const void **value,
1527 int n_elements,
1528 int byte_order,
1529 int *new_pos)
1530{
1531 int array_len;
1532 int alignment;
1533
1534 _dbus_assert (dbus_type_is_fixed (element_type));
1535 _dbus_assert (dbus_type_is_basic (element_type));
1536
1537#if 0
1538 _dbus_verbose ("reading %d elements of %s\n",
1539 n_elements, _dbus_type_to_string (element_type));
1540#endif
1541
1542 alignment = _dbus_type_get_alignment (element_type);
1543
1544 pos = _DBUS_ALIGN_VALUE (pos, alignment);
1545
1546 array_len = n_elements * alignment;
1547
1548 *value = _dbus_string_get_const_data_len (str, pos, array_len);
1549 if (new_pos)
1550 *new_pos = pos + array_len;
1551}
1552
1553static void
1554swap_test_array (void *array,
1555 int len_bytes,
1556 int byte_order,
1557 int alignment)
1558{
1559 DBusString t;
1560
1561 if (alignment == 1)
1562 return;
1563
1564 _dbus_string_init_const_len (&t, array, len_bytes);
1565 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
1566}
1567
1568#define MARSHAL_BASIC(typename, byte_order, literal) \
1569 do { \
1570 v_##typename = literal; \
1571 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \
1572 &v_##typename, \
1573 byte_order, NULL)) \
1574 _dbus_test_fatal ("no memory"); \
1575 } while (0)
1576
1577#define DEMARSHAL_BASIC(typename, byte_order) \
1578 do { \
1579 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \
1580 byte_order, &pos); \
1581 } while (0)
1582
1583#define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \
1584 do { \
1585 DEMARSHAL_BASIC (typename, byte_order); \
1586 if (literal != v_##typename) \
1587 { \
1588 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1589 _dbus_string_get_length (&str) - dump_pos); \
1590 _dbus_test_fatal ("demarshaled wrong value"); \
1591 } \
1592 } while (0)
1593
1594#define MARSHAL_TEST(typename, byte_order, literal) \
1595 do { \
1596 MARSHAL_BASIC (typename, byte_order, literal); \
1597 dump_pos = pos; \
1598 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \
1599 } while (0)
1600
1601#define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \
1602 do { \
1603 MARSHAL_BASIC (typename, byte_order, literal); \
1604 dump_pos = pos; \
1605 DEMARSHAL_BASIC (typename, byte_order); \
1606 if (strcmp (literal, v_##typename) != 0) \
1607 { \
1608 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1609 _dbus_string_get_length (&str) - dump_pos); \
1610 _dbus_warn ("literal '%s'\nvalue '%s'", literal, v_##typename); \
1611 _dbus_test_fatal ("demarshaled wrong value"); \
1612 } \
1613 } while (0)
1614
1615#define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \
1616 do { \
1617 int next; \
1618 v_UINT32 = sizeof(literal); \
1619 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \
1620 byte_order, &next)) \
1621 _dbus_test_fatal ("no memory"); \
1622 v_ARRAY_##typename = literal; \
1623 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \
1624 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \
1625 byte_order, NULL)) \
1626 _dbus_test_fatal ("no memory"); \
1627 } while (0)
1628
1629#define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \
1630 do { \
1631 int next; \
1632 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \
1633 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \
1634 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, \
1635 (const void **) &v_ARRAY_##typename, \
1636 v_UINT32/alignment, \
1637 byte_order, NULL); \
1638 swap_test_array (v_ARRAY_##typename, v_UINT32, \
1639 byte_order, alignment); \
1640 } while (0)
1641
1642#define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \
1643 do { \
1644 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \
1645 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal)) != 0) \
1646 { \
1647 _dbus_verbose ("MARSHALED DATA\n"); \
1648 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1649 _dbus_string_get_length (&str) - dump_pos); \
1650 _dbus_verbose ("LITERAL DATA\n"); \
1651 _dbus_verbose_bytes ((const unsigned char *) literal, sizeof (literal), 0); \
1652 _dbus_verbose ("READ DATA\n"); \
1653 _dbus_verbose_bytes ((const unsigned char *) v_ARRAY_##typename, sizeof (literal), 0); \
1654 _dbus_test_fatal ("demarshaled wrong fixed array value"); \
1655 } \
1656 } while (0)
1657
1658#define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \
1659 do { \
1660 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \
1661 dump_pos = pos; \
1662 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \
1663 } while (0)
1664
1666_dbus_marshal_test (const char *test_data_dir _DBUS_GNUC_UNUSED)
1667{
1668 int alignment;
1669 DBusString str;
1670 int pos, dump_pos;
1671 unsigned char array1[5] = { 3, 4, 0, 1, 9 };
1672 dbus_int16_t array2[3] = { 124, 457, 780 };
1673 dbus_uint16_t array2u[3] = { 124, 457, 780 };
1674 dbus_int32_t array4[3] = { 123, 456, 789 };
1675 dbus_uint32_t array4u[3] = { 123, 456, 789 };
1676 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
1677 DBUS_INT64_CONSTANT (0x456ffffffff),
1678 DBUS_INT64_CONSTANT (0x789ffffffff) };
1679 dbus_int64_t *v_ARRAY_INT64;
1680 unsigned char *v_ARRAY_BYTE;
1681 dbus_int16_t *v_ARRAY_INT16;
1682 dbus_uint16_t *v_ARRAY_UINT16;
1683 dbus_int32_t *v_ARRAY_INT32;
1684 dbus_uint32_t *v_ARRAY_UINT32;
1685 DBusString t;
1686 double v_DOUBLE;
1687 double t_DOUBLE;
1688 dbus_int16_t v_INT16;
1689 dbus_uint16_t v_UINT16;
1690 dbus_int32_t v_INT32;
1691 dbus_uint32_t v_UINT32;
1692 dbus_int64_t v_INT64;
1693 dbus_uint64_t v_UINT64;
1694 unsigned char v_BYTE;
1695 dbus_bool_t v_BOOLEAN;
1696 const char *v_STRING;
1697 const char *v_SIGNATURE;
1698 const char *v_OBJECT_PATH;
1699 int byte_order;
1700
1701 if (!_dbus_string_init (&str))
1702 _dbus_test_fatal ("failed to init string");
1703
1704 pos = 0;
1705
1706 /* Marshal doubles */
1707 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
1708 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
1709 t_DOUBLE = 3.14;
1710 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1711 _dbus_test_fatal ("got wrong double value");
1712
1713 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
1714 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
1715 t_DOUBLE = 3.14;
1716 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1717 _dbus_test_fatal ("got wrong double value");
1718
1719 /* Marshal signed 16 integers */
1720 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
1721 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
1722
1723 /* Marshal unsigned 16 integers */
1724 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
1725 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
1726
1727 /* Marshal signed integers */
1728 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
1729 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
1730
1731 /* Marshal unsigned integers */
1732 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
1733 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
1734
1735 /* Marshal signed integers */
1736 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1737 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1738
1739 /* Marshal unsigned integers */
1740 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1741 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1742
1743 /* Marshal byte */
1744 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
1745 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
1746
1747 /* Marshal all possible bools! */
1748 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
1749 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
1750 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
1751 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
1752
1753 /* Marshal strings */
1754 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
1755 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
1756 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
1757 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
1758
1759 /* object paths */
1760 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
1761 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
1762
1763 /* signatures */
1764 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
1765 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
1766 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
1767 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
1768
1769 /* Arrays */
1770 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
1771 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
1772 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2u);
1773 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2u);
1774
1775 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
1776 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
1777 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4u);
1778 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4u);
1779
1780 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
1781 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
1782
1783 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
1784 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
1785
1786#if 0
1787
1788 /*
1789 * FIXME restore the set/pack tests
1790 */
1791
1792 /* set/pack 64-bit integers */
1793 _dbus_string_set_length (&str, 8);
1794
1795 /* signed little */
1796 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
1797 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1798
1799 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1800 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1801 _dbus_string_get_const_data (&str)));
1802
1803 /* signed big */
1804 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
1805 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1806
1807 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1808 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1809 _dbus_string_get_const_data (&str)));
1810
1811 /* signed little pack */
1812 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1814 _dbus_string_get_data (&str));
1815
1816 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1817 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1818 _dbus_string_get_const_data (&str)));
1819
1820 /* signed big pack */
1821 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1823 _dbus_string_get_data (&str));
1824
1825 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1826 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1827 _dbus_string_get_const_data (&str)));
1828
1829 /* unsigned little */
1830 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
1831 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1832
1833 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1834 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1835 _dbus_string_get_const_data (&str)));
1836
1837 /* unsigned big */
1838 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
1839 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1840
1841 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1842 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1843 _dbus_string_get_const_data (&str)));
1844
1845 /* unsigned little pack */
1846 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1848 _dbus_string_get_data (&str));
1849
1850 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1851 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1852 _dbus_string_get_const_data (&str)));
1853
1854 /* unsigned big pack */
1855 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1857 _dbus_string_get_data (&str));
1858
1859 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1860 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1861 _dbus_string_get_const_data (&str)));
1862
1863 /* set/pack 32-bit integers */
1864 _dbus_string_set_length (&str, 4);
1865
1866 /* signed little */
1867 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
1868 0, -0x123456);
1869
1870 _dbus_assert (-0x123456 ==
1871 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1872 _dbus_string_get_const_data (&str)));
1873
1874 /* signed big */
1875 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
1876 0, -0x123456);
1877
1878 _dbus_assert (-0x123456 ==
1879 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1880 _dbus_string_get_const_data (&str)));
1881
1882 /* signed little pack */
1883 _dbus_pack_int32 (-0x123456,
1885 _dbus_string_get_data (&str));
1886
1887 _dbus_assert (-0x123456 ==
1888 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1889 _dbus_string_get_const_data (&str)));
1890
1891 /* signed big pack */
1892 _dbus_pack_int32 (-0x123456,
1894 _dbus_string_get_data (&str));
1895
1896 _dbus_assert (-0x123456 ==
1897 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1898 _dbus_string_get_const_data (&str)));
1899
1900 /* unsigned little */
1902 0, 0x123456,
1904
1905 _dbus_assert (0x123456 ==
1907 _dbus_string_get_const_data (&str)));
1908
1909 /* unsigned big */
1911 0, 0x123456,
1913
1914 _dbus_assert (0x123456 ==
1916 _dbus_string_get_const_data (&str)));
1917
1918 /* unsigned little pack */
1919 _dbus_pack_uint32 (0x123456,
1921 _dbus_string_get_data (&str));
1922
1923 _dbus_assert (0x123456 ==
1925 _dbus_string_get_const_data (&str)));
1926
1927 /* unsigned big pack */
1928 _dbus_pack_uint32 (0x123456,
1930 _dbus_string_get_data (&str));
1931
1932 _dbus_assert (0x123456 ==
1934 _dbus_string_get_const_data (&str)));
1935
1936#endif /* set/pack tests for integers */
1937
1938 /* Strings in-place set */
1939 byte_order = DBUS_LITTLE_ENDIAN;
1940 while (TRUE)
1941 {
1942 /* Init a string */
1943 _dbus_string_set_length (&str, 0);
1944
1945 /* reset pos for the macros */
1946 pos = 0;
1947
1948 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
1949
1950 /* Set it to something longer */
1951 _dbus_string_init_const (&t, "Hello world foo");
1952
1953 v_STRING = _dbus_string_get_const_data (&t);
1955 &v_STRING, byte_order, NULL, NULL);
1956
1958 &v_STRING, byte_order,
1959 NULL);
1960 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
1961
1962 /* Set it to something shorter */
1963 _dbus_string_init_const (&t, "Hello");
1964
1965 v_STRING = _dbus_string_get_const_data (&t);
1967 &v_STRING, byte_order, NULL, NULL);
1969 &v_STRING, byte_order,
1970 NULL);
1971 _dbus_assert (strcmp (v_STRING, "Hello") == 0);
1972
1973 /* Do the other byte order */
1974 if (byte_order == DBUS_LITTLE_ENDIAN)
1975 byte_order = DBUS_BIG_ENDIAN;
1976 else
1977 break;
1978 }
1979
1980 /* Clean up */
1981 _dbus_string_free (&str);
1982
1983 return TRUE;
1984}
1985
1986#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
dbus_uint16_t _dbus_unpack_uint16(int byte_order, const unsigned char *data)
Unpacks a 16 bit unsigned integer from a data pointer.
int _dbus_type_get_alignment(int typecode)
Gets the alignment requirement for the given type; will be 1, 4, or 8.
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
void _dbus_pack_uint32(dbus_uint32_t value, int byte_order, unsigned char *data)
Packs a 32 bit unsigned integer into a data pointer.
void _dbus_marshal_set_uint32(DBusString *str, int pos, dbus_uint32_t value, int byte_order)
Sets the 4 bytes at the given offset to a marshaled unsigned integer, replacing anything found there ...
dbus_uint32_t _dbus_unpack_uint32(int byte_order, const unsigned char *data)
Unpacks a 32 bit unsigned integer from a data pointer.
dbus_bool_t _dbus_marshal_write_basic(DBusString *str, int insert_at, int type, const void *value, int byte_order, int *pos_after)
Marshals a basic-typed value.
int _dbus_first_type_in_signature(const DBusString *str, int pos)
Get the first type in the signature.
int _dbus_first_type_in_signature_c_str(const char *str, int pos)
Similar to _dbus_first_type_in_signature, but operates on a C string buffer.
dbus_uint32_t _dbus_marshal_read_uint32(const DBusString *str, int pos, int byte_order, int *new_pos)
Convenience function to demarshal a 32 bit unsigned integer.
void _dbus_verbose_bytes(const unsigned char *data, int len, int offset)
If in verbose mode, print a block of binary data.
dbus_bool_t _dbus_marshal_set_basic(DBusString *str, int pos, int type, const void *value, int byte_order, int *old_end_pos, int *new_end_pos)
Sets an existing basic type value to a new value.
void _dbus_marshal_skip_array(const DBusString *str, int element_type, int byte_order, int *pos)
Skips an array, returning the next position.
dbus_bool_t _dbus_marshal_write_fixed_multi(DBusString *str, int insert_at, int element_type, const void *value, int n_elements, int byte_order, int *pos_after)
Marshals a block of values of fixed-length type all at once, as an optimization.
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
void _dbus_marshal_read_basic(const DBusString *str, int pos, int type, void *value, int byte_order, int *new_pos)
Demarshals a basic-typed value.
void _dbus_swap_array(unsigned char *data, int n_elements, int alignment)
Swaps the elements of an array to the opposite byte order.
void _dbus_marshal_skip_basic(const DBusString *str, int type, int byte_order, int *pos)
Skips over a basic-typed value, reporting the following position.
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
#define DBUS_MAXIMUM_SIGNATURE_LENGTH
This one is 255 so it fits in a byte.
#define DBUS_DICT_ENTRY_END_CHAR
Code marking the end of a dict entry type in a type signature.
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
#define DBUS_TYPE_INT16
Type code marking a 16-bit signed integer.
Definition: dbus-protocol.h:74
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
#define DBUS_MAXIMUM_ARRAY_LENGTH
Max length of a marshaled array in bytes (64M, 2^26) We use signed int for lengths so must be INT_MAX...
#define DBUS_TYPE_INT32
Type code marking a 32-bit signed integer.
Definition: dbus-protocol.h:82
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
#define DBUS_STRUCT_BEGIN_CHAR
Code marking the start of a struct type in a type signature.
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:53
#define DBUS_TYPE_INT64
Type code marking a 64-bit signed integer.
Definition: dbus-protocol.h:90
#define DBUS_TYPE_DOUBLE
Type code marking an 8-byte double in IEEE 754 format.
Definition: dbus-protocol.h:98
#define DBUS_TYPE_UINT64
Type code marking a 64-bit unsigned integer.
Definition: dbus-protocol.h:94
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures,...
#define DBUS_DICT_ENTRY_BEGIN_CHAR
Code marking the start of a dict entry type in a type signature.
#define DBUS_TYPE_UINT16
Type code marking a 16-bit unsigned integer.
Definition: dbus-protocol.h:78
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string,...
#define DBUS_STRUCT_END_CHAR
Code marking the end of a struct type in a type signature.
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:54
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:833
dbus_bool_t _dbus_string_insert_8_aligned(DBusString *str, int insert_at, const unsigned char octets[8])
Inserts 8 bytes aligned on an 8 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1051
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2164
dbus_bool_t _dbus_string_insert_alignment(DBusString *str, int *insert_at, int alignment)
Inserts padding at *insert_at such to align it to the given boundary.
Definition: dbus-string.c:1079
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1343
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:521
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:217
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:278
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1253
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:645
dbus_bool_t _dbus_string_insert_4_aligned(DBusString *str, int insert_at, const unsigned char octets[4])
Inserts 4 bytes aligned on a 4 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1027
dbus_bool_t _dbus_string_insert_2_aligned(DBusString *str, int insert_at, const unsigned char octets[2])
Inserts 2 bytes aligned on a 2 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1003
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1435
dbus_bool_t _dbus_string_replace_len(const DBusString *source, int start, int len, DBusString *dest, int replace_at, int replace_len)
Replaces a segment of dest string with a segment of source string.
Definition: dbus-string.c:1464
#define _DBUS_DOUBLES_BITWISE_EQUAL(a, b)
On x86 there is an 80-bit FPU, and if you do "a == b" it may have a or b in an 80-bit register,...
Definition: dbus-sysdeps.h:632
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
An 8-byte struct you could use to access int64 without having int64 support.
Definition: dbus-types.h:122
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:138