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