D-Bus  1.4.10
dbus-marshal-basic.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-marshal-basic.c Marshalling routines for basic (primitive) types
3  *
4  * Copyright (C) 2002 CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-marshal-basic.h"
28 #include "dbus-signature.h"
29 
30 #include <string.h>
31 
47 static void
48 pack_2_octets (dbus_uint16_t value,
49  int byte_order,
50  unsigned char *data)
51 {
52  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
53 
54  if ((byte_order) == DBUS_LITTLE_ENDIAN)
55  *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
56  else
57  *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
58 }
59 
60 static void
61 pack_4_octets (dbus_uint32_t value,
62  int byte_order,
63  unsigned char *data)
64 {
65  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
66 
67  if ((byte_order) == DBUS_LITTLE_ENDIAN)
68  *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
69  else
70  *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
71 }
72 
73 static void
74 pack_8_octets (DBusBasicValue value,
75  int byte_order,
76  unsigned char *data)
77 {
78  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
79 
80 #ifdef DBUS_HAVE_INT64
81  if ((byte_order) == DBUS_LITTLE_ENDIAN)
82  *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
83  else
84  *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
85 #else
86  *(DBus8ByteStruct*)data = value.u64;
87  swap_8_octets ((DBusBasicValue*)data, byte_order);
88 #endif
89 }
90 
98 void
100  int byte_order,
101  unsigned char *data)
102 {
103  pack_4_octets (value, byte_order, data);
104 }
105 
106 #ifndef DBUS_HAVE_INT64
107 /* from ORBit */
108 static void
109 swap_bytes (unsigned char *data,
110  unsigned int len)
111 {
112  unsigned char *p1 = data;
113  unsigned char *p2 = data + len - 1;
114 
115  while (p1 < p2)
116  {
117  unsigned char tmp = *p1;
118  *p1 = *p2;
119  *p2 = tmp;
120 
121  --p2;
122  ++p1;
123  }
124 }
125 #endif /* !DBUS_HAVE_INT64 */
126 
127 static void
128 swap_8_octets (DBusBasicValue *value,
129  int byte_order)
130 {
131  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
132  {
133 #ifdef DBUS_HAVE_INT64
134  value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
135 #else
136  swap_bytes ((unsigned char *)value, 8);
137 #endif
138  }
139 }
140 
141 #if 0
142 static DBusBasicValue
143 unpack_8_octets (int byte_order,
144  const unsigned char *data)
145 {
146  DBusBasicValue r;
147 
148  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
149  _dbus_assert (sizeof (r) == 8);
150 
151 #ifdef DBUS_HAVE_INT64
152  if (byte_order == DBUS_LITTLE_ENDIAN)
153  r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
154  else
155  r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
156 #else
157  r.u64 = *(DBus8ByteStruct*)data;
158  swap_8_octets (&r, byte_order);
159 #endif
160 
161  return r;
162 }
163 #endif
164 
165 #ifndef _dbus_unpack_uint16
166 
174 _dbus_unpack_uint16 (int byte_order,
175  const unsigned char *data)
176 {
177  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
178 
179  if (byte_order == DBUS_LITTLE_ENDIAN)
180  return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
181  else
182  return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
183 }
184 #endif /* _dbus_unpack_uint16 */
185 
186 #ifndef _dbus_unpack_uint32
187 
195 _dbus_unpack_uint32 (int byte_order,
196  const unsigned char *data)
197 {
198  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
199 
200  if (byte_order == DBUS_LITTLE_ENDIAN)
201  return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
202  else
203  return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
204 }
205 #endif /* _dbus_unpack_uint32 */
206 
207 static void
208 set_2_octets (DBusString *str,
209  int offset,
210  dbus_uint16_t value,
211  int byte_order)
212 {
213  char *data;
214 
215  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
216  byte_order == DBUS_BIG_ENDIAN);
217 
218  data = _dbus_string_get_data_len (str, offset, 2);
219 
220  pack_2_octets (value, byte_order, data);
221 }
222 
223 static void
224 set_4_octets (DBusString *str,
225  int offset,
226  dbus_uint32_t value,
227  int byte_order)
228 {
229  char *data;
230 
231  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
232  byte_order == DBUS_BIG_ENDIAN);
233 
234  data = _dbus_string_get_data_len (str, offset, 4);
235 
236  pack_4_octets (value, byte_order, data);
237 }
238 
239 static void
240 set_8_octets (DBusString *str,
241  int offset,
242  DBusBasicValue value,
243  int byte_order)
244 {
245  char *data;
246 
247  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
248  byte_order == DBUS_BIG_ENDIAN);
249 
250  data = _dbus_string_get_data_len (str, offset, 8);
251 
252  pack_8_octets (value, byte_order, data);
253 }
254 
265 void
267  int pos,
268  dbus_uint32_t value,
269  int byte_order)
270 {
271  set_4_octets (str, pos, value, byte_order);
272 }
273 
293 static dbus_bool_t
294 set_string (DBusString *str,
295  int pos,
296  const char *value,
297  int byte_order,
298  int *old_end_pos,
299  int *new_end_pos)
300 {
301  int old_len, new_len;
302  DBusString dstr;
303 
304  _dbus_string_init_const (&dstr, value);
305 
306  _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
307  old_len = _dbus_unpack_uint32 (byte_order,
308  _dbus_string_get_const_data_len (str, pos, 4));
309 
310  new_len = _dbus_string_get_length (&dstr);
311 
312  if (!_dbus_string_replace_len (&dstr, 0, new_len,
313  str, pos + 4, old_len))
314  return FALSE;
315 
316  _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
317 
318  if (old_end_pos)
319  *old_end_pos = pos + 4 + old_len + 1;
320  if (new_end_pos)
321  *new_end_pos = pos + 4 + new_len + 1;
322 
323  return TRUE;
324 }
325 
339 static dbus_bool_t
340 set_signature (DBusString *str,
341  int pos,
342  const char *value,
343  int byte_order,
344  int *old_end_pos,
345  int *new_end_pos)
346 {
347  int old_len, new_len;
348  DBusString dstr;
349 
350  _dbus_string_init_const (&dstr, value);
351 
352  old_len = _dbus_string_get_byte (str, pos);
353  new_len = _dbus_string_get_length (&dstr);
354 
355  if (!_dbus_string_replace_len (&dstr, 0, new_len,
356  str, pos + 1, old_len))
357  return FALSE;
358 
359  _dbus_string_set_byte (str, pos, new_len);
360 
361  if (old_end_pos)
362  *old_end_pos = pos + 1 + old_len + 1;
363  if (new_end_pos)
364  *new_end_pos = pos + 1 + new_len + 1;
365 
366  return TRUE;
367 }
368 
384  int pos,
385  int type,
386  const void *value,
387  int byte_order,
388  int *old_end_pos,
389  int *new_end_pos)
390 {
391  const DBusBasicValue *vp;
392 
393  vp = value;
394 
395  switch (type)
396  {
397  case DBUS_TYPE_BYTE:
398  _dbus_string_set_byte (str, pos, vp->byt);
399  if (old_end_pos)
400  *old_end_pos = pos + 1;
401  if (new_end_pos)
402  *new_end_pos = pos + 1;
403  return TRUE;
404  break;
405  case DBUS_TYPE_INT16:
406  case DBUS_TYPE_UINT16:
407  pos = _DBUS_ALIGN_VALUE (pos, 2);
408  set_2_octets (str, pos, vp->u16, byte_order);
409  if (old_end_pos)
410  *old_end_pos = pos + 2;
411  if (new_end_pos)
412  *new_end_pos = pos + 2;
413  return TRUE;
414  break;
415  case DBUS_TYPE_BOOLEAN:
416  case DBUS_TYPE_INT32:
417  case DBUS_TYPE_UINT32:
418  case DBUS_TYPE_UNIX_FD:
419  pos = _DBUS_ALIGN_VALUE (pos, 4);
420  set_4_octets (str, pos, vp->u32, byte_order);
421  if (old_end_pos)
422  *old_end_pos = pos + 4;
423  if (new_end_pos)
424  *new_end_pos = pos + 4;
425  return TRUE;
426  break;
427  case DBUS_TYPE_INT64:
428  case DBUS_TYPE_UINT64:
429  case DBUS_TYPE_DOUBLE:
430  pos = _DBUS_ALIGN_VALUE (pos, 8);
431  set_8_octets (str, pos, *vp, byte_order);
432  if (old_end_pos)
433  *old_end_pos = pos + 8;
434  if (new_end_pos)
435  *new_end_pos = pos + 8;
436  return TRUE;
437  break;
438  case DBUS_TYPE_STRING:
440  pos = _DBUS_ALIGN_VALUE (pos, 4);
441  _dbus_assert (vp->str != NULL);
442  return set_string (str, pos, vp->str, byte_order,
443  old_end_pos, new_end_pos);
444  break;
445  case DBUS_TYPE_SIGNATURE:
446  _dbus_assert (vp->str != NULL);
447  return set_signature (str, pos, vp->str, byte_order,
448  old_end_pos, new_end_pos);
449  break;
450  default:
451  _dbus_assert_not_reached ("not a basic type");
452  return FALSE;
453  break;
454  }
455 }
456 
468  int pos,
469  int byte_order,
470  int *new_pos)
471 {
472  pos = _DBUS_ALIGN_VALUE (pos, 4);
473 
474  if (new_pos)
475  *new_pos = pos + 4;
476 
477  _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
478 
479  return _dbus_unpack_uint32 (byte_order,
480  _dbus_string_get_const_data (str) + pos);
481 }
482 
504 void
506  int pos,
507  int type,
508  void *value,
509  int byte_order,
510  int *new_pos)
511 {
512  const char *str_data;
513 
515 
516  str_data = _dbus_string_get_const_data (str);
517 
518  /* Below we volatile types to avoid aliasing issues;
519  * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
520  */
521 
522  switch (type)
523  {
524  case DBUS_TYPE_BYTE:
525  {
526  volatile unsigned char *vp = value;
527  *vp = (unsigned char) _dbus_string_get_byte (str, pos);
528  (pos)++;
529  }
530  break;
531  case DBUS_TYPE_INT16:
532  case DBUS_TYPE_UINT16:
533  {
534  volatile dbus_uint16_t *vp = value;
535  pos = _DBUS_ALIGN_VALUE (pos, 2);
536  *vp = *(dbus_uint16_t *)(str_data + pos);
537  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
538  *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
539  pos += 2;
540  }
541  break;
542  case DBUS_TYPE_INT32:
543  case DBUS_TYPE_UINT32:
544  case DBUS_TYPE_BOOLEAN:
545  case DBUS_TYPE_UNIX_FD:
546  {
547  volatile dbus_uint32_t *vp = value;
548  pos = _DBUS_ALIGN_VALUE (pos, 4);
549  *vp = *(dbus_uint32_t *)(str_data + pos);
550  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
551  *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
552  pos += 4;
553  }
554  break;
555  case DBUS_TYPE_INT64:
556  case DBUS_TYPE_UINT64:
557  case DBUS_TYPE_DOUBLE:
558  {
559  volatile dbus_uint64_t *vp = value;
560  pos = _DBUS_ALIGN_VALUE (pos, 8);
561 #ifdef DBUS_HAVE_INT64
562  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
563  *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
564  else
565  *vp = *(dbus_uint64_t*)(str_data + pos);
566 #else
567  *vp = *(DBus8ByteStruct*) (str_data + pos);
568  swap_8_octets (vp, byte_order);
569 #endif
570  pos += 8;
571  }
572  break;
573  case DBUS_TYPE_STRING:
575  {
576  int len;
577  volatile char **vp = value;
578 
579  len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
580 
581  *vp = (char*) str_data + pos;
582 
583  pos += len + 1; /* length plus nul */
584  }
585  break;
586  case DBUS_TYPE_SIGNATURE:
587  {
588  int len;
589  volatile char **vp = value;
590 
591  len = _dbus_string_get_byte (str, pos);
592  pos += 1;
593 
594  *vp = (char*) str_data + pos;
595 
596  pos += len + 1; /* length plus nul */
597  }
598  break;
599  default:
600  _dbus_warn_check_failed ("type %s %d not a basic type\n",
601  _dbus_type_to_string (type), type);
602  _dbus_assert_not_reached ("not a basic type");
603  break;
604  }
605 
606  if (new_pos)
607  *new_pos = pos;
608 }
609 
610 static dbus_bool_t
611 marshal_2_octets (DBusString *str,
612  int insert_at,
613  dbus_uint16_t value,
614  int byte_order,
615  int *pos_after)
616 {
617  dbus_bool_t retval;
618  int orig_len;
619 
620  _dbus_assert (sizeof (value) == 2);
621 
622  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
623  value = DBUS_UINT16_SWAP_LE_BE (value);
624 
625  orig_len = _dbus_string_get_length (str);
626 
627  retval = _dbus_string_insert_2_aligned (str, insert_at,
628  (const unsigned char *)&value);
629 
630  if (pos_after)
631  {
632  *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
633  _dbus_assert (*pos_after <= _dbus_string_get_length (str));
634  }
635 
636  return retval;
637 }
638 
639 static dbus_bool_t
640 marshal_4_octets (DBusString *str,
641  int insert_at,
642  dbus_uint32_t value,
643  int byte_order,
644  int *pos_after)
645 {
646  dbus_bool_t retval;
647  int orig_len;
648 
649  _dbus_assert (sizeof (value) == 4);
650 
651  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
652  value = DBUS_UINT32_SWAP_LE_BE (value);
653 
654  orig_len = _dbus_string_get_length (str);
655 
656  retval = _dbus_string_insert_4_aligned (str, insert_at,
657  (const unsigned char *)&value);
658 
659  if (pos_after)
660  {
661  *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
662  _dbus_assert (*pos_after <= _dbus_string_get_length (str));
663  }
664 
665  return retval;
666 }
667 
668 static dbus_bool_t
669 marshal_8_octets (DBusString *str,
670  int insert_at,
671  DBusBasicValue value,
672  int byte_order,
673  int *pos_after)
674 {
675  dbus_bool_t retval;
676  int orig_len;
677 
678  _dbus_assert (sizeof (value) == 8);
679 
680  swap_8_octets (&value, byte_order);
681 
682  orig_len = _dbus_string_get_length (str);
683 
684  retval = _dbus_string_insert_8_aligned (str, insert_at,
685  (const unsigned char *)&value);
686 
687  if (pos_after)
688  *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
689 
690  return retval;
691 }
692 
693 enum
694  {
695  MARSHAL_AS_STRING,
696  MARSHAL_AS_SIGNATURE,
697  MARSHAL_AS_BYTE_ARRAY
698  };
699 
700 static dbus_bool_t
701 marshal_len_followed_by_bytes (int marshal_as,
702  DBusString *str,
703  int insert_at,
704  const unsigned char *value,
705  int data_len, /* doesn't include nul if any */
706  int byte_order,
707  int *pos_after)
708 {
709  int pos;
710  DBusString value_str;
711  int value_len;
712 
713  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
714  if (insert_at > _dbus_string_get_length (str))
715  _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
716  insert_at, _dbus_string_get_length (str), data_len);
717 
718  if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
719  value_len = data_len;
720  else
721  value_len = data_len + 1; /* value has a nul */
722 
723  _dbus_string_init_const_len (&value_str, value, value_len);
724 
725  pos = insert_at;
726 
727  if (marshal_as == MARSHAL_AS_SIGNATURE)
728  {
730  _dbus_assert (data_len <= 255); /* same as max sig len right now */
731 
732  if (!_dbus_string_insert_byte (str, pos, data_len))
733  goto oom;
734 
735  pos += 1;
736  }
737  else
738  {
739  if (!marshal_4_octets (str, pos, data_len,
740  byte_order, &pos))
741  goto oom;
742  }
743 
744  if (!_dbus_string_copy_len (&value_str, 0, value_len,
745  str, pos))
746  goto oom;
747 
748 #if 0
749  /* too expensive */
750  _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
751  str, pos));
752  _dbus_verbose_bytes_of_string (str, pos, value_len);
753 #endif
754 
755  pos += value_len;
756 
757  if (pos_after)
758  *pos_after = pos;
759 
760  return TRUE;
761 
762  oom:
763  /* Delete what we've inserted */
764  _dbus_string_delete (str, insert_at, pos - insert_at);
765 
766  return FALSE;
767 }
768 
769 static dbus_bool_t
770 marshal_string (DBusString *str,
771  int insert_at,
772  const char *value,
773  int byte_order,
774  int *pos_after)
775 {
776  return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
777  str, insert_at, value,
778  strlen (value),
779  byte_order, pos_after);
780 }
781 
782 static dbus_bool_t
783 marshal_signature (DBusString *str,
784  int insert_at,
785  const char *value,
786  int *pos_after)
787 {
788  return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
789  str, insert_at, value,
790  strlen (value),
791  DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
792  pos_after);
793 }
794 
813  int insert_at,
814  int type,
815  const void *value,
816  int byte_order,
817  int *pos_after)
818 {
819  const DBusBasicValue *vp;
820 
822 
823  vp = value;
824 
825  switch (type)
826  {
827  case DBUS_TYPE_BYTE:
828  if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
829  return FALSE;
830  if (pos_after)
831  *pos_after = insert_at + 1;
832  return TRUE;
833  break;
834  case DBUS_TYPE_INT16:
835  case DBUS_TYPE_UINT16:
836  return marshal_2_octets (str, insert_at, vp->u16,
837  byte_order, pos_after);
838  break;
839  case DBUS_TYPE_BOOLEAN:
840  return marshal_4_octets (str, insert_at, vp->u32 != FALSE,
841  byte_order, pos_after);
842  break;
843  case DBUS_TYPE_INT32:
844  case DBUS_TYPE_UINT32:
845  case DBUS_TYPE_UNIX_FD:
846  return marshal_4_octets (str, insert_at, vp->u32,
847  byte_order, pos_after);
848  break;
849  case DBUS_TYPE_INT64:
850  case DBUS_TYPE_UINT64:
851  case DBUS_TYPE_DOUBLE:
852  return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
853  break;
854 
855  case DBUS_TYPE_STRING:
857  _dbus_assert (vp->str != NULL);
858  return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
859  break;
860  case DBUS_TYPE_SIGNATURE:
861  _dbus_assert (vp->str != NULL);
862  return marshal_signature (str, insert_at, vp->str, pos_after);
863  break;
864  default:
865  _dbus_assert_not_reached ("not a basic type");
866  return FALSE;
867  break;
868  }
869 }
870 
871 static dbus_bool_t
872 marshal_1_octets_array (DBusString *str,
873  int insert_at,
874  const unsigned char *value,
875  int n_elements,
876  int byte_order,
877  int *pos_after)
878 {
879  int pos;
880  DBusString value_str;
881 
882  _dbus_string_init_const_len (&value_str, value, n_elements);
883 
884  pos = insert_at;
885 
886  if (!_dbus_string_copy_len (&value_str, 0, n_elements,
887  str, pos))
888  return FALSE;
889 
890  pos += n_elements;
891 
892  if (pos_after)
893  *pos_after = pos;
894 
895  return TRUE;
896 }
897 
905 void
906 _dbus_swap_array (unsigned char *data,
907  int n_elements,
908  int alignment)
909 {
910  unsigned char *d;
911  unsigned char *end;
912 
913  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
914 
915  /* we use const_data and cast it off so DBusString can be a const string
916  * for the unit tests. don't ask.
917  */
918  d = data;
919  end = d + (n_elements * alignment);
920 
921  if (alignment == 8)
922  {
923  while (d != end)
924  {
925 #ifdef DBUS_HAVE_INT64
926  *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
927 #else
928  swap_8_bytes ((DBusBasicValue*) d);
929 #endif
930  d += 8;
931  }
932  }
933  else if (alignment == 4)
934  {
935  while (d != end)
936  {
937  *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
938  d += 4;
939  }
940  }
941  else
942  {
943  _dbus_assert (alignment == 2);
944 
945  while (d != end)
946  {
947  *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
948  d += 2;
949  }
950  }
951 }
952 
953 static void
954 swap_array (DBusString *str,
955  int array_start,
956  int n_elements,
957  int byte_order,
958  int alignment)
959 {
960  _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
961 
962  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
963  {
964  /* we use const_data and cast it off so DBusString can be a const string
965  * for the unit tests. don't ask.
966  */
967  _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
968  n_elements, alignment);
969  }
970 }
971 
972 static dbus_bool_t
973 marshal_fixed_multi (DBusString *str,
974  int insert_at,
975  const DBusBasicValue *value,
976  int n_elements,
977  int byte_order,
978  int alignment,
979  int *pos_after)
980 {
981  int old_string_len;
982  int array_start;
983  DBusString t;
984  int len_in_bytes;
985 
986  _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
987 
988  old_string_len = _dbus_string_get_length (str);
989 
990  len_in_bytes = n_elements * alignment;
991  array_start = insert_at;
992 
993  /* Note that we do alignment padding unconditionally
994  * even if the array is empty; this means that
995  * padding + len is always equal to the number of bytes
996  * in the array.
997  */
998 
999  if (!_dbus_string_insert_alignment (str, &array_start, alignment))
1000  goto error;
1001 
1003  (const unsigned char*) value,
1004  len_in_bytes);
1005 
1006  if (!_dbus_string_copy (&t, 0,
1007  str, array_start))
1008  goto error;
1009 
1010  swap_array (str, array_start, n_elements, byte_order, alignment);
1011 
1012  if (pos_after)
1013  *pos_after = array_start + len_in_bytes;
1014 
1015  return TRUE;
1016 
1017  error:
1018  _dbus_string_delete (str, insert_at,
1019  _dbus_string_get_length (str) - old_string_len);
1020 
1021  return FALSE;
1022 }
1023 
1043  int insert_at,
1044  int element_type,
1045  const void *value,
1046  int n_elements,
1047  int byte_order,
1048  int *pos_after)
1049 {
1050  const void* vp = *(const DBusBasicValue**)value;
1051 
1052  _dbus_assert (dbus_type_is_fixed (element_type));
1053  _dbus_assert (n_elements >= 0);
1054 
1055 #if 0
1056  _dbus_verbose ("writing %d elements of %s\n",
1057  n_elements, _dbus_type_to_string (element_type));
1058 #endif
1059 
1060  switch (element_type)
1061  {
1062  case DBUS_TYPE_BYTE:
1063  return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after);
1064  break;
1065  case DBUS_TYPE_INT16:
1066  case DBUS_TYPE_UINT16:
1067  return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
1068  case DBUS_TYPE_BOOLEAN:
1069  case DBUS_TYPE_INT32:
1070  case DBUS_TYPE_UINT32:
1071  case DBUS_TYPE_UNIX_FD:
1072  return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
1073  break;
1074  case DBUS_TYPE_INT64:
1075  case DBUS_TYPE_UINT64:
1076  case DBUS_TYPE_DOUBLE:
1077  return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after);
1078  break;
1079 
1080  default:
1081  _dbus_assert_not_reached ("non fixed type in array write");
1082  break;
1083  }
1084 
1085  return FALSE;
1086 }
1087 
1088 
1098 void
1100  int type,
1101  int byte_order,
1102  int *pos)
1103 {
1104  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
1105  byte_order == DBUS_BIG_ENDIAN);
1106 
1107  switch (type)
1108  {
1109  case DBUS_TYPE_BYTE:
1110  (*pos)++;
1111  break;
1112  case DBUS_TYPE_INT16:
1113  case DBUS_TYPE_UINT16:
1114  *pos = _DBUS_ALIGN_VALUE (*pos, 2);
1115  *pos += 2;
1116  break;
1117  case DBUS_TYPE_BOOLEAN:
1118  case DBUS_TYPE_INT32:
1119  case DBUS_TYPE_UINT32:
1120  case DBUS_TYPE_UNIX_FD:
1121  *pos = _DBUS_ALIGN_VALUE (*pos, 4);
1122  *pos += 4;
1123  break;
1124  case DBUS_TYPE_INT64:
1125  case DBUS_TYPE_UINT64:
1126  case DBUS_TYPE_DOUBLE:
1127  *pos = _DBUS_ALIGN_VALUE (*pos, 8);
1128  *pos += 8;
1129  break;
1130  case DBUS_TYPE_STRING:
1131  case DBUS_TYPE_OBJECT_PATH:
1132  {
1133  int len;
1134 
1135  len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
1136 
1137  *pos += len + 1; /* length plus nul */
1138  }
1139  break;
1140  case DBUS_TYPE_SIGNATURE:
1141  {
1142  int len;
1143 
1144  len = _dbus_string_get_byte (str, *pos);
1145 
1146  *pos += len + 2; /* length byte plus length plus nul */
1147  }
1148  break;
1149  default:
1150  _dbus_warn ("type %s not a basic type\n",
1151  _dbus_type_to_string (type));
1152  _dbus_assert_not_reached ("not a basic type");
1153  break;
1154  }
1155 }
1156 
1166 void
1168  int element_type,
1169  int byte_order,
1170  int *pos)
1171 {
1172  dbus_uint32_t array_len;
1173  int i;
1174  int alignment;
1175 
1176  i = _DBUS_ALIGN_VALUE (*pos, 4);
1177 
1178  array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
1179 
1180  alignment = _dbus_type_get_alignment (element_type);
1181 
1182  i = _DBUS_ALIGN_VALUE (i, alignment);
1183 
1184  *pos = i + array_len;
1185 }
1186 
1194 int
1196 {
1197  switch (typecode)
1198  {
1199  case DBUS_TYPE_BYTE:
1200  case DBUS_TYPE_VARIANT:
1201  case DBUS_TYPE_SIGNATURE:
1202  return 1;
1203  case DBUS_TYPE_INT16:
1204  case DBUS_TYPE_UINT16:
1205  return 2;
1206  case DBUS_TYPE_BOOLEAN:
1207  case DBUS_TYPE_INT32:
1208  case DBUS_TYPE_UINT32:
1209  case DBUS_TYPE_UNIX_FD:
1210  /* this stuff is 4 since it starts with a length */
1211  case DBUS_TYPE_STRING:
1212  case DBUS_TYPE_OBJECT_PATH:
1213  case DBUS_TYPE_ARRAY:
1214  return 4;
1215  case DBUS_TYPE_INT64:
1216  case DBUS_TYPE_UINT64:
1217  case DBUS_TYPE_DOUBLE:
1218  /* struct is 8 since it could contain an 8-aligned item
1219  * and it's simpler to just always align structs to 8;
1220  * we want the amount of padding in a struct of a given
1221  * type to be predictable, not location-dependent.
1222  * DICT_ENTRY is always the same as struct.
1223  */
1224  case DBUS_TYPE_STRUCT:
1225  case DBUS_TYPE_DICT_ENTRY:
1226  return 8;
1227 
1228  default:
1229  _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
1230  return 0;
1231  }
1232 }
1233 
1234 
1244 _dbus_type_is_valid (int typecode)
1245 {
1246  switch (typecode)
1247  {
1248  case DBUS_TYPE_BYTE:
1249  case DBUS_TYPE_BOOLEAN:
1250  case DBUS_TYPE_INT16:
1251  case DBUS_TYPE_UINT16:
1252  case DBUS_TYPE_INT32:
1253  case DBUS_TYPE_UINT32:
1254  case DBUS_TYPE_INT64:
1255  case DBUS_TYPE_UINT64:
1256  case DBUS_TYPE_DOUBLE:
1257  case DBUS_TYPE_STRING:
1258  case DBUS_TYPE_OBJECT_PATH:
1259  case DBUS_TYPE_SIGNATURE:
1260  case DBUS_TYPE_ARRAY:
1261  case DBUS_TYPE_STRUCT:
1262  case DBUS_TYPE_DICT_ENTRY:
1263  case DBUS_TYPE_VARIANT:
1264  case DBUS_TYPE_UNIX_FD:
1265  return TRUE;
1266 
1267  default:
1268  return FALSE;
1269  }
1270 }
1271 
1278 const char *
1279 _dbus_type_to_string (int typecode)
1280 {
1281  switch (typecode)
1282  {
1283  case DBUS_TYPE_INVALID:
1284  return "invalid";
1285  case DBUS_TYPE_BOOLEAN:
1286  return "boolean";
1287  case DBUS_TYPE_BYTE:
1288  return "byte";
1289  case DBUS_TYPE_INT16:
1290  return "int16";
1291  case DBUS_TYPE_UINT16:
1292  return "uint16";
1293  case DBUS_TYPE_INT32:
1294  return "int32";
1295  case DBUS_TYPE_UINT32:
1296  return "uint32";
1297  case DBUS_TYPE_INT64:
1298  return "int64";
1299  case DBUS_TYPE_UINT64:
1300  return "uint64";
1301  case DBUS_TYPE_DOUBLE:
1302  return "double";
1303  case DBUS_TYPE_STRING:
1304  return "string";
1305  case DBUS_TYPE_OBJECT_PATH:
1306  return "object_path";
1307  case DBUS_TYPE_SIGNATURE:
1308  return "signature";
1309  case DBUS_TYPE_STRUCT:
1310  return "struct";
1311  case DBUS_TYPE_DICT_ENTRY:
1312  return "dict_entry";
1313  case DBUS_TYPE_ARRAY:
1314  return "array";
1315  case DBUS_TYPE_VARIANT:
1316  return "variant";
1318  return "begin_struct";
1319  case DBUS_STRUCT_END_CHAR:
1320  return "end_struct";
1322  return "begin_dict_entry";
1324  return "end_dict_entry";
1325  case DBUS_TYPE_UNIX_FD:
1326  return "unix_fd";
1327  default:
1328  return "unknown";
1329  }
1330 }
1331 
1339 void
1340 _dbus_verbose_bytes (const unsigned char *data,
1341  int len,
1342  int offset)
1343 {
1344  int i;
1345  const unsigned char *aligned;
1346 
1347  _dbus_assert (len >= 0);
1348 
1349  if (!_dbus_is_verbose())
1350  return;
1351 
1352  /* Print blanks on first row if appropriate */
1353  aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1354  if (aligned > data)
1355  aligned -= 4;
1356  _dbus_assert (aligned <= data);
1357 
1358  if (aligned != data)
1359  {
1360  _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
1361  while (aligned != data)
1362  {
1363  _dbus_verbose (" ");
1364  ++aligned;
1365  }
1366  }
1367 
1368  /* now print the bytes */
1369  i = 0;
1370  while (i < len)
1371  {
1372  if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1373  {
1374  _dbus_verbose ("%4d\t%p: ",
1375  offset + i, &data[i]);
1376  }
1377 
1378  if (data[i] >= 32 &&
1379  data[i] <= 126)
1380  _dbus_verbose (" '%c' ", data[i]);
1381  else
1382  _dbus_verbose ("0x%s%x ",
1383  data[i] <= 0xf ? "0" : "", data[i]);
1384 
1385  ++i;
1386 
1387  if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1388  {
1389  if (i > 3)
1390  _dbus_verbose ("BE: %d LE: %d",
1391  _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1392  _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1393 
1394  if (i > 7 &&
1395  _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1396  {
1397 #ifdef DBUS_INT64_PRINTF_MODIFIER
1398  _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x",
1399  *(dbus_uint64_t*)&data[i-8]);
1400 #endif
1401  _dbus_verbose (" dbl: %g",
1402  *(double*)&data[i-8]);
1403  }
1404 
1405  _dbus_verbose ("\n");
1406  }
1407  }
1408 
1409  _dbus_verbose ("\n");
1410 }
1411 
1419 void
1421  int start,
1422  int len)
1423 {
1424  const char *d;
1425  int real_len;
1426 
1427  real_len = _dbus_string_get_length (str);
1428 
1429  _dbus_assert (start >= 0);
1430 
1431  if (start > real_len)
1432  {
1433  _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1434  start, len, real_len);
1435  return;
1436  }
1437 
1438  if ((start + len) > real_len)
1439  {
1440  _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1441  start, len, real_len);
1442  len = real_len - start;
1443  }
1444 
1445  d = _dbus_string_get_const_data_len (str, start, len);
1446 
1447  _dbus_verbose_bytes (d, len, start);
1448 }
1449 
1450 static int
1451 map_type_char_to_type (int t)
1452 {
1453  if (t == DBUS_STRUCT_BEGIN_CHAR)
1454  return DBUS_TYPE_STRUCT;
1455  else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
1456  return DBUS_TYPE_DICT_ENTRY;
1457  else
1458  {
1461  return t;
1462  }
1463 }
1464 
1475 int
1477  int pos)
1478 {
1479  return map_type_char_to_type (_dbus_string_get_byte (str, pos));
1480 }
1481 
1490 int
1492  int pos)
1493 {
1494  return map_type_char_to_type (str[pos]);
1495 }
1496 
1499 #ifdef DBUS_BUILD_TESTS
1500 #include "dbus-test.h"
1501 #include <stdio.h>
1502 
1521 void
1522 _dbus_marshal_read_fixed_multi (const DBusString *str,
1523  int pos,
1524  int element_type,
1525  void *value,
1526  int n_elements,
1527  int byte_order,
1528  int *new_pos)
1529 {
1530  int array_len;
1531  int alignment;
1532 
1533  _dbus_assert (dbus_type_is_fixed (element_type));
1534  _dbus_assert (dbus_type_is_basic (element_type));
1535 
1536 #if 0
1537  _dbus_verbose ("reading %d elements of %s\n",
1538  n_elements, _dbus_type_to_string (element_type));
1539 #endif
1540 
1541  alignment = _dbus_type_get_alignment (element_type);
1542 
1543  pos = _DBUS_ALIGN_VALUE (pos, alignment);
1544 
1545  array_len = n_elements * alignment;
1546 
1547  *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
1548  if (new_pos)
1549  *new_pos = pos + array_len;
1550 }
1551 
1552 static void
1553 swap_test_array (void *array,
1554  int len_bytes,
1555  int byte_order,
1556  int alignment)
1557 {
1558  DBusString t;
1559 
1560  if (alignment == 1)
1561  return;
1562 
1563  _dbus_string_init_const_len (&t, array, len_bytes);
1564  swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
1565 }
1566 
1567 #define MARSHAL_BASIC(typename, byte_order, literal) \
1568  do { \
1569  v_##typename = literal; \
1570  if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \
1571  &v_##typename, \
1572  byte_order, NULL)) \
1573  _dbus_assert_not_reached ("no memory"); \
1574  } while (0)
1575 
1576 #define DEMARSHAL_BASIC(typename, byte_order) \
1577  do { \
1578  _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \
1579  byte_order, &pos); \
1580  } while (0)
1581 
1582 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \
1583  do { \
1584  DEMARSHAL_BASIC (typename, byte_order); \
1585  if (literal != v_##typename) \
1586  { \
1587  _dbus_verbose_bytes_of_string (&str, dump_pos, \
1588  _dbus_string_get_length (&str) - dump_pos); \
1589  _dbus_assert_not_reached ("demarshaled wrong value"); \
1590  } \
1591  } while (0)
1592 
1593 #define MARSHAL_TEST(typename, byte_order, literal) \
1594  do { \
1595  MARSHAL_BASIC (typename, byte_order, literal); \
1596  dump_pos = pos; \
1597  DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \
1598  } while (0)
1599 
1600 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \
1601  do { \
1602  MARSHAL_BASIC (typename, byte_order, literal); \
1603  dump_pos = pos; \
1604  DEMARSHAL_BASIC (typename, byte_order); \
1605  if (strcmp (literal, v_##typename) != 0) \
1606  { \
1607  _dbus_verbose_bytes_of_string (&str, dump_pos, \
1608  _dbus_string_get_length (&str) - dump_pos); \
1609  _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \
1610  _dbus_assert_not_reached ("demarshaled wrong value"); \
1611  } \
1612  } while (0)
1613 
1614 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \
1615  do { \
1616  int next; \
1617  v_UINT32 = sizeof(literal); \
1618  if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \
1619  byte_order, &next)) \
1620  _dbus_assert_not_reached ("no memory"); \
1621  v_ARRAY_##typename = literal; \
1622  if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \
1623  &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \
1624  byte_order, NULL)) \
1625  _dbus_assert_not_reached ("no memory"); \
1626  } while (0)
1627 
1628 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \
1629  do { \
1630  int next; \
1631  alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \
1632  v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \
1633  _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \
1634  v_UINT32/alignment, \
1635  byte_order, NULL); \
1636  swap_test_array (v_ARRAY_##typename, v_UINT32, \
1637  byte_order, alignment); \
1638  } while (0)
1639 
1640 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \
1641  do { \
1642  DEMARSHAL_FIXED_ARRAY (typename, byte_order); \
1643  if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0)) \
1644  { \
1645  _dbus_verbose ("MARSHALED DATA\n"); \
1646  _dbus_verbose_bytes_of_string (&str, dump_pos, \
1647  _dbus_string_get_length (&str) - dump_pos); \
1648  _dbus_verbose ("LITERAL DATA\n"); \
1649  _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \
1650  _dbus_verbose ("READ DATA\n"); \
1651  _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \
1652  _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \
1653  } \
1654  } while (0)
1655 
1656 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \
1657  do { \
1658  MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \
1659  dump_pos = pos; \
1660  DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \
1661  } while (0)
1662 
1664 _dbus_marshal_test (void)
1665 {
1666  int alignment;
1667  DBusString str;
1668  int pos, dump_pos;
1669  unsigned char array1[5] = { 3, 4, 0, 1, 9 };
1670  dbus_int16_t array2[3] = { 124, 457, 780 };
1671  dbus_int32_t array4[3] = { 123, 456, 789 };
1672 #ifdef DBUS_HAVE_INT64
1673  dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
1674  DBUS_INT64_CONSTANT (0x456ffffffff),
1675  DBUS_INT64_CONSTANT (0x789ffffffff) };
1676  dbus_int64_t *v_ARRAY_INT64;
1677 #endif
1678  unsigned char *v_ARRAY_BYTE;
1679  dbus_int16_t *v_ARRAY_INT16;
1680  dbus_uint16_t *v_ARRAY_UINT16;
1681  dbus_int32_t *v_ARRAY_INT32;
1682  dbus_uint32_t *v_ARRAY_UINT32;
1683  DBusString t;
1684  double v_DOUBLE;
1685  double t_DOUBLE;
1686  dbus_int16_t v_INT16;
1687  dbus_uint16_t v_UINT16;
1688  dbus_int32_t v_INT32;
1689  dbus_uint32_t v_UINT32;
1690  dbus_int64_t v_INT64;
1691  dbus_uint64_t v_UINT64;
1692  unsigned char v_BYTE;
1693  dbus_bool_t v_BOOLEAN;
1694  const char *v_STRING;
1695  const char *v_SIGNATURE;
1696  const char *v_OBJECT_PATH;
1697  int byte_order;
1698 
1699  if (!_dbus_string_init (&str))
1700  _dbus_assert_not_reached ("failed to init string");
1701 
1702  pos = 0;
1703 
1704  /* Marshal doubles */
1705  MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
1706  DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
1707  t_DOUBLE = 3.14;
1708  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1709  _dbus_assert_not_reached ("got wrong double value");
1710 
1711  MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
1712  DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
1713  t_DOUBLE = 3.14;
1714  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
1715  _dbus_assert_not_reached ("got wrong double value");
1716 
1717  /* Marshal signed 16 integers */
1718  MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
1719  MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
1720 
1721  /* Marshal unsigned 16 integers */
1722  MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
1723  MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
1724 
1725  /* Marshal signed integers */
1726  MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
1727  MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
1728 
1729  /* Marshal unsigned integers */
1730  MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
1731  MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
1732 
1733 #ifdef DBUS_HAVE_INT64
1734  /* Marshal signed integers */
1735  MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1736  MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
1737 
1738  /* Marshal unsigned integers */
1739  MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1740  MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
1741 #endif /* DBUS_HAVE_INT64 */
1742 
1743  /* Marshal byte */
1744  MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
1745  MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
1746 
1747  /* Marshal all possible bools! */
1748  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
1749  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
1750  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
1751  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
1752 
1753  /* Marshal strings */
1754  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
1755  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
1756  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
1757  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
1758 
1759  /* object paths */
1760  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
1761  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
1762 
1763  /* signatures */
1764  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
1765  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
1766  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
1767  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
1768 
1769  /* Arrays */
1770  MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
1771  MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
1772  MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2);
1773  MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2);
1774 
1775  MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
1776  MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
1777  MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4);
1778  MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4);
1779 
1780  MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
1781  MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
1782 
1783 #ifdef DBUS_HAVE_INT64
1784  MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
1785  MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
1786 #endif
1787 
1788 #if 0
1789 
1790  /*
1791  * FIXME restore the set/pack tests
1792  */
1793 
1794 #ifdef DBUS_HAVE_INT64
1795  /* set/pack 64-bit integers */
1796  _dbus_string_set_length (&str, 8);
1797 
1798  /* signed little */
1799  _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
1800  0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1801 
1802  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1803  _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1804  _dbus_string_get_const_data (&str)));
1805 
1806  /* signed big */
1807  _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
1808  0, DBUS_INT64_CONSTANT (-0x123456789abc7));
1809 
1810  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1811  _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1812  _dbus_string_get_const_data (&str)));
1813 
1814  /* signed little pack */
1815  _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1817  _dbus_string_get_data (&str));
1818 
1819  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1820  _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
1821  _dbus_string_get_const_data (&str)));
1822 
1823  /* signed big pack */
1824  _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
1826  _dbus_string_get_data (&str));
1827 
1828  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
1829  _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
1830  _dbus_string_get_const_data (&str)));
1831 
1832  /* unsigned little */
1833  _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
1834  0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1835 
1836  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1837  _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1838  _dbus_string_get_const_data (&str)));
1839 
1840  /* unsigned big */
1841  _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
1842  0, DBUS_UINT64_CONSTANT (0x123456789abc7));
1843 
1844  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1845  _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1846  _dbus_string_get_const_data (&str)));
1847 
1848  /* unsigned little pack */
1849  _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1851  _dbus_string_get_data (&str));
1852 
1853  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1854  _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
1855  _dbus_string_get_const_data (&str)));
1856 
1857  /* unsigned big pack */
1858  _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
1860  _dbus_string_get_data (&str));
1861 
1862  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
1863  _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
1864  _dbus_string_get_const_data (&str)));
1865 #endif /* DBUS_HAVE_INT64 */
1866 
1867  /* set/pack 32-bit integers */
1868  _dbus_string_set_length (&str, 4);
1869 
1870  /* signed little */
1871  _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
1872  0, -0x123456);
1873 
1874  _dbus_assert (-0x123456 ==
1875  _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1876  _dbus_string_get_const_data (&str)));
1877 
1878  /* signed big */
1879  _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
1880  0, -0x123456);
1881 
1882  _dbus_assert (-0x123456 ==
1883  _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1884  _dbus_string_get_const_data (&str)));
1885 
1886  /* signed little pack */
1887  _dbus_pack_int32 (-0x123456,
1889  _dbus_string_get_data (&str));
1890 
1891  _dbus_assert (-0x123456 ==
1892  _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
1893  _dbus_string_get_const_data (&str)));
1894 
1895  /* signed big pack */
1896  _dbus_pack_int32 (-0x123456,
1898  _dbus_string_get_data (&str));
1899 
1900  _dbus_assert (-0x123456 ==
1901  _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
1902  _dbus_string_get_const_data (&str)));
1903 
1904  /* unsigned little */
1906  0, 0x123456,
1908 
1909  _dbus_assert (0x123456 ==
1911  _dbus_string_get_const_data (&str)));
1912 
1913  /* unsigned big */
1915  0, 0x123456,
1916  DBUS_BIG_ENDIAN);
1917 
1918  _dbus_assert (0x123456 ==
1920  _dbus_string_get_const_data (&str)));
1921 
1922  /* unsigned little pack */
1923  _dbus_pack_uint32 (0x123456,
1925  _dbus_string_get_data (&str));
1926 
1927  _dbus_assert (0x123456 ==
1929  _dbus_string_get_const_data (&str)));
1930 
1931  /* unsigned big pack */
1932  _dbus_pack_uint32 (0x123456,
1934  _dbus_string_get_data (&str));
1935 
1936  _dbus_assert (0x123456 ==
1938  _dbus_string_get_const_data (&str)));
1939 
1940 #endif /* set/pack tests for integers */
1941 
1942  /* Strings in-place set */
1943  byte_order = DBUS_LITTLE_ENDIAN;
1944  while (TRUE)
1945  {
1946  /* Init a string */
1947  _dbus_string_set_length (&str, 0);
1948 
1949  /* reset pos for the macros */
1950  pos = 0;
1951 
1952  MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
1953 
1954  /* Set it to something longer */
1955  _dbus_string_init_const (&t, "Hello world foo");
1956 
1957  v_STRING = _dbus_string_get_const_data (&t);
1959  &v_STRING, byte_order, NULL, NULL);
1960 
1962  &v_STRING, byte_order,
1963  NULL);
1964  _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
1965 
1966  /* Set it to something shorter */
1967  _dbus_string_init_const (&t, "Hello");
1968 
1969  v_STRING = _dbus_string_get_const_data (&t);
1971  &v_STRING, byte_order, NULL, NULL);
1973  &v_STRING, byte_order,
1974  NULL);
1975  _dbus_assert (strcmp (v_STRING, "Hello") == 0);
1976 
1977  /* Do the other byte order */
1978  if (byte_order == DBUS_LITTLE_ENDIAN)
1979  byte_order = DBUS_BIG_ENDIAN;
1980  else
1981  break;
1982  }
1983 
1984  /* Clean up */
1985  _dbus_string_free (&str);
1986 
1987  return TRUE;
1988 }
1989 
1990 #endif /* DBUS_BUILD_TESTS */