D-Bus
1.10.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-marshal-basic.c Marshalling routines for basic (primitive) types 00003 * 00004 * Copyright (C) 2002 CodeFactory AB 00005 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* not gcc, so probably no alignof operator: just use a no-op statement 00037 * that's valid in the same contexts */ 00038 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \ 00039 _DBUS_STATIC_ASSERT (TRUE) 00040 #endif 00041 00042 /* True by definition, but just for completeness... */ 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 _DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8); 00062 _DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8); 00063 _DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8); 00064 _DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8); 00065 00066 _DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8); 00067 /* The alignment of a DBusBasicValue might conceivably be > 8 because of the 00068 * pointer, so we don't assert about it */ 00069 00070 _DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8); 00071 _DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8); 00072 00088 static void 00089 pack_2_octets (dbus_uint16_t value, 00090 int byte_order, 00091 unsigned char *data) 00092 { 00093 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 00094 00095 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00096 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value); 00097 else 00098 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value); 00099 } 00100 00101 static void 00102 pack_4_octets (dbus_uint32_t value, 00103 int byte_order, 00104 unsigned char *data) 00105 { 00106 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 00107 00108 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00109 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value); 00110 else 00111 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value); 00112 } 00113 00114 static void 00115 pack_8_octets (DBusBasicValue value, 00116 int byte_order, 00117 unsigned char *data) 00118 { 00119 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data); 00120 00121 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00122 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64); 00123 else 00124 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64); 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 static void 00143 swap_8_octets (DBusBasicValue *value, 00144 int byte_order) 00145 { 00146 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00147 { 00148 value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64); 00149 } 00150 } 00151 00152 #ifndef _dbus_unpack_uint16 00153 00160 dbus_uint16_t 00161 _dbus_unpack_uint16 (int byte_order, 00162 const unsigned char *data) 00163 { 00164 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 00165 00166 if (byte_order == DBUS_LITTLE_ENDIAN) 00167 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data); 00168 else 00169 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data); 00170 } 00171 #endif /* _dbus_unpack_uint16 */ 00172 00173 #ifndef _dbus_unpack_uint32 00174 00181 dbus_uint32_t 00182 _dbus_unpack_uint32 (int byte_order, 00183 const unsigned char *data) 00184 { 00185 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 00186 00187 if (byte_order == DBUS_LITTLE_ENDIAN) 00188 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data); 00189 else 00190 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data); 00191 } 00192 #endif /* _dbus_unpack_uint32 */ 00193 00194 static void 00195 set_2_octets (DBusString *str, 00196 int offset, 00197 dbus_uint16_t value, 00198 int byte_order) 00199 { 00200 char *data; 00201 00202 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00203 byte_order == DBUS_BIG_ENDIAN); 00204 00205 data = _dbus_string_get_data_len (str, offset, 2); 00206 00207 pack_2_octets (value, byte_order, data); 00208 } 00209 00210 static void 00211 set_4_octets (DBusString *str, 00212 int offset, 00213 dbus_uint32_t value, 00214 int byte_order) 00215 { 00216 char *data; 00217 00218 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00219 byte_order == DBUS_BIG_ENDIAN); 00220 00221 data = _dbus_string_get_data_len (str, offset, 4); 00222 00223 pack_4_octets (value, byte_order, data); 00224 } 00225 00226 static void 00227 set_8_octets (DBusString *str, 00228 int offset, 00229 DBusBasicValue value, 00230 int byte_order) 00231 { 00232 char *data; 00233 00234 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00235 byte_order == DBUS_BIG_ENDIAN); 00236 00237 data = _dbus_string_get_data_len (str, offset, 8); 00238 00239 pack_8_octets (value, byte_order, data); 00240 } 00241 00252 void 00253 _dbus_marshal_set_uint32 (DBusString *str, 00254 int pos, 00255 dbus_uint32_t value, 00256 int byte_order) 00257 { 00258 set_4_octets (str, pos, value, byte_order); 00259 } 00260 00280 static dbus_bool_t 00281 set_string (DBusString *str, 00282 int pos, 00283 const char *value, 00284 int byte_order, 00285 int *old_end_pos, 00286 int *new_end_pos) 00287 { 00288 int old_len, new_len; 00289 DBusString dstr; 00290 00291 _dbus_string_init_const (&dstr, value); 00292 00293 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos); 00294 old_len = _dbus_unpack_uint32 (byte_order, 00295 _dbus_string_get_const_data_len (str, pos, 4)); 00296 00297 new_len = _dbus_string_get_length (&dstr); 00298 00299 if (!_dbus_string_replace_len (&dstr, 0, new_len, 00300 str, pos + 4, old_len)) 00301 return FALSE; 00302 00303 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order); 00304 00305 if (old_end_pos) 00306 *old_end_pos = pos + 4 + old_len + 1; 00307 if (new_end_pos) 00308 *new_end_pos = pos + 4 + new_len + 1; 00309 00310 return TRUE; 00311 } 00312 00326 static dbus_bool_t 00327 set_signature (DBusString *str, 00328 int pos, 00329 const char *value, 00330 int byte_order, 00331 int *old_end_pos, 00332 int *new_end_pos) 00333 { 00334 int old_len, new_len; 00335 DBusString dstr; 00336 00337 _dbus_string_init_const (&dstr, value); 00338 00339 old_len = _dbus_string_get_byte (str, pos); 00340 new_len = _dbus_string_get_length (&dstr); 00341 00342 if (!_dbus_string_replace_len (&dstr, 0, new_len, 00343 str, pos + 1, old_len)) 00344 return FALSE; 00345 00346 _dbus_string_set_byte (str, pos, new_len); 00347 00348 if (old_end_pos) 00349 *old_end_pos = pos + 1 + old_len + 1; 00350 if (new_end_pos) 00351 *new_end_pos = pos + 1 + new_len + 1; 00352 00353 return TRUE; 00354 } 00355 00369 dbus_bool_t 00370 _dbus_marshal_set_basic (DBusString *str, 00371 int pos, 00372 int type, 00373 const void *value, 00374 int byte_order, 00375 int *old_end_pos, 00376 int *new_end_pos) 00377 { 00378 const DBusBasicValue *vp; 00379 00380 vp = value; 00381 00382 switch (type) 00383 { 00384 case DBUS_TYPE_BYTE: 00385 _dbus_string_set_byte (str, pos, vp->byt); 00386 if (old_end_pos) 00387 *old_end_pos = pos + 1; 00388 if (new_end_pos) 00389 *new_end_pos = pos + 1; 00390 return TRUE; 00391 break; 00392 case DBUS_TYPE_INT16: 00393 case DBUS_TYPE_UINT16: 00394 pos = _DBUS_ALIGN_VALUE (pos, 2); 00395 set_2_octets (str, pos, vp->u16, byte_order); 00396 if (old_end_pos) 00397 *old_end_pos = pos + 2; 00398 if (new_end_pos) 00399 *new_end_pos = pos + 2; 00400 return TRUE; 00401 break; 00402 case DBUS_TYPE_BOOLEAN: 00403 case DBUS_TYPE_INT32: 00404 case DBUS_TYPE_UINT32: 00405 case DBUS_TYPE_UNIX_FD: 00406 pos = _DBUS_ALIGN_VALUE (pos, 4); 00407 set_4_octets (str, pos, vp->u32, byte_order); 00408 if (old_end_pos) 00409 *old_end_pos = pos + 4; 00410 if (new_end_pos) 00411 *new_end_pos = pos + 4; 00412 return TRUE; 00413 break; 00414 case DBUS_TYPE_INT64: 00415 case DBUS_TYPE_UINT64: 00416 case DBUS_TYPE_DOUBLE: 00417 pos = _DBUS_ALIGN_VALUE (pos, 8); 00418 set_8_octets (str, pos, *vp, byte_order); 00419 if (old_end_pos) 00420 *old_end_pos = pos + 8; 00421 if (new_end_pos) 00422 *new_end_pos = pos + 8; 00423 return TRUE; 00424 break; 00425 case DBUS_TYPE_STRING: 00426 case DBUS_TYPE_OBJECT_PATH: 00427 pos = _DBUS_ALIGN_VALUE (pos, 4); 00428 _dbus_assert (vp->str != NULL); 00429 return set_string (str, pos, vp->str, byte_order, 00430 old_end_pos, new_end_pos); 00431 break; 00432 case DBUS_TYPE_SIGNATURE: 00433 _dbus_assert (vp->str != NULL); 00434 return set_signature (str, pos, vp->str, byte_order, 00435 old_end_pos, new_end_pos); 00436 break; 00437 default: 00438 _dbus_assert_not_reached ("not a basic type"); 00439 return FALSE; 00440 break; 00441 } 00442 } 00443 00453 dbus_uint32_t 00454 _dbus_marshal_read_uint32 (const DBusString *str, 00455 int pos, 00456 int byte_order, 00457 int *new_pos) 00458 { 00459 pos = _DBUS_ALIGN_VALUE (pos, 4); 00460 00461 if (new_pos) 00462 *new_pos = pos + 4; 00463 00464 _dbus_assert (pos + 4 <= _dbus_string_get_length (str)); 00465 00466 return _dbus_unpack_uint32 (byte_order, 00467 _dbus_string_get_const_data (str) + pos); 00468 } 00469 00491 void 00492 _dbus_marshal_read_basic (const DBusString *str, 00493 int pos, 00494 int type, 00495 void *value, 00496 int byte_order, 00497 int *new_pos) 00498 { 00499 const char *str_data; 00500 00501 _dbus_assert (dbus_type_is_basic (type)); 00502 00503 str_data = _dbus_string_get_const_data (str); 00504 00505 /* Below we volatile types to avoid aliasing issues; 00506 * see http://bugs.freedesktop.org/show_bug.cgi?id=20137 00507 */ 00508 00509 switch (type) 00510 { 00511 case DBUS_TYPE_BYTE: 00512 { 00513 volatile unsigned char *vp = value; 00514 *vp = (unsigned char) _dbus_string_get_byte (str, pos); 00515 (pos)++; 00516 } 00517 break; 00518 case DBUS_TYPE_INT16: 00519 case DBUS_TYPE_UINT16: 00520 { 00521 volatile dbus_uint16_t *vp = value; 00522 pos = _DBUS_ALIGN_VALUE (pos, 2); 00523 *vp = *(dbus_uint16_t *)(str_data + pos); 00524 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00525 *vp = DBUS_UINT16_SWAP_LE_BE (*vp); 00526 pos += 2; 00527 } 00528 break; 00529 case DBUS_TYPE_INT32: 00530 case DBUS_TYPE_UINT32: 00531 case DBUS_TYPE_BOOLEAN: 00532 case DBUS_TYPE_UNIX_FD: 00533 { 00534 volatile dbus_uint32_t *vp = value; 00535 pos = _DBUS_ALIGN_VALUE (pos, 4); 00536 *vp = *(dbus_uint32_t *)(str_data + pos); 00537 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00538 *vp = DBUS_UINT32_SWAP_LE_BE (*vp); 00539 pos += 4; 00540 } 00541 break; 00542 case DBUS_TYPE_INT64: 00543 case DBUS_TYPE_UINT64: 00544 case DBUS_TYPE_DOUBLE: 00545 { 00546 volatile dbus_uint64_t *vp = value; 00547 pos = _DBUS_ALIGN_VALUE (pos, 8); 00548 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00549 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); 00550 else 00551 *vp = *(dbus_uint64_t*)(str_data + pos); 00552 pos += 8; 00553 } 00554 break; 00555 case DBUS_TYPE_STRING: 00556 case DBUS_TYPE_OBJECT_PATH: 00557 { 00558 int len; 00559 volatile char **vp = value; 00560 00561 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); 00562 00563 *vp = (char*) str_data + pos; 00564 00565 pos += len + 1; /* length plus nul */ 00566 } 00567 break; 00568 case DBUS_TYPE_SIGNATURE: 00569 { 00570 int len; 00571 volatile char **vp = value; 00572 00573 len = _dbus_string_get_byte (str, pos); 00574 pos += 1; 00575 00576 *vp = (char*) str_data + pos; 00577 00578 pos += len + 1; /* length plus nul */ 00579 } 00580 break; 00581 default: 00582 _dbus_warn_check_failed ("type %s %d not a basic type\n", 00583 _dbus_type_to_string (type), type); 00584 _dbus_assert_not_reached ("not a basic type"); 00585 break; 00586 } 00587 00588 if (new_pos) 00589 *new_pos = pos; 00590 } 00591 00592 static dbus_bool_t 00593 marshal_2_octets (DBusString *str, 00594 int insert_at, 00595 dbus_uint16_t value, 00596 int byte_order, 00597 int *pos_after) 00598 { 00599 dbus_bool_t retval; 00600 int orig_len; 00601 00602 _DBUS_STATIC_ASSERT (sizeof (value) == 2); 00603 00604 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00605 value = DBUS_UINT16_SWAP_LE_BE (value); 00606 00607 orig_len = _dbus_string_get_length (str); 00608 00609 retval = _dbus_string_insert_2_aligned (str, insert_at, 00610 (const unsigned char *)&value); 00611 00612 if (pos_after) 00613 { 00614 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 00615 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 00616 } 00617 00618 return retval; 00619 } 00620 00621 static dbus_bool_t 00622 marshal_4_octets (DBusString *str, 00623 int insert_at, 00624 dbus_uint32_t value, 00625 int byte_order, 00626 int *pos_after) 00627 { 00628 dbus_bool_t retval; 00629 int orig_len; 00630 00631 _DBUS_STATIC_ASSERT (sizeof (value) == 4); 00632 00633 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00634 value = DBUS_UINT32_SWAP_LE_BE (value); 00635 00636 orig_len = _dbus_string_get_length (str); 00637 00638 retval = _dbus_string_insert_4_aligned (str, insert_at, 00639 (const unsigned char *)&value); 00640 00641 if (pos_after) 00642 { 00643 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 00644 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 00645 } 00646 00647 return retval; 00648 } 00649 00650 static dbus_bool_t 00651 marshal_8_octets (DBusString *str, 00652 int insert_at, 00653 DBusBasicValue value, 00654 int byte_order, 00655 int *pos_after) 00656 { 00657 dbus_bool_t retval; 00658 int orig_len; 00659 00660 _DBUS_STATIC_ASSERT (sizeof (value) == 8); 00661 00662 swap_8_octets (&value, byte_order); 00663 00664 orig_len = _dbus_string_get_length (str); 00665 00666 retval = _dbus_string_insert_8_aligned (str, insert_at, 00667 (const unsigned char *)&value); 00668 00669 if (pos_after) 00670 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len; 00671 00672 return retval; 00673 } 00674 00675 enum 00676 { 00677 MARSHAL_AS_STRING, 00678 MARSHAL_AS_SIGNATURE, 00679 MARSHAL_AS_BYTE_ARRAY 00680 }; 00681 00682 static dbus_bool_t 00683 marshal_len_followed_by_bytes (int marshal_as, 00684 DBusString *str, 00685 int insert_at, 00686 const unsigned char *value, 00687 int data_len, /* doesn't include nul if any */ 00688 int byte_order, 00689 int *pos_after) 00690 { 00691 int pos; 00692 DBusString value_str; 00693 int value_len; 00694 00695 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN); 00696 if (insert_at > _dbus_string_get_length (str)) 00697 _dbus_warn ("insert_at = %d string len = %d data_len = %d\n", 00698 insert_at, _dbus_string_get_length (str), data_len); 00699 00700 if (marshal_as == MARSHAL_AS_BYTE_ARRAY) 00701 value_len = data_len; 00702 else 00703 value_len = data_len + 1; /* value has a nul */ 00704 00705 _dbus_string_init_const_len (&value_str, value, value_len); 00706 00707 pos = insert_at; 00708 00709 if (marshal_as == MARSHAL_AS_SIGNATURE) 00710 { 00711 _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH); 00712 _dbus_assert (data_len <= 255); /* same as max sig len right now */ 00713 00714 if (!_dbus_string_insert_byte (str, pos, data_len)) 00715 goto oom; 00716 00717 pos += 1; 00718 } 00719 else 00720 { 00721 if (!marshal_4_octets (str, pos, data_len, 00722 byte_order, &pos)) 00723 goto oom; 00724 } 00725 00726 if (!_dbus_string_copy_len (&value_str, 0, value_len, 00727 str, pos)) 00728 goto oom; 00729 00730 #if 0 00731 /* too expensive */ 00732 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len, 00733 str, pos)); 00734 _dbus_verbose_bytes_of_string (str, pos, value_len); 00735 #endif 00736 00737 pos += value_len; 00738 00739 if (pos_after) 00740 *pos_after = pos; 00741 00742 return TRUE; 00743 00744 oom: 00745 /* Delete what we've inserted */ 00746 _dbus_string_delete (str, insert_at, pos - insert_at); 00747 00748 return FALSE; 00749 } 00750 00751 static dbus_bool_t 00752 marshal_string (DBusString *str, 00753 int insert_at, 00754 const char *value, 00755 int byte_order, 00756 int *pos_after) 00757 { 00758 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING, 00759 str, insert_at, value, 00760 strlen (value), 00761 byte_order, pos_after); 00762 } 00763 00764 static dbus_bool_t 00765 marshal_signature (DBusString *str, 00766 int insert_at, 00767 const char *value, 00768 int *pos_after) 00769 { 00770 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE, 00771 str, insert_at, value, 00772 strlen (value), 00773 DBUS_COMPILER_BYTE_ORDER, /* irrelevant */ 00774 pos_after); 00775 } 00776 00793 dbus_bool_t 00794 _dbus_marshal_write_basic (DBusString *str, 00795 int insert_at, 00796 int type, 00797 const void *value, 00798 int byte_order, 00799 int *pos_after) 00800 { 00801 const DBusBasicValue *vp; 00802 00803 _dbus_assert (dbus_type_is_basic (type)); 00804 00805 vp = value; 00806 00807 switch (type) 00808 { 00809 case DBUS_TYPE_BYTE: 00810 if (!_dbus_string_insert_byte (str, insert_at, vp->byt)) 00811 return FALSE; 00812 if (pos_after) 00813 *pos_after = insert_at + 1; 00814 return TRUE; 00815 break; 00816 case DBUS_TYPE_INT16: 00817 case DBUS_TYPE_UINT16: 00818 return marshal_2_octets (str, insert_at, vp->u16, 00819 byte_order, pos_after); 00820 break; 00821 case DBUS_TYPE_BOOLEAN: 00822 return marshal_4_octets (str, insert_at, vp->u32 != FALSE, 00823 byte_order, pos_after); 00824 break; 00825 case DBUS_TYPE_INT32: 00826 case DBUS_TYPE_UINT32: 00827 case DBUS_TYPE_UNIX_FD: 00828 return marshal_4_octets (str, insert_at, vp->u32, 00829 byte_order, pos_after); 00830 break; 00831 case DBUS_TYPE_INT64: 00832 case DBUS_TYPE_UINT64: 00833 case DBUS_TYPE_DOUBLE: 00834 return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after); 00835 break; 00836 00837 case DBUS_TYPE_STRING: 00838 case DBUS_TYPE_OBJECT_PATH: 00839 _dbus_assert (vp->str != NULL); 00840 return marshal_string (str, insert_at, vp->str, byte_order, pos_after); 00841 break; 00842 case DBUS_TYPE_SIGNATURE: 00843 _dbus_assert (vp->str != NULL); 00844 return marshal_signature (str, insert_at, vp->str, pos_after); 00845 break; 00846 default: 00847 _dbus_assert_not_reached ("not a basic type"); 00848 return FALSE; 00849 break; 00850 } 00851 } 00852 00853 static dbus_bool_t 00854 marshal_1_octets_array (DBusString *str, 00855 int insert_at, 00856 const unsigned char *value, 00857 int n_elements, 00858 int byte_order, 00859 int *pos_after) 00860 { 00861 int pos; 00862 DBusString value_str; 00863 00864 _dbus_string_init_const_len (&value_str, value, n_elements); 00865 00866 pos = insert_at; 00867 00868 if (!_dbus_string_copy_len (&value_str, 0, n_elements, 00869 str, pos)) 00870 return FALSE; 00871 00872 pos += n_elements; 00873 00874 if (pos_after) 00875 *pos_after = pos; 00876 00877 return TRUE; 00878 } 00879 00887 void 00888 _dbus_swap_array (unsigned char *data, 00889 int n_elements, 00890 int alignment) 00891 { 00892 unsigned char *d; 00893 unsigned char *end; 00894 00895 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data); 00896 00897 /* we use const_data and cast it off so DBusString can be a const string 00898 * for the unit tests. don't ask. 00899 */ 00900 d = data; 00901 end = d + (n_elements * alignment); 00902 00903 if (alignment == 8) 00904 { 00905 while (d != end) 00906 { 00907 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d)); 00908 d += 8; 00909 } 00910 } 00911 else if (alignment == 4) 00912 { 00913 while (d != end) 00914 { 00915 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d)); 00916 d += 4; 00917 } 00918 } 00919 else 00920 { 00921 _dbus_assert (alignment == 2); 00922 00923 while (d != end) 00924 { 00925 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d)); 00926 d += 2; 00927 } 00928 } 00929 } 00930 00931 static void 00932 swap_array (DBusString *str, 00933 int array_start, 00934 int n_elements, 00935 int byte_order, 00936 int alignment) 00937 { 00938 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start); 00939 00940 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00941 { 00942 /* we use const_data and cast it off so DBusString can be a const string 00943 * for the unit tests. don't ask. 00944 */ 00945 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start), 00946 n_elements, alignment); 00947 } 00948 } 00949 00950 static dbus_bool_t 00951 marshal_fixed_multi (DBusString *str, 00952 int insert_at, 00953 const DBusBasicValue *value, 00954 int n_elements, 00955 int byte_order, 00956 int alignment, 00957 int *pos_after) 00958 { 00959 int old_string_len; 00960 int array_start; 00961 DBusString t; 00962 int len_in_bytes; 00963 00964 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment); 00965 00966 old_string_len = _dbus_string_get_length (str); 00967 00968 len_in_bytes = n_elements * alignment; 00969 array_start = insert_at; 00970 00971 /* Note that we do alignment padding unconditionally 00972 * even if the array is empty; this means that 00973 * padding + len is always equal to the number of bytes 00974 * in the array. 00975 */ 00976 00977 if (!_dbus_string_insert_alignment (str, &array_start, alignment)) 00978 goto error; 00979 00980 _dbus_string_init_const_len (&t, 00981 (const unsigned char*) value, 00982 len_in_bytes); 00983 00984 if (!_dbus_string_copy (&t, 0, 00985 str, array_start)) 00986 goto error; 00987 00988 swap_array (str, array_start, n_elements, byte_order, alignment); 00989 00990 if (pos_after) 00991 *pos_after = array_start + len_in_bytes; 00992 00993 return TRUE; 00994 00995 error: 00996 _dbus_string_delete (str, insert_at, 00997 _dbus_string_get_length (str) - old_string_len); 00998 00999 return FALSE; 01000 } 01001 01019 dbus_bool_t 01020 _dbus_marshal_write_fixed_multi (DBusString *str, 01021 int insert_at, 01022 int element_type, 01023 const void *value, 01024 int n_elements, 01025 int byte_order, 01026 int *pos_after) 01027 { 01028 const void* vp = *(const DBusBasicValue**)value; 01029 01030 _dbus_assert (dbus_type_is_fixed (element_type)); 01031 _dbus_assert (n_elements >= 0); 01032 01033 #if 0 01034 _dbus_verbose ("writing %d elements of %s\n", 01035 n_elements, _dbus_type_to_string (element_type)); 01036 #endif 01037 01038 switch (element_type) 01039 { 01040 case DBUS_TYPE_BYTE: 01041 return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after); 01042 break; 01043 case DBUS_TYPE_INT16: 01044 case DBUS_TYPE_UINT16: 01045 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after); 01046 case DBUS_TYPE_BOOLEAN: 01047 case DBUS_TYPE_INT32: 01048 case DBUS_TYPE_UINT32: 01049 case DBUS_TYPE_UNIX_FD: 01050 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after); 01051 break; 01052 case DBUS_TYPE_INT64: 01053 case DBUS_TYPE_UINT64: 01054 case DBUS_TYPE_DOUBLE: 01055 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after); 01056 break; 01057 01058 default: 01059 _dbus_assert_not_reached ("non fixed type in array write"); 01060 break; 01061 } 01062 01063 return FALSE; 01064 } 01065 01066 01076 void 01077 _dbus_marshal_skip_basic (const DBusString *str, 01078 int type, 01079 int byte_order, 01080 int *pos) 01081 { 01082 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 01083 byte_order == DBUS_BIG_ENDIAN); 01084 01085 switch (type) 01086 { 01087 case DBUS_TYPE_BYTE: 01088 (*pos)++; 01089 break; 01090 case DBUS_TYPE_INT16: 01091 case DBUS_TYPE_UINT16: 01092 *pos = _DBUS_ALIGN_VALUE (*pos, 2); 01093 *pos += 2; 01094 break; 01095 case DBUS_TYPE_BOOLEAN: 01096 case DBUS_TYPE_INT32: 01097 case DBUS_TYPE_UINT32: 01098 case DBUS_TYPE_UNIX_FD: 01099 *pos = _DBUS_ALIGN_VALUE (*pos, 4); 01100 *pos += 4; 01101 break; 01102 case DBUS_TYPE_INT64: 01103 case DBUS_TYPE_UINT64: 01104 case DBUS_TYPE_DOUBLE: 01105 *pos = _DBUS_ALIGN_VALUE (*pos, 8); 01106 *pos += 8; 01107 break; 01108 case DBUS_TYPE_STRING: 01109 case DBUS_TYPE_OBJECT_PATH: 01110 { 01111 int len; 01112 01113 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos); 01114 01115 *pos += len + 1; /* length plus nul */ 01116 } 01117 break; 01118 case DBUS_TYPE_SIGNATURE: 01119 { 01120 int len; 01121 01122 len = _dbus_string_get_byte (str, *pos); 01123 01124 *pos += len + 2; /* length byte plus length plus nul */ 01125 } 01126 break; 01127 default: 01128 _dbus_warn ("type %s not a basic type\n", 01129 _dbus_type_to_string (type)); 01130 _dbus_assert_not_reached ("not a basic type"); 01131 break; 01132 } 01133 } 01134 01144 void 01145 _dbus_marshal_skip_array (const DBusString *str, 01146 int element_type, 01147 int byte_order, 01148 int *pos) 01149 { 01150 dbus_uint32_t array_len; 01151 int i; 01152 int alignment; 01153 01154 i = _DBUS_ALIGN_VALUE (*pos, 4); 01155 01156 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i); 01157 01158 alignment = _dbus_type_get_alignment (element_type); 01159 01160 i = _DBUS_ALIGN_VALUE (i, alignment); 01161 01162 *pos = i + array_len; 01163 } 01164 01172 int 01173 _dbus_type_get_alignment (int typecode) 01174 { 01175 switch (typecode) 01176 { 01177 case DBUS_TYPE_BYTE: 01178 case DBUS_TYPE_VARIANT: 01179 case DBUS_TYPE_SIGNATURE: 01180 return 1; 01181 case DBUS_TYPE_INT16: 01182 case DBUS_TYPE_UINT16: 01183 return 2; 01184 case DBUS_TYPE_BOOLEAN: 01185 case DBUS_TYPE_INT32: 01186 case DBUS_TYPE_UINT32: 01187 case DBUS_TYPE_UNIX_FD: 01188 /* this stuff is 4 since it starts with a length */ 01189 case DBUS_TYPE_STRING: 01190 case DBUS_TYPE_OBJECT_PATH: 01191 case DBUS_TYPE_ARRAY: 01192 return 4; 01193 case DBUS_TYPE_INT64: 01194 case DBUS_TYPE_UINT64: 01195 case DBUS_TYPE_DOUBLE: 01196 /* struct is 8 since it could contain an 8-aligned item 01197 * and it's simpler to just always align structs to 8; 01198 * we want the amount of padding in a struct of a given 01199 * type to be predictable, not location-dependent. 01200 * DICT_ENTRY is always the same as struct. 01201 */ 01202 case DBUS_TYPE_STRUCT: 01203 case DBUS_TYPE_DICT_ENTRY: 01204 return 8; 01205 01206 default: 01207 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); 01208 return 0; 01209 } 01210 } 01211 01218 const char * 01219 _dbus_type_to_string (int typecode) 01220 { 01221 switch (typecode) 01222 { 01223 case DBUS_TYPE_INVALID: 01224 return "invalid"; 01225 case DBUS_TYPE_BOOLEAN: 01226 return "boolean"; 01227 case DBUS_TYPE_BYTE: 01228 return "byte"; 01229 case DBUS_TYPE_INT16: 01230 return "int16"; 01231 case DBUS_TYPE_UINT16: 01232 return "uint16"; 01233 case DBUS_TYPE_INT32: 01234 return "int32"; 01235 case DBUS_TYPE_UINT32: 01236 return "uint32"; 01237 case DBUS_TYPE_INT64: 01238 return "int64"; 01239 case DBUS_TYPE_UINT64: 01240 return "uint64"; 01241 case DBUS_TYPE_DOUBLE: 01242 return "double"; 01243 case DBUS_TYPE_STRING: 01244 return "string"; 01245 case DBUS_TYPE_OBJECT_PATH: 01246 return "object_path"; 01247 case DBUS_TYPE_SIGNATURE: 01248 return "signature"; 01249 case DBUS_TYPE_STRUCT: 01250 return "struct"; 01251 case DBUS_TYPE_DICT_ENTRY: 01252 return "dict_entry"; 01253 case DBUS_TYPE_ARRAY: 01254 return "array"; 01255 case DBUS_TYPE_VARIANT: 01256 return "variant"; 01257 case DBUS_STRUCT_BEGIN_CHAR: 01258 return "begin_struct"; 01259 case DBUS_STRUCT_END_CHAR: 01260 return "end_struct"; 01261 case DBUS_DICT_ENTRY_BEGIN_CHAR: 01262 return "begin_dict_entry"; 01263 case DBUS_DICT_ENTRY_END_CHAR: 01264 return "end_dict_entry"; 01265 case DBUS_TYPE_UNIX_FD: 01266 return "unix_fd"; 01267 default: 01268 return "unknown"; 01269 } 01270 } 01271 01279 void 01280 _dbus_verbose_bytes (const unsigned char *data, 01281 int len, 01282 int offset) 01283 { 01284 int i; 01285 const unsigned char *aligned; 01286 01287 _dbus_assert (len >= 0); 01288 01289 if (!_dbus_is_verbose()) 01290 return; 01291 01292 /* Print blanks on first row if appropriate */ 01293 aligned = _DBUS_ALIGN_ADDRESS (data, 4); 01294 if (aligned > data) 01295 aligned -= 4; 01296 _dbus_assert (aligned <= data); 01297 01298 if (aligned != data) 01299 { 01300 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned); 01301 while (aligned != data) 01302 { 01303 _dbus_verbose (" "); 01304 ++aligned; 01305 } 01306 } 01307 01308 /* now print the bytes */ 01309 i = 0; 01310 while (i < len) 01311 { 01312 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01313 { 01314 _dbus_verbose ("%4d\t%p: ", 01315 offset + i, &data[i]); 01316 } 01317 01318 if (data[i] >= 32 && 01319 data[i] <= 126) 01320 _dbus_verbose (" '%c' ", data[i]); 01321 else 01322 _dbus_verbose ("0x%s%x ", 01323 data[i] <= 0xf ? "0" : "", data[i]); 01324 01325 ++i; 01326 01327 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01328 { 01329 if (i > 3) 01330 _dbus_verbose ("BE: %d LE: %d", 01331 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), 01332 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); 01333 01334 if (i > 7 && 01335 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) 01336 { 01337 #ifdef DBUS_INT64_PRINTF_MODIFIER 01338 _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x", 01339 *(dbus_uint64_t*)&data[i-8]); 01340 #endif 01341 _dbus_verbose (" dbl: %g", 01342 *(double*)&data[i-8]); 01343 } 01344 01345 _dbus_verbose ("\n"); 01346 } 01347 } 01348 01349 _dbus_verbose ("\n"); 01350 } 01351 01359 void 01360 _dbus_verbose_bytes_of_string (const DBusString *str, 01361 int start, 01362 int len) 01363 { 01364 const char *d; 01365 int real_len; 01366 01367 real_len = _dbus_string_get_length (str); 01368 01369 _dbus_assert (start >= 0); 01370 01371 if (start > real_len) 01372 { 01373 _dbus_verbose (" [%d,%d) is not inside string of length %d\n", 01374 start, len, real_len); 01375 return; 01376 } 01377 01378 if ((start + len) > real_len) 01379 { 01380 _dbus_verbose (" [%d,%d) extends outside string of length %d\n", 01381 start, len, real_len); 01382 len = real_len - start; 01383 } 01384 01385 d = _dbus_string_get_const_data_len (str, start, len); 01386 01387 _dbus_verbose_bytes (d, len, start); 01388 } 01389 01390 static int 01391 map_type_char_to_type (int t) 01392 { 01393 if (t == DBUS_STRUCT_BEGIN_CHAR) 01394 return DBUS_TYPE_STRUCT; 01395 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR) 01396 return DBUS_TYPE_DICT_ENTRY; 01397 else 01398 { 01399 _dbus_assert (t != DBUS_STRUCT_END_CHAR); 01400 _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR); 01401 return t; 01402 } 01403 } 01404 01415 int 01416 _dbus_first_type_in_signature (const DBusString *str, 01417 int pos) 01418 { 01419 return map_type_char_to_type (_dbus_string_get_byte (str, pos)); 01420 } 01421 01430 int 01431 _dbus_first_type_in_signature_c_str (const char *str, 01432 int pos) 01433 { 01434 return map_type_char_to_type (str[pos]); 01435 } 01436 01439 #ifdef DBUS_ENABLE_EMBEDDED_TESTS 01440 #include "dbus-test.h" 01441 #include <stdio.h> 01442 01461 void 01462 _dbus_marshal_read_fixed_multi (const DBusString *str, 01463 int pos, 01464 int element_type, 01465 void *value, 01466 int n_elements, 01467 int byte_order, 01468 int *new_pos) 01469 { 01470 int array_len; 01471 int alignment; 01472 01473 _dbus_assert (dbus_type_is_fixed (element_type)); 01474 _dbus_assert (dbus_type_is_basic (element_type)); 01475 01476 #if 0 01477 _dbus_verbose ("reading %d elements of %s\n", 01478 n_elements, _dbus_type_to_string (element_type)); 01479 #endif 01480 01481 alignment = _dbus_type_get_alignment (element_type); 01482 01483 pos = _DBUS_ALIGN_VALUE (pos, alignment); 01484 01485 array_len = n_elements * alignment; 01486 01487 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len); 01488 if (new_pos) 01489 *new_pos = pos + array_len; 01490 } 01491 01492 static void 01493 swap_test_array (void *array, 01494 int len_bytes, 01495 int byte_order, 01496 int alignment) 01497 { 01498 DBusString t; 01499 01500 if (alignment == 1) 01501 return; 01502 01503 _dbus_string_init_const_len (&t, array, len_bytes); 01504 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment); 01505 } 01506 01507 #define MARSHAL_BASIC(typename, byte_order, literal) \ 01508 do { \ 01509 v_##typename = literal; \ 01510 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \ 01511 &v_##typename, \ 01512 byte_order, NULL)) \ 01513 _dbus_assert_not_reached ("no memory"); \ 01514 } while (0) 01515 01516 #define DEMARSHAL_BASIC(typename, byte_order) \ 01517 do { \ 01518 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \ 01519 byte_order, &pos); \ 01520 } while (0) 01521 01522 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \ 01523 do { \ 01524 DEMARSHAL_BASIC (typename, byte_order); \ 01525 if (literal != v_##typename) \ 01526 { \ 01527 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01528 _dbus_string_get_length (&str) - dump_pos); \ 01529 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01530 } \ 01531 } while (0) 01532 01533 #define MARSHAL_TEST(typename, byte_order, literal) \ 01534 do { \ 01535 MARSHAL_BASIC (typename, byte_order, literal); \ 01536 dump_pos = pos; \ 01537 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \ 01538 } while (0) 01539 01540 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \ 01541 do { \ 01542 MARSHAL_BASIC (typename, byte_order, literal); \ 01543 dump_pos = pos; \ 01544 DEMARSHAL_BASIC (typename, byte_order); \ 01545 if (strcmp (literal, v_##typename) != 0) \ 01546 { \ 01547 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01548 _dbus_string_get_length (&str) - dump_pos); \ 01549 _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \ 01550 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01551 } \ 01552 } while (0) 01553 01554 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \ 01555 do { \ 01556 int next; \ 01557 v_UINT32 = sizeof(literal); \ 01558 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \ 01559 byte_order, &next)) \ 01560 _dbus_assert_not_reached ("no memory"); \ 01561 v_ARRAY_##typename = literal; \ 01562 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \ 01563 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \ 01564 byte_order, NULL)) \ 01565 _dbus_assert_not_reached ("no memory"); \ 01566 } while (0) 01567 01568 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \ 01569 do { \ 01570 int next; \ 01571 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \ 01572 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \ 01573 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \ 01574 v_UINT32/alignment, \ 01575 byte_order, NULL); \ 01576 swap_test_array (v_ARRAY_##typename, v_UINT32, \ 01577 byte_order, alignment); \ 01578 } while (0) 01579 01580 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \ 01581 do { \ 01582 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \ 01583 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal)) != 0) \ 01584 { \ 01585 _dbus_verbose ("MARSHALED DATA\n"); \ 01586 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01587 _dbus_string_get_length (&str) - dump_pos); \ 01588 _dbus_verbose ("LITERAL DATA\n"); \ 01589 _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \ 01590 _dbus_verbose ("READ DATA\n"); \ 01591 _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \ 01592 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \ 01593 } \ 01594 } while (0) 01595 01596 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \ 01597 do { \ 01598 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \ 01599 dump_pos = pos; \ 01600 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \ 01601 } while (0) 01602 01603 dbus_bool_t 01604 _dbus_marshal_test (void) 01605 { 01606 int alignment; 01607 DBusString str; 01608 int pos, dump_pos; 01609 unsigned char array1[5] = { 3, 4, 0, 1, 9 }; 01610 dbus_int16_t array2[3] = { 124, 457, 780 }; 01611 dbus_int32_t array4[3] = { 123, 456, 789 }; 01612 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 01613 DBUS_INT64_CONSTANT (0x456ffffffff), 01614 DBUS_INT64_CONSTANT (0x789ffffffff) }; 01615 dbus_int64_t *v_ARRAY_INT64; 01616 unsigned char *v_ARRAY_BYTE; 01617 dbus_int16_t *v_ARRAY_INT16; 01618 dbus_uint16_t *v_ARRAY_UINT16; 01619 dbus_int32_t *v_ARRAY_INT32; 01620 dbus_uint32_t *v_ARRAY_UINT32; 01621 DBusString t; 01622 double v_DOUBLE; 01623 double t_DOUBLE; 01624 dbus_int16_t v_INT16; 01625 dbus_uint16_t v_UINT16; 01626 dbus_int32_t v_INT32; 01627 dbus_uint32_t v_UINT32; 01628 dbus_int64_t v_INT64; 01629 dbus_uint64_t v_UINT64; 01630 unsigned char v_BYTE; 01631 dbus_bool_t v_BOOLEAN; 01632 const char *v_STRING; 01633 const char *v_SIGNATURE; 01634 const char *v_OBJECT_PATH; 01635 int byte_order; 01636 01637 if (!_dbus_string_init (&str)) 01638 _dbus_assert_not_reached ("failed to init string"); 01639 01640 pos = 0; 01641 01642 /* Marshal doubles */ 01643 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14); 01644 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN); 01645 t_DOUBLE = 3.14; 01646 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01647 _dbus_assert_not_reached ("got wrong double value"); 01648 01649 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14); 01650 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN); 01651 t_DOUBLE = 3.14; 01652 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01653 _dbus_assert_not_reached ("got wrong double value"); 01654 01655 /* Marshal signed 16 integers */ 01656 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345); 01657 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345); 01658 01659 /* Marshal unsigned 16 integers */ 01660 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234); 01661 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234); 01662 01663 /* Marshal signed integers */ 01664 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678); 01665 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678); 01666 01667 /* Marshal unsigned integers */ 01668 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678); 01669 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678); 01670 01671 /* Marshal signed integers */ 01672 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01673 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01674 01675 /* Marshal unsigned integers */ 01676 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01677 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01678 01679 /* Marshal byte */ 01680 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5); 01681 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5); 01682 01683 /* Marshal all possible bools! */ 01684 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE); 01685 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE); 01686 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE); 01687 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE); 01688 01689 /* Marshal strings */ 01690 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, ""); 01691 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, ""); 01692 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string"); 01693 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string"); 01694 01695 /* object paths */ 01696 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c"); 01697 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c"); 01698 01699 /* signatures */ 01700 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, ""); 01701 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, ""); 01702 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)"); 01703 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)"); 01704 01705 /* Arrays */ 01706 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2); 01707 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2); 01708 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2); 01709 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2); 01710 01711 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4); 01712 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4); 01713 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4); 01714 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4); 01715 01716 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1); 01717 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1); 01718 01719 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8); 01720 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8); 01721 01722 #if 0 01723 01724 /* 01725 * FIXME restore the set/pack tests 01726 */ 01727 01728 /* set/pack 64-bit integers */ 01729 _dbus_string_set_length (&str, 8); 01730 01731 /* signed little */ 01732 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN, 01733 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01734 01735 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01736 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01737 _dbus_string_get_const_data (&str))); 01738 01739 /* signed big */ 01740 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN, 01741 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01742 01743 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01744 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01745 _dbus_string_get_const_data (&str))); 01746 01747 /* signed little pack */ 01748 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01749 DBUS_LITTLE_ENDIAN, 01750 _dbus_string_get_data (&str)); 01751 01752 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01753 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01754 _dbus_string_get_const_data (&str))); 01755 01756 /* signed big pack */ 01757 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01758 DBUS_BIG_ENDIAN, 01759 _dbus_string_get_data (&str)); 01760 01761 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01762 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01763 _dbus_string_get_const_data (&str))); 01764 01765 /* unsigned little */ 01766 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN, 01767 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01768 01769 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01770 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01771 _dbus_string_get_const_data (&str))); 01772 01773 /* unsigned big */ 01774 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN, 01775 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01776 01777 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01778 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01779 _dbus_string_get_const_data (&str))); 01780 01781 /* unsigned little pack */ 01782 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01783 DBUS_LITTLE_ENDIAN, 01784 _dbus_string_get_data (&str)); 01785 01786 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01787 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01788 _dbus_string_get_const_data (&str))); 01789 01790 /* unsigned big pack */ 01791 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01792 DBUS_BIG_ENDIAN, 01793 _dbus_string_get_data (&str)); 01794 01795 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01796 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01797 _dbus_string_get_const_data (&str))); 01798 01799 /* set/pack 32-bit integers */ 01800 _dbus_string_set_length (&str, 4); 01801 01802 /* signed little */ 01803 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN, 01804 0, -0x123456); 01805 01806 _dbus_assert (-0x123456 == 01807 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01808 _dbus_string_get_const_data (&str))); 01809 01810 /* signed big */ 01811 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN, 01812 0, -0x123456); 01813 01814 _dbus_assert (-0x123456 == 01815 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01816 _dbus_string_get_const_data (&str))); 01817 01818 /* signed little pack */ 01819 _dbus_pack_int32 (-0x123456, 01820 DBUS_LITTLE_ENDIAN, 01821 _dbus_string_get_data (&str)); 01822 01823 _dbus_assert (-0x123456 == 01824 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01825 _dbus_string_get_const_data (&str))); 01826 01827 /* signed big pack */ 01828 _dbus_pack_int32 (-0x123456, 01829 DBUS_BIG_ENDIAN, 01830 _dbus_string_get_data (&str)); 01831 01832 _dbus_assert (-0x123456 == 01833 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01834 _dbus_string_get_const_data (&str))); 01835 01836 /* unsigned little */ 01837 _dbus_marshal_set_uint32 (&str, 01838 0, 0x123456, 01839 DBUS_LITTLE_ENDIAN); 01840 01841 _dbus_assert (0x123456 == 01842 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01843 _dbus_string_get_const_data (&str))); 01844 01845 /* unsigned big */ 01846 _dbus_marshal_set_uint32 (&str, 01847 0, 0x123456, 01848 DBUS_BIG_ENDIAN); 01849 01850 _dbus_assert (0x123456 == 01851 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01852 _dbus_string_get_const_data (&str))); 01853 01854 /* unsigned little pack */ 01855 _dbus_pack_uint32 (0x123456, 01856 DBUS_LITTLE_ENDIAN, 01857 _dbus_string_get_data (&str)); 01858 01859 _dbus_assert (0x123456 == 01860 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01861 _dbus_string_get_const_data (&str))); 01862 01863 /* unsigned big pack */ 01864 _dbus_pack_uint32 (0x123456, 01865 DBUS_BIG_ENDIAN, 01866 _dbus_string_get_data (&str)); 01867 01868 _dbus_assert (0x123456 == 01869 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01870 _dbus_string_get_const_data (&str))); 01871 01872 #endif /* set/pack tests for integers */ 01873 01874 /* Strings in-place set */ 01875 byte_order = DBUS_LITTLE_ENDIAN; 01876 while (TRUE) 01877 { 01878 /* Init a string */ 01879 _dbus_string_set_length (&str, 0); 01880 01881 /* reset pos for the macros */ 01882 pos = 0; 01883 01884 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world"); 01885 01886 /* Set it to something longer */ 01887 _dbus_string_init_const (&t, "Hello world foo"); 01888 01889 v_STRING = _dbus_string_get_const_data (&t); 01890 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01891 &v_STRING, byte_order, NULL, NULL); 01892 01893 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01894 &v_STRING, byte_order, 01895 NULL); 01896 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0); 01897 01898 /* Set it to something shorter */ 01899 _dbus_string_init_const (&t, "Hello"); 01900 01901 v_STRING = _dbus_string_get_const_data (&t); 01902 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01903 &v_STRING, byte_order, NULL, NULL); 01904 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01905 &v_STRING, byte_order, 01906 NULL); 01907 _dbus_assert (strcmp (v_STRING, "Hello") == 0); 01908 01909 /* Do the other byte order */ 01910 if (byte_order == DBUS_LITTLE_ENDIAN) 01911 byte_order = DBUS_BIG_ENDIAN; 01912 else 01913 break; 01914 } 01915 01916 /* Clean up */ 01917 _dbus_string_free (&str); 01918 01919 return TRUE; 01920 } 01921 01922 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */