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