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;
00107 };
00108
00109 enum {
00110 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00111 DBUS_MESSAGE_ITER_TYPE_ARRAY,
00112 DBUS_MESSAGE_ITER_TYPE_DICT
00113 };
00114
00116 typedef struct DBusMessageRealIter DBusMessageRealIter;
00117
00123 struct DBusMessageRealIter
00124 {
00125 DBusMessageRealIter *parent_iter;
00126 DBusMessage *message;
00127 dbus_uint32_t changed_stamp;
00129
00130 int type;
00132 int pos;
00133 int end;
00134 int container_start;
00135 int container_length_pos;
00137 int wrote_dict_key;
00139 int array_type_pos;
00140 int array_type_done;
00141 };
00142
00153 void
00154 _dbus_message_get_network_data (DBusMessage *message,
00155 const DBusString **header,
00156 const DBusString **body)
00157 {
00158 _dbus_assert (message->locked);
00159
00160 *header = &message->header;
00161 *body = &message->body;
00162 }
00163
00164 static void
00165 clear_header_padding (DBusMessage *message)
00166 {
00167 _dbus_string_shorten (&message->header,
00168 message->header_padding);
00169 message->header_padding = 0;
00170 }
00171
00172 #ifdef DBUS_DISABLE_CHECKS
00173 #define is_valid_error_name(x) TRUE
00174 #else
00175 static dbus_bool_t
00176 is_valid_error_name (const char *error_name)
00177 {
00178 DBusString the_error_name;
00179
00180 if (error_name == NULL)
00181 return FALSE;
00182
00183 _dbus_string_init_const (&the_error_name, error_name);
00184 return _dbus_string_validate_error_name (&the_error_name, 0,
00185 _dbus_string_get_length (&the_error_name));
00186 }
00187 #endif
00188
00189 static dbus_bool_t
00190 append_header_padding (DBusMessage *message)
00191 {
00192 int old_len;
00193 old_len = _dbus_string_get_length (&message->header);
00194 if (!_dbus_string_align_length (&message->header, 8))
00195 return FALSE;
00196
00197 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00198
00199 return TRUE;
00200 }
00201
00202 #ifdef DBUS_BUILD_TESTS
00203
00204 static dbus_int32_t
00205 get_int_field (DBusMessage *message,
00206 int field)
00207 {
00208 int offset;
00209
00210 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00211
00212 offset = message->header_fields[field].value_offset;
00213
00214 if (offset < 0)
00215 return -1;
00216
00217 return _dbus_demarshal_int32 (&message->header,
00218 message->byte_order,
00219 offset,
00220 NULL);
00221 }
00222 #endif
00223
00224 static dbus_uint32_t
00225 get_uint_field (DBusMessage *message,
00226 int field)
00227 {
00228 int offset;
00229
00230 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00231
00232 offset = message->header_fields[field].value_offset;
00233
00234 if (offset < 0)
00235 return 0;
00236
00237 return _dbus_demarshal_uint32 (&message->header,
00238 message->byte_order,
00239 offset,
00240 NULL);
00241 }
00242
00243 static const char*
00244 get_string_field (DBusMessage *message,
00245 int field,
00246 int *len)
00247 {
00248 int offset;
00249 const char *data;
00250
00251 offset = message->header_fields[field].value_offset;
00252
00253 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00254
00255 if (offset < 0)
00256 return NULL;
00257
00258
00259
00260
00261
00262
00263 if (len)
00264 *len = _dbus_demarshal_uint32 (&message->header,
00265 message->byte_order,
00266 offset,
00267 NULL);
00268
00269 data = _dbus_string_get_const_data (&message->header);
00270
00271 return data + (offset + 4);
00272 }
00273
00274
00275 static dbus_bool_t
00276 get_path_field_decomposed (DBusMessage *message,
00277 int field,
00278 char ***path)
00279 {
00280 int offset;
00281
00282 offset = message->header_fields[field].value_offset;
00283
00284 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00285
00286 if (offset < 0)
00287 {
00288 *path = NULL;
00289 return TRUE;
00290 }
00291
00292 return _dbus_demarshal_object_path (&message->header,
00293 message->byte_order,
00294 offset,
00295 NULL,
00296 path, NULL);
00297 }
00298
00299 #ifdef DBUS_BUILD_TESTS
00300 static dbus_bool_t
00301 append_int_field (DBusMessage *message,
00302 int field,
00303 int value)
00304 {
00305 _dbus_assert (!message->locked);
00306
00307 clear_header_padding (message);
00308
00309 message->header_fields[field].name_offset =
00310 _dbus_string_get_length (&message->header);
00311
00312 if (!_dbus_string_append_byte (&message->header, field))
00313 goto failed;
00314
00315 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00316 goto failed;
00317
00318 if (!_dbus_string_align_length (&message->header, 4))
00319 goto failed;
00320
00321 message->header_fields[field].value_offset =
00322 _dbus_string_get_length (&message->header);
00323
00324 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00325 value))
00326 goto failed;
00327
00328 if (!append_header_padding (message))
00329 goto failed;
00330
00331 return TRUE;
00332
00333 failed:
00334 _dbus_string_set_length (&message->header,
00335 message->header_fields[field].name_offset);
00336 message->header_fields[field].name_offset = -1;
00337 message->header_fields[field].value_offset = -1;
00338
00339
00340
00341
00342 if (!append_header_padding (message))
00343 _dbus_assert_not_reached ("failed to reappend header padding");
00344 return FALSE;
00345 }
00346 #endif
00347
00348 static dbus_bool_t
00349 append_uint_field (DBusMessage *message,
00350 int field,
00351 int value)
00352 {
00353 _dbus_assert (!message->locked);
00354
00355 clear_header_padding (message);
00356
00357 message->header_fields[field].name_offset =
00358 _dbus_string_get_length (&message->header);
00359
00360 if (!_dbus_string_append_byte (&message->header, field))
00361 goto failed;
00362
00363 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00364 goto failed;
00365
00366 if (!_dbus_string_align_length (&message->header, 4))
00367 goto failed;
00368
00369 message->header_fields[field].value_offset =
00370 _dbus_string_get_length (&message->header);
00371
00372 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00373 value))
00374 goto failed;
00375
00376 if (!append_header_padding (message))
00377 goto failed;
00378
00379 return TRUE;
00380
00381 failed:
00382 _dbus_string_set_length (&message->header,
00383 message->header_fields[field].name_offset);
00384 message->header_fields[field].name_offset = -1;
00385 message->header_fields[field].value_offset = -1;
00386
00387
00388
00389
00390 if (!append_header_padding (message))
00391 _dbus_assert_not_reached ("failed to reappend header padding");
00392 return FALSE;
00393 }
00394
00398 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8)
00399
00400 static dbus_bool_t
00401 append_string_field_len (DBusMessage *message,
00402 int field,
00403 int type,
00404 const char *value,
00405 int value_len)
00406 {
00407 _dbus_assert (!message->locked);
00408
00409 clear_header_padding (message);
00410
00411 message->header_fields[field].name_offset =
00412 _dbus_string_get_length (&message->header);
00413
00414 if (!_dbus_string_append_byte (&message->header, field))
00415 goto failed;
00416
00417 if (!_dbus_string_append_byte (&message->header, type))
00418 goto failed;
00419
00420 if (!_dbus_string_align_length (&message->header, 4))
00421 goto failed;
00422
00423 message->header_fields[field].value_offset =
00424 _dbus_string_get_length (&message->header);
00425
00426 if (!_dbus_marshal_string_len (&message->header, message->byte_order,
00427 value, value_len))
00428 goto failed;
00429
00430 if (!append_header_padding (message))
00431 goto failed;
00432
00433 return TRUE;
00434
00435 failed:
00436 _dbus_string_set_length (&message->header,
00437 message->header_fields[field].name_offset);
00438 message->header_fields[field].name_offset = -1;
00439 message->header_fields[field].value_offset = -1;
00440
00441
00442
00443
00444 if (!append_header_padding (message))
00445 _dbus_assert_not_reached ("failed to reappend header padding");
00446
00447 return FALSE;
00448 }
00449
00450 static dbus_bool_t
00451 append_string_field (DBusMessage *message,
00452 int field,
00453 int type,
00454 const char *value)
00455 {
00456 int value_len;
00457
00458 value_len = strlen (value);
00459
00460 return append_string_field_len (message, field, type, value, value_len);
00461 }
00462
00463 static int
00464 get_type_alignment (int type)
00465 {
00466 int alignment;
00467
00468 switch (type)
00469 {
00470 case DBUS_TYPE_NIL:
00471 case DBUS_TYPE_BYTE:
00472 case DBUS_TYPE_BOOLEAN:
00473 alignment = 0;
00474 break;
00475
00476 case DBUS_TYPE_INT32:
00477 case DBUS_TYPE_UINT32:
00478 case DBUS_TYPE_STRING:
00479 case DBUS_TYPE_OBJECT_PATH:
00480
00481
00482
00483 case DBUS_TYPE_CUSTOM:
00484 case DBUS_TYPE_DICT:
00485 alignment = 4;
00486 break;
00487
00488 case DBUS_TYPE_INT64:
00489 case DBUS_TYPE_UINT64:
00490 case DBUS_TYPE_DOUBLE:
00491 alignment = 8;
00492 break;
00493
00494 case DBUS_TYPE_ARRAY:
00495 _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
00496 break;
00497
00498 case DBUS_TYPE_INVALID:
00499 default:
00500 _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
00501 break;
00502 }
00503
00504 return alignment;
00505 }
00506
00507 static dbus_bool_t
00508 iterate_one_field (const DBusString *str,
00509 int byte_order,
00510 int name_offset,
00511 int *next_offset_p,
00512 int *field_name_p,
00513 DBusString *append_copy_to,
00514 int *copy_name_offset_p,
00515 int *copy_value_offset_p)
00516 {
00517 int name, type, array_type;
00518 int alignment;
00519 int type_len;
00520 int type_pos;
00521 int value_pos;
00522 int value_len;
00523 int value_end;
00524 int pos;
00525
00526 _dbus_verbose ("%s: name_offset=%d, append to %p\n",
00527 _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
00528
00529 pos = name_offset;
00530
00531 name = _dbus_string_get_byte (str, name_offset);
00532 pos++;
00533
00534 type_pos = pos;
00535 type = _dbus_string_get_byte (str, type_pos);
00536 pos++;
00537 type_len = 1;
00538
00539 array_type = type;
00540
00541 while (array_type == DBUS_TYPE_ARRAY)
00542 {
00543 pos++;
00544 type_len++;
00545 array_type = _dbus_string_get_byte (str, pos);
00546 }
00547
00548 _dbus_verbose ("%s: name %d, type '%c' %d at %d len %d, array type '%c' %d\n",
00549 _DBUS_FUNCTION_NAME,
00550 name, type, type, type_pos, type_len, array_type, array_type);
00551
00552 #ifndef DBUS_DISABLE_ASSERT
00553 if (!_dbus_type_is_valid (array_type))
00554 {
00555 _dbus_warn ("type '%c' %d is not valid in %s\n",
00556 array_type, array_type, _DBUS_FUNCTION_NAME);
00557 _dbus_assert_not_reached ("invalid type");
00558 }
00559 #endif
00560
00561 alignment = get_type_alignment (array_type);
00562
00563 if (alignment > 0)
00564 pos = _DBUS_ALIGN_VALUE (pos, alignment);
00565
00566 _dbus_verbose ("%s: alignment %d value at pos %d\n",
00567 _DBUS_FUNCTION_NAME, alignment, pos);
00568
00569
00570 if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
00571 type, pos, &value_end))
00572 _dbus_assert_not_reached ("failed to get the byte after this header");
00573
00574 value_pos = pos;
00575 value_len = value_end - value_pos;
00576
00577 _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
00578 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
00579
00580 if (next_offset_p)
00581 *next_offset_p = pos + value_len;
00582
00583 if (field_name_p)
00584 *field_name_p = name;
00585
00586 if (append_copy_to)
00587 {
00588 int orig_len;
00589
00590 orig_len = _dbus_string_get_length (append_copy_to);
00591
00592 if (copy_name_offset_p)
00593 *copy_name_offset_p = orig_len;
00594
00595 if (!_dbus_string_append_byte (append_copy_to, name))
00596 goto failed_copy;
00597
00598 if (!_dbus_string_copy_len (str, type_pos, type_len,
00599 append_copy_to,
00600 _dbus_string_get_length (append_copy_to)))
00601 goto failed_copy;
00602
00603 if (!_dbus_string_align_length (append_copy_to, alignment))
00604 goto failed_copy;
00605
00606 if (copy_value_offset_p)
00607 *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
00608
00609 if (!_dbus_string_copy_len (str, value_pos, value_len,
00610 append_copy_to,
00611 _dbus_string_get_length (append_copy_to)))
00612 goto failed_copy;
00613
00614 return TRUE;
00615
00616 failed_copy:
00617 _dbus_verbose ("%s: Failed copying old fields to new string\n",
00618 _DBUS_FUNCTION_NAME);
00619 _dbus_string_set_length (append_copy_to, orig_len);
00620 return FALSE;
00621 }
00622 else
00623 return TRUE;
00624 }
00625
00626 #ifndef DBUS_DISABLE_ASSERT
00627 static void
00628 verify_header_fields (DBusMessage *message)
00629 {
00630 int i;
00631 i = 0;
00632 while (i < DBUS_HEADER_FIELD_LAST)
00633 {
00634 if (message->header_fields[i].name_offset >= 0)
00635 _dbus_assert (_dbus_string_get_byte (&message->header,
00636 message->header_fields[i].name_offset) ==
00637 i);
00638 ++i;
00639 }
00640 }
00641 #else
00642 #define verify_header_fields(x)
00643 #endif
00644
00645
00646
00647
00648 static dbus_bool_t
00649 delete_one_and_re_align (DBusMessage *message,
00650 int name_offset_to_delete)
00651 {
00652 DBusString copy;
00653 int new_fields_front_padding;
00654 int next_offset;
00655 int field_name;
00656 dbus_bool_t retval;
00657 HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST];
00658
00659 _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
00660 verify_header_fields (message);
00661
00662 _dbus_verbose ("%s: Deleting one field at offset %d\n",
00663 _DBUS_FUNCTION_NAME,
00664 name_offset_to_delete);
00665
00666 retval = FALSE;
00667
00668 clear_header_padding (message);
00669
00670 if (!_dbus_string_init_preallocated (©,
00671 _dbus_string_get_length (&message->header) -
00672 name_offset_to_delete + 8))
00673 {
00674 _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
00675 _DBUS_FUNCTION_NAME);
00676 goto out_0;
00677 }
00678
00679
00680
00681
00682 new_fields_front_padding = name_offset_to_delete % 8;
00683
00684 if (!_dbus_string_insert_bytes (©, 0, new_fields_front_padding,
00685 '\0'))
00686 _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
00687
00688 memcpy (new_header_fields, message->header_fields,
00689 sizeof (new_header_fields));
00690
00691
00692
00693
00694
00695
00696
00697 if (!iterate_one_field (&message->header,
00698 message->byte_order,
00699 name_offset_to_delete,
00700 &next_offset,
00701 &field_name, NULL, NULL, NULL))
00702 _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
00703
00704 if (field_name < DBUS_HEADER_FIELD_LAST)
00705 {
00706 new_header_fields[field_name].name_offset = -1;
00707 new_header_fields[field_name].value_offset = -1;
00708 }
00709
00710 while (next_offset < _dbus_string_get_length (&message->header))
00711 {
00712 int copy_name_offset;
00713 int copy_value_offset;
00714
00715 if (!iterate_one_field (&message->header,
00716 message->byte_order,
00717 next_offset,
00718 &next_offset,
00719 &field_name,
00720 ©,
00721 ©_name_offset,
00722 ©_value_offset))
00723 {
00724 _dbus_verbose ("%s: OOM iterating one field\n",
00725 _DBUS_FUNCTION_NAME);
00726 goto out_1;
00727 }
00728
00729 if (field_name < DBUS_HEADER_FIELD_LAST)
00730 {
00731 new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
00732 new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
00733 }
00734 }
00735
00736 if (!_dbus_string_replace_len (©,
00737 new_fields_front_padding,
00738 _dbus_string_get_length (©) - new_fields_front_padding,
00739 &message->header,
00740 name_offset_to_delete,
00741 _dbus_string_get_length (&message->header) - name_offset_to_delete))
00742 {
00743 _dbus_verbose ("%s: OOM moving copy back into header\n",
00744 _DBUS_FUNCTION_NAME);
00745 goto out_1;
00746 }
00747
00748 memcpy (message->header_fields, new_header_fields,
00749 sizeof (new_header_fields));
00750 verify_header_fields (message);
00751
00752 retval = TRUE;
00753
00754 out_1:
00755 _dbus_string_free (©);
00756
00757 out_0:
00758 if (!append_header_padding (message))
00759 _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
00760
00761 return retval;
00762 }
00763
00764 static dbus_bool_t
00765 delete_field (DBusMessage *message,
00766 int field,
00767 int prealloc_header_space)
00768 {
00769 int offset;
00770
00771 _dbus_assert (!message->locked);
00772
00773
00774 if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
00775 {
00776 _dbus_verbose ("failed to prealloc %d bytes header space\n",
00777 prealloc_header_space);
00778 return FALSE;
00779 }
00780 _dbus_string_shorten (&message->header, prealloc_header_space);
00781
00782
00783 offset = message->header_fields[field].name_offset;
00784 if (offset < 0)
00785 {
00786 _dbus_verbose ("header field didn't exist, no need to delete\n");
00787 return TRUE;
00788 }
00789
00790 return delete_one_and_re_align (message, offset);
00791 }
00792
00793 #ifdef DBUS_BUILD_TESTS
00794 static dbus_bool_t
00795 set_int_field (DBusMessage *message,
00796 int field,
00797 int value)
00798 {
00799 int offset = message->header_fields[field].value_offset;
00800
00801 _dbus_assert (!message->locked);
00802
00803 if (offset < 0)
00804 {
00805
00806 return append_int_field (message, field, value);
00807 }
00808 else
00809 {
00810 _dbus_marshal_set_int32 (&message->header,
00811 message->byte_order,
00812 offset, value);
00813
00814 return TRUE;
00815 }
00816 }
00817 #endif
00818
00819 static dbus_bool_t
00820 set_uint_field (DBusMessage *message,
00821 int field,
00822 dbus_uint32_t value)
00823 {
00824 int offset = message->header_fields[field].value_offset;
00825
00826 _dbus_assert (!message->locked);
00827
00828 if (offset < 0)
00829 {
00830
00831 return append_uint_field (message, field, value);
00832 }
00833 else
00834 {
00835 _dbus_marshal_set_uint32 (&message->header,
00836 message->byte_order,
00837 offset, value);
00838
00839 return TRUE;
00840 }
00841 }
00842
00843 static dbus_bool_t
00844 set_string_field (DBusMessage *message,
00845 int field,
00846 int type,
00847 const char *value)
00848 {
00849 int prealloc;
00850 int value_len;
00851
00852 _dbus_assert (!message->locked);
00853
00854 value_len = value ? strlen (value) : 0;
00855
00856
00857
00858
00859 prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
00860
00861 _dbus_verbose ("set_string_field() field %d prealloc %d\n",
00862 field, prealloc);
00863
00864 if (!delete_field (message, field, prealloc))
00865 return FALSE;
00866
00867 if (value != NULL)
00868 {
00869
00870 if (!append_string_field_len (message, field, type, value, value_len))
00871 _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
00872 }
00873
00874 return TRUE;
00875 }
00876
00884 void
00885 _dbus_message_set_serial (DBusMessage *message,
00886 dbus_int32_t serial)
00887 {
00888 _dbus_assert (!message->locked);
00889 _dbus_assert (dbus_message_get_serial (message) == 0);
00890
00891 _dbus_marshal_set_uint32 (&message->header,
00892 message->byte_order,
00893 CLIENT_SERIAL_OFFSET,
00894 serial);
00895
00896 message->client_serial = serial;
00897 }
00898
00907 dbus_bool_t
00908 dbus_message_set_reply_serial (DBusMessage *message,
00909 dbus_uint32_t reply_serial)
00910 {
00911 _dbus_assert (!message->locked);
00912
00913 if (set_uint_field (message,
00914 DBUS_HEADER_FIELD_REPLY_SERIAL,
00915 reply_serial))
00916 {
00917 message->reply_serial = reply_serial;
00918 return TRUE;
00919 }
00920 else
00921 return FALSE;
00922 }
00923
00934 dbus_uint32_t
00935 dbus_message_get_serial (DBusMessage *message)
00936 {
00937 return message->client_serial;
00938 }
00939
00946 dbus_uint32_t
00947 dbus_message_get_reply_serial (DBusMessage *message)
00948 {
00949 return message->reply_serial;
00950 }
00951
00964 void
00965 _dbus_message_add_size_counter_link (DBusMessage *message,
00966 DBusList *link)
00967 {
00968
00969
00970
00971
00972
00973
00974 if (message->size_counters == NULL)
00975 {
00976 message->size_counter_delta =
00977 _dbus_string_get_length (&message->header) +
00978 _dbus_string_get_length (&message->body);
00979
00980 #if 0
00981 _dbus_verbose ("message has size %ld\n",
00982 message->size_counter_delta);
00983 #endif
00984 }
00985
00986 _dbus_list_append_link (&message->size_counters, link);
00987
00988 _dbus_counter_adjust (link->data, message->size_counter_delta);
00989 }
00990
01000 dbus_bool_t
01001 _dbus_message_add_size_counter (DBusMessage *message,
01002 DBusCounter *counter)
01003 {
01004 DBusList *link;
01005
01006 link = _dbus_list_alloc_link (counter);
01007 if (link == NULL)
01008 return FALSE;
01009
01010 _dbus_counter_ref (counter);
01011 _dbus_message_add_size_counter_link (message, link);
01012
01013 return TRUE;
01014 }
01015
01024 void
01025 _dbus_message_remove_size_counter (DBusMessage *message,
01026 DBusCounter *counter,
01027 DBusList **link_return)
01028 {
01029 DBusList *link;
01030
01031 link = _dbus_list_find_last (&message->size_counters,
01032 counter);
01033 _dbus_assert (link != NULL);
01034
01035 _dbus_list_unlink (&message->size_counters,
01036 link);
01037 if (link_return)
01038 *link_return = link;
01039 else
01040 _dbus_list_free_link (link);
01041
01042 _dbus_counter_adjust (counter, message->size_counter_delta);
01043
01044 _dbus_counter_unref (counter);
01045 }
01046
01047 static dbus_bool_t
01048 dbus_message_create_header (DBusMessage *message,
01049 int type,
01050 const char *service,
01051 const char *path,
01052 const char *interface,
01053 const char *member,
01054 const char *error_name)
01055 {
01056 unsigned int flags;
01057
01058 _dbus_assert ((interface && member) ||
01059 (error_name) ||
01060 !(interface || member || error_name));
01061 _dbus_assert (error_name == NULL || is_valid_error_name (error_name));
01062
01063 if (!_dbus_string_append_byte (&message->header, message->byte_order))
01064 return FALSE;
01065
01066 if (!_dbus_string_append_byte (&message->header, type))
01067 return FALSE;
01068
01069 flags = 0;
01070 if (!_dbus_string_append_byte (&message->header, flags))
01071 return FALSE;
01072
01073 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
01074 return FALSE;
01075
01076
01077 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01078 return FALSE;
01079
01080
01081 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01082 return FALSE;
01083
01084
01085 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01086 return FALSE;
01087
01088
01089
01090 if (path != NULL)
01091 {
01092 if (!append_string_field (message,
01093 DBUS_HEADER_FIELD_PATH,
01094 DBUS_TYPE_OBJECT_PATH,
01095 path))
01096 return FALSE;
01097 }
01098
01099 if (service != NULL)
01100 {
01101 if (!append_string_field (message,
01102 DBUS_HEADER_FIELD_DESTINATION,
01103 DBUS_TYPE_STRING,
01104 service))
01105 return FALSE;
01106 }
01107
01108 if (interface != NULL)
01109 {
01110 if (!append_string_field (message,
01111 DBUS_HEADER_FIELD_INTERFACE,
01112 DBUS_TYPE_STRING,
01113 interface))
01114 return FALSE;
01115 }
01116
01117 if (member != NULL)
01118 {
01119 if (!append_string_field (message,
01120 DBUS_HEADER_FIELD_MEMBER,
01121 DBUS_TYPE_STRING,
01122 member))
01123 return FALSE;
01124 }
01125
01126 if (error_name != NULL)
01127 {
01128 if (!append_string_field (message,
01129 DBUS_HEADER_FIELD_ERROR_NAME,
01130 DBUS_TYPE_STRING,
01131 error_name))
01132 return FALSE;
01133 }
01134
01135
01136
01137
01138 if (!append_string_field (message,
01139 DBUS_HEADER_FIELD_SIGNATURE,
01140 DBUS_TYPE_STRING,
01141 ""))
01142 return FALSE;
01143
01144 return TRUE;
01145 }
01146
01156 void
01157 _dbus_message_lock (DBusMessage *message)
01158 {
01159 if (!message->locked)
01160 {
01161
01162 _dbus_marshal_set_uint32 (&message->header,
01163 message->byte_order,
01164 HEADER_LENGTH_OFFSET,
01165 _dbus_string_get_length (&message->header));
01166
01167 _dbus_marshal_set_uint32 (&message->header,
01168 message->byte_order,
01169 BODY_LENGTH_OFFSET,
01170 _dbus_string_get_length (&message->body));
01171
01172 message->locked = TRUE;
01173 }
01174 }
01175
01207 static dbus_bool_t
01208 dbus_message_set_signature (DBusMessage *message,
01209 const char *signature)
01210 {
01211 _dbus_return_val_if_fail (message != NULL, FALSE);
01212 _dbus_return_val_if_fail (!message->locked, FALSE);
01213
01214 return set_string_field (message,
01215 DBUS_HEADER_FIELD_SIGNATURE,
01216 DBUS_TYPE_STRING,
01217 signature);
01218 }
01219
01228 static dbus_bool_t
01229 dbus_message_append_to_signature (DBusMessage *message,
01230 const char *append_bytes)
01231 {
01232 const char *signature;
01233 DBusString append_str;
01234 dbus_bool_t retval;
01235
01236 _dbus_return_val_if_fail (append_bytes != NULL, FALSE);
01237 _dbus_return_val_if_fail (message != NULL, FALSE);
01238 _dbus_return_val_if_fail (!message->locked, FALSE);
01239
01240 retval = FALSE;
01241
01242
01243
01244
01245 signature = dbus_message_get_signature (message);
01246
01247 if (!_dbus_string_init (&append_str))
01248 return FALSE;
01249
01250 if (signature && !_dbus_string_append (&append_str, signature))
01251 goto out;
01252
01253 if (!_dbus_string_append (&append_str, append_bytes))
01254 goto out;
01255
01256 if (!set_string_field (message,
01257 DBUS_HEADER_FIELD_SIGNATURE,
01258 DBUS_TYPE_STRING,
01259 _dbus_string_get_const_data (&append_str)))
01260 goto out;
01261
01262 retval = TRUE;
01263
01264 out:
01265
01266 _dbus_string_free (&append_str);
01267
01268 return retval;
01269 }
01270
01279 static dbus_bool_t
01280 _dbus_message_append_byte_to_signature (DBusMessage *message,
01281 unsigned char append_byte)
01282 {
01283 char buf[2];
01284
01285 _dbus_return_val_if_fail (message != NULL, FALSE);
01286 _dbus_return_val_if_fail (!message->locked, FALSE);
01287
01288 buf[0] = append_byte;
01289 buf[1] = '\0';
01290
01291 return dbus_message_append_to_signature (message, buf);
01292 }
01293
01300 static void
01301 _dbus_message_remove_byte_from_signature (DBusMessage *message)
01302 {
01303 const char *signature;
01304
01305 _dbus_return_if_fail (message != NULL);
01306 _dbus_return_if_fail (!message->locked);
01307
01308 signature = dbus_message_get_signature (message);
01309
01310 _dbus_return_if_fail (signature != NULL);
01311
01312 if (!delete_field (message,
01313 DBUS_HEADER_FIELD_SIGNATURE,
01314 0))
01315 _dbus_assert_not_reached ("failed to delete signature field");
01316
01317
01318
01319
01320 if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE,
01321 DBUS_TYPE_STRING, signature,
01322 strlen (signature) - 1))
01323 _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed");
01324 }
01325
01333 static DBusMessage*
01334 dbus_message_new_empty_header (void)
01335 {
01336 DBusMessage *message;
01337 int i;
01338
01339 message = dbus_new0 (DBusMessage, 1);
01340 if (message == NULL)
01341 return NULL;
01342
01343 message->refcount.value = 1;
01344 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01345 message->client_serial = 0;
01346 message->reply_serial = 0;
01347
01348 _dbus_data_slot_list_init (&message->slot_list);
01349
01350 i = 0;
01351 while (i <= DBUS_HEADER_FIELD_LAST)
01352 {
01353 message->header_fields[i].name_offset = -1;
01354 message->header_fields[i].value_offset = -1;
01355 ++i;
01356 }
01357
01358 if (!_dbus_string_init_preallocated (&message->header, 64))
01359 {
01360 dbus_free (message);
01361 return NULL;
01362 }
01363
01364 if (!_dbus_string_init_preallocated (&message->body, 64))
01365 {
01366 _dbus_string_free (&message->header);
01367 dbus_free (message);
01368 return NULL;
01369 }
01370
01371 return message;
01372 }
01373
01382 DBusMessage*
01383 dbus_message_new (int message_type)
01384 {
01385 DBusMessage *message;
01386
01387 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01388
01389 message = dbus_message_new_empty_header ();
01390 if (message == NULL)
01391 return NULL;
01392
01393 if (!dbus_message_create_header (message,
01394 message_type,
01395 NULL, NULL, NULL, NULL, NULL))
01396 {
01397 dbus_message_unref (message);
01398 return NULL;
01399 }
01400
01401 return message;
01402 }
01403
01421 DBusMessage*
01422 dbus_message_new_method_call (const char *service,
01423 const char *path,
01424 const char *interface,
01425 const char *method)
01426 {
01427 DBusMessage *message;
01428
01429 _dbus_return_val_if_fail (path != NULL, NULL);
01430 _dbus_return_val_if_fail (method != NULL, NULL);
01431
01432 message = dbus_message_new_empty_header ();
01433 if (message == NULL)
01434 return NULL;
01435
01436 if (!dbus_message_create_header (message,
01437 DBUS_MESSAGE_TYPE_METHOD_CALL,
01438 service, path, interface, method, NULL))
01439 {
01440 dbus_message_unref (message);
01441 return NULL;
01442 }
01443
01444 return message;
01445 }
01446
01456 DBusMessage*
01457 dbus_message_new_method_return (DBusMessage *method_call)
01458 {
01459 DBusMessage *message;
01460 const char *sender;
01461
01462 _dbus_return_val_if_fail (method_call != NULL, NULL);
01463
01464 sender = get_string_field (method_call,
01465 DBUS_HEADER_FIELD_SENDER,
01466 NULL);
01467
01468
01469
01470 message = dbus_message_new_empty_header ();
01471 if (message == NULL)
01472 return NULL;
01473
01474 if (!dbus_message_create_header (message,
01475 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01476 sender, NULL, NULL, NULL, NULL))
01477 {
01478 dbus_message_unref (message);
01479 return NULL;
01480 }
01481
01482 dbus_message_set_no_reply (message, TRUE);
01483
01484 if (!dbus_message_set_reply_serial (message,
01485 dbus_message_get_serial (method_call)))
01486 {
01487 dbus_message_unref (message);
01488 return NULL;
01489 }
01490
01491 return message;
01492 }
01493
01506 DBusMessage*
01507 dbus_message_new_signal (const char *path,
01508 const char *interface,
01509 const char *name)
01510 {
01511 DBusMessage *message;
01512
01513 _dbus_return_val_if_fail (path != NULL, NULL);
01514 _dbus_return_val_if_fail (interface != NULL, NULL);
01515 _dbus_return_val_if_fail (name != NULL, NULL);
01516
01517 message = dbus_message_new_empty_header ();
01518 if (message == NULL)
01519 return NULL;
01520
01521 if (!dbus_message_create_header (message,
01522 DBUS_MESSAGE_TYPE_SIGNAL,
01523 NULL, path, interface, name, NULL))
01524 {
01525 dbus_message_unref (message);
01526 return NULL;
01527 }
01528
01529 dbus_message_set_no_reply (message, TRUE);
01530
01531 return message;
01532 }
01533
01543 DBusMessage*
01544 dbus_message_new_error (DBusMessage *reply_to,
01545 const char *error_name,
01546 const char *error_message)
01547 {
01548 DBusMessage *message;
01549 const char *sender;
01550 DBusMessageIter iter;
01551
01552 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01553 _dbus_return_val_if_fail (error_name != NULL, NULL);
01554 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01555
01556 sender = get_string_field (reply_to,
01557 DBUS_HEADER_FIELD_SENDER,
01558 NULL);
01559
01560
01561
01562
01563
01564 message = dbus_message_new_empty_header ();
01565 if (message == NULL)
01566 return NULL;
01567
01568 if (!dbus_message_create_header (message,
01569 DBUS_MESSAGE_TYPE_ERROR,
01570 sender, NULL, NULL, NULL, error_name))
01571 {
01572 dbus_message_unref (message);
01573 return NULL;
01574 }
01575
01576 dbus_message_set_no_reply (message, TRUE);
01577
01578 if (!dbus_message_set_reply_serial (message,
01579 dbus_message_get_serial (reply_to)))
01580 {
01581 dbus_message_unref (message);
01582 return NULL;
01583 }
01584
01585 if (error_message != NULL)
01586 {
01587 dbus_message_append_iter_init (message, &iter);
01588 if (!dbus_message_iter_append_string (&iter, error_message))
01589 {
01590 dbus_message_unref (message);
01591 return NULL;
01592 }
01593 }
01594
01595 return message;
01596 }
01597
01608 DBusMessage*
01609 dbus_message_new_error_printf (DBusMessage *reply_to,
01610 const char *error_name,
01611 const char *error_format,
01612 ...)
01613 {
01614 va_list args;
01615 DBusString str;
01616 DBusMessage *message;
01617
01618 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01619 _dbus_return_val_if_fail (error_name != NULL, NULL);
01620 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01621
01622 if (!_dbus_string_init (&str))
01623 return NULL;
01624
01625 va_start (args, error_format);
01626
01627 if (_dbus_string_append_printf_valist (&str, error_format, args))
01628 message = dbus_message_new_error (reply_to, error_name,
01629 _dbus_string_get_const_data (&str));
01630 else
01631 message = NULL;
01632
01633 _dbus_string_free (&str);
01634
01635 va_end (args);
01636
01637 return message;
01638 }
01639
01640
01648 DBusMessage *
01649 dbus_message_copy (const DBusMessage *message)
01650 {
01651 DBusMessage *retval;
01652 int i;
01653
01654 _dbus_return_val_if_fail (message != NULL, NULL);
01655
01656 retval = dbus_new0 (DBusMessage, 1);
01657 if (retval == NULL)
01658 return NULL;
01659
01660 retval->refcount.value = 1;
01661 retval->byte_order = message->byte_order;
01662 retval->client_serial = message->client_serial;
01663 retval->reply_serial = message->reply_serial;
01664 retval->header_padding = message->header_padding;
01665 retval->locked = FALSE;
01666
01667 if (!_dbus_string_init_preallocated (&retval->header,
01668 _dbus_string_get_length (&message->header)))
01669 {
01670 dbus_free (retval);
01671 return NULL;
01672 }
01673
01674 if (!_dbus_string_init_preallocated (&retval->body,
01675 _dbus_string_get_length (&message->body)))
01676 {
01677 _dbus_string_free (&retval->header);
01678 dbus_free (retval);
01679 return NULL;
01680 }
01681
01682 if (!_dbus_string_copy (&message->header, 0,
01683 &retval->header, 0))
01684 goto failed_copy;
01685
01686 if (!_dbus_string_copy (&message->body, 0,
01687 &retval->body, 0))
01688 goto failed_copy;
01689
01690 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
01691 {
01692 retval->header_fields[i] = message->header_fields[i];
01693 }
01694
01695 return retval;
01696
01697 failed_copy:
01698 _dbus_string_free (&retval->header);
01699 _dbus_string_free (&retval->body);
01700 dbus_free (retval);
01701
01702 return NULL;
01703 }
01704
01705
01713 DBusMessage *
01714 dbus_message_ref (DBusMessage *message)
01715 {
01716 dbus_int32_t old_refcount;
01717
01718 _dbus_return_val_if_fail (message != NULL, NULL);
01719
01720 old_refcount = _dbus_atomic_inc (&message->refcount);
01721 _dbus_assert (old_refcount >= 1);
01722
01723 return message;
01724 }
01725
01726 static void
01727 free_size_counter (void *element,
01728 void *data)
01729 {
01730 DBusCounter *counter = element;
01731 DBusMessage *message = data;
01732
01733 _dbus_counter_adjust (counter, - message->size_counter_delta);
01734
01735 _dbus_counter_unref (counter);
01736 }
01737
01744 void
01745 dbus_message_unref (DBusMessage *message)
01746 {
01747 dbus_int32_t old_refcount;
01748
01749 _dbus_return_if_fail (message != NULL);
01750
01751 old_refcount = _dbus_atomic_dec (&message->refcount);
01752
01753 _dbus_assert (old_refcount >= 0);
01754
01755 if (old_refcount == 1)
01756 {
01757
01758 _dbus_data_slot_list_free (&message->slot_list);
01759
01760 _dbus_list_foreach (&message->size_counters,
01761 free_size_counter, message);
01762 _dbus_list_clear (&message->size_counters);
01763
01764 _dbus_string_free (&message->header);
01765 _dbus_string_free (&message->body);
01766
01767 dbus_free (message);
01768 }
01769 }
01770
01782 int
01783 dbus_message_get_type (DBusMessage *message)
01784 {
01785 int type;
01786
01787 type = _dbus_string_get_byte (&message->header, 1);
01788 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
01789
01790 return type;
01791 }
01792
01802 dbus_bool_t
01803 dbus_message_set_path (DBusMessage *message,
01804 const char *object_path)
01805 {
01806 _dbus_return_val_if_fail (message != NULL, FALSE);
01807 _dbus_return_val_if_fail (!message->locked, FALSE);
01808
01809 return set_string_field (message,
01810 DBUS_HEADER_FIELD_PATH,
01811 DBUS_TYPE_OBJECT_PATH,
01812 object_path);
01813 }
01814
01823 const char*
01824 dbus_message_get_path (DBusMessage *message)
01825 {
01826 _dbus_return_val_if_fail (message != NULL, NULL);
01827
01828 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
01829 }
01830
01846 dbus_bool_t
01847 dbus_message_get_path_decomposed (DBusMessage *message,
01848 char ***path)
01849 {
01850 _dbus_return_val_if_fail (message != NULL, FALSE);
01851 _dbus_return_val_if_fail (path != NULL, FALSE);
01852
01853 return get_path_field_decomposed (message,
01854 DBUS_HEADER_FIELD_PATH,
01855 path);
01856 }
01857
01868 dbus_bool_t
01869 dbus_message_set_interface (DBusMessage *message,
01870 const char *interface)
01871 {
01872 _dbus_return_val_if_fail (message != NULL, FALSE);
01873 _dbus_return_val_if_fail (!message->locked, FALSE);
01874
01875 return set_string_field (message,
01876 DBUS_HEADER_FIELD_INTERFACE,
01877 DBUS_TYPE_STRING,
01878 interface);
01879 }
01880
01890 const char*
01891 dbus_message_get_interface (DBusMessage *message)
01892 {
01893 _dbus_return_val_if_fail (message != NULL, NULL);
01894
01895 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
01896 }
01897
01908 dbus_bool_t
01909 dbus_message_set_member (DBusMessage *message,
01910 const char *member)
01911 {
01912 _dbus_return_val_if_fail (message != NULL, FALSE);
01913 _dbus_return_val_if_fail (!message->locked, FALSE);
01914
01915 return set_string_field (message,
01916 DBUS_HEADER_FIELD_MEMBER,
01917 DBUS_TYPE_STRING,
01918 member);
01919 }
01920
01929 const char*
01930 dbus_message_get_member (DBusMessage *message)
01931 {
01932 _dbus_return_val_if_fail (message != NULL, NULL);
01933
01934 return get_string_field (message,
01935 DBUS_HEADER_FIELD_MEMBER,
01936 NULL);
01937 }
01938
01947 dbus_bool_t
01948 dbus_message_set_error_name (DBusMessage *message,
01949 const char *error_name)
01950 {
01951 _dbus_return_val_if_fail (message != NULL, FALSE);
01952 _dbus_return_val_if_fail (!message->locked, FALSE);
01953 _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE);
01954
01955 return set_string_field (message,
01956 DBUS_HEADER_FIELD_ERROR_NAME,
01957 DBUS_TYPE_STRING,
01958 error_name);
01959 }
01960
01967 const char*
01968 dbus_message_get_error_name (DBusMessage *message)
01969 {
01970 _dbus_return_val_if_fail (message != NULL, NULL);
01971
01972 return get_string_field (message,
01973 DBUS_HEADER_FIELD_ERROR_NAME,
01974 NULL);
01975 }
01976
01984 dbus_bool_t
01985 dbus_message_set_destination (DBusMessage *message,
01986 const char *destination)
01987 {
01988 _dbus_return_val_if_fail (message != NULL, FALSE);
01989 _dbus_return_val_if_fail (!message->locked, FALSE);
01990
01991 return set_string_field (message,
01992 DBUS_HEADER_FIELD_DESTINATION,
01993 DBUS_TYPE_STRING,
01994 destination);
01995 }
01996
02003 const char*
02004 dbus_message_get_destination (DBusMessage *message)
02005 {
02006 _dbus_return_val_if_fail (message != NULL, NULL);
02007
02008 return get_string_field (message,
02009 DBUS_HEADER_FIELD_DESTINATION,
02010 NULL);
02011 }
02012
02031 dbus_bool_t
02032 dbus_message_append_args (DBusMessage *message,
02033 int first_arg_type,
02034 ...)
02035 {
02036 dbus_bool_t retval;
02037 va_list var_args;
02038
02039 _dbus_return_val_if_fail (message != NULL, FALSE);
02040
02041 va_start (var_args, first_arg_type);
02042 retval = dbus_message_append_args_valist (message,
02043 first_arg_type,
02044 var_args);
02045 va_end (var_args);
02046
02047 return retval;
02048 }
02049
02062 dbus_bool_t
02063 dbus_message_get_args (DBusMessage *message,
02064 DBusError *error,
02065 int first_arg_type,
02066 ...)
02067 {
02068 dbus_bool_t retval;
02069 va_list var_args;
02070
02071 _dbus_return_val_if_fail (message != NULL, FALSE);
02072 _dbus_return_val_if_error_is_set (error, FALSE);
02073
02074 va_start (var_args, first_arg_type);
02075 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02076 va_end (var_args);
02077
02078 return retval;
02079 }
02080
02093 dbus_bool_t
02094 dbus_message_get_args_valist (DBusMessage *message,
02095 DBusError *error,
02096 int first_arg_type,
02097 va_list var_args)
02098 {
02099 DBusMessageIter iter;
02100
02101 _dbus_return_val_if_fail (message != NULL, FALSE);
02102 _dbus_return_val_if_error_is_set (error, FALSE);
02103
02104 dbus_message_iter_init (message, &iter);
02105 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02106 }
02107
02120 dbus_bool_t
02121 dbus_message_iter_get_args (DBusMessageIter *iter,
02122 DBusError *error,
02123 int first_arg_type,
02124 ...)
02125 {
02126 dbus_bool_t retval;
02127 va_list var_args;
02128
02129 _dbus_return_val_if_fail (iter != NULL, FALSE);
02130 _dbus_return_val_if_error_is_set (error, FALSE);
02131
02132 va_start (var_args, first_arg_type);
02133 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
02134 va_end (var_args);
02135
02136 return retval;
02137 }
02138
02147 dbus_bool_t
02148 dbus_message_iter_init (DBusMessage *message,
02149 DBusMessageIter *iter)
02150 {
02151 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02152
02153 _dbus_return_val_if_fail (message != NULL, FALSE);
02154 _dbus_return_val_if_fail (iter != NULL, FALSE);
02155
02156 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02157
02158 real->message = message;
02159 real->parent_iter = NULL;
02160 real->changed_stamp = message->changed_stamp;
02161
02162 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02163 real->pos = 0;
02164 real->end = _dbus_string_get_length (&message->body);
02165
02166 real->container_start = 0;
02167 real->container_length_pos = 0;
02168 real->wrote_dict_key = 0;
02169 real->array_type_pos = 0;
02170
02171 return real->end > real->pos;
02172 }
02173
02174 #ifndef DBUS_DISABLE_CHECKS
02175 static dbus_bool_t
02176 dbus_message_iter_check (DBusMessageRealIter *iter)
02177 {
02178 if (iter == NULL)
02179 {
02180 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
02181 return FALSE;
02182 }
02183
02184 if (iter->changed_stamp != iter->message->changed_stamp)
02185 {
02186 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
02187 return FALSE;
02188 }
02189
02190 if (iter->pos < 0 || iter->pos > iter->end)
02191 {
02192 _dbus_warn ("dbus iterator check failed: invalid position\n");
02193 return FALSE;
02194 }
02195
02196 return TRUE;
02197 }
02198 #endif
02199
02200 static int
02201 skip_array_type (DBusMessageRealIter *iter, int pos)
02202 {
02203 const char *data;
02204
02205 do
02206 {
02207 data = _dbus_string_get_const_data_len (&iter->message->body,
02208 pos++, 1);
02209 }
02210 while (*data == DBUS_TYPE_ARRAY);
02211
02212 return pos;
02213 }
02214
02215
02216
02217
02218 static int
02219 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
02220 {
02221 const char *data;
02222 int pos, len;
02223
02224 switch (iter->type)
02225 {
02226 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02227 data = _dbus_string_get_const_data_len (&iter->message->body,
02228 iter->pos, 1);
02229 if (_dbus_type_is_valid (*data))
02230 *type = *data;
02231 else
02232 *type = DBUS_TYPE_INVALID;
02233
02234 return skip_array_type (iter, iter->pos);
02235
02236 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02237 data = _dbus_string_get_const_data_len (&iter->message->body,
02238 iter->array_type_pos, 1);
02239 if (_dbus_type_is_valid (*data))
02240 *type = *data;
02241 else
02242 *type = DBUS_TYPE_INVALID;
02243
02244 return iter->pos;
02245
02246 case DBUS_MESSAGE_ITER_TYPE_DICT:
02247
02248 len = _dbus_demarshal_uint32 (&iter->message->body,
02249 iter->message->byte_order,
02250 iter->pos, &pos);
02251 pos = pos + len + 1;
02252
02253 data = _dbus_string_get_const_data_len (&iter->message->body,
02254 pos, 1);
02255 if (_dbus_type_is_valid (*data))
02256 *type = *data;
02257 else
02258 *type = DBUS_TYPE_INVALID;
02259
02260 return skip_array_type (iter, pos);
02261
02262 default:
02263 _dbus_assert_not_reached ("Invalid iter type");
02264 break;
02265 }
02266 *type = DBUS_TYPE_INVALID;
02267 return iter->pos;
02268 }
02269
02270
02278 dbus_bool_t
02279 dbus_message_iter_has_next (DBusMessageIter *iter)
02280 {
02281 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02282 int end_pos;
02283 int type, pos;
02284
02285 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02286
02287 if (real->pos >= real->end)
02288 return FALSE;
02289
02290 pos = dbus_message_iter_get_data_start (real, &type);
02291
02292 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02293 real->message->byte_order,
02294 type, pos, &end_pos))
02295 return FALSE;
02296
02297 if (end_pos >= real->end)
02298 return FALSE;
02299
02300 return TRUE;
02301 }
02302
02309 dbus_bool_t
02310 dbus_message_iter_next (DBusMessageIter *iter)
02311 {
02312 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02313 int end_pos;
02314 int type, pos;
02315
02316 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02317
02318 pos = dbus_message_iter_get_data_start (real, &type);
02319
02320 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02321 real->message->byte_order,
02322 type, pos, &end_pos))
02323 return FALSE;
02324
02325 if (end_pos >= real->end)
02326 return FALSE;
02327
02328 real->pos = end_pos;
02329
02330 return TRUE;
02331 }
02332
02340 int
02341 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02342 {
02343 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02344 int type, pos;
02345
02346 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02347
02348 if (real->pos >= real->end)
02349 {
02350 _dbus_verbose (" iterator at or beyond end of message\n");
02351 return DBUS_TYPE_INVALID;
02352 }
02353
02354 pos = dbus_message_iter_get_data_start (real, &type);
02355
02356 return type;
02357 }
02358
02359
02360
02361
02362 static int
02363 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02364 {
02365 const char *data;
02366 int _array_type_pos;
02367 int len, pos;
02368
02369 switch (iter->type)
02370 {
02371 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02372 _array_type_pos = iter->pos + 1;
02373 break;
02374 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02375 _array_type_pos = iter->array_type_pos + 1;
02376 break;
02377 case DBUS_MESSAGE_ITER_TYPE_DICT:
02378
02379 len = _dbus_demarshal_uint32 (&iter->message->body,
02380 iter->message->byte_order,
02381 iter->pos, &pos);
02382 pos = pos + len + 1;
02383 data = _dbus_string_get_const_data_len (&iter->message->body,
02384 pos + 1, 1);
02385 _array_type_pos = pos + 1;
02386 break;
02387 default:
02388 _dbus_assert_not_reached ("wrong iter type");
02389 return DBUS_TYPE_INVALID;
02390 }
02391
02392 if (array_type_pos != NULL)
02393 *array_type_pos = _array_type_pos;
02394
02395 data = _dbus_string_get_const_data_len (&iter->message->body,
02396 _array_type_pos, 1);
02397 if (_dbus_type_is_valid (*data))
02398 return *data;
02399
02400 return DBUS_TYPE_INVALID;
02401 }
02402
02403
02413 int
02414 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02415 {
02416 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02417 int type, pos;
02418
02419 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02420
02421 if (real->pos >= real->end)
02422 return DBUS_TYPE_INVALID;
02423
02424 pos = dbus_message_iter_get_data_start (real, &type);
02425
02426 _dbus_assert (type == DBUS_TYPE_ARRAY);
02427
02428 return iter_get_array_type (real, NULL);
02429 }
02430
02431
02441 char *
02442 dbus_message_iter_get_string (DBusMessageIter *iter)
02443 {
02444 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02445 int type, pos;
02446
02447 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02448 pos = dbus_message_iter_get_data_start (real, &type);
02449
02450 _dbus_assert (type == DBUS_TYPE_STRING);
02451
02452 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02453 pos, NULL);
02454 }
02455
02465 char *
02466 dbus_message_iter_get_object_path (DBusMessageIter *iter)
02467 {
02468 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02469 int type, pos;
02470
02471 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02472
02473 pos = dbus_message_iter_get_data_start (real, &type);
02474
02475 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
02476
02477 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02478 pos, NULL);
02479 }
02480
02494 dbus_bool_t
02495 dbus_message_iter_get_custom (DBusMessageIter *iter,
02496 char **name,
02497 unsigned char **value,
02498 int *len)
02499 {
02500 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02501 int type, pos;
02502 char *_name;
02503
02504 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02505
02506 pos = dbus_message_iter_get_data_start (real, &type);
02507
02508 _dbus_assert (type == DBUS_TYPE_CUSTOM);
02509
02510 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02511 pos, &pos);
02512
02513 if (_name == NULL)
02514 return FALSE;
02515
02516 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02517 pos, NULL, value, len))
02518 {
02519 dbus_free (_name);
02520 return FALSE;
02521 }
02522
02523 *name = _name;
02524
02525 return TRUE;
02526 }
02527
02528 static void
02529 _dbus_message_iter_get_basic_type (DBusMessageIter *iter,
02530 char type,
02531 void *value)
02532 {
02533 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02534 int item_type, pos;
02535
02536 _dbus_return_if_fail (dbus_message_iter_check (real));
02537
02538 pos = dbus_message_iter_get_data_start (real, &item_type);
02539
02540 _dbus_assert (type == item_type);
02541
02542 _dbus_demarshal_basic_type (&real->message->body,
02543 type, value,
02544 real->message->byte_order,
02545 &pos);
02546 }
02547
02548
02571 dbus_bool_t
02572 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
02573 DBusError *error,
02574 int first_arg_type,
02575 va_list var_args)
02576 {
02577 int spec_type, msg_type, i;
02578 dbus_bool_t retval;
02579
02580 _dbus_return_val_if_fail (iter != NULL, FALSE);
02581 _dbus_return_val_if_error_is_set (error, FALSE);
02582
02583 retval = FALSE;
02584
02585 spec_type = first_arg_type;
02586 i = 0;
02587
02588 while (spec_type != DBUS_TYPE_INVALID)
02589 {
02590 msg_type = dbus_message_iter_get_arg_type (iter);
02591
02592 if (msg_type != spec_type)
02593 {
02594 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02595 "Argument %d is specified to be of type \"%s\", but "
02596 "is actually of type \"%s\"\n", i,
02597 _dbus_type_to_string (spec_type),
02598 _dbus_type_to_string (msg_type));
02599
02600 goto out;
02601 }
02602
02603 switch (spec_type)
02604 {
02605 case DBUS_TYPE_NIL:
02606 break;
02607 case DBUS_TYPE_BOOLEAN:
02608 {
02609 dbus_bool_t *ptr;
02610
02611 ptr = va_arg (var_args, dbus_bool_t *);
02612
02613 *ptr = dbus_message_iter_get_boolean (iter);
02614 break;
02615 }
02616 case DBUS_TYPE_BYTE:
02617 case DBUS_TYPE_INT32:
02618 case DBUS_TYPE_UINT32:
02619 #ifdef DBUS_HAVE_INT64
02620 case DBUS_TYPE_INT64:
02621 case DBUS_TYPE_UINT64:
02622 #endif
02623 case DBUS_TYPE_DOUBLE:
02624 {
02625 void *ptr = va_arg (var_args, void *);
02626 _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
02627 break;
02628 }
02629
02630 case DBUS_TYPE_STRING:
02631 {
02632 char **ptr;
02633
02634 ptr = va_arg (var_args, char **);
02635
02636 *ptr = dbus_message_iter_get_string (iter);
02637
02638 if (!*ptr)
02639 {
02640 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02641 goto out;
02642 }
02643
02644 break;
02645 }
02646
02647 case DBUS_TYPE_OBJECT_PATH:
02648 {
02649 char **ptr;
02650
02651 ptr = va_arg (var_args, char **);
02652
02653 *ptr = dbus_message_iter_get_object_path (iter);
02654
02655 if (!*ptr)
02656 {
02657 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02658 goto out;
02659 }
02660
02661 break;
02662 }
02663
02664 case DBUS_TYPE_CUSTOM:
02665 {
02666 char **name;
02667 unsigned char **data;
02668 int *len;
02669
02670 name = va_arg (var_args, char **);
02671 data = va_arg (var_args, unsigned char **);
02672 len = va_arg (var_args, int *);
02673
02674 if (!dbus_message_iter_get_custom (iter, name, data, len))
02675 {
02676 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02677 goto out;
02678 }
02679 }
02680 break;
02681 case DBUS_TYPE_ARRAY:
02682 {
02683 void **data;
02684 int *len, type;
02685 dbus_bool_t err = FALSE;
02686
02687 type = va_arg (var_args, int);
02688 data = va_arg (var_args, void *);
02689 len = va_arg (var_args, int *);
02690
02691 _dbus_return_val_if_fail (data != NULL, FALSE);
02692 _dbus_return_val_if_fail (len != NULL, FALSE);
02693
02694 if (dbus_message_iter_get_array_type (iter) != type)
02695 {
02696 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02697 "Argument %d is specified to be of type \"array of %s\", but "
02698 "is actually of type \"array of %s\"\n", i,
02699 _dbus_type_to_string (type),
02700 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
02701 goto out;
02702 }
02703
02704 switch (type)
02705 {
02706 case DBUS_TYPE_BYTE:
02707 err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
02708 break;
02709 case DBUS_TYPE_BOOLEAN:
02710 err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
02711 break;
02712 case DBUS_TYPE_INT32:
02713 err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
02714 break;
02715 case DBUS_TYPE_UINT32:
02716 err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
02717 break;
02718 #ifdef DBUS_HAVE_INT64
02719 case DBUS_TYPE_INT64:
02720 err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
02721 break;
02722 case DBUS_TYPE_UINT64:
02723 err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
02724 break;
02725 #endif
02726 case DBUS_TYPE_DOUBLE:
02727 err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
02728 break;
02729 case DBUS_TYPE_STRING:
02730 err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
02731 break;
02732 case DBUS_TYPE_OBJECT_PATH:
02733 err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
02734 break;
02735
02736 case DBUS_TYPE_NIL:
02737 case DBUS_TYPE_ARRAY:
02738 case DBUS_TYPE_CUSTOM:
02739 case DBUS_TYPE_DICT:
02740 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
02741 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02742 goto out;
02743 default:
02744 _dbus_warn ("Unknown field type %d\n", type);
02745 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02746 goto out;
02747 }
02748 if (err)
02749 {
02750 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02751 goto out;
02752 }
02753 }
02754 break;
02755 case DBUS_TYPE_DICT:
02756 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
02757 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02758 goto out;
02759 default:
02760 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
02761 _dbus_warn ("Unknown field type %d\n", spec_type);
02762 goto out;
02763 }
02764
02765 spec_type = va_arg (var_args, int);
02766 if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
02767 {
02768 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02769 "Message has only %d arguments, but more were expected", i);
02770 goto out;
02771 }
02772
02773 i++;
02774 }
02775
02776 retval = TRUE;
02777
02778 out:
02779
02780 return retval;
02781 }
02782
02792 unsigned char
02793 dbus_message_iter_get_byte (DBusMessageIter *iter)
02794 {
02795 unsigned char value = 0;
02796
02797 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value);
02798
02799 return value;
02800 }
02801
02811 dbus_bool_t
02812 dbus_message_iter_get_boolean (DBusMessageIter *iter)
02813 {
02814 unsigned char value = 0;
02815
02816 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value);
02817
02818 return (value != FALSE);
02819 }
02820
02830 dbus_int32_t
02831 dbus_message_iter_get_int32 (DBusMessageIter *iter)
02832 {
02833 dbus_int32_t value = 0;
02834
02835 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value);
02836
02837 return value;
02838 }
02839
02849 dbus_uint32_t
02850 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
02851 {
02852 dbus_int32_t value = 0;
02853
02854 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value);
02855
02856 return value;
02857 }
02858
02859 #ifdef DBUS_HAVE_INT64
02860
02872 dbus_int64_t
02873 dbus_message_iter_get_int64 (DBusMessageIter *iter)
02874 {
02875 dbus_int64_t value = 0;
02876
02877 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value);
02878
02879 return value;
02880 }
02881
02893 dbus_uint64_t
02894 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
02895 {
02896 dbus_uint64_t value = 0;
02897
02898 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value);
02899
02900 return value;
02901 }
02902
02903 #endif
02904
02914 double
02915 dbus_message_iter_get_double (DBusMessageIter *iter)
02916 {
02917 double value = 0.0;
02918
02919 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value);
02920
02921 return value;
02922 }
02923
02937 dbus_bool_t
02938 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
02939 DBusMessageIter *array_iter,
02940 int *array_type)
02941 {
02942 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02943 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
02944 int type, pos, len_pos, len, array_type_pos;
02945 int _array_type;
02946
02947 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02948
02949 pos = dbus_message_iter_get_data_start (real, &type);
02950
02951 _dbus_assert (type == DBUS_TYPE_ARRAY);
02952
02953 _array_type = iter_get_array_type (real, &array_type_pos);
02954
02955 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
02956 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02957 pos, &pos);
02958
02959 array_real->parent_iter = real;
02960 array_real->message = real->message;
02961 array_real->changed_stamp = real->message->changed_stamp;
02962
02963 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
02964 array_real->pos = pos;
02965 array_real->end = pos + len;
02966
02967 array_real->container_start = pos;
02968 array_real->container_length_pos = len_pos;
02969 array_real->wrote_dict_key = 0;
02970 array_real->array_type_pos = array_type_pos;
02971 array_real->array_type_done = TRUE;
02972
02973 if (array_type != NULL)
02974 *array_type = _array_type;
02975
02976 return len > 0;
02977 }
02978
02979
02989 dbus_bool_t
02990 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
02991 DBusMessageIter *dict_iter)
02992 {
02993 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02994 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
02995 int type, pos, len_pos, len;
02996
02997 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02998
02999 pos = dbus_message_iter_get_data_start (real, &type);
03000
03001 _dbus_assert (type == DBUS_TYPE_DICT);
03002
03003 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03004 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03005 pos, &pos);
03006
03007 dict_real->parent_iter = real;
03008 dict_real->message = real->message;
03009 dict_real->changed_stamp = real->message->changed_stamp;
03010
03011 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03012 dict_real->pos = pos;
03013 dict_real->end = pos + len;
03014
03015 dict_real->container_start = pos;
03016 dict_real->container_length_pos = len_pos;
03017 dict_real->wrote_dict_key = 0;
03018
03019 return len > 0;
03020 }
03021
03022 static dbus_bool_t
03023 _dbus_message_iter_get_basic_type_array (DBusMessageIter *iter,
03024 char type,
03025 void **array,
03026 int *array_len)
03027 {
03028 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03029 int item_type, pos;
03030
03031 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03032
03033 pos = dbus_message_iter_get_data_start (real, &item_type);
03034
03035 _dbus_assert (item_type == DBUS_TYPE_ARRAY);
03036
03037 item_type = iter_get_array_type (real, NULL);
03038
03039 _dbus_assert (type == item_type);
03040
03041 return _dbus_demarshal_basic_type_array (&real->message->body,
03042 item_type, array, array_len,
03043 real->message->byte_order, &pos);
03044 }
03045
03056 dbus_bool_t
03057 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
03058 unsigned char **value,
03059 int *len)
03060 {
03061 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE,
03062 (void **) value, len);
03063 }
03064
03075 dbus_bool_t
03076 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
03077 unsigned char **value,
03078 int *len)
03079 {
03080 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN,
03081 (void **) value, len);
03082 }
03083
03094 dbus_bool_t
03095 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
03096 dbus_int32_t **value,
03097 int *len)
03098 {
03099 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03100 (void **) value, len);
03101 }
03102
03113 dbus_bool_t
03114 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
03115 dbus_uint32_t **value,
03116 int *len)
03117 {
03118 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03119 (void **) value, len);
03120 }
03121
03122 #ifdef DBUS_HAVE_INT64
03123
03136 dbus_bool_t
03137 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
03138 dbus_int64_t **value,
03139 int *len)
03140 {
03141 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03142 (void **) value, len);
03143 }
03144
03157 dbus_bool_t
03158 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
03159 dbus_uint64_t **value,
03160 int *len)
03161 {
03162 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03163 (void **) value, len);
03164 }
03165
03166 #endif
03167
03178 dbus_bool_t
03179 dbus_message_iter_get_double_array (DBusMessageIter *iter,
03180 double **value,
03181 int *len)
03182 {
03183 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03184 (void **) value, len);
03185 }
03186
03202 dbus_bool_t
03203 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03204 char ***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 _dbus_assert (type == DBUS_TYPE_STRING);
03218
03219 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03220 pos, NULL, value, len))
03221 return FALSE;
03222 else
03223 return TRUE;
03224 }
03225
03241 dbus_bool_t
03242 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03243 char ***value,
03244 int *len)
03245 {
03246 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03247 int type, pos;
03248
03249 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03250
03251 pos = dbus_message_iter_get_data_start (real, &type);
03252
03253 _dbus_assert (type == DBUS_TYPE_ARRAY);
03254
03255 type = iter_get_array_type (real, NULL);
03256 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03257
03258 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03259 pos, NULL, value, len))
03260 return FALSE;
03261 else
03262 return TRUE;
03263 }
03264
03274 char *
03275 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
03276 {
03277 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03278
03279 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03280
03281 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03282
03283 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03284 real->pos, NULL);
03285 }
03286
03295 void
03296 dbus_message_append_iter_init (DBusMessage *message,
03297 DBusMessageIter *iter)
03298 {
03299 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03300
03301 _dbus_return_if_fail (message != NULL);
03302 _dbus_return_if_fail (iter != NULL);
03303
03304 real->message = message;
03305 real->parent_iter = NULL;
03306 real->changed_stamp = message->changed_stamp;
03307
03308 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03309 real->end = _dbus_string_get_length (&real->message->body);
03310 real->pos = real->end;
03311
03312 real->container_length_pos = 0;
03313 real->wrote_dict_key = 0;
03314 }
03315
03316 #ifndef DBUS_DISABLE_CHECKS
03317 static dbus_bool_t
03318 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03319 {
03320 if (iter == NULL)
03321 {
03322 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03323 return FALSE;
03324 }
03325
03326 if (iter->message->locked)
03327 {
03328 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03329 return FALSE;
03330 }
03331
03332 if (iter->changed_stamp != iter->message->changed_stamp)
03333 {
03334 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03335 return FALSE;
03336 }
03337
03338 if (iter->pos != iter->end)
03339 {
03340 _dbus_warn ("dbus iterator check failed: can only append at end of message");
03341 return FALSE;
03342 }
03343
03344 if (iter->pos != _dbus_string_get_length (&iter->message->body))
03345 {
03346 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03347 return FALSE;
03348 }
03349
03350 return TRUE;
03351 }
03352 #endif
03353
03354 static dbus_bool_t
03355 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03356 int type)
03357 {
03358 const char *data;
03359
03360 switch (iter->type)
03361 {
03362 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03363 if (!_dbus_string_append_byte (&iter->message->body, type))
03364 return FALSE;
03365
03366 if (!_dbus_message_append_byte_to_signature (iter->message, type))
03367 {
03368 _dbus_string_shorten (&iter->message->body, 1);
03369 return FALSE;
03370 }
03371 break;
03372
03373 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03374 data = _dbus_string_get_const_data_len (&iter->message->body,
03375 iter->array_type_pos, 1);
03376 if (type != *data)
03377 {
03378 _dbus_warn ("Appended element of wrong type for array\n");
03379 return FALSE;
03380 }
03381 break;
03382
03383 case DBUS_MESSAGE_ITER_TYPE_DICT:
03384 if (!iter->wrote_dict_key)
03385 {
03386 _dbus_warn ("Appending dict data before key name\n");
03387 return FALSE;
03388 }
03389
03390 if (!_dbus_string_append_byte (&iter->message->body, type))
03391 return FALSE;
03392
03393 break;
03394
03395 default:
03396 _dbus_assert_not_reached ("Invalid iter type");
03397 break;
03398 }
03399
03400 return TRUE;
03401 }
03402
03403 static void
03404 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
03405 {
03406 iter->changed_stamp = iter->message->changed_stamp;
03407
03408
03409 iter->end = _dbus_string_get_length (&iter->message->body);
03410 iter->pos = iter->end;
03411
03412
03413 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
03414 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
03415 _dbus_marshal_set_uint32 (&iter->message->body,
03416 iter->message->byte_order,
03417 iter->container_length_pos,
03418 iter->end - iter->container_start);
03419
03420 if (iter->parent_iter)
03421 dbus_message_iter_update_after_change (iter->parent_iter);
03422 }
03423
03424 static void
03425 dbus_message_iter_append_done (DBusMessageRealIter *iter)
03426 {
03427 iter->message->changed_stamp++;
03428 dbus_message_iter_update_after_change (iter);
03429 iter->wrote_dict_key = FALSE;
03430 }
03431
03438 dbus_bool_t
03439 dbus_message_iter_append_nil (DBusMessageIter *iter)
03440 {
03441 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03442
03443 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03444
03445 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
03446 return FALSE;
03447
03448 dbus_message_iter_append_done (real);
03449
03450 return TRUE;
03451 }
03452
03453 static dbus_bool_t
03454 dbus_message_iter_append_basic (DBusMessageIter *iter,
03455 char type,
03456 void *value)
03457 {
03458 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03459
03460 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03461
03462 if (!dbus_message_iter_append_type (real, type))
03463 return FALSE;
03464
03465 if (!_dbus_marshal_basic_type (&real->message->body,
03466 type, value,
03467 real->message->byte_order))
03468 {
03469 _dbus_string_set_length (&real->message->body, real->pos);
03470 return FALSE;
03471 }
03472
03473 dbus_message_iter_append_done (real);
03474
03475 return TRUE;
03476 }
03477
03485 dbus_bool_t
03486 dbus_message_iter_append_boolean (DBusMessageIter *iter,
03487 dbus_bool_t value)
03488 {
03489 unsigned char val = (value != FALSE);
03490 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val);
03491 }
03492
03500 dbus_bool_t
03501 dbus_message_iter_append_byte (DBusMessageIter *iter,
03502 unsigned char value)
03503 {
03504 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value);
03505 }
03506
03514 dbus_bool_t
03515 dbus_message_iter_append_int32 (DBusMessageIter *iter,
03516 dbus_int32_t value)
03517 {
03518 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value);
03519 }
03520
03528 dbus_bool_t
03529 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
03530 dbus_uint32_t value)
03531 {
03532 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value);
03533 }
03534
03535 #ifdef DBUS_HAVE_INT64
03536
03546 dbus_bool_t
03547 dbus_message_iter_append_int64 (DBusMessageIter *iter,
03548 dbus_int64_t value)
03549 {
03550 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
03551 }
03552
03562 dbus_bool_t
03563 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
03564 dbus_uint64_t value)
03565 {
03566 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value);
03567 }
03568
03569 #endif
03570
03578 dbus_bool_t
03579 dbus_message_iter_append_double (DBusMessageIter *iter,
03580 double value)
03581 {
03582 return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value);
03583 }
03584
03594 dbus_bool_t
03595 dbus_message_iter_append_string (DBusMessageIter *iter,
03596 const char *value)
03597 {
03598 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03599
03600 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03601
03602 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
03603 return FALSE;
03604
03605 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03606 {
03607 _dbus_string_set_length (&real->message->body, real->pos);
03608 return FALSE;
03609 }
03610
03611 dbus_message_iter_append_done (real);
03612
03613 return TRUE;
03614 }
03615
03625 dbus_bool_t
03626 dbus_message_iter_append_object_path (DBusMessageIter *iter,
03627 const char *value)
03628 {
03629 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03630
03631 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03632
03633 if (!dbus_message_iter_append_type (real, DBUS_TYPE_OBJECT_PATH))
03634 return FALSE;
03635
03636 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03637 {
03638 _dbus_string_set_length (&real->message->body, real->pos);
03639 return FALSE;
03640 }
03641
03642 dbus_message_iter_append_done (real);
03643
03644 return TRUE;
03645 }
03646
03659 dbus_bool_t
03660 dbus_message_iter_append_custom (DBusMessageIter *iter,
03661 const char *name,
03662 const unsigned char *data,
03663 int len)
03664 {
03665 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03666
03667 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03668
03669 if (!dbus_message_iter_append_type (real, DBUS_TYPE_CUSTOM))
03670 return FALSE;
03671
03672 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
03673 {
03674 _dbus_string_set_length (&real->message->body, real->pos);
03675 return FALSE;
03676 }
03677
03678 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
03679 {
03680 _dbus_string_set_length (&real->message->body, real->pos);
03681 return FALSE;
03682 }
03683
03684 dbus_message_iter_append_done (real);
03685
03686 return TRUE;
03687 }
03688
03689
03698 dbus_bool_t
03699 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
03700 const char *value)
03701 {
03702 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03703
03704 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03705 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03706
03707 if (real->wrote_dict_key)
03708 {
03709 _dbus_warn ("Appending multiple dict key names\n");
03710 return FALSE;
03711 }
03712
03713 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03714 {
03715 return FALSE;
03716 }
03717
03718 dbus_message_iter_append_done (real);
03719 real->wrote_dict_key = TRUE;
03720
03721 return TRUE;
03722 }
03723
03724 static dbus_bool_t
03725 array_iter_type_mark_done (DBusMessageRealIter *iter)
03726 {
03727 int len_pos;
03728
03729 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
03730 array_iter_type_mark_done (iter->parent_iter);
03731 else
03732 return TRUE;
03733
03734 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
03735 sizeof (dbus_uint32_t));
03736
03737
03738 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
03739 {
03740 _dbus_string_set_length (&iter->message->body, iter->pos);
03741 return FALSE;
03742 }
03743
03744 iter->container_start = _dbus_string_get_length (&iter->message->body);
03745 iter->container_length_pos = len_pos;
03746 iter->array_type_done = TRUE;
03747
03748 return TRUE;
03749 }
03750
03751 static dbus_bool_t
03752 append_array_type (DBusMessageRealIter *real,
03753 int element_type,
03754 dbus_bool_t *array_type_done,
03755 int *array_type_pos)
03756 {
03757 int existing_element_type;
03758
03759 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
03760 return FALSE;
03761
03762 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
03763 real->array_type_done)
03764 {
03765 existing_element_type = iter_get_array_type (real, array_type_pos);
03766 if (existing_element_type != element_type)
03767 {
03768 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
03769 _dbus_type_to_string (element_type),
03770 _dbus_type_to_string (existing_element_type));
03771 _dbus_string_set_length (&real->message->body, real->pos);
03772 return FALSE;
03773 }
03774 if (array_type_done != NULL)
03775 *array_type_done = TRUE;
03776 }
03777 else
03778 {
03779 if (array_type_pos != NULL)
03780 *array_type_pos = _dbus_string_get_length (&real->message->body);
03781
03782
03783 if (!_dbus_message_append_byte_to_signature (real->message, element_type))
03784 {
03785 _dbus_string_set_length (&real->message->body, real->pos);
03786 return FALSE;
03787 }
03788
03789
03790 if (!_dbus_string_append_byte (&real->message->body, element_type))
03791 {
03792 _dbus_message_remove_byte_from_signature (real->message);
03793 _dbus_string_set_length (&real->message->body, real->pos);
03794 return FALSE;
03795 }
03796
03797 if (array_type_done != NULL)
03798 *array_type_done = element_type != DBUS_TYPE_ARRAY;
03799
03800 if (element_type != DBUS_TYPE_ARRAY &&
03801 !array_iter_type_mark_done (real))
03802 {
03803 _dbus_message_remove_byte_from_signature (real->message);
03804 return FALSE;
03805 }
03806 }
03807
03808 return TRUE;
03809 }
03810
03820 dbus_bool_t
03821 dbus_message_iter_append_array (DBusMessageIter *iter,
03822 DBusMessageIter *array_iter,
03823 int element_type)
03824 {
03825 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03826 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03827 int len_pos;
03828 int array_type_pos;
03829 dbus_bool_t array_type_done;
03830
03831 if (element_type == DBUS_TYPE_NIL)
03832 {
03833 _dbus_warn ("Can't create NIL arrays\n");
03834 return FALSE;
03835 }
03836
03837 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03838
03839 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
03840 return FALSE;
03841
03842 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
03843
03844 if (array_type_done)
03845 {
03846
03847 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
03848 {
03849 _dbus_string_set_length (&real->message->body, real->pos);
03850 return FALSE;
03851 }
03852 }
03853
03854 array_real->parent_iter = real;
03855 array_real->message = real->message;
03856 array_real->changed_stamp = real->message->changed_stamp;
03857
03858 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
03859 array_real->pos = _dbus_string_get_length (&real->message->body);
03860 array_real->end = array_real->end;
03861
03862 array_real->container_start = array_real->pos;
03863 array_real->container_length_pos = len_pos;
03864 array_real->wrote_dict_key = 0;
03865 array_real->array_type_done = array_type_done;
03866 array_real->array_type_pos = array_type_pos;
03867
03868 dbus_message_iter_append_done (array_real);
03869
03870 return TRUE;
03871 }
03872
03881 dbus_bool_t
03882 dbus_message_iter_append_dict (DBusMessageIter *iter,
03883 DBusMessageIter *dict_iter)
03884 {
03885 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03886 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03887 int len_pos;
03888
03889 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03890
03891 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
03892 return FALSE;
03893
03894 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
03895
03896
03897 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
03898 {
03899 _dbus_string_set_length (&real->message->body, real->pos);
03900 return FALSE;
03901 }
03902
03903 dict_real->parent_iter = real;
03904 dict_real->message = real->message;
03905 dict_real->changed_stamp = real->message->changed_stamp;
03906
03907 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03908 dict_real->pos = _dbus_string_get_length (&real->message->body);
03909 dict_real->end = dict_real->end;
03910
03911 dict_real->container_start = dict_real->pos;
03912 dict_real->container_length_pos = len_pos;
03913 dict_real->wrote_dict_key = 0;
03914
03915 dbus_message_iter_append_done (dict_real);
03916
03917 real->wrote_dict_key = FALSE;
03918
03919 return TRUE;
03920 }
03921
03922 static dbus_bool_t
03923 _dbus_message_iter_append_basic_array (DBusMessageIter *iter,
03924 char type,
03925 const void *value,
03926 int len)
03927 {
03928 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03929
03930 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03931
03932 if (!append_array_type (real, type, NULL, NULL))
03933 return FALSE;
03934
03935 if (!_dbus_marshal_basic_type_array (&real->message->body,
03936 type, value, len,
03937 real->message->byte_order))
03938 {
03939 _dbus_string_set_length (&real->message->body, real->pos);
03940 return FALSE;
03941 }
03942
03943 dbus_message_iter_append_done (real);
03944
03945 return TRUE;
03946 }
03947
03948
03962 dbus_bool_t
03963 dbus_message_append_args_valist (DBusMessage *message,
03964 int first_arg_type,
03965 va_list var_args)
03966 {
03967 int type, old_len;
03968 DBusMessageIter iter;
03969
03970 _dbus_return_val_if_fail (message != NULL, FALSE);
03971
03972 old_len = _dbus_string_get_length (&message->body);
03973
03974 type = first_arg_type;
03975
03976 dbus_message_append_iter_init (message, &iter);
03977
03978 while (type != DBUS_TYPE_INVALID)
03979 {
03980 switch (type)
03981 {
03982 case DBUS_TYPE_NIL:
03983 if (!dbus_message_iter_append_nil (&iter))
03984 goto errorout;
03985 break;
03986 case DBUS_TYPE_BYTE:
03987
03988
03989
03990 if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, unsigned char)))
03991 goto errorout;
03992 break;
03993 case DBUS_TYPE_BOOLEAN:
03994 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
03995 goto errorout;
03996 break;
03997 case DBUS_TYPE_INT32:
03998
03999
04000
04001 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
04002 goto errorout;
04003 break;
04004 case DBUS_TYPE_UINT32:
04005
04006
04007
04008 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
04009 goto errorout;
04010 break;
04011 #ifdef DBUS_HAVE_INT64
04012 case DBUS_TYPE_INT64:
04013 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
04014 goto errorout;
04015 break;
04016 case DBUS_TYPE_UINT64:
04017 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
04018 goto errorout;
04019 break;
04020 #endif
04021 case DBUS_TYPE_DOUBLE:
04022 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
04023 goto errorout;
04024 break;
04025 case DBUS_TYPE_STRING:
04026 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
04027 goto errorout;
04028 break;
04029 case DBUS_TYPE_OBJECT_PATH:
04030 if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
04031 goto errorout;
04032 break;
04033 case DBUS_TYPE_CUSTOM:
04034 {
04035 const char *name;
04036 unsigned char *data;
04037 int len;
04038
04039 name = va_arg (var_args, const char *);
04040 data = va_arg (var_args, unsigned char *);
04041 len = va_arg (var_args, int);
04042
04043 if (!dbus_message_iter_append_custom (&iter, name, data, len))
04044 goto errorout;
04045 break;
04046 }
04047 case DBUS_TYPE_ARRAY:
04048 {
04049 void *data;
04050 int len, type;
04051
04052 type = va_arg (var_args, int);
04053 data = va_arg (var_args, void *);
04054 len = va_arg (var_args, int);
04055
04056 switch (type)
04057 {
04058 case DBUS_TYPE_BYTE:
04059 case DBUS_TYPE_BOOLEAN:
04060 case DBUS_TYPE_INT32:
04061 case DBUS_TYPE_UINT32:
04062 #ifdef DBUS_HAVE_INT64
04063 case DBUS_TYPE_INT64:
04064 case DBUS_TYPE_UINT64:
04065 #endif
04066 case DBUS_TYPE_DOUBLE:
04067 if (!_dbus_message_iter_append_basic_array (&iter, type, data, len))
04068 goto errorout;
04069 break;
04070 case DBUS_TYPE_STRING:
04071 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
04072 goto errorout;
04073 break;
04074 case DBUS_TYPE_OBJECT_PATH:
04075 if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
04076 goto errorout;
04077 break;
04078 case DBUS_TYPE_NIL:
04079 case DBUS_TYPE_ARRAY:
04080 case DBUS_TYPE_CUSTOM:
04081 case DBUS_TYPE_DICT:
04082 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
04083 goto errorout;
04084 default:
04085 _dbus_warn ("Unknown field type %d\n", type);
04086 goto errorout;
04087 }
04088 }
04089 break;
04090
04091 case DBUS_TYPE_DICT:
04092 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
04093 goto errorout;
04094 default:
04095 _dbus_warn ("Unknown field type %d\n", type);
04096 goto errorout;
04097 }
04098
04099 type = va_arg (var_args, int);
04100 }
04101
04102 return TRUE;
04103
04104 errorout:
04105 return FALSE;
04106 }
04107
04116 dbus_bool_t
04117 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
04118 unsigned const char *value,
04119 int len)
04120 {
04121 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN,
04122 value, len);
04123 }
04124
04133 dbus_bool_t
04134 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
04135 const dbus_int32_t *value,
04136 int len)
04137 {
04138 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32,
04139 value, len);
04140 }
04141
04150 dbus_bool_t
04151 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
04152 const dbus_uint32_t *value,
04153 int len)
04154 {
04155 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32,
04156 value, len);
04157 }
04158
04159 #ifdef DBUS_HAVE_INT64
04160
04171 dbus_bool_t
04172 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
04173 const dbus_int64_t *value,
04174 int len)
04175 {
04176 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64,
04177 value, len);
04178 }
04179
04190 dbus_bool_t
04191 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
04192 const dbus_uint64_t *value,
04193 int len)
04194 {
04195 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64,
04196 value, len);
04197 }
04198 #endif
04199
04208 dbus_bool_t
04209 dbus_message_iter_append_double_array (DBusMessageIter *iter,
04210 const double *value,
04211 int len)
04212 {
04213 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE,
04214 value, len);
04215 }
04216
04225 dbus_bool_t
04226 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
04227 unsigned const char *value,
04228 int len)
04229 {
04230 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE,
04231 value, len);
04232 }
04233
04242 dbus_bool_t
04243 dbus_message_iter_append_string_array (DBusMessageIter *iter,
04244 const char **value,
04245 int len)
04246 {
04247 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04248
04249 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04250
04251 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
04252 return FALSE;
04253
04254 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04255 {
04256 _dbus_string_set_length (&real->message->body, real->pos);
04257 return FALSE;
04258 }
04259
04260 dbus_message_iter_append_done (real);
04261
04262 return TRUE;
04263 }
04264
04273 dbus_bool_t
04274 dbus_message_iter_append_object_path_array (DBusMessageIter *iter,
04275 const char **value,
04276 int len)
04277 {
04278 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04279
04280 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04281
04282 if (!append_array_type (real, DBUS_TYPE_OBJECT_PATH, NULL, NULL))
04283 return FALSE;
04284
04285 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04286 {
04287 _dbus_string_set_length (&real->message->body, real->pos);
04288 return FALSE;
04289 }
04290
04291 dbus_message_iter_append_done (real);
04292
04293 return TRUE;
04294 }
04295
04303 dbus_bool_t
04304 dbus_message_set_sender (DBusMessage *message,
04305 const char *sender)
04306 {
04307 _dbus_return_val_if_fail (message != NULL, FALSE);
04308 _dbus_return_val_if_fail (!message->locked, FALSE);
04309
04310 return set_string_field (message,
04311 DBUS_HEADER_FIELD_SENDER,
04312 DBUS_TYPE_STRING,
04313 sender);
04314 }
04315
04326 void
04327 dbus_message_set_no_reply (DBusMessage *message,
04328 dbus_bool_t no_reply)
04329 {
04330 char *header;
04331
04332 _dbus_return_if_fail (message != NULL);
04333 _dbus_return_if_fail (!message->locked);
04334
04335 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04336
04337 if (no_reply)
04338 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04339 else
04340 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04341 }
04342
04350 dbus_bool_t
04351 dbus_message_get_no_reply (DBusMessage *message)
04352 {
04353 const char *header;
04354
04355 _dbus_return_val_if_fail (message != NULL, FALSE);
04356
04357 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04358
04359 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
04360 }
04361
04362
04372 void
04373 dbus_message_set_auto_activation (DBusMessage *message,
04374 dbus_bool_t auto_activation)
04375 {
04376 char *header;
04377
04378 _dbus_return_if_fail (message != NULL);
04379 _dbus_return_if_fail (!message->locked);
04380
04381 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04382
04383 if (auto_activation)
04384 *header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04385 else
04386 *header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04387 }
04388
04396 dbus_bool_t
04397 dbus_message_get_auto_activation (DBusMessage *message)
04398 {
04399 const char *header;
04400
04401 _dbus_return_val_if_fail (message != NULL, FALSE);
04402
04403 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04404
04405 return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0;
04406 }
04407
04415 const char*
04416 dbus_message_get_sender (DBusMessage *message)
04417 {
04418 _dbus_return_val_if_fail (message != NULL, NULL);
04419
04420 return get_string_field (message,
04421 DBUS_HEADER_FIELD_SENDER,
04422 NULL);
04423 }
04424
04440 const char*
04441 dbus_message_get_signature (DBusMessage *message)
04442 {
04443 _dbus_return_val_if_fail (message != NULL, NULL);
04444
04445 return get_string_field (message,
04446 DBUS_HEADER_FIELD_SIGNATURE,
04447 NULL);
04448 }
04449
04450 static dbus_bool_t
04451 _dbus_message_has_type_interface_member (DBusMessage *message,
04452 int type,
04453 const char *interface,
04454 const char *method)
04455 {
04456 const char *n;
04457
04458 _dbus_assert (message != NULL);
04459 _dbus_assert (interface != NULL);
04460 _dbus_assert (method != NULL);
04461
04462 if (dbus_message_get_type (message) != type)
04463 return FALSE;
04464
04465
04466
04467
04468
04469 n = dbus_message_get_member (message);
04470
04471 if (n && strcmp (n, method) == 0)
04472 {
04473 n = dbus_message_get_interface (message);
04474
04475 if (n && strcmp (n, interface) == 0)
04476 return TRUE;
04477 }
04478
04479 return FALSE;
04480 }
04481
04494 dbus_bool_t
04495 dbus_message_is_method_call (DBusMessage *message,
04496 const char *interface,
04497 const char *method)
04498 {
04499 _dbus_return_val_if_fail (message != NULL, FALSE);
04500 _dbus_return_val_if_fail (interface != NULL, FALSE);
04501 _dbus_return_val_if_fail (method != NULL, FALSE);
04502
04503 return _dbus_message_has_type_interface_member (message,
04504 DBUS_MESSAGE_TYPE_METHOD_CALL,
04505 interface, method);
04506 }
04507
04520 dbus_bool_t
04521 dbus_message_is_signal (DBusMessage *message,
04522 const char *interface,
04523 const char *signal_name)
04524 {
04525 _dbus_return_val_if_fail (message != NULL, FALSE);
04526 _dbus_return_val_if_fail (interface != NULL, FALSE);
04527 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
04528
04529 return _dbus_message_has_type_interface_member (message,
04530 DBUS_MESSAGE_TYPE_SIGNAL,
04531 interface, signal_name);
04532 }
04533
04544 dbus_bool_t
04545 dbus_message_is_error (DBusMessage *message,
04546 const char *error_name)
04547 {
04548 const char *n;
04549
04550 _dbus_return_val_if_fail (message != NULL, FALSE);
04551 _dbus_return_val_if_fail (error_name != NULL, FALSE);
04552 _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE);
04553
04554 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04555 return FALSE;
04556
04557 n = dbus_message_get_error_name (message);
04558
04559 if (n && strcmp (n, error_name) == 0)
04560 return TRUE;
04561 else
04562 return FALSE;
04563 }
04564
04575 dbus_bool_t
04576 dbus_message_has_destination (DBusMessage *message,
04577 const char *service)
04578 {
04579 const char *s;
04580
04581 _dbus_return_val_if_fail (message != NULL, FALSE);
04582 _dbus_return_val_if_fail (service != NULL, FALSE);
04583
04584 s = dbus_message_get_destination (message);
04585
04586 if (s && strcmp (s, service) == 0)
04587 return TRUE;
04588 else
04589 return FALSE;
04590 }
04591
04606 dbus_bool_t
04607 dbus_message_has_sender (DBusMessage *message,
04608 const char *service)
04609 {
04610 const char *s;
04611
04612 _dbus_return_val_if_fail (message != NULL, FALSE);
04613 _dbus_return_val_if_fail (service != NULL, FALSE);
04614
04615 s = dbus_message_get_sender (message);
04616
04617 if (s && strcmp (s, service) == 0)
04618 return TRUE;
04619 else
04620 return FALSE;
04621 }
04622
04632 dbus_bool_t
04633 dbus_message_has_signature (DBusMessage *message,
04634 const char *signature)
04635 {
04636 const char *s;
04637
04638 _dbus_return_val_if_fail (message != NULL, FALSE);
04639 _dbus_return_val_if_fail (signature != NULL, FALSE);
04640
04641 s = dbus_message_get_signature (message);
04642
04643 if (s && strcmp (s, signature) == 0)
04644 return TRUE;
04645 else
04646 return FALSE;
04647 }
04648
04666 dbus_bool_t
04667 dbus_set_error_from_message (DBusError *error,
04668 DBusMessage *message)
04669 {
04670 char *str;
04671
04672 _dbus_return_val_if_fail (message != NULL, FALSE);
04673 _dbus_return_val_if_error_is_set (error, FALSE);
04674
04675 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04676 return FALSE;
04677
04678 str = NULL;
04679 dbus_message_get_args (message, NULL,
04680 DBUS_TYPE_STRING, &str,
04681 DBUS_TYPE_INVALID);
04682
04683 dbus_set_error (error, dbus_message_get_error_name (message),
04684 str ? "%s" : NULL, str);
04685
04686 dbus_free (str);
04687
04688 return TRUE;
04689 }
04690
04715
04716
04717
04718
04719
04723 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
04724
04729 struct DBusMessageLoader
04730 {
04731 int refcount;
04733 DBusString data;
04735 DBusList *messages;
04737 long max_message_size;
04739 unsigned int buffer_outstanding : 1;
04741 unsigned int corrupted : 1;
04742 };
04743
04754 #define INITIAL_LOADER_DATA_LEN 32
04755
04762 DBusMessageLoader*
04763 _dbus_message_loader_new (void)
04764 {
04765 DBusMessageLoader *loader;
04766
04767 loader = dbus_new0 (DBusMessageLoader, 1);
04768 if (loader == NULL)
04769 return NULL;
04770
04771 loader->refcount = 1;
04772
04773
04774
04775
04776 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
04777
04778 if (!_dbus_string_init (&loader->data))
04779 {
04780 dbus_free (loader);
04781 return NULL;
04782 }
04783
04784
04785 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
04786 _dbus_string_set_length (&loader->data, 0);
04787
04788 return loader;
04789 }
04790
04797 DBusMessageLoader *
04798 _dbus_message_loader_ref (DBusMessageLoader *loader)
04799 {
04800 loader->refcount += 1;
04801
04802 return loader;
04803 }
04804
04811 void
04812 _dbus_message_loader_unref (DBusMessageLoader *loader)
04813 {
04814 loader->refcount -= 1;
04815 if (loader->refcount == 0)
04816 {
04817 _dbus_list_foreach (&loader->messages,
04818 (DBusForeachFunction) dbus_message_unref,
04819 NULL);
04820 _dbus_list_clear (&loader->messages);
04821 _dbus_string_free (&loader->data);
04822 dbus_free (loader);
04823 }
04824 }
04825
04844 void
04845 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04846 DBusString **buffer)
04847 {
04848 _dbus_assert (!loader->buffer_outstanding);
04849
04850 *buffer = &loader->data;
04851
04852 loader->buffer_outstanding = TRUE;
04853 }
04854
04859 #define DBUS_MINIMUM_HEADER_SIZE 16
04860
04861 static dbus_bool_t
04862 decode_string_field (const DBusString *data,
04863 int field,
04864 HeaderField *header_field,
04865 DBusString *field_data,
04866 int pos,
04867 int type)
04868 {
04869 int string_data_pos;
04870
04871 _dbus_assert (header_field != NULL);
04872 _dbus_assert (field_data != NULL);
04873
04874 if (header_field->name_offset >= 0)
04875 {
04876 _dbus_verbose ("%s field provided twice\n",
04877 _dbus_header_field_to_string (field));
04878 return FALSE;
04879 }
04880
04881 if (type != DBUS_TYPE_STRING)
04882 {
04883 _dbus_verbose ("%s field has wrong type %s\n",
04884 _dbus_header_field_to_string (field),
04885 _dbus_type_to_string (type));
04886 return FALSE;
04887 }
04888
04889
04890
04891
04892
04893 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
04894 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
04895
04896 _dbus_string_init_const (field_data,
04897 _dbus_string_get_const_data (data) + string_data_pos);
04898
04899 header_field->name_offset = pos - 2;
04900 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
04901
04902 #if 0
04903 _dbus_verbose ("Found field %s at offset %d\n",
04904 _dbus_header_field_to_string (field),
04905 header_field->value_offset);
04906 #endif
04907
04908 return TRUE;
04909 }
04910
04911
04912
04913
04914
04915
04916 static dbus_bool_t
04917 decode_header_data (const DBusString *data,
04918 int header_len,
04919 int byte_order,
04920 int message_type,
04921 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
04922 int *message_padding)
04923 {
04924 DBusString field_data;
04925 int pos, new_pos;
04926 int i;
04927 int field;
04928 int type;
04929 dbus_bool_t signature_required;
04930
04931 if (header_len < 16)
04932 {
04933 _dbus_verbose ("Header length %d is too short\n", header_len);
04934 return FALSE;
04935 }
04936
04937 i = 0;
04938 while (i <= DBUS_HEADER_FIELD_LAST)
04939 {
04940 fields[i].name_offset = -1;
04941 fields[i].value_offset = -1;
04942 ++i;
04943 }
04944
04945 pos = 16;
04946 while (pos < header_len)
04947 {
04948 field = _dbus_string_get_byte (data, pos);
04949 if (field == DBUS_HEADER_FIELD_INVALID)
04950 break;
04951 pos++;
04952
04953 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
04954 {
04955 _dbus_verbose ("Failed to validate type of named header field pos = %d\n",
04956 pos);
04957 return FALSE;
04958 }
04959
04960 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
04961 {
04962 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n",
04963 pos);
04964 return FALSE;
04965 }
04966
04967 if (new_pos > header_len)
04968 {
04969 _dbus_verbose ("Named header field tries to extend beyond header length\n");
04970 return FALSE;
04971 }
04972
04973 switch (field)
04974 {
04975 case DBUS_HEADER_FIELD_DESTINATION:
04976 if (!decode_string_field (data, field, &fields[field],
04977 &field_data, pos, type))
04978 return FALSE;
04979
04980 if (!_dbus_string_validate_service (&field_data, 0,
04981 _dbus_string_get_length (&field_data)))
04982 {
04983 _dbus_verbose ("service field has invalid content \"%s\"\n",
04984 _dbus_string_get_const_data (&field_data));
04985 return FALSE;
04986 }
04987 break;
04988
04989 case DBUS_HEADER_FIELD_INTERFACE:
04990 if (!decode_string_field (data, field, &fields[field],
04991 &field_data, pos, type))
04992 return FALSE;
04993
04994 if (!_dbus_string_validate_interface (&field_data, 0,
04995 _dbus_string_get_length (&field_data)))
04996 {
04997 _dbus_verbose ("interface field has invalid content \"%s\"\n",
04998 _dbus_string_get_const_data (&field_data));
04999 return FALSE;
05000 }
05001
05002 if (_dbus_string_equal_c_str (&field_data,
05003 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
05004 {
05005 _dbus_verbose ("Message is on the local interface\n");
05006 return FALSE;
05007 }
05008 break;
05009
05010 case DBUS_HEADER_FIELD_MEMBER:
05011 if (!decode_string_field (data, field, &fields[field],
05012 &field_data, pos, type))
05013 return FALSE;
05014
05015 if (!_dbus_string_validate_member (&field_data, 0,
05016 _dbus_string_get_length (&field_data)))
05017 {
05018 _dbus_verbose ("member field has invalid content \"%s\"\n",
05019 _dbus_string_get_const_data (&field_data));
05020 return FALSE;
05021 }
05022 break;
05023
05024 case DBUS_HEADER_FIELD_ERROR_NAME:
05025 if (!decode_string_field (data, field, &fields[field],
05026 &field_data, pos, type))
05027 return FALSE;
05028
05029 if (!_dbus_string_validate_error_name (&field_data, 0,
05030 _dbus_string_get_length (&field_data)))
05031 {
05032 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
05033 _dbus_string_get_const_data (&field_data));
05034 return FALSE;
05035 }
05036 break;
05037
05038 case DBUS_HEADER_FIELD_SENDER:
05039 if (!decode_string_field (data, field, &fields[field],
05040 &field_data, pos, type))
05041 return FALSE;
05042
05043 if (!_dbus_string_validate_service (&field_data, 0,
05044 _dbus_string_get_length (&field_data)))
05045 {
05046 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
05047 _dbus_string_get_const_data (&field_data));
05048 return FALSE;
05049 }
05050 break;
05051
05052 case DBUS_HEADER_FIELD_PATH:
05053
05054
05055
05056
05057
05058
05059 if (fields[field].name_offset >= 0)
05060 {
05061 _dbus_verbose ("path field provided twice\n");
05062 return FALSE;
05063 }
05064 if (type != DBUS_TYPE_OBJECT_PATH)
05065 {
05066 _dbus_verbose ("path field has wrong type\n");
05067 return FALSE;
05068 }
05069
05070 fields[field].name_offset = pos - 2;
05071 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05072
05073
05074 {
05075 const char *s;
05076 s = _dbus_string_get_const_data_len (data,
05077 fields[field].value_offset,
05078 _dbus_string_get_length (data) -
05079 fields[field].value_offset);
05080 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
05081 {
05082 _dbus_verbose ("Message is on the local path\n");
05083 return FALSE;
05084 }
05085 }
05086
05087 _dbus_verbose ("Found path at offset %d\n",
05088 fields[field].value_offset);
05089 break;
05090
05091 case DBUS_HEADER_FIELD_REPLY_SERIAL:
05092 if (fields[field].name_offset >= 0)
05093 {
05094 _dbus_verbose ("reply field provided twice\n");
05095 return FALSE;
05096 }
05097
05098 if (type != DBUS_TYPE_UINT32)
05099 {
05100 _dbus_verbose ("reply field has wrong type\n");
05101 return FALSE;
05102 }
05103
05104 fields[field].name_offset = pos - 2;
05105 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05106
05107 _dbus_verbose ("Found reply serial %u at offset %d\n",
05108 _dbus_demarshal_uint32 (data,
05109 byte_order,
05110 fields[field].value_offset,
05111 NULL),
05112 fields[field].value_offset);
05113 break;
05114
05115 case DBUS_HEADER_FIELD_SIGNATURE:
05116 if (!decode_string_field (data, field, &fields[field],
05117 &field_data, pos, type))
05118 return FALSE;
05119
05120 #if 0
05121
05122 if (!_dbus_string_validate_signature (&field_data, 0,
05123 _dbus_string_get_length (&field_data)))
05124 {
05125 _dbus_verbose ("signature field has invalid content \"%s\"\n",
05126 _dbus_string_get_const_data (&field_data));
05127 return FALSE;
05128 }
05129 #endif
05130 break;
05131
05132 default:
05133 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
05134 field, pos);
05135 }
05136
05137 pos = new_pos;
05138 }
05139
05140 if (pos < header_len)
05141 {
05142
05143 if ((header_len - pos) >= 8)
05144 {
05145 _dbus_verbose ("too much header alignment padding\n");
05146 return FALSE;
05147 }
05148
05149 if (!_dbus_string_validate_nul (data,
05150 pos, (header_len - pos)))
05151 {
05152 _dbus_verbose ("header alignment padding is not nul\n");
05153 return FALSE;
05154 }
05155 }
05156
05157
05158 signature_required = TRUE;
05159
05160 switch (message_type)
05161 {
05162 case DBUS_MESSAGE_TYPE_SIGNAL:
05163 case DBUS_MESSAGE_TYPE_METHOD_CALL:
05164 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
05165 {
05166 _dbus_verbose ("No path field provided\n");
05167 return FALSE;
05168 }
05169
05170 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
05171 {
05172 _dbus_verbose ("No interface field provided\n");
05173 return FALSE;
05174 }
05175 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
05176 {
05177 _dbus_verbose ("No member field provided\n");
05178 return FALSE;
05179 }
05180 break;
05181 case DBUS_MESSAGE_TYPE_ERROR:
05182 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
05183 {
05184 _dbus_verbose ("No error-name field provided\n");
05185 return FALSE;
05186 }
05187 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05188 {
05189 _dbus_verbose ("No reply serial field provided in error\n");
05190 return FALSE;
05191 }
05192 break;
05193 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
05194 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05195 {
05196 _dbus_verbose ("No reply serial field provided in method return\n");
05197 return FALSE;
05198 }
05199 break;
05200 default:
05201
05202 signature_required = FALSE;
05203 break;
05204 }
05205
05206
05207 if (signature_required)
05208 {
05209 if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0)
05210 {
05211 _dbus_verbose ("No signature field provided\n");
05212 return FALSE;
05213 }
05214 }
05215
05216 if (message_padding)
05217 *message_padding = header_len - pos;
05218
05219 return TRUE;
05220 }
05221
05232 void
05233 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
05234 DBusString *buffer,
05235 int bytes_read)
05236 {
05237 _dbus_assert (loader->buffer_outstanding);
05238 _dbus_assert (buffer == &loader->data);
05239
05240 loader->buffer_outstanding = FALSE;
05241 }
05242
05243 static dbus_bool_t
05244 load_one_message (DBusMessageLoader *loader,
05245 int byte_order,
05246 int message_type,
05247 int header_len,
05248 int body_len)
05249 {
05250 DBusMessage *message;
05251 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
05252 int i;
05253 int next_arg;
05254 dbus_bool_t oom;
05255 int header_padding;
05256
05257 message = NULL;
05258 oom = FALSE;
05259
05260 #if 0
05261 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
05262 #endif
05263
05264 if (!decode_header_data (&loader->data,
05265 header_len, byte_order,
05266 message_type,
05267 fields, &header_padding))
05268 {
05269 _dbus_verbose ("Header was invalid\n");
05270 loader->corrupted = TRUE;
05271 goto failed;
05272 }
05273
05274 next_arg = header_len;
05275 while (next_arg < (header_len + body_len))
05276 {
05277 int type;
05278 int prev = next_arg;
05279
05280 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
05281 &type, &next_arg))
05282 {
05283 _dbus_verbose ("invalid typecode at offset %d\n", prev);
05284 loader->corrupted = TRUE;
05285 goto failed;
05286 }
05287
05288 if (!_dbus_marshal_validate_arg (&loader->data,
05289 byte_order,
05290 0,
05291 type, -1,
05292 next_arg,
05293 &next_arg))
05294 {
05295 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
05296 loader->corrupted = TRUE;
05297 goto failed;
05298 }
05299
05300 _dbus_assert (next_arg > prev);
05301 }
05302
05303 if (next_arg > (header_len + body_len))
05304 {
05305 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
05306 next_arg, header_len, body_len,
05307 header_len + body_len);
05308 loader->corrupted = TRUE;
05309 goto failed;
05310 }
05311
05312 message = dbus_message_new_empty_header ();
05313 if (message == NULL)
05314 {
05315 _dbus_verbose ("Failed to allocate empty message\n");
05316 oom = TRUE;
05317 goto failed;
05318 }
05319
05320 message->byte_order = byte_order;
05321 message->header_padding = header_padding;
05322
05323
05324 i = 0;
05325 while (i <= DBUS_HEADER_FIELD_LAST)
05326 {
05327 message->header_fields[i] = fields[i];
05328 ++i;
05329 }
05330
05331 if (!_dbus_list_append (&loader->messages, message))
05332 {
05333 _dbus_verbose ("Failed to append new message to loader queue\n");
05334 oom = TRUE;
05335 goto failed;
05336 }
05337
05338 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
05339 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
05340
05341 _dbus_assert (_dbus_string_get_length (&loader->data) >=
05342 (header_len + body_len));
05343
05344 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
05345 {
05346 _dbus_verbose ("Failed to move header into new message\n");
05347 oom = TRUE;
05348 goto failed;
05349 }
05350
05351 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
05352 {
05353 _dbus_verbose ("Failed to move body into new message\n");
05354
05355 oom = TRUE;
05356 goto failed;
05357 }
05358
05359 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
05360 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
05361
05362
05363
05364
05365 message->reply_serial = get_uint_field (message,
05366 DBUS_HEADER_FIELD_REPLY_SERIAL);
05367
05368 message->client_serial = _dbus_demarshal_uint32 (&message->header,
05369 message->byte_order,
05370 CLIENT_SERIAL_OFFSET,
05371 NULL);
05372 if (message->client_serial == 0 ||
05373 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0))
05374 {
05375 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n",
05376 message->client_serial,
05377 message->reply_serial);
05378
05379 loader->corrupted = TRUE;
05380 goto failed;
05381 }
05382
05383 _dbus_verbose ("Loaded message %p\n", message);
05384
05385 _dbus_assert (!oom);
05386 _dbus_assert (!loader->corrupted);
05387
05388 return TRUE;
05389
05390 failed:
05391
05392
05393
05394 if (message != NULL)
05395 {
05396
05397 if (_dbus_string_get_length (&message->body) > 0)
05398 {
05399 dbus_bool_t result;
05400
05401 result = _dbus_string_copy_len (&message->body, 0, body_len,
05402 &loader->data, 0);
05403
05404 _dbus_assert (result);
05405 }
05406
05407 if (_dbus_string_get_length (&message->header) > 0)
05408 {
05409 dbus_bool_t result;
05410
05411 result = _dbus_string_copy_len (&message->header, 0, header_len,
05412 &loader->data, 0);
05413
05414 _dbus_assert (result);
05415 }
05416
05417
05418 _dbus_list_remove_last (&loader->messages, message);
05419
05420 dbus_message_unref (message);
05421 }
05422
05423
05424 return !oom;
05425 }
05426
05440 dbus_bool_t
05441 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
05442 {
05443 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16)
05444 {
05445 const char *header_data;
05446 int byte_order, message_type, header_len, body_len;
05447 dbus_uint32_t header_len_unsigned, body_len_unsigned;
05448
05449 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
05450
05451 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
05452
05453 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
05454 {
05455 _dbus_verbose ("Message has protocol version %d ours is %d\n",
05456 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
05457 loader->corrupted = TRUE;
05458 return TRUE;
05459 }
05460
05461 byte_order = header_data[BYTE_ORDER_OFFSET];
05462
05463 if (byte_order != DBUS_LITTLE_ENDIAN &&
05464 byte_order != DBUS_BIG_ENDIAN)
05465 {
05466 _dbus_verbose ("Message with bad byte order '%c' received\n",
05467 byte_order);
05468 loader->corrupted = TRUE;
05469 return TRUE;
05470 }
05471
05472
05473
05474
05475 message_type = header_data[TYPE_OFFSET];
05476 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
05477 {
05478 _dbus_verbose ("Message with bad type '%d' received\n",
05479 message_type);
05480 loader->corrupted = TRUE;
05481 return TRUE;
05482 }
05483
05484 header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
05485 body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
05486
05487 if (header_len_unsigned < 16)
05488 {
05489 _dbus_verbose ("Message had broken too-small header length %u\n",
05490 header_len_unsigned);
05491 loader->corrupted = TRUE;
05492 return TRUE;
05493 }
05494
05495 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
05496 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
05497 {
05498 _dbus_verbose ("Header or body length too large (%u %u)\n",
05499 header_len_unsigned,
05500 body_len_unsigned);
05501 loader->corrupted = TRUE;
05502 return TRUE;
05503 }
05504
05505
05506
05507
05508 header_len = header_len_unsigned;
05509 body_len = body_len_unsigned;
05510
05511 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
05512 {
05513
05514 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
05515 header_len);
05516 loader->corrupted = TRUE;
05517 return TRUE;
05518 }
05519
05520 if (header_len + body_len > loader->max_message_size)
05521 {
05522 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
05523 header_len, body_len, loader->max_message_size);
05524 loader->corrupted = TRUE;
05525 return TRUE;
05526 }
05527
05528 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
05529 {
05530 if (!load_one_message (loader, byte_order, message_type,
05531 header_len, body_len))
05532 return FALSE;
05533 }
05534 else
05535 return TRUE;
05536 }
05537
05538 return TRUE;
05539 }
05540
05548 DBusMessage*
05549 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
05550 {
05551 if (loader->messages)
05552 return loader->messages->data;
05553 else
05554 return NULL;
05555 }
05556
05565 DBusMessage*
05566 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
05567 {
05568 return _dbus_list_pop_first (&loader->messages);
05569 }
05570
05579 DBusList*
05580 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
05581 {
05582 return _dbus_list_pop_first_link (&loader->messages);
05583 }
05584
05591 void
05592 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
05593 DBusList *link)
05594 {
05595 _dbus_list_prepend_link (&loader->messages, link);
05596 }
05597
05607 dbus_bool_t
05608 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
05609 {
05610 return loader->corrupted;
05611 }
05612
05619 void
05620 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
05621 long size)
05622 {
05623 if (size > MAX_SANE_MESSAGE_SIZE)
05624 {
05625 _dbus_verbose ("clamping requested max message size %ld to %d\n",
05626 size, MAX_SANE_MESSAGE_SIZE);
05627 size = MAX_SANE_MESSAGE_SIZE;
05628 }
05629 loader->max_message_size = size;
05630 }
05631
05638 long
05639 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
05640 {
05641 return loader->max_message_size;
05642 }
05643
05644 static DBusDataSlotAllocator slot_allocator;
05645 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
05646
05661 dbus_bool_t
05662 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
05663 {
05664 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05665 _DBUS_LOCK_NAME (message_slots),
05666 slot_p);
05667 }
05668
05680 void
05681 dbus_message_free_data_slot (dbus_int32_t *slot_p)
05682 {
05683 _dbus_return_if_fail (*slot_p >= 0);
05684
05685 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05686 }
05687
05701 dbus_bool_t
05702 dbus_message_set_data (DBusMessage *message,
05703 dbus_int32_t slot,
05704 void *data,
05705 DBusFreeFunction free_data_func)
05706 {
05707 DBusFreeFunction old_free_func;
05708 void *old_data;
05709 dbus_bool_t retval;
05710
05711 _dbus_return_val_if_fail (message != NULL, FALSE);
05712 _dbus_return_val_if_fail (slot >= 0, FALSE);
05713
05714 retval = _dbus_data_slot_list_set (&slot_allocator,
05715 &message->slot_list,
05716 slot, data, free_data_func,
05717 &old_free_func, &old_data);
05718
05719 if (retval)
05720 {
05721
05722 if (old_free_func)
05723 (* old_free_func) (old_data);
05724 }
05725
05726 return retval;
05727 }
05728
05737 void*
05738 dbus_message_get_data (DBusMessage *message,
05739 dbus_int32_t slot)
05740 {
05741 void *res;
05742
05743 _dbus_return_val_if_fail (message != NULL, NULL);
05744
05745 res = _dbus_data_slot_list_get (&slot_allocator,
05746 &message->slot_list,
05747 slot);
05748
05749 return res;
05750 }
05751
05765 int
05766 dbus_message_type_from_string (const char *type_str)
05767 {
05768 if (strcmp (type_str, "method_call") == 0)
05769 return DBUS_MESSAGE_TYPE_METHOD_CALL;
05770 if (strcmp (type_str, "method_return") == 0)
05771 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
05772 else if (strcmp (type_str, "signal") == 0)
05773 return DBUS_MESSAGE_TYPE_SIGNAL;
05774 else if (strcmp (type_str, "error") == 0)
05775 return DBUS_MESSAGE_TYPE_ERROR;
05776 else
05777 return DBUS_MESSAGE_TYPE_INVALID;
05778 }
05779
05781 #ifdef DBUS_BUILD_TESTS
05782 #include "dbus-test.h"
05783 #include <stdio.h>
05784 #include <stdlib.h>
05785
05786 static void
05787 message_iter_test (DBusMessage *message)
05788 {
05789 DBusMessageIter iter, dict, dict2, array, array2;
05790 char *str;
05791 unsigned char *data;
05792 dbus_int32_t *our_int_array;
05793 int len;
05794
05795 dbus_message_iter_init (message, &iter);
05796
05797
05798 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
05799 _dbus_assert_not_reached ("Argument type isn't string");
05800
05801 str = dbus_message_iter_get_string (&iter);
05802 if (strcmp (str, "Test string") != 0)
05803 _dbus_assert_not_reached ("Strings differ");
05804 dbus_free (str);
05805
05806 if (!dbus_message_iter_next (&iter))
05807 _dbus_assert_not_reached ("Reached end of arguments");
05808
05809
05810 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
05811 _dbus_assert_not_reached ("Argument type isn't int32");
05812
05813 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
05814 _dbus_assert_not_reached ("Signed integers differ");
05815
05816 if (!dbus_message_iter_next (&iter))
05817 _dbus_assert_not_reached ("Reached end of fields");
05818
05819
05820 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
05821 _dbus_assert_not_reached ("Argument type isn't int32");
05822
05823 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
05824 _dbus_assert_not_reached ("Unsigned integers differ");
05825
05826 if (!dbus_message_iter_next (&iter))
05827 _dbus_assert_not_reached ("Reached end of arguments");
05828
05829
05830 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
05831 _dbus_assert_not_reached ("Argument type isn't double");
05832
05833 if (dbus_message_iter_get_double (&iter) != 3.14159)
05834 _dbus_assert_not_reached ("Doubles differ");
05835
05836 if (!dbus_message_iter_next (&iter))
05837 _dbus_assert_not_reached ("Reached end of arguments");
05838
05839 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
05840 _dbus_assert_not_reached ("Argument type not an array");
05841
05842 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
05843 _dbus_assert_not_reached ("Array type not double");
05844
05845
05846 dbus_message_iter_init_array_iterator (&iter, &array, NULL);
05847
05848 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05849 _dbus_assert_not_reached ("Argument type isn't double");
05850
05851 if (dbus_message_iter_get_double (&array) != 1.5)
05852 _dbus_assert_not_reached ("Unsigned integers differ");
05853
05854 if (!dbus_message_iter_next (&array))
05855 _dbus_assert_not_reached ("Reached end of arguments");
05856
05857 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05858 _dbus_assert_not_reached ("Argument type isn't double");
05859
05860 if (dbus_message_iter_get_double (&array) != 2.5)
05861 _dbus_assert_not_reached ("Unsigned integers differ");
05862
05863 if (dbus_message_iter_next (&array))
05864 _dbus_assert_not_reached ("Didn't reach end of arguments");
05865
05866 if (!dbus_message_iter_next (&iter))
05867 _dbus_assert_not_reached ("Reached end of arguments");
05868
05869
05870
05871
05872 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
05873 _dbus_assert_not_reached ("not dict type");
05874
05875 dbus_message_iter_init_dict_iterator (&iter, &dict);
05876
05877 str = dbus_message_iter_get_dict_key (&dict);
05878 if (str == NULL || strcmp (str, "test") != 0)
05879 _dbus_assert_not_reached ("wrong dict key");
05880 dbus_free (str);
05881
05882 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
05883 _dbus_assert_not_reached ("wrong dict entry type");
05884
05885 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
05886 _dbus_assert_not_reached ("wrong dict entry value");
05887
05888
05889
05890 if (!dbus_message_iter_next (&dict))
05891 _dbus_assert_not_reached ("reached end of dict");
05892
05893 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_DICT)
05894 _dbus_assert_not_reached ("not dict type");
05895
05896 dbus_message_iter_init_dict_iterator (&dict, &dict2);
05897
05898 str = dbus_message_iter_get_dict_key (&dict2);
05899 if (str == NULL || strcmp (str, "dictkey") != 0)
05900 _dbus_assert_not_reached ("wrong dict key");
05901 dbus_free (str);
05902
05903 if (dbus_message_iter_get_arg_type (&dict2) != DBUS_TYPE_STRING)
05904 _dbus_assert_not_reached ("wrong dict entry type");
05905
05906 str = dbus_message_iter_get_string (&dict2);
05907 if (str == NULL || strcmp (str, "dictvalue") != 0)
05908 _dbus_assert_not_reached ("wrong dict entry value");
05909 dbus_free (str);
05910
05911 if (dbus_message_iter_next (&dict2))
05912 _dbus_assert_not_reached ("didn't reach end of dict");
05913
05914 if (!dbus_message_iter_next (&dict))
05915 _dbus_assert_not_reached ("reached end of dict");
05916
05917
05918
05919 str = dbus_message_iter_get_dict_key (&dict);
05920 if (str == NULL || strcmp (str, "array") != 0)
05921 _dbus_assert_not_reached ("wrong dict key");
05922 dbus_free (str);
05923
05924 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
05925 _dbus_assert_not_reached ("Argument type not an array");
05926
05927 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
05928 _dbus_assert_not_reached ("Array type not array");
05929
05930 dbus_message_iter_init_array_iterator (&dict, &array, NULL);
05931
05932 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
05933 _dbus_assert_not_reached ("Argument type isn't array");
05934
05935 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05936 _dbus_assert_not_reached ("Array type not int32");
05937
05938 dbus_message_iter_init_array_iterator (&array, &array2, NULL);
05939
05940 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
05941 _dbus_assert_not_reached ("Argument type isn't int32");
05942
05943 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
05944 _dbus_assert_not_reached ("Signed integers differ");
05945
05946 if (!dbus_message_iter_next (&array2))
05947 _dbus_assert_not_reached ("Reached end of arguments");
05948
05949 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
05950 _dbus_assert_not_reached ("Signed integers differ");
05951
05952 if (dbus_message_iter_next (&array2))
05953 _dbus_assert_not_reached ("Didn't reached end of arguments");
05954
05955 if (!dbus_message_iter_next (&array))
05956 _dbus_assert_not_reached ("Reached end of arguments");
05957
05958 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05959 _dbus_assert_not_reached ("Array type not int32");
05960
05961 if (!dbus_message_iter_get_int32_array (&array,
05962 &our_int_array,
05963 &len))
05964 _dbus_assert_not_reached ("couldn't get int32 array");
05965
05966 _dbus_assert (len == 3);
05967 _dbus_assert (our_int_array[0] == 0x34567812 &&
05968 our_int_array[1] == 0x45678123 &&
05969 our_int_array[2] == 0x56781234);
05970 dbus_free (our_int_array);
05971
05972 if (dbus_message_iter_next (&array))
05973 _dbus_assert_not_reached ("Didn't reach end of array");
05974
05975 if (dbus_message_iter_next (&dict))
05976 _dbus_assert_not_reached ("Didn't reach end of dict");
05977
05978 if (!dbus_message_iter_next (&iter))
05979 _dbus_assert_not_reached ("Reached end of arguments");
05980
05981 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
05982 {
05983 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
05984 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
05985 }
05986
05987 if (dbus_message_iter_get_byte (&iter) != 0xF0)
05988 _dbus_assert_not_reached ("wrong value after dict");
05989
05990
05991 if (!dbus_message_iter_next (&iter))
05992 _dbus_assert_not_reached ("Reached end of arguments");
05993
05994 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
05995 _dbus_assert_not_reached ("not a nil type");
05996
05997 if (!dbus_message_iter_next (&iter))
05998 _dbus_assert_not_reached ("Reached end of arguments");
05999
06000 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_CUSTOM)
06001 _dbus_assert_not_reached ("wrong type after dict");
06002
06003 if (!dbus_message_iter_get_custom (&iter, &str, &data, &len))
06004 _dbus_assert_not_reached ("failed to get custom type");
06005
06006 _dbus_assert (strcmp (str, "MyTypeName")==0);
06007 _dbus_assert (len == 5);
06008 _dbus_assert (strcmp (data, "data")==0);
06009 dbus_free (str);
06010 dbus_free (data);
06011
06012 if (!dbus_message_iter_next (&iter))
06013 _dbus_assert_not_reached ("Reached end of arguments");
06014
06015 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06016 _dbus_assert_not_reached ("wrong value after custom");
06017
06018 if (!dbus_message_iter_next (&iter))
06019 _dbus_assert_not_reached ("Reached end of arguments");
06020
06021 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
06022 _dbus_assert_not_reached ("no array");
06023
06024 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_INT32)
06025 _dbus_assert_not_reached ("Array type not int32");
06026
06027 if (dbus_message_iter_init_array_iterator (&iter, &array, NULL))
06028 _dbus_assert_not_reached ("non empty array");
06029
06030 if (!dbus_message_iter_next (&iter))
06031 _dbus_assert_not_reached ("Reached end of arguments");
06032
06033 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06034 _dbus_assert_not_reached ("wrong value after empty array");
06035
06036 if (!dbus_message_iter_next (&iter))
06037 _dbus_assert_not_reached ("Reached end of arguments");
06038
06039 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06040 _dbus_assert_not_reached ("non dict");
06041
06042 if (dbus_message_iter_init_dict_iterator (&iter, &dict))
06043 _dbus_assert_not_reached ("non empty dict");
06044
06045 if (!dbus_message_iter_next (&iter))
06046 _dbus_assert_not_reached ("Reached end of arguments");
06047
06048 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06049 _dbus_assert_not_reached ("wrong value after empty dict");
06050
06051 if (dbus_message_iter_next (&iter))
06052 _dbus_assert_not_reached ("Didn't reach end of arguments");
06053 }
06054
06055
06056 static dbus_bool_t
06057 check_message_handling_type (DBusMessageIter *iter,
06058 int type)
06059 {
06060 DBusMessageIter child_iter;
06061
06062 switch (type)
06063 {
06064 case DBUS_TYPE_NIL:
06065 break;
06066 case DBUS_TYPE_BYTE:
06067 dbus_message_iter_get_byte (iter);
06068 break;
06069 case DBUS_TYPE_BOOLEAN:
06070 dbus_message_iter_get_boolean (iter);
06071 break;
06072 case DBUS_TYPE_INT32:
06073 dbus_message_iter_get_int32 (iter);
06074 break;
06075 case DBUS_TYPE_UINT32:
06076 dbus_message_iter_get_uint32 (iter);
06077 break;
06078 case DBUS_TYPE_INT64:
06079 #ifdef DBUS_HAVE_INT64
06080 dbus_message_iter_get_int64 (iter);
06081 #endif
06082 break;
06083 case DBUS_TYPE_UINT64:
06084 #ifdef DBUS_HAVE_INT64
06085 dbus_message_iter_get_uint64 (iter);
06086 #endif
06087 break;
06088 case DBUS_TYPE_DOUBLE:
06089 dbus_message_iter_get_double (iter);
06090 break;
06091 case DBUS_TYPE_STRING:
06092 {
06093 char *str;
06094 str = dbus_message_iter_get_string (iter);
06095 if (str == NULL)
06096 {
06097 _dbus_warn ("NULL string in message\n");
06098 return FALSE;
06099 }
06100 dbus_free (str);
06101 }
06102 break;
06103 case DBUS_TYPE_CUSTOM:
06104 {
06105 char *name;
06106 unsigned char *data;
06107 int len;
06108
06109 if (!dbus_message_iter_get_custom (iter, &name, &data, &len))
06110 {
06111 _dbus_warn ("error reading name from custom type\n");
06112 return FALSE;
06113 }
06114 dbus_free (data);
06115 dbus_free (name);
06116 }
06117 break;
06118 case DBUS_TYPE_ARRAY:
06119 {
06120 int array_type;
06121
06122 dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type);
06123
06124 while (dbus_message_iter_has_next (&child_iter))
06125 {
06126 if (!check_message_handling_type (&child_iter, array_type))
06127 {
06128 _dbus_warn ("error in array element\n");
06129 return FALSE;
06130 }
06131
06132 if (!dbus_message_iter_next (&child_iter))
06133 break;
06134 }
06135 }
06136 break;
06137 case DBUS_TYPE_DICT:
06138 {
06139 int entry_type;
06140 char *key;
06141
06142 dbus_message_iter_init_dict_iterator (iter, &child_iter);
06143
06144 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
06145 {
06146 key = dbus_message_iter_get_dict_key (&child_iter);
06147 if (key == NULL)
06148 {
06149 _dbus_warn ("error reading dict key\n");
06150 return FALSE;
06151 }
06152 dbus_free (key);
06153
06154 if (!check_message_handling_type (&child_iter, entry_type))
06155 {
06156 _dbus_warn ("error in dict value\n");
06157 return FALSE;
06158 }
06159
06160 if (!dbus_message_iter_next (&child_iter))
06161 break;
06162 }
06163 }
06164 break;
06165
06166 default:
06167 _dbus_warn ("unknown type %d\n", type);
06168 return FALSE;
06169 break;
06170 }
06171 return TRUE;
06172 }
06173
06174
06175 static dbus_bool_t
06176 check_message_handling (DBusMessage *message)
06177 {
06178 DBusMessageIter iter;
06179 int type;
06180 dbus_bool_t retval;
06181 dbus_uint32_t client_serial;
06182
06183 retval = FALSE;
06184
06185 client_serial = dbus_message_get_serial (message);
06186
06187
06188 _dbus_marshal_set_uint32 (&message->header,
06189 message->byte_order,
06190 CLIENT_SERIAL_OFFSET,
06191 client_serial);
06192
06193 if (client_serial != dbus_message_get_serial (message))
06194 {
06195 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
06196 goto failed;
06197 }
06198
06199
06200
06201
06202
06203 dbus_message_iter_init (message, &iter);
06204 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
06205 {
06206 if (!check_message_handling_type (&iter, type))
06207 goto failed;
06208
06209 if (!dbus_message_iter_next (&iter))
06210 break;
06211 }
06212
06213 retval = TRUE;
06214
06215 failed:
06216 return retval;
06217 }
06218
06219 static dbus_bool_t
06220 check_have_valid_message (DBusMessageLoader *loader)
06221 {
06222 DBusMessage *message;
06223 dbus_bool_t retval;
06224
06225 message = NULL;
06226 retval = FALSE;
06227
06228 if (!_dbus_message_loader_queue_messages (loader))
06229 _dbus_assert_not_reached ("no memory to queue messages");
06230
06231 if (_dbus_message_loader_get_is_corrupted (loader))
06232 {
06233 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
06234 goto failed;
06235 }
06236
06237 message = _dbus_message_loader_pop_message (loader);
06238 if (message == NULL)
06239 {
06240 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
06241 goto failed;
06242 }
06243
06244 if (_dbus_string_get_length (&loader->data) > 0)
06245 {
06246 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
06247 goto failed;
06248 }
06249
06250
06251
06252
06253
06254 if (!check_message_handling (message))
06255 goto failed;
06256
06257 retval = TRUE;
06258
06259 failed:
06260 if (message)
06261 dbus_message_unref (message);
06262
06263 return retval;
06264 }
06265
06266 static dbus_bool_t
06267 check_invalid_message (DBusMessageLoader *loader)
06268 {
06269 dbus_bool_t retval;
06270
06271 retval = FALSE;
06272
06273 if (!_dbus_message_loader_queue_messages (loader))
06274 _dbus_assert_not_reached ("no memory to queue messages");
06275
06276 if (!_dbus_message_loader_get_is_corrupted (loader))
06277 {
06278 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
06279 goto failed;
06280 }
06281
06282 retval = TRUE;
06283
06284 failed:
06285 return retval;
06286 }
06287
06288 static dbus_bool_t
06289 check_incomplete_message (DBusMessageLoader *loader)
06290 {
06291 DBusMessage *message;
06292 dbus_bool_t retval;
06293
06294 message = NULL;
06295 retval = FALSE;
06296
06297 if (!_dbus_message_loader_queue_messages (loader))
06298 _dbus_assert_not_reached ("no memory to queue messages");
06299
06300 if (_dbus_message_loader_get_is_corrupted (loader))
06301 {
06302 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
06303 goto failed;
06304 }
06305
06306 message = _dbus_message_loader_pop_message (loader);
06307 if (message != NULL)
06308 {
06309 _dbus_warn ("loaded message that was expected to be incomplete\n");
06310 goto failed;
06311 }
06312
06313 retval = TRUE;
06314
06315 failed:
06316 if (message)
06317 dbus_message_unref (message);
06318 return retval;
06319 }
06320
06321 static dbus_bool_t
06322 check_loader_results (DBusMessageLoader *loader,
06323 DBusMessageValidity validity)
06324 {
06325 if (!_dbus_message_loader_queue_messages (loader))
06326 _dbus_assert_not_reached ("no memory to queue messages");
06327
06328 switch (validity)
06329 {
06330 case _DBUS_MESSAGE_VALID:
06331 return check_have_valid_message (loader);
06332 case _DBUS_MESSAGE_INVALID:
06333 return check_invalid_message (loader);
06334 case _DBUS_MESSAGE_INCOMPLETE:
06335 return check_incomplete_message (loader);
06336 case _DBUS_MESSAGE_UNKNOWN:
06337 return TRUE;
06338 }
06339
06340 _dbus_assert_not_reached ("bad DBusMessageValidity");
06341 return FALSE;
06342 }
06343
06344
06353 dbus_bool_t
06354 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
06355 dbus_bool_t is_raw,
06356 DBusString *data)
06357 {
06358 dbus_bool_t retval;
06359
06360 retval = FALSE;
06361
06362 if (is_raw)
06363 {
06364 DBusError error;
06365
06366 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
06367 dbus_error_init (&error);
06368 if (!_dbus_file_get_contents (data, filename, &error))
06369 {
06370 _dbus_warn ("Could not load message file %s: %s\n",
06371 _dbus_string_get_const_data (filename),
06372 error.message);
06373 dbus_error_free (&error);
06374 goto failed;
06375 }
06376 }
06377 else
06378 {
06379 if (!_dbus_message_data_load (data, filename))
06380 {
06381 _dbus_warn ("Could not load message file %s\n",
06382 _dbus_string_get_const_data (filename));
06383 goto failed;
06384 }
06385 }
06386
06387 retval = TRUE;
06388
06389 failed:
06390
06391 return retval;
06392 }
06393
06403 dbus_bool_t
06404 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
06405 dbus_bool_t is_raw,
06406 DBusMessageValidity expected_validity)
06407 {
06408 DBusString data;
06409 dbus_bool_t retval;
06410
06411 retval = FALSE;
06412
06413 if (!_dbus_string_init (&data))
06414 _dbus_assert_not_reached ("could not allocate string\n");
06415
06416 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
06417 &data))
06418 goto failed;
06419
06420 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
06421
06422 failed:
06423
06424 if (!retval)
06425 {
06426 if (_dbus_string_get_length (&data) > 0)
06427 _dbus_verbose_bytes_of_string (&data, 0,
06428 _dbus_string_get_length (&data));
06429
06430 _dbus_warn ("Failed message loader test on %s\n",
06431 _dbus_string_get_const_data (filename));
06432 }
06433
06434 _dbus_string_free (&data);
06435
06436 return retval;
06437 }
06438
06447 dbus_bool_t
06448 dbus_internal_do_not_use_try_message_data (const DBusString *data,
06449 DBusMessageValidity expected_validity)
06450 {
06451 DBusMessageLoader *loader;
06452 dbus_bool_t retval;
06453 int len;
06454 int i;
06455
06456 loader = NULL;
06457 retval = FALSE;
06458
06459
06460
06461 loader = _dbus_message_loader_new ();
06462
06463
06464 _dbus_message_loader_ref (loader);
06465 _dbus_message_loader_unref (loader);
06466 _dbus_message_loader_get_max_message_size (loader);
06467
06468 len = _dbus_string_get_length (data);
06469 for (i = 0; i < len; i++)
06470 {
06471 DBusString *buffer;
06472
06473 _dbus_message_loader_get_buffer (loader, &buffer);
06474 _dbus_string_append_byte (buffer,
06475 _dbus_string_get_byte (data, i));
06476 _dbus_message_loader_return_buffer (loader, buffer, 1);
06477 }
06478
06479 if (!check_loader_results (loader, expected_validity))
06480 goto failed;
06481
06482 _dbus_message_loader_unref (loader);
06483 loader = NULL;
06484
06485
06486
06487 loader = _dbus_message_loader_new ();
06488
06489 {
06490 DBusString *buffer;
06491
06492 _dbus_message_loader_get_buffer (loader, &buffer);
06493 _dbus_string_copy (data, 0, buffer,
06494 _dbus_string_get_length (buffer));
06495 _dbus_message_loader_return_buffer (loader, buffer, 1);
06496 }
06497
06498 if (!check_loader_results (loader, expected_validity))
06499 goto failed;
06500
06501 _dbus_message_loader_unref (loader);
06502 loader = NULL;
06503
06504
06505
06506 loader = _dbus_message_loader_new ();
06507
06508 len = _dbus_string_get_length (data);
06509 for (i = 0; i < len; i += 2)
06510 {
06511 DBusString *buffer;
06512
06513 _dbus_message_loader_get_buffer (loader, &buffer);
06514 _dbus_string_append_byte (buffer,
06515 _dbus_string_get_byte (data, i));
06516 if ((i+1) < len)
06517 _dbus_string_append_byte (buffer,
06518 _dbus_string_get_byte (data, i+1));
06519 _dbus_message_loader_return_buffer (loader, buffer, 1);
06520 }
06521
06522 if (!check_loader_results (loader, expected_validity))
06523 goto failed;
06524
06525 _dbus_message_loader_unref (loader);
06526 loader = NULL;
06527
06528 retval = TRUE;
06529
06530 failed:
06531
06532 if (loader)
06533 _dbus_message_loader_unref (loader);
06534
06535 return retval;
06536 }
06537
06538 static dbus_bool_t
06539 process_test_subdir (const DBusString *test_base_dir,
06540 const char *subdir,
06541 DBusMessageValidity validity,
06542 DBusForeachMessageFileFunc function,
06543 void *user_data)
06544 {
06545 DBusString test_directory;
06546 DBusString filename;
06547 DBusDirIter *dir;
06548 dbus_bool_t retval;
06549 DBusError error;
06550
06551 retval = FALSE;
06552 dir = NULL;
06553
06554 if (!_dbus_string_init (&test_directory))
06555 _dbus_assert_not_reached ("didn't allocate test_directory\n");
06556
06557 _dbus_string_init_const (&filename, subdir);
06558
06559 if (!_dbus_string_copy (test_base_dir, 0,
06560 &test_directory, 0))
06561 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
06562
06563 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
06564 _dbus_assert_not_reached ("couldn't allocate full path");
06565
06566 _dbus_string_free (&filename);
06567 if (!_dbus_string_init (&filename))
06568 _dbus_assert_not_reached ("didn't allocate filename string\n");
06569
06570 dbus_error_init (&error);
06571 dir = _dbus_directory_open (&test_directory, &error);
06572 if (dir == NULL)
06573 {
06574 _dbus_warn ("Could not open %s: %s\n",
06575 _dbus_string_get_const_data (&test_directory),
06576 error.message);
06577 dbus_error_free (&error);
06578 goto failed;
06579 }
06580
06581 printf ("Testing %s:\n", subdir);
06582
06583 next:
06584 while (_dbus_directory_get_next_file (dir, &filename, &error))
06585 {
06586 DBusString full_path;
06587 dbus_bool_t is_raw;
06588
06589 if (!_dbus_string_init (&full_path))
06590 _dbus_assert_not_reached ("couldn't init string");
06591
06592 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
06593 _dbus_assert_not_reached ("couldn't copy dir to full_path");
06594
06595 if (!_dbus_concat_dir_and_file (&full_path, &filename))
06596 _dbus_assert_not_reached ("couldn't concat file to dir");
06597
06598 if (_dbus_string_ends_with_c_str (&filename, ".message"))
06599 is_raw = FALSE;
06600 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
06601 is_raw = TRUE;
06602 else
06603 {
06604 _dbus_verbose ("Skipping non-.message file %s\n",
06605 _dbus_string_get_const_data (&filename));
06606 _dbus_string_free (&full_path);
06607 goto next;
06608 }
06609
06610 printf (" %s\n",
06611 _dbus_string_get_const_data (&filename));
06612
06613 _dbus_verbose (" expecting %s for %s\n",
06614 validity == _DBUS_MESSAGE_VALID ? "valid" :
06615 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
06616 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
06617 _dbus_string_get_const_data (&filename));
06618
06619 if (! (*function) (&full_path, is_raw, validity, user_data))
06620 {
06621 _dbus_string_free (&full_path);
06622 goto failed;
06623 }
06624 else
06625 _dbus_string_free (&full_path);
06626 }
06627
06628 if (dbus_error_is_set (&error))
06629 {
06630 _dbus_warn ("Could not get next file in %s: %s\n",
06631 _dbus_string_get_const_data (&test_directory),
06632 error.message);
06633 dbus_error_free (&error);
06634 goto failed;
06635 }
06636
06637 retval = TRUE;
06638
06639 failed:
06640
06641 if (dir)
06642 _dbus_directory_close (dir);
06643 _dbus_string_free (&test_directory);
06644 _dbus_string_free (&filename);
06645
06646 return retval;
06647 }
06648
06658 dbus_bool_t
06659 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
06660 DBusForeachMessageFileFunc func,
06661 void *user_data)
06662 {
06663 DBusString test_directory;
06664 dbus_bool_t retval;
06665
06666 retval = FALSE;
06667
06668 _dbus_string_init_const (&test_directory, test_data_dir);
06669
06670 if (!process_test_subdir (&test_directory, "valid-messages",
06671 _DBUS_MESSAGE_VALID, func, user_data))
06672 goto failed;
06673
06674 if (!process_test_subdir (&test_directory, "invalid-messages",
06675 _DBUS_MESSAGE_INVALID, func, user_data))
06676 goto failed;
06677
06678 if (!process_test_subdir (&test_directory, "incomplete-messages",
06679 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
06680 goto failed;
06681
06682 retval = TRUE;
06683
06684 failed:
06685
06686 _dbus_string_free (&test_directory);
06687
06688 return retval;
06689 }
06690
06691 static void
06692 verify_test_message (DBusMessage *message)
06693 {
06694 DBusMessageIter iter, dict;
06695 DBusError error;
06696 dbus_int32_t our_int;
06697 char *our_str;
06698 double our_double;
06699 dbus_bool_t our_bool;
06700 dbus_uint32_t our_uint32;
06701 dbus_int32_t *our_uint32_array;
06702 int our_uint32_array_len;
06703 dbus_int32_t *our_int32_array;
06704 int our_int32_array_len;
06705 char **our_string_array;
06706 int our_string_array_len;
06707 #ifdef DBUS_HAVE_INT64
06708 dbus_int64_t our_int64;
06709 dbus_uint64_t our_uint64;
06710 dbus_int64_t *our_uint64_array;
06711 int our_uint64_array_len;
06712 dbus_int64_t *our_int64_array;
06713 int our_int64_array_len;
06714 #endif
06715 double *our_double_array;
06716 int our_double_array_len;
06717 unsigned char *our_byte_array;
06718 int our_byte_array_len;
06719 unsigned char *our_boolean_array;
06720 int our_boolean_array_len;
06721
06722 dbus_message_iter_init (message, &iter);
06723
06724 dbus_error_init (&error);
06725 if (!dbus_message_iter_get_args (&iter, &error,
06726 DBUS_TYPE_INT32, &our_int,
06727 #ifdef DBUS_HAVE_INT64
06728 DBUS_TYPE_INT64, &our_int64,
06729 DBUS_TYPE_UINT64, &our_uint64,
06730 #endif
06731 DBUS_TYPE_STRING, &our_str,
06732 DBUS_TYPE_DOUBLE, &our_double,
06733 DBUS_TYPE_BOOLEAN, &our_bool,
06734 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
06735 &our_uint32_array, &our_uint32_array_len,
06736 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
06737 &our_int32_array, &our_int32_array_len,
06738 #ifdef DBUS_HAVE_INT64
06739 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
06740 &our_uint64_array, &our_uint64_array_len,
06741 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
06742 &our_int64_array, &our_int64_array_len,
06743 #endif
06744 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
06745 &our_string_array, &our_string_array_len,
06746 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
06747 &our_double_array, &our_double_array_len,
06748 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
06749 &our_byte_array, &our_byte_array_len,
06750 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
06751 &our_boolean_array, &our_boolean_array_len,
06752 0))
06753 {
06754 _dbus_warn ("error: %s - %s\n", error.name,
06755 (error.message != NULL) ? error.message : "no message");
06756 _dbus_assert_not_reached ("Could not get arguments");
06757 }
06758
06759 if (our_int != -0x12345678)
06760 _dbus_assert_not_reached ("integers differ!");
06761
06762 #ifdef DBUS_HAVE_INT64
06763 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
06764 _dbus_assert_not_reached ("64-bit integers differ!");
06765 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
06766 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
06767 #endif
06768
06769 if (our_double != 3.14159)
06770 _dbus_assert_not_reached ("doubles differ!");
06771
06772 if (strcmp (our_str, "Test string") != 0)
06773 _dbus_assert_not_reached ("strings differ!");
06774 dbus_free (our_str);
06775
06776 if (!our_bool)
06777 _dbus_assert_not_reached ("booleans differ");
06778
06779 if (our_uint32_array_len != 4 ||
06780 our_uint32_array[0] != 0x12345678 ||
06781 our_uint32_array[1] != 0x23456781 ||
06782 our_uint32_array[2] != 0x34567812 ||
06783 our_uint32_array[3] != 0x45678123)
06784 _dbus_assert_not_reached ("uint array differs");
06785 dbus_free (our_uint32_array);
06786
06787 if (our_int32_array_len != 4 ||
06788 our_int32_array[0] != 0x12345678 ||
06789 our_int32_array[1] != -0x23456781 ||
06790 our_int32_array[2] != 0x34567812 ||
06791 our_int32_array[3] != -0x45678123)
06792 _dbus_assert_not_reached ("int array differs");
06793 dbus_free (our_int32_array);
06794
06795 #ifdef DBUS_HAVE_INT64
06796 if (our_uint64_array_len != 4 ||
06797 our_uint64_array[0] != 0x12345678 ||
06798 our_uint64_array[1] != 0x23456781 ||
06799 our_uint64_array[2] != 0x34567812 ||
06800 our_uint64_array[3] != 0x45678123)
06801 _dbus_assert_not_reached ("uint64 array differs");
06802 dbus_free (our_uint64_array);
06803
06804 if (our_int64_array_len != 4 ||
06805 our_int64_array[0] != 0x12345678 ||
06806 our_int64_array[1] != -0x23456781 ||
06807 our_int64_array[2] != 0x34567812 ||
06808 our_int64_array[3] != -0x45678123)
06809 _dbus_assert_not_reached ("int64 array differs");
06810 dbus_free (our_int64_array);
06811 #endif
06812
06813 if (our_string_array_len != 4)
06814 _dbus_assert_not_reached ("string array has wrong length");
06815
06816 if (strcmp (our_string_array[0], "Foo") != 0 ||
06817 strcmp (our_string_array[1], "bar") != 0 ||
06818 strcmp (our_string_array[2], "") != 0 ||
06819 strcmp (our_string_array[3], "woo woo woo woo") != 0)
06820 _dbus_assert_not_reached ("string array differs");
06821
06822 dbus_free_string_array (our_string_array);
06823
06824 if (our_double_array_len != 3)
06825 _dbus_assert_not_reached ("double array had wrong length");
06826
06827
06828
06829
06830 if (our_double_array[0] != 0.1234 ||
06831 our_double_array[1] != 9876.54321 ||
06832 our_double_array[2] != -300.0)
06833 _dbus_assert_not_reached ("double array had wrong values");
06834
06835 dbus_free (our_double_array);
06836
06837 if (our_byte_array_len != 4)
06838 _dbus_assert_not_reached ("byte array had wrong length");
06839
06840 if (our_byte_array[0] != 'a' ||
06841 our_byte_array[1] != 'b' ||
06842 our_byte_array[2] != 'c' ||
06843 our_byte_array[3] != 234)
06844 _dbus_assert_not_reached ("byte array had wrong values");
06845
06846 dbus_free (our_byte_array);
06847
06848 if (our_boolean_array_len != 5)
06849 _dbus_assert_not_reached ("bool array had wrong length");
06850
06851 if (our_boolean_array[0] != TRUE ||
06852 our_boolean_array[1] != FALSE ||
06853 our_boolean_array[2] != TRUE ||
06854 our_boolean_array[3] != TRUE ||
06855 our_boolean_array[4] != FALSE)
06856 _dbus_assert_not_reached ("bool array had wrong values");
06857
06858 dbus_free (our_boolean_array);
06859
06860 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06861 _dbus_assert_not_reached ("not dict type");
06862
06863 dbus_message_iter_init_dict_iterator (&iter, &dict);
06864
06865 our_str = dbus_message_iter_get_dict_key (&dict);
06866 if (our_str == NULL || strcmp (our_str, "test") != 0)
06867 _dbus_assert_not_reached ("wrong dict key");
06868 dbus_free (our_str);
06869
06870 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
06871 {
06872 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
06873 _dbus_assert_not_reached ("wrong dict entry type");
06874 }
06875
06876 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
06877 {
06878 _dbus_verbose ("dict entry val: %x\n", our_uint32);
06879 _dbus_assert_not_reached ("wrong dict entry value");
06880 }
06881
06882 if (dbus_message_iter_next (&dict))
06883 _dbus_assert_not_reached ("Didn't reach end of dict");
06884
06885 if (!dbus_message_iter_next (&iter))
06886 _dbus_assert_not_reached ("Reached end of arguments");
06887
06888 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
06889 _dbus_assert_not_reached ("wrong type after dict");
06890
06891 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
06892 _dbus_assert_not_reached ("wrong value after dict");
06893
06894 if (dbus_message_iter_next (&iter))
06895 _dbus_assert_not_reached ("Didn't reach end of arguments");
06896 }
06897
06904 dbus_bool_t
06905 _dbus_message_test (const char *test_data_dir)
06906 {
06907 DBusMessage *message;
06908 DBusMessageLoader *loader;
06909 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
06910 int i;
06911 const char *data;
06912 DBusMessage *copy;
06913 const char *name1;
06914 const char *name2;
06915 const dbus_uint32_t our_uint32_array[] =
06916 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06917 const dbus_uint32_t our_int32_array[] =
06918 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06919 #ifdef DBUS_HAVE_INT64
06920 const dbus_uint64_t our_uint64_array[] =
06921 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06922 const dbus_uint64_t our_int64_array[] =
06923 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06924 #endif
06925 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
06926 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
06927 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
06928 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
06929 char sig[64];
06930 const char *s;
06931 char *t;
06932 DBusError error;
06933
06934 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
06935
06936 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
06937 "/org/freedesktop/TestPath",
06938 "Foo.TestInterface",
06939 "TestMethod");
06940 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06941 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
06942 "TestMethod"));
06943 _dbus_assert (strcmp (dbus_message_get_path (message),
06944 "/org/freedesktop/TestPath") == 0);
06945 _dbus_message_set_serial (message, 1234);
06946
06947 if (!dbus_message_set_sender (message, "org.foo.bar1"))
06948 _dbus_assert_not_reached ("out of memory");
06949 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
06950 dbus_message_set_reply_serial (message, 5678);
06951 if (!dbus_message_set_sender (message, NULL))
06952 _dbus_assert_not_reached ("out of memory");
06953 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
06954 _dbus_assert (dbus_message_get_serial (message) == 1234);
06955 _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
06956 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06957
06958 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06959 dbus_message_set_no_reply (message, TRUE);
06960 _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
06961 dbus_message_set_no_reply (message, FALSE);
06962 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06963
06964
06965
06966 if (!dbus_message_set_path (message, "/foo"))
06967 _dbus_assert_not_reached ("out of memory");
06968 _dbus_assert (strcmp (dbus_message_get_path (message),
06969 "/foo") == 0);
06970
06971 if (!dbus_message_set_interface (message, "org.Foo"))
06972 _dbus_assert_not_reached ("out of memory");
06973 _dbus_assert (strcmp (dbus_message_get_interface (message),
06974 "org.Foo") == 0);
06975
06976 if (!dbus_message_set_member (message, "Bar"))
06977 _dbus_assert_not_reached ("out of memory");
06978 _dbus_assert (strcmp (dbus_message_get_member (message),
06979 "Bar") == 0);
06980
06981
06982 if (!dbus_message_set_path (message, "/foo/bar"))
06983 _dbus_assert_not_reached ("out of memory");
06984 _dbus_assert (strcmp (dbus_message_get_path (message),
06985 "/foo/bar") == 0);
06986
06987 if (!dbus_message_set_interface (message, "org.Foo.Bar"))
06988 _dbus_assert_not_reached ("out of memory");
06989 _dbus_assert (strcmp (dbus_message_get_interface (message),
06990 "org.Foo.Bar") == 0);
06991
06992 if (!dbus_message_set_member (message, "BarFoo"))
06993 _dbus_assert_not_reached ("out of memory");
06994 _dbus_assert (strcmp (dbus_message_get_member (message),
06995 "BarFoo") == 0);
06996
06997
06998
06999 if (!dbus_message_set_path (message, "/foo"))
07000 _dbus_assert_not_reached ("out of memory");
07001 _dbus_assert (strcmp (dbus_message_get_path (message),
07002 "/foo") == 0);
07003
07004 if (!dbus_message_set_interface (message, "org.Foo"))
07005 _dbus_assert_not_reached ("out of memory");
07006 _dbus_assert (strcmp (dbus_message_get_interface (message),
07007 "org.Foo") == 0);
07008
07009 if (!dbus_message_set_member (message, "Bar"))
07010 _dbus_assert_not_reached ("out of memory");
07011 _dbus_assert (strcmp (dbus_message_get_member (message),
07012 "Bar") == 0);
07013
07014 dbus_message_unref (message);
07015
07016
07017 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07018 "/org/freedesktop/TestPath",
07019 "Foo.TestInterface",
07020 "TestMethod");
07021 _dbus_message_set_serial (message, 1);
07022 dbus_message_append_args (message,
07023 DBUS_TYPE_INT32, -0x12345678,
07024 #ifdef DBUS_HAVE_INT64
07025 DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd),
07026 DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd),
07027 #endif
07028 DBUS_TYPE_STRING, "Test string",
07029 DBUS_TYPE_DOUBLE, 3.14159,
07030 DBUS_TYPE_BOOLEAN, TRUE,
07031 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
07032 _DBUS_N_ELEMENTS (our_uint32_array),
07033 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
07034 _DBUS_N_ELEMENTS (our_int32_array),
07035 #ifdef DBUS_HAVE_INT64
07036 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
07037 _DBUS_N_ELEMENTS (our_uint64_array),
07038 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
07039 _DBUS_N_ELEMENTS (our_int64_array),
07040 #endif
07041 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
07042 _DBUS_N_ELEMENTS (our_string_array),
07043 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
07044 _DBUS_N_ELEMENTS (our_double_array),
07045 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
07046 _DBUS_N_ELEMENTS (our_byte_array),
07047 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
07048 _DBUS_N_ELEMENTS (our_boolean_array),
07049 0);
07050
07051 dbus_message_append_iter_init (message, &iter);
07052 dbus_message_iter_append_dict (&iter, &child_iter);
07053 dbus_message_iter_append_dict_key (&child_iter, "test");
07054 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07055 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
07056
07057 i = 0;
07058 sig[i++] = DBUS_TYPE_INT32;
07059 #ifdef DBUS_HAVE_INT64
07060 sig[i++] = DBUS_TYPE_INT64;
07061 sig[i++] = DBUS_TYPE_UINT64;
07062 #endif
07063 sig[i++] = DBUS_TYPE_STRING;
07064 sig[i++] = DBUS_TYPE_DOUBLE;
07065 sig[i++] = DBUS_TYPE_BOOLEAN;
07066 sig[i++] = DBUS_TYPE_ARRAY;
07067 sig[i++] = DBUS_TYPE_UINT32;
07068 sig[i++] = DBUS_TYPE_ARRAY;
07069 sig[i++] = DBUS_TYPE_INT32;
07070 #ifdef DBUS_HAVE_INT64
07071 sig[i++] = DBUS_TYPE_ARRAY;
07072 sig[i++] = DBUS_TYPE_UINT64;
07073 sig[i++] = DBUS_TYPE_ARRAY;
07074 sig[i++] = DBUS_TYPE_INT64;
07075 #endif
07076 sig[i++] = DBUS_TYPE_ARRAY;
07077 sig[i++] = DBUS_TYPE_STRING;
07078 sig[i++] = DBUS_TYPE_ARRAY;
07079 sig[i++] = DBUS_TYPE_DOUBLE;
07080 sig[i++] = DBUS_TYPE_ARRAY;
07081 sig[i++] = DBUS_TYPE_BYTE;
07082 sig[i++] = DBUS_TYPE_ARRAY;
07083 sig[i++] = DBUS_TYPE_BOOLEAN;
07084 sig[i++] = DBUS_TYPE_DICT;
07085 sig[i++] = DBUS_TYPE_UINT32;
07086 sig[i++] = DBUS_TYPE_INVALID;
07087
07088 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
07089
07090 _dbus_verbose_bytes_of_string (&message->header, 0,
07091 _dbus_string_get_length (&message->header));
07092 _dbus_verbose_bytes_of_string (&message->body, 0,
07093 _dbus_string_get_length (&message->body));
07094
07095 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
07096 sig, dbus_message_get_signature (message));
07097
07098 s = dbus_message_get_signature (message);
07099
07100 _dbus_assert (dbus_message_has_signature (message, sig));
07101 _dbus_assert (strcmp (s, sig) == 0);
07102
07103 verify_test_message (message);
07104
07105 copy = dbus_message_copy (message);
07106
07107 _dbus_assert (message->client_serial == copy->client_serial);
07108 _dbus_assert (message->reply_serial == copy->reply_serial);
07109 _dbus_assert (message->header_padding == copy->header_padding);
07110
07111 _dbus_assert (_dbus_string_get_length (&message->header) ==
07112 _dbus_string_get_length (©->header));
07113
07114 _dbus_assert (_dbus_string_get_length (&message->body) ==
07115 _dbus_string_get_length (©->body));
07116
07117 verify_test_message (copy);
07118
07119 name1 = dbus_message_get_interface (message);
07120 name2 = dbus_message_get_interface (copy);
07121
07122 _dbus_assert (strcmp (name1, name2) == 0);
07123
07124 name1 = dbus_message_get_member (message);
07125 name2 = dbus_message_get_member (copy);
07126
07127 _dbus_assert (strcmp (name1, name2) == 0);
07128
07129 dbus_message_unref (message);
07130 dbus_message_unref (copy);
07131
07132 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07133 "/org/freedesktop/TestPath",
07134 "Foo.TestInterface",
07135 "TestMethod");
07136
07137 _dbus_message_set_serial (message, 1);
07138 dbus_message_set_reply_serial (message, 0x12345678);
07139
07140 dbus_message_append_iter_init (message, &iter);
07141 dbus_message_iter_append_string (&iter, "Test string");
07142 dbus_message_iter_append_int32 (&iter, -0x12345678);
07143 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
07144 dbus_message_iter_append_double (&iter, 3.14159);
07145
07146 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
07147 dbus_message_iter_append_double (&child_iter, 1.5);
07148 dbus_message_iter_append_double (&child_iter, 2.5);
07149
07150
07151 dbus_message_iter_append_dict (&iter, &child_iter);
07152 dbus_message_iter_append_dict_key (&child_iter, "test");
07153 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07154
07155
07156 dbus_message_iter_append_dict_key (&child_iter, "testdict");
07157 dbus_message_iter_append_dict (&child_iter, &child_iter2);
07158
07159 dbus_message_iter_append_dict_key (&child_iter2, "dictkey");
07160 dbus_message_iter_append_string (&child_iter2, "dictvalue");
07161
07162
07163 dbus_message_iter_append_dict_key (&child_iter, "array");
07164 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
07165 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07166 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
07167 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
07168 _dbus_warn ("next call expected to fail with wrong array type\n");
07169 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
07170 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07171 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
07172 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
07173 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
07174
07175 dbus_message_iter_append_byte (&iter, 0xF0);
07176
07177 dbus_message_iter_append_nil (&iter);
07178
07179 dbus_message_iter_append_custom (&iter, "MyTypeName",
07180 "data", 5);
07181
07182 dbus_message_iter_append_byte (&iter, 0xF0);
07183
07184 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_INT32);
07185
07186 dbus_message_iter_append_byte (&iter, 0xF0);
07187
07188 dbus_message_iter_append_dict (&iter, &child_iter);
07189
07190 dbus_message_iter_append_byte (&iter, 0xF0);
07191
07192 message_iter_test (message);
07193
07194
07195 _dbus_message_lock (message);
07196 loader = _dbus_message_loader_new ();
07197
07198
07199 _dbus_message_loader_ref (loader);
07200 _dbus_message_loader_unref (loader);
07201
07202
07203 data = _dbus_string_get_const_data (&message->header);
07204 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
07205 {
07206 DBusString *buffer;
07207
07208 _dbus_message_loader_get_buffer (loader, &buffer);
07209 _dbus_string_append_byte (buffer, data[i]);
07210 _dbus_message_loader_return_buffer (loader, buffer, 1);
07211 }
07212
07213
07214 data = _dbus_string_get_const_data (&message->body);
07215 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
07216 {
07217 DBusString *buffer;
07218
07219 _dbus_message_loader_get_buffer (loader, &buffer);
07220 _dbus_string_append_byte (buffer, data[i]);
07221 _dbus_message_loader_return_buffer (loader, buffer, 1);
07222 }
07223
07224 copy = dbus_message_copy (message);
07225 dbus_message_unref (message);
07226
07227
07228 if (!_dbus_message_loader_queue_messages (loader))
07229 _dbus_assert_not_reached ("no memory to queue messages");
07230
07231 if (_dbus_message_loader_get_is_corrupted (loader))
07232 _dbus_assert_not_reached ("message loader corrupted");
07233
07234 message = _dbus_message_loader_pop_message (loader);
07235 if (!message)
07236 _dbus_assert_not_reached ("received a NULL message");
07237
07238 if (dbus_message_get_reply_serial (message) != 0x12345678)
07239 _dbus_assert_not_reached ("reply serial fields differ");
07240
07241 message_iter_test (message);
07242
07243 dbus_message_unref (message);
07244 _dbus_message_loader_unref (loader);
07245
07246 message = dbus_message_new_method_return (copy);
07247 if (message == NULL)
07248 _dbus_assert_not_reached ("out of memory\n");
07249 dbus_message_unref (copy);
07250
07251 if (!dbus_message_append_args (message,
07252 DBUS_TYPE_STRING, "hello",
07253 DBUS_TYPE_INVALID))
07254 _dbus_assert_not_reached ("no memory");
07255
07256 if (!dbus_message_has_signature (message, "s"))
07257 _dbus_assert_not_reached ("method return has wrong signature");
07258
07259 dbus_error_init (&error);
07260 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
07261 &t, DBUS_TYPE_INVALID))
07262
07263 {
07264 _dbus_warn ("Failed to get expected string arg: %s\n", error.message);
07265 exit (1);
07266 }
07267 dbus_free (t);
07268
07269 dbus_message_unref (message);
07270
07271
07272 if (test_data_dir == NULL)
07273 return TRUE;
07274
07275 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
07276 (DBusForeachMessageFileFunc)
07277 dbus_internal_do_not_use_try_message_file,
07278 NULL);
07279 }
07280
07281 #endif