1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-marshal-basic.c Marshalling routines for basic (primitive) types 3 * 4 * Copyright (C) 2002 CodeFactory AB 5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 #include "dbus-internals.h" 27 #include "dbus-marshal-basic.h" 28 #include "dbus-signature.h" 29 30 #include <string.h> 31 32 #if defined(__GNUC__) && (__GNUC__ >= 4) 33 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \ 34 _DBUS_STATIC_ASSERT (__extension__ __alignof__ (type) op val) 35 #else 36 /* not gcc, so probably no alignof operator: just use a no-op statement 37 * that's valid in the same contexts */ 38 # define _DBUS_ASSERT_ALIGNMENT(type, op, val) \ 39 _DBUS_STATIC_ASSERT (TRUE) 40 #endif 41 42 /* True by definition, but just for completeness... */ 43 _DBUS_STATIC_ASSERT (sizeof (char) == 1); 44 _DBUS_ASSERT_ALIGNMENT (char, ==, 1); 45 46 _DBUS_STATIC_ASSERT (sizeof (dbus_int16_t) == 2); 47 _DBUS_ASSERT_ALIGNMENT (dbus_int16_t, <=, 2); 48 _DBUS_STATIC_ASSERT (sizeof (dbus_uint16_t) == 2); 49 _DBUS_ASSERT_ALIGNMENT (dbus_uint16_t, <=, 2); 50 51 _DBUS_STATIC_ASSERT (sizeof (dbus_int32_t) == 4); 52 _DBUS_ASSERT_ALIGNMENT (dbus_int32_t, <=, 4); 53 _DBUS_STATIC_ASSERT (sizeof (dbus_uint32_t) == 4); 54 _DBUS_ASSERT_ALIGNMENT (dbus_uint32_t, <=, 4); 55 _DBUS_STATIC_ASSERT (sizeof (dbus_bool_t) == 4); 56 _DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4); 57 58 _DBUS_STATIC_ASSERT (sizeof (double) == 8); 59 _DBUS_ASSERT_ALIGNMENT (double, <=, 8); 60 61 #ifdef DBUS_HAVE_INT64 62 _DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8); 63 _DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8); 64 _DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8); 65 _DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8); 66 #endif 67 68 _DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8); 69 /* The alignment of a DBusBasicValue might conceivably be > 8 because of the 70 * pointer, so we don't assert about it */ 71 72 _DBUS_STATIC_ASSERT (sizeof (DBus8ByteStruct) == 8); 73 _DBUS_ASSERT_ALIGNMENT (DBus8ByteStruct, <=, 8); 74 75 /** 76 * @defgroup DBusMarshal marshaling and unmarshaling 77 * @ingroup DBusInternals 78 * @brief functions to marshal/unmarshal data from the wire 79 * 80 * Types and functions related to converting primitive data types from 81 * wire format to native machine format, and vice versa. 82 * 83 * A signature is just a string with multiple types one after the other. 84 * for example a type is "i" or "(ii)", a signature is "i(ii)" 85 * where i is int and (ii) is struct { int; int; } 86 * 87 * @{ 88 */ 89 90 static void 91 pack_2_octets (dbus_uint16_t value, 92 int byte_order, 93 unsigned char *data) 94 { 95 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 96 97 if ((byte_order) == DBUS_LITTLE_ENDIAN) 98 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value); 99 else 100 *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value); 101 } 102 103 static void 104 pack_4_octets (dbus_uint32_t value, 105 int byte_order, 106 unsigned char *data) 107 { 108 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 109 110 if ((byte_order) == DBUS_LITTLE_ENDIAN) 111 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value); 112 else 113 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value); 114 } 115 116 static void 117 pack_8_octets (DBusBasicValue value, 118 int byte_order, 119 unsigned char *data) 120 { 121 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data); 122 123 #ifdef DBUS_HAVE_INT64 124 if ((byte_order) == DBUS_LITTLE_ENDIAN) 125 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64); 126 else 127 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64); 128 #else 129 *(DBus8ByteStruct*)data = value.eight; 130 swap_8_octets ((DBusBasicValue*)data, byte_order); 131 #endif 132 } 133 134 /** 135 * Packs a 32 bit unsigned integer into a data pointer. 136 * 137 * @param value the value 138 * @param byte_order the byte order to use 139 * @param data the data pointer 140 */ 141 void 142 _dbus_pack_uint32 (dbus_uint32_t value, 143 int byte_order, 144 unsigned char *data) 145 { 146 pack_4_octets (value, byte_order, data); 147 } 148 149 #ifndef DBUS_HAVE_INT64 150 /* from ORBit */ 151 static void 152 swap_bytes (unsigned char *data, 153 unsigned int len) 154 { 155 unsigned char *p1 = data; 156 unsigned char *p2 = data + len - 1; 157 158 while (p1 < p2) 159 { 160 unsigned char tmp = *p1; 161 *p1 = *p2; 162 *p2 = tmp; 163 164 --p2; 165 ++p1; 166 } 167 } 168 #endif /* !DBUS_HAVE_INT64 */ 169 170 static void 171 swap_8_octets (DBusBasicValue *value, 172 int byte_order) 173 { 174 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 175 { 176 #ifdef DBUS_HAVE_INT64 177 value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64); 178 #else 179 swap_bytes (&value->bytes, 8); 180 #endif 181 } 182 } 183 184 #if 0 185 static DBusBasicValue 186 unpack_8_octets (int byte_order, 187 const unsigned char *data) 188 { 189 DBusBasicValue r; 190 191 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data); 192 _dbus_assert (sizeof (r) == 8); 193 194 #ifdef DBUS_HAVE_INT64 195 if (byte_order == DBUS_LITTLE_ENDIAN) 196 r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data); 197 else 198 r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data); 199 #else 200 r.eight = *(DBus8ByteStruct*)data; 201 swap_8_octets (&r, byte_order); 202 #endif 203 204 return r; 205 } 206 #endif 207 208 #ifndef _dbus_unpack_uint16 209 /** 210 * Unpacks a 16 bit unsigned integer from a data pointer 211 * 212 * @param byte_order The byte order to use 213 * @param data the data pointer 214 * @returns the integer 215 */ 216 dbus_uint16_t 217 _dbus_unpack_uint16 (int byte_order, 218 const unsigned char *data) 219 { 220 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data); 221 222 if (byte_order == DBUS_LITTLE_ENDIAN) 223 return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data); 224 else 225 return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data); 226 } 227 #endif /* _dbus_unpack_uint16 */ 228 229 #ifndef _dbus_unpack_uint32 230 /** 231 * Unpacks a 32 bit unsigned integer from a data pointer 232 * 233 * @param byte_order The byte order to use 234 * @param data the data pointer 235 * @returns the integer 236 */ 237 dbus_uint32_t 238 _dbus_unpack_uint32 (int byte_order, 239 const unsigned char *data) 240 { 241 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data); 242 243 if (byte_order == DBUS_LITTLE_ENDIAN) 244 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data); 245 else 246 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data); 247 } 248 #endif /* _dbus_unpack_uint32 */ 249 250 static void 251 set_2_octets (DBusString *str, 252 int offset, 253 dbus_uint16_t value, 254 int byte_order) 255 { 256 char *data; 257 258 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 259 byte_order == DBUS_BIG_ENDIAN); 260 261 data = _dbus_string_get_data_len (str, offset, 2); 262 263 pack_2_octets (value, byte_order, data); 264 } 265 266 static void 267 set_4_octets (DBusString *str, 268 int offset, 269 dbus_uint32_t value, 270 int byte_order) 271 { 272 char *data; 273 274 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 275 byte_order == DBUS_BIG_ENDIAN); 276 277 data = _dbus_string_get_data_len (str, offset, 4); 278 279 pack_4_octets (value, byte_order, data); 280 } 281 282 static void 283 set_8_octets (DBusString *str, 284 int offset, 285 DBusBasicValue value, 286 int byte_order) 287 { 288 char *data; 289 290 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 291 byte_order == DBUS_BIG_ENDIAN); 292 293 data = _dbus_string_get_data_len (str, offset, 8); 294 295 pack_8_octets (value, byte_order, data); 296 } 297 298 /** 299 * Sets the 4 bytes at the given offset to a marshaled unsigned 300 * integer, replacing anything found there previously. 301 * 302 * @param str the string to write the marshalled int to 303 * @param pos the byte offset where int should be written 304 * @param value the value 305 * @param byte_order the byte order to use 306 * 307 */ 308 void 309 _dbus_marshal_set_uint32 (DBusString *str, 310 int pos, 311 dbus_uint32_t value, 312 int byte_order) 313 { 314 set_4_octets (str, pos, value, byte_order); 315 } 316 317 /** 318 * Sets the existing marshaled string at the given offset with 319 * a new marshaled string. The given offset must point to 320 * an existing string or the wrong length will be deleted 321 * and replaced with the new string. 322 * 323 * Note: no attempt is made by this function to re-align 324 * any data which has been already marshalled after this 325 * string. Use with caution. 326 * 327 * @param str the string to write the marshalled string to 328 * @param pos the position of the marshaled string length 329 * @param value the value 330 * @param byte_order the byte order to use 331 * @param old_end_pos place to store byte after the nul byte of the old value 332 * @param new_end_pos place to store byte after the nul byte of the new value 333 * @returns #TRUE on success, #FALSE if no memory 334 * 335 */ 336 static dbus_bool_t 337 set_string (DBusString *str, 338 int pos, 339 const char *value, 340 int byte_order, 341 int *old_end_pos, 342 int *new_end_pos) 343 { 344 int old_len, new_len; 345 DBusString dstr; 346 347 _dbus_string_init_const (&dstr, value); 348 349 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos); 350 old_len = _dbus_unpack_uint32 (byte_order, 351 _dbus_string_get_const_data_len (str, pos, 4)); 352 353 new_len = _dbus_string_get_length (&dstr); 354 355 if (!_dbus_string_replace_len (&dstr, 0, new_len, 356 str, pos + 4, old_len)) 357 return FALSE; 358 359 _dbus_marshal_set_uint32 (str, pos, new_len, byte_order); 360 361 if (old_end_pos) 362 *old_end_pos = pos + 4 + old_len + 1; 363 if (new_end_pos) 364 *new_end_pos = pos + 4 + new_len + 1; 365 366 return TRUE; 367 } 368 369 /** 370 * Sets the existing marshaled signature at the given offset to a new 371 * marshaled signature. Same basic ideas as set_string(). 372 * 373 * @param str the string to write the marshalled signature to 374 * @param pos the position of the marshaled signature length 375 * @param value the value 376 * @param byte_order the byte order to use 377 * @param old_end_pos place to store byte after the nul byte of the old value 378 * @param new_end_pos place to store byte after the nul byte of the new value 379 * @returns #TRUE on success, #FALSE if no memory 380 * 381 */ 382 static dbus_bool_t 383 set_signature (DBusString *str, 384 int pos, 385 const char *value, 386 int byte_order, 387 int *old_end_pos, 388 int *new_end_pos) 389 { 390 int old_len, new_len; 391 DBusString dstr; 392 393 _dbus_string_init_const (&dstr, value); 394 395 old_len = _dbus_string_get_byte (str, pos); 396 new_len = _dbus_string_get_length (&dstr); 397 398 if (!_dbus_string_replace_len (&dstr, 0, new_len, 399 str, pos + 1, old_len)) 400 return FALSE; 401 402 _dbus_string_set_byte (str, pos, new_len); 403 404 if (old_end_pos) 405 *old_end_pos = pos + 1 + old_len + 1; 406 if (new_end_pos) 407 *new_end_pos = pos + 1 + new_len + 1; 408 409 return TRUE; 410 } 411 412 /** 413 * Sets an existing basic type value to a new value. 414 * Arguments work the same way as _dbus_marshal_basic_type(). 415 * 416 * @param str the string 417 * @param pos location of the current value 418 * @param type the type of the current and new values 419 * @param value the address of the new value 420 * @param byte_order byte order for marshaling 421 * @param old_end_pos location to store end position of the old value, or #NULL 422 * @param new_end_pos location to store end position of the new value, or #NULL 423 * @returns #FALSE if no memory 424 */ 425 dbus_bool_t 426 _dbus_marshal_set_basic (DBusString *str, 427 int pos, 428 int type, 429 const void *value, 430 int byte_order, 431 int *old_end_pos, 432 int *new_end_pos) 433 { 434 const DBusBasicValue *vp; 435 436 vp = value; 437 438 switch (type) 439 { 440 case DBUS_TYPE_BYTE: 441 _dbus_string_set_byte (str, pos, vp->byt); 442 if (old_end_pos) 443 *old_end_pos = pos + 1; 444 if (new_end_pos) 445 *new_end_pos = pos + 1; 446 return TRUE; 447 break; 448 case DBUS_TYPE_INT16: 449 case DBUS_TYPE_UINT16: 450 pos = _DBUS_ALIGN_VALUE (pos, 2); 451 set_2_octets (str, pos, vp->u16, byte_order); 452 if (old_end_pos) 453 *old_end_pos = pos + 2; 454 if (new_end_pos) 455 *new_end_pos = pos + 2; 456 return TRUE; 457 break; 458 case DBUS_TYPE_BOOLEAN: 459 case DBUS_TYPE_INT32: 460 case DBUS_TYPE_UINT32: 461 case DBUS_TYPE_UNIX_FD: 462 pos = _DBUS_ALIGN_VALUE (pos, 4); 463 set_4_octets (str, pos, vp->u32, byte_order); 464 if (old_end_pos) 465 *old_end_pos = pos + 4; 466 if (new_end_pos) 467 *new_end_pos = pos + 4; 468 return TRUE; 469 break; 470 case DBUS_TYPE_INT64: 471 case DBUS_TYPE_UINT64: 472 case DBUS_TYPE_DOUBLE: 473 pos = _DBUS_ALIGN_VALUE (pos, 8); 474 set_8_octets (str, pos, *vp, byte_order); 475 if (old_end_pos) 476 *old_end_pos = pos + 8; 477 if (new_end_pos) 478 *new_end_pos = pos + 8; 479 return TRUE; 480 break; 481 case DBUS_TYPE_STRING: 482 case DBUS_TYPE_OBJECT_PATH: 483 pos = _DBUS_ALIGN_VALUE (pos, 4); 484 _dbus_assert (vp->str != NULL); 485 return set_string (str, pos, vp->str, byte_order, 486 old_end_pos, new_end_pos); 487 break; 488 case DBUS_TYPE_SIGNATURE: 489 _dbus_assert (vp->str != NULL); 490 return set_signature (str, pos, vp->str, byte_order, 491 old_end_pos, new_end_pos); 492 break; 493 default: 494 _dbus_assert_not_reached ("not a basic type"); 495 return FALSE; 496 break; 497 } 498 } 499 500 /** 501 * Convenience function to demarshal a 32 bit unsigned integer. 502 * 503 * @param str the string containing the data 504 * @param byte_order the byte order 505 * @param pos the position in the string 506 * @param new_pos the new position of the string 507 * @returns the demarshaled integer. 508 */ 509 dbus_uint32_t 510 _dbus_marshal_read_uint32 (const DBusString *str, 511 int pos, 512 int byte_order, 513 int *new_pos) 514 { 515 pos = _DBUS_ALIGN_VALUE (pos, 4); 516 517 if (new_pos) 518 *new_pos = pos + 4; 519 520 _dbus_assert (pos + 4 <= _dbus_string_get_length (str)); 521 522 return _dbus_unpack_uint32 (byte_order, 523 _dbus_string_get_const_data (str) + pos); 524 } 525 526 /** 527 * Demarshals a basic-typed value. The "value" pointer is always 528 * the address of a variable of the basic type. So e.g. 529 * if the basic type is "double" then the pointer is 530 * a double*, and if it's "char*" then the pointer is 531 * a "char**". 532 * 533 * A value of type #DBusBasicValue is guaranteed to be large enough to 534 * hold any of the types that may be returned, which is handy if you 535 * are trying to do things generically. For example you can pass 536 * a DBusBasicValue* in to this function, and then pass the same 537 * DBusBasicValue* in to _dbus_marshal_basic_type() in order to 538 * move a value from one place to another. 539 * 540 * @param str the string containing the data 541 * @param pos position in the string 542 * @param type type of value to demarshal 543 * @param value pointer to return value data 544 * @param byte_order the byte order 545 * @param new_pos pointer to update with new position, or #NULL 546 **/ 547 void 548 _dbus_marshal_read_basic (const DBusString *str, 549 int pos, 550 int type, 551 void *value, 552 int byte_order, 553 int *new_pos) 554 { 555 const char *str_data; 556 557 _dbus_assert (dbus_type_is_basic (type)); 558 559 str_data = _dbus_string_get_const_data (str); 560 561 /* Below we volatile types to avoid aliasing issues; 562 * see http://bugs.freedesktop.org/show_bug.cgi?id=20137 563 */ 564 565 switch (type) 566 { 567 case DBUS_TYPE_BYTE: 568 { 569 volatile unsigned char *vp = value; 570 *vp = (unsigned char) _dbus_string_get_byte (str, pos); 571 (pos)++; 572 } 573 break; 574 case DBUS_TYPE_INT16: 575 case DBUS_TYPE_UINT16: 576 { 577 volatile dbus_uint16_t *vp = value; 578 pos = _DBUS_ALIGN_VALUE (pos, 2); 579 *vp = *(dbus_uint16_t *)(str_data + pos); 580 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 581 *vp = DBUS_UINT16_SWAP_LE_BE (*vp); 582 pos += 2; 583 } 584 break; 585 case DBUS_TYPE_INT32: 586 case DBUS_TYPE_UINT32: 587 case DBUS_TYPE_BOOLEAN: 588 case DBUS_TYPE_UNIX_FD: 589 { 590 volatile dbus_uint32_t *vp = value; 591 pos = _DBUS_ALIGN_VALUE (pos, 4); 592 *vp = *(dbus_uint32_t *)(str_data + pos); 593 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 594 *vp = DBUS_UINT32_SWAP_LE_BE (*vp); 595 pos += 4; 596 } 597 break; 598 case DBUS_TYPE_INT64: 599 case DBUS_TYPE_UINT64: 600 case DBUS_TYPE_DOUBLE: 601 { 602 volatile dbus_uint64_t *vp = value; 603 pos = _DBUS_ALIGN_VALUE (pos, 8); 604 #ifdef DBUS_HAVE_INT64 605 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 606 *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); 607 else 608 *vp = *(dbus_uint64_t*)(str_data + pos); 609 #else 610 *vp = *(DBus8ByteStruct*) (str_data + pos); 611 swap_8_octets (vp, byte_order); 612 #endif 613 pos += 8; 614 } 615 break; 616 case DBUS_TYPE_STRING: 617 case DBUS_TYPE_OBJECT_PATH: 618 { 619 int len; 620 volatile char **vp = value; 621 622 len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); 623 624 *vp = (char*) str_data + pos; 625 626 pos += len + 1; /* length plus nul */ 627 } 628 break; 629 case DBUS_TYPE_SIGNATURE: 630 { 631 int len; 632 volatile char **vp = value; 633 634 len = _dbus_string_get_byte (str, pos); 635 pos += 1; 636 637 *vp = (char*) str_data + pos; 638 639 pos += len + 1; /* length plus nul */ 640 } 641 break; 642 default: 643 _dbus_warn_check_failed ("type %s %d not a basic type\n", 644 _dbus_type_to_string (type), type); 645 _dbus_assert_not_reached ("not a basic type"); 646 break; 647 } 648 649 if (new_pos) 650 *new_pos = pos; 651 } 652 653 static dbus_bool_t 654 marshal_2_octets (DBusString *str, 655 int insert_at, 656 dbus_uint16_t value, 657 int byte_order, 658 int *pos_after) 659 { 660 dbus_bool_t retval; 661 int orig_len; 662 663 _dbus_assert (sizeof (value) == 2); 664 665 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 666 value = DBUS_UINT16_SWAP_LE_BE (value); 667 668 orig_len = _dbus_string_get_length (str); 669 670 retval = _dbus_string_insert_2_aligned (str, insert_at, 671 (const unsigned char *)&value); 672 673 if (pos_after) 674 { 675 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 676 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 677 } 678 679 return retval; 680 } 681 682 static dbus_bool_t 683 marshal_4_octets (DBusString *str, 684 int insert_at, 685 dbus_uint32_t value, 686 int byte_order, 687 int *pos_after) 688 { 689 dbus_bool_t retval; 690 int orig_len; 691 692 _dbus_assert (sizeof (value) == 4); 693 694 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 695 value = DBUS_UINT32_SWAP_LE_BE (value); 696 697 orig_len = _dbus_string_get_length (str); 698 699 retval = _dbus_string_insert_4_aligned (str, insert_at, 700 (const unsigned char *)&value); 701 702 if (pos_after) 703 { 704 *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len); 705 _dbus_assert (*pos_after <= _dbus_string_get_length (str)); 706 } 707 708 return retval; 709 } 710 711 static dbus_bool_t 712 marshal_8_octets (DBusString *str, 713 int insert_at, 714 DBusBasicValue value, 715 int byte_order, 716 int *pos_after) 717 { 718 dbus_bool_t retval; 719 int orig_len; 720 721 _dbus_assert (sizeof (value) == 8); 722 723 swap_8_octets (&value, byte_order); 724 725 orig_len = _dbus_string_get_length (str); 726 727 retval = _dbus_string_insert_8_aligned (str, insert_at, 728 (const unsigned char *)&value); 729 730 if (pos_after) 731 *pos_after = insert_at + _dbus_string_get_length (str) - orig_len; 732 733 return retval; 734 } 735 736 enum 737 { 738 MARSHAL_AS_STRING, 739 MARSHAL_AS_SIGNATURE, 740 MARSHAL_AS_BYTE_ARRAY 741 }; 742 743 static dbus_bool_t 744 marshal_len_followed_by_bytes (int marshal_as, 745 DBusString *str, 746 int insert_at, 747 const unsigned char *value, 748 int data_len, /* doesn't include nul if any */ 749 int byte_order, 750 int *pos_after) 751 { 752 int pos; 753 DBusString value_str; 754 int value_len; 755 756 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN); 757 if (insert_at > _dbus_string_get_length (str)) 758 _dbus_warn ("insert_at = %d string len = %d data_len = %d\n", 759 insert_at, _dbus_string_get_length (str), data_len); 760 761 if (marshal_as == MARSHAL_AS_BYTE_ARRAY) 762 value_len = data_len; 763 else 764 value_len = data_len + 1; /* value has a nul */ 765 766 _dbus_string_init_const_len (&value_str, value, value_len); 767 768 pos = insert_at; 769 770 if (marshal_as == MARSHAL_AS_SIGNATURE) 771 { 772 _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH); 773 _dbus_assert (data_len <= 255); /* same as max sig len right now */ 774 775 if (!_dbus_string_insert_byte (str, pos, data_len)) 776 goto oom; 777 778 pos += 1; 779 } 780 else 781 { 782 if (!marshal_4_octets (str, pos, data_len, 783 byte_order, &pos)) 784 goto oom; 785 } 786 787 if (!_dbus_string_copy_len (&value_str, 0, value_len, 788 str, pos)) 789 goto oom; 790 791 #if 0 792 /* too expensive */ 793 _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len, 794 str, pos)); 795 _dbus_verbose_bytes_of_string (str, pos, value_len); 796 #endif 797 798 pos += value_len; 799 800 if (pos_after) 801 *pos_after = pos; 802 803 return TRUE; 804 805 oom: 806 /* Delete what we've inserted */ 807 _dbus_string_delete (str, insert_at, pos - insert_at); 808 809 return FALSE; 810 } 811 812 static dbus_bool_t 813 marshal_string (DBusString *str, 814 int insert_at, 815 const char *value, 816 int byte_order, 817 int *pos_after) 818 { 819 return marshal_len_followed_by_bytes (MARSHAL_AS_STRING, 820 str, insert_at, value, 821 strlen (value), 822 byte_order, pos_after); 823 } 824 825 static dbus_bool_t 826 marshal_signature (DBusString *str, 827 int insert_at, 828 const char *value, 829 int *pos_after) 830 { 831 return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE, 832 str, insert_at, value, 833 strlen (value), 834 DBUS_COMPILER_BYTE_ORDER, /* irrelevant */ 835 pos_after); 836 } 837 838 /** 839 * Marshals a basic-typed value. The "value" pointer is always the 840 * address of a variable containing the basic type value. 841 * So for example for int32 it will be dbus_int32_t*, and 842 * for string it will be const char**. This is for symmetry 843 * with _dbus_marshal_read_basic() and to have a simple 844 * consistent rule. 845 * 846 * @param str string to marshal to 847 * @param insert_at where to insert the value 848 * @param type type of value 849 * @param value pointer to a variable containing the value 850 * @param byte_order byte order 851 * @param pos_after #NULL or the position after the type 852 * @returns #TRUE on success 853 **/ 854 dbus_bool_t 855 _dbus_marshal_write_basic (DBusString *str, 856 int insert_at, 857 int type, 858 const void *value, 859 int byte_order, 860 int *pos_after) 861 { 862 const DBusBasicValue *vp; 863 864 _dbus_assert (dbus_type_is_basic (type)); 865 866 vp = value; 867 868 switch (type) 869 { 870 case DBUS_TYPE_BYTE: 871 if (!_dbus_string_insert_byte (str, insert_at, vp->byt)) 872 return FALSE; 873 if (pos_after) 874 *pos_after = insert_at + 1; 875 return TRUE; 876 break; 877 case DBUS_TYPE_INT16: 878 case DBUS_TYPE_UINT16: 879 return marshal_2_octets (str, insert_at, vp->u16, 880 byte_order, pos_after); 881 break; 882 case DBUS_TYPE_BOOLEAN: 883 return marshal_4_octets (str, insert_at, vp->u32 != FALSE, 884 byte_order, pos_after); 885 break; 886 case DBUS_TYPE_INT32: 887 case DBUS_TYPE_UINT32: 888 case DBUS_TYPE_UNIX_FD: 889 return marshal_4_octets (str, insert_at, vp->u32, 890 byte_order, pos_after); 891 break; 892 case DBUS_TYPE_INT64: 893 case DBUS_TYPE_UINT64: 894 case DBUS_TYPE_DOUBLE: 895 return marshal_8_octets (str, insert_at, *vp, byte_order, pos_after); 896 break; 897 898 case DBUS_TYPE_STRING: 899 case DBUS_TYPE_OBJECT_PATH: 900 _dbus_assert (vp->str != NULL); 901 return marshal_string (str, insert_at, vp->str, byte_order, pos_after); 902 break; 903 case DBUS_TYPE_SIGNATURE: 904 _dbus_assert (vp->str != NULL); 905 return marshal_signature (str, insert_at, vp->str, pos_after); 906 break; 907 default: 908 _dbus_assert_not_reached ("not a basic type"); 909 return FALSE; 910 break; 911 } 912 } 913 914 static dbus_bool_t 915 marshal_1_octets_array (DBusString *str, 916 int insert_at, 917 const unsigned char *value, 918 int n_elements, 919 int byte_order, 920 int *pos_after) 921 { 922 int pos; 923 DBusString value_str; 924 925 _dbus_string_init_const_len (&value_str, value, n_elements); 926 927 pos = insert_at; 928 929 if (!_dbus_string_copy_len (&value_str, 0, n_elements, 930 str, pos)) 931 return FALSE; 932 933 pos += n_elements; 934 935 if (pos_after) 936 *pos_after = pos; 937 938 return TRUE; 939 } 940 941 /** 942 * Swaps the elements of an array to the opposite byte order 943 * 944 * @param data start of array 945 * @param n_elements number of elements 946 * @param alignment size of each element 947 */ 948 void 949 _dbus_swap_array (unsigned char *data, 950 int n_elements, 951 int alignment) 952 { 953 unsigned char *d; 954 unsigned char *end; 955 956 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data); 957 958 /* we use const_data and cast it off so DBusString can be a const string 959 * for the unit tests. don't ask. 960 */ 961 d = data; 962 end = d + (n_elements * alignment); 963 964 if (alignment == 8) 965 { 966 while (d != end) 967 { 968 #ifdef DBUS_HAVE_INT64 969 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d)); 970 #else 971 swap_8_bytes ((DBusBasicValue*) d); 972 #endif 973 d += 8; 974 } 975 } 976 else if (alignment == 4) 977 { 978 while (d != end) 979 { 980 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d)); 981 d += 4; 982 } 983 } 984 else 985 { 986 _dbus_assert (alignment == 2); 987 988 while (d != end) 989 { 990 *((dbus_uint16_t*)d) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)d)); 991 d += 2; 992 } 993 } 994 } 995 996 static void 997 swap_array (DBusString *str, 998 int array_start, 999 int n_elements, 1000 int byte_order, 1001 int alignment) 1002 { 1003 _dbus_assert (_DBUS_ALIGN_VALUE (array_start, alignment) == (unsigned) array_start); 1004 1005 if (byte_order != DBUS_COMPILER_BYTE_ORDER) 1006 { 1007 /* we use const_data and cast it off so DBusString can be a const string 1008 * for the unit tests. don't ask. 1009 */ 1010 _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start), 1011 n_elements, alignment); 1012 } 1013 } 1014 1015 static dbus_bool_t 1016 marshal_fixed_multi (DBusString *str, 1017 int insert_at, 1018 const DBusBasicValue *value, 1019 int n_elements, 1020 int byte_order, 1021 int alignment, 1022 int *pos_after) 1023 { 1024 int old_string_len; 1025 int array_start; 1026 DBusString t; 1027 int len_in_bytes; 1028 1029 _dbus_assert (n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / alignment); 1030 1031 old_string_len = _dbus_string_get_length (str); 1032 1033 len_in_bytes = n_elements * alignment; 1034 array_start = insert_at; 1035 1036 /* Note that we do alignment padding unconditionally 1037 * even if the array is empty; this means that 1038 * padding + len is always equal to the number of bytes 1039 * in the array. 1040 */ 1041 1042 if (!_dbus_string_insert_alignment (str, &array_start, alignment)) 1043 goto error; 1044 1045 _dbus_string_init_const_len (&t, 1046 (const unsigned char*) value, 1047 len_in_bytes); 1048 1049 if (!_dbus_string_copy (&t, 0, 1050 str, array_start)) 1051 goto error; 1052 1053 swap_array (str, array_start, n_elements, byte_order, alignment); 1054 1055 if (pos_after) 1056 *pos_after = array_start + len_in_bytes; 1057 1058 return TRUE; 1059 1060 error: 1061 _dbus_string_delete (str, insert_at, 1062 _dbus_string_get_length (str) - old_string_len); 1063 1064 return FALSE; 1065 } 1066 1067 /** 1068 * Marshals a block of values of fixed-length type all at once, as an 1069 * optimization. dbus_type_is_fixed() returns #TRUE for fixed-length 1070 * types, which are the basic types minus the string-like types. 1071 * 1072 * The value argument should be the adddress of an 1073 * array, so e.g. "const dbus_uint32_t**" 1074 * 1075 * @param str string to marshal to 1076 * @param insert_at where to insert the value 1077 * @param element_type type of array elements 1078 * @param value address of an array to marshal 1079 * @param n_elements number of elements in the array 1080 * @param byte_order byte order 1081 * @param pos_after #NULL or the position after the type 1082 * @returns #TRUE on success 1083 **/ 1084 dbus_bool_t 1085 _dbus_marshal_write_fixed_multi (DBusString *str, 1086 int insert_at, 1087 int element_type, 1088 const void *value, 1089 int n_elements, 1090 int byte_order, 1091 int *pos_after) 1092 { 1093 const void* vp = *(const DBusBasicValue**)value; 1094 1095 _dbus_assert (dbus_type_is_fixed (element_type)); 1096 _dbus_assert (n_elements >= 0); 1097 1098 #if 0 1099 _dbus_verbose ("writing %d elements of %s\n", 1100 n_elements, _dbus_type_to_string (element_type)); 1101 #endif 1102 1103 switch (element_type) 1104 { 1105 case DBUS_TYPE_BYTE: 1106 return marshal_1_octets_array (str, insert_at, vp, n_elements, byte_order, pos_after); 1107 break; 1108 case DBUS_TYPE_INT16: 1109 case DBUS_TYPE_UINT16: 1110 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after); 1111 case DBUS_TYPE_BOOLEAN: 1112 case DBUS_TYPE_INT32: 1113 case DBUS_TYPE_UINT32: 1114 case DBUS_TYPE_UNIX_FD: 1115 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after); 1116 break; 1117 case DBUS_TYPE_INT64: 1118 case DBUS_TYPE_UINT64: 1119 case DBUS_TYPE_DOUBLE: 1120 return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 8, pos_after); 1121 break; 1122 1123 default: 1124 _dbus_assert_not_reached ("non fixed type in array write"); 1125 break; 1126 } 1127 1128 return FALSE; 1129 } 1130 1131 1132 /** 1133 * Skips over a basic-typed value, reporting the following position. 1134 * 1135 * @param str the string containing the data 1136 * @param type type of value to read 1137 * @param byte_order the byte order 1138 * @param pos pointer to position in the string, 1139 * updated on return to new position 1140 **/ 1141 void 1142 _dbus_marshal_skip_basic (const DBusString *str, 1143 int type, 1144 int byte_order, 1145 int *pos) 1146 { 1147 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 1148 byte_order == DBUS_BIG_ENDIAN); 1149 1150 switch (type) 1151 { 1152 case DBUS_TYPE_BYTE: 1153 (*pos)++; 1154 break; 1155 case DBUS_TYPE_INT16: 1156 case DBUS_TYPE_UINT16: 1157 *pos = _DBUS_ALIGN_VALUE (*pos, 2); 1158 *pos += 2; 1159 break; 1160 case DBUS_TYPE_BOOLEAN: 1161 case DBUS_TYPE_INT32: 1162 case DBUS_TYPE_UINT32: 1163 case DBUS_TYPE_UNIX_FD: 1164 *pos = _DBUS_ALIGN_VALUE (*pos, 4); 1165 *pos += 4; 1166 break; 1167 case DBUS_TYPE_INT64: 1168 case DBUS_TYPE_UINT64: 1169 case DBUS_TYPE_DOUBLE: 1170 *pos = _DBUS_ALIGN_VALUE (*pos, 8); 1171 *pos += 8; 1172 break; 1173 case DBUS_TYPE_STRING: 1174 case DBUS_TYPE_OBJECT_PATH: 1175 { 1176 int len; 1177 1178 len = _dbus_marshal_read_uint32 (str, *pos, byte_order, pos); 1179 1180 *pos += len + 1; /* length plus nul */ 1181 } 1182 break; 1183 case DBUS_TYPE_SIGNATURE: 1184 { 1185 int len; 1186 1187 len = _dbus_string_get_byte (str, *pos); 1188 1189 *pos += len + 2; /* length byte plus length plus nul */ 1190 } 1191 break; 1192 default: 1193 _dbus_warn ("type %s not a basic type\n", 1194 _dbus_type_to_string (type)); 1195 _dbus_assert_not_reached ("not a basic type"); 1196 break; 1197 } 1198 } 1199 1200 /** 1201 * Skips an array, returning the next position. 1202 * 1203 * @param str the string containing the data 1204 * @param element_type the type of array elements 1205 * @param byte_order the byte order 1206 * @param pos pointer to position in the string, 1207 * updated on return to new position 1208 */ 1209 void 1210 _dbus_marshal_skip_array (const DBusString *str, 1211 int element_type, 1212 int byte_order, 1213 int *pos) 1214 { 1215 dbus_uint32_t array_len; 1216 int i; 1217 int alignment; 1218 1219 i = _DBUS_ALIGN_VALUE (*pos, 4); 1220 1221 array_len = _dbus_marshal_read_uint32 (str, i, byte_order, &i); 1222 1223 alignment = _dbus_type_get_alignment (element_type); 1224 1225 i = _DBUS_ALIGN_VALUE (i, alignment); 1226 1227 *pos = i + array_len; 1228 } 1229 1230 /** 1231 * Gets the alignment requirement for the given type; 1232 * will be 1, 4, or 8. 1233 * 1234 * @param typecode the type 1235 * @returns alignment of 1, 4, or 8 1236 */ 1237 int 1238 _dbus_type_get_alignment (int typecode) 1239 { 1240 switch (typecode) 1241 { 1242 case DBUS_TYPE_BYTE: 1243 case DBUS_TYPE_VARIANT: 1244 case DBUS_TYPE_SIGNATURE: 1245 return 1; 1246 case DBUS_TYPE_INT16: 1247 case DBUS_TYPE_UINT16: 1248 return 2; 1249 case DBUS_TYPE_BOOLEAN: 1250 case DBUS_TYPE_INT32: 1251 case DBUS_TYPE_UINT32: 1252 case DBUS_TYPE_UNIX_FD: 1253 /* this stuff is 4 since it starts with a length */ 1254 case DBUS_TYPE_STRING: 1255 case DBUS_TYPE_OBJECT_PATH: 1256 case DBUS_TYPE_ARRAY: 1257 return 4; 1258 case DBUS_TYPE_INT64: 1259 case DBUS_TYPE_UINT64: 1260 case DBUS_TYPE_DOUBLE: 1261 /* struct is 8 since it could contain an 8-aligned item 1262 * and it's simpler to just always align structs to 8; 1263 * we want the amount of padding in a struct of a given 1264 * type to be predictable, not location-dependent. 1265 * DICT_ENTRY is always the same as struct. 1266 */ 1267 case DBUS_TYPE_STRUCT: 1268 case DBUS_TYPE_DICT_ENTRY: 1269 return 8; 1270 1271 default: 1272 _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()"); 1273 return 0; 1274 } 1275 } 1276 1277 /** 1278 * Returns a string describing the given type. 1279 * 1280 * @param typecode the type to describe 1281 * @returns a constant string describing the type 1282 */ 1283 const char * 1284 _dbus_type_to_string (int typecode) 1285 { 1286 switch (typecode) 1287 { 1288 case DBUS_TYPE_INVALID: 1289 return "invalid"; 1290 case DBUS_TYPE_BOOLEAN: 1291 return "boolean"; 1292 case DBUS_TYPE_BYTE: 1293 return "byte"; 1294 case DBUS_TYPE_INT16: 1295 return "int16"; 1296 case DBUS_TYPE_UINT16: 1297 return "uint16"; 1298 case DBUS_TYPE_INT32: 1299 return "int32"; 1300 case DBUS_TYPE_UINT32: 1301 return "uint32"; 1302 case DBUS_TYPE_INT64: 1303 return "int64"; 1304 case DBUS_TYPE_UINT64: 1305 return "uint64"; 1306 case DBUS_TYPE_DOUBLE: 1307 return "double"; 1308 case DBUS_TYPE_STRING: 1309 return "string"; 1310 case DBUS_TYPE_OBJECT_PATH: 1311 return "object_path"; 1312 case DBUS_TYPE_SIGNATURE: 1313 return "signature"; 1314 case DBUS_TYPE_STRUCT: 1315 return "struct"; 1316 case DBUS_TYPE_DICT_ENTRY: 1317 return "dict_entry"; 1318 case DBUS_TYPE_ARRAY: 1319 return "array"; 1320 case DBUS_TYPE_VARIANT: 1321 return "variant"; 1322 case DBUS_STRUCT_BEGIN_CHAR: 1323 return "begin_struct"; 1324 case DBUS_STRUCT_END_CHAR: 1325 return "end_struct"; 1326 case DBUS_DICT_ENTRY_BEGIN_CHAR: 1327 return "begin_dict_entry"; 1328 case DBUS_DICT_ENTRY_END_CHAR: 1329 return "end_dict_entry"; 1330 case DBUS_TYPE_UNIX_FD: 1331 return "unix_fd"; 1332 default: 1333 return "unknown"; 1334 } 1335 } 1336 1337 /** 1338 * If in verbose mode, print a block of binary data. 1339 * 1340 * @param data the data 1341 * @param len the length of the data 1342 * @param offset where to start counting for byte indexes 1343 */ 1344 void 1345 _dbus_verbose_bytes (const unsigned char *data, 1346 int len, 1347 int offset) 1348 { 1349 int i; 1350 const unsigned char *aligned; 1351 1352 _dbus_assert (len >= 0); 1353 1354 if (!_dbus_is_verbose()) 1355 return; 1356 1357 /* Print blanks on first row if appropriate */ 1358 aligned = _DBUS_ALIGN_ADDRESS (data, 4); 1359 if (aligned > data) 1360 aligned -= 4; 1361 _dbus_assert (aligned <= data); 1362 1363 if (aligned != data) 1364 { 1365 _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned); 1366 while (aligned != data) 1367 { 1368 _dbus_verbose (" "); 1369 ++aligned; 1370 } 1371 } 1372 1373 /* now print the bytes */ 1374 i = 0; 1375 while (i < len) 1376 { 1377 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 1378 { 1379 _dbus_verbose ("%4d\t%p: ", 1380 offset + i, &data[i]); 1381 } 1382 1383 if (data[i] >= 32 && 1384 data[i] <= 126) 1385 _dbus_verbose (" '%c' ", data[i]); 1386 else 1387 _dbus_verbose ("0x%s%x ", 1388 data[i] <= 0xf ? "0" : "", data[i]); 1389 1390 ++i; 1391 1392 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i]) 1393 { 1394 if (i > 3) 1395 _dbus_verbose ("BE: %d LE: %d", 1396 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]), 1397 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4])); 1398 1399 if (i > 7 && 1400 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i]) 1401 { 1402 #ifdef DBUS_INT64_PRINTF_MODIFIER 1403 _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x", 1404 *(dbus_uint64_t*)&data[i-8]); 1405 #endif 1406 _dbus_verbose (" dbl: %g", 1407 *(double*)&data[i-8]); 1408 } 1409 1410 _dbus_verbose ("\n"); 1411 } 1412 } 1413 1414 _dbus_verbose ("\n"); 1415 } 1416 1417 /** 1418 * Dump the given part of the string to verbose log. 1419 * 1420 * @param str the string 1421 * @param start the start of range to dump 1422 * @param len length of range 1423 */ 1424 void 1425 _dbus_verbose_bytes_of_string (const DBusString *str, 1426 int start, 1427 int len) 1428 { 1429 const char *d; 1430 int real_len; 1431 1432 real_len = _dbus_string_get_length (str); 1433 1434 _dbus_assert (start >= 0); 1435 1436 if (start > real_len) 1437 { 1438 _dbus_verbose (" [%d,%d) is not inside string of length %d\n", 1439 start, len, real_len); 1440 return; 1441 } 1442 1443 if ((start + len) > real_len) 1444 { 1445 _dbus_verbose (" [%d,%d) extends outside string of length %d\n", 1446 start, len, real_len); 1447 len = real_len - start; 1448 } 1449 1450 d = _dbus_string_get_const_data_len (str, start, len); 1451 1452 _dbus_verbose_bytes (d, len, start); 1453 } 1454 1455 static int 1456 map_type_char_to_type (int t) 1457 { 1458 if (t == DBUS_STRUCT_BEGIN_CHAR) 1459 return DBUS_TYPE_STRUCT; 1460 else if (t == DBUS_DICT_ENTRY_BEGIN_CHAR) 1461 return DBUS_TYPE_DICT_ENTRY; 1462 else 1463 { 1464 _dbus_assert (t != DBUS_STRUCT_END_CHAR); 1465 _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR); 1466 return t; 1467 } 1468 } 1469 1470 /** 1471 * Get the first type in the signature. The difference between this 1472 * and just getting the first byte of the signature is that you won't 1473 * get DBUS_STRUCT_BEGIN_CHAR, you'll get DBUS_TYPE_STRUCT 1474 * instead. 1475 * 1476 * @param str string containing signature 1477 * @param pos where the signature starts 1478 * @returns the first type in the signature 1479 */ 1480 int 1481 _dbus_first_type_in_signature (const DBusString *str, 1482 int pos) 1483 { 1484 return map_type_char_to_type (_dbus_string_get_byte (str, pos)); 1485 } 1486 1487 /** 1488 * Similar to #_dbus_first_type_in_signature, but operates 1489 * on a C string buffer. 1490 * 1491 * @param str a C string buffer 1492 * @param pos where the signature starts 1493 * @returns the first type in the signature 1494 */ 1495 int 1496 _dbus_first_type_in_signature_c_str (const char *str, 1497 int pos) 1498 { 1499 return map_type_char_to_type (str[pos]); 1500 } 1501 1502 /** @} */ 1503 1504 #ifdef DBUS_BUILD_TESTS 1505 #include "dbus-test.h" 1506 #include <stdio.h> 1507 1508 /** 1509 * Reads a block of fixed-length basic values, as an optimization 1510 * vs. reading each one individually into a new buffer. 1511 * 1512 * This function returns the data in-place; it does not make a copy, 1513 * and it does not swap the bytes. 1514 * 1515 * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back 1516 * and the "value" argument should be a "const double**" and so on. 1517 * 1518 * @param str the string to read from 1519 * @param pos position to read from 1520 * @param element_type type of array elements 1521 * @param value place to return the array 1522 * @param n_elements number of array elements to read 1523 * @param byte_order the byte order, used to read the array length 1524 * @param new_pos #NULL or location to store a position after the elements 1525 */ 1526 void 1527 _dbus_marshal_read_fixed_multi (const DBusString *str, 1528 int pos, 1529 int element_type, 1530 void *value, 1531 int n_elements, 1532 int byte_order, 1533 int *new_pos) 1534 { 1535 int array_len; 1536 int alignment; 1537 1538 _dbus_assert (dbus_type_is_fixed (element_type)); 1539 _dbus_assert (dbus_type_is_basic (element_type)); 1540 1541 #if 0 1542 _dbus_verbose ("reading %d elements of %s\n", 1543 n_elements, _dbus_type_to_string (element_type)); 1544 #endif 1545 1546 alignment = _dbus_type_get_alignment (element_type); 1547 1548 pos = _DBUS_ALIGN_VALUE (pos, alignment); 1549 1550 array_len = n_elements * alignment; 1551 1552 *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len); 1553 if (new_pos) 1554 *new_pos = pos + array_len; 1555 } 1556 1557 static void 1558 swap_test_array (void *array, 1559 int len_bytes, 1560 int byte_order, 1561 int alignment) 1562 { 1563 DBusString t; 1564 1565 if (alignment == 1) 1566 return; 1567 1568 _dbus_string_init_const_len (&t, array, len_bytes); 1569 swap_array (&t, 0, len_bytes / alignment, byte_order, alignment); 1570 } 1571 1572 #define MARSHAL_BASIC(typename, byte_order, literal) \ 1573 do { \ 1574 v_##typename = literal; \ 1575 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_##typename, \ 1576 &v_##typename, \ 1577 byte_order, NULL)) \ 1578 _dbus_assert_not_reached ("no memory"); \ 1579 } while (0) 1580 1581 #define DEMARSHAL_BASIC(typename, byte_order) \ 1582 do { \ 1583 _dbus_marshal_read_basic (&str, pos, DBUS_TYPE_##typename, &v_##typename, \ 1584 byte_order, &pos); \ 1585 } while (0) 1586 1587 #define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal) \ 1588 do { \ 1589 DEMARSHAL_BASIC (typename, byte_order); \ 1590 if (literal != v_##typename) \ 1591 { \ 1592 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 1593 _dbus_string_get_length (&str) - dump_pos); \ 1594 _dbus_assert_not_reached ("demarshaled wrong value"); \ 1595 } \ 1596 } while (0) 1597 1598 #define MARSHAL_TEST(typename, byte_order, literal) \ 1599 do { \ 1600 MARSHAL_BASIC (typename, byte_order, literal); \ 1601 dump_pos = pos; \ 1602 DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal); \ 1603 } while (0) 1604 1605 #define MARSHAL_TEST_STRCMP(typename, byte_order, literal) \ 1606 do { \ 1607 MARSHAL_BASIC (typename, byte_order, literal); \ 1608 dump_pos = pos; \ 1609 DEMARSHAL_BASIC (typename, byte_order); \ 1610 if (strcmp (literal, v_##typename) != 0) \ 1611 { \ 1612 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 1613 _dbus_string_get_length (&str) - dump_pos); \ 1614 _dbus_warn ("literal '%s'\nvalue '%s'\n", literal, v_##typename); \ 1615 _dbus_assert_not_reached ("demarshaled wrong value"); \ 1616 } \ 1617 } while (0) 1618 1619 #define MARSHAL_FIXED_ARRAY(typename, byte_order, literal) \ 1620 do { \ 1621 int next; \ 1622 v_UINT32 = sizeof(literal); \ 1623 if (!_dbus_marshal_write_basic (&str, pos, DBUS_TYPE_UINT32, &v_UINT32, \ 1624 byte_order, &next)) \ 1625 _dbus_assert_not_reached ("no memory"); \ 1626 v_ARRAY_##typename = literal; \ 1627 if (!_dbus_marshal_write_fixed_multi (&str, next, DBUS_TYPE_##typename, \ 1628 &v_ARRAY_##typename, _DBUS_N_ELEMENTS(literal), \ 1629 byte_order, NULL)) \ 1630 _dbus_assert_not_reached ("no memory"); \ 1631 } while (0) 1632 1633 #define DEMARSHAL_FIXED_ARRAY(typename, byte_order) \ 1634 do { \ 1635 int next; \ 1636 alignment = _dbus_type_get_alignment (DBUS_TYPE_##typename); \ 1637 v_UINT32 = _dbus_marshal_read_uint32 (&str, dump_pos, byte_order, &next); \ 1638 _dbus_marshal_read_fixed_multi (&str, next, DBUS_TYPE_##typename, &v_ARRAY_##typename, \ 1639 v_UINT32/alignment, \ 1640 byte_order, NULL); \ 1641 swap_test_array (v_ARRAY_##typename, v_UINT32, \ 1642 byte_order, alignment); \ 1643 } while (0) 1644 1645 #define DEMARSHAL_FIXED_ARRAY_AND_CHECK(typename, byte_order, literal) \ 1646 do { \ 1647 DEMARSHAL_FIXED_ARRAY (typename, byte_order); \ 1648 if (memcmp (literal, v_ARRAY_##typename, sizeof (literal) != 0)) \ 1649 { \ 1650 _dbus_verbose ("MARSHALED DATA\n"); \ 1651 _dbus_verbose_bytes_of_string (&str, dump_pos, \ 1652 _dbus_string_get_length (&str) - dump_pos); \ 1653 _dbus_verbose ("LITERAL DATA\n"); \ 1654 _dbus_verbose_bytes ((char*)literal, sizeof (literal), 0); \ 1655 _dbus_verbose ("READ DATA\n"); \ 1656 _dbus_verbose_bytes ((char*)v_ARRAY_##typename, sizeof (literal), 0); \ 1657 _dbus_assert_not_reached ("demarshaled wrong fixed array value"); \ 1658 } \ 1659 } while (0) 1660 1661 #define MARSHAL_TEST_FIXED_ARRAY(typename, byte_order, literal) \ 1662 do { \ 1663 MARSHAL_FIXED_ARRAY (typename, byte_order, literal); \ 1664 dump_pos = pos; \ 1665 DEMARSHAL_FIXED_ARRAY_AND_CHECK (typename, byte_order, literal); \ 1666 } while (0) 1667 1668 dbus_bool_t 1669 _dbus_marshal_test (void) 1670 { 1671 int alignment; 1672 DBusString str; 1673 int pos, dump_pos; 1674 unsigned char array1[5] = { 3, 4, 0, 1, 9 }; 1675 dbus_int16_t array2[3] = { 124, 457, 780 }; 1676 dbus_int32_t array4[3] = { 123, 456, 789 }; 1677 #ifdef DBUS_HAVE_INT64 1678 dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 1679 DBUS_INT64_CONSTANT (0x456ffffffff), 1680 DBUS_INT64_CONSTANT (0x789ffffffff) }; 1681 dbus_int64_t *v_ARRAY_INT64; 1682 #endif 1683 unsigned char *v_ARRAY_BYTE; 1684 dbus_int16_t *v_ARRAY_INT16; 1685 dbus_uint16_t *v_ARRAY_UINT16; 1686 dbus_int32_t *v_ARRAY_INT32; 1687 dbus_uint32_t *v_ARRAY_UINT32; 1688 DBusString t; 1689 double v_DOUBLE; 1690 double t_DOUBLE; 1691 dbus_int16_t v_INT16; 1692 dbus_uint16_t v_UINT16; 1693 dbus_int32_t v_INT32; 1694 dbus_uint32_t v_UINT32; 1695 dbus_int64_t v_INT64; 1696 dbus_uint64_t v_UINT64; 1697 unsigned char v_BYTE; 1698 dbus_bool_t v_BOOLEAN; 1699 const char *v_STRING; 1700 const char *v_SIGNATURE; 1701 const char *v_OBJECT_PATH; 1702 int byte_order; 1703 1704 if (!_dbus_string_init (&str)) 1705 _dbus_assert_not_reached ("failed to init string"); 1706 1707 pos = 0; 1708 1709 /* Marshal doubles */ 1710 MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14); 1711 DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN); 1712 t_DOUBLE = 3.14; 1713 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 1714 _dbus_assert_not_reached ("got wrong double value"); 1715 1716 MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14); 1717 DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN); 1718 t_DOUBLE = 3.14; 1719 if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE)) 1720 _dbus_assert_not_reached ("got wrong double value"); 1721 1722 /* Marshal signed 16 integers */ 1723 MARSHAL_TEST (INT16, DBUS_BIG_ENDIAN, -12345); 1724 MARSHAL_TEST (INT16, DBUS_LITTLE_ENDIAN, -12345); 1725 1726 /* Marshal unsigned 16 integers */ 1727 MARSHAL_TEST (UINT16, DBUS_BIG_ENDIAN, 0x1234); 1728 MARSHAL_TEST (UINT16, DBUS_LITTLE_ENDIAN, 0x1234); 1729 1730 /* Marshal signed integers */ 1731 MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678); 1732 MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678); 1733 1734 /* Marshal unsigned integers */ 1735 MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678); 1736 MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678); 1737 1738 #ifdef DBUS_HAVE_INT64 1739 /* Marshal signed integers */ 1740 MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 1741 MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)); 1742 1743 /* Marshal unsigned integers */ 1744 MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 1745 MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)); 1746 #endif /* DBUS_HAVE_INT64 */ 1747 1748 /* Marshal byte */ 1749 MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5); 1750 MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5); 1751 1752 /* Marshal all possible bools! */ 1753 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE); 1754 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE); 1755 MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE); 1756 MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE); 1757 1758 /* Marshal strings */ 1759 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, ""); 1760 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, ""); 1761 MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string"); 1762 MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string"); 1763 1764 /* object paths */ 1765 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c"); 1766 MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c"); 1767 1768 /* signatures */ 1769 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, ""); 1770 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, ""); 1771 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)"); 1772 MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)"); 1773 1774 /* Arrays */ 1775 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_BIG_ENDIAN, array2); 1776 MARSHAL_TEST_FIXED_ARRAY (INT16, DBUS_LITTLE_ENDIAN, array2); 1777 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_BIG_ENDIAN, array2); 1778 MARSHAL_TEST_FIXED_ARRAY (UINT16, DBUS_LITTLE_ENDIAN, array2); 1779 1780 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_BIG_ENDIAN, array4); 1781 MARSHAL_TEST_FIXED_ARRAY (INT32, DBUS_LITTLE_ENDIAN, array4); 1782 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_BIG_ENDIAN, array4); 1783 MARSHAL_TEST_FIXED_ARRAY (UINT32, DBUS_LITTLE_ENDIAN, array4); 1784 1785 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1); 1786 MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1); 1787 1788 #ifdef DBUS_HAVE_INT64 1789 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8); 1790 MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8); 1791 #endif 1792 1793 #if 0 1794 1795 /* 1796 * FIXME restore the set/pack tests 1797 */ 1798 1799 #ifdef DBUS_HAVE_INT64 1800 /* set/pack 64-bit integers */ 1801 _dbus_string_set_length (&str, 8); 1802 1803 /* signed little */ 1804 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN, 1805 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 1806 1807 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 1808 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 1809 _dbus_string_get_const_data (&str))); 1810 1811 /* signed big */ 1812 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN, 1813 0, DBUS_INT64_CONSTANT (-0x123456789abc7)); 1814 1815 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 1816 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 1817 _dbus_string_get_const_data (&str))); 1818 1819 /* signed little pack */ 1820 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 1821 DBUS_LITTLE_ENDIAN, 1822 _dbus_string_get_data (&str)); 1823 1824 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 1825 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN, 1826 _dbus_string_get_const_data (&str))); 1827 1828 /* signed big pack */ 1829 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7), 1830 DBUS_BIG_ENDIAN, 1831 _dbus_string_get_data (&str)); 1832 1833 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) == 1834 _dbus_unpack_int64 (DBUS_BIG_ENDIAN, 1835 _dbus_string_get_const_data (&str))); 1836 1837 /* unsigned little */ 1838 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN, 1839 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 1840 1841 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 1842 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 1843 _dbus_string_get_const_data (&str))); 1844 1845 /* unsigned big */ 1846 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN, 1847 0, DBUS_UINT64_CONSTANT (0x123456789abc7)); 1848 1849 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 1850 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 1851 _dbus_string_get_const_data (&str))); 1852 1853 /* unsigned little pack */ 1854 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 1855 DBUS_LITTLE_ENDIAN, 1856 _dbus_string_get_data (&str)); 1857 1858 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 1859 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN, 1860 _dbus_string_get_const_data (&str))); 1861 1862 /* unsigned big pack */ 1863 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7), 1864 DBUS_BIG_ENDIAN, 1865 _dbus_string_get_data (&str)); 1866 1867 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) == 1868 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN, 1869 _dbus_string_get_const_data (&str))); 1870 #endif /* DBUS_HAVE_INT64 */ 1871 1872 /* set/pack 32-bit integers */ 1873 _dbus_string_set_length (&str, 4); 1874 1875 /* signed little */ 1876 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN, 1877 0, -0x123456); 1878 1879 _dbus_assert (-0x123456 == 1880 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 1881 _dbus_string_get_const_data (&str))); 1882 1883 /* signed big */ 1884 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN, 1885 0, -0x123456); 1886 1887 _dbus_assert (-0x123456 == 1888 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 1889 _dbus_string_get_const_data (&str))); 1890 1891 /* signed little pack */ 1892 _dbus_pack_int32 (-0x123456, 1893 DBUS_LITTLE_ENDIAN, 1894 _dbus_string_get_data (&str)); 1895 1896 _dbus_assert (-0x123456 == 1897 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN, 1898 _dbus_string_get_const_data (&str))); 1899 1900 /* signed big pack */ 1901 _dbus_pack_int32 (-0x123456, 1902 DBUS_BIG_ENDIAN, 1903 _dbus_string_get_data (&str)); 1904 1905 _dbus_assert (-0x123456 == 1906 _dbus_unpack_int32 (DBUS_BIG_ENDIAN, 1907 _dbus_string_get_const_data (&str))); 1908 1909 /* unsigned little */ 1910 _dbus_marshal_set_uint32 (&str, 1911 0, 0x123456, 1912 DBUS_LITTLE_ENDIAN); 1913 1914 _dbus_assert (0x123456 == 1915 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 1916 _dbus_string_get_const_data (&str))); 1917 1918 /* unsigned big */ 1919 _dbus_marshal_set_uint32 (&str, 1920 0, 0x123456, 1921 DBUS_BIG_ENDIAN); 1922 1923 _dbus_assert (0x123456 == 1924 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 1925 _dbus_string_get_const_data (&str))); 1926 1927 /* unsigned little pack */ 1928 _dbus_pack_uint32 (0x123456, 1929 DBUS_LITTLE_ENDIAN, 1930 _dbus_string_get_data (&str)); 1931 1932 _dbus_assert (0x123456 == 1933 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, 1934 _dbus_string_get_const_data (&str))); 1935 1936 /* unsigned big pack */ 1937 _dbus_pack_uint32 (0x123456, 1938 DBUS_BIG_ENDIAN, 1939 _dbus_string_get_data (&str)); 1940 1941 _dbus_assert (0x123456 == 1942 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, 1943 _dbus_string_get_const_data (&str))); 1944 1945 #endif /* set/pack tests for integers */ 1946 1947 /* Strings in-place set */ 1948 byte_order = DBUS_LITTLE_ENDIAN; 1949 while (TRUE) 1950 { 1951 /* Init a string */ 1952 _dbus_string_set_length (&str, 0); 1953 1954 /* reset pos for the macros */ 1955 pos = 0; 1956 1957 MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world"); 1958 1959 /* Set it to something longer */ 1960 _dbus_string_init_const (&t, "Hello world foo"); 1961 1962 v_STRING = _dbus_string_get_const_data (&t); 1963 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 1964 &v_STRING, byte_order, NULL, NULL); 1965 1966 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 1967 &v_STRING, byte_order, 1968 NULL); 1969 _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0); 1970 1971 /* Set it to something shorter */ 1972 _dbus_string_init_const (&t, "Hello"); 1973 1974 v_STRING = _dbus_string_get_const_data (&t); 1975 _dbus_marshal_set_basic (&str, 0, DBUS_TYPE_STRING, 1976 &v_STRING, byte_order, NULL, NULL); 1977 _dbus_marshal_read_basic (&str, 0, DBUS_TYPE_STRING, 1978 &v_STRING, byte_order, 1979 NULL); 1980 _dbus_assert (strcmp (v_STRING, "Hello") == 0); 1981 1982 /* Do the other byte order */ 1983 if (byte_order == DBUS_LITTLE_ENDIAN) 1984 byte_order = DBUS_BIG_ENDIAN; 1985 else 1986 break; 1987 } 1988 1989 /* Clean up */ 1990 _dbus_string_free (&str); 1991 1992 return TRUE; 1993 } 1994 1995 #endif /* DBUS_BUILD_TESTS */ 1996