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