D-Bus
1.4.10
|
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 00047 static void 00048 pack_2_octets (dbus_uint16_t value, 00049 int byte_order, 00050 unsigned char *data) 00051 { 00052 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 00053 00054 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00055 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value); 00056 else 00057 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value); 00058 } 00059 00060 static void 00061 pack_4_octets (dbus_uint32_t value, 00062 int byte_order, 00063 unsigned char *data) 00064 { 00065 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 00066 00067 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00068 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value); 00069 else 00070 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value); 00071 } 00072 00073 static void 00074 pack_8_octets (DBusBasicValue value, 00075 int byte_order, 00076 unsigned char *data) 00077 { 00078 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data); 00079 00080 #ifdef DBUS_HAVE_INT64 00081 if ((byte_order) == DBUS_LITTLE_ENDIAN) 00082 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64); 00083 else 00084 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64); 00085 #else 00086 *(DBus8ByteStruct*)data = value.u64; 00087 swap_8_octets ((DBusBasicValue*)data, byte_order); 00088 #endif 00089 } 00090 00098 void 00099 _dbus_pack_uint32 (dbus_uint32_t value, 00100 int byte_order, 00101 unsigned char *data) 00102 { 00103 pack_4_octets (value, byte_order, data); 00104 } 00105 00106 #ifndef DBUS_HAVE_INT64 00107 /* from ORBit */ 00108 static void 00109 swap_bytes (unsigned char *data, 00110 unsigned int len) 00111 { 00112 unsigned char *p1 = data; 00113 unsigned char *p2 = data + len - 1; 00114 00115 while (p1 < p2) 00116 { 00117 unsigned char tmp = *p1; 00118 *p1 = *p2; 00119 *p2 = tmp; 00120 00121 --p2; 00122 ++p1; 00123 } 00124 } 00125 #endif /* !DBUS_HAVE_INT64 */ 00126 00127 static void 00128 swap_8_octets (DBusBasicValue *value, 00129 int byte_order) 00130 { 00131 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00132 { 00133 #ifdef DBUS_HAVE_INT64 00134 value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64); 00135 #else 00136 swap_bytes ((unsigned char *)value, 8); 00137 #endif 00138 } 00139 } 00140 00141 #if 0 00142 static DBusBasicValue 00143 unpack_8_octets (int byte_order, 00144 const unsigned char *data) 00145 { 00146 DBusBasicValue r; 00147 00148 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data); 00149 _dbus_assert (sizeof (r) == 8); 00150 00151 #ifdef DBUS_HAVE_INT64 00152 if (byte_order == DBUS_LITTLE_ENDIAN) 00153 r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data); 00154 else 00155 r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data); 00156 #else 00157 r.u64 = *(DBus8ByteStruct*)data; 00158 swap_8_octets (&r, byte_order); 00159 #endif 00160 00161 return r; 00162 } 00163 #endif 00164 00165 #ifndef _dbus_unpack_uint16 00166 00173 dbus_uint16_t 00174 _dbus_unpack_uint16 (int byte_order, 00175 const unsigned char *data) 00176 { 00177 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 00178 00179 if (byte_order == DBUS_LITTLE_ENDIAN) 00180 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data); 00181 else 00182 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data); 00183 } 00184 #endif /* _dbus_unpack_uint16 */ 00185 00186 #ifndef _dbus_unpack_uint32 00187 00194 dbus_uint32_t 00195 _dbus_unpack_uint32 (int byte_order, 00196 const unsigned char *data) 00197 { 00198 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 00199 00200 if (byte_order == DBUS_LITTLE_ENDIAN) 00201 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data); 00202 else 00203 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data); 00204 } 00205 #endif /* _dbus_unpack_uint32 */ 00206 00207 static void 00208 set_2_octets (DBusString *str, 00209 int offset, 00210 dbus_uint16_t value, 00211 int byte_order) 00212 { 00213 char *data; 00214 00215 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00216 byte_order == DBUS_BIG_ENDIAN); 00217 00218 data = _dbus_string_get_data_len (str, offset, 2); 00219 00220 pack_2_octets (value, byte_order, data); 00221 } 00222 00223 static void 00224 set_4_octets (DBusString *str, 00225 int offset, 00226 dbus_uint32_t value, 00227 int byte_order) 00228 { 00229 char *data; 00230 00231 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00232 byte_order == DBUS_BIG_ENDIAN); 00233 00234 data = _dbus_string_get_data_len (str, offset, 4); 00235 00236 pack_4_octets (value, byte_order, data); 00237 } 00238 00239 static void 00240 set_8_octets (DBusString *str, 00241 int offset, 00242 DBusBasicValue value, 00243 int byte_order) 00244 { 00245 char *data; 00246 00247 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00248 byte_order == DBUS_BIG_ENDIAN); 00249 00250 data = _dbus_string_get_data_len (str, offset, 8); 00251 00252 pack_8_octets (value, byte_order, data); 00253 } 00254 00265 void 00266 _dbus_marshal_set_uint32 (DBusString *str, 00267 int pos, 00268 dbus_uint32_t value, 00269 int byte_order) 00270 { 00271 set_4_octets (str, pos, value, byte_order); 00272 } 00273 00293 static dbus_bool_t 00294 set_string (DBusString *str, 00295 int pos, 00296 const char *value, 00297 int byte_order, 00298 int *old_end_pos, 00299 int *new_end_pos) 00300 { 00301 int old_len, new_len; 00302 DBusString dstr; 00303 00304 _dbus_string_init_const (&dstr, value); 00305 00306 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos); 00307 old_len = _dbus_unpack_uint32 (byte_order, 00308 _dbus_string_get_const_data_len (str, pos, 4)); 00309 00310 new_len = _dbus_string_get_length (&dstr); 00311 00312 if (!_dbus_string_replace_len (&dstr, 0, new_len, 00313 str, pos + 4, old_len)) 00314 return FALSE; 00315 00316 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order); 00317 00318 if (old_end_pos) 00319 *old_end_pos = pos + 4 + old_len + 1; 00320 if (new_end_pos) 00321 *new_end_pos = pos + 4 + new_len + 1; 00322 00323 return TRUE; 00324 } 00325 00339 static dbus_bool_t 00340 set_signature (DBusString *str, 00341 int pos, 00342 const char *value, 00343 int byte_order, 00344 int *old_end_pos, 00345 int *new_end_pos) 00346 { 00347 int old_len, new_len; 00348 DBusString dstr; 00349 00350 _dbus_string_init_const (&dstr, value); 00351 00352 old_len = _dbus_string_get_byte (str, pos); 00353 new_len = _dbus_string_get_length (&dstr); 00354 00355 if (!_dbus_string_replace_len (&dstr, 0, new_len, 00356 str, pos + 1, old_len)) 00357 return FALSE; 00358 00359 _dbus_string_set_byte (str, pos, new_len); 00360 00361 if (old_end_pos) 00362 *old_end_pos = pos + 1 + old_len + 1; 00363 if (new_end_pos) 00364 *new_end_pos = pos + 1 + new_len + 1; 00365 00366 return TRUE; 00367 } 00368 00382 dbus_bool_t 00383 _dbus_marshal_set_basic (DBusString *str, 00384 int pos, 00385 int type, 00386 const void *value, 00387 int byte_order, 00388 int *old_end_pos, 00389 int *new_end_pos) 00390 { 00391 const DBusBasicValue *vp; 00392 00393 vp = value; 00394 00395 switch (type) 00396 { 00397 case DBUS_TYPE_BYTE: 00398 _dbus_string_set_byte (str, pos, vp->byt); 00399 if (old_end_pos) 00400 *old_end_pos = pos + 1; 00401 if (new_end_pos) 00402 *new_end_pos = pos + 1; 00403 return TRUE; 00404 break; 00405 case DBUS_TYPE_INT16: 00406 case DBUS_TYPE_UINT16: 00407 pos = _DBUS_ALIGN_VALUE (pos, 2); 00408 set_2_octets (str, pos, vp->u16, byte_order); 00409 if (old_end_pos) 00410 *old_end_pos = pos + 2; 00411 if (new_end_pos) 00412 *new_end_pos = pos + 2; 00413 return TRUE; 00414 break; 00415 case DBUS_TYPE_BOOLEAN: 00416 case DBUS_TYPE_INT32: 00417 case DBUS_TYPE_UINT32: 00418 case DBUS_TYPE_UNIX_FD: 00419 pos = _DBUS_ALIGN_VALUE (pos, 4); 00420 set_4_octets (str, pos, vp->u32, byte_order); 00421 if (old_end_pos) 00422 *old_end_pos = pos + 4; 00423 if (new_end_pos) 00424 *new_end_pos = pos + 4; 00425 return TRUE; 00426 break; 00427 case DBUS_TYPE_INT64: 00428 case DBUS_TYPE_UINT64: 00429 case DBUS_TYPE_DOUBLE: 00430 pos = _DBUS_ALIGN_VALUE (pos, 8); 00431 set_8_octets (str, pos, *vp, byte_order); 00432 if (old_end_pos) 00433 *old_end_pos = pos + 8; 00434 if (new_end_pos) 00435 *new_end_pos = pos + 8; 00436 return TRUE; 00437 break; 00438 case DBUS_TYPE_STRING: 00439 case DBUS_TYPE_OBJECT_PATH: 00440 pos = _DBUS_ALIGN_VALUE (pos, 4); 00441 _dbus_assert (vp->str != NULL); 00442 return set_string (str, pos, vp->str, byte_order, 00443 old_end_pos, new_end_pos); 00444 break; 00445 case DBUS_TYPE_SIGNATURE: 00446 _dbus_assert (vp->str != NULL); 00447 return set_signature (str, pos, vp->str, byte_order, 00448 old_end_pos, new_end_pos); 00449 break; 00450 default: 00451 _dbus_assert_not_reached ("not a basic type"); 00452 return FALSE; 00453 break; 00454 } 00455 } 00456 00466 dbus_uint32_t 00467 _dbus_marshal_read_uint32 (const DBusString *str, 00468 int pos, 00469 int byte_order, 00470 int *new_pos) 00471 { 00472 pos = _DBUS_ALIGN_VALUE (pos, 4); 00473 00474 if (new_pos) 00475 *new_pos = pos + 4; 00476 00477 _dbus_assert (pos + 4 <= _dbus_string_get_length (str)); 00478 00479 return _dbus_unpack_uint32 (byte_order, 00480 _dbus_string_get_const_data (str) + pos); 00481 } 00482 00504 void 00505 _dbus_marshal_read_basic (const DBusString *str, 00506 int pos, 00507 int type, 00508 void *value, 00509 int byte_order, 00510 int *new_pos) 00511 { 00512 const char *str_data; 00513 00514 _dbus_assert (dbus_type_is_basic (type)); 00515 00516 str_data = _dbus_string_get_const_data (str); 00517 00518 /* Below we volatile types to avoid aliasing issues; 00519 * see http://bugs.freedesktop.org/show_bug.cgi?id=20137 00520 */ 00521 00522 switch (type) 00523 { 00524 case DBUS_TYPE_BYTE: 00525 { 00526 volatile unsigned char *vp = value; 00527 *vp = (unsigned char) _dbus_string_get_byte (str, pos); 00528 (pos)++; 00529 } 00530 break; 00531 case DBUS_TYPE_INT16: 00532 case DBUS_TYPE_UINT16: 00533 { 00534 volatile dbus_uint16_t *vp = value; 00535 pos = _DBUS_ALIGN_VALUE (pos, 2); 00536 *vp = *(dbus_uint16_t *)(str_data + pos); 00537 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00538 *vp = DBUS_UINT16_SWAP_LE_BE (*vp); 00539 pos += 2; 00540 } 00541 break; 00542 case DBUS_TYPE_INT32: 00543 case DBUS_TYPE_UINT32: 00544 case DBUS_TYPE_BOOLEAN: 00545 case DBUS_TYPE_UNIX_FD: 00546 { 00547 volatile dbus_uint32_t *vp = value; 00548 pos = _DBUS_ALIGN_VALUE (pos, 4); 00549 *vp = *(dbus_uint32_t *)(str_data + pos); 00550 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00551 *vp = DBUS_UINT32_SWAP_LE_BE (*vp); 00552 pos += 4; 00553 } 00554 break; 00555 case DBUS_TYPE_INT64: 00556 case DBUS_TYPE_UINT64: 00557 case DBUS_TYPE_DOUBLE: 00558 { 00559 volatile dbus_uint64_t *vp = value; 00560 pos = _DBUS_ALIGN_VALUE (pos, 8); 00561 #ifdef DBUS_HAVE_INT64 00562 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00563 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); 00564 else 00565 *vp = *(dbus_uint64_t*)(str_data + pos); 00566 #else 00567 *vp = *(DBus8ByteStruct*) (str_data + pos); 00568 swap_8_octets (vp, byte_order); 00569 #endif 00570 pos += 8; 00571 } 00572 break; 00573 case DBUS_TYPE_STRING: 00574 case DBUS_TYPE_OBJECT_PATH: 00575 { 00576 int len; 00577 volatile char **vp = value; 00578 00579 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); 00580 00581 *vp = (char*) str_data + pos; 00582 00583 pos += len + 1; /* length plus nul */ 00584 } 00585 break; 00586 case DBUS_TYPE_SIGNATURE: 00587 { 00588 int len; 00589 volatile char **vp = value; 00590 00591 len = _dbus_string_get_byte (str, pos); 00592 pos += 1; 00593 00594 *vp = (char*) str_data + pos; 00595 00596 pos += len + 1; /* length plus nul */ 00597 } 00598 break; 00599 default: 00600 _dbus_warn_check_failed ("type %s %d not a basic type\n", 00601 _dbus_type_to_string (type), type); 00602 _dbus_assert_not_reached ("not a basic type"); 00603 break; 00604 } 00605 00606 if (new_pos) 00607 *new_pos = pos; 00608 } 00609 00610 static dbus_bool_t 00611 marshal_2_octets (DBusString *str, 00612 int insert_at, 00613 dbus_uint16_t value, 00614 int byte_order, 00615 int *pos_after) 00616 { 00617 dbus_bool_t retval; 00618 int orig_len; 00619 00620 _dbus_assert (sizeof (value) == 2); 00621 00622 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00623 value = DBUS_UINT16_SWAP_LE_BE (value); 00624 00625 orig_len = _dbus_string_get_length (str); 00626 00627 retval = _dbus_string_insert_2_aligned (str, insert_at, 00628 (const unsigned char *)&value); 00629 00630 if (pos_after) 00631 { 00632 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 00633 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 00634 } 00635 00636 return retval; 00637 } 00638 00639 static dbus_bool_t 00640 marshal_4_octets (DBusString *str, 00641 int insert_at, 00642 dbus_uint32_t value, 00643 int byte_order, 00644 int *pos_after) 00645 { 00646 dbus_bool_t retval; 00647 int orig_len; 00648 00649 _dbus_assert (sizeof (value) == 4); 00650 00651 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00652 value = DBUS_UINT32_SWAP_LE_BE (value); 00653 00654 orig_len = _dbus_string_get_length (str); 00655 00656 retval = _dbus_string_insert_4_aligned (str, insert_at, 00657 (const unsigned char *)&value); 00658 00659 if (pos_after) 00660 { 00661 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 00662 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 00663 } 00664 00665 return retval; 00666 } 00667 00668 static dbus_bool_t 00669 marshal_8_octets (DBusString *str, 00670 int insert_at, 00671 DBusBasicValue value, 00672 int byte_order, 00673 int *pos_after) 00674 { 00675 dbus_bool_t retval; 00676 int orig_len; 00677 00678 _dbus_assert (sizeof (value) == 8); 00679 00680 swap_8_octets (&value, byte_order); 00681 00682 orig_len = _dbus_string_get_length (str); 00683 00684 retval = _dbus_string_insert_8_aligned (str, insert_at, 00685 (const unsigned char *)&value); 00686 00687 if (pos_after) 00688 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len; 00689 00690 return retval; 00691 } 00692 00693 enum 00694 { 00695 MARSHAL_AS_STRING, 00696 MARSHAL_AS_SIGNATURE, 00697 MARSHAL_AS_BYTE_ARRAY 00698 }; 00699 00700 static dbus_bool_t 00701 marshal_len_followed_by_bytes (int marshal_as, 00702 DBusString *str, 00703 int insert_at, 00704 const unsigned char *value, 00705 int data_len, /* doesn't include nul if any */ 00706 int byte_order, 00707 int *pos_after) 00708 { 00709 int pos; 00710 DBusString value_str; 00711 int value_len; 00712 00713 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN); 00714 if (insert_at > _dbus_string_get_length (str)) 00715 _dbus_warn ("insert_at = %d string len = %d data_len = %d\n", 00716 insert_at, _dbus_string_get_length (str), data_len); 00717 00718 if (marshal_as == MARSHAL_AS_BYTE_ARRAY) 00719 value_len = data_len; 00720 else 00721 value_len = data_len + 1; /* value has a nul */ 00722 00723 _dbus_string_init_const_len (&value_str, value, value_len); 00724 00725 pos = insert_at; 00726 00727 if (marshal_as == MARSHAL_AS_SIGNATURE) 00728 { 00729 _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH); 00730 _dbus_assert (data_len <= 255); /* same as max sig len right now */ 00731 00732 if (!_dbus_string_insert_byte (str, pos, data_len)) 00733 goto oom; 00734 00735 pos += 1; 00736 } 00737 else 00738 { 00739 if (!marshal_4_octets (str, pos, data_len, 00740 byte_order, &pos)) 00741 goto oom; 00742 } 00743 00744 if (!_dbus_string_copy_len (&value_str, 0, value_len, 00745 str, pos)) 00746 goto oom; 00747 00748 #if 0 00749 /* too expensive */ 00750 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len, 00751 str, pos)); 00752 _dbus_verbose_bytes_of_string (str, pos, value_len); 00753 #endif 00754 00755 pos += value_len; 00756 00757 if (pos_after) 00758 *pos_after = pos; 00759 00760 return TRUE; 00761 00762 oom: 00763 /* Delete what we've inserted */ 00764 _dbus_string_delete (str, insert_at, pos - insert_at); 00765 00766 return FALSE; 00767 } 00768 00769 static dbus_bool_t 00770 marshal_string (DBusString *str, 00771 int insert_at, 00772 const char *value, 00773 int byte_order, 00774 int *pos_after) 00775 { 00776 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING, 00777 str, insert_at, value, 00778 strlen (value), 00779 byte_order, pos_after); 00780 } 00781 00782 static dbus_bool_t 00783 marshal_signature (DBusString *str, 00784 int insert_at, 00785 const char *value, 00786 int *pos_after) 00787 { 00788 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE, 00789 str, insert_at, value, 00790 strlen (value), 00791 DBUS_COMPILER_BYTE_ORDER, /* irrelevant */ 00792 pos_after); 00793 } 00794 00811 dbus_bool_t 00812 _dbus_marshal_write_basic (DBusString *str, 00813 int insert_at, 00814 int type, 00815 const void *value, 00816 int byte_order, 00817 int *pos_after) 00818 { 00819 const DBusBasicValue *vp; 00820 00821 _dbus_assert (dbus_type_is_basic (type)); 00822 00823 vp = value; 00824 00825 switch (type) 00826 { 00827 case DBUS_TYPE_BYTE: 00828 if (!_dbus_string_insert_byte (str, insert_at, vp->byt)) 00829 return FALSE; 00830 if (pos_after) 00831 *pos_after = insert_at + 1; 00832 return TRUE; 00833 break; 00834 case DBUS_TYPE_INT16: 00835 case DBUS_TYPE_UINT16: 00836 return marshal_2_octets (str, insert_at, vp->u16, 00837 byte_order, pos_after); 00838 break; 00839 case DBUS_TYPE_BOOLEAN: 00840 return marshal_4_octets (str, insert_at, vp->u32 != FALSE, 00841 byte_order, pos_after); 00842 break; 00843 case DBUS_TYPE_INT32: 00844 case DBUS_TYPE_UINT32: 00845 case DBUS_TYPE_UNIX_FD: 00846 return marshal_4_octets (str, insert_at, vp->u32, 00847 byte_order, pos_after); 00848 break; 00849 case DBUS_TYPE_INT64: 00850 case DBUS_TYPE_UINT64: 00851 case DBUS_TYPE_DOUBLE: 00852 return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after); 00853 break; 00854 00855 case DBUS_TYPE_STRING: 00856 case DBUS_TYPE_OBJECT_PATH: 00857 _dbus_assert (vp->str != NULL); 00858 return marshal_string (str, insert_at, vp->str, byte_order, pos_after); 00859 break; 00860 case DBUS_TYPE_SIGNATURE: 00861 _dbus_assert (vp->str != NULL); 00862 return marshal_signature (str, insert_at, vp->str, pos_after); 00863 break; 00864 default: 00865 _dbus_assert_not_reached ("not a basic type"); 00866 return FALSE; 00867 break; 00868 } 00869 } 00870 00871 static dbus_bool_t 00872 marshal_1_octets_array (DBusString *str, 00873 int insert_at, 00874 const unsigned char *value, 00875 int n_elements, 00876 int byte_order, 00877 int *pos_after) 00878 { 00879 int pos; 00880 DBusString value_str; 00881 00882 _dbus_string_init_const_len (&value_str, value, n_elements); 00883 00884 pos = insert_at; 00885 00886 if (!_dbus_string_copy_len (&value_str, 0, n_elements, 00887 str, pos)) 00888 return FALSE; 00889 00890 pos += n_elements; 00891 00892 if (pos_after) 00893 *pos_after = pos; 00894 00895 return TRUE; 00896 } 00897 00905 void 00906 _dbus_swap_array (unsigned char *data, 00907 int n_elements, 00908 int alignment) 00909 { 00910 unsigned char *d; 00911 unsigned char *end; 00912 00913 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data); 00914 00915 /* we use const_data and cast it off so DBusString can be a const string 00916 * for the unit tests. don't ask. 00917 */ 00918 d = data; 00919 end = d + (n_elements * alignment); 00920 00921 if (alignment == 8) 00922 { 00923 while (d != end) 00924 { 00925 #ifdef DBUS_HAVE_INT64 00926 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d)); 00927 #else 00928 swap_8_bytes ((DBusBasicValue*) d); 00929 #endif 00930 d += 8; 00931 } 00932 } 00933 else if (alignment == 4) 00934 { 00935 while (d != end) 00936 { 00937 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d)); 00938 d += 4; 00939 } 00940 } 00941 else 00942 { 00943 _dbus_assert (alignment == 2); 00944 00945 while (d != end) 00946 { 00947 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d)); 00948 d += 2; 00949 } 00950 } 00951 } 00952 00953 static void 00954 swap_array (DBusString *str, 00955 int array_start, 00956 int n_elements, 00957 int byte_order, 00958 int alignment) 00959 { 00960 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start); 00961 00962 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 00963 { 00964 /* we use const_data and cast it off so DBusString can be a const string 00965 * for the unit tests. don't ask. 00966 */ 00967 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start), 00968 n_elements, alignment); 00969 } 00970 } 00971 00972 static dbus_bool_t 00973 marshal_fixed_multi (DBusString *str, 00974 int insert_at, 00975 const DBusBasicValue *value, 00976 int n_elements, 00977 int byte_order, 00978 int alignment, 00979 int *pos_after) 00980 { 00981 int old_string_len; 00982 int array_start; 00983 DBusString t; 00984 int len_in_bytes; 00985 00986 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment); 00987 00988 old_string_len = _dbus_string_get_length (str); 00989 00990 len_in_bytes = n_elements * alignment; 00991 array_start = insert_at; 00992 00993 /* Note that we do alignment padding unconditionally 00994 * even if the array is empty; this means that 00995 * padding + len is always equal to the number of bytes 00996 * in the array. 00997 */ 00998 00999 if (!_dbus_string_insert_alignment (str, &array_start, alignment)) 01000 goto error; 01001 01002 _dbus_string_init_const_len (&t, 01003 (const unsigned char*) value, 01004 len_in_bytes); 01005 01006 if (!_dbus_string_copy (&t, 0, 01007 str, array_start)) 01008 goto error; 01009 01010 swap_array (str, array_start, n_elements, byte_order, alignment); 01011 01012 if (pos_after) 01013 *pos_after = array_start + len_in_bytes; 01014 01015 return TRUE; 01016 01017 error: 01018 _dbus_string_delete (str, insert_at, 01019 _dbus_string_get_length (str) - old_string_len); 01020 01021 return FALSE; 01022 } 01023 01041 dbus_bool_t 01042 _dbus_marshal_write_fixed_multi (DBusString *str, 01043 int insert_at, 01044 int element_type, 01045 const void *value, 01046 int n_elements, 01047 int byte_order, 01048 int *pos_after) 01049 { 01050 const void* vp = *(const DBusBasicValue**)value; 01051 01052 _dbus_assert (dbus_type_is_fixed (element_type)); 01053 _dbus_assert (n_elements >= 0); 01054 01055 #if 0 01056 _dbus_verbose ("writing %d elements of %s\n", 01057 n_elements, _dbus_type_to_string (element_type)); 01058 #endif 01059 01060 switch (element_type) 01061 { 01062 case DBUS_TYPE_BYTE: 01063 return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after); 01064 break; 01065 case DBUS_TYPE_INT16: 01066 case DBUS_TYPE_UINT16: 01067 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after); 01068 case DBUS_TYPE_BOOLEAN: 01069 case DBUS_TYPE_INT32: 01070 case DBUS_TYPE_UINT32: 01071 case DBUS_TYPE_UNIX_FD: 01072 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after); 01073 break; 01074 case DBUS_TYPE_INT64: 01075 case DBUS_TYPE_UINT64: 01076 case DBUS_TYPE_DOUBLE: 01077 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after); 01078 break; 01079 01080 default: 01081 _dbus_assert_not_reached ("non fixed type in array write"); 01082 break; 01083 } 01084 01085 return FALSE; 01086 } 01087 01088 01098 void 01099 _dbus_marshal_skip_basic (const DBusString *str, 01100 int type, 01101 int byte_order, 01102 int *pos) 01103 { 01104 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 01105 byte_order == DBUS_BIG_ENDIAN); 01106 01107 switch (type) 01108 { 01109 case DBUS_TYPE_BYTE: 01110 (*pos)++; 01111 break; 01112 case DBUS_TYPE_INT16: 01113 case DBUS_TYPE_UINT16: 01114 *pos = _DBUS_ALIGN_VALUE (*pos, 2); 01115 *pos += 2; 01116 break; 01117 case DBUS_TYPE_BOOLEAN: 01118 case DBUS_TYPE_INT32: 01119 case DBUS_TYPE_UINT32: 01120 case DBUS_TYPE_UNIX_FD: 01121 *pos = _DBUS_ALIGN_VALUE (*pos, 4); 01122 *pos += 4; 01123 break; 01124 case DBUS_TYPE_INT64: 01125 case DBUS_TYPE_UINT64: 01126 case DBUS_TYPE_DOUBLE: 01127 *pos = _DBUS_ALIGN_VALUE (*pos, 8); 01128 *pos += 8; 01129 break; 01130 case DBUS_TYPE_STRING: 01131 case DBUS_TYPE_OBJECT_PATH: 01132 { 01133 int len; 01134 01135 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos); 01136 01137 *pos += len + 1; /* length plus nul */ 01138 } 01139 break; 01140 case DBUS_TYPE_SIGNATURE: 01141 { 01142 int len; 01143 01144 len = _dbus_string_get_byte (str, *pos); 01145 01146 *pos += len + 2; /* length byte plus length plus nul */ 01147 } 01148 break; 01149 default: 01150 _dbus_warn ("type %s not a basic type\n", 01151 _dbus_type_to_string (type)); 01152 _dbus_assert_not_reached ("not a basic type"); 01153 break; 01154 } 01155 } 01156 01166 void 01167 _dbus_marshal_skip_array (const DBusString *str, 01168 int element_type, 01169 int byte_order, 01170 int *pos) 01171 { 01172 dbus_uint32_t array_len; 01173 int i; 01174 int alignment; 01175 01176 i = _DBUS_ALIGN_VALUE (*pos, 4); 01177 01178 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i); 01179 01180 alignment = _dbus_type_get_alignment (element_type); 01181 01182 i = _DBUS_ALIGN_VALUE (i, alignment); 01183 01184 *pos = i + array_len; 01185 } 01186 01194 int 01195 _dbus_type_get_alignment (int typecode) 01196 { 01197 switch (typecode) 01198 { 01199 case DBUS_TYPE_BYTE: 01200 case DBUS_TYPE_VARIANT: 01201 case DBUS_TYPE_SIGNATURE: 01202 return 1; 01203 case DBUS_TYPE_INT16: 01204 case DBUS_TYPE_UINT16: 01205 return 2; 01206 case DBUS_TYPE_BOOLEAN: 01207 case DBUS_TYPE_INT32: 01208 case DBUS_TYPE_UINT32: 01209 case DBUS_TYPE_UNIX_FD: 01210 /* this stuff is 4 since it starts with a length */ 01211 case DBUS_TYPE_STRING: 01212 case DBUS_TYPE_OBJECT_PATH: 01213 case DBUS_TYPE_ARRAY: 01214 return 4; 01215 case DBUS_TYPE_INT64: 01216 case DBUS_TYPE_UINT64: 01217 case DBUS_TYPE_DOUBLE: 01218 /* struct is 8 since it could contain an 8-aligned item 01219 * and it's simpler to just always align structs to 8; 01220 * we want the amount of padding in a struct of a given 01221 * type to be predictable, not location-dependent. 01222 * DICT_ENTRY is always the same as struct. 01223 */ 01224 case DBUS_TYPE_STRUCT: 01225 case DBUS_TYPE_DICT_ENTRY: 01226 return 8; 01227 01228 default: 01229 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); 01230 return 0; 01231 } 01232 } 01233 01234 01243 dbus_bool_t 01244 _dbus_type_is_valid (int typecode) 01245 { 01246 switch (typecode) 01247 { 01248 case DBUS_TYPE_BYTE: 01249 case DBUS_TYPE_BOOLEAN: 01250 case DBUS_TYPE_INT16: 01251 case DBUS_TYPE_UINT16: 01252 case DBUS_TYPE_INT32: 01253 case DBUS_TYPE_UINT32: 01254 case DBUS_TYPE_INT64: 01255 case DBUS_TYPE_UINT64: 01256 case DBUS_TYPE_DOUBLE: 01257 case DBUS_TYPE_STRING: 01258 case DBUS_TYPE_OBJECT_PATH: 01259 case DBUS_TYPE_SIGNATURE: 01260 case DBUS_TYPE_ARRAY: 01261 case DBUS_TYPE_STRUCT: 01262 case DBUS_TYPE_DICT_ENTRY: 01263 case DBUS_TYPE_VARIANT: 01264 case DBUS_TYPE_UNIX_FD: 01265 return TRUE; 01266 01267 default: 01268 return FALSE; 01269 } 01270 } 01271 01278 const char * 01279 _dbus_type_to_string (int typecode) 01280 { 01281 switch (typecode) 01282 { 01283 case DBUS_TYPE_INVALID: 01284 return "invalid"; 01285 case DBUS_TYPE_BOOLEAN: 01286 return "boolean"; 01287 case DBUS_TYPE_BYTE: 01288 return "byte"; 01289 case DBUS_TYPE_INT16: 01290 return "int16"; 01291 case DBUS_TYPE_UINT16: 01292 return "uint16"; 01293 case DBUS_TYPE_INT32: 01294 return "int32"; 01295 case DBUS_TYPE_UINT32: 01296 return "uint32"; 01297 case DBUS_TYPE_INT64: 01298 return "int64"; 01299 case DBUS_TYPE_UINT64: 01300 return "uint64"; 01301 case DBUS_TYPE_DOUBLE: 01302 return "double"; 01303 case DBUS_TYPE_STRING: 01304 return "string"; 01305 case DBUS_TYPE_OBJECT_PATH: 01306 return "object_path"; 01307 case DBUS_TYPE_SIGNATURE: 01308 return "signature"; 01309 case DBUS_TYPE_STRUCT: 01310 return "struct"; 01311 case DBUS_TYPE_DICT_ENTRY: 01312 return "dict_entry"; 01313 case DBUS_TYPE_ARRAY: 01314 return "array"; 01315 case DBUS_TYPE_VARIANT: 01316 return "variant"; 01317 case DBUS_STRUCT_BEGIN_CHAR: 01318 return "begin_struct"; 01319 case DBUS_STRUCT_END_CHAR: 01320 return "end_struct"; 01321 case DBUS_DICT_ENTRY_BEGIN_CHAR: 01322 return "begin_dict_entry"; 01323 case DBUS_DICT_ENTRY_END_CHAR: 01324 return "end_dict_entry"; 01325 case DBUS_TYPE_UNIX_FD: 01326 return "unix_fd"; 01327 default: 01328 return "unknown"; 01329 } 01330 } 01331 01339 void 01340 _dbus_verbose_bytes (const unsigned char *data, 01341 int len, 01342 int offset) 01343 { 01344 int i; 01345 const unsigned char *aligned; 01346 01347 _dbus_assert (len >= 0); 01348 01349 if (!_dbus_is_verbose()) 01350 return; 01351 01352 /* Print blanks on first row if appropriate */ 01353 aligned = _DBUS_ALIGN_ADDRESS (data, 4); 01354 if (aligned > data) 01355 aligned -= 4; 01356 _dbus_assert (aligned <= data); 01357 01358 if (aligned != data) 01359 { 01360 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned); 01361 while (aligned != data) 01362 { 01363 _dbus_verbose (" "); 01364 ++aligned; 01365 } 01366 } 01367 01368 /* now print the bytes */ 01369 i = 0; 01370 while (i < len) 01371 { 01372 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01373 { 01374 _dbus_verbose ("%4d\t%p: ", 01375 offset + i, &data[i]); 01376 } 01377 01378 if (data[i] >= 32 && 01379 data[i] <= 126) 01380 _dbus_verbose (" '%c' ", data[i]); 01381 else 01382 _dbus_verbose ("0x%s%x ", 01383 data[i] <= 0xf ? "0" : "", data[i]); 01384 01385 ++i; 01386 01387 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01388 { 01389 if (i > 3) 01390 _dbus_verbose ("BE: %d LE: %d", 01391 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), 01392 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); 01393 01394 if (i > 7 && 01395 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) 01396 { 01397 #ifdef DBUS_INT64_PRINTF_MODIFIER 01398 _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x", 01399 *(dbus_uint64_t*)&data[i-8]); 01400 #endif 01401 _dbus_verbose (" dbl: %g", 01402 *(double*)&data[i-8]); 01403 } 01404 01405 _dbus_verbose ("\n"); 01406 } 01407 } 01408 01409 _dbus_verbose ("\n"); 01410 } 01411 01419 void 01420 _dbus_verbose_bytes_of_string (const DBusString *str, 01421 int start, 01422 int len) 01423 { 01424 const char *d; 01425 int real_len; 01426 01427 real_len = _dbus_string_get_length (str); 01428 01429 _dbus_assert (start >= 0); 01430 01431 if (start > real_len) 01432 { 01433 _dbus_verbose (" [%d,%d) is not inside string of length %d\n", 01434 start, len, real_len); 01435 return; 01436 } 01437 01438 if ((start + len) > real_len) 01439 { 01440 _dbus_verbose (" [%d,%d) extends outside string of length %d\n", 01441 start, len, real_len); 01442 len = real_len - start; 01443 } 01444 01445 d = _dbus_string_get_const_data_len (str, start, len); 01446 01447 _dbus_verbose_bytes (d, len, start); 01448 } 01449 01450 static int 01451 map_type_char_to_type (int t) 01452 { 01453 if (t == DBUS_STRUCT_BEGIN_CHAR) 01454 return DBUS_TYPE_STRUCT; 01455 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR) 01456 return DBUS_TYPE_DICT_ENTRY; 01457 else 01458 { 01459 _dbus_assert (t != DBUS_STRUCT_END_CHAR); 01460 _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR); 01461 return t; 01462 } 01463 } 01464 01475 int 01476 _dbus_first_type_in_signature (const DBusString *str, 01477 int pos) 01478 { 01479 return map_type_char_to_type (_dbus_string_get_byte (str, pos)); 01480 } 01481 01490 int 01491 _dbus_first_type_in_signature_c_str (const char *str, 01492 int pos) 01493 { 01494 return map_type_char_to_type (str[pos]); 01495 } 01496 01499 #ifdef DBUS_BUILD_TESTS 01500 #include "dbus-test.h" 01501 #include <stdio.h> 01502 01521 void 01522 _dbus_marshal_read_fixed_multi (const DBusString *str, 01523 int pos, 01524 int element_type, 01525 void *value, 01526 int n_elements, 01527 int byte_order, 01528 int *new_pos) 01529 { 01530 int array_len; 01531 int alignment; 01532 01533 _dbus_assert (dbus_type_is_fixed (element_type)); 01534 _dbus_assert (dbus_type_is_basic (element_type)); 01535 01536 #if 0 01537 _dbus_verbose ("reading %d elements of %s\n", 01538 n_elements, _dbus_type_to_string (element_type)); 01539 #endif 01540 01541 alignment = _dbus_type_get_alignment (element_type); 01542 01543 pos = _DBUS_ALIGN_VALUE (pos, alignment); 01544 01545 array_len = n_elements * alignment; 01546 01547 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len); 01548 if (new_pos) 01549 *new_pos = pos + array_len; 01550 } 01551 01552 static void 01553 swap_test_array (void *array, 01554 int len_bytes, 01555 int byte_order, 01556 int alignment) 01557 { 01558 DBusString t; 01559 01560 if (alignment == 1) 01561 return; 01562 01563 _dbus_string_init_const_len (&t, array, len_bytes); 01564 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment); 01565 } 01566 01567 #define MARSHAL_BASIC(typename, byte_order, literal) \ 01568 do { \ 01569 v_##typename = literal; \ 01570 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \ 01571 &v_##typename, \ 01572 byte_order, NULL)) \ 01573 _dbus_assert_not_reached ("no memory"); \ 01574 } while (0) 01575 01576 #define DEMARSHAL_BASIC(typename, byte_order) \ 01577 do { \ 01578 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \ 01579 byte_order, &pos); \ 01580 } while (0) 01581 01582 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \ 01583 do { \ 01584 DEMARSHAL_BASIC (typename, byte_order); \ 01585 if (literal != v_##typename) \ 01586 { \ 01587 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01588 _dbus_string_get_length (&str) - dump_pos); \ 01589 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01590 } \ 01591 } while (0) 01592 01593 #define MARSHAL_TEST(typename, byte_order, literal) \ 01594 do { \ 01595 MARSHAL_BASIC (typename, byte_order, literal); \ 01596 dump_pos = pos; \ 01597 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \ 01598 } while (0) 01599 01600 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \ 01601 do { \ 01602 MARSHAL_BASIC (typename, byte_order, literal); \ 01603 dump_pos = pos; \ 01604 DEMARSHAL_BASIC (typename, byte_order); \ 01605 if (strcmp (literal, v_##typename) != 0) \ 01606 { \ 01607 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01608 _dbus_string_get_length (&str) - dump_pos); \ 01609 _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \ 01610 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01611 } \ 01612 } while (0) 01613 01614 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \ 01615 do { \ 01616 int next; \ 01617 v_UINT32 = sizeof(literal); \ 01618 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \ 01619 byte_order, &next)) \ 01620 _dbus_assert_not_reached ("no memory"); \ 01621 v_ARRAY_##typename = literal; \ 01622 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \ 01623 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \ 01624 byte_order, NULL)) \ 01625 _dbus_assert_not_reached ("no memory"); \ 01626 } while (0) 01627 01628 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \ 01629 do { \ 01630 int next; \ 01631 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \ 01632 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \ 01633 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \ 01634 v_UINT32/alignment, \ 01635 byte_order, NULL); \ 01636 swap_test_array (v_ARRAY_##typename, v_UINT32, \ 01637 byte_order, alignment); \ 01638 } while (0) 01639 01640 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \ 01641 do { \ 01642 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \ 01643 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0)) \ 01644 { \ 01645 _dbus_verbose ("MARSHALED DATA\n"); \ 01646 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01647 _dbus_string_get_length (&str) - dump_pos); \ 01648 _dbus_verbose ("LITERAL DATA\n"); \ 01649 _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \ 01650 _dbus_verbose ("READ DATA\n"); \ 01651 _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \ 01652 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \ 01653 } \ 01654 } while (0) 01655 01656 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \ 01657 do { \ 01658 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \ 01659 dump_pos = pos; \ 01660 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \ 01661 } while (0) 01662 01663 dbus_bool_t 01664 _dbus_marshal_test (void) 01665 { 01666 int alignment; 01667 DBusString str; 01668 int pos, dump_pos; 01669 unsigned char array1[5] = { 3, 4, 0, 1, 9 }; 01670 dbus_int16_t array2[3] = { 124, 457, 780 }; 01671 dbus_int32_t array4[3] = { 123, 456, 789 }; 01672 #ifdef DBUS_HAVE_INT64 01673 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 01674 DBUS_INT64_CONSTANT (0x456ffffffff), 01675 DBUS_INT64_CONSTANT (0x789ffffffff) }; 01676 dbus_int64_t *v_ARRAY_INT64; 01677 #endif 01678 unsigned char *v_ARRAY_BYTE; 01679 dbus_int16_t *v_ARRAY_INT16; 01680 dbus_uint16_t *v_ARRAY_UINT16; 01681 dbus_int32_t *v_ARRAY_INT32; 01682 dbus_uint32_t *v_ARRAY_UINT32; 01683 DBusString t; 01684 double v_DOUBLE; 01685 double t_DOUBLE; 01686 dbus_int16_t v_INT16; 01687 dbus_uint16_t v_UINT16; 01688 dbus_int32_t v_INT32; 01689 dbus_uint32_t v_UINT32; 01690 dbus_int64_t v_INT64; 01691 dbus_uint64_t v_UINT64; 01692 unsigned char v_BYTE; 01693 dbus_bool_t v_BOOLEAN; 01694 const char *v_STRING; 01695 const char *v_SIGNATURE; 01696 const char *v_OBJECT_PATH; 01697 int byte_order; 01698 01699 if (!_dbus_string_init (&str)) 01700 _dbus_assert_not_reached ("failed to init string"); 01701 01702 pos = 0; 01703 01704 /* Marshal doubles */ 01705 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14); 01706 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN); 01707 t_DOUBLE = 3.14; 01708 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01709 _dbus_assert_not_reached ("got wrong double value"); 01710 01711 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14); 01712 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN); 01713 t_DOUBLE = 3.14; 01714 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01715 _dbus_assert_not_reached ("got wrong double value"); 01716 01717 /* Marshal signed 16 integers */ 01718 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345); 01719 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345); 01720 01721 /* Marshal unsigned 16 integers */ 01722 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234); 01723 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234); 01724 01725 /* Marshal signed integers */ 01726 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678); 01727 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678); 01728 01729 /* Marshal unsigned integers */ 01730 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678); 01731 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678); 01732 01733 #ifdef DBUS_HAVE_INT64 01734 /* Marshal signed integers */ 01735 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01736 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01737 01738 /* Marshal unsigned integers */ 01739 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01740 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01741 #endif /* DBUS_HAVE_INT64 */ 01742 01743 /* Marshal byte */ 01744 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5); 01745 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5); 01746 01747 /* Marshal all possible bools! */ 01748 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE); 01749 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE); 01750 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE); 01751 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE); 01752 01753 /* Marshal strings */ 01754 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, ""); 01755 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, ""); 01756 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string"); 01757 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string"); 01758 01759 /* object paths */ 01760 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c"); 01761 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c"); 01762 01763 /* signatures */ 01764 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, ""); 01765 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, ""); 01766 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)"); 01767 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)"); 01768 01769 /* Arrays */ 01770 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2); 01771 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2); 01772 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2); 01773 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2); 01774 01775 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4); 01776 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4); 01777 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4); 01778 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4); 01779 01780 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1); 01781 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1); 01782 01783 #ifdef DBUS_HAVE_INT64 01784 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8); 01785 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8); 01786 #endif 01787 01788 #if 0 01789 01790 /* 01791 * FIXME restore the set/pack tests 01792 */ 01793 01794 #ifdef DBUS_HAVE_INT64 01795 /* set/pack 64-bit integers */ 01796 _dbus_string_set_length (&str, 8); 01797 01798 /* signed little */ 01799 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN, 01800 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01801 01802 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01803 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01804 _dbus_string_get_const_data (&str))); 01805 01806 /* signed big */ 01807 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN, 01808 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01809 01810 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01811 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01812 _dbus_string_get_const_data (&str))); 01813 01814 /* signed little pack */ 01815 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01816 DBUS_LITTLE_ENDIAN, 01817 _dbus_string_get_data (&str)); 01818 01819 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01820 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01821 _dbus_string_get_const_data (&str))); 01822 01823 /* signed big pack */ 01824 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01825 DBUS_BIG_ENDIAN, 01826 _dbus_string_get_data (&str)); 01827 01828 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01829 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01830 _dbus_string_get_const_data (&str))); 01831 01832 /* unsigned little */ 01833 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN, 01834 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01835 01836 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01837 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01838 _dbus_string_get_const_data (&str))); 01839 01840 /* unsigned big */ 01841 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN, 01842 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01843 01844 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01845 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01846 _dbus_string_get_const_data (&str))); 01847 01848 /* unsigned little pack */ 01849 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01850 DBUS_LITTLE_ENDIAN, 01851 _dbus_string_get_data (&str)); 01852 01853 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01854 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01855 _dbus_string_get_const_data (&str))); 01856 01857 /* unsigned big pack */ 01858 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01859 DBUS_BIG_ENDIAN, 01860 _dbus_string_get_data (&str)); 01861 01862 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01863 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01864 _dbus_string_get_const_data (&str))); 01865 #endif /* DBUS_HAVE_INT64 */ 01866 01867 /* set/pack 32-bit integers */ 01868 _dbus_string_set_length (&str, 4); 01869 01870 /* signed little */ 01871 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN, 01872 0, -0x123456); 01873 01874 _dbus_assert (-0x123456 == 01875 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01876 _dbus_string_get_const_data (&str))); 01877 01878 /* signed big */ 01879 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN, 01880 0, -0x123456); 01881 01882 _dbus_assert (-0x123456 == 01883 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01884 _dbus_string_get_const_data (&str))); 01885 01886 /* signed little pack */ 01887 _dbus_pack_int32 (-0x123456, 01888 DBUS_LITTLE_ENDIAN, 01889 _dbus_string_get_data (&str)); 01890 01891 _dbus_assert (-0x123456 == 01892 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01893 _dbus_string_get_const_data (&str))); 01894 01895 /* signed big pack */ 01896 _dbus_pack_int32 (-0x123456, 01897 DBUS_BIG_ENDIAN, 01898 _dbus_string_get_data (&str)); 01899 01900 _dbus_assert (-0x123456 == 01901 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01902 _dbus_string_get_const_data (&str))); 01903 01904 /* unsigned little */ 01905 _dbus_marshal_set_uint32 (&str, 01906 0, 0x123456, 01907 DBUS_LITTLE_ENDIAN); 01908 01909 _dbus_assert (0x123456 == 01910 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01911 _dbus_string_get_const_data (&str))); 01912 01913 /* unsigned big */ 01914 _dbus_marshal_set_uint32 (&str, 01915 0, 0x123456, 01916 DBUS_BIG_ENDIAN); 01917 01918 _dbus_assert (0x123456 == 01919 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01920 _dbus_string_get_const_data (&str))); 01921 01922 /* unsigned little pack */ 01923 _dbus_pack_uint32 (0x123456, 01924 DBUS_LITTLE_ENDIAN, 01925 _dbus_string_get_data (&str)); 01926 01927 _dbus_assert (0x123456 == 01928 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01929 _dbus_string_get_const_data (&str))); 01930 01931 /* unsigned big pack */ 01932 _dbus_pack_uint32 (0x123456, 01933 DBUS_BIG_ENDIAN, 01934 _dbus_string_get_data (&str)); 01935 01936 _dbus_assert (0x123456 == 01937 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01938 _dbus_string_get_const_data (&str))); 01939 01940 #endif /* set/pack tests for integers */ 01941 01942 /* Strings in-place set */ 01943 byte_order = DBUS_LITTLE_ENDIAN; 01944 while (TRUE) 01945 { 01946 /* Init a string */ 01947 _dbus_string_set_length (&str, 0); 01948 01949 /* reset pos for the macros */ 01950 pos = 0; 01951 01952 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world"); 01953 01954 /* Set it to something longer */ 01955 _dbus_string_init_const (&t, "Hello world foo"); 01956 01957 v_STRING = _dbus_string_get_const_data (&t); 01958 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01959 &v_STRING, byte_order, NULL, NULL); 01960 01961 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01962 &v_STRING, byte_order, 01963 NULL); 01964 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0); 01965 01966 /* Set it to something shorter */ 01967 _dbus_string_init_const (&t, "Hello"); 01968 01969 v_STRING = _dbus_string_get_const_data (&t); 01970 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01971 &v_STRING, byte_order, NULL, NULL); 01972 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01973 &v_STRING, byte_order, 01974 NULL); 01975 _dbus_assert (strcmp (v_STRING, "Hello") == 0); 01976 01977 /* Do the other byte order */ 01978 if (byte_order == DBUS_LITTLE_ENDIAN) 01979 byte_order = DBUS_BIG_ENDIAN; 01980 else 01981 break; 01982 } 01983 01984 /* Clean up */ 01985 _dbus_string_free (&str); 01986 01987 return TRUE; 01988 } 01989 01990 #endif /* DBUS_BUILD_TESTS */