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