00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-marshal-basic.h"
00028 #include "dbus-signature.h"
00029
00030 #include <string.h>
00031
00032 #if defined(__GNUC__) && (__GNUC__ >= 4)
00033 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
00034 _DBUS_STATIC_ASSERT (__extension__ __alignof__ (type) op val)
00035 #else
00036
00037
00038 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \
00039 _DBUS_STATIC_ASSERT (TRUE)
00040 #endif
00041
00042
00043 _DBUS_STATIC_ASSERT (sizeof (char) == 1);
00044 _DBUS_ASSERT_ALIGNMENT (char, ==, 1);
00045
00046 _DBUS_STATIC_ASSERT (sizeof (dbus_int16_t) == 2);
00047 _DBUS_ASSERT_ALIGNMENT (dbus_int16_t, <=, 2);
00048 _DBUS_STATIC_ASSERT (sizeof (dbus_uint16_t) == 2);
00049 _DBUS_ASSERT_ALIGNMENT (dbus_uint16_t, <=, 2);
00050
00051 _DBUS_STATIC_ASSERT (sizeof (dbus_int32_t) == 4);
00052 _DBUS_ASSERT_ALIGNMENT (dbus_int32_t, <=, 4);
00053 _DBUS_STATIC_ASSERT (sizeof (dbus_uint32_t) == 4);
00054 _DBUS_ASSERT_ALIGNMENT (dbus_uint32_t, <=, 4);
00055 _DBUS_STATIC_ASSERT (sizeof (dbus_bool_t) == 4);
00056 _DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4);
00057
00058 _DBUS_STATIC_ASSERT (sizeof (double) == 8);
00059 _DBUS_ASSERT_ALIGNMENT (double, <=, 8);
00060
00061 #ifdef DBUS_HAVE_INT64
00062 _DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8);
00063 _DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8);
00064 _DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8);
00065 _DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8);
00066 #endif
00067
00068 _DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8);
00069
00070
00071
00072 _DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8);
00073 _DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8);
00074
00090 static void
00091 pack_2_octets (dbus_uint16_t value,
00092 int byte_order,
00093 unsigned char *data)
00094 {
00095 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
00096
00097 if ((byte_order) == DBUS_LITTLE_ENDIAN)
00098 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
00099 else
00100 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
00101 }
00102
00103 static void
00104 pack_4_octets (dbus_uint32_t value,
00105 int byte_order,
00106 unsigned char *data)
00107 {
00108 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00109
00110 if ((byte_order) == DBUS_LITTLE_ENDIAN)
00111 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
00112 else
00113 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
00114 }
00115
00116 static void
00117 pack_8_octets (DBusBasicValue value,
00118 int byte_order,
00119 unsigned char *data)
00120 {
00121 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00122
00123 #ifdef DBUS_HAVE_INT64
00124 if ((byte_order) == DBUS_LITTLE_ENDIAN)
00125 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
00126 else
00127 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
00128 #else
00129 *(DBus8ByteStruct*)data = value.eight;
00130 swap_8_octets ((DBusBasicValue*)data, byte_order);
00131 #endif
00132 }
00133
00141 void
00142 _dbus_pack_uint32 (dbus_uint32_t value,
00143 int byte_order,
00144 unsigned char *data)
00145 {
00146 pack_4_octets (value, byte_order, data);
00147 }
00148
00149 #ifndef DBUS_HAVE_INT64
00150
00151 static void
00152 swap_bytes (unsigned char *data,
00153 unsigned int len)
00154 {
00155 unsigned char *p1 = data;
00156 unsigned char *p2 = data + len - 1;
00157
00158 while (p1 < p2)
00159 {
00160 unsigned char tmp = *p1;
00161 *p1 = *p2;
00162 *p2 = tmp;
00163
00164 --p2;
00165 ++p1;
00166 }
00167 }
00168 #endif
00169
00170 static void
00171 swap_8_octets (DBusBasicValue *value,
00172 int byte_order)
00173 {
00174 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00175 {
00176 #ifdef DBUS_HAVE_INT64
00177 value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
00178 #else
00179 swap_bytes (&value->bytes, 8);
00180 #endif
00181 }
00182 }
00183
00184 #if 0
00185 static DBusBasicValue
00186 unpack_8_octets (int byte_order,
00187 const unsigned char *data)
00188 {
00189 DBusBasicValue r;
00190
00191 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00192 _dbus_assert (sizeof (r) == 8);
00193
00194 #ifdef DBUS_HAVE_INT64
00195 if (byte_order == DBUS_LITTLE_ENDIAN)
00196 r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
00197 else
00198 r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
00199 #else
00200 r.eight = *(DBus8ByteStruct*)data;
00201 swap_8_octets (&r, byte_order);
00202 #endif
00203
00204 return r;
00205 }
00206 #endif
00207
00208 #ifndef _dbus_unpack_uint16
00209
00216 dbus_uint16_t
00217 _dbus_unpack_uint16 (int byte_order,
00218 const unsigned char *data)
00219 {
00220 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
00221
00222 if (byte_order == DBUS_LITTLE_ENDIAN)
00223 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
00224 else
00225 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
00226 }
00227 #endif
00228
00229 #ifndef _dbus_unpack_uint32
00230
00237 dbus_uint32_t
00238 _dbus_unpack_uint32 (int byte_order,
00239 const unsigned char *data)
00240 {
00241 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00242
00243 if (byte_order == DBUS_LITTLE_ENDIAN)
00244 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
00245 else
00246 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
00247 }
00248 #endif
00249
00250 static void
00251 set_2_octets (DBusString *str,
00252 int offset,
00253 dbus_uint16_t value,
00254 int byte_order)
00255 {
00256 char *data;
00257
00258 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00259 byte_order == DBUS_BIG_ENDIAN);
00260
00261 data = _dbus_string_get_data_len (str, offset, 2);
00262
00263 pack_2_octets (value, byte_order, data);
00264 }
00265
00266 static void
00267 set_4_octets (DBusString *str,
00268 int offset,
00269 dbus_uint32_t value,
00270 int byte_order)
00271 {
00272 char *data;
00273
00274 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00275 byte_order == DBUS_BIG_ENDIAN);
00276
00277 data = _dbus_string_get_data_len (str, offset, 4);
00278
00279 pack_4_octets (value, byte_order, data);
00280 }
00281
00282 static void
00283 set_8_octets (DBusString *str,
00284 int offset,
00285 DBusBasicValue value,
00286 int byte_order)
00287 {
00288 char *data;
00289
00290 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00291 byte_order == DBUS_BIG_ENDIAN);
00292
00293 data = _dbus_string_get_data_len (str, offset, 8);
00294
00295 pack_8_octets (value, byte_order, data);
00296 }
00297
00308 void
00309 _dbus_marshal_set_uint32 (DBusString *str,
00310 int pos,
00311 dbus_uint32_t value,
00312 int byte_order)
00313 {
00314 set_4_octets (str, pos, value, byte_order);
00315 }
00316
00336 static dbus_bool_t
00337 set_string (DBusString *str,
00338 int pos,
00339 const char *value,
00340 int byte_order,
00341 int *old_end_pos,
00342 int *new_end_pos)
00343 {
00344 int old_len, new_len;
00345 DBusString dstr;
00346
00347 _dbus_string_init_const (&dstr, value);
00348
00349 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
00350 old_len = _dbus_unpack_uint32 (byte_order,
00351 _dbus_string_get_const_data_len (str, pos, 4));
00352
00353 new_len = _dbus_string_get_length (&dstr);
00354
00355 if (!_dbus_string_replace_len (&dstr, 0, new_len,
00356 str, pos + 4, old_len))
00357 return FALSE;
00358
00359 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
00360
00361 if (old_end_pos)
00362 *old_end_pos = pos + 4 + old_len + 1;
00363 if (new_end_pos)
00364 *new_end_pos = pos + 4 + new_len + 1;
00365
00366 return TRUE;
00367 }
00368
00382 static dbus_bool_t
00383 set_signature (DBusString *str,
00384 int pos,
00385 const char *value,
00386 int byte_order,
00387 int *old_end_pos,
00388 int *new_end_pos)
00389 {
00390 int old_len, new_len;
00391 DBusString dstr;
00392
00393 _dbus_string_init_const (&dstr, value);
00394
00395 old_len = _dbus_string_get_byte (str, pos);
00396 new_len = _dbus_string_get_length (&dstr);
00397
00398 if (!_dbus_string_replace_len (&dstr, 0, new_len,
00399 str, pos + 1, old_len))
00400 return FALSE;
00401
00402 _dbus_string_set_byte (str, pos, new_len);
00403
00404 if (old_end_pos)
00405 *old_end_pos = pos + 1 + old_len + 1;
00406 if (new_end_pos)
00407 *new_end_pos = pos + 1 + new_len + 1;
00408
00409 return TRUE;
00410 }
00411
00425 dbus_bool_t
00426 _dbus_marshal_set_basic (DBusString *str,
00427 int pos,
00428 int type,
00429 const void *value,
00430 int byte_order,
00431 int *old_end_pos,
00432 int *new_end_pos)
00433 {
00434 const DBusBasicValue *vp;
00435
00436 vp = value;
00437
00438 switch (type)
00439 {
00440 case DBUS_TYPE_BYTE:
00441 _dbus_string_set_byte (str, pos, vp->byt);
00442 if (old_end_pos)
00443 *old_end_pos = pos + 1;
00444 if (new_end_pos)
00445 *new_end_pos = pos + 1;
00446 return TRUE;
00447 break;
00448 case DBUS_TYPE_INT16:
00449 case DBUS_TYPE_UINT16:
00450 pos = _DBUS_ALIGN_VALUE (pos, 2);
00451 set_2_octets (str, pos, vp->u16, byte_order);
00452 if (old_end_pos)
00453 *old_end_pos = pos + 2;
00454 if (new_end_pos)
00455 *new_end_pos = pos + 2;
00456 return TRUE;
00457 break;
00458 case DBUS_TYPE_BOOLEAN:
00459 case DBUS_TYPE_INT32:
00460 case DBUS_TYPE_UINT32:
00461 case DBUS_TYPE_UNIX_FD:
00462 pos = _DBUS_ALIGN_VALUE (pos, 4);
00463 set_4_octets (str, pos, vp->u32, byte_order);
00464 if (old_end_pos)
00465 *old_end_pos = pos + 4;
00466 if (new_end_pos)
00467 *new_end_pos = pos + 4;
00468 return TRUE;
00469 break;
00470 case DBUS_TYPE_INT64:
00471 case DBUS_TYPE_UINT64:
00472 case DBUS_TYPE_DOUBLE:
00473 pos = _DBUS_ALIGN_VALUE (pos, 8);
00474 set_8_octets (str, pos, *vp, byte_order);
00475 if (old_end_pos)
00476 *old_end_pos = pos + 8;
00477 if (new_end_pos)
00478 *new_end_pos = pos + 8;
00479 return TRUE;
00480 break;
00481 case DBUS_TYPE_STRING:
00482 case DBUS_TYPE_OBJECT_PATH:
00483 pos = _DBUS_ALIGN_VALUE (pos, 4);
00484 _dbus_assert (vp->str != NULL);
00485 return set_string (str, pos, vp->str, byte_order,
00486 old_end_pos, new_end_pos);
00487 break;
00488 case DBUS_TYPE_SIGNATURE:
00489 _dbus_assert (vp->str != NULL);
00490 return set_signature (str, pos, vp->str, byte_order,
00491 old_end_pos, new_end_pos);
00492 break;
00493 default:
00494 _dbus_assert_not_reached ("not a basic type");
00495 return FALSE;
00496 break;
00497 }
00498 }
00499
00509 dbus_uint32_t
00510 _dbus_marshal_read_uint32 (const DBusString *str,
00511 int pos,
00512 int byte_order,
00513 int *new_pos)
00514 {
00515 pos = _DBUS_ALIGN_VALUE (pos, 4);
00516
00517 if (new_pos)
00518 *new_pos = pos + 4;
00519
00520 _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
00521
00522 return _dbus_unpack_uint32 (byte_order,
00523 _dbus_string_get_const_data (str) + pos);
00524 }
00525
00547 void
00548 _dbus_marshal_read_basic (const DBusString *str,
00549 int pos,
00550 int type,
00551 void *value,
00552 int byte_order,
00553 int *new_pos)
00554 {
00555 const char *str_data;
00556
00557 _dbus_assert (dbus_type_is_basic (type));
00558
00559 str_data = _dbus_string_get_const_data (str);
00560
00561
00562
00563
00564
00565 switch (type)
00566 {
00567 case DBUS_TYPE_BYTE:
00568 {
00569 volatile unsigned char *vp = value;
00570 *vp = (unsigned char) _dbus_string_get_byte (str, pos);
00571 (pos)++;
00572 }
00573 break;
00574 case DBUS_TYPE_INT16:
00575 case DBUS_TYPE_UINT16:
00576 {
00577 volatile dbus_uint16_t *vp = value;
00578 pos = _DBUS_ALIGN_VALUE (pos, 2);
00579 *vp = *(dbus_uint16_t *)(str_data + pos);
00580 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00581 *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
00582 pos += 2;
00583 }
00584 break;
00585 case DBUS_TYPE_INT32:
00586 case DBUS_TYPE_UINT32:
00587 case DBUS_TYPE_BOOLEAN:
00588 case DBUS_TYPE_UNIX_FD:
00589 {
00590 volatile dbus_uint32_t *vp = value;
00591 pos = _DBUS_ALIGN_VALUE (pos, 4);
00592 *vp = *(dbus_uint32_t *)(str_data + pos);
00593 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00594 *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
00595 pos += 4;
00596 }
00597 break;
00598 case DBUS_TYPE_INT64:
00599 case DBUS_TYPE_UINT64:
00600 case DBUS_TYPE_DOUBLE:
00601 {
00602 volatile dbus_uint64_t *vp = value;
00603 pos = _DBUS_ALIGN_VALUE (pos, 8);
00604 #ifdef DBUS_HAVE_INT64
00605 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00606 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
00607 else
00608 *vp = *(dbus_uint64_t*)(str_data + pos);
00609 #else
00610 *vp = *(DBus8ByteStruct*) (str_data + pos);
00611 swap_8_octets (vp, byte_order);
00612 #endif
00613 pos += 8;
00614 }
00615 break;
00616 case DBUS_TYPE_STRING:
00617 case DBUS_TYPE_OBJECT_PATH:
00618 {
00619 int len;
00620 volatile char **vp = value;
00621
00622 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
00623
00624 *vp = (char*) str_data + pos;
00625
00626 pos += len + 1;
00627 }
00628 break;
00629 case DBUS_TYPE_SIGNATURE:
00630 {
00631 int len;
00632 volatile char **vp = value;
00633
00634 len = _dbus_string_get_byte (str, pos);
00635 pos += 1;
00636
00637 *vp = (char*) str_data + pos;
00638
00639 pos += len + 1;
00640 }
00641 break;
00642 default:
00643 _dbus_warn_check_failed ("type %s %d not a basic type\n",
00644 _dbus_type_to_string (type), type);
00645 _dbus_assert_not_reached ("not a basic type");
00646 break;
00647 }
00648
00649 if (new_pos)
00650 *new_pos = pos;
00651 }
00652
00653 static dbus_bool_t
00654 marshal_2_octets (DBusString *str,
00655 int insert_at,
00656 dbus_uint16_t value,
00657 int byte_order,
00658 int *pos_after)
00659 {
00660 dbus_bool_t retval;
00661 int orig_len;
00662
00663 _dbus_assert (sizeof (value) == 2);
00664
00665 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00666 value = DBUS_UINT16_SWAP_LE_BE (value);
00667
00668 orig_len = _dbus_string_get_length (str);
00669
00670 retval = _dbus_string_insert_2_aligned (str, insert_at,
00671 (const unsigned char *)&value);
00672
00673 if (pos_after)
00674 {
00675 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
00676 _dbus_assert (*pos_after <= _dbus_string_get_length (str));
00677 }
00678
00679 return retval;
00680 }
00681
00682 static dbus_bool_t
00683 marshal_4_octets (DBusString *str,
00684 int insert_at,
00685 dbus_uint32_t value,
00686 int byte_order,
00687 int *pos_after)
00688 {
00689 dbus_bool_t retval;
00690 int orig_len;
00691
00692 _dbus_assert (sizeof (value) == 4);
00693
00694 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00695 value = DBUS_UINT32_SWAP_LE_BE (value);
00696
00697 orig_len = _dbus_string_get_length (str);
00698
00699 retval = _dbus_string_insert_4_aligned (str, insert_at,
00700 (const unsigned char *)&value);
00701
00702 if (pos_after)
00703 {
00704 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
00705 _dbus_assert (*pos_after <= _dbus_string_get_length (str));
00706 }
00707
00708 return retval;
00709 }
00710
00711 static dbus_bool_t
00712 marshal_8_octets (DBusString *str,
00713 int insert_at,
00714 DBusBasicValue value,
00715 int byte_order,
00716 int *pos_after)
00717 {
00718 dbus_bool_t retval;
00719 int orig_len;
00720
00721 _dbus_assert (sizeof (value) == 8);
00722
00723 swap_8_octets (&value, byte_order);
00724
00725 orig_len = _dbus_string_get_length (str);
00726
00727 retval = _dbus_string_insert_8_aligned (str, insert_at,
00728 (const unsigned char *)&value);
00729
00730 if (pos_after)
00731 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
00732
00733 return retval;
00734 }
00735
00736 enum
00737 {
00738 MARSHAL_AS_STRING,
00739 MARSHAL_AS_SIGNATURE,
00740 MARSHAL_AS_BYTE_ARRAY
00741 };
00742
00743 static dbus_bool_t
00744 marshal_len_followed_by_bytes (int marshal_as,
00745 DBusString *str,
00746 int insert_at,
00747 const unsigned char *value,
00748 int data_len,
00749 int byte_order,
00750 int *pos_after)
00751 {
00752 int pos;
00753 DBusString value_str;
00754 int value_len;
00755
00756 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
00757 if (insert_at > _dbus_string_get_length (str))
00758 _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
00759 insert_at, _dbus_string_get_length (str), data_len);
00760
00761 if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
00762 value_len = data_len;
00763 else
00764 value_len = data_len + 1;
00765
00766 _dbus_string_init_const_len (&value_str, value, value_len);
00767
00768 pos = insert_at;
00769
00770 if (marshal_as == MARSHAL_AS_SIGNATURE)
00771 {
00772 _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
00773 _dbus_assert (data_len <= 255);
00774
00775 if (!_dbus_string_insert_byte (str, pos, data_len))
00776 goto oom;
00777
00778 pos += 1;
00779 }
00780 else
00781 {
00782 if (!marshal_4_octets (str, pos, data_len,
00783 byte_order, &pos))
00784 goto oom;
00785 }
00786
00787 if (!_dbus_string_copy_len (&value_str, 0, value_len,
00788 str, pos))
00789 goto oom;
00790
00791 #if 0
00792
00793 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
00794 str, pos));
00795 _dbus_verbose_bytes_of_string (str, pos, value_len);
00796 #endif
00797
00798 pos += value_len;
00799
00800 if (pos_after)
00801 *pos_after = pos;
00802
00803 return TRUE;
00804
00805 oom:
00806
00807 _dbus_string_delete (str, insert_at, pos - insert_at);
00808
00809 return FALSE;
00810 }
00811
00812 static dbus_bool_t
00813 marshal_string (DBusString *str,
00814 int insert_at,
00815 const char *value,
00816 int byte_order,
00817 int *pos_after)
00818 {
00819 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
00820 str, insert_at, value,
00821 strlen (value),
00822 byte_order, pos_after);
00823 }
00824
00825 static dbus_bool_t
00826 marshal_signature (DBusString *str,
00827 int insert_at,
00828 const char *value,
00829 int *pos_after)
00830 {
00831 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
00832 str, insert_at, value,
00833 strlen (value),
00834 DBUS_COMPILER_BYTE_ORDER,
00835 pos_after);
00836 }
00837
00854 dbus_bool_t
00855 _dbus_marshal_write_basic (DBusString *str,
00856 int insert_at,
00857 int type,
00858 const void *value,
00859 int byte_order,
00860 int *pos_after)
00861 {
00862 const DBusBasicValue *vp;
00863
00864 _dbus_assert (dbus_type_is_basic (type));
00865
00866 vp = value;
00867
00868 switch (type)
00869 {
00870 case DBUS_TYPE_BYTE:
00871 if (!_dbus_string_insert_byte (str, insert_at, vp->byt))
00872 return FALSE;
00873 if (pos_after)
00874 *pos_after = insert_at + 1;
00875 return TRUE;
00876 break;
00877 case DBUS_TYPE_INT16:
00878 case DBUS_TYPE_UINT16:
00879 return marshal_2_octets (str, insert_at, vp->u16,
00880 byte_order, pos_after);
00881 break;
00882 case DBUS_TYPE_BOOLEAN:
00883 return marshal_4_octets (str, insert_at, vp->u32 != FALSE,
00884 byte_order, pos_after);
00885 break;
00886 case DBUS_TYPE_INT32:
00887 case DBUS_TYPE_UINT32:
00888 case DBUS_TYPE_UNIX_FD:
00889 return marshal_4_octets (str, insert_at, vp->u32,
00890 byte_order, pos_after);
00891 break;
00892 case DBUS_TYPE_INT64:
00893 case DBUS_TYPE_UINT64:
00894 case DBUS_TYPE_DOUBLE:
00895 return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after);
00896 break;
00897
00898 case DBUS_TYPE_STRING:
00899 case DBUS_TYPE_OBJECT_PATH:
00900 _dbus_assert (vp->str != NULL);
00901 return marshal_string (str, insert_at, vp->str, byte_order, pos_after);
00902 break;
00903 case DBUS_TYPE_SIGNATURE:
00904 _dbus_assert (vp->str != NULL);
00905 return marshal_signature (str, insert_at, vp->str, pos_after);
00906 break;
00907 default:
00908 _dbus_assert_not_reached ("not a basic type");
00909 return FALSE;
00910 break;
00911 }
00912 }
00913
00914 static dbus_bool_t
00915 marshal_1_octets_array (DBusString *str,
00916 int insert_at,
00917 const unsigned char *value,
00918 int n_elements,
00919 int byte_order,
00920 int *pos_after)
00921 {
00922 int pos;
00923 DBusString value_str;
00924
00925 _dbus_string_init_const_len (&value_str, value, n_elements);
00926
00927 pos = insert_at;
00928
00929 if (!_dbus_string_copy_len (&value_str, 0, n_elements,
00930 str, pos))
00931 return FALSE;
00932
00933 pos += n_elements;
00934
00935 if (pos_after)
00936 *pos_after = pos;
00937
00938 return TRUE;
00939 }
00940
00948 void
00949 _dbus_swap_array (unsigned char *data,
00950 int n_elements,
00951 int alignment)
00952 {
00953 unsigned char *d;
00954 unsigned char *end;
00955
00956 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
00957
00958
00959
00960
00961 d = data;
00962 end = d + (n_elements * alignment);
00963
00964 if (alignment == 8)
00965 {
00966 while (d != end)
00967 {
00968 #ifdef DBUS_HAVE_INT64
00969 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
00970 #else
00971 swap_8_bytes ((DBusBasicValue*) d);
00972 #endif
00973 d += 8;
00974 }
00975 }
00976 else if (alignment == 4)
00977 {
00978 while (d != end)
00979 {
00980 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
00981 d += 4;
00982 }
00983 }
00984 else
00985 {
00986 _dbus_assert (alignment == 2);
00987
00988 while (d != end)
00989 {
00990 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d));
00991 d += 2;
00992 }
00993 }
00994 }
00995
00996 static void
00997 swap_array (DBusString *str,
00998 int array_start,
00999 int n_elements,
01000 int byte_order,
01001 int alignment)
01002 {
01003 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start);
01004
01005 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01006 {
01007
01008
01009
01010 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
01011 n_elements, alignment);
01012 }
01013 }
01014
01015 static dbus_bool_t
01016 marshal_fixed_multi (DBusString *str,
01017 int insert_at,
01018 const DBusBasicValue *value,
01019 int n_elements,
01020 int byte_order,
01021 int alignment,
01022 int *pos_after)
01023 {
01024 int old_string_len;
01025 int array_start;
01026 DBusString t;
01027 int len_in_bytes;
01028
01029 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment);
01030
01031 old_string_len = _dbus_string_get_length (str);
01032
01033 len_in_bytes = n_elements * alignment;
01034 array_start = insert_at;
01035
01036
01037
01038
01039
01040
01041
01042 if (!_dbus_string_insert_alignment (str, &array_start, alignment))
01043 goto error;
01044
01045 _dbus_string_init_const_len (&t,
01046 (const unsigned char*) value,
01047 len_in_bytes);
01048
01049 if (!_dbus_string_copy (&t, 0,
01050 str, array_start))
01051 goto error;
01052
01053 swap_array (str, array_start, n_elements, byte_order, alignment);
01054
01055 if (pos_after)
01056 *pos_after = array_start + len_in_bytes;
01057
01058 return TRUE;
01059
01060 error:
01061 _dbus_string_delete (str, insert_at,
01062 _dbus_string_get_length (str) - old_string_len);
01063
01064 return FALSE;
01065 }
01066
01084 dbus_bool_t
01085 _dbus_marshal_write_fixed_multi (DBusString *str,
01086 int insert_at,
01087 int element_type,
01088 const void *value,
01089 int n_elements,
01090 int byte_order,
01091 int *pos_after)
01092 {
01093 const void* vp = *(const DBusBasicValue**)value;
01094
01095 _dbus_assert (dbus_type_is_fixed (element_type));
01096 _dbus_assert (n_elements >= 0);
01097
01098 #if 0
01099 _dbus_verbose ("writing %d elements of %s\n",
01100 n_elements, _dbus_type_to_string (element_type));
01101 #endif
01102
01103 switch (element_type)
01104 {
01105 case DBUS_TYPE_BYTE:
01106 return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after);
01107 break;
01108 case DBUS_TYPE_INT16:
01109 case DBUS_TYPE_UINT16:
01110 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
01111 case DBUS_TYPE_BOOLEAN:
01112 case DBUS_TYPE_INT32:
01113 case DBUS_TYPE_UINT32:
01114 case DBUS_TYPE_UNIX_FD:
01115 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
01116 break;
01117 case DBUS_TYPE_INT64:
01118 case DBUS_TYPE_UINT64:
01119 case DBUS_TYPE_DOUBLE:
01120 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after);
01121 break;
01122
01123 default:
01124 _dbus_assert_not_reached ("non fixed type in array write");
01125 break;
01126 }
01127
01128 return FALSE;
01129 }
01130
01131
01141 void
01142 _dbus_marshal_skip_basic (const DBusString *str,
01143 int type,
01144 int byte_order,
01145 int *pos)
01146 {
01147 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
01148 byte_order == DBUS_BIG_ENDIAN);
01149
01150 switch (type)
01151 {
01152 case DBUS_TYPE_BYTE:
01153 (*pos)++;
01154 break;
01155 case DBUS_TYPE_INT16:
01156 case DBUS_TYPE_UINT16:
01157 *pos = _DBUS_ALIGN_VALUE (*pos, 2);
01158 *pos += 2;
01159 break;
01160 case DBUS_TYPE_BOOLEAN:
01161 case DBUS_TYPE_INT32:
01162 case DBUS_TYPE_UINT32:
01163 case DBUS_TYPE_UNIX_FD:
01164 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
01165 *pos += 4;
01166 break;
01167 case DBUS_TYPE_INT64:
01168 case DBUS_TYPE_UINT64:
01169 case DBUS_TYPE_DOUBLE:
01170 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
01171 *pos += 8;
01172 break;
01173 case DBUS_TYPE_STRING:
01174 case DBUS_TYPE_OBJECT_PATH:
01175 {
01176 int len;
01177
01178 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos);
01179
01180 *pos += len + 1;
01181 }
01182 break;
01183 case DBUS_TYPE_SIGNATURE:
01184 {
01185 int len;
01186
01187 len = _dbus_string_get_byte (str, *pos);
01188
01189 *pos += len + 2;
01190 }
01191 break;
01192 default:
01193 _dbus_warn ("type %s not a basic type\n",
01194 _dbus_type_to_string (type));
01195 _dbus_assert_not_reached ("not a basic type");
01196 break;
01197 }
01198 }
01199
01209 void
01210 _dbus_marshal_skip_array (const DBusString *str,
01211 int element_type,
01212 int byte_order,
01213 int *pos)
01214 {
01215 dbus_uint32_t array_len;
01216 int i;
01217 int alignment;
01218
01219 i = _DBUS_ALIGN_VALUE (*pos, 4);
01220
01221 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i);
01222
01223 alignment = _dbus_type_get_alignment (element_type);
01224
01225 i = _DBUS_ALIGN_VALUE (i, alignment);
01226
01227 *pos = i + array_len;
01228 }
01229
01237 int
01238 _dbus_type_get_alignment (int typecode)
01239 {
01240 switch (typecode)
01241 {
01242 case DBUS_TYPE_BYTE:
01243 case DBUS_TYPE_VARIANT:
01244 case DBUS_TYPE_SIGNATURE:
01245 return 1;
01246 case DBUS_TYPE_INT16:
01247 case DBUS_TYPE_UINT16:
01248 return 2;
01249 case DBUS_TYPE_BOOLEAN:
01250 case DBUS_TYPE_INT32:
01251 case DBUS_TYPE_UINT32:
01252 case DBUS_TYPE_UNIX_FD:
01253
01254 case DBUS_TYPE_STRING:
01255 case DBUS_TYPE_OBJECT_PATH:
01256 case DBUS_TYPE_ARRAY:
01257 return 4;
01258 case DBUS_TYPE_INT64:
01259 case DBUS_TYPE_UINT64:
01260 case DBUS_TYPE_DOUBLE:
01261
01262
01263
01264
01265
01266
01267 case DBUS_TYPE_STRUCT:
01268 case DBUS_TYPE_DICT_ENTRY:
01269 return 8;
01270
01271 default:
01272 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
01273 return 0;
01274 }
01275 }
01276
01283 const char *
01284 _dbus_type_to_string (int typecode)
01285 {
01286 switch (typecode)
01287 {
01288 case DBUS_TYPE_INVALID:
01289 return "invalid";
01290 case DBUS_TYPE_BOOLEAN:
01291 return "boolean";
01292 case DBUS_TYPE_BYTE:
01293 return "byte";
01294 case DBUS_TYPE_INT16:
01295 return "int16";
01296 case DBUS_TYPE_UINT16:
01297 return "uint16";
01298 case DBUS_TYPE_INT32:
01299 return "int32";
01300 case DBUS_TYPE_UINT32:
01301 return "uint32";
01302 case DBUS_TYPE_INT64:
01303 return "int64";
01304 case DBUS_TYPE_UINT64:
01305 return "uint64";
01306 case DBUS_TYPE_DOUBLE:
01307 return "double";
01308 case DBUS_TYPE_STRING:
01309 return "string";
01310 case DBUS_TYPE_OBJECT_PATH:
01311 return "object_path";
01312 case DBUS_TYPE_SIGNATURE:
01313 return "signature";
01314 case DBUS_TYPE_STRUCT:
01315 return "struct";
01316 case DBUS_TYPE_DICT_ENTRY:
01317 return "dict_entry";
01318 case DBUS_TYPE_ARRAY:
01319 return "array";
01320 case DBUS_TYPE_VARIANT:
01321 return "variant";
01322 case DBUS_STRUCT_BEGIN_CHAR:
01323 return "begin_struct";
01324 case DBUS_STRUCT_END_CHAR:
01325 return "end_struct";
01326 case DBUS_DICT_ENTRY_BEGIN_CHAR:
01327 return "begin_dict_entry";
01328 case DBUS_DICT_ENTRY_END_CHAR:
01329 return "end_dict_entry";
01330 case DBUS_TYPE_UNIX_FD:
01331 return "unix_fd";
01332 default:
01333 return "unknown";
01334 }
01335 }
01336
01344 void
01345 _dbus_verbose_bytes (const unsigned char *data,
01346 int len,
01347 int offset)
01348 {
01349 int i;
01350 const unsigned char *aligned;
01351
01352 _dbus_assert (len >= 0);
01353
01354 if (!_dbus_is_verbose())
01355 return;
01356
01357
01358 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
01359 if (aligned > data)
01360 aligned -= 4;
01361 _dbus_assert (aligned <= data);
01362
01363 if (aligned != data)
01364 {
01365 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
01366 while (aligned != data)
01367 {
01368 _dbus_verbose (" ");
01369 ++aligned;
01370 }
01371 }
01372
01373
01374 i = 0;
01375 while (i < len)
01376 {
01377 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
01378 {
01379 _dbus_verbose ("%4d\t%p: ",
01380 offset + i, &data[i]);
01381 }
01382
01383 if (data[i] >= 32 &&
01384 data[i] <= 126)
01385 _dbus_verbose (" '%c' ", data[i]);
01386 else
01387 _dbus_verbose ("0x%s%x ",
01388 data[i] <= 0xf ? "0" : "", data[i]);
01389
01390 ++i;
01391
01392 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
01393 {
01394 if (i > 3)
01395 _dbus_verbose ("BE: %d LE: %d",
01396 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
01397 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
01398
01399 if (i > 7 &&
01400 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
01401 {
01402 #ifdef DBUS_INT64_PRINTF_MODIFIER
01403 _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x",
01404 *(dbus_uint64_t*)&data[i-8]);
01405 #endif
01406 _dbus_verbose (" dbl: %g",
01407 *(double*)&data[i-8]);
01408 }
01409
01410 _dbus_verbose ("\n");
01411 }
01412 }
01413
01414 _dbus_verbose ("\n");
01415 }
01416
01424 void
01425 _dbus_verbose_bytes_of_string (const DBusString *str,
01426 int start,
01427 int len)
01428 {
01429 const char *d;
01430 int real_len;
01431
01432 real_len = _dbus_string_get_length (str);
01433
01434 _dbus_assert (start >= 0);
01435
01436 if (start > real_len)
01437 {
01438 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
01439 start, len, real_len);
01440 return;
01441 }
01442
01443 if ((start + len) > real_len)
01444 {
01445 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
01446 start, len, real_len);
01447 len = real_len - start;
01448 }
01449
01450 d = _dbus_string_get_const_data_len (str, start, len);
01451
01452 _dbus_verbose_bytes (d, len, start);
01453 }
01454
01455 static int
01456 map_type_char_to_type (int t)
01457 {
01458 if (t == DBUS_STRUCT_BEGIN_CHAR)
01459 return DBUS_TYPE_STRUCT;
01460 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR)
01461 return DBUS_TYPE_DICT_ENTRY;
01462 else
01463 {
01464 _dbus_assert (t != DBUS_STRUCT_END_CHAR);
01465 _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR);
01466 return t;
01467 }
01468 }
01469
01480 int
01481 _dbus_first_type_in_signature (const DBusString *str,
01482 int pos)
01483 {
01484 return map_type_char_to_type (_dbus_string_get_byte (str, pos));
01485 }
01486
01495 int
01496 _dbus_first_type_in_signature_c_str (const char *str,
01497 int pos)
01498 {
01499 return map_type_char_to_type (str[pos]);
01500 }
01501
01504 #ifdef DBUS_BUILD_TESTS
01505 #include "dbus-test.h"
01506 #include <stdio.h>
01507
01526 void
01527 _dbus_marshal_read_fixed_multi (const DBusString *str,
01528 int pos,
01529 int element_type,
01530 void *value,
01531 int n_elements,
01532 int byte_order,
01533 int *new_pos)
01534 {
01535 int array_len;
01536 int alignment;
01537
01538 _dbus_assert (dbus_type_is_fixed (element_type));
01539 _dbus_assert (dbus_type_is_basic (element_type));
01540
01541 #if 0
01542 _dbus_verbose ("reading %d elements of %s\n",
01543 n_elements, _dbus_type_to_string (element_type));
01544 #endif
01545
01546 alignment = _dbus_type_get_alignment (element_type);
01547
01548 pos = _DBUS_ALIGN_VALUE (pos, alignment);
01549
01550 array_len = n_elements * alignment;
01551
01552 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
01553 if (new_pos)
01554 *new_pos = pos + array_len;
01555 }
01556
01557 static void
01558 swap_test_array (void *array,
01559 int len_bytes,
01560 int byte_order,
01561 int alignment)
01562 {
01563 DBusString t;
01564
01565 if (alignment == 1)
01566 return;
01567
01568 _dbus_string_init_const_len (&t, array, len_bytes);
01569 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment);
01570 }
01571
01572 #define MARSHAL_BASIC(typename, byte_order, literal) \
01573 do { \
01574 v_##typename = literal; \
01575 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \
01576 &v_##typename, \
01577 byte_order, NULL)) \
01578 _dbus_assert_not_reached ("no memory"); \
01579 } while (0)
01580
01581 #define DEMARSHAL_BASIC(typename, byte_order) \
01582 do { \
01583 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \
01584 byte_order, &pos); \
01585 } while (0)
01586
01587 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \
01588 do { \
01589 DEMARSHAL_BASIC (typename, byte_order); \
01590 if (literal != v_##typename) \
01591 { \
01592 _dbus_verbose_bytes_of_string (&str, dump_pos, \
01593 _dbus_string_get_length (&str) - dump_pos); \
01594 _dbus_assert_not_reached ("demarshaled wrong value"); \
01595 } \
01596 } while (0)
01597
01598 #define MARSHAL_TEST(typename, byte_order, literal) \
01599 do { \
01600 MARSHAL_BASIC (typename, byte_order, literal); \
01601 dump_pos = pos; \
01602 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \
01603 } while (0)
01604
01605 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \
01606 do { \
01607 MARSHAL_BASIC (typename, byte_order, literal); \
01608 dump_pos = pos; \
01609 DEMARSHAL_BASIC (typename, byte_order); \
01610 if (strcmp (literal, v_##typename) != 0) \
01611 { \
01612 _dbus_verbose_bytes_of_string (&str, dump_pos, \
01613 _dbus_string_get_length (&str) - dump_pos); \
01614 _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \
01615 _dbus_assert_not_reached ("demarshaled wrong value"); \
01616 } \
01617 } while (0)
01618
01619 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \
01620 do { \
01621 int next; \
01622 v_UINT32 = sizeof(literal); \
01623 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \
01624 byte_order, &next)) \
01625 _dbus_assert_not_reached ("no memory"); \
01626 v_ARRAY_##typename = literal; \
01627 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \
01628 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \
01629 byte_order, NULL)) \
01630 _dbus_assert_not_reached ("no memory"); \
01631 } while (0)
01632
01633 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \
01634 do { \
01635 int next; \
01636 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \
01637 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \
01638 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \
01639 v_UINT32/alignment, \
01640 byte_order, NULL); \
01641 swap_test_array (v_ARRAY_##typename, v_UINT32, \
01642 byte_order, alignment); \
01643 } while (0)
01644
01645 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \
01646 do { \
01647 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \
01648 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0)) \
01649 { \
01650 _dbus_verbose ("MARSHALED DATA\n"); \
01651 _dbus_verbose_bytes_of_string (&str, dump_pos, \
01652 _dbus_string_get_length (&str) - dump_pos); \
01653 _dbus_verbose ("LITERAL DATA\n"); \
01654 _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \
01655 _dbus_verbose ("READ DATA\n"); \
01656 _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \
01657 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \
01658 } \
01659 } while (0)
01660
01661 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \
01662 do { \
01663 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \
01664 dump_pos = pos; \
01665 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \
01666 } while (0)
01667
01668 dbus_bool_t
01669 _dbus_marshal_test (void)
01670 {
01671 int alignment;
01672 DBusString str;
01673 int pos, dump_pos;
01674 unsigned char array1[5] = { 3, 4, 0, 1, 9 };
01675 dbus_int16_t array2[3] = { 124, 457, 780 };
01676 dbus_int32_t array4[3] = { 123, 456, 789 };
01677 #ifdef DBUS_HAVE_INT64
01678 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
01679 DBUS_INT64_CONSTANT (0x456ffffffff),
01680 DBUS_INT64_CONSTANT (0x789ffffffff) };
01681 dbus_int64_t *v_ARRAY_INT64;
01682 #endif
01683 unsigned char *v_ARRAY_BYTE;
01684 dbus_int16_t *v_ARRAY_INT16;
01685 dbus_uint16_t *v_ARRAY_UINT16;
01686 dbus_int32_t *v_ARRAY_INT32;
01687 dbus_uint32_t *v_ARRAY_UINT32;
01688 DBusString t;
01689 double v_DOUBLE;
01690 double t_DOUBLE;
01691 dbus_int16_t v_INT16;
01692 dbus_uint16_t v_UINT16;
01693 dbus_int32_t v_INT32;
01694 dbus_uint32_t v_UINT32;
01695 dbus_int64_t v_INT64;
01696 dbus_uint64_t v_UINT64;
01697 unsigned char v_BYTE;
01698 dbus_bool_t v_BOOLEAN;
01699 const char *v_STRING;
01700 const char *v_SIGNATURE;
01701 const char *v_OBJECT_PATH;
01702 int byte_order;
01703
01704 if (!_dbus_string_init (&str))
01705 _dbus_assert_not_reached ("failed to init string");
01706
01707 pos = 0;
01708
01709
01710 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
01711 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
01712 t_DOUBLE = 3.14;
01713 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
01714 _dbus_assert_not_reached ("got wrong double value");
01715
01716 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
01717 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
01718 t_DOUBLE = 3.14;
01719 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
01720 _dbus_assert_not_reached ("got wrong double value");
01721
01722
01723 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345);
01724 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345);
01725
01726
01727 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234);
01728 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234);
01729
01730
01731 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
01732 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
01733
01734
01735 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
01736 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
01737
01738 #ifdef DBUS_HAVE_INT64
01739
01740 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
01741 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
01742
01743
01744 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
01745 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
01746 #endif
01747
01748
01749 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
01750 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
01751
01752
01753 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
01754 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
01755 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
01756 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
01757
01758
01759 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
01760 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
01761 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
01762 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
01763
01764
01765 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
01766 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
01767
01768
01769 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
01770 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
01771 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
01772 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
01773
01774
01775 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2);
01776 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2);
01777 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2);
01778 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2);
01779
01780 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4);
01781 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4);
01782 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4);
01783 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4);
01784
01785 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
01786 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
01787
01788 #ifdef DBUS_HAVE_INT64
01789 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
01790 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
01791 #endif
01792
01793 #if 0
01794
01795
01796
01797
01798
01799 #ifdef DBUS_HAVE_INT64
01800
01801 _dbus_string_set_length (&str, 8);
01802
01803
01804 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
01805 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
01806
01807 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
01808 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
01809 _dbus_string_get_const_data (&str)));
01810
01811
01812 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
01813 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
01814
01815 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
01816 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
01817 _dbus_string_get_const_data (&str)));
01818
01819
01820 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
01821 DBUS_LITTLE_ENDIAN,
01822 _dbus_string_get_data (&str));
01823
01824 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
01825 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
01826 _dbus_string_get_const_data (&str)));
01827
01828
01829 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
01830 DBUS_BIG_ENDIAN,
01831 _dbus_string_get_data (&str));
01832
01833 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
01834 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
01835 _dbus_string_get_const_data (&str)));
01836
01837
01838 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
01839 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
01840
01841 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
01842 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
01843 _dbus_string_get_const_data (&str)));
01844
01845
01846 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
01847 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
01848
01849 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
01850 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
01851 _dbus_string_get_const_data (&str)));
01852
01853
01854 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
01855 DBUS_LITTLE_ENDIAN,
01856 _dbus_string_get_data (&str));
01857
01858 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
01859 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
01860 _dbus_string_get_const_data (&str)));
01861
01862
01863 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
01864 DBUS_BIG_ENDIAN,
01865 _dbus_string_get_data (&str));
01866
01867 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
01868 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
01869 _dbus_string_get_const_data (&str)));
01870 #endif
01871
01872
01873 _dbus_string_set_length (&str, 4);
01874
01875
01876 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
01877 0, -0x123456);
01878
01879 _dbus_assert (-0x123456 ==
01880 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
01881 _dbus_string_get_const_data (&str)));
01882
01883
01884 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
01885 0, -0x123456);
01886
01887 _dbus_assert (-0x123456 ==
01888 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
01889 _dbus_string_get_const_data (&str)));
01890
01891
01892 _dbus_pack_int32 (-0x123456,
01893 DBUS_LITTLE_ENDIAN,
01894 _dbus_string_get_data (&str));
01895
01896 _dbus_assert (-0x123456 ==
01897 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
01898 _dbus_string_get_const_data (&str)));
01899
01900
01901 _dbus_pack_int32 (-0x123456,
01902 DBUS_BIG_ENDIAN,
01903 _dbus_string_get_data (&str));
01904
01905 _dbus_assert (-0x123456 ==
01906 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
01907 _dbus_string_get_const_data (&str)));
01908
01909
01910 _dbus_marshal_set_uint32 (&str,
01911 0, 0x123456,
01912 DBUS_LITTLE_ENDIAN);
01913
01914 _dbus_assert (0x123456 ==
01915 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
01916 _dbus_string_get_const_data (&str)));
01917
01918
01919 _dbus_marshal_set_uint32 (&str,
01920 0, 0x123456,
01921 DBUS_BIG_ENDIAN);
01922
01923 _dbus_assert (0x123456 ==
01924 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
01925 _dbus_string_get_const_data (&str)));
01926
01927
01928 _dbus_pack_uint32 (0x123456,
01929 DBUS_LITTLE_ENDIAN,
01930 _dbus_string_get_data (&str));
01931
01932 _dbus_assert (0x123456 ==
01933 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
01934 _dbus_string_get_const_data (&str)));
01935
01936
01937 _dbus_pack_uint32 (0x123456,
01938 DBUS_BIG_ENDIAN,
01939 _dbus_string_get_data (&str));
01940
01941 _dbus_assert (0x123456 ==
01942 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
01943 _dbus_string_get_const_data (&str)));
01944
01945 #endif
01946
01947
01948 byte_order = DBUS_LITTLE_ENDIAN;
01949 while (TRUE)
01950 {
01951
01952 _dbus_string_set_length (&str, 0);
01953
01954
01955 pos = 0;
01956
01957 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
01958
01959
01960 _dbus_string_init_const (&t, "Hello world foo");
01961
01962 v_STRING = _dbus_string_get_const_data (&t);
01963 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
01964 &v_STRING, byte_order, NULL, NULL);
01965
01966 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
01967 &v_STRING, byte_order,
01968 NULL);
01969 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
01970
01971
01972 _dbus_string_init_const (&t, "Hello");
01973
01974 v_STRING = _dbus_string_get_const_data (&t);
01975 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING,
01976 &v_STRING, byte_order, NULL, NULL);
01977 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING,
01978 &v_STRING, byte_order,
01979 NULL);
01980 _dbus_assert (strcmp (v_STRING, "Hello") == 0);
01981
01982
01983 if (byte_order == DBUS_LITTLE_ENDIAN)
01984 byte_order = DBUS_BIG_ENDIAN;
01985 else
01986 break;
01987 }
01988
01989
01990 _dbus_string_free (&str);
01991
01992 return TRUE;
01993 }
01994
01995 #endif