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