D-Bus 1.4.1
|
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 /* FIXME: we canonicalize to 0 or 1 for the single boolean case 01069 * should we here too ? */ 01070 case DBUS_TYPE_BOOLEAN: 01071 case DBUS_TYPE_INT32: 01072 case DBUS_TYPE_UINT32: 01073 case DBUS_TYPE_UNIX_FD: 01074 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after); 01075 break; 01076 case DBUS_TYPE_INT64: 01077 case DBUS_TYPE_UINT64: 01078 case DBUS_TYPE_DOUBLE: 01079 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after); 01080 break; 01081 01082 default: 01083 _dbus_assert_not_reached ("non fixed type in array write"); 01084 break; 01085 } 01086 01087 return FALSE; 01088 } 01089 01090 01100 void 01101 _dbus_marshal_skip_basic (const DBusString *str, 01102 int type, 01103 int byte_order, 01104 int *pos) 01105 { 01106 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 01107 byte_order == DBUS_BIG_ENDIAN); 01108 01109 switch (type) 01110 { 01111 case DBUS_TYPE_BYTE: 01112 (*pos)++; 01113 break; 01114 case DBUS_TYPE_INT16: 01115 case DBUS_TYPE_UINT16: 01116 *pos = _DBUS_ALIGN_VALUE (*pos, 2); 01117 *pos += 2; 01118 break; 01119 case DBUS_TYPE_BOOLEAN: 01120 case DBUS_TYPE_INT32: 01121 case DBUS_TYPE_UINT32: 01122 case DBUS_TYPE_UNIX_FD: 01123 *pos = _DBUS_ALIGN_VALUE (*pos, 4); 01124 *pos += 4; 01125 break; 01126 case DBUS_TYPE_INT64: 01127 case DBUS_TYPE_UINT64: 01128 case DBUS_TYPE_DOUBLE: 01129 *pos = _DBUS_ALIGN_VALUE (*pos, 8); 01130 *pos += 8; 01131 break; 01132 case DBUS_TYPE_STRING: 01133 case DBUS_TYPE_OBJECT_PATH: 01134 { 01135 int len; 01136 01137 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos); 01138 01139 *pos += len + 1; /* length plus nul */ 01140 } 01141 break; 01142 case DBUS_TYPE_SIGNATURE: 01143 { 01144 int len; 01145 01146 len = _dbus_string_get_byte (str, *pos); 01147 01148 *pos += len + 2; /* length byte plus length plus nul */ 01149 } 01150 break; 01151 default: 01152 _dbus_warn ("type %s not a basic type\n", 01153 _dbus_type_to_string (type)); 01154 _dbus_assert_not_reached ("not a basic type"); 01155 break; 01156 } 01157 } 01158 01168 void 01169 _dbus_marshal_skip_array (const DBusString *str, 01170 int element_type, 01171 int byte_order, 01172 int *pos) 01173 { 01174 dbus_uint32_t array_len; 01175 int i; 01176 int alignment; 01177 01178 i = _DBUS_ALIGN_VALUE (*pos, 4); 01179 01180 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i); 01181 01182 alignment = _dbus_type_get_alignment (element_type); 01183 01184 i = _DBUS_ALIGN_VALUE (i, alignment); 01185 01186 *pos = i + array_len; 01187 } 01188 01196 int 01197 _dbus_type_get_alignment (int typecode) 01198 { 01199 switch (typecode) 01200 { 01201 case DBUS_TYPE_BYTE: 01202 case DBUS_TYPE_VARIANT: 01203 case DBUS_TYPE_SIGNATURE: 01204 return 1; 01205 case DBUS_TYPE_INT16: 01206 case DBUS_TYPE_UINT16: 01207 return 2; 01208 case DBUS_TYPE_BOOLEAN: 01209 case DBUS_TYPE_INT32: 01210 case DBUS_TYPE_UINT32: 01211 case DBUS_TYPE_UNIX_FD: 01212 /* this stuff is 4 since it starts with a length */ 01213 case DBUS_TYPE_STRING: 01214 case DBUS_TYPE_OBJECT_PATH: 01215 case DBUS_TYPE_ARRAY: 01216 return 4; 01217 case DBUS_TYPE_INT64: 01218 case DBUS_TYPE_UINT64: 01219 case DBUS_TYPE_DOUBLE: 01220 /* struct is 8 since it could contain an 8-aligned item 01221 * and it's simpler to just always align structs to 8; 01222 * we want the amount of padding in a struct of a given 01223 * type to be predictable, not location-dependent. 01224 * DICT_ENTRY is always the same as struct. 01225 */ 01226 case DBUS_TYPE_STRUCT: 01227 case DBUS_TYPE_DICT_ENTRY: 01228 return 8; 01229 01230 default: 01231 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); 01232 return 0; 01233 } 01234 } 01235 01236 01245 dbus_bool_t 01246 _dbus_type_is_valid (int typecode) 01247 { 01248 switch (typecode) 01249 { 01250 case DBUS_TYPE_BYTE: 01251 case DBUS_TYPE_BOOLEAN: 01252 case DBUS_TYPE_INT16: 01253 case DBUS_TYPE_UINT16: 01254 case DBUS_TYPE_INT32: 01255 case DBUS_TYPE_UINT32: 01256 case DBUS_TYPE_INT64: 01257 case DBUS_TYPE_UINT64: 01258 case DBUS_TYPE_DOUBLE: 01259 case DBUS_TYPE_STRING: 01260 case DBUS_TYPE_OBJECT_PATH: 01261 case DBUS_TYPE_SIGNATURE: 01262 case DBUS_TYPE_ARRAY: 01263 case DBUS_TYPE_STRUCT: 01264 case DBUS_TYPE_DICT_ENTRY: 01265 case DBUS_TYPE_VARIANT: 01266 case DBUS_TYPE_UNIX_FD: 01267 return TRUE; 01268 01269 default: 01270 return FALSE; 01271 } 01272 } 01273 01280 const char * 01281 _dbus_type_to_string (int typecode) 01282 { 01283 switch (typecode) 01284 { 01285 case DBUS_TYPE_INVALID: 01286 return "invalid"; 01287 case DBUS_TYPE_BOOLEAN: 01288 return "boolean"; 01289 case DBUS_TYPE_BYTE: 01290 return "byte"; 01291 case DBUS_TYPE_INT16: 01292 return "int16"; 01293 case DBUS_TYPE_UINT16: 01294 return "uint16"; 01295 case DBUS_TYPE_INT32: 01296 return "int32"; 01297 case DBUS_TYPE_UINT32: 01298 return "uint32"; 01299 case DBUS_TYPE_INT64: 01300 return "int64"; 01301 case DBUS_TYPE_UINT64: 01302 return "uint64"; 01303 case DBUS_TYPE_DOUBLE: 01304 return "double"; 01305 case DBUS_TYPE_STRING: 01306 return "string"; 01307 case DBUS_TYPE_OBJECT_PATH: 01308 return "object_path"; 01309 case DBUS_TYPE_SIGNATURE: 01310 return "signature"; 01311 case DBUS_TYPE_STRUCT: 01312 return "struct"; 01313 case DBUS_TYPE_DICT_ENTRY: 01314 return "dict_entry"; 01315 case DBUS_TYPE_ARRAY: 01316 return "array"; 01317 case DBUS_TYPE_VARIANT: 01318 return "variant"; 01319 case DBUS_STRUCT_BEGIN_CHAR: 01320 return "begin_struct"; 01321 case DBUS_STRUCT_END_CHAR: 01322 return "end_struct"; 01323 case DBUS_DICT_ENTRY_BEGIN_CHAR: 01324 return "begin_dict_entry"; 01325 case DBUS_DICT_ENTRY_END_CHAR: 01326 return "end_dict_entry"; 01327 case DBUS_TYPE_UNIX_FD: 01328 return "unix_fd"; 01329 default: 01330 return "unknown"; 01331 } 01332 } 01333 01341 void 01342 _dbus_verbose_bytes (const unsigned char *data, 01343 int len, 01344 int offset) 01345 { 01346 int i; 01347 const unsigned char *aligned; 01348 01349 _dbus_assert (len >= 0); 01350 01351 if (!_dbus_is_verbose()) 01352 return; 01353 01354 /* Print blanks on first row if appropriate */ 01355 aligned = _DBUS_ALIGN_ADDRESS (data, 4); 01356 if (aligned > data) 01357 aligned -= 4; 01358 _dbus_assert (aligned <= data); 01359 01360 if (aligned != data) 01361 { 01362 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned); 01363 while (aligned != data) 01364 { 01365 _dbus_verbose (" "); 01366 ++aligned; 01367 } 01368 } 01369 01370 /* now print the bytes */ 01371 i = 0; 01372 while (i < len) 01373 { 01374 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01375 { 01376 _dbus_verbose ("%4d\t%p: ", 01377 offset + i, &data[i]); 01378 } 01379 01380 if (data[i] >= 32 && 01381 data[i] <= 126) 01382 _dbus_verbose (" '%c' ", data[i]); 01383 else 01384 _dbus_verbose ("0x%s%x ", 01385 data[i] <= 0xf ? "0" : "", data[i]); 01386 01387 ++i; 01388 01389 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 01390 { 01391 if (i > 3) 01392 _dbus_verbose ("BE: %d LE: %d", 01393 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), 01394 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); 01395 01396 if (i > 7 && 01397 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) 01398 { 01399 #ifdef DBUS_INT64_PRINTF_MODIFIER 01400 _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x", 01401 *(dbus_uint64_t*)&data[i-8]); 01402 #endif 01403 _dbus_verbose (" dbl: %g", 01404 *(double*)&data[i-8]); 01405 } 01406 01407 _dbus_verbose ("\n"); 01408 } 01409 } 01410 01411 _dbus_verbose ("\n"); 01412 } 01413 01421 void 01422 _dbus_verbose_bytes_of_string (const DBusString *str, 01423 int start, 01424 int len) 01425 { 01426 const char *d; 01427 int real_len; 01428 01429 real_len = _dbus_string_get_length (str); 01430 01431 _dbus_assert (start >= 0); 01432 01433 if (start > real_len) 01434 { 01435 _dbus_verbose (" [%d,%d) is not inside string of length %d\n", 01436 start, len, real_len); 01437 return; 01438 } 01439 01440 if ((start + len) > real_len) 01441 { 01442 _dbus_verbose (" [%d,%d) extends outside string of length %d\n", 01443 start, len, real_len); 01444 len = real_len - start; 01445 } 01446 01447 d = _dbus_string_get_const_data_len (str, start, len); 01448 01449 _dbus_verbose_bytes (d, len, start); 01450 } 01451 01452 static int 01453 map_type_char_to_type (int t) 01454 { 01455 if (t == DBUS_STRUCT_BEGIN_CHAR) 01456 return DBUS_TYPE_STRUCT; 01457 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR) 01458 return DBUS_TYPE_DICT_ENTRY; 01459 else 01460 { 01461 _dbus_assert (t != DBUS_STRUCT_END_CHAR); 01462 _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR); 01463 return t; 01464 } 01465 } 01466 01477 int 01478 _dbus_first_type_in_signature (const DBusString *str, 01479 int pos) 01480 { 01481 return map_type_char_to_type (_dbus_string_get_byte (str, pos)); 01482 } 01483 01492 int 01493 _dbus_first_type_in_signature_c_str (const char *str, 01494 int pos) 01495 { 01496 return map_type_char_to_type (str[pos]); 01497 } 01498 01501 #ifdef DBUS_BUILD_TESTS 01502 #include "dbus-test.h" 01503 #include <stdio.h> 01504 01523 void 01524 _dbus_marshal_read_fixed_multi (const DBusString *str, 01525 int pos, 01526 int element_type, 01527 void *value, 01528 int n_elements, 01529 int byte_order, 01530 int *new_pos) 01531 { 01532 int array_len; 01533 int alignment; 01534 01535 _dbus_assert (dbus_type_is_fixed (element_type)); 01536 _dbus_assert (dbus_type_is_basic (element_type)); 01537 01538 #if 0 01539 _dbus_verbose ("reading %d elements of %s\n", 01540 n_elements, _dbus_type_to_string (element_type)); 01541 #endif 01542 01543 alignment = _dbus_type_get_alignment (element_type); 01544 01545 pos = _DBUS_ALIGN_VALUE (pos, alignment); 01546 01547 array_len = n_elements * alignment; 01548 01549 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len); 01550 if (new_pos) 01551 *new_pos = pos + array_len; 01552 } 01553 01554 static void 01555 swap_test_array (void *array, 01556 int len_bytes, 01557 int byte_order, 01558 int alignment) 01559 { 01560 DBusString t; 01561 01562 if (alignment == 1) 01563 return; 01564 01565 _dbus_string_init_const_len (&t, array, len_bytes); 01566 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment); 01567 } 01568 01569 #define MARSHAL_BASIC(typename, byte_order, literal) \ 01570 do { \ 01571 v_##typename = literal; \ 01572 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \ 01573 &v_##typename, \ 01574 byte_order, NULL)) \ 01575 _dbus_assert_not_reached ("no memory"); \ 01576 } while (0) 01577 01578 #define DEMARSHAL_BASIC(typename, byte_order) \ 01579 do { \ 01580 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \ 01581 byte_order, &pos); \ 01582 } while (0) 01583 01584 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \ 01585 do { \ 01586 DEMARSHAL_BASIC (typename, byte_order); \ 01587 if (literal != v_##typename) \ 01588 { \ 01589 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01590 _dbus_string_get_length (&str) - dump_pos); \ 01591 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01592 } \ 01593 } while (0) 01594 01595 #define MARSHAL_TEST(typename, byte_order, literal) \ 01596 do { \ 01597 MARSHAL_BASIC (typename, byte_order, literal); \ 01598 dump_pos = pos; \ 01599 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \ 01600 } while (0) 01601 01602 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \ 01603 do { \ 01604 MARSHAL_BASIC (typename, byte_order, literal); \ 01605 dump_pos = pos; \ 01606 DEMARSHAL_BASIC (typename, byte_order); \ 01607 if (strcmp (literal, v_##typename) != 0) \ 01608 { \ 01609 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01610 _dbus_string_get_length (&str) - dump_pos); \ 01611 _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \ 01612 _dbus_assert_not_reached ("demarshaled wrong value"); \ 01613 } \ 01614 } while (0) 01615 01616 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \ 01617 do { \ 01618 int next; \ 01619 v_UINT32 = sizeof(literal); \ 01620 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \ 01621 byte_order, &next)) \ 01622 _dbus_assert_not_reached ("no memory"); \ 01623 v_ARRAY_##typename = literal; \ 01624 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \ 01625 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \ 01626 byte_order, NULL)) \ 01627 _dbus_assert_not_reached ("no memory"); \ 01628 } while (0) 01629 01630 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \ 01631 do { \ 01632 int next; \ 01633 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \ 01634 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \ 01635 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \ 01636 v_UINT32/alignment, \ 01637 byte_order, NULL); \ 01638 swap_test_array (v_ARRAY_##typename, v_UINT32, \ 01639 byte_order, alignment); \ 01640 } while (0) 01641 01642 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \ 01643 do { \ 01644 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \ 01645 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0)) \ 01646 { \ 01647 _dbus_verbose ("MARSHALED DATA\n"); \ 01648 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 01649 _dbus_string_get_length (&str) - dump_pos); \ 01650 _dbus_verbose ("LITERAL DATA\n"); \ 01651 _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \ 01652 _dbus_verbose ("READ DATA\n"); \ 01653 _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \ 01654 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \ 01655 } \ 01656 } while (0) 01657 01658 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \ 01659 do { \ 01660 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \ 01661 dump_pos = pos; \ 01662 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \ 01663 } while (0) 01664 01665 dbus_bool_t 01666 _dbus_marshal_test (void) 01667 { 01668 int alignment; 01669 DBusString str; 01670 int pos, dump_pos; 01671 unsigned char array1[5] = { 3, 4, 0, 1, 9 }; 01672 dbus_int16_t array2[3] = { 124, 457, 780 }; 01673 dbus_int32_t array4[3] = { 123, 456, 789 }; 01674 #ifdef DBUS_HAVE_INT64 01675 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 01676 DBUS_INT64_CONSTANT (0x456ffffffff), 01677 DBUS_INT64_CONSTANT (0x789ffffffff) }; 01678 dbus_int64_t *v_ARRAY_INT64; 01679 #endif 01680 unsigned char *v_ARRAY_BYTE; 01681 dbus_int16_t *v_ARRAY_INT16; 01682 dbus_uint16_t *v_ARRAY_UINT16; 01683 dbus_int32_t *v_ARRAY_INT32; 01684 dbus_uint32_t *v_ARRAY_UINT32; 01685 DBusString t; 01686 double v_DOUBLE; 01687 double t_DOUBLE; 01688 dbus_int16_t v_INT16; 01689 dbus_uint16_t v_UINT16; 01690 dbus_int32_t v_INT32; 01691 dbus_uint32_t v_UINT32; 01692 dbus_int64_t v_INT64; 01693 dbus_uint64_t v_UINT64; 01694 unsigned char v_BYTE; 01695 dbus_bool_t v_BOOLEAN; 01696 const char *v_STRING; 01697 const char *v_SIGNATURE; 01698 const char *v_OBJECT_PATH; 01699 int byte_order; 01700 01701 if (!_dbus_string_init (&str)) 01702 _dbus_assert_not_reached ("failed to init string"); 01703 01704 pos = 0; 01705 01706 /* Marshal doubles */ 01707 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14); 01708 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN); 01709 t_DOUBLE = 3.14; 01710 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01711 _dbus_assert_not_reached ("got wrong double value"); 01712 01713 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14); 01714 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN); 01715 t_DOUBLE = 3.14; 01716 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 01717 _dbus_assert_not_reached ("got wrong double value"); 01718 01719 /* Marshal signed 16 integers */ 01720 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345); 01721 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345); 01722 01723 /* Marshal unsigned 16 integers */ 01724 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234); 01725 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234); 01726 01727 /* Marshal signed integers */ 01728 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678); 01729 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678); 01730 01731 /* Marshal unsigned integers */ 01732 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678); 01733 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678); 01734 01735 #ifdef DBUS_HAVE_INT64 01736 /* Marshal signed integers */ 01737 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01738 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01739 01740 /* Marshal unsigned integers */ 01741 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01742 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01743 #endif /* DBUS_HAVE_INT64 */ 01744 01745 /* Marshal byte */ 01746 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5); 01747 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5); 01748 01749 /* Marshal all possible bools! */ 01750 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE); 01751 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE); 01752 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE); 01753 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE); 01754 01755 /* Marshal strings */ 01756 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, ""); 01757 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, ""); 01758 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string"); 01759 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string"); 01760 01761 /* object paths */ 01762 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c"); 01763 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c"); 01764 01765 /* signatures */ 01766 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, ""); 01767 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, ""); 01768 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)"); 01769 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)"); 01770 01771 /* Arrays */ 01772 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2); 01773 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2); 01774 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2); 01775 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2); 01776 01777 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4); 01778 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4); 01779 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4); 01780 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4); 01781 01782 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1); 01783 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1); 01784 01785 #ifdef DBUS_HAVE_INT64 01786 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8); 01787 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8); 01788 #endif 01789 01790 #if 0 01791 01792 /* 01793 * FIXME restore the set/pack tests 01794 */ 01795 01796 #ifdef DBUS_HAVE_INT64 01797 /* set/pack 64-bit integers */ 01798 _dbus_string_set_length (&str, 8); 01799 01800 /* signed little */ 01801 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN, 01802 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01803 01804 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01805 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01806 _dbus_string_get_const_data (&str))); 01807 01808 /* signed big */ 01809 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN, 01810 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 01811 01812 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01813 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01814 _dbus_string_get_const_data (&str))); 01815 01816 /* signed little pack */ 01817 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01818 DBUS_LITTLE_ENDIAN, 01819 _dbus_string_get_data (&str)); 01820 01821 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01822 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 01823 _dbus_string_get_const_data (&str))); 01824 01825 /* signed big pack */ 01826 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 01827 DBUS_BIG_ENDIAN, 01828 _dbus_string_get_data (&str)); 01829 01830 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 01831 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 01832 _dbus_string_get_const_data (&str))); 01833 01834 /* unsigned little */ 01835 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN, 01836 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01837 01838 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01839 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01840 _dbus_string_get_const_data (&str))); 01841 01842 /* unsigned big */ 01843 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN, 01844 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 01845 01846 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01847 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01848 _dbus_string_get_const_data (&str))); 01849 01850 /* unsigned little pack */ 01851 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01852 DBUS_LITTLE_ENDIAN, 01853 _dbus_string_get_data (&str)); 01854 01855 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01856 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 01857 _dbus_string_get_const_data (&str))); 01858 01859 /* unsigned big pack */ 01860 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 01861 DBUS_BIG_ENDIAN, 01862 _dbus_string_get_data (&str)); 01863 01864 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 01865 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 01866 _dbus_string_get_const_data (&str))); 01867 #endif /* DBUS_HAVE_INT64 */ 01868 01869 /* set/pack 32-bit integers */ 01870 _dbus_string_set_length (&str, 4); 01871 01872 /* signed little */ 01873 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN, 01874 0, -0x123456); 01875 01876 _dbus_assert (-0x123456 == 01877 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01878 _dbus_string_get_const_data (&str))); 01879 01880 /* signed big */ 01881 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN, 01882 0, -0x123456); 01883 01884 _dbus_assert (-0x123456 == 01885 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01886 _dbus_string_get_const_data (&str))); 01887 01888 /* signed little pack */ 01889 _dbus_pack_int32 (-0x123456, 01890 DBUS_LITTLE_ENDIAN, 01891 _dbus_string_get_data (&str)); 01892 01893 _dbus_assert (-0x123456 == 01894 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 01895 _dbus_string_get_const_data (&str))); 01896 01897 /* signed big pack */ 01898 _dbus_pack_int32 (-0x123456, 01899 DBUS_BIG_ENDIAN, 01900 _dbus_string_get_data (&str)); 01901 01902 _dbus_assert (-0x123456 == 01903 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 01904 _dbus_string_get_const_data (&str))); 01905 01906 /* unsigned little */ 01907 _dbus_marshal_set_uint32 (&str, 01908 0, 0x123456, 01909 DBUS_LITTLE_ENDIAN); 01910 01911 _dbus_assert (0x123456 == 01912 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01913 _dbus_string_get_const_data (&str))); 01914 01915 /* unsigned big */ 01916 _dbus_marshal_set_uint32 (&str, 01917 0, 0x123456, 01918 DBUS_BIG_ENDIAN); 01919 01920 _dbus_assert (0x123456 == 01921 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01922 _dbus_string_get_const_data (&str))); 01923 01924 /* unsigned little pack */ 01925 _dbus_pack_uint32 (0x123456, 01926 DBUS_LITTLE_ENDIAN, 01927 _dbus_string_get_data (&str)); 01928 01929 _dbus_assert (0x123456 == 01930 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 01931 _dbus_string_get_const_data (&str))); 01932 01933 /* unsigned big pack */ 01934 _dbus_pack_uint32 (0x123456, 01935 DBUS_BIG_ENDIAN, 01936 _dbus_string_get_data (&str)); 01937 01938 _dbus_assert (0x123456 == 01939 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 01940 _dbus_string_get_const_data (&str))); 01941 01942 #endif /* set/pack tests for integers */ 01943 01944 /* Strings in-place set */ 01945 byte_order = DBUS_LITTLE_ENDIAN; 01946 while (TRUE) 01947 { 01948 /* Init a string */ 01949 _dbus_string_set_length (&str, 0); 01950 01951 /* reset pos for the macros */ 01952 pos = 0; 01953 01954 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world"); 01955 01956 /* Set it to something longer */ 01957 _dbus_string_init_const (&t, "Hello world foo"); 01958 01959 v_STRING = _dbus_string_get_const_data (&t); 01960 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01961 &v_STRING, byte_order, NULL, NULL); 01962 01963 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01964 &v_STRING, byte_order, 01965 NULL); 01966 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0); 01967 01968 /* Set it to something shorter */ 01969 _dbus_string_init_const (&t, "Hello"); 01970 01971 v_STRING = _dbus_string_get_const_data (&t); 01972 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 01973 &v_STRING, byte_order, NULL, NULL); 01974 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 01975 &v_STRING, byte_order, 01976 NULL); 01977 _dbus_assert (strcmp (v_STRING, "Hello") == 0); 01978 01979 /* Do the other byte order */ 01980 if (byte_order == DBUS_LITTLE_ENDIAN) 01981 byte_order = DBUS_BIG_ENDIAN; 01982 else 01983 break; 01984 } 01985 01986 /* Clean up */ 01987 _dbus_string_free (&str); 01988 01989 return TRUE; 01990 } 01991 01992 #endif /* DBUS_BUILD_TESTS */