D-Bus  1.12.2
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 
92 static void
93 pack_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 
105 static void
106 pack_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 
118 static void
119 pack_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 
138 void
140  int byte_order,
141  unsigned char *data)
142 {
143  pack_4_octets (value, byte_order, data);
144 }
145 
146 static void
147 swap_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
157 
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
178 
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 
198 static void
199 set_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 
214 static void
215 set_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 
230 static void
231 set_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 
256 void
258  int pos,
259  dbus_uint32_t value,
260  int byte_order)
261 {
262  set_4_octets (str, pos, value, byte_order);
263 }
264 
284 static dbus_bool_t
285 set_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 
330 static dbus_bool_t
331 set_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;
406  case DBUS_TYPE_BOOLEAN:
407  case DBUS_TYPE_INT32:
408  case DBUS_TYPE_UINT32:
409  case DBUS_TYPE_UNIX_FD:
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;
436  case DBUS_TYPE_SIGNATURE:
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 
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 
495 void
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:
535  case DBUS_TYPE_BOOLEAN:
536  case DBUS_TYPE_UNIX_FD:
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;
572  case DBUS_TYPE_SIGNATURE:
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 
596 static dbus_bool_t
597 marshal_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 
625 static dbus_bool_t
626 marshal_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 
654 static dbus_bool_t
655 marshal_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 
679 enum
680  {
681  MARSHAL_AS_STRING,
682  MARSHAL_AS_SIGNATURE,
683  MARSHAL_AS_BYTE_ARRAY
684  };
685 
686 static dbus_bool_t
687 marshal_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 
755 static dbus_bool_t
756 marshal_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 
768 static dbus_bool_t
769 marshal_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;
825  case DBUS_TYPE_BOOLEAN:
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:
831  case DBUS_TYPE_UNIX_FD:
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;
846  case DBUS_TYPE_SIGNATURE:
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 
857 static dbus_bool_t
858 marshal_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 
891 void
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 
935 static void
936 swap_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 
954 static dbus_bool_t
955 marshal_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 
1080 void
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:
1113  case DBUS_TYPE_OBJECT_PATH:
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;
1122  case DBUS_TYPE_SIGNATURE:
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 
1148 void
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 
1176 int
1178 {
1179  switch (typecode)
1180  {
1181  case DBUS_TYPE_BYTE:
1182  case DBUS_TYPE_VARIANT:
1183  case DBUS_TYPE_SIGNATURE:
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:
1194  case DBUS_TYPE_OBJECT_PATH:
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:
1207  case DBUS_TYPE_DICT_ENTRY:
1208  return 8;
1209 
1210  default:
1211  _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1212  return 0;
1213  }
1214 }
1215 
1222 const char *
1223 _dbus_type_to_string (int typecode)
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";
1249  case DBUS_TYPE_OBJECT_PATH:
1250  return "object_path";
1251  case DBUS_TYPE_SIGNATURE:
1252  return "signature";
1253  case DBUS_TYPE_STRUCT:
1254  return "struct";
1255  case DBUS_TYPE_DICT_ENTRY:
1256  return "dict_entry";
1257  case DBUS_TYPE_ARRAY:
1258  return "array";
1259  case DBUS_TYPE_VARIANT:
1260  return "variant";
1262  return "begin_struct";
1263  case DBUS_STRUCT_END_CHAR:
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 
1283 void
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",
1335  _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1336  _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
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 
1361 void
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 
1392 static int
1393 map_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 
1417 int
1419  int pos)
1420 {
1421  return map_type_char_to_type (_dbus_string_get_byte (str, pos));
1422 }
1423 
1432 int
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 
1463 void
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 
1494 static void
1495 swap_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,
1852  DBUS_BIG_ENDIAN);
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 */
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...
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
#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 "critical" 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 "basic type" 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_GNUC_EXTENSION typedef unsigned long dbus_uint64_t
A 64-bit unsigned integer.
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
_DBUS_GNUC_EXTENSION typedef long dbus_int64_t
A 64-bit signed integer.
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
short dbus_int16_t
A 16-bit signed integer on all platforms.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
#define TRUE
Expands to "1".
#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_INT64_CONSTANT(val)
Declare a 64-bit signed integer constant.
#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 "0".
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
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_int32_t
A 32-bit signed integer on all platforms.
#define DBUS_UINT64_CONSTANT(val)
Declare a 64-bit unsigned integer constant.
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 "a == b" it may have a or b in an 80-bit register...
Definition: dbus-sysdeps.h:597
unsigned short dbus_uint16_t
A 16-bit unsigned integer on all platforms.
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.