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