00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dbus-internals.h"
00026 #include "dbus-marshal.h"
00027 #include "dbus-message.h"
00028 #include "dbus-message-internal.h"
00029 #include "dbus-memory.h"
00030 #include "dbus-list.h"
00031 #include "dbus-message-builder.h"
00032 #include "dbus-dataslot.h"
00033 #include <string.h>
00034
00048 typedef struct
00049 {
00050 int name_offset;
00051 int value_offset;
00052 } HeaderField;
00053
00055 #define BYTE_ORDER_OFFSET 0
00056
00057 #define TYPE_OFFSET 1
00058
00059 #define FLAGS_OFFSET 2
00060
00061 #define VERSION_OFFSET 3
00062
00063 #define HEADER_LENGTH_OFFSET 4
00064
00065 #define BODY_LENGTH_OFFSET 8
00066
00067 #define CLIENT_SERIAL_OFFSET 12
00068
00069
00077 struct DBusMessage
00078 {
00079 DBusAtomic refcount;
00081 DBusString header;
00086 HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1];
00090 dbus_uint32_t client_serial;
00091 dbus_uint32_t reply_serial;
00093 int header_padding;
00095 DBusString body;
00097 char byte_order;
00099 DBusList *size_counters;
00100 long size_counter_delta;
00102 dbus_uint32_t changed_stamp;
00104 unsigned int locked : 1;
00106 DBusDataSlotList slot_list;
00108 DBusString signature;
00109 };
00110
00111 enum {
00112 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00113 DBUS_MESSAGE_ITER_TYPE_ARRAY,
00114 DBUS_MESSAGE_ITER_TYPE_DICT
00115 };
00116
00118 typedef struct DBusMessageRealIter DBusMessageRealIter;
00119
00125 struct DBusMessageRealIter
00126 {
00127 DBusMessageRealIter *parent_iter;
00128 DBusMessage *message;
00129 dbus_uint32_t changed_stamp;
00131
00132 int type;
00134 int pos;
00135 int end;
00136 int container_start;
00137 int container_length_pos;
00139 int wrote_dict_key;
00141 int array_type_pos;
00142 int array_type_done;
00143 };
00144
00155 void
00156 _dbus_message_get_network_data (DBusMessage *message,
00157 const DBusString **header,
00158 const DBusString **body)
00159 {
00160 _dbus_assert (message->locked);
00161
00162 *header = &message->header;
00163 *body = &message->body;
00164 }
00165
00166 static void
00167 clear_header_padding (DBusMessage *message)
00168 {
00169 _dbus_string_shorten (&message->header,
00170 message->header_padding);
00171 message->header_padding = 0;
00172 }
00173
00174 static dbus_bool_t
00175 append_header_padding (DBusMessage *message)
00176 {
00177 int old_len;
00178 old_len = _dbus_string_get_length (&message->header);
00179 if (!_dbus_string_align_length (&message->header, 8))
00180 return FALSE;
00181
00182 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00183
00184 return TRUE;
00185 }
00186
00187 #ifdef DBUS_BUILD_TESTS
00188
00189 static dbus_int32_t
00190 get_int_field (DBusMessage *message,
00191 int field)
00192 {
00193 int offset;
00194
00195 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00196
00197 offset = message->header_fields[field].value_offset;
00198
00199 if (offset < 0)
00200 return -1;
00201
00202 return _dbus_demarshal_int32 (&message->header,
00203 message->byte_order,
00204 offset,
00205 NULL);
00206 }
00207 #endif
00208
00209 static dbus_uint32_t
00210 get_uint_field (DBusMessage *message,
00211 int field)
00212 {
00213 int offset;
00214
00215 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00216
00217 offset = message->header_fields[field].value_offset;
00218
00219 if (offset < 0)
00220 return 0;
00221
00222 return _dbus_demarshal_uint32 (&message->header,
00223 message->byte_order,
00224 offset,
00225 NULL);
00226 }
00227
00228 static const char*
00229 get_string_field (DBusMessage *message,
00230 int field,
00231 int *len)
00232 {
00233 int offset;
00234 const char *data;
00235
00236 offset = message->header_fields[field].value_offset;
00237
00238 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00239
00240 if (offset < 0)
00241 return NULL;
00242
00243
00244
00245
00246
00247
00248 if (len)
00249 *len = _dbus_demarshal_uint32 (&message->header,
00250 message->byte_order,
00251 offset,
00252 NULL);
00253
00254 data = _dbus_string_get_const_data (&message->header);
00255
00256 return data + (offset + 4);
00257 }
00258
00259
00260 static dbus_bool_t
00261 get_path_field_decomposed (DBusMessage *message,
00262 int field,
00263 char ***path)
00264 {
00265 int offset;
00266
00267 offset = message->header_fields[field].value_offset;
00268
00269 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00270
00271 if (offset < 0)
00272 {
00273 *path = NULL;
00274 return TRUE;
00275 }
00276
00277 return _dbus_demarshal_object_path (&message->header,
00278 message->byte_order,
00279 offset,
00280 NULL,
00281 path, NULL);
00282 }
00283
00284 #ifdef DBUS_BUILD_TESTS
00285 static dbus_bool_t
00286 append_int_field (DBusMessage *message,
00287 int field,
00288 int value)
00289 {
00290 _dbus_assert (!message->locked);
00291
00292 clear_header_padding (message);
00293
00294 message->header_fields[field].name_offset =
00295 _dbus_string_get_length (&message->header);
00296
00297 if (!_dbus_string_append_byte (&message->header, field))
00298 goto failed;
00299
00300 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00301 goto failed;
00302
00303 if (!_dbus_string_align_length (&message->header, 4))
00304 goto failed;
00305
00306 message->header_fields[field].value_offset =
00307 _dbus_string_get_length (&message->header);
00308
00309 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00310 value))
00311 goto failed;
00312
00313 if (!append_header_padding (message))
00314 goto failed;
00315
00316 return TRUE;
00317
00318 failed:
00319 _dbus_string_set_length (&message->header,
00320 message->header_fields[field].name_offset);
00321 message->header_fields[field].name_offset = -1;
00322 message->header_fields[field].value_offset = -1;
00323
00324
00325
00326
00327 if (!append_header_padding (message))
00328 _dbus_assert_not_reached ("failed to reappend header padding");
00329 return FALSE;
00330 }
00331 #endif
00332
00333 static dbus_bool_t
00334 append_uint_field (DBusMessage *message,
00335 int field,
00336 int value)
00337 {
00338 _dbus_assert (!message->locked);
00339
00340 clear_header_padding (message);
00341
00342 message->header_fields[field].name_offset =
00343 _dbus_string_get_length (&message->header);
00344
00345 if (!_dbus_string_append_byte (&message->header, field))
00346 goto failed;
00347
00348 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00349 goto failed;
00350
00351 if (!_dbus_string_align_length (&message->header, 4))
00352 goto failed;
00353
00354 message->header_fields[field].value_offset =
00355 _dbus_string_get_length (&message->header);
00356
00357 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00358 value))
00359 goto failed;
00360
00361 if (!append_header_padding (message))
00362 goto failed;
00363
00364 return TRUE;
00365
00366 failed:
00367 _dbus_string_set_length (&message->header,
00368 message->header_fields[field].name_offset);
00369 message->header_fields[field].name_offset = -1;
00370 message->header_fields[field].value_offset = -1;
00371
00372
00373
00374
00375 if (!append_header_padding (message))
00376 _dbus_assert_not_reached ("failed to reappend header padding");
00377 return FALSE;
00378 }
00379
00380 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 1 + 8)
00381 static dbus_bool_t
00382 append_string_field (DBusMessage *message,
00383 int field,
00384 int type,
00385 const char *value)
00386 {
00387 _dbus_assert (!message->locked);
00388
00389 clear_header_padding (message);
00390
00391 message->header_fields[field].name_offset =
00392 _dbus_string_get_length (&message->header);
00393
00394 if (!_dbus_string_append_byte (&message->header, field))
00395 goto failed;
00396
00397 if (!_dbus_string_append_byte (&message->header, type))
00398 goto failed;
00399
00400 if (!_dbus_string_align_length (&message->header, 4))
00401 goto failed;
00402
00403 message->header_fields[field].value_offset =
00404 _dbus_string_get_length (&message->header);
00405
00406 if (!_dbus_marshal_string (&message->header, message->byte_order,
00407 value))
00408 goto failed;
00409
00410 if (!append_header_padding (message))
00411 goto failed;
00412
00413 return TRUE;
00414
00415 failed:
00416 _dbus_string_set_length (&message->header,
00417 message->header_fields[field].name_offset);
00418 message->header_fields[field].name_offset = -1;
00419 message->header_fields[field].value_offset = -1;
00420
00421
00422
00423
00424 if (!append_header_padding (message))
00425 _dbus_assert_not_reached ("failed to reappend header padding");
00426
00427 return FALSE;
00428 }
00429
00430 static int
00431 get_type_alignment (int type)
00432 {
00433 int alignment;
00434
00435 switch (type)
00436 {
00437 case DBUS_TYPE_NIL:
00438 case DBUS_TYPE_BYTE:
00439 case DBUS_TYPE_BOOLEAN:
00440 alignment = 0;
00441 break;
00442
00443 case DBUS_TYPE_INT32:
00444 case DBUS_TYPE_UINT32:
00445 case DBUS_TYPE_STRING:
00446 case DBUS_TYPE_OBJECT_PATH:
00447
00448
00449
00450 case DBUS_TYPE_CUSTOM:
00451 case DBUS_TYPE_DICT:
00452 alignment = 4;
00453 break;
00454
00455 case DBUS_TYPE_INT64:
00456 case DBUS_TYPE_UINT64:
00457 case DBUS_TYPE_DOUBLE:
00458 alignment = 8;
00459 break;
00460
00461 case DBUS_TYPE_ARRAY:
00462 _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
00463 break;
00464
00465 case DBUS_TYPE_INVALID:
00466 default:
00467 _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
00468 break;
00469 }
00470
00471 return alignment;
00472 }
00473
00474 static dbus_bool_t
00475 iterate_one_field (const DBusString *str,
00476 int byte_order,
00477 int name_offset,
00478 int *next_offset_p,
00479 int *field_name_p,
00480 DBusString *append_copy_to,
00481 int *copy_name_offset_p,
00482 int *copy_value_offset_p)
00483 {
00484 int name, type, array_type;
00485 int alignment;
00486 int type_len;
00487 int type_pos;
00488 int value_pos;
00489 int value_len;
00490 int value_end;
00491 int pos;
00492
00493 _dbus_verbose ("%s: name_offset=%d, append to %p\n",
00494 _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
00495
00496 pos = name_offset;
00497
00498 name = _dbus_string_get_byte (str, name_offset);
00499 pos++;
00500
00501 type_pos = pos;
00502 type = _dbus_string_get_byte (str, type_pos);
00503 pos++;
00504 type_len = 1;
00505
00506 array_type = type;
00507
00508 while (array_type == DBUS_TYPE_ARRAY)
00509 {
00510 pos++;
00511 type_len++;
00512 array_type = _dbus_string_get_byte (str, pos);
00513 }
00514
00515 _dbus_verbose ("%s: name %d, type '%c' %d at %d len %d, array type '%c' %d\n",
00516 _DBUS_FUNCTION_NAME,
00517 name, type, type, type_pos, type_len, array_type, array_type);
00518
00519 #ifndef DBUS_DISABLE_ASSERT
00520 if (!_dbus_type_is_valid (array_type))
00521 {
00522 _dbus_warn ("type '%c' %d is not valid in %s\n",
00523 array_type, array_type, _DBUS_FUNCTION_NAME);
00524 _dbus_assert_not_reached ("invalid type");
00525 }
00526 #endif
00527
00528 alignment = get_type_alignment (array_type);
00529
00530 if (alignment > 0)
00531 pos = _DBUS_ALIGN_VALUE (pos, alignment);
00532
00533 _dbus_verbose ("%s: alignment %d value at pos %d\n",
00534 _DBUS_FUNCTION_NAME, alignment, pos);
00535
00536
00537 if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
00538 type, pos, &value_end))
00539 _dbus_assert_not_reached ("failed to get the byte after this header");
00540
00541 value_pos = pos;
00542 value_len = value_end - value_pos;
00543
00544 _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
00545 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
00546
00547 if (next_offset_p)
00548 *next_offset_p = pos + value_len;
00549
00550 if (field_name_p)
00551 *field_name_p = name;
00552
00553 if (append_copy_to)
00554 {
00555 int orig_len;
00556
00557 orig_len = _dbus_string_get_length (append_copy_to);
00558
00559 if (copy_name_offset_p)
00560 *copy_name_offset_p = orig_len;
00561
00562 if (!_dbus_string_append_byte (append_copy_to, name))
00563 goto failed_copy;
00564
00565 if (!_dbus_string_copy_len (str, type_pos, type_len,
00566 append_copy_to,
00567 _dbus_string_get_length (append_copy_to)))
00568 goto failed_copy;
00569
00570 if (!_dbus_string_align_length (append_copy_to, alignment))
00571 goto failed_copy;
00572
00573 if (copy_value_offset_p)
00574 *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
00575
00576 if (!_dbus_string_copy_len (str, value_pos, value_len,
00577 append_copy_to,
00578 _dbus_string_get_length (append_copy_to)))
00579 goto failed_copy;
00580
00581 return TRUE;
00582
00583 failed_copy:
00584 _dbus_verbose ("%s: Failed copying old fields to new string\n",
00585 _DBUS_FUNCTION_NAME);
00586 _dbus_string_set_length (append_copy_to, orig_len);
00587 return FALSE;
00588 }
00589 else
00590 return TRUE;
00591 }
00592
00593 #ifndef DBUS_DISABLE_ASSERT
00594 static void
00595 verify_header_fields (DBusMessage *message)
00596 {
00597 int i;
00598 i = 0;
00599 while (i < DBUS_HEADER_FIELD_LAST)
00600 {
00601 if (message->header_fields[i].name_offset >= 0)
00602 _dbus_assert (_dbus_string_get_byte (&message->header,
00603 message->header_fields[i].name_offset) ==
00604 i);
00605 ++i;
00606 }
00607 }
00608 #else
00609 #define verify_header_fields(x)
00610 #endif
00611
00612
00613
00614
00615 static dbus_bool_t
00616 delete_one_and_re_align (DBusMessage *message,
00617 int name_offset_to_delete)
00618 {
00619 DBusString copy;
00620 int new_fields_front_padding;
00621 int next_offset;
00622 int field_name;
00623 dbus_bool_t retval;
00624 HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST];
00625
00626 _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
00627 verify_header_fields (message);
00628
00629 _dbus_verbose ("%s: Deleting one field at offset %d\n",
00630 _DBUS_FUNCTION_NAME,
00631 name_offset_to_delete);
00632
00633 retval = FALSE;
00634
00635 clear_header_padding (message);
00636
00637 if (!_dbus_string_init_preallocated (©,
00638 _dbus_string_get_length (&message->header) -
00639 name_offset_to_delete + 8))
00640 {
00641 _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
00642 _DBUS_FUNCTION_NAME);
00643 goto out_0;
00644 }
00645
00646
00647
00648
00649 new_fields_front_padding = name_offset_to_delete % 8;
00650
00651 if (!_dbus_string_insert_bytes (©, 0, new_fields_front_padding,
00652 '\0'))
00653 _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
00654
00655 memcpy (new_header_fields, message->header_fields,
00656 sizeof (new_header_fields));
00657
00658
00659
00660
00661
00662
00663
00664 if (!iterate_one_field (&message->header,
00665 message->byte_order,
00666 name_offset_to_delete,
00667 &next_offset,
00668 &field_name, NULL, NULL, NULL))
00669 _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
00670
00671 if (field_name < DBUS_HEADER_FIELD_LAST)
00672 {
00673 new_header_fields[field_name].name_offset = -1;
00674 new_header_fields[field_name].value_offset = -1;
00675 }
00676
00677 while (next_offset < _dbus_string_get_length (&message->header))
00678 {
00679 int copy_name_offset;
00680 int copy_value_offset;
00681
00682 if (!iterate_one_field (&message->header,
00683 message->byte_order,
00684 next_offset,
00685 &next_offset,
00686 &field_name,
00687 ©,
00688 ©_name_offset,
00689 ©_value_offset))
00690 {
00691 _dbus_verbose ("%s: OOM iterating one field\n",
00692 _DBUS_FUNCTION_NAME);
00693 goto out_1;
00694 }
00695
00696 if (field_name < DBUS_HEADER_FIELD_LAST)
00697 {
00698 new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
00699 new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
00700 }
00701 }
00702
00703 if (!_dbus_string_replace_len (©,
00704 new_fields_front_padding,
00705 _dbus_string_get_length (©) - new_fields_front_padding,
00706 &message->header,
00707 name_offset_to_delete,
00708 _dbus_string_get_length (&message->header) - name_offset_to_delete))
00709 {
00710 _dbus_verbose ("%s: OOM moving copy back into header\n",
00711 _DBUS_FUNCTION_NAME);
00712 goto out_1;
00713 }
00714
00715 memcpy (message->header_fields, new_header_fields,
00716 sizeof (new_header_fields));
00717 verify_header_fields (message);
00718
00719 retval = TRUE;
00720
00721 out_1:
00722 _dbus_string_free (©);
00723
00724 out_0:
00725 if (!append_header_padding (message))
00726 _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
00727
00728 return retval;
00729 }
00730
00731 static dbus_bool_t
00732 delete_field (DBusMessage *message,
00733 int field,
00734 int prealloc_header_space)
00735 {
00736 int offset;
00737
00738 _dbus_assert (!message->locked);
00739
00740
00741 if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
00742 {
00743 _dbus_verbose ("failed to prealloc %d bytes header space\n",
00744 prealloc_header_space);
00745 return FALSE;
00746 }
00747 _dbus_string_shorten (&message->header, prealloc_header_space);
00748
00749
00750 offset = message->header_fields[field].name_offset;
00751 if (offset < 0)
00752 {
00753 _dbus_verbose ("header field didn't exist, no need to delete\n");
00754 return TRUE;
00755 }
00756
00757 return delete_one_and_re_align (message, offset);
00758 }
00759
00760 #ifdef DBUS_BUILD_TESTS
00761 static dbus_bool_t
00762 set_int_field (DBusMessage *message,
00763 int field,
00764 int value)
00765 {
00766 int offset = message->header_fields[field].value_offset;
00767
00768 _dbus_assert (!message->locked);
00769
00770 if (offset < 0)
00771 {
00772
00773 return append_int_field (message, field, value);
00774 }
00775 else
00776 {
00777 _dbus_marshal_set_int32 (&message->header,
00778 message->byte_order,
00779 offset, value);
00780
00781 return TRUE;
00782 }
00783 }
00784 #endif
00785
00786 static dbus_bool_t
00787 set_uint_field (DBusMessage *message,
00788 int field,
00789 dbus_uint32_t value)
00790 {
00791 int offset = message->header_fields[field].value_offset;
00792
00793 _dbus_assert (!message->locked);
00794
00795 if (offset < 0)
00796 {
00797
00798 return append_uint_field (message, field, value);
00799 }
00800 else
00801 {
00802 _dbus_marshal_set_uint32 (&message->header,
00803 message->byte_order,
00804 offset, value);
00805
00806 return TRUE;
00807 }
00808 }
00809
00810 static dbus_bool_t
00811 set_string_field (DBusMessage *message,
00812 int field,
00813 int type,
00814 const char *value)
00815 {
00816 int prealloc;
00817
00818 _dbus_assert (!message->locked);
00819
00820
00821
00822
00823 prealloc = (value ? strlen (value) : 0) + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
00824
00825 _dbus_verbose ("set_string_field() field %d prealloc %d\n",
00826 field, prealloc);
00827
00828 if (!delete_field (message, field, prealloc))
00829 return FALSE;
00830
00831 if (value != NULL)
00832 {
00833
00834 if (!append_string_field (message, field, type, value))
00835 _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
00836 }
00837
00838 return TRUE;
00839 }
00840
00848 void
00849 _dbus_message_set_serial (DBusMessage *message,
00850 dbus_int32_t serial)
00851 {
00852 _dbus_assert (!message->locked);
00853 _dbus_assert (dbus_message_get_serial (message) == 0);
00854
00855 _dbus_marshal_set_uint32 (&message->header,
00856 message->byte_order,
00857 CLIENT_SERIAL_OFFSET,
00858 serial);
00859
00860 message->client_serial = serial;
00861 }
00862
00871 dbus_bool_t
00872 dbus_message_set_reply_serial (DBusMessage *message,
00873 dbus_uint32_t reply_serial)
00874 {
00875 _dbus_assert (!message->locked);
00876
00877 if (set_uint_field (message,
00878 DBUS_HEADER_FIELD_REPLY_SERIAL,
00879 reply_serial))
00880 {
00881 message->reply_serial = reply_serial;
00882 return TRUE;
00883 }
00884 else
00885 return FALSE;
00886 }
00887
00898 dbus_uint32_t
00899 dbus_message_get_serial (DBusMessage *message)
00900 {
00901 return message->client_serial;
00902 }
00903
00910 dbus_uint32_t
00911 dbus_message_get_reply_serial (DBusMessage *message)
00912 {
00913 return message->reply_serial;
00914 }
00915
00928 void
00929 _dbus_message_add_size_counter_link (DBusMessage *message,
00930 DBusList *link)
00931 {
00932
00933
00934
00935
00936
00937
00938 if (message->size_counters == NULL)
00939 {
00940 message->size_counter_delta =
00941 _dbus_string_get_length (&message->header) +
00942 _dbus_string_get_length (&message->body);
00943
00944 #if 0
00945 _dbus_verbose ("message has size %ld\n",
00946 message->size_counter_delta);
00947 #endif
00948 }
00949
00950 _dbus_list_append_link (&message->size_counters, link);
00951
00952 _dbus_counter_adjust (link->data, message->size_counter_delta);
00953 }
00954
00964 dbus_bool_t
00965 _dbus_message_add_size_counter (DBusMessage *message,
00966 DBusCounter *counter)
00967 {
00968 DBusList *link;
00969
00970 link = _dbus_list_alloc_link (counter);
00971 if (link == NULL)
00972 return FALSE;
00973
00974 _dbus_counter_ref (counter);
00975 _dbus_message_add_size_counter_link (message, link);
00976
00977 return TRUE;
00978 }
00979
00988 void
00989 _dbus_message_remove_size_counter (DBusMessage *message,
00990 DBusCounter *counter,
00991 DBusList **link_return)
00992 {
00993 DBusList *link;
00994
00995 link = _dbus_list_find_last (&message->size_counters,
00996 counter);
00997 _dbus_assert (link != NULL);
00998
00999 _dbus_list_unlink (&message->size_counters,
01000 link);
01001 if (link_return)
01002 *link_return = link;
01003 else
01004 _dbus_list_free_link (link);
01005
01006 _dbus_counter_adjust (counter, message->size_counter_delta);
01007
01008 _dbus_counter_unref (counter);
01009 }
01010
01011 static dbus_bool_t
01012 dbus_message_create_header (DBusMessage *message,
01013 int type,
01014 const char *service,
01015 const char *path,
01016 const char *interface,
01017 const char *member,
01018 const char *error_name)
01019 {
01020 unsigned int flags;
01021
01022 _dbus_assert ((interface && member) ||
01023 (error_name) ||
01024 !(interface || member || error_name));
01025
01026 if (!_dbus_string_append_byte (&message->header, message->byte_order))
01027 return FALSE;
01028
01029 if (!_dbus_string_append_byte (&message->header, type))
01030 return FALSE;
01031
01032 flags = 0;
01033 if (!_dbus_string_append_byte (&message->header, flags))
01034 return FALSE;
01035
01036 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
01037 return FALSE;
01038
01039
01040 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01041 return FALSE;
01042
01043
01044 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01045 return FALSE;
01046
01047
01048 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01049 return FALSE;
01050
01051
01052
01053 if (path != NULL)
01054 {
01055 if (!append_string_field (message,
01056 DBUS_HEADER_FIELD_PATH,
01057 DBUS_TYPE_OBJECT_PATH,
01058 path))
01059 return FALSE;
01060 }
01061
01062 if (service != NULL)
01063 {
01064 if (!append_string_field (message,
01065 DBUS_HEADER_FIELD_SERVICE,
01066 DBUS_TYPE_STRING,
01067 service))
01068 return FALSE;
01069 }
01070
01071 if (interface != NULL)
01072 {
01073 if (!append_string_field (message,
01074 DBUS_HEADER_FIELD_INTERFACE,
01075 DBUS_TYPE_STRING,
01076 interface))
01077 return FALSE;
01078 }
01079
01080 if (member != NULL)
01081 {
01082 if (!append_string_field (message,
01083 DBUS_HEADER_FIELD_MEMBER,
01084 DBUS_TYPE_STRING,
01085 member))
01086 return FALSE;
01087 }
01088
01089 if (error_name != NULL)
01090 {
01091 if (!append_string_field (message,
01092 DBUS_HEADER_FIELD_ERROR_NAME,
01093 DBUS_TYPE_STRING,
01094 error_name))
01095 return FALSE;
01096 }
01097
01098 return TRUE;
01099 }
01100
01110 void
01111 _dbus_message_lock (DBusMessage *message)
01112 {
01113 if (!message->locked)
01114 {
01115
01116 _dbus_marshal_set_uint32 (&message->header,
01117 message->byte_order,
01118 HEADER_LENGTH_OFFSET,
01119 _dbus_string_get_length (&message->header));
01120
01121 _dbus_marshal_set_uint32 (&message->header,
01122 message->byte_order,
01123 BODY_LENGTH_OFFSET,
01124 _dbus_string_get_length (&message->body));
01125
01126 message->locked = TRUE;
01127 }
01128 }
01129
01152 static DBusMessage*
01153 dbus_message_new_empty_header (void)
01154 {
01155 DBusMessage *message;
01156 int i;
01157
01158 message = dbus_new0 (DBusMessage, 1);
01159 if (message == NULL)
01160 return NULL;
01161
01162 message->refcount.value = 1;
01163 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01164 message->client_serial = 0;
01165 message->reply_serial = 0;
01166
01167 _dbus_data_slot_list_init (&message->slot_list);
01168
01169 i = 0;
01170 while (i <= DBUS_HEADER_FIELD_LAST)
01171 {
01172 message->header_fields[i].name_offset = -1;
01173 message->header_fields[i].value_offset = -1;
01174 ++i;
01175 }
01176
01177 if (!_dbus_string_init_preallocated (&message->header, 64))
01178 {
01179 dbus_free (message);
01180 return NULL;
01181 }
01182
01183 if (!_dbus_string_init_preallocated (&message->body, 64))
01184 {
01185 _dbus_string_free (&message->header);
01186 dbus_free (message);
01187 return NULL;
01188 }
01189
01190 if (!_dbus_string_init_preallocated (&message->signature, 4))
01191 {
01192 _dbus_string_free (&message->header);
01193 _dbus_string_free (&message->body);
01194 dbus_free (message);
01195 return NULL;
01196 }
01197
01198 return message;
01199 }
01200
01209 DBusMessage*
01210 dbus_message_new (int message_type)
01211 {
01212 DBusMessage *message;
01213
01214 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01215
01216 message = dbus_message_new_empty_header ();
01217 if (message == NULL)
01218 return NULL;
01219
01220 if (!dbus_message_create_header (message,
01221 message_type,
01222 NULL, NULL, NULL, NULL, NULL))
01223 {
01224 dbus_message_unref (message);
01225 return NULL;
01226 }
01227
01228 return message;
01229 }
01230
01248 DBusMessage*
01249 dbus_message_new_method_call (const char *service,
01250 const char *path,
01251 const char *interface,
01252 const char *method)
01253 {
01254 DBusMessage *message;
01255
01256 _dbus_return_val_if_fail (path != NULL, NULL);
01257 _dbus_return_val_if_fail (method != NULL, NULL);
01258
01259 message = dbus_message_new_empty_header ();
01260 if (message == NULL)
01261 return NULL;
01262
01263 if (!dbus_message_create_header (message,
01264 DBUS_MESSAGE_TYPE_METHOD_CALL,
01265 service, path, interface, method, NULL))
01266 {
01267 dbus_message_unref (message);
01268 return NULL;
01269 }
01270
01271 return message;
01272 }
01273
01283 DBusMessage*
01284 dbus_message_new_method_return (DBusMessage *method_call)
01285 {
01286 DBusMessage *message;
01287 const char *sender;
01288
01289 _dbus_return_val_if_fail (method_call != NULL, NULL);
01290
01291 sender = get_string_field (method_call,
01292 DBUS_HEADER_FIELD_SENDER_SERVICE,
01293 NULL);
01294
01295
01296
01297 message = dbus_message_new_empty_header ();
01298 if (message == NULL)
01299 return NULL;
01300
01301 if (!dbus_message_create_header (message,
01302 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01303 sender, NULL, NULL, NULL, NULL))
01304 {
01305 dbus_message_unref (message);
01306 return NULL;
01307 }
01308
01309 dbus_message_set_no_reply (message, TRUE);
01310
01311 if (!dbus_message_set_reply_serial (message,
01312 dbus_message_get_serial (method_call)))
01313 {
01314 dbus_message_unref (message);
01315 return NULL;
01316 }
01317
01318 return message;
01319 }
01320
01333 DBusMessage*
01334 dbus_message_new_signal (const char *path,
01335 const char *interface,
01336 const char *name)
01337 {
01338 DBusMessage *message;
01339
01340 _dbus_return_val_if_fail (path != NULL, NULL);
01341 _dbus_return_val_if_fail (interface != NULL, NULL);
01342 _dbus_return_val_if_fail (name != NULL, NULL);
01343
01344 message = dbus_message_new_empty_header ();
01345 if (message == NULL)
01346 return NULL;
01347
01348 if (!dbus_message_create_header (message,
01349 DBUS_MESSAGE_TYPE_SIGNAL,
01350 NULL, path, interface, name, NULL))
01351 {
01352 dbus_message_unref (message);
01353 return NULL;
01354 }
01355
01356 dbus_message_set_no_reply (message, TRUE);
01357
01358 return message;
01359 }
01360
01370 DBusMessage*
01371 dbus_message_new_error (DBusMessage *reply_to,
01372 const char *error_name,
01373 const char *error_message)
01374 {
01375 DBusMessage *message;
01376 const char *sender;
01377 DBusMessageIter iter;
01378
01379 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01380 _dbus_return_val_if_fail (error_name != NULL, NULL);
01381
01382 sender = get_string_field (reply_to,
01383 DBUS_HEADER_FIELD_SENDER_SERVICE,
01384 NULL);
01385
01386
01387
01388
01389
01390 message = dbus_message_new_empty_header ();
01391 if (message == NULL)
01392 return NULL;
01393
01394 if (!dbus_message_create_header (message,
01395 DBUS_MESSAGE_TYPE_ERROR,
01396 sender, NULL, NULL, NULL, error_name))
01397 {
01398 dbus_message_unref (message);
01399 return NULL;
01400 }
01401
01402 dbus_message_set_no_reply (message, TRUE);
01403
01404 if (!dbus_message_set_reply_serial (message,
01405 dbus_message_get_serial (reply_to)))
01406 {
01407 dbus_message_unref (message);
01408 return NULL;
01409 }
01410
01411 if (error_message != NULL)
01412 {
01413 dbus_message_append_iter_init (message, &iter);
01414 if (!dbus_message_iter_append_string (&iter, error_message))
01415 {
01416 dbus_message_unref (message);
01417 return NULL;
01418 }
01419 }
01420
01421 return message;
01422 }
01423
01431 DBusMessage *
01432 dbus_message_copy (const DBusMessage *message)
01433 {
01434 DBusMessage *retval;
01435 int i;
01436
01437 _dbus_return_val_if_fail (message != NULL, NULL);
01438
01439 retval = dbus_new0 (DBusMessage, 1);
01440 if (retval == NULL)
01441 return NULL;
01442
01443 retval->refcount.value = 1;
01444 retval->byte_order = message->byte_order;
01445 retval->client_serial = message->client_serial;
01446 retval->reply_serial = message->reply_serial;
01447 retval->header_padding = message->header_padding;
01448 retval->locked = FALSE;
01449
01450 if (!_dbus_string_init_preallocated (&retval->header,
01451 _dbus_string_get_length (&message->header)))
01452 {
01453 dbus_free (retval);
01454 return NULL;
01455 }
01456
01457 if (!_dbus_string_init_preallocated (&retval->body,
01458 _dbus_string_get_length (&message->body)))
01459 {
01460 _dbus_string_free (&retval->header);
01461 dbus_free (retval);
01462 return NULL;
01463 }
01464
01465 if (!_dbus_string_init_preallocated (&retval->signature,
01466 _dbus_string_get_length (&message->signature)))
01467 {
01468 _dbus_string_free (&retval->header);
01469 _dbus_string_free (&retval->body);
01470 dbus_free (retval);
01471 return NULL;
01472 }
01473
01474 if (!_dbus_string_copy (&message->header, 0,
01475 &retval->header, 0))
01476 goto failed_copy;
01477
01478 if (!_dbus_string_copy (&message->body, 0,
01479 &retval->body, 0))
01480 goto failed_copy;
01481
01482 if (!_dbus_string_copy (&message->signature, 0,
01483 &retval->signature, 0))
01484 goto failed_copy;
01485
01486 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
01487 {
01488 retval->header_fields[i] = message->header_fields[i];
01489 }
01490
01491 return retval;
01492
01493 failed_copy:
01494 _dbus_string_free (&retval->header);
01495 _dbus_string_free (&retval->body);
01496 _dbus_string_free (&retval->signature);
01497 dbus_free (retval);
01498
01499 return NULL;
01500 }
01501
01502
01509 void
01510 dbus_message_ref (DBusMessage *message)
01511 {
01512 dbus_int32_t old_refcount;
01513
01514 _dbus_return_if_fail (message != NULL);
01515
01516 old_refcount = _dbus_atomic_inc (&message->refcount);
01517 _dbus_assert (old_refcount >= 1);
01518 }
01519
01520 static void
01521 free_size_counter (void *element,
01522 void *data)
01523 {
01524 DBusCounter *counter = element;
01525 DBusMessage *message = data;
01526
01527 _dbus_counter_adjust (counter, - message->size_counter_delta);
01528
01529 _dbus_counter_unref (counter);
01530 }
01531
01538 void
01539 dbus_message_unref (DBusMessage *message)
01540 {
01541 dbus_int32_t old_refcount;
01542
01543 _dbus_return_if_fail (message != NULL);
01544
01545 old_refcount = _dbus_atomic_dec (&message->refcount);
01546
01547 _dbus_assert (old_refcount >= 0);
01548
01549 if (old_refcount == 1)
01550 {
01551
01552 _dbus_data_slot_list_free (&message->slot_list);
01553
01554 _dbus_list_foreach (&message->size_counters,
01555 free_size_counter, message);
01556 _dbus_list_clear (&message->size_counters);
01557
01558 _dbus_string_free (&message->header);
01559 _dbus_string_free (&message->body);
01560 _dbus_string_free (&message->signature);
01561
01562 dbus_free (message);
01563 }
01564 }
01565
01577 int
01578 dbus_message_get_type (DBusMessage *message)
01579 {
01580 int type;
01581
01582 type = _dbus_string_get_byte (&message->header, 1);
01583 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
01584
01585 return type;
01586 }
01587
01597 dbus_bool_t
01598 dbus_message_set_path (DBusMessage *message,
01599 const char *object_path)
01600 {
01601 _dbus_return_val_if_fail (message != NULL, FALSE);
01602 _dbus_return_val_if_fail (!message->locked, FALSE);
01603
01604 return set_string_field (message,
01605 DBUS_HEADER_FIELD_PATH,
01606 DBUS_TYPE_OBJECT_PATH,
01607 object_path);
01608 }
01609
01618 const char*
01619 dbus_message_get_path (DBusMessage *message)
01620 {
01621 _dbus_return_val_if_fail (message != NULL, NULL);
01622
01623 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
01624 }
01625
01641 dbus_bool_t
01642 dbus_message_get_path_decomposed (DBusMessage *message,
01643 char ***path)
01644 {
01645 _dbus_return_val_if_fail (message != NULL, FALSE);
01646 _dbus_return_val_if_fail (path != NULL, FALSE);
01647
01648 return get_path_field_decomposed (message,
01649 DBUS_HEADER_FIELD_PATH,
01650 path);
01651 }
01652
01663 dbus_bool_t
01664 dbus_message_set_interface (DBusMessage *message,
01665 const char *interface)
01666 {
01667 _dbus_return_val_if_fail (message != NULL, FALSE);
01668 _dbus_return_val_if_fail (!message->locked, FALSE);
01669
01670 return set_string_field (message,
01671 DBUS_HEADER_FIELD_INTERFACE,
01672 DBUS_TYPE_STRING,
01673 interface);
01674 }
01675
01685 const char*
01686 dbus_message_get_interface (DBusMessage *message)
01687 {
01688 _dbus_return_val_if_fail (message != NULL, NULL);
01689
01690 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
01691 }
01692
01703 dbus_bool_t
01704 dbus_message_set_member (DBusMessage *message,
01705 const char *member)
01706 {
01707 _dbus_return_val_if_fail (message != NULL, FALSE);
01708 _dbus_return_val_if_fail (!message->locked, FALSE);
01709
01710 return set_string_field (message,
01711 DBUS_HEADER_FIELD_MEMBER,
01712 DBUS_TYPE_STRING,
01713 member);
01714 }
01715
01724 const char*
01725 dbus_message_get_member (DBusMessage *message)
01726 {
01727 _dbus_return_val_if_fail (message != NULL, NULL);
01728
01729 return get_string_field (message,
01730 DBUS_HEADER_FIELD_MEMBER,
01731 NULL);
01732 }
01733
01742 dbus_bool_t
01743 dbus_message_set_error_name (DBusMessage *message,
01744 const char *error_name)
01745 {
01746 _dbus_return_val_if_fail (message != NULL, FALSE);
01747 _dbus_return_val_if_fail (!message->locked, FALSE);
01748
01749 return set_string_field (message,
01750 DBUS_HEADER_FIELD_ERROR_NAME,
01751 DBUS_TYPE_STRING,
01752 error_name);
01753 }
01754
01761 const char*
01762 dbus_message_get_error_name (DBusMessage *message)
01763 {
01764 _dbus_return_val_if_fail (message != NULL, NULL);
01765
01766 return get_string_field (message,
01767 DBUS_HEADER_FIELD_ERROR_NAME,
01768 NULL);
01769 }
01770
01778 dbus_bool_t
01779 dbus_message_set_destination (DBusMessage *message,
01780 const char *destination)
01781 {
01782 _dbus_return_val_if_fail (message != NULL, FALSE);
01783 _dbus_return_val_if_fail (!message->locked, FALSE);
01784
01785 return set_string_field (message,
01786 DBUS_HEADER_FIELD_SERVICE,
01787 DBUS_TYPE_STRING,
01788 destination);
01789 }
01790
01797 const char*
01798 dbus_message_get_destination (DBusMessage *message)
01799 {
01800 _dbus_return_val_if_fail (message != NULL, NULL);
01801
01802 return get_string_field (message,
01803 DBUS_HEADER_FIELD_SERVICE,
01804 NULL);
01805 }
01806
01825 dbus_bool_t
01826 dbus_message_append_args (DBusMessage *message,
01827 int first_arg_type,
01828 ...)
01829 {
01830 dbus_bool_t retval;
01831 va_list var_args;
01832
01833 _dbus_return_val_if_fail (message != NULL, FALSE);
01834
01835 va_start (var_args, first_arg_type);
01836 retval = dbus_message_append_args_valist (message,
01837 first_arg_type,
01838 var_args);
01839 va_end (var_args);
01840
01841 return retval;
01842 }
01843
01857 dbus_bool_t
01858 dbus_message_append_args_valist (DBusMessage *message,
01859 int first_arg_type,
01860 va_list var_args)
01861 {
01862 int type, old_len;
01863 DBusMessageIter iter;
01864
01865 _dbus_return_val_if_fail (message != NULL, FALSE);
01866
01867 old_len = _dbus_string_get_length (&message->body);
01868
01869 type = first_arg_type;
01870
01871 dbus_message_append_iter_init (message, &iter);
01872
01873 while (type != DBUS_TYPE_INVALID)
01874 {
01875 switch (type)
01876 {
01877 case DBUS_TYPE_NIL:
01878 if (!dbus_message_iter_append_nil (&iter))
01879 goto errorout;
01880 break;
01881 case DBUS_TYPE_BOOLEAN:
01882 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
01883 goto errorout;
01884 break;
01885 case DBUS_TYPE_INT32:
01886 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
01887 goto errorout;
01888 break;
01889 case DBUS_TYPE_UINT32:
01890 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
01891 goto errorout;
01892 break;
01893 #ifdef DBUS_HAVE_INT64
01894 case DBUS_TYPE_INT64:
01895 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
01896 goto errorout;
01897 break;
01898 case DBUS_TYPE_UINT64:
01899 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
01900 goto errorout;
01901 break;
01902 #endif
01903 case DBUS_TYPE_DOUBLE:
01904 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
01905 goto errorout;
01906 break;
01907 case DBUS_TYPE_STRING:
01908 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
01909 goto errorout;
01910 break;
01911 case DBUS_TYPE_OBJECT_PATH:
01912
01913 break;
01914 case DBUS_TYPE_CUSTOM:
01915 {
01916 const char *name;
01917 unsigned char *data;
01918 int len;
01919
01920 name = va_arg (var_args, const char *);
01921 data = va_arg (var_args, unsigned char *);
01922 len = va_arg (var_args, int);
01923
01924 if (!dbus_message_iter_append_custom (&iter, name, data, len))
01925 goto errorout;
01926 break;
01927 }
01928 case DBUS_TYPE_ARRAY:
01929 {
01930 void *data;
01931 int len, type;
01932
01933 type = va_arg (var_args, int);
01934 data = va_arg (var_args, void *);
01935 len = va_arg (var_args, int);
01936
01937 switch (type)
01938 {
01939 case DBUS_TYPE_BYTE:
01940 if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len))
01941 goto errorout;
01942 break;
01943 case DBUS_TYPE_BOOLEAN:
01944 if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len))
01945 goto errorout;
01946 break;
01947 case DBUS_TYPE_INT32:
01948 if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len))
01949 goto errorout;
01950 break;
01951 case DBUS_TYPE_UINT32:
01952 if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len))
01953 goto errorout;
01954 break;
01955 #ifdef DBUS_HAVE_INT64
01956 case DBUS_TYPE_INT64:
01957 if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len))
01958 goto errorout;
01959 break;
01960 case DBUS_TYPE_UINT64:
01961 if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len))
01962 goto errorout;
01963 break;
01964 #endif
01965 case DBUS_TYPE_DOUBLE:
01966 if (!dbus_message_iter_append_double_array (&iter, (double *)data, len))
01967 goto errorout;
01968 break;
01969 case DBUS_TYPE_STRING:
01970 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
01971 goto errorout;
01972 break;
01973 case DBUS_TYPE_NIL:
01974 case DBUS_TYPE_ARRAY:
01975 case DBUS_TYPE_CUSTOM:
01976 case DBUS_TYPE_DICT:
01977 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
01978 goto errorout;
01979 default:
01980 _dbus_warn ("Unknown field type %d\n", type);
01981 goto errorout;
01982 }
01983 }
01984 break;
01985
01986 case DBUS_TYPE_DICT:
01987 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
01988 goto errorout;
01989 default:
01990 _dbus_warn ("Unknown field type %d\n", type);
01991 goto errorout;
01992 }
01993
01994 type = va_arg (var_args, int);
01995 }
01996
01997 return TRUE;
01998
01999 errorout:
02000 return FALSE;
02001 }
02002
02003
02016 dbus_bool_t
02017 dbus_message_get_args (DBusMessage *message,
02018 DBusError *error,
02019 int first_arg_type,
02020 ...)
02021 {
02022 dbus_bool_t retval;
02023 va_list var_args;
02024
02025 _dbus_return_val_if_fail (message != NULL, FALSE);
02026 _dbus_return_val_if_error_is_set (error, FALSE);
02027
02028 va_start (var_args, first_arg_type);
02029 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02030 va_end (var_args);
02031
02032 return retval;
02033 }
02034
02047 dbus_bool_t
02048 dbus_message_get_args_valist (DBusMessage *message,
02049 DBusError *error,
02050 int first_arg_type,
02051 va_list var_args)
02052 {
02053 DBusMessageIter iter;
02054
02055 _dbus_return_val_if_fail (message != NULL, FALSE);
02056 _dbus_return_val_if_error_is_set (error, FALSE);
02057
02058 dbus_message_iter_init (message, &iter);
02059 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02060 }
02061
02074 dbus_bool_t
02075 dbus_message_iter_get_args (DBusMessageIter *iter,
02076 DBusError *error,
02077 int first_arg_type,
02078 ...)
02079 {
02080 dbus_bool_t retval;
02081 va_list var_args;
02082
02083 _dbus_return_val_if_fail (iter != NULL, FALSE);
02084 _dbus_return_val_if_error_is_set (error, FALSE);
02085
02086 va_start (var_args, first_arg_type);
02087 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
02088 va_end (var_args);
02089
02090 return retval;
02091 }
02092
02115 dbus_bool_t
02116 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
02117 DBusError *error,
02118 int first_arg_type,
02119 va_list var_args)
02120 {
02121 int spec_type, msg_type, i;
02122 dbus_bool_t retval;
02123
02124 _dbus_return_val_if_fail (iter != NULL, FALSE);
02125 _dbus_return_val_if_error_is_set (error, FALSE);
02126
02127 retval = FALSE;
02128
02129 spec_type = first_arg_type;
02130 i = 0;
02131
02132 while (spec_type != 0)
02133 {
02134 msg_type = dbus_message_iter_get_arg_type (iter);
02135
02136 if (msg_type != spec_type)
02137 {
02138 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02139 "Argument %d is specified to be of type \"%s\", but "
02140 "is actually of type \"%s\"\n", i,
02141 _dbus_type_to_string (spec_type),
02142 _dbus_type_to_string (msg_type));
02143
02144 goto out;
02145 }
02146
02147 switch (spec_type)
02148 {
02149 case DBUS_TYPE_NIL:
02150 break;
02151 case DBUS_TYPE_BYTE:
02152 {
02153 unsigned char *ptr;
02154
02155 ptr = va_arg (var_args, unsigned char *);
02156
02157 *ptr = dbus_message_iter_get_byte (iter);
02158 break;
02159 }
02160 case DBUS_TYPE_BOOLEAN:
02161 {
02162 dbus_bool_t *ptr;
02163
02164 ptr = va_arg (var_args, dbus_bool_t *);
02165
02166 *ptr = dbus_message_iter_get_boolean (iter);
02167 break;
02168 }
02169 case DBUS_TYPE_INT32:
02170 {
02171 dbus_int32_t *ptr;
02172
02173 ptr = va_arg (var_args, dbus_int32_t *);
02174
02175 *ptr = dbus_message_iter_get_int32 (iter);
02176 break;
02177 }
02178 case DBUS_TYPE_UINT32:
02179 {
02180 dbus_uint32_t *ptr;
02181
02182 ptr = va_arg (var_args, dbus_uint32_t *);
02183
02184 *ptr = dbus_message_iter_get_uint32 (iter);
02185 break;
02186 }
02187 #ifdef DBUS_HAVE_INT64
02188 case DBUS_TYPE_INT64:
02189 {
02190 dbus_int64_t *ptr;
02191
02192 ptr = va_arg (var_args, dbus_int64_t *);
02193
02194 *ptr = dbus_message_iter_get_int64 (iter);
02195 break;
02196 }
02197 case DBUS_TYPE_UINT64:
02198 {
02199 dbus_uint64_t *ptr;
02200
02201 ptr = va_arg (var_args, dbus_uint64_t *);
02202
02203 *ptr = dbus_message_iter_get_uint64 (iter);
02204 break;
02205 }
02206 #endif
02207
02208 case DBUS_TYPE_DOUBLE:
02209 {
02210 double *ptr;
02211
02212 ptr = va_arg (var_args, double *);
02213
02214 *ptr = dbus_message_iter_get_double (iter);
02215 break;
02216 }
02217
02218 case DBUS_TYPE_STRING:
02219 {
02220 char **ptr;
02221
02222 ptr = va_arg (var_args, char **);
02223
02224 *ptr = dbus_message_iter_get_string (iter);
02225
02226 if (!*ptr)
02227 {
02228 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02229 goto out;
02230 }
02231
02232 break;
02233 }
02234
02235 case DBUS_TYPE_CUSTOM:
02236 {
02237 char **name;
02238 unsigned char **data;
02239 int *len;
02240
02241 name = va_arg (var_args, char **);
02242 data = va_arg (var_args, unsigned char **);
02243 len = va_arg (var_args, int *);
02244
02245 if (!dbus_message_iter_get_custom (iter, name, data, len))
02246 {
02247 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02248 goto out;
02249 }
02250 }
02251 break;
02252 case DBUS_TYPE_ARRAY:
02253 {
02254 void **data;
02255 int *len, type;
02256
02257 type = va_arg (var_args, int);
02258 data = va_arg (var_args, void *);
02259 len = va_arg (var_args, int *);
02260
02261 _dbus_return_val_if_fail (data != NULL, FALSE);
02262 _dbus_return_val_if_fail (len != NULL, FALSE);
02263
02264 if (dbus_message_iter_get_array_type (iter) != type)
02265 {
02266 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02267 "Argument %d is specified to be of type \"array of %s\", but "
02268 "is actually of type \"array of %s\"\n", i,
02269 _dbus_type_to_string (type),
02270 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
02271 goto out;
02272 }
02273
02274 switch (type)
02275 {
02276 case DBUS_TYPE_BYTE:
02277 if (!dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len))
02278 {
02279 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02280 goto out;
02281 }
02282 break;
02283 case DBUS_TYPE_BOOLEAN:
02284 if (!dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len))
02285 {
02286 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02287 goto out;
02288 }
02289 break;
02290 case DBUS_TYPE_INT32:
02291 if (!dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len))
02292 {
02293 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02294 goto out;
02295 }
02296 break;
02297 case DBUS_TYPE_UINT32:
02298 if (!dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len))
02299 {
02300 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02301 goto out;
02302 }
02303 break;
02304 #ifdef DBUS_HAVE_INT64
02305 case DBUS_TYPE_INT64:
02306 if (!dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len))
02307 {
02308 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02309 goto out;
02310 }
02311 break;
02312 case DBUS_TYPE_UINT64:
02313 if (!dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len))
02314 {
02315 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02316 goto out;
02317 }
02318 break;
02319 #endif
02320 case DBUS_TYPE_DOUBLE:
02321 if (!dbus_message_iter_get_double_array (iter, (double **)data, len))
02322 {
02323 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02324 goto out;
02325 }
02326 break;
02327 case DBUS_TYPE_STRING:
02328 if (!dbus_message_iter_get_string_array (iter, (char ***)data, len))
02329 {
02330 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02331 goto out;
02332 }
02333 break;
02334 case DBUS_TYPE_NIL:
02335 case DBUS_TYPE_ARRAY:
02336 case DBUS_TYPE_CUSTOM:
02337 case DBUS_TYPE_DICT:
02338 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
02339 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02340 goto out;
02341 default:
02342 _dbus_warn ("Unknown field type %d\n", type);
02343 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02344 goto out;
02345 }
02346 }
02347 break;
02348 case DBUS_TYPE_DICT:
02349 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
02350 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02351 goto out;
02352 default:
02353 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02354 _dbus_warn ("Unknown field type %d\n", spec_type);
02355 goto out;
02356 }
02357
02358 spec_type = va_arg (var_args, int);
02359 if (spec_type != 0 && !dbus_message_iter_next (iter))
02360 {
02361 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02362 "Message has only %d arguments, but more were expected", i);
02363 goto out;
02364 }
02365
02366 i++;
02367 }
02368
02369 retval = TRUE;
02370
02371 out:
02372
02373 return retval;
02374 }
02375
02376
02384 void
02385 dbus_message_iter_init (DBusMessage *message,
02386 DBusMessageIter *iter)
02387 {
02388 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02389
02390 _dbus_return_if_fail (message != NULL);
02391 _dbus_return_if_fail (iter != NULL);
02392
02393 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02394
02395 real->message = message;
02396 real->parent_iter = NULL;
02397 real->changed_stamp = message->changed_stamp;
02398
02399 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02400 real->pos = 0;
02401 real->end = _dbus_string_get_length (&message->body);
02402
02403 real->container_start = 0;
02404 real->container_length_pos = 0;
02405 real->wrote_dict_key = 0;
02406 real->array_type_pos = 0;
02407 }
02408
02409 #ifndef DBUS_DISABLE_CHECKS
02410 static dbus_bool_t
02411 dbus_message_iter_check (DBusMessageRealIter *iter)
02412 {
02413 if (iter == NULL)
02414 {
02415 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
02416 return FALSE;
02417 }
02418
02419 if (iter->changed_stamp != iter->message->changed_stamp)
02420 {
02421 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
02422 return FALSE;
02423 }
02424
02425 if (iter->pos < 0 || iter->pos > iter->end)
02426 {
02427 _dbus_warn ("dbus iterator check failed: invalid position\n");
02428 return FALSE;
02429 }
02430
02431 return TRUE;
02432 }
02433 #endif
02434
02435 static int
02436 skip_array_type (DBusMessageRealIter *iter, int pos)
02437 {
02438 const char *data;
02439
02440 do
02441 {
02442 data = _dbus_string_get_const_data_len (&iter->message->body,
02443 pos++, 1);
02444 }
02445 while (*data == DBUS_TYPE_ARRAY);
02446
02447 return pos;
02448 }
02449
02450
02451
02452
02453 static int
02454 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
02455 {
02456 const char *data;
02457 int pos, len;
02458
02459 switch (iter->type)
02460 {
02461 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02462 data = _dbus_string_get_const_data_len (&iter->message->body,
02463 iter->pos, 1);
02464 if (_dbus_type_is_valid (*data))
02465 *type = *data;
02466 else
02467 *type = DBUS_TYPE_INVALID;
02468
02469 return skip_array_type (iter, iter->pos);
02470
02471 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02472 data = _dbus_string_get_const_data_len (&iter->message->body,
02473 iter->array_type_pos, 1);
02474 if (_dbus_type_is_valid (*data))
02475 *type = *data;
02476 else
02477 *type = DBUS_TYPE_INVALID;
02478
02479 return iter->pos;
02480
02481 case DBUS_MESSAGE_ITER_TYPE_DICT:
02482
02483 len = _dbus_demarshal_uint32 (&iter->message->body,
02484 iter->message->byte_order,
02485 iter->pos, &pos);
02486 pos = pos + len + 1;
02487
02488 data = _dbus_string_get_const_data_len (&iter->message->body,
02489 pos, 1);
02490 if (_dbus_type_is_valid (*data))
02491 *type = *data;
02492 else
02493 *type = DBUS_TYPE_INVALID;
02494
02495 return skip_array_type (iter, pos);
02496
02497 default:
02498 _dbus_assert_not_reached ("Invalid iter type");
02499 break;
02500 }
02501 *type = DBUS_TYPE_INVALID;
02502 return iter->pos;
02503 }
02504
02505
02513 dbus_bool_t
02514 dbus_message_iter_has_next (DBusMessageIter *iter)
02515 {
02516 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02517 int end_pos;
02518 int type, pos;
02519
02520 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02521
02522 if (real->pos >= real->end)
02523 return FALSE;
02524
02525 pos = dbus_message_iter_get_data_start (real, &type);
02526
02527 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02528 real->message->byte_order,
02529 type, pos, &end_pos))
02530 return FALSE;
02531
02532 if (end_pos >= real->end)
02533 return FALSE;
02534
02535 return TRUE;
02536 }
02537
02544 dbus_bool_t
02545 dbus_message_iter_next (DBusMessageIter *iter)
02546 {
02547 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02548 int end_pos;
02549 int type, pos;
02550
02551 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02552
02553 pos = dbus_message_iter_get_data_start (real, &type);
02554
02555 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02556 real->message->byte_order,
02557 type, pos, &end_pos))
02558 return FALSE;
02559
02560 if (end_pos >= real->end)
02561 return FALSE;
02562
02563 real->pos = end_pos;
02564
02565 return TRUE;
02566 }
02567
02575 int
02576 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02577 {
02578 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02579 int type, pos;
02580
02581 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02582
02583 if (real->pos >= real->end)
02584 {
02585 _dbus_verbose (" iterator at or beyond end of message\n");
02586 return DBUS_TYPE_INVALID;
02587 }
02588
02589 pos = dbus_message_iter_get_data_start (real, &type);
02590
02591 return type;
02592 }
02593
02594
02595
02596
02597 static int
02598 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02599 {
02600 const char *data;
02601 int _array_type_pos;
02602 int len, pos;
02603
02604 switch (iter->type)
02605 {
02606 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02607 _array_type_pos = iter->pos + 1;
02608 break;
02609 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02610 _array_type_pos = iter->array_type_pos + 1;
02611 break;
02612 case DBUS_MESSAGE_ITER_TYPE_DICT:
02613
02614 len = _dbus_demarshal_uint32 (&iter->message->body,
02615 iter->message->byte_order,
02616 iter->pos, &pos);
02617 pos = pos + len + 1;
02618 data = _dbus_string_get_const_data_len (&iter->message->body,
02619 pos + 1, 1);
02620 _array_type_pos = pos + 1;
02621 break;
02622 default:
02623 _dbus_assert_not_reached ("wrong iter type");
02624 return DBUS_TYPE_INVALID;
02625 }
02626
02627 if (array_type_pos != NULL)
02628 *array_type_pos = _array_type_pos;
02629
02630 data = _dbus_string_get_const_data_len (&iter->message->body,
02631 _array_type_pos, 1);
02632 if (_dbus_type_is_valid (*data))
02633 return *data;
02634
02635 return DBUS_TYPE_INVALID;
02636 }
02637
02638
02648 int
02649 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02650 {
02651 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02652 int type, pos;
02653
02654 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02655
02656 if (real->pos >= real->end)
02657 return DBUS_TYPE_INVALID;
02658
02659 pos = dbus_message_iter_get_data_start (real, &type);
02660
02661 _dbus_assert (type == DBUS_TYPE_ARRAY);
02662
02663 return iter_get_array_type (real, NULL);
02664 }
02665
02666
02676 char *
02677 dbus_message_iter_get_string (DBusMessageIter *iter)
02678 {
02679 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02680 int type, pos;
02681
02682 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02683
02684 pos = dbus_message_iter_get_data_start (real, &type);
02685
02686 _dbus_assert (type == DBUS_TYPE_STRING);
02687
02688 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02689 pos, NULL);
02690 }
02691
02692 #if 0
02693
02705 char *
02706 dbus_message_iter_get_object_path (DBusMessageIter *iter)
02707 {
02708 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02709 int type, pos;
02710
02711 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02712
02713 pos = dbus_message_iter_get_data_start (real, &type);
02714
02715 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
02716
02717 return _dbus_demarshal_object_path (&real->message->body, real->message->byte_order,
02718 pos, NULL);
02719 }
02720 #endif
02721
02735 dbus_bool_t
02736 dbus_message_iter_get_custom (DBusMessageIter *iter,
02737 char **name,
02738 unsigned char **value,
02739 int *len)
02740 {
02741 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02742 int type, pos;
02743 char *_name;
02744
02745 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02746
02747 pos = dbus_message_iter_get_data_start (real, &type);
02748
02749 _dbus_assert (type == DBUS_TYPE_CUSTOM);
02750
02751 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02752 pos, &pos);
02753
02754 if (_name == NULL)
02755 return FALSE;
02756
02757 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02758 pos, NULL, value, len))
02759 {
02760 dbus_free (_name);
02761 return FALSE;
02762 }
02763
02764 *name = _name;
02765
02766 return TRUE;
02767 }
02768
02778 unsigned char
02779 dbus_message_iter_get_byte (DBusMessageIter *iter)
02780 {
02781 unsigned char value;
02782 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02783 int type, pos;
02784
02785 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02786
02787 pos = dbus_message_iter_get_data_start (real, &type);
02788
02789 _dbus_assert (type == DBUS_TYPE_BYTE);
02790
02791 value = _dbus_string_get_byte (&real->message->body, pos);
02792
02793 return value;
02794 }
02795
02796
02806 dbus_bool_t
02807 dbus_message_iter_get_boolean (DBusMessageIter *iter)
02808 {
02809 unsigned char value;
02810 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02811 int type, pos;
02812
02813 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02814
02815 pos = dbus_message_iter_get_data_start (real, &type);
02816
02817 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
02818
02819 value = _dbus_string_get_byte (&real->message->body, pos);
02820
02821 return value;
02822 }
02823
02833 dbus_int32_t
02834 dbus_message_iter_get_int32 (DBusMessageIter *iter)
02835 {
02836 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02837 int type, pos;
02838
02839 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02840
02841 pos = dbus_message_iter_get_data_start (real, &type);
02842
02843 _dbus_assert (type == DBUS_TYPE_INT32);
02844
02845 return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
02846 pos, NULL);
02847 }
02848
02858 dbus_uint32_t
02859 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
02860 {
02861 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02862 int type, pos;
02863
02864 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02865
02866 pos = dbus_message_iter_get_data_start (real, &type);
02867
02868 _dbus_assert (type == DBUS_TYPE_UINT32);
02869
02870 return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02871 pos, NULL);
02872 }
02873
02874 #ifdef DBUS_HAVE_INT64
02875
02887 dbus_int64_t
02888 dbus_message_iter_get_int64 (DBusMessageIter *iter)
02889 {
02890 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02891 int type, pos;
02892
02893 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02894
02895 pos = dbus_message_iter_get_data_start (real, &type);
02896
02897 _dbus_assert (type == DBUS_TYPE_INT64);
02898
02899 return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order,
02900 pos, NULL);
02901 }
02902
02914 dbus_uint64_t
02915 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
02916 {
02917 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02918 int type, pos;
02919
02920 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02921
02922 pos = dbus_message_iter_get_data_start (real, &type);
02923
02924 _dbus_assert (type == DBUS_TYPE_UINT64);
02925
02926 return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order,
02927 pos, NULL);
02928 }
02929
02930 #endif
02931
02941 double
02942 dbus_message_iter_get_double (DBusMessageIter *iter)
02943 {
02944 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02945 int type, pos;
02946
02947 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0);
02948
02949 pos = dbus_message_iter_get_data_start (real, &type);
02950
02951 _dbus_assert (type == DBUS_TYPE_DOUBLE);
02952
02953 return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
02954 pos, NULL);
02955 }
02956
02969 void
02970 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
02971 DBusMessageIter *array_iter,
02972 int *array_type)
02973 {
02974 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02975 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
02976 int type, pos, len_pos, len, array_type_pos;
02977 int _array_type;
02978
02979 _dbus_return_if_fail (dbus_message_iter_check (real));
02980
02981 pos = dbus_message_iter_get_data_start (real, &type);
02982
02983 _dbus_assert (type == DBUS_TYPE_ARRAY);
02984
02985 _array_type = iter_get_array_type (real, &array_type_pos);
02986
02987 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
02988 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02989 pos, &pos);
02990
02991 array_real->parent_iter = real;
02992 array_real->message = real->message;
02993 array_real->changed_stamp = real->message->changed_stamp;
02994
02995 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
02996 array_real->pos = pos;
02997 array_real->end = pos + len;
02998
02999 array_real->container_start = pos;
03000 array_real->container_length_pos = len_pos;
03001 array_real->wrote_dict_key = 0;
03002 array_real->array_type_pos = array_type_pos;
03003 array_real->array_type_done = TRUE;
03004
03005 if (array_type != NULL)
03006 *array_type = _array_type;
03007 }
03008
03009
03018 void
03019 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
03020 DBusMessageIter *dict_iter)
03021 {
03022 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03023 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03024 int type, pos, len_pos, len;
03025
03026 _dbus_return_if_fail (dbus_message_iter_check (real));
03027
03028 pos = dbus_message_iter_get_data_start (real, &type);
03029
03030 _dbus_assert (type == DBUS_TYPE_DICT);
03031
03032 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03033 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03034 pos, &pos);
03035
03036 dict_real->parent_iter = real;
03037 dict_real->message = real->message;
03038 dict_real->changed_stamp = real->message->changed_stamp;
03039
03040 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03041 dict_real->pos = pos;
03042 dict_real->end = pos + len;
03043
03044 dict_real->container_start = pos;
03045 dict_real->container_length_pos = len_pos;
03046 dict_real->wrote_dict_key = 0;
03047 }
03048
03059 dbus_bool_t
03060 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
03061 unsigned char **value,
03062 int *len)
03063 {
03064 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03065 int type, pos;
03066
03067 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03068
03069 pos = dbus_message_iter_get_data_start (real, &type);
03070
03071 _dbus_assert (type == DBUS_TYPE_ARRAY);
03072
03073 type = iter_get_array_type (real, NULL);
03074
03075 _dbus_assert (type == DBUS_TYPE_BYTE);
03076
03077 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
03078 pos, NULL, value, len))
03079 return FALSE;
03080 else
03081 return TRUE;
03082 }
03083
03094 dbus_bool_t
03095 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
03096 unsigned char **value,
03097 int *len)
03098 {
03099 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03100 int type, pos;
03101
03102 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03103
03104 pos = dbus_message_iter_get_data_start (real, &type);
03105
03106 _dbus_assert (type == DBUS_TYPE_ARRAY);
03107
03108 type = iter_get_array_type (real, NULL);
03109
03110 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
03111
03112 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
03113 pos, NULL, value, len))
03114 return FALSE;
03115 else
03116 return TRUE;
03117 }
03118
03129 dbus_bool_t
03130 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
03131 dbus_int32_t **value,
03132 int *len)
03133 {
03134 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03135 int type, pos;
03136
03137 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03138
03139 pos = dbus_message_iter_get_data_start (real, &type);
03140
03141 _dbus_assert (type == DBUS_TYPE_ARRAY);
03142
03143 type = iter_get_array_type (real, NULL);
03144
03145 _dbus_assert (type == DBUS_TYPE_INT32);
03146
03147 if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
03148 pos, NULL, value, len))
03149 return FALSE;
03150 else
03151 return TRUE;
03152 }
03153
03164 dbus_bool_t
03165 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
03166 dbus_uint32_t **value,
03167 int *len)
03168 {
03169 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03170 int type, pos;
03171
03172 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03173
03174 pos = dbus_message_iter_get_data_start (real, &type);
03175
03176 _dbus_assert (type == DBUS_TYPE_ARRAY);
03177
03178 type = iter_get_array_type (real, NULL);
03179 _dbus_assert (type == DBUS_TYPE_UINT32);
03180
03181 if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
03182 pos, NULL, value, len))
03183 return FALSE;
03184 else
03185 return TRUE;
03186 }
03187
03188 #ifdef DBUS_HAVE_INT64
03189
03202 dbus_bool_t
03203 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
03204 dbus_int64_t **value,
03205 int *len)
03206 {
03207 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03208 int type, pos;
03209
03210 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03211
03212 pos = dbus_message_iter_get_data_start (real, &type);
03213
03214 _dbus_assert (type == DBUS_TYPE_ARRAY);
03215
03216 type = iter_get_array_type (real, NULL);
03217
03218 _dbus_assert (type == DBUS_TYPE_INT64);
03219
03220 if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order,
03221 pos, NULL, value, len))
03222 return FALSE;
03223 else
03224 return TRUE;
03225 }
03226
03239 dbus_bool_t
03240 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
03241 dbus_uint64_t **value,
03242 int *len)
03243 {
03244 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03245 int type, pos;
03246
03247 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03248
03249 pos = dbus_message_iter_get_data_start (real, &type);
03250
03251 _dbus_assert (type == DBUS_TYPE_ARRAY);
03252
03253 type = iter_get_array_type (real, NULL);
03254 _dbus_assert (type == DBUS_TYPE_UINT64);
03255
03256 if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order,
03257 pos, NULL, value, len))
03258 return FALSE;
03259 else
03260 return TRUE;
03261 }
03262
03263 #endif
03264
03275 dbus_bool_t
03276 dbus_message_iter_get_double_array (DBusMessageIter *iter,
03277 double **value,
03278 int *len)
03279 {
03280 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03281 int type, pos;
03282
03283 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03284
03285 pos = dbus_message_iter_get_data_start (real, &type);
03286
03287 _dbus_assert (type == DBUS_TYPE_ARRAY);
03288
03289 type = iter_get_array_type (real, NULL);
03290 _dbus_assert (type == DBUS_TYPE_DOUBLE);
03291
03292 if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
03293 pos, NULL, value, len))
03294 return FALSE;
03295 else
03296 return TRUE;
03297 }
03298
03314 dbus_bool_t
03315 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03316 char ***value,
03317 int *len)
03318 {
03319 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03320 int type, pos;
03321
03322 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03323
03324 pos = dbus_message_iter_get_data_start (real, &type);
03325
03326 _dbus_assert (type == DBUS_TYPE_ARRAY);
03327
03328 type = iter_get_array_type (real, NULL);
03329 _dbus_assert (type == DBUS_TYPE_STRING);
03330
03331 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03332 pos, NULL, value, len))
03333 return FALSE;
03334 else
03335 return TRUE;
03336 }
03337
03338 #if 0
03339
03357 dbus_bool_t
03358 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03359 char ***value,
03360 int *len)
03361 {
03362 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03363 int type, pos;
03364
03365 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03366
03367 pos = dbus_message_iter_get_data_start (real, &type);
03368
03369 _dbus_assert (type == DBUS_TYPE_ARRAY);
03370
03371 type = iter_get_array_type (real, NULL);
03372 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03373
03374 if (!_dbus_demarshal_object_path_array (&real->message->body, real->message->byte_order,
03375 pos, NULL, value, len))
03376 return FALSE;
03377 else
03378 return TRUE;
03379 }
03380 #endif
03381
03391 char *
03392 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
03393 {
03394 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03395
03396 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03397
03398 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03399
03400 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03401 real->pos, NULL);
03402 }
03403
03412 void
03413 dbus_message_append_iter_init (DBusMessage *message,
03414 DBusMessageIter *iter)
03415 {
03416 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03417
03418 _dbus_return_if_fail (message != NULL);
03419 _dbus_return_if_fail (iter != NULL);
03420
03421 real->message = message;
03422 real->parent_iter = NULL;
03423 real->changed_stamp = message->changed_stamp;
03424
03425 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03426 real->end = _dbus_string_get_length (&real->message->body);
03427 real->pos = real->end;
03428
03429 real->container_length_pos = 0;
03430 real->wrote_dict_key = 0;
03431 }
03432
03433 #ifndef DBUS_DISABLE_CHECKS
03434 static dbus_bool_t
03435 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03436 {
03437 if (iter == NULL)
03438 {
03439 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03440 return FALSE;
03441 }
03442
03443 if (iter->message->locked)
03444 {
03445 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03446 return FALSE;
03447 }
03448
03449 if (iter->changed_stamp != iter->message->changed_stamp)
03450 {
03451 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03452 return FALSE;
03453 }
03454
03455 if (iter->pos != iter->end)
03456 {
03457 _dbus_warn ("dbus iterator check failed: can only append at end of message");
03458 return FALSE;
03459 }
03460
03461 if (iter->pos != _dbus_string_get_length (&iter->message->body))
03462 {
03463 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03464 return FALSE;
03465 }
03466
03467 return TRUE;
03468 }
03469 #endif
03470
03471 static dbus_bool_t
03472 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03473 int type)
03474 {
03475 const char *data;
03476 switch (iter->type)
03477 {
03478 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03479 if (!_dbus_string_append_byte (&iter->message->signature, type))
03480 return FALSE;
03481
03482 if (!_dbus_string_append_byte (&iter->message->body, type))
03483 {
03484 _dbus_string_shorten (&iter->message->signature, 1);
03485 return FALSE;
03486 }
03487 break;
03488
03489 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03490 data = _dbus_string_get_const_data_len (&iter->message->body,
03491 iter->array_type_pos, 1);
03492 if (type != *data)
03493 {
03494 _dbus_warn ("Appended element of wrong type for array\n");
03495 return FALSE;
03496 }
03497 break;
03498
03499 case DBUS_MESSAGE_ITER_TYPE_DICT:
03500 if (!iter->wrote_dict_key)
03501 {
03502 _dbus_warn ("Appending dict data before key name\n");
03503 return FALSE;
03504 }
03505
03506 if (!_dbus_string_append_byte (&iter->message->body, type))
03507 return FALSE;
03508
03509 break;
03510
03511 default:
03512 _dbus_assert_not_reached ("Invalid iter type");
03513 break;
03514 }
03515
03516 return TRUE;
03517 }
03518
03519 static void
03520 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
03521 {
03522 iter->changed_stamp = iter->message->changed_stamp;
03523
03524
03525 iter->end = _dbus_string_get_length (&iter->message->body);
03526 iter->pos = iter->end;
03527
03528
03529 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
03530 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
03531 _dbus_marshal_set_uint32 (&iter->message->body,
03532 iter->message->byte_order,
03533 iter->container_length_pos,
03534 iter->end - iter->container_start);
03535
03536 if (iter->parent_iter)
03537 dbus_message_iter_update_after_change (iter->parent_iter);
03538 }
03539
03540 static void
03541 dbus_message_iter_append_done (DBusMessageRealIter *iter)
03542 {
03543 iter->message->changed_stamp++;
03544 dbus_message_iter_update_after_change (iter);
03545 iter->wrote_dict_key = FALSE;
03546 }
03547
03554 dbus_bool_t
03555 dbus_message_iter_append_nil (DBusMessageIter *iter)
03556 {
03557 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03558
03559 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03560
03561 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
03562 return FALSE;
03563
03564 dbus_message_iter_append_done (real);
03565
03566 return TRUE;
03567 }
03568
03576 dbus_bool_t
03577 dbus_message_iter_append_boolean (DBusMessageIter *iter,
03578 dbus_bool_t value)
03579 {
03580 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03581
03582 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03583
03584 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
03585 return FALSE;
03586
03587 if (!_dbus_string_append_byte (&real->message->body, (value != FALSE)))
03588 {
03589 _dbus_string_set_length (&real->message->body, real->pos);
03590 return FALSE;
03591 }
03592
03593 dbus_message_iter_append_done (real);
03594
03595 return TRUE;
03596 }
03597
03605 dbus_bool_t
03606 dbus_message_iter_append_byte (DBusMessageIter *iter,
03607 unsigned char value)
03608 {
03609 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03610
03611 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03612
03613 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE))
03614 return FALSE;
03615
03616 if (!_dbus_string_append_byte (&real->message->body, value))
03617 {
03618 _dbus_string_set_length (&real->message->body, real->pos);
03619 return FALSE;
03620 }
03621
03622 dbus_message_iter_append_done (real);
03623
03624 return TRUE;
03625 }
03626
03627
03635 dbus_bool_t
03636 dbus_message_iter_append_int32 (DBusMessageIter *iter,
03637 dbus_int32_t value)
03638 {
03639 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03640
03641 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03642
03643 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32))
03644 return FALSE;
03645
03646 if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value))
03647 {
03648 _dbus_string_set_length (&real->message->body, real->pos);
03649 return FALSE;
03650 }
03651
03652 dbus_message_iter_append_done (real);
03653
03654 return TRUE;
03655 }
03656
03664 dbus_bool_t
03665 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
03666 dbus_uint32_t value)
03667 {
03668 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03669
03670 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03671
03672 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32))
03673 return FALSE;
03674
03675 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value))
03676 {
03677 _dbus_string_set_length (&real->message->body, real->pos);
03678 return FALSE;
03679 }
03680
03681 dbus_message_iter_append_done (real);
03682
03683 return TRUE;
03684 }
03685
03686 #ifdef DBUS_HAVE_INT64
03687
03697 dbus_bool_t
03698 dbus_message_iter_append_int64 (DBusMessageIter *iter,
03699 dbus_int64_t value)
03700 {
03701 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03702
03703 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03704
03705 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64))
03706 return FALSE;
03707
03708 if (!_dbus_marshal_int64 (&real->message->body, real->message->byte_order, value))
03709 {
03710 _dbus_string_set_length (&real->message->body, real->pos);
03711 return FALSE;
03712 }
03713
03714 dbus_message_iter_append_done (real);
03715
03716 return TRUE;
03717 }
03718
03728 dbus_bool_t
03729 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
03730 dbus_uint64_t value)
03731 {
03732 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03733
03734 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03735
03736 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64))
03737 return FALSE;
03738
03739 if (!_dbus_marshal_uint64 (&real->message->body, real->message->byte_order, value))
03740 {
03741 _dbus_string_set_length (&real->message->body, real->pos);
03742 return FALSE;
03743 }
03744
03745 dbus_message_iter_append_done (real);
03746
03747 return TRUE;
03748 }
03749
03750 #endif
03751
03759 dbus_bool_t
03760 dbus_message_iter_append_double (DBusMessageIter *iter,
03761 double value)
03762 {
03763 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03764
03765 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03766
03767 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE))
03768 return FALSE;
03769
03770 if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value))
03771 {
03772 _dbus_string_set_length (&real->message->body, real->pos);
03773 return FALSE;
03774 }
03775
03776 dbus_message_iter_append_done (real);
03777
03778 return TRUE;
03779 }
03780
03790 dbus_bool_t
03791 dbus_message_iter_append_string (DBusMessageIter *iter,
03792 const char *value)
03793 {
03794 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03795
03796 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03797
03798 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
03799 return FALSE;
03800
03801 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03802 {
03803 _dbus_string_set_length (&real->message->body, real->pos);
03804 return FALSE;
03805 }
03806
03807 dbus_message_iter_append_done (real);
03808
03809 return TRUE;
03810 }
03811
03824 dbus_bool_t
03825 dbus_message_iter_append_custom (DBusMessageIter *iter,
03826 const char *name,
03827 const unsigned char *data,
03828 int len)
03829 {
03830 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03831
03832 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03833
03834 if (!dbus_message_iter_append_type (real, DBUS_TYPE_CUSTOM))
03835 return FALSE;
03836
03837 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
03838 {
03839 _dbus_string_set_length (&real->message->body, real->pos);
03840 return FALSE;
03841 }
03842
03843 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
03844 {
03845 _dbus_string_set_length (&real->message->body, real->pos);
03846 return FALSE;
03847 }
03848
03849 dbus_message_iter_append_done (real);
03850
03851 return TRUE;
03852 }
03853
03854
03863 dbus_bool_t
03864 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
03865 const char *value)
03866 {
03867 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03868
03869 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03870 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03871
03872 if (real->wrote_dict_key)
03873 {
03874 _dbus_warn ("Appendinging multiple dict key names\n");
03875 return FALSE;
03876 }
03877
03878 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03879 {
03880 return FALSE;
03881 }
03882
03883 dbus_message_iter_append_done (real);
03884 real->wrote_dict_key = TRUE;
03885
03886 return TRUE;
03887 }
03888
03889 static dbus_bool_t
03890 array_iter_type_mark_done (DBusMessageRealIter *iter)
03891 {
03892 int len_pos;
03893
03894 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
03895 array_iter_type_mark_done (iter->parent_iter);
03896 else
03897 return TRUE;
03898
03899 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
03900 sizeof (dbus_uint32_t));
03901
03902
03903 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
03904 {
03905 _dbus_string_set_length (&iter->message->body, iter->pos);
03906 return FALSE;
03907 }
03908
03909 iter->container_start = _dbus_string_get_length (&iter->message->body);
03910 iter->container_length_pos = len_pos;
03911 iter->array_type_done = TRUE;
03912
03913 return TRUE;
03914 }
03915
03916 static dbus_bool_t
03917 append_array_type (DBusMessageRealIter *real,
03918 int element_type,
03919 dbus_bool_t *array_type_done,
03920 int *array_type_pos)
03921 {
03922 int existing_element_type;
03923
03924 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
03925 return FALSE;
03926
03927 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
03928 real->array_type_done)
03929 {
03930 existing_element_type = iter_get_array_type (real, array_type_pos);
03931 if (existing_element_type != element_type)
03932 {
03933 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
03934 _dbus_type_to_string (element_type),
03935 _dbus_type_to_string (existing_element_type));
03936 _dbus_string_set_length (&real->message->body, real->pos);
03937 return FALSE;
03938 }
03939 if (array_type_done != NULL)
03940 *array_type_done = TRUE;
03941 }
03942 else
03943 {
03944 if (array_type_pos != NULL)
03945 *array_type_pos = _dbus_string_get_length (&real->message->body);
03946
03947
03948 if (!_dbus_string_append_byte (&real->message->signature, element_type))
03949 {
03950 _dbus_string_set_length (&real->message->body, real->pos);
03951 return FALSE;
03952 }
03953
03954
03955 if (!_dbus_string_append_byte (&real->message->body, element_type))
03956 {
03957 _dbus_string_shorten (&real->message->signature, 1);
03958 _dbus_string_set_length (&real->message->body, real->pos);
03959 return FALSE;
03960 }
03961
03962 if (array_type_done != NULL)
03963 *array_type_done = element_type != DBUS_TYPE_ARRAY;
03964
03965 if (element_type != DBUS_TYPE_ARRAY &&
03966 !array_iter_type_mark_done (real))
03967 {
03968 _dbus_string_shorten (&real->message->signature, 1);
03969 return FALSE;
03970 }
03971 }
03972
03973 return TRUE;
03974 }
03975
03985 dbus_bool_t
03986 dbus_message_iter_append_array (DBusMessageIter *iter,
03987 DBusMessageIter *array_iter,
03988 int element_type)
03989 {
03990 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03991 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03992 int len_pos;
03993 int array_type_pos;
03994 dbus_bool_t array_type_done;
03995
03996 if (element_type == DBUS_TYPE_NIL)
03997 {
03998 _dbus_warn ("Can't create NIL arrays\n");
03999 return FALSE;
04000 }
04001
04002 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04003
04004 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
04005 return FALSE;
04006
04007 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04008
04009 if (array_type_done)
04010 {
04011
04012 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04013 {
04014 _dbus_string_set_length (&real->message->body, real->pos);
04015 return FALSE;
04016 }
04017 }
04018
04019 array_real->parent_iter = real;
04020 array_real->message = real->message;
04021 array_real->changed_stamp = real->message->changed_stamp;
04022
04023 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
04024 array_real->pos = _dbus_string_get_length (&real->message->body);
04025 array_real->end = array_real->end;
04026
04027 array_real->container_start = array_real->pos;
04028 array_real->container_length_pos = len_pos;
04029 array_real->wrote_dict_key = 0;
04030 array_real->array_type_done = array_type_done;
04031 array_real->array_type_pos = array_type_pos;
04032
04033 dbus_message_iter_append_done (array_real);
04034
04035 return TRUE;
04036 }
04037
04046 dbus_bool_t
04047 dbus_message_iter_append_dict (DBusMessageIter *iter,
04048 DBusMessageIter *dict_iter)
04049 {
04050 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04051 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
04052 int len_pos;
04053
04054 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04055
04056 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
04057 return FALSE;
04058
04059 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04060
04061
04062 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04063 {
04064 _dbus_string_set_length (&real->message->body, real->pos);
04065 return FALSE;
04066 }
04067
04068 dict_real->parent_iter = real;
04069 dict_real->message = real->message;
04070 dict_real->changed_stamp = real->message->changed_stamp;
04071
04072 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
04073 dict_real->pos = _dbus_string_get_length (&real->message->body);
04074 dict_real->end = dict_real->end;
04075
04076 dict_real->container_start = dict_real->pos;
04077 dict_real->container_length_pos = len_pos;
04078 dict_real->wrote_dict_key = 0;
04079
04080 dbus_message_iter_append_done (dict_real);
04081
04082 return TRUE;
04083 }
04084
04085
04094 dbus_bool_t
04095 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
04096 unsigned const char *value,
04097 int len)
04098 {
04099 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04100
04101 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04102
04103 if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))
04104 return FALSE;
04105
04106 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
04107 {
04108 _dbus_string_set_length (&real->message->body, real->pos);
04109 return FALSE;
04110 }
04111
04112 dbus_message_iter_append_done (real);
04113
04114 return TRUE;
04115 }
04116
04125 dbus_bool_t
04126 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
04127 const dbus_int32_t *value,
04128 int len)
04129 {
04130 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04131
04132 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04133
04134 if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))
04135 return FALSE;
04136
04137 if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))
04138 {
04139 _dbus_string_set_length (&real->message->body, real->pos);
04140 return FALSE;
04141 }
04142
04143 dbus_message_iter_append_done (real);
04144
04145 return TRUE;
04146 }
04147
04156 dbus_bool_t
04157 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
04158 const dbus_uint32_t *value,
04159 int len)
04160 {
04161 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04162
04163 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04164
04165 if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))
04166 return FALSE;
04167
04168 if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))
04169 {
04170 _dbus_string_set_length (&real->message->body, real->pos);
04171 return FALSE;
04172 }
04173
04174 dbus_message_iter_append_done (real);
04175
04176 return TRUE;
04177 }
04178
04179 #ifdef DBUS_HAVE_INT64
04180
04191 dbus_bool_t
04192 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
04193 const dbus_int64_t *value,
04194 int len)
04195 {
04196 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04197
04198 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04199
04200 if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL))
04201 return FALSE;
04202
04203 if (!_dbus_marshal_int64_array (&real->message->body, real->message->byte_order, value, len))
04204 {
04205 _dbus_string_set_length (&real->message->body, real->pos);
04206 return FALSE;
04207 }
04208
04209 dbus_message_iter_append_done (real);
04210
04211 return TRUE;
04212 }
04213
04224 dbus_bool_t
04225 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
04226 const dbus_uint64_t *value,
04227 int len)
04228 {
04229 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04230
04231 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04232
04233 if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL))
04234 return FALSE;
04235
04236 if (!_dbus_marshal_uint64_array (&real->message->body, real->message->byte_order, value, len))
04237 {
04238 _dbus_string_set_length (&real->message->body, real->pos);
04239 return FALSE;
04240 }
04241
04242 dbus_message_iter_append_done (real);
04243
04244 return TRUE;
04245 }
04246 #endif
04247
04256 dbus_bool_t
04257 dbus_message_iter_append_double_array (DBusMessageIter *iter,
04258 const double *value,
04259 int len)
04260 {
04261 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04262
04263 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04264
04265 if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))
04266 return FALSE;
04267
04268 if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))
04269 {
04270 _dbus_string_set_length (&real->message->body, real->pos);
04271 return FALSE;
04272 }
04273
04274 dbus_message_iter_append_done (real);
04275
04276 return TRUE;
04277 }
04278
04287 dbus_bool_t
04288 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
04289 unsigned const char *value,
04290 int len)
04291 {
04292 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04293
04294 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04295
04296 if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))
04297 return FALSE;
04298
04299 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
04300 {
04301 _dbus_string_set_length (&real->message->body, real->pos);
04302 return FALSE;
04303 }
04304
04305 dbus_message_iter_append_done (real);
04306
04307 return TRUE;
04308 }
04309
04318 dbus_bool_t
04319 dbus_message_iter_append_string_array (DBusMessageIter *iter,
04320 const char **value,
04321 int len)
04322 {
04323 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04324
04325 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04326
04327 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
04328 return FALSE;
04329
04330 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04331 {
04332 _dbus_string_set_length (&real->message->body, real->pos);
04333 return FALSE;
04334 }
04335
04336 dbus_message_iter_append_done (real);
04337
04338 return TRUE;
04339 }
04340
04348 dbus_bool_t
04349 dbus_message_set_sender (DBusMessage *message,
04350 const char *sender)
04351 {
04352 _dbus_return_val_if_fail (message != NULL, FALSE);
04353 _dbus_return_val_if_fail (!message->locked, FALSE);
04354
04355 return set_string_field (message,
04356 DBUS_HEADER_FIELD_SENDER_SERVICE,
04357 DBUS_TYPE_STRING,
04358 sender);
04359 }
04360
04371 void
04372 dbus_message_set_no_reply (DBusMessage *message,
04373 dbus_bool_t no_reply)
04374 {
04375 char *header;
04376
04377 _dbus_return_if_fail (message != NULL);
04378 _dbus_return_if_fail (!message->locked);
04379
04380 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04381
04382 if (no_reply)
04383 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04384 else
04385 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04386 }
04387
04395 dbus_bool_t
04396 dbus_message_get_no_reply (DBusMessage *message)
04397 {
04398 const char *header;
04399
04400 _dbus_return_val_if_fail (message != NULL, FALSE);
04401
04402 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04403
04404 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
04405 }
04406
04414 const char*
04415 dbus_message_get_sender (DBusMessage *message)
04416 {
04417 _dbus_return_val_if_fail (message != NULL, NULL);
04418
04419 return get_string_field (message,
04420 DBUS_HEADER_FIELD_SENDER_SERVICE,
04421 NULL);
04422 }
04423
04439 const char*
04440 dbus_message_get_signature (DBusMessage *message)
04441 {
04442 _dbus_return_val_if_fail (message != NULL, NULL);
04443
04444 return _dbus_string_get_const_data (&message->signature);
04445 }
04446
04447 static dbus_bool_t
04448 _dbus_message_has_type_interface_member (DBusMessage *message,
04449 int type,
04450 const char *interface,
04451 const char *method)
04452 {
04453 const char *n;
04454
04455 _dbus_assert (message != NULL);
04456 _dbus_assert (interface != NULL);
04457 _dbus_assert (method != NULL);
04458
04459 if (dbus_message_get_type (message) != type)
04460 return FALSE;
04461
04462
04463
04464
04465
04466 n = dbus_message_get_member (message);
04467
04468 if (n && strcmp (n, method) == 0)
04469 {
04470 n = dbus_message_get_interface (message);
04471
04472 if (n && strcmp (n, interface) == 0)
04473 return TRUE;
04474 }
04475
04476 return FALSE;
04477 }
04478
04491 dbus_bool_t
04492 dbus_message_is_method_call (DBusMessage *message,
04493 const char *interface,
04494 const char *method)
04495 {
04496 _dbus_return_val_if_fail (message != NULL, FALSE);
04497 _dbus_return_val_if_fail (interface != NULL, FALSE);
04498 _dbus_return_val_if_fail (method != NULL, FALSE);
04499
04500 return _dbus_message_has_type_interface_member (message,
04501 DBUS_MESSAGE_TYPE_METHOD_CALL,
04502 interface, method);
04503 }
04504
04517 dbus_bool_t
04518 dbus_message_is_signal (DBusMessage *message,
04519 const char *interface,
04520 const char *signal_name)
04521 {
04522 _dbus_return_val_if_fail (message != NULL, FALSE);
04523 _dbus_return_val_if_fail (interface != NULL, FALSE);
04524 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
04525
04526 return _dbus_message_has_type_interface_member (message,
04527 DBUS_MESSAGE_TYPE_SIGNAL,
04528 interface, signal_name);
04529 }
04530
04541 dbus_bool_t
04542 dbus_message_is_error (DBusMessage *message,
04543 const char *error_name)
04544 {
04545 const char *n;
04546
04547 _dbus_return_val_if_fail (message != NULL, FALSE);
04548 _dbus_return_val_if_fail (error_name != NULL, FALSE);
04549
04550 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04551 return FALSE;
04552
04553 n = dbus_message_get_error_name (message);
04554
04555 if (n && strcmp (n, error_name) == 0)
04556 return TRUE;
04557 else
04558 return FALSE;
04559 }
04560
04571 dbus_bool_t
04572 dbus_message_has_destination (DBusMessage *message,
04573 const char *service)
04574 {
04575 const char *s;
04576
04577 _dbus_return_val_if_fail (message != NULL, FALSE);
04578 _dbus_return_val_if_fail (service != NULL, FALSE);
04579
04580 s = dbus_message_get_destination (message);
04581
04582 if (s && strcmp (s, service) == 0)
04583 return TRUE;
04584 else
04585 return FALSE;
04586 }
04587
04602 dbus_bool_t
04603 dbus_message_has_sender (DBusMessage *message,
04604 const char *service)
04605 {
04606 const char *s;
04607
04608 _dbus_return_val_if_fail (message != NULL, FALSE);
04609 _dbus_return_val_if_fail (service != NULL, FALSE);
04610
04611 s = dbus_message_get_sender (message);
04612
04613 if (s && strcmp (s, service) == 0)
04614 return TRUE;
04615 else
04616 return FALSE;
04617 }
04618
04628 dbus_bool_t
04629 dbus_message_has_signature (DBusMessage *message,
04630 const char *signature)
04631 {
04632 _dbus_return_val_if_fail (message != NULL, FALSE);
04633 _dbus_return_val_if_fail (signature != NULL, FALSE);
04634
04635 return _dbus_string_equal_c_str (&message->signature, signature);
04636 }
04637
04655 dbus_bool_t
04656 dbus_set_error_from_message (DBusError *error,
04657 DBusMessage *message)
04658 {
04659 char *str;
04660
04661 _dbus_return_val_if_fail (message != NULL, FALSE);
04662 _dbus_return_val_if_error_is_set (error, FALSE);
04663
04664 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04665 return FALSE;
04666
04667 str = NULL;
04668 dbus_message_get_args (message, NULL,
04669 DBUS_TYPE_STRING, &str,
04670 DBUS_TYPE_INVALID);
04671
04672 dbus_set_error (error, dbus_message_get_error_name (message),
04673 str ? "%s" : NULL, str);
04674
04675 dbus_free (str);
04676
04677 return TRUE;
04678 }
04679
04704
04705
04706
04707
04708
04712 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
04713
04718 struct DBusMessageLoader
04719 {
04720 int refcount;
04722 DBusString data;
04724 DBusList *messages;
04726 long max_message_size;
04728 unsigned int buffer_outstanding : 1;
04730 unsigned int corrupted : 1;
04731 };
04732
04743 #define INITIAL_LOADER_DATA_LEN 32
04744
04751 DBusMessageLoader*
04752 _dbus_message_loader_new (void)
04753 {
04754 DBusMessageLoader *loader;
04755
04756 loader = dbus_new0 (DBusMessageLoader, 1);
04757 if (loader == NULL)
04758 return NULL;
04759
04760 loader->refcount = 1;
04761
04762
04763
04764
04765 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
04766
04767 if (!_dbus_string_init (&loader->data))
04768 {
04769 dbus_free (loader);
04770 return NULL;
04771 }
04772
04773
04774 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
04775 _dbus_string_set_length (&loader->data, 0);
04776
04777 return loader;
04778 }
04779
04785 void
04786 _dbus_message_loader_ref (DBusMessageLoader *loader)
04787 {
04788 loader->refcount += 1;
04789 }
04790
04797 void
04798 _dbus_message_loader_unref (DBusMessageLoader *loader)
04799 {
04800 loader->refcount -= 1;
04801 if (loader->refcount == 0)
04802 {
04803 _dbus_list_foreach (&loader->messages,
04804 (DBusForeachFunction) dbus_message_unref,
04805 NULL);
04806 _dbus_list_clear (&loader->messages);
04807 _dbus_string_free (&loader->data);
04808 dbus_free (loader);
04809 }
04810 }
04811
04830 void
04831 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04832 DBusString **buffer)
04833 {
04834 _dbus_assert (!loader->buffer_outstanding);
04835
04836 *buffer = &loader->data;
04837
04838 loader->buffer_outstanding = TRUE;
04839 }
04840
04845 #define DBUS_MINIMUM_HEADER_SIZE 16
04846
04847 static dbus_bool_t
04848 decode_string_field (const DBusString *data,
04849 int field,
04850 HeaderField *header_field,
04851 DBusString *field_data,
04852 int pos,
04853 int type)
04854 {
04855 int string_data_pos;
04856
04857 _dbus_assert (header_field != NULL);
04858 _dbus_assert (field_data != NULL);
04859
04860 if (header_field->name_offset >= 0)
04861 {
04862 _dbus_verbose ("%s field provided twice\n",
04863 _dbus_header_field_to_string (field));
04864 return FALSE;
04865 }
04866
04867 if (type != DBUS_TYPE_STRING)
04868 {
04869 _dbus_verbose ("%s field has wrong type %s\n",
04870 _dbus_header_field_to_string (field),
04871 _dbus_type_to_string (type));
04872 return FALSE;
04873 }
04874
04875
04876
04877
04878
04879 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
04880 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
04881
04882 _dbus_string_init_const (field_data,
04883 _dbus_string_get_const_data (data) + string_data_pos);
04884
04885 header_field->name_offset = pos;
04886 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
04887
04888 #if 0
04889 _dbus_verbose ("Found field %s at offset %d\n",
04890 _dbus_header_field_to_string (field),
04891 header_field->value_offset);
04892 #endif
04893
04894 return TRUE;
04895 }
04896
04897
04898
04899
04900
04901
04902 static dbus_bool_t
04903 decode_header_data (const DBusString *data,
04904 int header_len,
04905 int byte_order,
04906 int message_type,
04907 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
04908 int *message_padding)
04909 {
04910 DBusString field_data;
04911 int pos, new_pos;
04912 int i;
04913 int field;
04914 int type;
04915
04916 if (header_len < 16)
04917 {
04918 _dbus_verbose ("Header length %d is too short\n", header_len);
04919 return FALSE;
04920 }
04921
04922 i = 0;
04923 while (i <= DBUS_HEADER_FIELD_LAST)
04924 {
04925 fields[i].name_offset = -1;
04926 fields[i].value_offset = -1;
04927 ++i;
04928 }
04929
04930 pos = 16;
04931 while (pos < header_len)
04932 {
04933 field = _dbus_string_get_byte (data, pos);
04934 if (field == DBUS_HEADER_FIELD_INVALID)
04935 break;
04936 pos++;
04937
04938 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
04939 {
04940 _dbus_verbose ("Failed to validate type of named header field pos = %d\n",
04941 pos);
04942 return FALSE;
04943 }
04944
04945 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
04946 {
04947 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n",
04948 pos);
04949 return FALSE;
04950 }
04951
04952 if (new_pos > header_len)
04953 {
04954 _dbus_verbose ("Named header field tries to extend beyond header length\n");
04955 return FALSE;
04956 }
04957
04958 switch (field)
04959 {
04960 case DBUS_HEADER_FIELD_SERVICE:
04961 if (!decode_string_field (data, field, &fields[field],
04962 &field_data, pos, type))
04963 return FALSE;
04964
04965 if (!_dbus_string_validate_service (&field_data, 0,
04966 _dbus_string_get_length (&field_data)))
04967 {
04968 _dbus_verbose ("service field has invalid content \"%s\"\n",
04969 _dbus_string_get_const_data (&field_data));
04970 return FALSE;
04971 }
04972 break;
04973
04974 case DBUS_HEADER_FIELD_INTERFACE:
04975 if (!decode_string_field (data, field, &fields[field],
04976 &field_data, pos, type))
04977 return FALSE;
04978
04979 if (!_dbus_string_validate_interface (&field_data, 0,
04980 _dbus_string_get_length (&field_data)))
04981 {
04982 _dbus_verbose ("interface field has invalid content \"%s\"\n",
04983 _dbus_string_get_const_data (&field_data));
04984 return FALSE;
04985 }
04986
04987 if (_dbus_string_equal_c_str (&field_data,
04988 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
04989 {
04990 _dbus_verbose ("Message is on the local interface\n");
04991 return FALSE;
04992 }
04993 break;
04994
04995 case DBUS_HEADER_FIELD_MEMBER:
04996 if (!decode_string_field (data, field, &fields[field],
04997 &field_data, pos, type))
04998 return FALSE;
04999
05000 if (!_dbus_string_validate_member (&field_data, 0,
05001 _dbus_string_get_length (&field_data)))
05002 {
05003 _dbus_verbose ("member field has invalid content \"%s\"\n",
05004 _dbus_string_get_const_data (&field_data));
05005 return FALSE;
05006 }
05007 break;
05008
05009 case DBUS_HEADER_FIELD_ERROR_NAME:
05010 if (!decode_string_field (data, field, &fields[field],
05011 &field_data, pos, type))
05012 return FALSE;
05013
05014 if (!_dbus_string_validate_error_name (&field_data, 0,
05015 _dbus_string_get_length (&field_data)))
05016 {
05017 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
05018 _dbus_string_get_const_data (&field_data));
05019 return FALSE;
05020 }
05021 break;
05022
05023 case DBUS_HEADER_FIELD_SENDER_SERVICE:
05024 if (!decode_string_field (data, field, &fields[field],
05025 &field_data, pos, type))
05026 return FALSE;
05027
05028 if (!_dbus_string_validate_service (&field_data, 0,
05029 _dbus_string_get_length (&field_data)))
05030 {
05031 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
05032 _dbus_string_get_const_data (&field_data));
05033 return FALSE;
05034 }
05035 break;
05036
05037 case DBUS_HEADER_FIELD_PATH:
05038
05039
05040
05041
05042
05043
05044 if (fields[field].name_offset >= 0)
05045 {
05046 _dbus_verbose ("path field provided twice\n");
05047 return FALSE;
05048 }
05049 if (type != DBUS_TYPE_OBJECT_PATH)
05050 {
05051 _dbus_verbose ("path field has wrong type\n");
05052 return FALSE;
05053 }
05054
05055 fields[field].name_offset = pos;
05056 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05057
05058
05059 {
05060 const char *s;
05061 s = _dbus_string_get_const_data_len (data,
05062 fields[field].value_offset,
05063 _dbus_string_get_length (data) -
05064 fields[field].value_offset);
05065 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
05066 {
05067 _dbus_verbose ("Message is on the local path\n");
05068 return FALSE;
05069 }
05070 }
05071
05072 _dbus_verbose ("Found path at offset %d\n",
05073 fields[field].value_offset);
05074 break;
05075
05076 case DBUS_HEADER_FIELD_REPLY_SERIAL:
05077 if (fields[field].name_offset >= 0)
05078 {
05079 _dbus_verbose ("reply field provided twice\n");
05080 return FALSE;
05081 }
05082
05083 if (type != DBUS_TYPE_UINT32)
05084 {
05085 _dbus_verbose ("reply field has wrong type\n");
05086 return FALSE;
05087 }
05088
05089 fields[field].name_offset = pos;
05090 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05091
05092 _dbus_verbose ("Found reply serial %u at offset %d\n",
05093 _dbus_demarshal_uint32 (data,
05094 byte_order,
05095 fields[field].value_offset,
05096 NULL),
05097 fields[field].value_offset);
05098 break;
05099
05100 default:
05101 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
05102 field, pos);
05103 }
05104
05105 pos = new_pos;
05106 }
05107
05108 if (pos < header_len)
05109 {
05110
05111 if ((header_len - pos) >= 8)
05112 {
05113 _dbus_verbose ("too much header alignment padding\n");
05114 return FALSE;
05115 }
05116
05117 if (!_dbus_string_validate_nul (data,
05118 pos, (header_len - pos)))
05119 {
05120 _dbus_verbose ("header alignment padding is not nul\n");
05121 return FALSE;
05122 }
05123 }
05124
05125
05126 switch (message_type)
05127 {
05128 case DBUS_MESSAGE_TYPE_SIGNAL:
05129 case DBUS_MESSAGE_TYPE_METHOD_CALL:
05130 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
05131 {
05132 _dbus_verbose ("No path field provided\n");
05133 return FALSE;
05134 }
05135
05136 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
05137 {
05138 _dbus_verbose ("No interface field provided\n");
05139 return FALSE;
05140 }
05141 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
05142 {
05143 _dbus_verbose ("No member field provided\n");
05144 return FALSE;
05145 }
05146 break;
05147 case DBUS_MESSAGE_TYPE_ERROR:
05148 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
05149 {
05150 _dbus_verbose ("No error-name field provided\n");
05151 return FALSE;
05152 }
05153 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05154 {
05155 _dbus_verbose ("No reply serial field provided in error\n");
05156 return FALSE;
05157 }
05158 break;
05159 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
05160 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05161 {
05162 _dbus_verbose ("No reply serial field provided in method return\n");
05163 return FALSE;
05164 }
05165 break;
05166 default:
05167
05168 break;
05169 }
05170
05171 if (message_padding)
05172 *message_padding = header_len - pos;
05173
05174 return TRUE;
05175 }
05176
05187 void
05188 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
05189 DBusString *buffer,
05190 int bytes_read)
05191 {
05192 _dbus_assert (loader->buffer_outstanding);
05193 _dbus_assert (buffer == &loader->data);
05194
05195 loader->buffer_outstanding = FALSE;
05196 }
05197
05198 static dbus_bool_t
05199 load_one_message (DBusMessageLoader *loader,
05200 int byte_order,
05201 int message_type,
05202 int header_len,
05203 int body_len)
05204 {
05205 DBusMessage *message;
05206 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
05207 int i;
05208 int next_arg;
05209 dbus_bool_t oom;
05210 int header_padding;
05211
05212 message = NULL;
05213 oom = FALSE;
05214
05215 #if 0
05216 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
05217 #endif
05218
05219 if (!decode_header_data (&loader->data,
05220 header_len, byte_order,
05221 message_type,
05222 fields, &header_padding))
05223 {
05224 _dbus_verbose ("Header was invalid\n");
05225 loader->corrupted = TRUE;
05226 goto failed;
05227 }
05228
05229 next_arg = header_len;
05230 while (next_arg < (header_len + body_len))
05231 {
05232 int type;
05233 int prev = next_arg;
05234
05235 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
05236 &type, &next_arg))
05237 {
05238 _dbus_verbose ("invalid typecode at offset %d\n", prev);
05239 loader->corrupted = TRUE;
05240 goto failed;
05241 }
05242
05243 if (!_dbus_marshal_validate_arg (&loader->data,
05244 byte_order,
05245 0,
05246 type, -1,
05247 next_arg,
05248 &next_arg))
05249 {
05250 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
05251 loader->corrupted = TRUE;
05252 goto failed;
05253 }
05254
05255 _dbus_assert (next_arg > prev);
05256 }
05257
05258 if (next_arg > (header_len + body_len))
05259 {
05260 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
05261 next_arg, header_len, body_len,
05262 header_len + body_len);
05263 loader->corrupted = TRUE;
05264 goto failed;
05265 }
05266
05267 message = dbus_message_new_empty_header ();
05268 if (message == NULL)
05269 {
05270 _dbus_verbose ("Failed to allocate empty message\n");
05271 oom = TRUE;
05272 goto failed;
05273 }
05274
05275 message->byte_order = byte_order;
05276 message->header_padding = header_padding;
05277
05278
05279 i = 0;
05280 while (i <= DBUS_HEADER_FIELD_LAST)
05281 {
05282 message->header_fields[i] = fields[i];
05283 ++i;
05284 }
05285
05286 if (!_dbus_list_append (&loader->messages, message))
05287 {
05288 _dbus_verbose ("Failed to append new message to loader queue\n");
05289 oom = TRUE;
05290 goto failed;
05291 }
05292
05293 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
05294 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
05295
05296 _dbus_assert (_dbus_string_get_length (&loader->data) >=
05297 (header_len + body_len));
05298
05299 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
05300 {
05301 _dbus_verbose ("Failed to move header into new message\n");
05302 oom = TRUE;
05303 goto failed;
05304 }
05305
05306 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
05307 {
05308 _dbus_verbose ("Failed to move body into new message\n");
05309
05310 oom = TRUE;
05311 goto failed;
05312 }
05313
05314 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
05315 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
05316
05317
05318
05319
05320 message->reply_serial = get_uint_field (message,
05321 DBUS_HEADER_FIELD_REPLY_SERIAL);
05322
05323 message->client_serial = _dbus_demarshal_uint32 (&message->header,
05324 message->byte_order,
05325 CLIENT_SERIAL_OFFSET,
05326 NULL);
05327 if (message->client_serial == 0 ||
05328 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0))
05329 {
05330 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n",
05331 message->client_serial,
05332 message->reply_serial);
05333
05334 loader->corrupted = TRUE;
05335 goto failed;
05336 }
05337
05338
05339
05340
05341
05342 {
05343 DBusMessageIter iter;
05344
05345 dbus_message_iter_init (message, &iter);
05346
05347 do
05348 {
05349 int t;
05350
05351 t = dbus_message_iter_get_arg_type (&iter);
05352 if (t == DBUS_TYPE_INVALID)
05353 break;
05354
05355 if (!_dbus_string_append_byte (&message->signature,
05356 t))
05357 {
05358 _dbus_verbose ("failed to append type byte to signature\n");
05359 oom = TRUE;
05360 goto failed;
05361 }
05362
05363 if (t == DBUS_TYPE_ARRAY)
05364 {
05365 DBusMessageIter child_iter;
05366 int array_type = t;
05367
05368 child_iter = iter;
05369
05370 while (array_type == DBUS_TYPE_ARRAY)
05371 {
05372 DBusMessageIter parent_iter = child_iter;
05373 dbus_message_iter_init_array_iterator (&parent_iter,
05374 &child_iter,
05375 &array_type);
05376
05377 if (!_dbus_string_append_byte (&message->signature,
05378 array_type))
05379 {
05380 _dbus_verbose ("failed to append array type byte to signature\n");
05381
05382 oom = TRUE;
05383 goto failed;
05384 }
05385 }
05386 }
05387 }
05388 while (dbus_message_iter_next (&iter));
05389 }
05390
05391 _dbus_verbose ("Loaded message %p\n", message);
05392
05393 _dbus_assert (!oom);
05394 _dbus_assert (!loader->corrupted);
05395
05396 return TRUE;
05397
05398 failed:
05399
05400
05401
05402 if (message != NULL)
05403 {
05404
05405 if (_dbus_string_get_length (&message->body) > 0)
05406 {
05407 dbus_bool_t result;
05408
05409 result = _dbus_string_copy_len (&message->body, 0, body_len,
05410 &loader->data, 0);
05411
05412 _dbus_assert (result);
05413 }
05414
05415 if (_dbus_string_get_length (&message->header) > 0)
05416 {
05417 dbus_bool_t result;
05418
05419 result = _dbus_string_copy_len (&message->header, 0, header_len,
05420 &loader->data, 0);
05421
05422 _dbus_assert (result);
05423 }
05424
05425
05426 _dbus_list_remove_last (&loader->messages, message);
05427
05428 dbus_message_unref (message);
05429 }
05430
05431
05432 return !oom;
05433 }
05434
05448 dbus_bool_t
05449 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
05450 {
05451 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16)
05452 {
05453 const char *header_data;
05454 int byte_order, message_type, header_len, body_len;
05455 dbus_uint32_t header_len_unsigned, body_len_unsigned;
05456
05457 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
05458
05459 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
05460
05461 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
05462 {
05463 _dbus_verbose ("Message has protocol version %d ours is %d\n",
05464 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
05465 loader->corrupted = TRUE;
05466 return TRUE;
05467 }
05468
05469 byte_order = header_data[BYTE_ORDER_OFFSET];
05470
05471 if (byte_order != DBUS_LITTLE_ENDIAN &&
05472 byte_order != DBUS_BIG_ENDIAN)
05473 {
05474 _dbus_verbose ("Message with bad byte order '%c' received\n",
05475 byte_order);
05476 loader->corrupted = TRUE;
05477 return TRUE;
05478 }
05479
05480
05481
05482
05483 message_type = header_data[TYPE_OFFSET];
05484 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
05485 {
05486 _dbus_verbose ("Message with bad type '%d' received\n",
05487 message_type);
05488 loader->corrupted = TRUE;
05489 return TRUE;
05490 }
05491
05492 header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
05493 body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
05494
05495 if (header_len_unsigned < 16)
05496 {
05497 _dbus_verbose ("Message had broken too-small header length %u\n",
05498 header_len_unsigned);
05499 loader->corrupted = TRUE;
05500 return TRUE;
05501 }
05502
05503 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
05504 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
05505 {
05506 _dbus_verbose ("Header or body length too large (%u %u)\n",
05507 header_len_unsigned,
05508 body_len_unsigned);
05509 loader->corrupted = TRUE;
05510 return TRUE;
05511 }
05512
05513
05514
05515
05516 header_len = header_len_unsigned;
05517 body_len = body_len_unsigned;
05518
05519 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
05520 {
05521
05522 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
05523 header_len);
05524 loader->corrupted = TRUE;
05525 return TRUE;
05526 }
05527
05528 if (header_len + body_len > loader->max_message_size)
05529 {
05530 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
05531 header_len, body_len, loader->max_message_size);
05532 loader->corrupted = TRUE;
05533 return TRUE;
05534 }
05535
05536 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
05537 {
05538 if (!load_one_message (loader, byte_order, message_type,
05539 header_len, body_len))
05540 return FALSE;
05541 }
05542 else
05543 return TRUE;
05544 }
05545
05546 return TRUE;
05547 }
05548
05556 DBusMessage*
05557 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
05558 {
05559 if (loader->messages)
05560 return loader->messages->data;
05561 else
05562 return NULL;
05563 }
05564
05573 DBusMessage*
05574 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
05575 {
05576 return _dbus_list_pop_first (&loader->messages);
05577 }
05578
05587 DBusList*
05588 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
05589 {
05590 return _dbus_list_pop_first_link (&loader->messages);
05591 }
05592
05599 void
05600 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
05601 DBusList *link)
05602 {
05603 _dbus_list_prepend_link (&loader->messages, link);
05604 }
05605
05615 dbus_bool_t
05616 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
05617 {
05618 return loader->corrupted;
05619 }
05620
05627 void
05628 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
05629 long size)
05630 {
05631 if (size > MAX_SANE_MESSAGE_SIZE)
05632 {
05633 _dbus_verbose ("clamping requested max message size %ld to %d\n",
05634 size, MAX_SANE_MESSAGE_SIZE);
05635 size = MAX_SANE_MESSAGE_SIZE;
05636 }
05637 loader->max_message_size = size;
05638 }
05639
05646 long
05647 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
05648 {
05649 return loader->max_message_size;
05650 }
05651
05652 static DBusDataSlotAllocator slot_allocator;
05653 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
05654
05669 dbus_bool_t
05670 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
05671 {
05672 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05673 _DBUS_LOCK_NAME (message_slots),
05674 slot_p);
05675 }
05676
05688 void
05689 dbus_message_free_data_slot (dbus_int32_t *slot_p)
05690 {
05691 _dbus_return_if_fail (*slot_p >= 0);
05692
05693 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05694 }
05695
05709 dbus_bool_t
05710 dbus_message_set_data (DBusMessage *message,
05711 dbus_int32_t slot,
05712 void *data,
05713 DBusFreeFunction free_data_func)
05714 {
05715 DBusFreeFunction old_free_func;
05716 void *old_data;
05717 dbus_bool_t retval;
05718
05719 _dbus_return_val_if_fail (message != NULL, FALSE);
05720 _dbus_return_val_if_fail (slot >= 0, FALSE);
05721
05722 retval = _dbus_data_slot_list_set (&slot_allocator,
05723 &message->slot_list,
05724 slot, data, free_data_func,
05725 &old_free_func, &old_data);
05726
05727 if (retval)
05728 {
05729
05730 if (old_free_func)
05731 (* old_free_func) (old_data);
05732 }
05733
05734 return retval;
05735 }
05736
05745 void*
05746 dbus_message_get_data (DBusMessage *message,
05747 dbus_int32_t slot)
05748 {
05749 void *res;
05750
05751 _dbus_return_val_if_fail (message != NULL, NULL);
05752
05753 res = _dbus_data_slot_list_get (&slot_allocator,
05754 &message->slot_list,
05755 slot);
05756
05757 return res;
05758 }
05759
05773 int
05774 dbus_message_type_from_string (const char *type_str)
05775 {
05776 if (strcmp (type_str, "method_call") == 0)
05777 return DBUS_MESSAGE_TYPE_METHOD_CALL;
05778 if (strcmp (type_str, "method_return") == 0)
05779 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
05780 else if (strcmp (type_str, "signal") == 0)
05781 return DBUS_MESSAGE_TYPE_SIGNAL;
05782 else if (strcmp (type_str, "error") == 0)
05783 return DBUS_MESSAGE_TYPE_ERROR;
05784 else
05785 return DBUS_MESSAGE_TYPE_INVALID;
05786 }
05787
05789 #ifdef DBUS_BUILD_TESTS
05790 #include "dbus-test.h"
05791 #include <stdio.h>
05792 #include <stdlib.h>
05793
05794 static void
05795 message_iter_test (DBusMessage *message)
05796 {
05797 DBusMessageIter iter, dict, array, array2;
05798 char *str;
05799 unsigned char *data;
05800 dbus_int32_t *our_int_array;
05801 int len;
05802
05803 dbus_message_iter_init (message, &iter);
05804
05805
05806 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
05807 _dbus_assert_not_reached ("Argument type isn't string");
05808
05809 str = dbus_message_iter_get_string (&iter);
05810 if (strcmp (str, "Test string") != 0)
05811 _dbus_assert_not_reached ("Strings differ");
05812 dbus_free (str);
05813
05814 if (!dbus_message_iter_next (&iter))
05815 _dbus_assert_not_reached ("Reached end of arguments");
05816
05817
05818 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
05819 _dbus_assert_not_reached ("Argument type isn't int32");
05820
05821 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
05822 _dbus_assert_not_reached ("Signed integers differ");
05823
05824 if (!dbus_message_iter_next (&iter))
05825 _dbus_assert_not_reached ("Reached end of fields");
05826
05827
05828 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
05829 _dbus_assert_not_reached ("Argument type isn't int32");
05830
05831 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
05832 _dbus_assert_not_reached ("Unsigned integers differ");
05833
05834 if (!dbus_message_iter_next (&iter))
05835 _dbus_assert_not_reached ("Reached end of arguments");
05836
05837
05838 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
05839 _dbus_assert_not_reached ("Argument type isn't double");
05840
05841 if (dbus_message_iter_get_double (&iter) != 3.14159)
05842 _dbus_assert_not_reached ("Doubles differ");
05843
05844 if (!dbus_message_iter_next (&iter))
05845 _dbus_assert_not_reached ("Reached end of arguments");
05846
05847 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
05848 _dbus_assert_not_reached ("Argument type not an array");
05849
05850 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
05851 _dbus_assert_not_reached ("Array type not double");
05852
05853
05854 dbus_message_iter_init_array_iterator (&iter, &array, NULL);
05855
05856 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05857 _dbus_assert_not_reached ("Argument type isn't double");
05858
05859 if (dbus_message_iter_get_double (&array) != 1.5)
05860 _dbus_assert_not_reached ("Unsigned integers differ");
05861
05862 if (!dbus_message_iter_next (&array))
05863 _dbus_assert_not_reached ("Reached end of arguments");
05864
05865 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05866 _dbus_assert_not_reached ("Argument type isn't double");
05867
05868 if (dbus_message_iter_get_double (&array) != 2.5)
05869 _dbus_assert_not_reached ("Unsigned integers differ");
05870
05871 if (dbus_message_iter_next (&array))
05872 _dbus_assert_not_reached ("Didn't reach end of arguments");
05873
05874 if (!dbus_message_iter_next (&iter))
05875 _dbus_assert_not_reached ("Reached end of arguments");
05876
05877
05878
05879
05880 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
05881 _dbus_assert_not_reached ("not dict type");
05882
05883 dbus_message_iter_init_dict_iterator (&iter, &dict);
05884
05885 str = dbus_message_iter_get_dict_key (&dict);
05886 if (str == NULL || strcmp (str, "test") != 0)
05887 _dbus_assert_not_reached ("wrong dict key");
05888 dbus_free (str);
05889
05890 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
05891 _dbus_assert_not_reached ("wrong dict entry type");
05892
05893 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
05894 _dbus_assert_not_reached ("wrong dict entry value");
05895
05896 if (!dbus_message_iter_next (&dict))
05897 _dbus_assert_not_reached ("reached end of dict");
05898
05899
05900
05901 str = dbus_message_iter_get_dict_key (&dict);
05902 if (str == NULL || strcmp (str, "array") != 0)
05903 _dbus_assert_not_reached ("wrong dict key");
05904 dbus_free (str);
05905
05906 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
05907 _dbus_assert_not_reached ("Argument type not an array");
05908
05909 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
05910 _dbus_assert_not_reached ("Array type not array");
05911
05912 dbus_message_iter_init_array_iterator (&dict, &array, NULL);
05913
05914 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
05915 _dbus_assert_not_reached ("Argument type isn't array");
05916
05917 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05918 _dbus_assert_not_reached ("Array type not int32");
05919
05920 dbus_message_iter_init_array_iterator (&array, &array2, NULL);
05921
05922 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
05923 _dbus_assert_not_reached ("Argument type isn't int32");
05924
05925 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
05926 _dbus_assert_not_reached ("Signed integers differ");
05927
05928 if (!dbus_message_iter_next (&array2))
05929 _dbus_assert_not_reached ("Reached end of arguments");
05930
05931 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
05932 _dbus_assert_not_reached ("Signed integers differ");
05933
05934 if (dbus_message_iter_next (&array2))
05935 _dbus_assert_not_reached ("Didn't reached end of arguments");
05936
05937 if (!dbus_message_iter_next (&array))
05938 _dbus_assert_not_reached ("Reached end of arguments");
05939
05940 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05941 _dbus_assert_not_reached ("Array type not int32");
05942
05943 if (!dbus_message_iter_get_int32_array (&array,
05944 &our_int_array,
05945 &len))
05946 _dbus_assert_not_reached ("couldn't get int32 array");
05947
05948 _dbus_assert (len == 3);
05949 _dbus_assert (our_int_array[0] == 0x34567812 &&
05950 our_int_array[1] == 0x45678123 &&
05951 our_int_array[2] == 0x56781234);
05952 dbus_free (our_int_array);
05953
05954 if (dbus_message_iter_next (&array))
05955 _dbus_assert_not_reached ("Didn't reach end of array");
05956
05957 if (dbus_message_iter_next (&dict))
05958 _dbus_assert_not_reached ("Didn't reach end of dict");
05959
05960 if (!dbus_message_iter_next (&iter))
05961 _dbus_assert_not_reached ("Reached end of arguments");
05962
05963 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
05964 {
05965 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
05966 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
05967 }
05968
05969 if (dbus_message_iter_get_byte (&iter) != 0xF0)
05970 _dbus_assert_not_reached ("wrong value after dict");
05971
05972
05973 if (!dbus_message_iter_next (&iter))
05974 _dbus_assert_not_reached ("Reached end of arguments");
05975
05976 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
05977 _dbus_assert_not_reached ("not a nil type");
05978
05979 if (!dbus_message_iter_next (&iter))
05980 _dbus_assert_not_reached ("Reached end of arguments");
05981
05982 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_CUSTOM)
05983 _dbus_assert_not_reached ("wrong type after dict");
05984
05985 if (!dbus_message_iter_get_custom (&iter, &str, &data, &len))
05986 _dbus_assert_not_reached ("failed to get custom type");
05987
05988 _dbus_assert (strcmp (str, "MyTypeName")==0);
05989 _dbus_assert (len == 5);
05990 _dbus_assert (strcmp (data, "data")==0);
05991 dbus_free (str);
05992 dbus_free (data);
05993
05994 if (dbus_message_iter_next (&iter))
05995 _dbus_assert_not_reached ("Didn't reach end of arguments");
05996 }
05997
05998
05999 static dbus_bool_t
06000 check_message_handling_type (DBusMessageIter *iter,
06001 int type)
06002 {
06003 DBusMessageIter child_iter;
06004
06005 switch (type)
06006 {
06007 case DBUS_TYPE_NIL:
06008 break;
06009 case DBUS_TYPE_BYTE:
06010 dbus_message_iter_get_byte (iter);
06011 break;
06012 case DBUS_TYPE_BOOLEAN:
06013 dbus_message_iter_get_boolean (iter);
06014 break;
06015 case DBUS_TYPE_INT32:
06016 dbus_message_iter_get_int32 (iter);
06017 break;
06018 case DBUS_TYPE_UINT32:
06019 dbus_message_iter_get_uint32 (iter);
06020 break;
06021 case DBUS_TYPE_INT64:
06022 #ifdef DBUS_HAVE_INT64
06023 dbus_message_iter_get_int64 (iter);
06024 #endif
06025 break;
06026 case DBUS_TYPE_UINT64:
06027 #ifdef DBUS_HAVE_INT64
06028 dbus_message_iter_get_uint64 (iter);
06029 #endif
06030 break;
06031 case DBUS_TYPE_DOUBLE:
06032 dbus_message_iter_get_double (iter);
06033 break;
06034 case DBUS_TYPE_STRING:
06035 {
06036 char *str;
06037 str = dbus_message_iter_get_string (iter);
06038 if (str == NULL)
06039 {
06040 _dbus_warn ("NULL string in message\n");
06041 return FALSE;
06042 }
06043 dbus_free (str);
06044 }
06045 break;
06046 case DBUS_TYPE_CUSTOM:
06047 {
06048 char *name;
06049 unsigned char *data;
06050 int len;
06051
06052 if (!dbus_message_iter_get_custom (iter, &name, &data, &len))
06053 {
06054 _dbus_warn ("error reading name from custom type\n");
06055 return FALSE;
06056 }
06057 dbus_free (data);
06058 dbus_free (name);
06059 }
06060 break;
06061 case DBUS_TYPE_ARRAY:
06062 {
06063 int array_type;
06064
06065 dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type);
06066
06067 while (dbus_message_iter_has_next (&child_iter))
06068 {
06069 if (!check_message_handling_type (&child_iter, array_type))
06070 {
06071 _dbus_warn ("error in array element\n");
06072 return FALSE;
06073 }
06074
06075 if (!dbus_message_iter_next (&child_iter))
06076 break;
06077 }
06078 }
06079 break;
06080 case DBUS_TYPE_DICT:
06081 {
06082 int entry_type;
06083 char *key;
06084
06085 dbus_message_iter_init_dict_iterator (iter, &child_iter);
06086
06087 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
06088 {
06089 key = dbus_message_iter_get_dict_key (&child_iter);
06090 if (key == NULL)
06091 {
06092 _dbus_warn ("error reading dict key\n");
06093 return FALSE;
06094 }
06095 dbus_free (key);
06096
06097 if (!check_message_handling_type (&child_iter, entry_type))
06098 {
06099 _dbus_warn ("error in dict value\n");
06100 return FALSE;
06101 }
06102
06103 if (!dbus_message_iter_next (&child_iter))
06104 break;
06105 }
06106 }
06107 break;
06108
06109 default:
06110 _dbus_warn ("unknown type %d\n", type);
06111 return FALSE;
06112 break;
06113 }
06114 return TRUE;
06115 }
06116
06117
06118 static dbus_bool_t
06119 check_message_handling (DBusMessage *message)
06120 {
06121 DBusMessageIter iter;
06122 int type;
06123 dbus_bool_t retval;
06124 dbus_uint32_t client_serial;
06125
06126 retval = FALSE;
06127
06128 client_serial = dbus_message_get_serial (message);
06129
06130
06131 _dbus_marshal_set_uint32 (&message->header,
06132 message->byte_order,
06133 CLIENT_SERIAL_OFFSET,
06134 client_serial);
06135
06136 if (client_serial != dbus_message_get_serial (message))
06137 {
06138 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
06139 goto failed;
06140 }
06141
06142
06143
06144
06145
06146 dbus_message_iter_init (message, &iter);
06147 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
06148 {
06149 if (!check_message_handling_type (&iter, type))
06150 goto failed;
06151
06152 if (!dbus_message_iter_next (&iter))
06153 break;
06154 }
06155
06156 retval = TRUE;
06157
06158 failed:
06159 return retval;
06160 }
06161
06162 static dbus_bool_t
06163 check_have_valid_message (DBusMessageLoader *loader)
06164 {
06165 DBusMessage *message;
06166 dbus_bool_t retval;
06167
06168 message = NULL;
06169 retval = FALSE;
06170
06171 if (!_dbus_message_loader_queue_messages (loader))
06172 _dbus_assert_not_reached ("no memory to queue messages");
06173
06174 if (_dbus_message_loader_get_is_corrupted (loader))
06175 {
06176 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
06177 goto failed;
06178 }
06179
06180 message = _dbus_message_loader_pop_message (loader);
06181 if (message == NULL)
06182 {
06183 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
06184 goto failed;
06185 }
06186
06187 if (_dbus_string_get_length (&loader->data) > 0)
06188 {
06189 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
06190 goto failed;
06191 }
06192
06193
06194
06195
06196
06197 if (!check_message_handling (message))
06198 goto failed;
06199
06200 retval = TRUE;
06201
06202 failed:
06203 if (message)
06204 dbus_message_unref (message);
06205
06206 return retval;
06207 }
06208
06209 static dbus_bool_t
06210 check_invalid_message (DBusMessageLoader *loader)
06211 {
06212 dbus_bool_t retval;
06213
06214 retval = FALSE;
06215
06216 if (!_dbus_message_loader_queue_messages (loader))
06217 _dbus_assert_not_reached ("no memory to queue messages");
06218
06219 if (!_dbus_message_loader_get_is_corrupted (loader))
06220 {
06221 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
06222 goto failed;
06223 }
06224
06225 retval = TRUE;
06226
06227 failed:
06228 return retval;
06229 }
06230
06231 static dbus_bool_t
06232 check_incomplete_message (DBusMessageLoader *loader)
06233 {
06234 DBusMessage *message;
06235 dbus_bool_t retval;
06236
06237 message = NULL;
06238 retval = FALSE;
06239
06240 if (!_dbus_message_loader_queue_messages (loader))
06241 _dbus_assert_not_reached ("no memory to queue messages");
06242
06243 if (_dbus_message_loader_get_is_corrupted (loader))
06244 {
06245 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
06246 goto failed;
06247 }
06248
06249 message = _dbus_message_loader_pop_message (loader);
06250 if (message != NULL)
06251 {
06252 _dbus_warn ("loaded message that was expected to be incomplete\n");
06253 goto failed;
06254 }
06255
06256 retval = TRUE;
06257
06258 failed:
06259 if (message)
06260 dbus_message_unref (message);
06261 return retval;
06262 }
06263
06264 static dbus_bool_t
06265 check_loader_results (DBusMessageLoader *loader,
06266 DBusMessageValidity validity)
06267 {
06268 if (!_dbus_message_loader_queue_messages (loader))
06269 _dbus_assert_not_reached ("no memory to queue messages");
06270
06271 switch (validity)
06272 {
06273 case _DBUS_MESSAGE_VALID:
06274 return check_have_valid_message (loader);
06275 case _DBUS_MESSAGE_INVALID:
06276 return check_invalid_message (loader);
06277 case _DBUS_MESSAGE_INCOMPLETE:
06278 return check_incomplete_message (loader);
06279 case _DBUS_MESSAGE_UNKNOWN:
06280 return TRUE;
06281 }
06282
06283 _dbus_assert_not_reached ("bad DBusMessageValidity");
06284 return FALSE;
06285 }
06286
06287
06296 dbus_bool_t
06297 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
06298 dbus_bool_t is_raw,
06299 DBusString *data)
06300 {
06301 dbus_bool_t retval;
06302
06303 retval = FALSE;
06304
06305 if (is_raw)
06306 {
06307 DBusError error;
06308
06309 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
06310 dbus_error_init (&error);
06311 if (!_dbus_file_get_contents (data, filename, &error))
06312 {
06313 _dbus_warn ("Could not load message file %s: %s\n",
06314 _dbus_string_get_const_data (filename),
06315 error.message);
06316 dbus_error_free (&error);
06317 goto failed;
06318 }
06319 }
06320 else
06321 {
06322 if (!_dbus_message_data_load (data, filename))
06323 {
06324 _dbus_warn ("Could not load message file %s\n",
06325 _dbus_string_get_const_data (filename));
06326 goto failed;
06327 }
06328 }
06329
06330 retval = TRUE;
06331
06332 failed:
06333
06334 return retval;
06335 }
06336
06346 dbus_bool_t
06347 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
06348 dbus_bool_t is_raw,
06349 DBusMessageValidity expected_validity)
06350 {
06351 DBusString data;
06352 dbus_bool_t retval;
06353
06354 retval = FALSE;
06355
06356 if (!_dbus_string_init (&data))
06357 _dbus_assert_not_reached ("could not allocate string\n");
06358
06359 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
06360 &data))
06361 goto failed;
06362
06363 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
06364
06365 failed:
06366
06367 if (!retval)
06368 {
06369 if (_dbus_string_get_length (&data) > 0)
06370 _dbus_verbose_bytes_of_string (&data, 0,
06371 _dbus_string_get_length (&data));
06372
06373 _dbus_warn ("Failed message loader test on %s\n",
06374 _dbus_string_get_const_data (filename));
06375 }
06376
06377 _dbus_string_free (&data);
06378
06379 return retval;
06380 }
06381
06390 dbus_bool_t
06391 dbus_internal_do_not_use_try_message_data (const DBusString *data,
06392 DBusMessageValidity expected_validity)
06393 {
06394 DBusMessageLoader *loader;
06395 dbus_bool_t retval;
06396 int len;
06397 int i;
06398
06399 loader = NULL;
06400 retval = FALSE;
06401
06402
06403
06404 loader = _dbus_message_loader_new ();
06405
06406
06407 _dbus_message_loader_ref (loader);
06408 _dbus_message_loader_unref (loader);
06409 _dbus_message_loader_get_max_message_size (loader);
06410
06411 len = _dbus_string_get_length (data);
06412 for (i = 0; i < len; i++)
06413 {
06414 DBusString *buffer;
06415
06416 _dbus_message_loader_get_buffer (loader, &buffer);
06417 _dbus_string_append_byte (buffer,
06418 _dbus_string_get_byte (data, i));
06419 _dbus_message_loader_return_buffer (loader, buffer, 1);
06420 }
06421
06422 if (!check_loader_results (loader, expected_validity))
06423 goto failed;
06424
06425 _dbus_message_loader_unref (loader);
06426 loader = NULL;
06427
06428
06429
06430 loader = _dbus_message_loader_new ();
06431
06432 {
06433 DBusString *buffer;
06434
06435 _dbus_message_loader_get_buffer (loader, &buffer);
06436 _dbus_string_copy (data, 0, buffer,
06437 _dbus_string_get_length (buffer));
06438 _dbus_message_loader_return_buffer (loader, buffer, 1);
06439 }
06440
06441 if (!check_loader_results (loader, expected_validity))
06442 goto failed;
06443
06444 _dbus_message_loader_unref (loader);
06445 loader = NULL;
06446
06447
06448
06449 loader = _dbus_message_loader_new ();
06450
06451 len = _dbus_string_get_length (data);
06452 for (i = 0; i < len; i += 2)
06453 {
06454 DBusString *buffer;
06455
06456 _dbus_message_loader_get_buffer (loader, &buffer);
06457 _dbus_string_append_byte (buffer,
06458 _dbus_string_get_byte (data, i));
06459 if ((i+1) < len)
06460 _dbus_string_append_byte (buffer,
06461 _dbus_string_get_byte (data, i+1));
06462 _dbus_message_loader_return_buffer (loader, buffer, 1);
06463 }
06464
06465 if (!check_loader_results (loader, expected_validity))
06466 goto failed;
06467
06468 _dbus_message_loader_unref (loader);
06469 loader = NULL;
06470
06471 retval = TRUE;
06472
06473 failed:
06474
06475 if (loader)
06476 _dbus_message_loader_unref (loader);
06477
06478 return retval;
06479 }
06480
06481 static dbus_bool_t
06482 process_test_subdir (const DBusString *test_base_dir,
06483 const char *subdir,
06484 DBusMessageValidity validity,
06485 DBusForeachMessageFileFunc function,
06486 void *user_data)
06487 {
06488 DBusString test_directory;
06489 DBusString filename;
06490 DBusDirIter *dir;
06491 dbus_bool_t retval;
06492 DBusError error;
06493
06494 retval = FALSE;
06495 dir = NULL;
06496
06497 if (!_dbus_string_init (&test_directory))
06498 _dbus_assert_not_reached ("didn't allocate test_directory\n");
06499
06500 _dbus_string_init_const (&filename, subdir);
06501
06502 if (!_dbus_string_copy (test_base_dir, 0,
06503 &test_directory, 0))
06504 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
06505
06506 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
06507 _dbus_assert_not_reached ("couldn't allocate full path");
06508
06509 _dbus_string_free (&filename);
06510 if (!_dbus_string_init (&filename))
06511 _dbus_assert_not_reached ("didn't allocate filename string\n");
06512
06513 dbus_error_init (&error);
06514 dir = _dbus_directory_open (&test_directory, &error);
06515 if (dir == NULL)
06516 {
06517 _dbus_warn ("Could not open %s: %s\n",
06518 _dbus_string_get_const_data (&test_directory),
06519 error.message);
06520 dbus_error_free (&error);
06521 goto failed;
06522 }
06523
06524 printf ("Testing %s:\n", subdir);
06525
06526 next:
06527 while (_dbus_directory_get_next_file (dir, &filename, &error))
06528 {
06529 DBusString full_path;
06530 dbus_bool_t is_raw;
06531
06532 if (!_dbus_string_init (&full_path))
06533 _dbus_assert_not_reached ("couldn't init string");
06534
06535 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
06536 _dbus_assert_not_reached ("couldn't copy dir to full_path");
06537
06538 if (!_dbus_concat_dir_and_file (&full_path, &filename))
06539 _dbus_assert_not_reached ("couldn't concat file to dir");
06540
06541 if (_dbus_string_ends_with_c_str (&filename, ".message"))
06542 is_raw = FALSE;
06543 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
06544 is_raw = TRUE;
06545 else
06546 {
06547 _dbus_verbose ("Skipping non-.message file %s\n",
06548 _dbus_string_get_const_data (&filename));
06549 _dbus_string_free (&full_path);
06550 goto next;
06551 }
06552
06553 printf (" %s\n",
06554 _dbus_string_get_const_data (&filename));
06555
06556 _dbus_verbose (" expecting %s for %s\n",
06557 validity == _DBUS_MESSAGE_VALID ? "valid" :
06558 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
06559 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
06560 _dbus_string_get_const_data (&filename));
06561
06562 if (! (*function) (&full_path, is_raw, validity, user_data))
06563 {
06564 _dbus_string_free (&full_path);
06565 goto failed;
06566 }
06567 else
06568 _dbus_string_free (&full_path);
06569 }
06570
06571 if (dbus_error_is_set (&error))
06572 {
06573 _dbus_warn ("Could not get next file in %s: %s\n",
06574 _dbus_string_get_const_data (&test_directory),
06575 error.message);
06576 dbus_error_free (&error);
06577 goto failed;
06578 }
06579
06580 retval = TRUE;
06581
06582 failed:
06583
06584 if (dir)
06585 _dbus_directory_close (dir);
06586 _dbus_string_free (&test_directory);
06587 _dbus_string_free (&filename);
06588
06589 return retval;
06590 }
06591
06601 dbus_bool_t
06602 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
06603 DBusForeachMessageFileFunc func,
06604 void *user_data)
06605 {
06606 DBusString test_directory;
06607 dbus_bool_t retval;
06608
06609 retval = FALSE;
06610
06611 _dbus_string_init_const (&test_directory, test_data_dir);
06612
06613 if (!process_test_subdir (&test_directory, "valid-messages",
06614 _DBUS_MESSAGE_VALID, func, user_data))
06615 goto failed;
06616
06617 if (!process_test_subdir (&test_directory, "invalid-messages",
06618 _DBUS_MESSAGE_INVALID, func, user_data))
06619 goto failed;
06620
06621 if (!process_test_subdir (&test_directory, "incomplete-messages",
06622 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
06623 goto failed;
06624
06625 retval = TRUE;
06626
06627 failed:
06628
06629 _dbus_string_free (&test_directory);
06630
06631 return retval;
06632 }
06633
06634 static void
06635 verify_test_message (DBusMessage *message)
06636 {
06637 DBusMessageIter iter, dict;
06638 DBusError error;
06639 dbus_int32_t our_int;
06640 char *our_str;
06641 double our_double;
06642 dbus_bool_t our_bool;
06643 dbus_uint32_t our_uint32;
06644 dbus_int32_t *our_uint32_array;
06645 int our_uint32_array_len;
06646 dbus_int32_t *our_int32_array;
06647 int our_int32_array_len;
06648 char **our_string_array;
06649 int our_string_array_len;
06650 #ifdef DBUS_HAVE_INT64
06651 dbus_int64_t our_int64;
06652 dbus_uint64_t our_uint64;
06653 dbus_int64_t *our_uint64_array;
06654 int our_uint64_array_len;
06655 dbus_int64_t *our_int64_array;
06656 int our_int64_array_len;
06657 #endif
06658 double *our_double_array;
06659 int our_double_array_len;
06660 unsigned char *our_byte_array;
06661 int our_byte_array_len;
06662 unsigned char *our_boolean_array;
06663 int our_boolean_array_len;
06664
06665 dbus_message_iter_init (message, &iter);
06666
06667 dbus_error_init (&error);
06668 if (!dbus_message_iter_get_args (&iter, &error,
06669 DBUS_TYPE_INT32, &our_int,
06670 #ifdef DBUS_HAVE_INT64
06671 DBUS_TYPE_INT64, &our_int64,
06672 DBUS_TYPE_UINT64, &our_uint64,
06673 #endif
06674 DBUS_TYPE_STRING, &our_str,
06675 DBUS_TYPE_DOUBLE, &our_double,
06676 DBUS_TYPE_BOOLEAN, &our_bool,
06677 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
06678 &our_uint32_array, &our_uint32_array_len,
06679 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
06680 &our_int32_array, &our_int32_array_len,
06681 #ifdef DBUS_HAVE_INT64
06682 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
06683 &our_uint64_array, &our_uint64_array_len,
06684 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
06685 &our_int64_array, &our_int64_array_len,
06686 #endif
06687 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
06688 &our_string_array, &our_string_array_len,
06689 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
06690 &our_double_array, &our_double_array_len,
06691 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
06692 &our_byte_array, &our_byte_array_len,
06693 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
06694 &our_boolean_array, &our_boolean_array_len,
06695 0))
06696 {
06697 _dbus_warn ("error: %s - %s\n", error.name,
06698 (error.message != NULL) ? error.message : "no message");
06699 _dbus_assert_not_reached ("Could not get arguments");
06700 }
06701
06702 if (our_int != -0x12345678)
06703 _dbus_assert_not_reached ("integers differ!");
06704
06705 #ifdef DBUS_HAVE_INT64
06706 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
06707 _dbus_assert_not_reached ("64-bit integers differ!");
06708 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
06709 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
06710 #endif
06711
06712 if (our_double != 3.14159)
06713 _dbus_assert_not_reached ("doubles differ!");
06714
06715 if (strcmp (our_str, "Test string") != 0)
06716 _dbus_assert_not_reached ("strings differ!");
06717 dbus_free (our_str);
06718
06719 if (!our_bool)
06720 _dbus_assert_not_reached ("booleans differ");
06721
06722 if (our_uint32_array_len != 4 ||
06723 our_uint32_array[0] != 0x12345678 ||
06724 our_uint32_array[1] != 0x23456781 ||
06725 our_uint32_array[2] != 0x34567812 ||
06726 our_uint32_array[3] != 0x45678123)
06727 _dbus_assert_not_reached ("uint array differs");
06728 dbus_free (our_uint32_array);
06729
06730 if (our_int32_array_len != 4 ||
06731 our_int32_array[0] != 0x12345678 ||
06732 our_int32_array[1] != -0x23456781 ||
06733 our_int32_array[2] != 0x34567812 ||
06734 our_int32_array[3] != -0x45678123)
06735 _dbus_assert_not_reached ("int array differs");
06736 dbus_free (our_int32_array);
06737
06738 #ifdef DBUS_HAVE_INT64
06739 if (our_uint64_array_len != 4 ||
06740 our_uint64_array[0] != 0x12345678 ||
06741 our_uint64_array[1] != 0x23456781 ||
06742 our_uint64_array[2] != 0x34567812 ||
06743 our_uint64_array[3] != 0x45678123)
06744 _dbus_assert_not_reached ("uint64 array differs");
06745 dbus_free (our_uint64_array);
06746
06747 if (our_int64_array_len != 4 ||
06748 our_int64_array[0] != 0x12345678 ||
06749 our_int64_array[1] != -0x23456781 ||
06750 our_int64_array[2] != 0x34567812 ||
06751 our_int64_array[3] != -0x45678123)
06752 _dbus_assert_not_reached ("int64 array differs");
06753 dbus_free (our_int64_array);
06754 #endif
06755
06756 if (our_string_array_len != 4)
06757 _dbus_assert_not_reached ("string array has wrong length");
06758
06759 if (strcmp (our_string_array[0], "Foo") != 0 ||
06760 strcmp (our_string_array[1], "bar") != 0 ||
06761 strcmp (our_string_array[2], "") != 0 ||
06762 strcmp (our_string_array[3], "woo woo woo woo") != 0)
06763 _dbus_assert_not_reached ("string array differs");
06764
06765 dbus_free_string_array (our_string_array);
06766
06767 if (our_double_array_len != 3)
06768 _dbus_assert_not_reached ("double array had wrong length");
06769
06770
06771
06772
06773 if (our_double_array[0] != 0.1234 ||
06774 our_double_array[1] != 9876.54321 ||
06775 our_double_array[2] != -300.0)
06776 _dbus_assert_not_reached ("double array had wrong values");
06777
06778 dbus_free (our_double_array);
06779
06780 if (our_byte_array_len != 4)
06781 _dbus_assert_not_reached ("byte array had wrong length");
06782
06783 if (our_byte_array[0] != 'a' ||
06784 our_byte_array[1] != 'b' ||
06785 our_byte_array[2] != 'c' ||
06786 our_byte_array[3] != 234)
06787 _dbus_assert_not_reached ("byte array had wrong values");
06788
06789 dbus_free (our_byte_array);
06790
06791 if (our_boolean_array_len != 5)
06792 _dbus_assert_not_reached ("bool array had wrong length");
06793
06794 if (our_boolean_array[0] != TRUE ||
06795 our_boolean_array[1] != FALSE ||
06796 our_boolean_array[2] != TRUE ||
06797 our_boolean_array[3] != TRUE ||
06798 our_boolean_array[4] != FALSE)
06799 _dbus_assert_not_reached ("bool array had wrong values");
06800
06801 dbus_free (our_boolean_array);
06802
06803 if (!dbus_message_iter_next (&iter))
06804 _dbus_assert_not_reached ("Reached end of arguments");
06805
06806 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06807 _dbus_assert_not_reached ("not dict type");
06808
06809 dbus_message_iter_init_dict_iterator (&iter, &dict);
06810
06811 our_str = dbus_message_iter_get_dict_key (&dict);
06812 if (our_str == NULL || strcmp (our_str, "test") != 0)
06813 _dbus_assert_not_reached ("wrong dict key");
06814 dbus_free (our_str);
06815
06816 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
06817 {
06818 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
06819 _dbus_assert_not_reached ("wrong dict entry type");
06820 }
06821
06822 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
06823 {
06824 _dbus_verbose ("dict entry val: %x\n", our_uint32);
06825 _dbus_assert_not_reached ("wrong dict entry value");
06826 }
06827
06828 if (dbus_message_iter_next (&dict))
06829 _dbus_assert_not_reached ("Didn't reach end of dict");
06830
06831 if (!dbus_message_iter_next (&iter))
06832 _dbus_assert_not_reached ("Reached end of arguments");
06833
06834 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
06835 _dbus_assert_not_reached ("wrong type after dict");
06836
06837 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
06838 _dbus_assert_not_reached ("wrong value after dict");
06839
06840 if (dbus_message_iter_next (&iter))
06841 _dbus_assert_not_reached ("Didn't reach end of arguments");
06842 }
06843
06850 dbus_bool_t
06851 _dbus_message_test (const char *test_data_dir)
06852 {
06853 DBusMessage *message;
06854 DBusMessageLoader *loader;
06855 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
06856 int i;
06857 const char *data;
06858 DBusMessage *copy;
06859 const char *name1;
06860 const char *name2;
06861 const dbus_uint32_t our_uint32_array[] =
06862 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06863 const dbus_uint32_t our_int32_array[] =
06864 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06865 #ifdef DBUS_HAVE_INT64
06866 const dbus_uint64_t our_uint64_array[] =
06867 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06868 const dbus_uint64_t our_int64_array[] =
06869 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06870 #endif
06871 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
06872 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
06873 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
06874 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
06875 char sig[64];
06876 const char *s;
06877 char *t;
06878 DBusError error;
06879
06880 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
06881
06882 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
06883 "/org/freedesktop/TestPath",
06884 "Foo.TestInterface",
06885 "TestMethod");
06886 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06887 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
06888 "TestMethod"));
06889 _dbus_assert (strcmp (dbus_message_get_path (message),
06890 "/org/freedesktop/TestPath") == 0);
06891 _dbus_message_set_serial (message, 1234);
06892
06893 if (!dbus_message_set_sender (message, "org.foo.bar1"))
06894 _dbus_assert_not_reached ("out of memory");
06895 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
06896 dbus_message_set_reply_serial (message, 5678);
06897 if (!dbus_message_set_sender (message, NULL))
06898 _dbus_assert_not_reached ("out of memory");
06899 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
06900 _dbus_assert (dbus_message_get_serial (message) == 1234);
06901 _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
06902 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06903
06904 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06905 dbus_message_set_no_reply (message, TRUE);
06906 _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
06907 dbus_message_set_no_reply (message, FALSE);
06908 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06909
06910
06911
06912 if (!dbus_message_set_path (message, "/foo"))
06913 _dbus_assert_not_reached ("out of memory");
06914 _dbus_assert (strcmp (dbus_message_get_path (message),
06915 "/foo") == 0);
06916
06917 if (!dbus_message_set_interface (message, "org.Foo"))
06918 _dbus_assert_not_reached ("out of memory");
06919 _dbus_assert (strcmp (dbus_message_get_interface (message),
06920 "org.Foo") == 0);
06921
06922 if (!dbus_message_set_member (message, "Bar"))
06923 _dbus_assert_not_reached ("out of memory");
06924 _dbus_assert (strcmp (dbus_message_get_member (message),
06925 "Bar") == 0);
06926
06927
06928 if (!dbus_message_set_path (message, "/foo/bar"))
06929 _dbus_assert_not_reached ("out of memory");
06930 _dbus_assert (strcmp (dbus_message_get_path (message),
06931 "/foo/bar") == 0);
06932
06933 if (!dbus_message_set_interface (message, "org.Foo.Bar"))
06934 _dbus_assert_not_reached ("out of memory");
06935 _dbus_assert (strcmp (dbus_message_get_interface (message),
06936 "org.Foo.Bar") == 0);
06937
06938 if (!dbus_message_set_member (message, "BarFoo"))
06939 _dbus_assert_not_reached ("out of memory");
06940 _dbus_assert (strcmp (dbus_message_get_member (message),
06941 "BarFoo") == 0);
06942
06943
06944
06945 if (!dbus_message_set_path (message, "/foo"))
06946 _dbus_assert_not_reached ("out of memory");
06947 _dbus_assert (strcmp (dbus_message_get_path (message),
06948 "/foo") == 0);
06949
06950 if (!dbus_message_set_interface (message, "org.Foo"))
06951 _dbus_assert_not_reached ("out of memory");
06952 _dbus_assert (strcmp (dbus_message_get_interface (message),
06953 "org.Foo") == 0);
06954
06955 if (!dbus_message_set_member (message, "Bar"))
06956 _dbus_assert_not_reached ("out of memory");
06957 _dbus_assert (strcmp (dbus_message_get_member (message),
06958 "Bar") == 0);
06959
06960 dbus_message_unref (message);
06961
06962
06963 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
06964 "/org/freedesktop/TestPath",
06965 "Foo.TestInterface",
06966 "TestMethod");
06967 _dbus_message_set_serial (message, 1);
06968 dbus_message_append_args (message,
06969 DBUS_TYPE_INT32, -0x12345678,
06970 #ifdef DBUS_HAVE_INT64
06971 DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd),
06972 DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd),
06973 #endif
06974 DBUS_TYPE_STRING, "Test string",
06975 DBUS_TYPE_DOUBLE, 3.14159,
06976 DBUS_TYPE_BOOLEAN, TRUE,
06977 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
06978 _DBUS_N_ELEMENTS (our_uint32_array),
06979 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
06980 _DBUS_N_ELEMENTS (our_int32_array),
06981 #ifdef DBUS_HAVE_INT64
06982 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
06983 _DBUS_N_ELEMENTS (our_uint64_array),
06984 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
06985 _DBUS_N_ELEMENTS (our_int64_array),
06986 #endif
06987 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
06988 _DBUS_N_ELEMENTS (our_string_array),
06989 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
06990 _DBUS_N_ELEMENTS (our_double_array),
06991 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
06992 _DBUS_N_ELEMENTS (our_byte_array),
06993 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
06994 _DBUS_N_ELEMENTS (our_boolean_array),
06995 0);
06996
06997 dbus_message_append_iter_init (message, &iter);
06998 dbus_message_iter_append_dict (&iter, &child_iter);
06999 dbus_message_iter_append_dict_key (&child_iter, "test");
07000 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07001 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
07002
07003 i = 0;
07004 sig[i++] = DBUS_TYPE_INT32;
07005 #ifdef DBUS_HAVE_INT64
07006 sig[i++] = DBUS_TYPE_INT64;
07007 sig[i++] = DBUS_TYPE_UINT64;
07008 #endif
07009 sig[i++] = DBUS_TYPE_STRING;
07010 sig[i++] = DBUS_TYPE_DOUBLE;
07011 sig[i++] = DBUS_TYPE_BOOLEAN;
07012 sig[i++] = DBUS_TYPE_ARRAY;
07013 sig[i++] = DBUS_TYPE_UINT32;
07014 sig[i++] = DBUS_TYPE_ARRAY;
07015 sig[i++] = DBUS_TYPE_INT32;
07016 #ifdef DBUS_HAVE_INT64
07017 sig[i++] = DBUS_TYPE_ARRAY;
07018 sig[i++] = DBUS_TYPE_UINT64;
07019 sig[i++] = DBUS_TYPE_ARRAY;
07020 sig[i++] = DBUS_TYPE_INT64;
07021 #endif
07022 sig[i++] = DBUS_TYPE_ARRAY;
07023 sig[i++] = DBUS_TYPE_STRING;
07024 sig[i++] = DBUS_TYPE_ARRAY;
07025 sig[i++] = DBUS_TYPE_DOUBLE;
07026 sig[i++] = DBUS_TYPE_ARRAY;
07027 sig[i++] = DBUS_TYPE_BYTE;
07028 sig[i++] = DBUS_TYPE_ARRAY;
07029 sig[i++] = DBUS_TYPE_BOOLEAN;
07030 sig[i++] = DBUS_TYPE_DICT;
07031 sig[i++] = DBUS_TYPE_UINT32;
07032 sig[i++] = DBUS_TYPE_INVALID;
07033
07034 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
07035
07036 _dbus_verbose_bytes_of_string (&message->header, 0,
07037 _dbus_string_get_length (&message->header));
07038 _dbus_verbose_bytes_of_string (&message->body, 0,
07039 _dbus_string_get_length (&message->body));
07040
07041 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
07042 sig, dbus_message_get_signature (message));
07043
07044 s = dbus_message_get_signature (message);
07045
07046 _dbus_assert (dbus_message_has_signature (message, sig));
07047 _dbus_assert (strcmp (s, sig) == 0);
07048
07049 verify_test_message (message);
07050
07051 copy = dbus_message_copy (message);
07052
07053 _dbus_assert (message->client_serial == copy->client_serial);
07054 _dbus_assert (message->reply_serial == copy->reply_serial);
07055 _dbus_assert (message->header_padding == copy->header_padding);
07056
07057 _dbus_assert (_dbus_string_get_length (&message->header) ==
07058 _dbus_string_get_length (©->header));
07059
07060 _dbus_assert (_dbus_string_get_length (&message->body) ==
07061 _dbus_string_get_length (©->body));
07062
07063 _dbus_assert (_dbus_string_get_length (&message->signature) ==
07064 _dbus_string_get_length (©->signature));
07065
07066 verify_test_message (copy);
07067
07068 name1 = dbus_message_get_interface (message);
07069 name2 = dbus_message_get_interface (copy);
07070
07071 _dbus_assert (strcmp (name1, name2) == 0);
07072
07073 name1 = dbus_message_get_member (message);
07074 name2 = dbus_message_get_member (copy);
07075
07076 _dbus_assert (strcmp (name1, name2) == 0);
07077
07078 dbus_message_unref (message);
07079 dbus_message_unref (copy);
07080
07081 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07082 "/org/freedesktop/TestPath",
07083 "Foo.TestInterface",
07084 "TestMethod");
07085
07086 _dbus_message_set_serial (message, 1);
07087 dbus_message_set_reply_serial (message, 0x12345678);
07088
07089 dbus_message_append_iter_init (message, &iter);
07090 dbus_message_iter_append_string (&iter, "Test string");
07091 dbus_message_iter_append_int32 (&iter, -0x12345678);
07092 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
07093 dbus_message_iter_append_double (&iter, 3.14159);
07094
07095 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
07096 dbus_message_iter_append_double (&child_iter, 1.5);
07097 dbus_message_iter_append_double (&child_iter, 2.5);
07098
07099
07100 dbus_message_iter_append_dict (&iter, &child_iter);
07101 dbus_message_iter_append_dict_key (&child_iter, "test");
07102 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07103
07104
07105 dbus_message_iter_append_dict_key (&child_iter, "array");
07106 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
07107 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07108 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
07109 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
07110 _dbus_warn ("next call expected to fail with wrong array type\n");
07111 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
07112 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07113 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
07114 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
07115 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
07116
07117 dbus_message_iter_append_byte (&iter, 0xF0);
07118
07119 dbus_message_iter_append_nil (&iter);
07120
07121 dbus_message_iter_append_custom (&iter, "MyTypeName",
07122 "data", 5);
07123
07124 message_iter_test (message);
07125
07126
07127 _dbus_message_lock (message);
07128 loader = _dbus_message_loader_new ();
07129
07130
07131 _dbus_message_loader_ref (loader);
07132 _dbus_message_loader_unref (loader);
07133
07134
07135 data = _dbus_string_get_const_data (&message->header);
07136 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
07137 {
07138 DBusString *buffer;
07139
07140 _dbus_message_loader_get_buffer (loader, &buffer);
07141 _dbus_string_append_byte (buffer, data[i]);
07142 _dbus_message_loader_return_buffer (loader, buffer, 1);
07143 }
07144
07145
07146 data = _dbus_string_get_const_data (&message->body);
07147 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
07148 {
07149 DBusString *buffer;
07150
07151 _dbus_message_loader_get_buffer (loader, &buffer);
07152 _dbus_string_append_byte (buffer, data[i]);
07153 _dbus_message_loader_return_buffer (loader, buffer, 1);
07154 }
07155
07156 copy = dbus_message_copy (message);
07157 dbus_message_unref (message);
07158
07159
07160 if (!_dbus_message_loader_queue_messages (loader))
07161 _dbus_assert_not_reached ("no memory to queue messages");
07162
07163 if (_dbus_message_loader_get_is_corrupted (loader))
07164 _dbus_assert_not_reached ("message loader corrupted");
07165
07166 message = _dbus_message_loader_pop_message (loader);
07167 if (!message)
07168 _dbus_assert_not_reached ("received a NULL message");
07169
07170 if (dbus_message_get_reply_serial (message) != 0x12345678)
07171 _dbus_assert_not_reached ("reply serial fields differ");
07172
07173 message_iter_test (message);
07174
07175 dbus_message_unref (message);
07176 _dbus_message_loader_unref (loader);
07177
07178 message = dbus_message_new_method_return (copy);
07179 if (message == NULL)
07180 _dbus_assert_not_reached ("out of memory\n");
07181 dbus_message_unref (copy);
07182
07183 if (!dbus_message_append_args (message,
07184 DBUS_TYPE_STRING, "hello",
07185 DBUS_TYPE_INVALID))
07186 _dbus_assert_not_reached ("no memory");
07187
07188 if (!dbus_message_has_signature (message, "s"))
07189 _dbus_assert_not_reached ("method return has wrong signature");
07190
07191 dbus_error_init (&error);
07192 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
07193 &t, DBUS_TYPE_INVALID))
07194
07195 {
07196 _dbus_warn ("Failed to get expected string arg: %s\n", error.message);
07197 exit (1);
07198 }
07199 dbus_free (t);
07200
07201 dbus_message_unref (message);
07202
07203
07204 if (test_data_dir == NULL)
07205 return TRUE;
07206
07207 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
07208 (DBusForeachMessageFileFunc)
07209 dbus_internal_do_not_use_try_message_file,
07210 NULL);
07211 }
07212
07213 #endif