D-Bus 1.12.20
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
30#include <string.h>
31
32#if !defined(PRIx64) && defined(DBUS_WIN)
33#define PRIx64 "I64x"
34#endif
35
36#if defined(__GNUC__) && (__GNUC__ >= 4)
37# define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
38 _DBUS_STATIC_ASSERT (__extension__ __alignof__ (type) op val)
39#else
40 /* not gcc, so probably no alignof operator: just use a no-op statement
41 * that's valid in the same contexts */
42# define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
43 _DBUS_STATIC_ASSERT (TRUE)
44#endif
45
46/* True by definition, but just for completeness... */
47_DBUS_STATIC_ASSERT (sizeof (char) == 1);
48_DBUS_ASSERT_ALIGNMENT (char, ==, 1);
49
50_DBUS_STATIC_ASSERT (sizeof (dbus_int16_t) == 2);
51_DBUS_ASSERT_ALIGNMENT (dbus_int16_t, <=, 2);
52_DBUS_STATIC_ASSERT (sizeof (dbus_uint16_t) == 2);
53_DBUS_ASSERT_ALIGNMENT (dbus_uint16_t, <=, 2);
54
55_DBUS_STATIC_ASSERT (sizeof (dbus_int32_t) == 4);
56_DBUS_ASSERT_ALIGNMENT (dbus_int32_t, <=, 4);
57_DBUS_STATIC_ASSERT (sizeof (dbus_uint32_t) == 4);
58_DBUS_ASSERT_ALIGNMENT (dbus_uint32_t, <=, 4);
59_DBUS_STATIC_ASSERT (sizeof (dbus_bool_t) == 4);
60_DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4);
61
62_DBUS_STATIC_ASSERT (sizeof (double) == 8);
63_DBUS_ASSERT_ALIGNMENT (double, <=, 8);
64
65_DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8);
66_DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8);
67_DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8);
68_DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8);
69
70_DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8);
71/* The alignment of a DBusBasicValue might conceivably be > 8 because of the
72 * pointer, so we don't assert about it */
73
74_DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8);
75_DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8);
76
92static void
93pack_2_octets (dbus_uint16_t value,
94 int byte_order,
95 unsigned char *data)
96{
97 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
98
99 if ((byte_order) == DBUS_LITTLE_ENDIAN)
100 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
101 else
102 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
103}
104
105static void
106pack_4_octets (dbus_uint32_t value,
107 int byte_order,
108 unsigned char *data)
109{
110 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
111
112 if ((byte_order) == DBUS_LITTLE_ENDIAN)
113 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
114 else
115 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
116}
117
118static void
119pack_8_octets (DBusBasicValue value,
120 int byte_order,
121 unsigned char *data)
122{
123 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
124
125 if ((byte_order) == DBUS_LITTLE_ENDIAN)
126 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
127 else
128 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
129}
130
138void
139_dbus_pack_uint32 (dbus_uint32_t value,
140 int byte_order,
141 unsigned char *data)
142{
143 pack_4_octets (value, byte_order, data);
144}
145
146static void
147swap_8_octets (DBusBasicValue *value,
148 int byte_order)
149{
150 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
151 {
152 value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
153 }
154}
155
156#ifndef _dbus_unpack_uint16
164dbus_uint16_t
165_dbus_unpack_uint16 (int byte_order,
166 const unsigned char *data)
167{
168 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
169
170 if (byte_order == DBUS_LITTLE_ENDIAN)
171 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
172 else
173 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
174}
175#endif /* _dbus_unpack_uint16 */
176
177#ifndef _dbus_unpack_uint32
185dbus_uint32_t
186_dbus_unpack_uint32 (int byte_order,
187 const unsigned char *data)
188{
189 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
190
191 if (byte_order == DBUS_LITTLE_ENDIAN)
192 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
193 else
194 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
195}
196#endif /* _dbus_unpack_uint32 */
197
198static void
199set_2_octets (DBusString *str,
200 int offset,
201 dbus_uint16_t value,
202 int byte_order)
203{
204 char *data;
205
206 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
207 byte_order == DBUS_BIG_ENDIAN);
208
209 data = _dbus_string_get_data_len (str, offset, 2);
210
211 pack_2_octets (value, byte_order, (unsigned char *) data);
212}
213
214static void
215set_4_octets (DBusString *str,
216 int offset,
217 dbus_uint32_t value,
218 int byte_order)
219{
220 char *data;
221
222 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
223 byte_order == DBUS_BIG_ENDIAN);
224
225 data = _dbus_string_get_data_len (str, offset, 4);
226
227 pack_4_octets (value, byte_order, (unsigned char *) data);
228}
229
230static void
231set_8_octets (DBusString *str,
232 int offset,
233 DBusBasicValue value,
234 int byte_order)
235{
236 char *data;
237
238 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
239 byte_order == DBUS_BIG_ENDIAN);
240
241 data = _dbus_string_get_data_len (str, offset, 8);
242
243 pack_8_octets (value, byte_order, (unsigned char *) data);
244}
245
256void
258 int pos,
259 dbus_uint32_t value,
260 int byte_order)
261{
262 set_4_octets (str, pos, value, byte_order);
263}
264
284static dbus_bool_t
285set_string (DBusString *str,
286 int pos,
287 const char *value,
288 int byte_order,
289 int *old_end_pos,
290 int *new_end_pos)
291{
292 int old_len, new_len;
293 DBusString dstr;
294
295 _dbus_string_init_const (&dstr, value);
296
297 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
298 old_len = _dbus_unpack_uint32 (byte_order,
299 _dbus_string_get_const_udata_len (str, pos, 4));
300
301 new_len = _dbus_string_get_length (&dstr);
302
303 if (!_dbus_string_replace_len (&dstr, 0, new_len,
304 str, pos + 4, old_len))
305 return FALSE;
306
307 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
308
309 if (old_end_pos)
310 *old_end_pos = pos + 4 + old_len + 1;
311 if (new_end_pos)
312 *new_end_pos = pos + 4 + new_len + 1;
313
314 return TRUE;
315}
316
330static dbus_bool_t
331set_signature (DBusString *str,
332 int pos,
333 const char *value,
334 int byte_order,
335 int *old_end_pos,
336 int *new_end_pos)
337{
338 int old_len, new_len;
339 DBusString dstr;
340
341 _dbus_string_init_const (&dstr, value);
342
343 old_len = _dbus_string_get_byte (str, pos);
344 new_len = _dbus_string_get_length (&dstr);
345
346 if (!_dbus_string_replace_len (&dstr, 0, new_len,
347 str, pos + 1, old_len))
348 return FALSE;
349
350 _dbus_string_set_byte (str, pos, new_len);
351
352 if (old_end_pos)
353 *old_end_pos = pos + 1 + old_len + 1;
354 if (new_end_pos)
355 *new_end_pos = pos + 1 + new_len + 1;
356
357 return TRUE;
358}
359
375 int pos,
376 int type,
377 const void *value,
378 int byte_order,
379 int *old_end_pos,
380 int *new_end_pos)
381{
382 const DBusBasicValue *vp;
383
384 vp = value;
385
386 switch (type)
387 {
388 case DBUS_TYPE_BYTE:
389 _dbus_string_set_byte (str, pos, vp->byt);
390 if (old_end_pos)
391 *old_end_pos = pos + 1;
392 if (new_end_pos)
393 *new_end_pos = pos + 1;
394 return TRUE;
395 break;
396 case DBUS_TYPE_INT16:
397 case DBUS_TYPE_UINT16:
398 pos = _DBUS_ALIGN_VALUE (pos, 2);
399 set_2_octets (str, pos, vp->u16, byte_order);
400 if (old_end_pos)
401 *old_end_pos = pos + 2;
402 if (new_end_pos)
403 *new_end_pos = pos + 2;
404 return TRUE;
405 break;
407 case DBUS_TYPE_INT32:
408 case DBUS_TYPE_UINT32:
410 pos = _DBUS_ALIGN_VALUE (pos, 4);
411 set_4_octets (str, pos, vp->u32, byte_order);
412 if (old_end_pos)
413 *old_end_pos = pos + 4;
414 if (new_end_pos)
415 *new_end_pos = pos + 4;
416 return TRUE;
417 break;
418 case DBUS_TYPE_INT64:
419 case DBUS_TYPE_UINT64:
420 case DBUS_TYPE_DOUBLE:
421 pos = _DBUS_ALIGN_VALUE (pos, 8);
422 set_8_octets (str, pos, *vp, byte_order);
423 if (old_end_pos)
424 *old_end_pos = pos + 8;
425 if (new_end_pos)
426 *new_end_pos = pos + 8;
427 return TRUE;
428 break;
429 case DBUS_TYPE_STRING:
431 pos = _DBUS_ALIGN_VALUE (pos, 4);
432 _dbus_assert (vp->str != NULL);
433 return set_string (str, pos, vp->str, byte_order,
434 old_end_pos, new_end_pos);
435 break;
437 _dbus_assert (vp->str != NULL);
438 return set_signature (str, pos, vp->str, byte_order,
439 old_end_pos, new_end_pos);
440 break;
441 default:
442 _dbus_assert_not_reached ("not a basic type");
443 return FALSE;
444 break;
445 }
446}
447
457dbus_uint32_t
459 int pos,
460 int byte_order,
461 int *new_pos)
462{
463 pos = _DBUS_ALIGN_VALUE (pos, 4);
464
465 if (new_pos)
466 *new_pos = pos + 4;
467
468 _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
469
470 return _dbus_unpack_uint32 (byte_order,
471 _dbus_string_get_const_udata (str) + pos);
472}
473
495void
497 int pos,
498 int type,
499 void *value,
500 int byte_order,
501 int *new_pos)
502{
503 const char *str_data;
504
506
507 str_data = _dbus_string_get_const_data (str);
508
509 /* Below we volatile types to avoid aliasing issues;
510 * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
511 */
512
513 switch (type)
514 {
515 case DBUS_TYPE_BYTE:
516 {
517 volatile unsigned char *vp = value;
518 *vp = (unsigned char) _dbus_string_get_byte (str, pos);
519 (pos)++;
520 }
521 break;
522 case DBUS_TYPE_INT16:
523 case DBUS_TYPE_UINT16:
524 {
525 volatile dbus_uint16_t *vp = value;
526 pos = _DBUS_ALIGN_VALUE (pos, 2);
527 *vp = *(dbus_uint16_t *)(str_data + pos);
528 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
529 *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
530 pos += 2;
531 }
532 break;
533 case DBUS_TYPE_INT32:
534 case DBUS_TYPE_UINT32:
537 {
538 volatile dbus_uint32_t *vp = value;
539 pos = _DBUS_ALIGN_VALUE (pos, 4);
540 *vp = *(dbus_uint32_t *)(str_data + pos);
541 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
542 *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
543 pos += 4;
544 }
545 break;
546 case DBUS_TYPE_INT64:
547 case DBUS_TYPE_UINT64:
548 case DBUS_TYPE_DOUBLE:
549 {
550 volatile dbus_uint64_t *vp = value;
551 pos = _DBUS_ALIGN_VALUE (pos, 8);
552 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
553 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
554 else
555 *vp = *(dbus_uint64_t*)(str_data + pos);
556 pos += 8;
557 }
558 break;
559 case DBUS_TYPE_STRING:
561 {
562 int len;
563 volatile char **vp = value;
564
565 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
566
567 *vp = (char*) str_data + pos;
568
569 pos += len + 1; /* length plus nul */
570 }
571 break;
573 {
574 int len;
575 volatile char **vp = value;
576
577 len = _dbus_string_get_byte (str, pos);
578 pos += 1;
579
580 *vp = (char*) str_data + pos;
581
582 pos += len + 1; /* length plus nul */
583 }
584 break;
585 default:
586 _dbus_warn_check_failed ("type %s %d not a basic type",
587 _dbus_type_to_string (type), type);
588 _dbus_assert_not_reached ("not a basic type");
589 break;
590 }
591
592 if (new_pos)
593 *new_pos = pos;
594}
595
596static dbus_bool_t
597marshal_2_octets (DBusString *str,
598 int insert_at,
599 dbus_uint16_t value,
600 int byte_order,
601 int *pos_after)
602{
603 dbus_bool_t retval;
604 int orig_len;
605
606 _DBUS_STATIC_ASSERT (sizeof (value) == 2);
607
608 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
609 value = DBUS_UINT16_SWAP_LE_BE (value);
610
611 orig_len = _dbus_string_get_length (str);
612
613 retval = _dbus_string_insert_2_aligned (str, insert_at,
614 (const unsigned char *)&value);
615
616 if (pos_after)
617 {
618 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
619 _dbus_assert (*pos_after <= _dbus_string_get_length (str));
620 }
621
622 return retval;
623}
624
625static dbus_bool_t
626marshal_4_octets (DBusString *str,
627 int insert_at,
628 dbus_uint32_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) == 4);
636
637 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
638 value = DBUS_UINT32_SWAP_LE_BE (value);
639
640 orig_len = _dbus_string_get_length (str);
641
642 retval = _dbus_string_insert_4_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_8_octets (DBusString *str,
656 int insert_at,
657 DBusBasicValue 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) == 8);
665
666 swap_8_octets (&value, byte_order);
667
668 orig_len = _dbus_string_get_length (str);
669
670 retval = _dbus_string_insert_8_aligned (str, insert_at,
671 (const unsigned char *)&value);
672
673 if (pos_after)
674 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
675
676 return retval;
677}
678
679enum
680 {
681 MARSHAL_AS_STRING,
682 MARSHAL_AS_SIGNATURE,
683 MARSHAL_AS_BYTE_ARRAY
684 };
685
686static dbus_bool_t
687marshal_len_followed_by_bytes (int marshal_as,
688 DBusString *str,
689 int insert_at,
690 const unsigned char *value,
691 int data_len, /* doesn't include nul if any */
692 int byte_order,
693 int *pos_after)
694{
695 int pos;
696 DBusString value_str;
697 int value_len;
698
699 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
700 if (insert_at > _dbus_string_get_length (str))
701 _dbus_warn ("insert_at = %d string len = %d data_len = %d",
702 insert_at, _dbus_string_get_length (str), data_len);
703
704 if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
705 value_len = data_len;
706 else
707 value_len = data_len + 1; /* value has a nul */
708
709 _dbus_string_init_const_len (&value_str, (const char *) value, value_len);
710
711 pos = insert_at;
712
713 if (marshal_as == MARSHAL_AS_SIGNATURE)
714 {
716 _dbus_assert (data_len <= 255); /* same as max sig len right now */
717
718 if (!_dbus_string_insert_byte (str, pos, data_len))
719 goto oom;
720
721 pos += 1;
722 }
723 else
724 {
725 if (!marshal_4_octets (str, pos, data_len,
726 byte_order, &pos))
727 goto oom;
728 }
729
730 if (!_dbus_string_copy_len (&value_str, 0, value_len,
731 str, pos))
732 goto oom;
733
734#if 0
735 /* too expensive */
736 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
737 str, pos));
738 _dbus_verbose_bytes_of_string (str, pos, value_len);
739#endif
740
741 pos += value_len;
742
743 if (pos_after)
744 *pos_after = pos;
745
746 return TRUE;
747
748 oom:
749 /* Delete what we've inserted */
750 _dbus_string_delete (str, insert_at, pos - insert_at);
751
752 return FALSE;
753}
754
755static dbus_bool_t
756marshal_string (DBusString *str,
757 int insert_at,
758 const char *value,
759 int byte_order,
760 int *pos_after)
761{
762 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
763 str, insert_at, (const unsigned char *) value,
764 strlen (value),
765 byte_order, pos_after);
766}
767
768static dbus_bool_t
769marshal_signature (DBusString *str,
770 int insert_at,
771 const char *value,
772 int *pos_after)
773{
774 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
775 str, insert_at, (const unsigned char *) value,
776 strlen (value),
777 DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
778 pos_after);
779}
780
799 int insert_at,
800 int type,
801 const void *value,
802 int byte_order,
803 int *pos_after)
804{
805 const DBusBasicValue *vp;
806
808
809 vp = value;
810
811 switch (type)
812 {
813 case DBUS_TYPE_BYTE:
814 if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
815 return FALSE;
816 if (pos_after)
817 *pos_after = insert_at + 1;
818 return TRUE;
819 break;
820 case DBUS_TYPE_INT16:
821 case DBUS_TYPE_UINT16:
822 return marshal_2_octets (str, insert_at, vp->u16,
823 byte_order, pos_after);
824 break;
826 return marshal_4_octets (str, insert_at, vp->u32 != FALSE,
827 byte_order, pos_after);
828 break;
829 case DBUS_TYPE_INT32:
830 case DBUS_TYPE_UINT32:
832 return marshal_4_octets (str, insert_at, vp->u32,
833 byte_order, pos_after);
834 break;
835 case DBUS_TYPE_INT64:
836 case DBUS_TYPE_UINT64:
837 case DBUS_TYPE_DOUBLE:
838 return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
839 break;
840
841 case DBUS_TYPE_STRING:
843 _dbus_assert (vp->str != NULL);
844 return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
845 break;
847 _dbus_assert (vp->str != NULL);
848 return marshal_signature (str, insert_at, vp->str, pos_after);
849 break;
850 default:
851 _dbus_assert_not_reached ("not a basic type");
852 return FALSE;
853 break;
854 }
855}
856
857static dbus_bool_t
858marshal_1_octets_array (DBusString *str,
859 int insert_at,
860 const unsigned char *value,
861 int n_elements,
862 int byte_order,
863 int *pos_after)
864{
865 int pos;
866 DBusString value_str;
867
868 _dbus_string_init_const_len (&value_str, (const char *) value, n_elements);
869
870 pos = insert_at;
871
872 if (!_dbus_string_copy_len (&value_str, 0, n_elements,
873 str, pos))
874 return FALSE;
875
876 pos += n_elements;
877
878 if (pos_after)
879 *pos_after = pos;
880
881 return TRUE;
882}
883
891void
892_dbus_swap_array (unsigned char *data,
893 int n_elements,
894 int alignment)
895{
896 unsigned char *d;
897 unsigned char *end;
898
899 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
900
901 /* we use const_data and cast it off so DBusString can be a const string
902 * for the unit tests. don't ask.
903 */
904 d = data;
905 end = d + (n_elements * alignment);
906
907 if (alignment == 8)
908 {
909 while (d != end)
910 {
911 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
912 d += 8;
913 }
914 }
915 else if (alignment == 4)
916 {
917 while (d != end)
918 {
919 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
920 d += 4;
921 }
922 }
923 else
924 {
925 _dbus_assert (alignment == 2);
926
927 while (d != end)
928 {
929 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
930 d += 2;
931 }
932 }
933}
934
935static void
936swap_array (DBusString *str,
937 int array_start,
938 int n_elements,
939 int byte_order,
940 int alignment)
941{
942 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
943
944 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
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 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
950 n_elements, alignment);
951 }
952}
953
954static dbus_bool_t
955marshal_fixed_multi (DBusString *str,
956 int insert_at,
957 const DBusBasicValue *value,
958 int n_elements,
959 int byte_order,
960 int alignment,
961 int *pos_after)
962{
963 int old_string_len;
964 int array_start;
965 DBusString t;
966 int len_in_bytes;
967
968 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
969
970 old_string_len = _dbus_string_get_length (str);
971
972 len_in_bytes = n_elements * alignment;
973 array_start = insert_at;
974
975 /* Note that we do alignment padding unconditionally
976 * even if the array is empty; this means that
977 * padding + len is always equal to the number of bytes
978 * in the array.
979 */
980
981 if (!_dbus_string_insert_alignment (str, &array_start, alignment))
982 goto error;
983
985 (const char *) value,
986 len_in_bytes);
987
988 if (!_dbus_string_copy (&t, 0,
989 str, array_start))
990 goto error;
991
992 swap_array (str, array_start, n_elements, byte_order, alignment);
993
994 if (pos_after)
995 *pos_after = array_start + len_in_bytes;
996
997 return TRUE;
998
999 error:
1000 _dbus_string_delete (str, insert_at,
1001 _dbus_string_get_length (str) - old_string_len);
1002
1003 return FALSE;
1004}
1005
1025 int insert_at,
1026 int element_type,
1027 const void *value,
1028 int n_elements,
1029 int byte_order,
1030 int *pos_after)
1031{
1032 const void* vp = *(const DBusBasicValue**)value;
1033
1034 _dbus_assert (dbus_type_is_fixed (element_type));
1035 _dbus_assert (n_elements >= 0);
1036
1037#if 0
1038 _dbus_verbose ("writing %d elements of %s\n",
1039 n_elements, _dbus_type_to_string (element_type));
1040#endif
1041
1042 switch (element_type)
1043 {
1044 case DBUS_TYPE_BYTE:
1045 return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after);
1046 break;
1047 case DBUS_TYPE_INT16:
1048 case DBUS_TYPE_UINT16:
1049 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
1050 case DBUS_TYPE_BOOLEAN:
1051 case DBUS_TYPE_INT32:
1052 case DBUS_TYPE_UINT32:
1053 case DBUS_TYPE_UNIX_FD:
1054 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
1055 break;
1056 case DBUS_TYPE_INT64:
1057 case DBUS_TYPE_UINT64:
1058 case DBUS_TYPE_DOUBLE:
1059 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after);
1060 break;
1061
1062 default:
1063 _dbus_assert_not_reached ("non fixed type in array write");
1064 break;
1065 }
1066
1067 return FALSE;
1068}
1069
1070
1080void
1082 int type,
1083 int byte_order,
1084 int *pos)
1085{
1086 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
1087 byte_order == DBUS_BIG_ENDIAN);
1088
1089 switch (type)
1090 {
1091 case DBUS_TYPE_BYTE:
1092 (*pos)++;
1093 break;
1094 case DBUS_TYPE_INT16:
1095 case DBUS_TYPE_UINT16:
1096 *pos = _DBUS_ALIGN_VALUE (*pos, 2);
1097 *pos += 2;
1098 break;
1099 case DBUS_TYPE_BOOLEAN:
1100 case DBUS_TYPE_INT32:
1101 case DBUS_TYPE_UINT32:
1102 case DBUS_TYPE_UNIX_FD:
1103 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1104 *pos += 4;
1105 break;
1106 case DBUS_TYPE_INT64:
1107 case DBUS_TYPE_UINT64:
1108 case DBUS_TYPE_DOUBLE:
1109 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1110 *pos += 8;
1111 break;
1112 case DBUS_TYPE_STRING:
1114 {
1115 int len;
1116
1117 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
1118
1119 *pos += len + 1; /* length plus nul */
1120 }
1121 break;
1123 {
1124 int len;
1125
1126 len = _dbus_string_get_byte (str, *pos);
1127
1128 *pos += len + 2; /* length byte plus length plus nul */
1129 }
1130 break;
1131 default:
1132 _dbus_warn ("type %s not a basic type",
1133 _dbus_type_to_string (type));
1134 _dbus_assert_not_reached ("not a basic type");
1135 break;
1136 }
1137}
1138
1148void
1150 int element_type,
1151 int byte_order,
1152 int *pos)
1153{
1154 dbus_uint32_t array_len;
1155 int i;
1156 int alignment;
1157
1158 i = _DBUS_ALIGN_VALUE (*pos, 4);
1159
1160 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
1161
1162 alignment = _dbus_type_get_alignment (element_type);
1163
1164 i = _DBUS_ALIGN_VALUE (i, alignment);
1165
1166 *pos = i + array_len;
1167}
1168
1176int
1178{
1179 switch (typecode)
1180 {
1181 case DBUS_TYPE_BYTE:
1182 case DBUS_TYPE_VARIANT:
1184 return 1;
1185 case DBUS_TYPE_INT16:
1186 case DBUS_TYPE_UINT16:
1187 return 2;
1188 case DBUS_TYPE_BOOLEAN:
1189 case DBUS_TYPE_INT32:
1190 case DBUS_TYPE_UINT32:
1191 case DBUS_TYPE_UNIX_FD:
1192 /* this stuff is 4 since it starts with a length */
1193 case DBUS_TYPE_STRING:
1195 case DBUS_TYPE_ARRAY:
1196 return 4;
1197 case DBUS_TYPE_INT64:
1198 case DBUS_TYPE_UINT64:
1199 case DBUS_TYPE_DOUBLE:
1200 /* struct is 8 since it could contain an 8-aligned item
1201 * and it's simpler to just always align structs to 8;
1202 * we want the amount of padding in a struct of a given
1203 * type to be predictable, not location-dependent.
1204 * DICT_ENTRY is always the same as struct.
1205 */
1206 case DBUS_TYPE_STRUCT:
1208 return 8;
1209
1210 default:
1211 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1212 return 0;
1213 }
1214}
1215
1222const char *
1224{
1225 switch (typecode)
1226 {
1227 case DBUS_TYPE_INVALID:
1228 return "invalid";
1229 case DBUS_TYPE_BOOLEAN:
1230 return "boolean";
1231 case DBUS_TYPE_BYTE:
1232 return "byte";
1233 case DBUS_TYPE_INT16:
1234 return "int16";
1235 case DBUS_TYPE_UINT16:
1236 return "uint16";
1237 case DBUS_TYPE_INT32:
1238 return "int32";
1239 case DBUS_TYPE_UINT32:
1240 return "uint32";
1241 case DBUS_TYPE_INT64:
1242 return "int64";
1243 case DBUS_TYPE_UINT64:
1244 return "uint64";
1245 case DBUS_TYPE_DOUBLE:
1246 return "double";
1247 case DBUS_TYPE_STRING:
1248 return "string";
1250 return "object_path";
1252 return "signature";
1253 case DBUS_TYPE_STRUCT:
1254 return "struct";
1256 return "dict_entry";
1257 case DBUS_TYPE_ARRAY:
1258 return "array";
1259 case DBUS_TYPE_VARIANT:
1260 return "variant";
1262 return "begin_struct";
1264 return "end_struct";
1266 return "begin_dict_entry";
1268 return "end_dict_entry";
1269 case DBUS_TYPE_UNIX_FD:
1270 return "unix_fd";
1271 default:
1272 return "unknown";
1273 }
1274}
1275
1283void
1284_dbus_verbose_bytes (const unsigned char *data,
1285 int len,
1286 int offset)
1287{
1288 int i;
1289 const unsigned char *aligned;
1290
1291 _dbus_assert (len >= 0);
1292
1293 if (!_dbus_is_verbose())
1294 return;
1295
1296 /* Print blanks on first row if appropriate */
1297 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1298 if (aligned > data)
1299 aligned -= 4;
1300 _dbus_assert (aligned <= data);
1301
1302 if (aligned != data)
1303 {
1304 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
1305 while (aligned != data)
1306 {
1307 _dbus_verbose (" ");
1308 ++aligned;
1309 }
1310 }
1311
1312 /* now print the bytes */
1313 i = 0;
1314 while (i < len)
1315 {
1316 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1317 {
1318 _dbus_verbose ("%4d\t%p: ",
1319 offset + i, &data[i]);
1320 }
1321
1322 if (data[i] >= 32 &&
1323 data[i] <= 126)
1324 _dbus_verbose (" '%c' ", data[i]);
1325 else
1326 _dbus_verbose ("0x%s%x ",
1327 data[i] <= 0xf ? "0" : "", data[i]);
1328
1329 ++i;
1330
1331 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1332 {
1333 if (i > 3)
1334 _dbus_verbose ("BE: %d LE: %d",
1337
1338 if (i > 7 &&
1339 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1340 {
1341 _dbus_verbose (" u64: 0x%" PRIx64,
1342 *(dbus_uint64_t*)&data[i-8]);
1343 _dbus_verbose (" dbl: %g",
1344 *(double*)&data[i-8]);
1345 }
1346
1347 _dbus_verbose ("\n");
1348 }
1349 }
1350
1351 _dbus_verbose ("\n");
1352}
1353
1361void
1363 int start,
1364 int len)
1365{
1366 const char *d;
1367 int real_len;
1368
1369 real_len = _dbus_string_get_length (str);
1370
1371 _dbus_assert (start >= 0);
1372
1373 if (start > real_len)
1374 {
1375 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1376 start, len, real_len);
1377 return;
1378 }
1379
1380 if ((start + len) > real_len)
1381 {
1382 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1383 start, len, real_len);
1384 len = real_len - start;
1385 }
1386
1387 d = _dbus_string_get_const_data_len (str, start, len);
1388
1389 _dbus_verbose_bytes ((const unsigned char *) d, len, start);
1390}
1391
1392static int
1393map_type_char_to_type (int t)
1394{
1395 if (t == DBUS_STRUCT_BEGIN_CHAR)
1396 return DBUS_TYPE_STRUCT;
1397 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
1398 return DBUS_TYPE_DICT_ENTRY;
1399 else
1400 {
1403 return t;
1404 }
1405}
1406
1417int
1419 int pos)
1420{
1421 return map_type_char_to_type (_dbus_string_get_byte (str, pos));
1422}
1423
1432int
1434 int pos)
1435{
1436 return map_type_char_to_type (str[pos]);
1437}
1438
1441#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1442#include "dbus-test.h"
1443#include <stdio.h>
1444
1463void
1464_dbus_marshal_read_fixed_multi (const DBusString *str,
1465 int pos,
1466 int element_type,
1467 void *value,
1468 int n_elements,
1469 int byte_order,
1470 int *new_pos)
1471{
1472 int array_len;
1473 int alignment;
1474
1475 _dbus_assert (dbus_type_is_fixed (element_type));
1476 _dbus_assert (dbus_type_is_basic (element_type));
1477
1478#if 0
1479 _dbus_verbose ("reading %d elements of %s\n",
1480 n_elements, _dbus_type_to_string (element_type));
1481#endif
1482
1483 alignment = _dbus_type_get_alignment (element_type);
1484
1485 pos = _DBUS_ALIGN_VALUE (pos, alignment);
1486
1487 array_len = n_elements * alignment;
1488
1489 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
1490 if (new_pos)
1491 *new_pos = pos + array_len;
1492}
1493
1494static void
1495swap_test_array (void *array,
1496 int len_bytes,
1497 int byte_order,
1498 int alignment)
1499{
1500 DBusString t;
1501
1502 if (alignment == 1)
1503 return;
1504
1505 _dbus_string_init_const_len (&t, array, len_bytes);
1506 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
1507}
1508
1509#define MARSHAL_BASIC(typename, byte_order, literal) \
1510 do { \
1511 v_##typename = literal; \
1512 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \
1513 &v_##typename, \
1514 byte_order, NULL)) \
1515 _dbus_assert_not_reached ("no memory"); \
1516 } while (0)
1517
1518#define DEMARSHAL_BASIC(typename, byte_order) \
1519 do { \
1520 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \
1521 byte_order, &pos); \
1522 } while (0)
1523
1524#define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \
1525 do { \
1526 DEMARSHAL_BASIC (typename, byte_order); \
1527 if (literal != v_##typename) \
1528 { \
1529 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1530 _dbus_string_get_length (&str) - dump_pos); \
1531 _dbus_assert_not_reached ("demarshaled wrong value"); \
1532 } \
1533 } while (0)
1534
1535#define MARSHAL_TEST(typename, byte_order, literal) \
1536 do { \
1537 MARSHAL_BASIC (typename, byte_order, literal); \
1538 dump_pos = pos; \
1539 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \
1540 } while (0)
1541
1542#define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \
1543 do { \
1544 MARSHAL_BASIC (typename, byte_order, literal); \
1545 dump_pos = pos; \
1546 DEMARSHAL_BASIC (typename, byte_order); \
1547 if (strcmp (literal, v_##typename) != 0) \
1548 { \
1549 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1550 _dbus_string_get_length (&str) - dump_pos); \
1551 _dbus_warn ("literal '%s'\nvalue '%s'", literal, v_##typename); \
1552 _dbus_assert_not_reached ("demarshaled wrong value"); \
1553 } \
1554 } while (0)
1555
1556#define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \
1557 do { \
1558 int next; \
1559 v_UINT32 = sizeof(literal); \
1560 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \
1561 byte_order, &next)) \
1562 _dbus_assert_not_reached ("no memory"); \
1563 v_ARRAY_##typename = literal; \
1564 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \
1565 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \
1566 byte_order, NULL)) \
1567 _dbus_assert_not_reached ("no memory"); \
1568 } while (0)
1569
1570#define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \
1571 do { \
1572 int next; \
1573 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \
1574 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \
1575 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \
1576 v_UINT32/alignment, \
1577 byte_order, NULL); \
1578 swap_test_array (v_ARRAY_##typename, v_UINT32, \
1579 byte_order, alignment); \
1580 } while (0)
1581
1582#define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \
1583 do { \
1584 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \
1585 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal)) != 0) \
1586 { \
1587 _dbus_verbose ("MARSHALED DATA\n"); \
1588 _dbus_verbose_bytes_of_string (&str, dump_pos, \
1589 _dbus_string_get_length (&str) - dump_pos); \
1590 _dbus_verbose ("LITERAL DATA\n"); \
1591 _dbus_verbose_bytes ((const unsigned char *) literal, sizeof (literal), 0); \
1592 _dbus_verbose ("READ DATA\n"); \
1593 _dbus_verbose_bytes ((const unsigned char *) v_ARRAY_##typename, sizeof (literal), 0); \
1594 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \
1595 } \
1596 } while (0)
1597
1598#define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \
1599 do { \
1600 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \
1601 dump_pos = pos; \
1602 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \
1603 } while (0)
1604
1606_dbus_marshal_test (void)
1607{
1608 int alignment;
1609 DBusString str;
1610 int pos, dump_pos;
1611 unsigned char array1[5] = { 3, 4, 0, 1, 9 };
1612 dbus_int16_t array2[3] = { 124, 457, 780 };
1613 dbus_uint16_t array2u[3] = { 124, 457, 780 };
1614 dbus_int32_t array4[3] = { 123, 456, 789 };
1615 dbus_uint32_t array4u[3] = { 123, 456, 789 };
1616 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
1617 DBUS_INT64_CONSTANT (0x456ffffffff),
1618 DBUS_INT64_CONSTANT (0x789ffffffff) };
1619 dbus_int64_t *v_ARRAY_INT64;
1620 unsigned char *v_ARRAY_BYTE;
1621 dbus_int16_t *v_ARRAY_INT16;
1622 dbus_uint16_t *v_ARRAY_UINT16;
1623 dbus_int32_t *v_ARRAY_INT32;
1624 dbus_uint32_t *v_ARRAY_UINT32;
1625 DBusString t;
1626 double v_DOUBLE;
1627 double t_DOUBLE;
1628 dbus_int16_t v_INT16;
1629 dbus_uint16_t v_UINT16;
1630 dbus_int32_t v_INT32;
1631 dbus_uint32_t v_UINT32;
1632 dbus_int64_t v_INT64;
1633 dbus_uint64_t v_UINT64;
1634 unsigned char v_BYTE;
1635 dbus_bool_t v_BOOLEAN;
1636 const char *v_STRING;
1637 const char *v_SIGNATURE;
1638 const char *v_OBJECT_PATH;
1639 int byte_order;
1640
1641 if (!_dbus_string_init (&str))
1642 _dbus_assert_not_reached ("failed to init string");
1643
1644 pos = 0;
1645
1646 /* Marshal doubles */
1647 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
1648 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
1649 t_DOUBLE = 3.14;
1650 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1651 _dbus_assert_not_reached ("got wrong double value");
1652
1653 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
1654 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
1655 t_DOUBLE = 3.14;
1656 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1657 _dbus_assert_not_reached ("got wrong double value");
1658
1659 /* Marshal signed 16 integers */
1660 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
1661 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
1662
1663 /* Marshal unsigned 16 integers */
1664 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
1665 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
1666
1667 /* Marshal signed integers */
1668 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
1669 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
1670
1671 /* Marshal unsigned integers */
1672 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
1673 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
1674
1675 /* Marshal signed integers */
1676 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1677 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1678
1679 /* Marshal unsigned integers */
1680 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1681 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1682
1683 /* Marshal byte */
1684 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
1685 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
1686
1687 /* Marshal all possible bools! */
1688 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
1689 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
1690 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
1691 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
1692
1693 /* Marshal strings */
1694 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
1695 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
1696 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
1697 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
1698
1699 /* object paths */
1700 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
1701 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
1702
1703 /* signatures */
1704 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
1705 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
1706 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
1707 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
1708
1709 /* Arrays */
1710 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
1711 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
1712 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2u);
1713 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2u);
1714
1715 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
1716 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
1717 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4u);
1718 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4u);
1719
1720 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
1721 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
1722
1723 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
1724 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
1725
1726#if 0
1727
1728 /*
1729 * FIXME restore the set/pack tests
1730 */
1731
1732 /* set/pack 64-bit integers */
1733 _dbus_string_set_length (&str, 8);
1734
1735 /* signed little */
1736 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
1737 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1738
1739 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1740 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1741 _dbus_string_get_const_data (&str)));
1742
1743 /* signed big */
1744 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
1745 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1746
1747 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1748 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1749 _dbus_string_get_const_data (&str)));
1750
1751 /* signed little pack */
1752 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1754 _dbus_string_get_data (&str));
1755
1756 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1757 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1758 _dbus_string_get_const_data (&str)));
1759
1760 /* signed big pack */
1761 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1763 _dbus_string_get_data (&str));
1764
1765 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1766 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1767 _dbus_string_get_const_data (&str)));
1768
1769 /* unsigned little */
1770 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
1771 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1772
1773 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1774 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1775 _dbus_string_get_const_data (&str)));
1776
1777 /* unsigned big */
1778 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
1779 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1780
1781 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1782 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1783 _dbus_string_get_const_data (&str)));
1784
1785 /* unsigned little pack */
1786 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1788 _dbus_string_get_data (&str));
1789
1790 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1791 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1792 _dbus_string_get_const_data (&str)));
1793
1794 /* unsigned big pack */
1795 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1797 _dbus_string_get_data (&str));
1798
1799 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1800 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1801 _dbus_string_get_const_data (&str)));
1802
1803 /* set/pack 32-bit integers */
1804 _dbus_string_set_length (&str, 4);
1805
1806 /* signed little */
1807 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
1808 0, -0x123456);
1809
1810 _dbus_assert (-0x123456 ==
1811 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1812 _dbus_string_get_const_data (&str)));
1813
1814 /* signed big */
1815 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
1816 0, -0x123456);
1817
1818 _dbus_assert (-0x123456 ==
1819 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1820 _dbus_string_get_const_data (&str)));
1821
1822 /* signed little pack */
1823 _dbus_pack_int32 (-0x123456,
1825 _dbus_string_get_data (&str));
1826
1827 _dbus_assert (-0x123456 ==
1828 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1829 _dbus_string_get_const_data (&str)));
1830
1831 /* signed big pack */
1832 _dbus_pack_int32 (-0x123456,
1834 _dbus_string_get_data (&str));
1835
1836 _dbus_assert (-0x123456 ==
1837 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1838 _dbus_string_get_const_data (&str)));
1839
1840 /* unsigned little */
1842 0, 0x123456,
1844
1845 _dbus_assert (0x123456 ==
1847 _dbus_string_get_const_data (&str)));
1848
1849 /* unsigned big */
1851 0, 0x123456,
1853
1854 _dbus_assert (0x123456 ==
1856 _dbus_string_get_const_data (&str)));
1857
1858 /* unsigned little pack */
1859 _dbus_pack_uint32 (0x123456,
1861 _dbus_string_get_data (&str));
1862
1863 _dbus_assert (0x123456 ==
1865 _dbus_string_get_const_data (&str)));
1866
1867 /* unsigned big pack */
1868 _dbus_pack_uint32 (0x123456,
1870 _dbus_string_get_data (&str));
1871
1872 _dbus_assert (0x123456 ==
1874 _dbus_string_get_const_data (&str)));
1875
1876#endif /* set/pack tests for integers */
1877
1878 /* Strings in-place set */
1879 byte_order = DBUS_LITTLE_ENDIAN;
1880 while (TRUE)
1881 {
1882 /* Init a string */
1883 _dbus_string_set_length (&str, 0);
1884
1885 /* reset pos for the macros */
1886 pos = 0;
1887
1888 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
1889
1890 /* Set it to something longer */
1891 _dbus_string_init_const (&t, "Hello world foo");
1892
1893 v_STRING = _dbus_string_get_const_data (&t);
1895 &v_STRING, byte_order, NULL, NULL);
1896
1898 &v_STRING, byte_order,
1899 NULL);
1900 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
1901
1902 /* Set it to something shorter */
1903 _dbus_string_init_const (&t, "Hello");
1904
1905 v_STRING = _dbus_string_get_const_data (&t);
1907 &v_STRING, byte_order, NULL, NULL);
1909 &v_STRING, byte_order,
1910 NULL);
1911 _dbus_assert (strcmp (v_STRING, "Hello") == 0);
1912
1913 /* Do the other byte order */
1914 if (byte_order == DBUS_LITTLE_ENDIAN)
1915 byte_order = DBUS_BIG_ENDIAN;
1916 else
1917 break;
1918 }
1919
1920 /* Clean up */
1921 _dbus_string_free (&str);
1922
1923 return TRUE;
1924}
1925
1926#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:802
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:1020
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:2104
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:1048
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
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:1283
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:490
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
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:1193
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:614
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:996
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:972
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:1375
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:1404
#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:623
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
dbus_uint32_t u32
as int32
Definition: dbus-types.h:143
dbus_uint64_t u64
as int64
Definition: dbus-types.h:146
dbus_uint16_t u16
as int16
Definition: dbus-types.h:141
unsigned char byt
as byte
Definition: dbus-types.h:149
char * str
as char* (string, object path or signature)
Definition: dbus-types.h:150