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, double *);
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 if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, int)))
03990 goto errorout;
03991 break;
03992 case DBUS_TYPE_BOOLEAN:
03993 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
03994 goto errorout;
03995 break;
03996 case DBUS_TYPE_INT32:
03997
03998
03999
04000 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
04001 goto errorout;
04002 break;
04003 case DBUS_TYPE_UINT32:
04004
04005
04006
04007 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
04008 goto errorout;
04009 break;
04010 #ifdef DBUS_HAVE_INT64
04011 case DBUS_TYPE_INT64:
04012 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
04013 goto errorout;
04014 break;
04015 case DBUS_TYPE_UINT64:
04016 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
04017 goto errorout;
04018 break;
04019 #endif
04020 case DBUS_TYPE_DOUBLE:
04021 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
04022 goto errorout;
04023 break;
04024 case DBUS_TYPE_STRING:
04025 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
04026 goto errorout;
04027 break;
04028 case DBUS_TYPE_OBJECT_PATH:
04029 if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
04030 goto errorout;
04031 break;
04032 case DBUS_TYPE_CUSTOM:
04033 {
04034 const char *name;
04035 unsigned char *data;
04036 int len;
04037
04038 name = va_arg (var_args, const char *);
04039 data = va_arg (var_args, unsigned char *);
04040 len = va_arg (var_args, int);
04041
04042 if (!dbus_message_iter_append_custom (&iter, name, data, len))
04043 goto errorout;
04044 break;
04045 }
04046 case DBUS_TYPE_ARRAY:
04047 {
04048 void *data;
04049 int len, type;
04050
04051 type = va_arg (var_args, int);
04052 data = va_arg (var_args, void *);
04053 len = va_arg (var_args, int);
04054
04055 switch (type)
04056 {
04057 case DBUS_TYPE_BYTE:
04058 case DBUS_TYPE_BOOLEAN:
04059 case DBUS_TYPE_INT32:
04060 case DBUS_TYPE_UINT32:
04061 #ifdef DBUS_HAVE_INT64
04062 case DBUS_TYPE_INT64:
04063 case DBUS_TYPE_UINT64:
04064 #endif
04065 case DBUS_TYPE_DOUBLE:
04066 if (!_dbus_message_iter_append_basic_array (&iter, type, data, len))
04067 goto errorout;
04068 break;
04069 case DBUS_TYPE_STRING:
04070 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
04071 goto errorout;
04072 break;
04073 case DBUS_TYPE_OBJECT_PATH:
04074 if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
04075 goto errorout;
04076 break;
04077 case DBUS_TYPE_NIL:
04078 case DBUS_TYPE_ARRAY:
04079 case DBUS_TYPE_CUSTOM:
04080 case DBUS_TYPE_DICT:
04081 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
04082 goto errorout;
04083 default:
04084 _dbus_warn ("Unknown field type %d\n", type);
04085 goto errorout;
04086 }
04087 }
04088 break;
04089
04090 case DBUS_TYPE_DICT:
04091 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
04092 goto errorout;
04093 default:
04094 _dbus_warn ("Unknown field type %d\n", type);
04095 goto errorout;
04096 }
04097
04098 type = va_arg (var_args, int);
04099 }
04100
04101 return TRUE;
04102
04103 errorout:
04104 return FALSE;
04105 }
04106
04115 dbus_bool_t
04116 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
04117 unsigned const char *value,
04118 int len)
04119 {
04120 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN,
04121 value, len);
04122 }
04123
04132 dbus_bool_t
04133 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
04134 const dbus_int32_t *value,
04135 int len)
04136 {
04137 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32,
04138 value, len);
04139 }
04140
04149 dbus_bool_t
04150 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
04151 const dbus_uint32_t *value,
04152 int len)
04153 {
04154 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32,
04155 value, len);
04156 }
04157
04158 #ifdef DBUS_HAVE_INT64
04159
04170 dbus_bool_t
04171 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
04172 const dbus_int64_t *value,
04173 int len)
04174 {
04175 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64,
04176 value, len);
04177 }
04178
04189 dbus_bool_t
04190 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
04191 const dbus_uint64_t *value,
04192 int len)
04193 {
04194 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64,
04195 value, len);
04196 }
04197 #endif
04198
04207 dbus_bool_t
04208 dbus_message_iter_append_double_array (DBusMessageIter *iter,
04209 const double *value,
04210 int len)
04211 {
04212 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE,
04213 value, len);
04214 }
04215
04224 dbus_bool_t
04225 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
04226 unsigned const char *value,
04227 int len)
04228 {
04229 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE,
04230 value, len);
04231 }
04232
04241 dbus_bool_t
04242 dbus_message_iter_append_string_array (DBusMessageIter *iter,
04243 const char **value,
04244 int len)
04245 {
04246 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04247
04248 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04249
04250 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
04251 return FALSE;
04252
04253 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04254 {
04255 _dbus_string_set_length (&real->message->body, real->pos);
04256 return FALSE;
04257 }
04258
04259 dbus_message_iter_append_done (real);
04260
04261 return TRUE;
04262 }
04263
04272 dbus_bool_t
04273 dbus_message_iter_append_object_path_array (DBusMessageIter *iter,
04274 const char **value,
04275 int len)
04276 {
04277 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04278
04279 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04280
04281 if (!append_array_type (real, DBUS_TYPE_OBJECT_PATH, NULL, NULL))
04282 return FALSE;
04283
04284 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04285 {
04286 _dbus_string_set_length (&real->message->body, real->pos);
04287 return FALSE;
04288 }
04289
04290 dbus_message_iter_append_done (real);
04291
04292 return TRUE;
04293 }
04294
04302 dbus_bool_t
04303 dbus_message_set_sender (DBusMessage *message,
04304 const char *sender)
04305 {
04306 _dbus_return_val_if_fail (message != NULL, FALSE);
04307 _dbus_return_val_if_fail (!message->locked, FALSE);
04308
04309 return set_string_field (message,
04310 DBUS_HEADER_FIELD_SENDER,
04311 DBUS_TYPE_STRING,
04312 sender);
04313 }
04314
04325 void
04326 dbus_message_set_no_reply (DBusMessage *message,
04327 dbus_bool_t no_reply)
04328 {
04329 char *header;
04330
04331 _dbus_return_if_fail (message != NULL);
04332 _dbus_return_if_fail (!message->locked);
04333
04334 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04335
04336 if (no_reply)
04337 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04338 else
04339 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04340 }
04341
04349 dbus_bool_t
04350 dbus_message_get_no_reply (DBusMessage *message)
04351 {
04352 const char *header;
04353
04354 _dbus_return_val_if_fail (message != NULL, FALSE);
04355
04356 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04357
04358 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
04359 }
04360
04361
04371 void
04372 dbus_message_set_auto_activation (DBusMessage *message,
04373 dbus_bool_t auto_activation)
04374 {
04375 char *header;
04376
04377 _dbus_return_if_fail (message != NULL);
04378 _dbus_return_if_fail (!message->locked);
04379
04380 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04381
04382 if (auto_activation)
04383 *header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04384 else
04385 *header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04386 }
04387
04395 dbus_bool_t
04396 dbus_message_get_auto_activation (DBusMessage *message)
04397 {
04398 const char *header;
04399
04400 _dbus_return_val_if_fail (message != NULL, FALSE);
04401
04402 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04403
04404 return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0;
04405 }
04406
04414 const char*
04415 dbus_message_get_sender (DBusMessage *message)
04416 {
04417 _dbus_return_val_if_fail (message != NULL, NULL);
04418
04419 return get_string_field (message,
04420 DBUS_HEADER_FIELD_SENDER,
04421 NULL);
04422 }
04423
04439 const char*
04440 dbus_message_get_signature (DBusMessage *message)
04441 {
04442 _dbus_return_val_if_fail (message != NULL, NULL);
04443
04444 return get_string_field (message,
04445 DBUS_HEADER_FIELD_SIGNATURE,
04446 NULL);
04447 }
04448
04449 static dbus_bool_t
04450 _dbus_message_has_type_interface_member (DBusMessage *message,
04451 int type,
04452 const char *interface,
04453 const char *method)
04454 {
04455 const char *n;
04456
04457 _dbus_assert (message != NULL);
04458 _dbus_assert (interface != NULL);
04459 _dbus_assert (method != NULL);
04460
04461 if (dbus_message_get_type (message) != type)
04462 return FALSE;
04463
04464
04465
04466
04467
04468 n = dbus_message_get_member (message);
04469
04470 if (n && strcmp (n, method) == 0)
04471 {
04472 n = dbus_message_get_interface (message);
04473
04474 if (n && strcmp (n, interface) == 0)
04475 return TRUE;
04476 }
04477
04478 return FALSE;
04479 }
04480
04493 dbus_bool_t
04494 dbus_message_is_method_call (DBusMessage *message,
04495 const char *interface,
04496 const char *method)
04497 {
04498 _dbus_return_val_if_fail (message != NULL, FALSE);
04499 _dbus_return_val_if_fail (interface != NULL, FALSE);
04500 _dbus_return_val_if_fail (method != NULL, FALSE);
04501
04502 return _dbus_message_has_type_interface_member (message,
04503 DBUS_MESSAGE_TYPE_METHOD_CALL,
04504 interface, method);
04505 }
04506
04519 dbus_bool_t
04520 dbus_message_is_signal (DBusMessage *message,
04521 const char *interface,
04522 const char *signal_name)
04523 {
04524 _dbus_return_val_if_fail (message != NULL, FALSE);
04525 _dbus_return_val_if_fail (interface != NULL, FALSE);
04526 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
04527
04528 return _dbus_message_has_type_interface_member (message,
04529 DBUS_MESSAGE_TYPE_SIGNAL,
04530 interface, signal_name);
04531 }
04532
04543 dbus_bool_t
04544 dbus_message_is_error (DBusMessage *message,
04545 const char *error_name)
04546 {
04547 const char *n;
04548
04549 _dbus_return_val_if_fail (message != NULL, FALSE);
04550 _dbus_return_val_if_fail (error_name != NULL, FALSE);
04551 _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE);
04552
04553 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04554 return FALSE;
04555
04556 n = dbus_message_get_error_name (message);
04557
04558 if (n && strcmp (n, error_name) == 0)
04559 return TRUE;
04560 else
04561 return FALSE;
04562 }
04563
04574 dbus_bool_t
04575 dbus_message_has_destination (DBusMessage *message,
04576 const char *service)
04577 {
04578 const char *s;
04579
04580 _dbus_return_val_if_fail (message != NULL, FALSE);
04581 _dbus_return_val_if_fail (service != NULL, FALSE);
04582
04583 s = dbus_message_get_destination (message);
04584
04585 if (s && strcmp (s, service) == 0)
04586 return TRUE;
04587 else
04588 return FALSE;
04589 }
04590
04605 dbus_bool_t
04606 dbus_message_has_sender (DBusMessage *message,
04607 const char *service)
04608 {
04609 const char *s;
04610
04611 _dbus_return_val_if_fail (message != NULL, FALSE);
04612 _dbus_return_val_if_fail (service != NULL, FALSE);
04613
04614 s = dbus_message_get_sender (message);
04615
04616 if (s && strcmp (s, service) == 0)
04617 return TRUE;
04618 else
04619 return FALSE;
04620 }
04621
04631 dbus_bool_t
04632 dbus_message_has_signature (DBusMessage *message,
04633 const char *signature)
04634 {
04635 const char *s;
04636
04637 _dbus_return_val_if_fail (message != NULL, FALSE);
04638 _dbus_return_val_if_fail (signature != NULL, FALSE);
04639
04640 s = dbus_message_get_signature (message);
04641
04642 if (s && strcmp (s, signature) == 0)
04643 return TRUE;
04644 else
04645 return FALSE;
04646 }
04647
04665 dbus_bool_t
04666 dbus_set_error_from_message (DBusError *error,
04667 DBusMessage *message)
04668 {
04669 char *str;
04670
04671 _dbus_return_val_if_fail (message != NULL, FALSE);
04672 _dbus_return_val_if_error_is_set (error, FALSE);
04673
04674 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04675 return FALSE;
04676
04677 str = NULL;
04678 dbus_message_get_args (message, NULL,
04679 DBUS_TYPE_STRING, &str,
04680 DBUS_TYPE_INVALID);
04681
04682 dbus_set_error (error, dbus_message_get_error_name (message),
04683 str ? "%s" : NULL, str);
04684
04685 dbus_free (str);
04686
04687 return TRUE;
04688 }
04689
04714
04715
04716
04717
04718
04722 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
04723
04728 struct DBusMessageLoader
04729 {
04730 int refcount;
04732 DBusString data;
04734 DBusList *messages;
04736 long max_message_size;
04738 unsigned int buffer_outstanding : 1;
04740 unsigned int corrupted : 1;
04741 };
04742
04753 #define INITIAL_LOADER_DATA_LEN 32
04754
04761 DBusMessageLoader*
04762 _dbus_message_loader_new (void)
04763 {
04764 DBusMessageLoader *loader;
04765
04766 loader = dbus_new0 (DBusMessageLoader, 1);
04767 if (loader == NULL)
04768 return NULL;
04769
04770 loader->refcount = 1;
04771
04772
04773
04774
04775 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
04776
04777 if (!_dbus_string_init (&loader->data))
04778 {
04779 dbus_free (loader);
04780 return NULL;
04781 }
04782
04783
04784 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
04785 _dbus_string_set_length (&loader->data, 0);
04786
04787 return loader;
04788 }
04789
04796 DBusMessageLoader *
04797 _dbus_message_loader_ref (DBusMessageLoader *loader)
04798 {
04799 loader->refcount += 1;
04800
04801 return loader;
04802 }
04803
04810 void
04811 _dbus_message_loader_unref (DBusMessageLoader *loader)
04812 {
04813 loader->refcount -= 1;
04814 if (loader->refcount == 0)
04815 {
04816 _dbus_list_foreach (&loader->messages,
04817 (DBusForeachFunction) dbus_message_unref,
04818 NULL);
04819 _dbus_list_clear (&loader->messages);
04820 _dbus_string_free (&loader->data);
04821 dbus_free (loader);
04822 }
04823 }
04824
04843 void
04844 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04845 DBusString **buffer)
04846 {
04847 _dbus_assert (!loader->buffer_outstanding);
04848
04849 *buffer = &loader->data;
04850
04851 loader->buffer_outstanding = TRUE;
04852 }
04853
04858 #define DBUS_MINIMUM_HEADER_SIZE 16
04859
04860 static dbus_bool_t
04861 decode_string_field (const DBusString *data,
04862 int field,
04863 HeaderField *header_field,
04864 DBusString *field_data,
04865 int pos,
04866 int type)
04867 {
04868 int string_data_pos;
04869
04870 _dbus_assert (header_field != NULL);
04871 _dbus_assert (field_data != NULL);
04872
04873 if (header_field->name_offset >= 0)
04874 {
04875 _dbus_verbose ("%s field provided twice\n",
04876 _dbus_header_field_to_string (field));
04877 return FALSE;
04878 }
04879
04880 if (type != DBUS_TYPE_STRING)
04881 {
04882 _dbus_verbose ("%s field has wrong type %s\n",
04883 _dbus_header_field_to_string (field),
04884 _dbus_type_to_string (type));
04885 return FALSE;
04886 }
04887
04888
04889
04890
04891
04892 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
04893 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
04894
04895 _dbus_string_init_const (field_data,
04896 _dbus_string_get_const_data (data) + string_data_pos);
04897
04898 header_field->name_offset = pos - 2;
04899 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
04900
04901 #if 0
04902 _dbus_verbose ("Found field %s at offset %d\n",
04903 _dbus_header_field_to_string (field),
04904 header_field->value_offset);
04905 #endif
04906
04907 return TRUE;
04908 }
04909
04910
04911
04912
04913
04914
04915 static dbus_bool_t
04916 decode_header_data (const DBusString *data,
04917 int header_len,
04918 int byte_order,
04919 int message_type,
04920 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
04921 int *message_padding)
04922 {
04923 DBusString field_data;
04924 int pos, new_pos;
04925 int i;
04926 int field;
04927 int type;
04928 dbus_bool_t signature_required;
04929
04930 if (header_len < 16)
04931 {
04932 _dbus_verbose ("Header length %d is too short\n", header_len);
04933 return FALSE;
04934 }
04935
04936 i = 0;
04937 while (i <= DBUS_HEADER_FIELD_LAST)
04938 {
04939 fields[i].name_offset = -1;
04940 fields[i].value_offset = -1;
04941 ++i;
04942 }
04943
04944 pos = 16;
04945 while (pos < header_len)
04946 {
04947 field = _dbus_string_get_byte (data, pos);
04948 if (field == DBUS_HEADER_FIELD_INVALID)
04949 break;
04950 pos++;
04951
04952 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
04953 {
04954 _dbus_verbose ("Failed to validate type of named header field pos = %d\n",
04955 pos);
04956 return FALSE;
04957 }
04958
04959 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
04960 {
04961 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n",
04962 pos);
04963 return FALSE;
04964 }
04965
04966 if (new_pos > header_len)
04967 {
04968 _dbus_verbose ("Named header field tries to extend beyond header length\n");
04969 return FALSE;
04970 }
04971
04972 switch (field)
04973 {
04974 case DBUS_HEADER_FIELD_DESTINATION:
04975 if (!decode_string_field (data, field, &fields[field],
04976 &field_data, pos, type))
04977 return FALSE;
04978
04979 if (!_dbus_string_validate_service (&field_data, 0,
04980 _dbus_string_get_length (&field_data)))
04981 {
04982 _dbus_verbose ("service field has invalid content \"%s\"\n",
04983 _dbus_string_get_const_data (&field_data));
04984 return FALSE;
04985 }
04986 break;
04987
04988 case DBUS_HEADER_FIELD_INTERFACE:
04989 if (!decode_string_field (data, field, &fields[field],
04990 &field_data, pos, type))
04991 return FALSE;
04992
04993 if (!_dbus_string_validate_interface (&field_data, 0,
04994 _dbus_string_get_length (&field_data)))
04995 {
04996 _dbus_verbose ("interface field has invalid content \"%s\"\n",
04997 _dbus_string_get_const_data (&field_data));
04998 return FALSE;
04999 }
05000
05001 if (_dbus_string_equal_c_str (&field_data,
05002 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
05003 {
05004 _dbus_verbose ("Message is on the local interface\n");
05005 return FALSE;
05006 }
05007 break;
05008
05009 case DBUS_HEADER_FIELD_MEMBER:
05010 if (!decode_string_field (data, field, &fields[field],
05011 &field_data, pos, type))
05012 return FALSE;
05013
05014 if (!_dbus_string_validate_member (&field_data, 0,
05015 _dbus_string_get_length (&field_data)))
05016 {
05017 _dbus_verbose ("member field has invalid content \"%s\"\n",
05018 _dbus_string_get_const_data (&field_data));
05019 return FALSE;
05020 }
05021 break;
05022
05023 case DBUS_HEADER_FIELD_ERROR_NAME:
05024 if (!decode_string_field (data, field, &fields[field],
05025 &field_data, pos, type))
05026 return FALSE;
05027
05028 if (!_dbus_string_validate_error_name (&field_data, 0,
05029 _dbus_string_get_length (&field_data)))
05030 {
05031 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
05032 _dbus_string_get_const_data (&field_data));
05033 return FALSE;
05034 }
05035 break;
05036
05037 case DBUS_HEADER_FIELD_SENDER:
05038 if (!decode_string_field (data, field, &fields[field],
05039 &field_data, pos, type))
05040 return FALSE;
05041
05042 if (!_dbus_string_validate_service (&field_data, 0,
05043 _dbus_string_get_length (&field_data)))
05044 {
05045 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
05046 _dbus_string_get_const_data (&field_data));
05047 return FALSE;
05048 }
05049 break;
05050
05051 case DBUS_HEADER_FIELD_PATH:
05052
05053
05054
05055
05056
05057
05058 if (fields[field].name_offset >= 0)
05059 {
05060 _dbus_verbose ("path field provided twice\n");
05061 return FALSE;
05062 }
05063 if (type != DBUS_TYPE_OBJECT_PATH)
05064 {
05065 _dbus_verbose ("path field has wrong type\n");
05066 return FALSE;
05067 }
05068
05069 fields[field].name_offset = pos - 2;
05070 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05071
05072
05073 {
05074 const char *s;
05075 s = _dbus_string_get_const_data_len (data,
05076 fields[field].value_offset,
05077 _dbus_string_get_length (data) -
05078 fields[field].value_offset);
05079 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
05080 {
05081 _dbus_verbose ("Message is on the local path\n");
05082 return FALSE;
05083 }
05084 }
05085
05086 _dbus_verbose ("Found path at offset %d\n",
05087 fields[field].value_offset);
05088 break;
05089
05090 case DBUS_HEADER_FIELD_REPLY_SERIAL:
05091 if (fields[field].name_offset >= 0)
05092 {
05093 _dbus_verbose ("reply field provided twice\n");
05094 return FALSE;
05095 }
05096
05097 if (type != DBUS_TYPE_UINT32)
05098 {
05099 _dbus_verbose ("reply field has wrong type\n");
05100 return FALSE;
05101 }
05102
05103 fields[field].name_offset = pos - 2;
05104 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05105
05106 _dbus_verbose ("Found reply serial %u at offset %d\n",
05107 _dbus_demarshal_uint32 (data,
05108 byte_order,
05109 fields[field].value_offset,
05110 NULL),
05111 fields[field].value_offset);
05112 break;
05113
05114 case DBUS_HEADER_FIELD_SIGNATURE:
05115 if (!decode_string_field (data, field, &fields[field],
05116 &field_data, pos, type))
05117 return FALSE;
05118
05119 #if 0
05120
05121 if (!_dbus_string_validate_signature (&field_data, 0,
05122 _dbus_string_get_length (&field_data)))
05123 {
05124 _dbus_verbose ("signature field has invalid content \"%s\"\n",
05125 _dbus_string_get_const_data (&field_data));
05126 return FALSE;
05127 }
05128 #endif
05129 break;
05130
05131 default:
05132 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
05133 field, pos);
05134 }
05135
05136 pos = new_pos;
05137 }
05138
05139 if (pos < header_len)
05140 {
05141
05142 if ((header_len - pos) >= 8)
05143 {
05144 _dbus_verbose ("too much header alignment padding\n");
05145 return FALSE;
05146 }
05147
05148 if (!_dbus_string_validate_nul (data,
05149 pos, (header_len - pos)))
05150 {
05151 _dbus_verbose ("header alignment padding is not nul\n");
05152 return FALSE;
05153 }
05154 }
05155
05156
05157 signature_required = TRUE;
05158
05159 switch (message_type)
05160 {
05161 case DBUS_MESSAGE_TYPE_SIGNAL:
05162 case DBUS_MESSAGE_TYPE_METHOD_CALL:
05163 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
05164 {
05165 _dbus_verbose ("No path field provided\n");
05166 return FALSE;
05167 }
05168
05169 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
05170 {
05171 _dbus_verbose ("No interface field provided\n");
05172 return FALSE;
05173 }
05174 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
05175 {
05176 _dbus_verbose ("No member field provided\n");
05177 return FALSE;
05178 }
05179 break;
05180 case DBUS_MESSAGE_TYPE_ERROR:
05181 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
05182 {
05183 _dbus_verbose ("No error-name field provided\n");
05184 return FALSE;
05185 }
05186 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05187 {
05188 _dbus_verbose ("No reply serial field provided in error\n");
05189 return FALSE;
05190 }
05191 break;
05192 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
05193 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05194 {
05195 _dbus_verbose ("No reply serial field provided in method return\n");
05196 return FALSE;
05197 }
05198 break;
05199 default:
05200
05201 signature_required = FALSE;
05202 break;
05203 }
05204
05205
05206 if (signature_required)
05207 {
05208 if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0)
05209 {
05210 _dbus_verbose ("No signature field provided\n");
05211 return FALSE;
05212 }
05213 }
05214
05215 if (message_padding)
05216 *message_padding = header_len - pos;
05217
05218 return TRUE;
05219 }
05220
05231 void
05232 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
05233 DBusString *buffer,
05234 int bytes_read)
05235 {
05236 _dbus_assert (loader->buffer_outstanding);
05237 _dbus_assert (buffer == &loader->data);
05238
05239 loader->buffer_outstanding = FALSE;
05240 }
05241
05242 static dbus_bool_t
05243 load_one_message (DBusMessageLoader *loader,
05244 int byte_order,
05245 int message_type,
05246 int header_len,
05247 int body_len)
05248 {
05249 DBusMessage *message;
05250 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
05251 int i;
05252 int next_arg;
05253 dbus_bool_t oom;
05254 int header_padding;
05255
05256 message = NULL;
05257 oom = FALSE;
05258
05259 #if 0
05260 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
05261 #endif
05262
05263 if (!decode_header_data (&loader->data,
05264 header_len, byte_order,
05265 message_type,
05266 fields, &header_padding))
05267 {
05268 _dbus_verbose ("Header was invalid\n");
05269 loader->corrupted = TRUE;
05270 goto failed;
05271 }
05272
05273 next_arg = header_len;
05274 while (next_arg < (header_len + body_len))
05275 {
05276 int type;
05277 int prev = next_arg;
05278
05279 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
05280 &type, &next_arg))
05281 {
05282 _dbus_verbose ("invalid typecode at offset %d\n", prev);
05283 loader->corrupted = TRUE;
05284 goto failed;
05285 }
05286
05287 if (!_dbus_marshal_validate_arg (&loader->data,
05288 byte_order,
05289 0,
05290 type, -1,
05291 next_arg,
05292 &next_arg))
05293 {
05294 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
05295 loader->corrupted = TRUE;
05296 goto failed;
05297 }
05298
05299 _dbus_assert (next_arg > prev);
05300 }
05301
05302 if (next_arg > (header_len + body_len))
05303 {
05304 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
05305 next_arg, header_len, body_len,
05306 header_len + body_len);
05307 loader->corrupted = TRUE;
05308 goto failed;
05309 }
05310
05311 message = dbus_message_new_empty_header ();
05312 if (message == NULL)
05313 {
05314 _dbus_verbose ("Failed to allocate empty message\n");
05315 oom = TRUE;
05316 goto failed;
05317 }
05318
05319 message->byte_order = byte_order;
05320 message->header_padding = header_padding;
05321
05322
05323 i = 0;
05324 while (i <= DBUS_HEADER_FIELD_LAST)
05325 {
05326 message->header_fields[i] = fields[i];
05327 ++i;
05328 }
05329
05330 if (!_dbus_list_append (&loader->messages, message))
05331 {
05332 _dbus_verbose ("Failed to append new message to loader queue\n");
05333 oom = TRUE;
05334 goto failed;
05335 }
05336
05337 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
05338 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
05339
05340 _dbus_assert (_dbus_string_get_length (&loader->data) >=
05341 (header_len + body_len));
05342
05343 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
05344 {
05345 _dbus_verbose ("Failed to move header into new message\n");
05346 oom = TRUE;
05347 goto failed;
05348 }
05349
05350 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
05351 {
05352 _dbus_verbose ("Failed to move body into new message\n");
05353
05354 oom = TRUE;
05355 goto failed;
05356 }
05357
05358 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
05359 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
05360
05361
05362
05363
05364 message->reply_serial = get_uint_field (message,
05365 DBUS_HEADER_FIELD_REPLY_SERIAL);
05366
05367 message->client_serial = _dbus_demarshal_uint32 (&message->header,
05368 message->byte_order,
05369 CLIENT_SERIAL_OFFSET,
05370 NULL);
05371 if (message->client_serial == 0 ||
05372 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0))
05373 {
05374 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n",
05375 message->client_serial,
05376 message->reply_serial);
05377
05378 loader->corrupted = TRUE;
05379 goto failed;
05380 }
05381
05382 _dbus_verbose ("Loaded message %p\n", message);
05383
05384 _dbus_assert (!oom);
05385 _dbus_assert (!loader->corrupted);
05386
05387 return TRUE;
05388
05389 failed:
05390
05391
05392
05393 if (message != NULL)
05394 {
05395
05396 if (_dbus_string_get_length (&message->body) > 0)
05397 {
05398 dbus_bool_t result;
05399
05400 result = _dbus_string_copy_len (&message->body, 0, body_len,
05401 &loader->data, 0);
05402
05403 _dbus_assert (result);
05404 }
05405
05406 if (_dbus_string_get_length (&message->header) > 0)
05407 {
05408 dbus_bool_t result;
05409
05410 result = _dbus_string_copy_len (&message->header, 0, header_len,
05411 &loader->data, 0);
05412
05413 _dbus_assert (result);
05414 }
05415
05416
05417 _dbus_list_remove_last (&loader->messages, message);
05418
05419 dbus_message_unref (message);
05420 }
05421
05422
05423 return !oom;
05424 }
05425
05439 dbus_bool_t
05440 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
05441 {
05442 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16)
05443 {
05444 const char *header_data;
05445 int byte_order, message_type, header_len, body_len;
05446 dbus_uint32_t header_len_unsigned, body_len_unsigned;
05447
05448 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
05449
05450 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
05451
05452 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
05453 {
05454 _dbus_verbose ("Message has protocol version %d ours is %d\n",
05455 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
05456 loader->corrupted = TRUE;
05457 return TRUE;
05458 }
05459
05460 byte_order = header_data[BYTE_ORDER_OFFSET];
05461
05462 if (byte_order != DBUS_LITTLE_ENDIAN &&
05463 byte_order != DBUS_BIG_ENDIAN)
05464 {
05465 _dbus_verbose ("Message with bad byte order '%c' received\n",
05466 byte_order);
05467 loader->corrupted = TRUE;
05468 return TRUE;
05469 }
05470
05471
05472
05473
05474 message_type = header_data[TYPE_OFFSET];
05475 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
05476 {
05477 _dbus_verbose ("Message with bad type '%d' received\n",
05478 message_type);
05479 loader->corrupted = TRUE;
05480 return TRUE;
05481 }
05482
05483 header_len_unsigned = _dbus_unpack_uint32 (byte_order,
05484 (const unsigned char *) header_data + 4);
05485 body_len_unsigned = _dbus_unpack_uint32 (byte_order,
05486 (const unsigned char *) header_data + 8);
05487
05488 if (header_len_unsigned < 16)
05489 {
05490 _dbus_verbose ("Message had broken too-small header length %u\n",
05491 header_len_unsigned);
05492 loader->corrupted = TRUE;
05493 return TRUE;
05494 }
05495
05496 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
05497 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
05498 {
05499 _dbus_verbose ("Header or body length too large (%u %u)\n",
05500 header_len_unsigned,
05501 body_len_unsigned);
05502 loader->corrupted = TRUE;
05503 return TRUE;
05504 }
05505
05506
05507
05508
05509 header_len = header_len_unsigned;
05510 body_len = body_len_unsigned;
05511
05512 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
05513 {
05514
05515 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
05516 header_len);
05517 loader->corrupted = TRUE;
05518 return TRUE;
05519 }
05520
05521 if (header_len + body_len > loader->max_message_size)
05522 {
05523 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
05524 header_len, body_len, loader->max_message_size);
05525 loader->corrupted = TRUE;
05526 return TRUE;
05527 }
05528
05529 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
05530 {
05531 if (!load_one_message (loader, byte_order, message_type,
05532 header_len, body_len))
05533 return FALSE;
05534 }
05535 else
05536 return TRUE;
05537 }
05538
05539 return TRUE;
05540 }
05541
05549 DBusMessage*
05550 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
05551 {
05552 if (loader->messages)
05553 return loader->messages->data;
05554 else
05555 return NULL;
05556 }
05557
05566 DBusMessage*
05567 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
05568 {
05569 return _dbus_list_pop_first (&loader->messages);
05570 }
05571
05580 DBusList*
05581 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
05582 {
05583 return _dbus_list_pop_first_link (&loader->messages);
05584 }
05585
05592 void
05593 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
05594 DBusList *link)
05595 {
05596 _dbus_list_prepend_link (&loader->messages, link);
05597 }
05598
05608 dbus_bool_t
05609 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
05610 {
05611 return loader->corrupted;
05612 }
05613
05620 void
05621 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
05622 long size)
05623 {
05624 if (size > MAX_SANE_MESSAGE_SIZE)
05625 {
05626 _dbus_verbose ("clamping requested max message size %ld to %d\n",
05627 size, MAX_SANE_MESSAGE_SIZE);
05628 size = MAX_SANE_MESSAGE_SIZE;
05629 }
05630 loader->max_message_size = size;
05631 }
05632
05639 long
05640 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
05641 {
05642 return loader->max_message_size;
05643 }
05644
05645 static DBusDataSlotAllocator slot_allocator;
05646 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
05647
05662 dbus_bool_t
05663 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
05664 {
05665 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05666 _DBUS_LOCK_NAME (message_slots),
05667 slot_p);
05668 }
05669
05681 void
05682 dbus_message_free_data_slot (dbus_int32_t *slot_p)
05683 {
05684 _dbus_return_if_fail (*slot_p >= 0);
05685
05686 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05687 }
05688
05702 dbus_bool_t
05703 dbus_message_set_data (DBusMessage *message,
05704 dbus_int32_t slot,
05705 void *data,
05706 DBusFreeFunction free_data_func)
05707 {
05708 DBusFreeFunction old_free_func;
05709 void *old_data;
05710 dbus_bool_t retval;
05711
05712 _dbus_return_val_if_fail (message != NULL, FALSE);
05713 _dbus_return_val_if_fail (slot >= 0, FALSE);
05714
05715 retval = _dbus_data_slot_list_set (&slot_allocator,
05716 &message->slot_list,
05717 slot, data, free_data_func,
05718 &old_free_func, &old_data);
05719
05720 if (retval)
05721 {
05722
05723 if (old_free_func)
05724 (* old_free_func) (old_data);
05725 }
05726
05727 return retval;
05728 }
05729
05738 void*
05739 dbus_message_get_data (DBusMessage *message,
05740 dbus_int32_t slot)
05741 {
05742 void *res;
05743
05744 _dbus_return_val_if_fail (message != NULL, NULL);
05745
05746 res = _dbus_data_slot_list_get (&slot_allocator,
05747 &message->slot_list,
05748 slot);
05749
05750 return res;
05751 }
05752
05766 int
05767 dbus_message_type_from_string (const char *type_str)
05768 {
05769 if (strcmp (type_str, "method_call") == 0)
05770 return DBUS_MESSAGE_TYPE_METHOD_CALL;
05771 if (strcmp (type_str, "method_return") == 0)
05772 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
05773 else if (strcmp (type_str, "signal") == 0)
05774 return DBUS_MESSAGE_TYPE_SIGNAL;
05775 else if (strcmp (type_str, "error") == 0)
05776 return DBUS_MESSAGE_TYPE_ERROR;
05777 else
05778 return DBUS_MESSAGE_TYPE_INVALID;
05779 }
05780
05782 #ifdef DBUS_BUILD_TESTS
05783 #include "dbus-test.h"
05784 #include <stdio.h>
05785 #include <stdlib.h>
05786
05787 static void
05788 message_iter_test (DBusMessage *message)
05789 {
05790 DBusMessageIter iter, dict, dict2, array, array2;
05791 char *str;
05792 unsigned char *data;
05793 dbus_int32_t *our_int_array;
05794 int len;
05795
05796 dbus_message_iter_init (message, &iter);
05797
05798
05799 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
05800 _dbus_assert_not_reached ("Argument type isn't string");
05801
05802 str = dbus_message_iter_get_string (&iter);
05803 if (strcmp (str, "Test string") != 0)
05804 _dbus_assert_not_reached ("Strings differ");
05805 dbus_free (str);
05806
05807 if (!dbus_message_iter_next (&iter))
05808 _dbus_assert_not_reached ("Reached end of arguments");
05809
05810
05811 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
05812 _dbus_assert_not_reached ("Argument type isn't int32");
05813
05814 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
05815 _dbus_assert_not_reached ("Signed integers differ");
05816
05817 if (!dbus_message_iter_next (&iter))
05818 _dbus_assert_not_reached ("Reached end of fields");
05819
05820
05821 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
05822 _dbus_assert_not_reached ("Argument type isn't int32");
05823
05824 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
05825 _dbus_assert_not_reached ("Unsigned integers differ");
05826
05827 if (!dbus_message_iter_next (&iter))
05828 _dbus_assert_not_reached ("Reached end of arguments");
05829
05830
05831 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
05832 _dbus_assert_not_reached ("Argument type isn't double");
05833
05834 if (dbus_message_iter_get_double (&iter) != 3.14159)
05835 _dbus_assert_not_reached ("Doubles differ");
05836
05837 if (!dbus_message_iter_next (&iter))
05838 _dbus_assert_not_reached ("Reached end of arguments");
05839
05840 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
05841 _dbus_assert_not_reached ("Argument type not an array");
05842
05843 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
05844 _dbus_assert_not_reached ("Array type not double");
05845
05846
05847 dbus_message_iter_init_array_iterator (&iter, &array, NULL);
05848
05849 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05850 _dbus_assert_not_reached ("Argument type isn't double");
05851
05852 if (dbus_message_iter_get_double (&array) != 1.5)
05853 _dbus_assert_not_reached ("Unsigned integers differ");
05854
05855 if (!dbus_message_iter_next (&array))
05856 _dbus_assert_not_reached ("Reached end of arguments");
05857
05858 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
05859 _dbus_assert_not_reached ("Argument type isn't double");
05860
05861 if (dbus_message_iter_get_double (&array) != 2.5)
05862 _dbus_assert_not_reached ("Unsigned integers differ");
05863
05864 if (dbus_message_iter_next (&array))
05865 _dbus_assert_not_reached ("Didn't reach end of arguments");
05866
05867 if (!dbus_message_iter_next (&iter))
05868 _dbus_assert_not_reached ("Reached end of arguments");
05869
05870
05871
05872
05873 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
05874 _dbus_assert_not_reached ("not dict type");
05875
05876 dbus_message_iter_init_dict_iterator (&iter, &dict);
05877
05878 str = dbus_message_iter_get_dict_key (&dict);
05879 if (str == NULL || strcmp (str, "test") != 0)
05880 _dbus_assert_not_reached ("wrong dict key");
05881 dbus_free (str);
05882
05883 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
05884 _dbus_assert_not_reached ("wrong dict entry type");
05885
05886 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
05887 _dbus_assert_not_reached ("wrong dict entry value");
05888
05889
05890
05891 if (!dbus_message_iter_next (&dict))
05892 _dbus_assert_not_reached ("reached end of dict");
05893
05894 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_DICT)
05895 _dbus_assert_not_reached ("not dict type");
05896
05897 dbus_message_iter_init_dict_iterator (&dict, &dict2);
05898
05899 str = dbus_message_iter_get_dict_key (&dict2);
05900 if (str == NULL || strcmp (str, "dictkey") != 0)
05901 _dbus_assert_not_reached ("wrong dict key");
05902 dbus_free (str);
05903
05904 if (dbus_message_iter_get_arg_type (&dict2) != DBUS_TYPE_STRING)
05905 _dbus_assert_not_reached ("wrong dict entry type");
05906
05907 str = dbus_message_iter_get_string (&dict2);
05908 if (str == NULL || strcmp (str, "dictvalue") != 0)
05909 _dbus_assert_not_reached ("wrong dict entry value");
05910 dbus_free (str);
05911
05912 if (dbus_message_iter_next (&dict2))
05913 _dbus_assert_not_reached ("didn't reach end of dict");
05914
05915 if (!dbus_message_iter_next (&dict))
05916 _dbus_assert_not_reached ("reached end of dict");
05917
05918
05919
05920 str = dbus_message_iter_get_dict_key (&dict);
05921 if (str == NULL || strcmp (str, "array") != 0)
05922 _dbus_assert_not_reached ("wrong dict key");
05923 dbus_free (str);
05924
05925 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
05926 _dbus_assert_not_reached ("Argument type not an array");
05927
05928 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
05929 _dbus_assert_not_reached ("Array type not array");
05930
05931 dbus_message_iter_init_array_iterator (&dict, &array, NULL);
05932
05933 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
05934 _dbus_assert_not_reached ("Argument type isn't array");
05935
05936 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05937 _dbus_assert_not_reached ("Array type not int32");
05938
05939 dbus_message_iter_init_array_iterator (&array, &array2, NULL);
05940
05941 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
05942 _dbus_assert_not_reached ("Argument type isn't int32");
05943
05944 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
05945 _dbus_assert_not_reached ("Signed integers differ");
05946
05947 if (!dbus_message_iter_next (&array2))
05948 _dbus_assert_not_reached ("Reached end of arguments");
05949
05950 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
05951 _dbus_assert_not_reached ("Signed integers differ");
05952
05953 if (dbus_message_iter_next (&array2))
05954 _dbus_assert_not_reached ("Didn't reached end of arguments");
05955
05956 if (!dbus_message_iter_next (&array))
05957 _dbus_assert_not_reached ("Reached end of arguments");
05958
05959 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
05960 _dbus_assert_not_reached ("Array type not int32");
05961
05962 if (!dbus_message_iter_get_int32_array (&array,
05963 &our_int_array,
05964 &len))
05965 _dbus_assert_not_reached ("couldn't get int32 array");
05966
05967 _dbus_assert (len == 3);
05968 _dbus_assert (our_int_array[0] == 0x34567812 &&
05969 our_int_array[1] == 0x45678123 &&
05970 our_int_array[2] == 0x56781234);
05971 dbus_free (our_int_array);
05972
05973 if (dbus_message_iter_next (&array))
05974 _dbus_assert_not_reached ("Didn't reach end of array");
05975
05976 if (dbus_message_iter_next (&dict))
05977 _dbus_assert_not_reached ("Didn't reach end of dict");
05978
05979 if (!dbus_message_iter_next (&iter))
05980 _dbus_assert_not_reached ("Reached end of arguments");
05981
05982 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
05983 {
05984 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
05985 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
05986 }
05987
05988 if (dbus_message_iter_get_byte (&iter) != 0xF0)
05989 _dbus_assert_not_reached ("wrong value after dict");
05990
05991
05992 if (!dbus_message_iter_next (&iter))
05993 _dbus_assert_not_reached ("Reached end of arguments");
05994
05995 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
05996 _dbus_assert_not_reached ("not a nil type");
05997
05998 if (!dbus_message_iter_next (&iter))
05999 _dbus_assert_not_reached ("Reached end of arguments");
06000
06001 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_CUSTOM)
06002 _dbus_assert_not_reached ("wrong type after dict");
06003
06004 if (!dbus_message_iter_get_custom (&iter, &str, &data, &len))
06005 _dbus_assert_not_reached ("failed to get custom type");
06006
06007 _dbus_assert (strcmp (str, "MyTypeName")==0);
06008 _dbus_assert (len == 5);
06009 _dbus_assert (strcmp (data, "data")==0);
06010 dbus_free (str);
06011 dbus_free (data);
06012
06013 if (!dbus_message_iter_next (&iter))
06014 _dbus_assert_not_reached ("Reached end of arguments");
06015
06016 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06017 _dbus_assert_not_reached ("wrong value after custom");
06018
06019 if (!dbus_message_iter_next (&iter))
06020 _dbus_assert_not_reached ("Reached end of arguments");
06021
06022 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
06023 _dbus_assert_not_reached ("no array");
06024
06025 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_INT32)
06026 _dbus_assert_not_reached ("Array type not int32");
06027
06028 if (dbus_message_iter_init_array_iterator (&iter, &array, NULL))
06029 _dbus_assert_not_reached ("non empty array");
06030
06031 if (!dbus_message_iter_next (&iter))
06032 _dbus_assert_not_reached ("Reached end of arguments");
06033
06034 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06035 _dbus_assert_not_reached ("wrong value after empty array");
06036
06037 if (!dbus_message_iter_next (&iter))
06038 _dbus_assert_not_reached ("Reached end of arguments");
06039
06040 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06041 _dbus_assert_not_reached ("non dict");
06042
06043 if (dbus_message_iter_init_dict_iterator (&iter, &dict))
06044 _dbus_assert_not_reached ("non empty dict");
06045
06046 if (!dbus_message_iter_next (&iter))
06047 _dbus_assert_not_reached ("Reached end of arguments");
06048
06049 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06050 _dbus_assert_not_reached ("wrong value after empty dict");
06051
06052 if (dbus_message_iter_next (&iter))
06053 _dbus_assert_not_reached ("Didn't reach end of arguments");
06054 }
06055
06056
06057 static dbus_bool_t
06058 check_message_handling_type (DBusMessageIter *iter,
06059 int type)
06060 {
06061 DBusMessageIter child_iter;
06062
06063 switch (type)
06064 {
06065 case DBUS_TYPE_NIL:
06066 break;
06067 case DBUS_TYPE_BYTE:
06068 dbus_message_iter_get_byte (iter);
06069 break;
06070 case DBUS_TYPE_BOOLEAN:
06071 dbus_message_iter_get_boolean (iter);
06072 break;
06073 case DBUS_TYPE_INT32:
06074 dbus_message_iter_get_int32 (iter);
06075 break;
06076 case DBUS_TYPE_UINT32:
06077 dbus_message_iter_get_uint32 (iter);
06078 break;
06079 case DBUS_TYPE_INT64:
06080 #ifdef DBUS_HAVE_INT64
06081 dbus_message_iter_get_int64 (iter);
06082 #endif
06083 break;
06084 case DBUS_TYPE_UINT64:
06085 #ifdef DBUS_HAVE_INT64
06086 dbus_message_iter_get_uint64 (iter);
06087 #endif
06088 break;
06089 case DBUS_TYPE_DOUBLE:
06090 dbus_message_iter_get_double (iter);
06091 break;
06092 case DBUS_TYPE_STRING:
06093 {
06094 char *str;
06095 str = dbus_message_iter_get_string (iter);
06096 if (str == NULL)
06097 {
06098 _dbus_warn ("NULL string in message\n");
06099 return FALSE;
06100 }
06101 dbus_free (str);
06102 }
06103 break;
06104 case DBUS_TYPE_CUSTOM:
06105 {
06106 char *name;
06107 unsigned char *data;
06108 int len;
06109
06110 if (!dbus_message_iter_get_custom (iter, &name, &data, &len))
06111 {
06112 _dbus_warn ("error reading name from custom type\n");
06113 return FALSE;
06114 }
06115 dbus_free (data);
06116 dbus_free (name);
06117 }
06118 break;
06119 case DBUS_TYPE_ARRAY:
06120 {
06121 int array_type;
06122
06123 dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type);
06124
06125 while (dbus_message_iter_has_next (&child_iter))
06126 {
06127 if (!check_message_handling_type (&child_iter, array_type))
06128 {
06129 _dbus_warn ("error in array element\n");
06130 return FALSE;
06131 }
06132
06133 if (!dbus_message_iter_next (&child_iter))
06134 break;
06135 }
06136 }
06137 break;
06138 case DBUS_TYPE_DICT:
06139 {
06140 int entry_type;
06141 char *key;
06142
06143 dbus_message_iter_init_dict_iterator (iter, &child_iter);
06144
06145 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
06146 {
06147 key = dbus_message_iter_get_dict_key (&child_iter);
06148 if (key == NULL)
06149 {
06150 _dbus_warn ("error reading dict key\n");
06151 return FALSE;
06152 }
06153 dbus_free (key);
06154
06155 if (!check_message_handling_type (&child_iter, entry_type))
06156 {
06157 _dbus_warn ("error in dict value\n");
06158 return FALSE;
06159 }
06160
06161 if (!dbus_message_iter_next (&child_iter))
06162 break;
06163 }
06164 }
06165 break;
06166
06167 default:
06168 _dbus_warn ("unknown type %d\n", type);
06169 return FALSE;
06170 break;
06171 }
06172 return TRUE;
06173 }
06174
06175
06176 static dbus_bool_t
06177 check_message_handling (DBusMessage *message)
06178 {
06179 DBusMessageIter iter;
06180 int type;
06181 dbus_bool_t retval;
06182 dbus_uint32_t client_serial;
06183
06184 retval = FALSE;
06185
06186 client_serial = dbus_message_get_serial (message);
06187
06188
06189 _dbus_marshal_set_uint32 (&message->header,
06190 message->byte_order,
06191 CLIENT_SERIAL_OFFSET,
06192 client_serial);
06193
06194 if (client_serial != dbus_message_get_serial (message))
06195 {
06196 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
06197 goto failed;
06198 }
06199
06200
06201
06202
06203
06204 dbus_message_iter_init (message, &iter);
06205 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
06206 {
06207 if (!check_message_handling_type (&iter, type))
06208 goto failed;
06209
06210 if (!dbus_message_iter_next (&iter))
06211 break;
06212 }
06213
06214 retval = TRUE;
06215
06216 failed:
06217 return retval;
06218 }
06219
06220 static dbus_bool_t
06221 check_have_valid_message (DBusMessageLoader *loader)
06222 {
06223 DBusMessage *message;
06224 dbus_bool_t retval;
06225
06226 message = NULL;
06227 retval = FALSE;
06228
06229 if (!_dbus_message_loader_queue_messages (loader))
06230 _dbus_assert_not_reached ("no memory to queue messages");
06231
06232 if (_dbus_message_loader_get_is_corrupted (loader))
06233 {
06234 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
06235 goto failed;
06236 }
06237
06238 message = _dbus_message_loader_pop_message (loader);
06239 if (message == NULL)
06240 {
06241 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
06242 goto failed;
06243 }
06244
06245 if (_dbus_string_get_length (&loader->data) > 0)
06246 {
06247 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
06248 goto failed;
06249 }
06250
06251
06252
06253
06254
06255 if (!check_message_handling (message))
06256 goto failed;
06257
06258 retval = TRUE;
06259
06260 failed:
06261 if (message)
06262 dbus_message_unref (message);
06263
06264 return retval;
06265 }
06266
06267 static dbus_bool_t
06268 check_invalid_message (DBusMessageLoader *loader)
06269 {
06270 dbus_bool_t retval;
06271
06272 retval = FALSE;
06273
06274 if (!_dbus_message_loader_queue_messages (loader))
06275 _dbus_assert_not_reached ("no memory to queue messages");
06276
06277 if (!_dbus_message_loader_get_is_corrupted (loader))
06278 {
06279 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
06280 goto failed;
06281 }
06282
06283 retval = TRUE;
06284
06285 failed:
06286 return retval;
06287 }
06288
06289 static dbus_bool_t
06290 check_incomplete_message (DBusMessageLoader *loader)
06291 {
06292 DBusMessage *message;
06293 dbus_bool_t retval;
06294
06295 message = NULL;
06296 retval = FALSE;
06297
06298 if (!_dbus_message_loader_queue_messages (loader))
06299 _dbus_assert_not_reached ("no memory to queue messages");
06300
06301 if (_dbus_message_loader_get_is_corrupted (loader))
06302 {
06303 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
06304 goto failed;
06305 }
06306
06307 message = _dbus_message_loader_pop_message (loader);
06308 if (message != NULL)
06309 {
06310 _dbus_warn ("loaded message that was expected to be incomplete\n");
06311 goto failed;
06312 }
06313
06314 retval = TRUE;
06315
06316 failed:
06317 if (message)
06318 dbus_message_unref (message);
06319 return retval;
06320 }
06321
06322 static dbus_bool_t
06323 check_loader_results (DBusMessageLoader *loader,
06324 DBusMessageValidity validity)
06325 {
06326 if (!_dbus_message_loader_queue_messages (loader))
06327 _dbus_assert_not_reached ("no memory to queue messages");
06328
06329 switch (validity)
06330 {
06331 case _DBUS_MESSAGE_VALID:
06332 return check_have_valid_message (loader);
06333 case _DBUS_MESSAGE_INVALID:
06334 return check_invalid_message (loader);
06335 case _DBUS_MESSAGE_INCOMPLETE:
06336 return check_incomplete_message (loader);
06337 case _DBUS_MESSAGE_UNKNOWN:
06338 return TRUE;
06339 }
06340
06341 _dbus_assert_not_reached ("bad DBusMessageValidity");
06342 return FALSE;
06343 }
06344
06345
06354 dbus_bool_t
06355 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
06356 dbus_bool_t is_raw,
06357 DBusString *data)
06358 {
06359 dbus_bool_t retval;
06360
06361 retval = FALSE;
06362
06363 if (is_raw)
06364 {
06365 DBusError error;
06366
06367 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
06368 dbus_error_init (&error);
06369 if (!_dbus_file_get_contents (data, filename, &error))
06370 {
06371 _dbus_warn ("Could not load message file %s: %s\n",
06372 _dbus_string_get_const_data (filename),
06373 error.message);
06374 dbus_error_free (&error);
06375 goto failed;
06376 }
06377 }
06378 else
06379 {
06380 if (!_dbus_message_data_load (data, filename))
06381 {
06382 _dbus_warn ("Could not load message file %s\n",
06383 _dbus_string_get_const_data (filename));
06384 goto failed;
06385 }
06386 }
06387
06388 retval = TRUE;
06389
06390 failed:
06391
06392 return retval;
06393 }
06394
06404 dbus_bool_t
06405 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
06406 dbus_bool_t is_raw,
06407 DBusMessageValidity expected_validity)
06408 {
06409 DBusString data;
06410 dbus_bool_t retval;
06411
06412 retval = FALSE;
06413
06414 if (!_dbus_string_init (&data))
06415 _dbus_assert_not_reached ("could not allocate string\n");
06416
06417 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
06418 &data))
06419 goto failed;
06420
06421 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
06422
06423 failed:
06424
06425 if (!retval)
06426 {
06427 if (_dbus_string_get_length (&data) > 0)
06428 _dbus_verbose_bytes_of_string (&data, 0,
06429 _dbus_string_get_length (&data));
06430
06431 _dbus_warn ("Failed message loader test on %s\n",
06432 _dbus_string_get_const_data (filename));
06433 }
06434
06435 _dbus_string_free (&data);
06436
06437 return retval;
06438 }
06439
06448 dbus_bool_t
06449 dbus_internal_do_not_use_try_message_data (const DBusString *data,
06450 DBusMessageValidity expected_validity)
06451 {
06452 DBusMessageLoader *loader;
06453 dbus_bool_t retval;
06454 int len;
06455 int i;
06456
06457 loader = NULL;
06458 retval = FALSE;
06459
06460
06461
06462 loader = _dbus_message_loader_new ();
06463
06464
06465 _dbus_message_loader_ref (loader);
06466 _dbus_message_loader_unref (loader);
06467 _dbus_message_loader_get_max_message_size (loader);
06468
06469 len = _dbus_string_get_length (data);
06470 for (i = 0; i < len; i++)
06471 {
06472 DBusString *buffer;
06473
06474 _dbus_message_loader_get_buffer (loader, &buffer);
06475 _dbus_string_append_byte (buffer,
06476 _dbus_string_get_byte (data, i));
06477 _dbus_message_loader_return_buffer (loader, buffer, 1);
06478 }
06479
06480 if (!check_loader_results (loader, expected_validity))
06481 goto failed;
06482
06483 _dbus_message_loader_unref (loader);
06484 loader = NULL;
06485
06486
06487
06488 loader = _dbus_message_loader_new ();
06489
06490 {
06491 DBusString *buffer;
06492
06493 _dbus_message_loader_get_buffer (loader, &buffer);
06494 _dbus_string_copy (data, 0, buffer,
06495 _dbus_string_get_length (buffer));
06496 _dbus_message_loader_return_buffer (loader, buffer, 1);
06497 }
06498
06499 if (!check_loader_results (loader, expected_validity))
06500 goto failed;
06501
06502 _dbus_message_loader_unref (loader);
06503 loader = NULL;
06504
06505
06506
06507 loader = _dbus_message_loader_new ();
06508
06509 len = _dbus_string_get_length (data);
06510 for (i = 0; i < len; i += 2)
06511 {
06512 DBusString *buffer;
06513
06514 _dbus_message_loader_get_buffer (loader, &buffer);
06515 _dbus_string_append_byte (buffer,
06516 _dbus_string_get_byte (data, i));
06517 if ((i+1) < len)
06518 _dbus_string_append_byte (buffer,
06519 _dbus_string_get_byte (data, i+1));
06520 _dbus_message_loader_return_buffer (loader, buffer, 1);
06521 }
06522
06523 if (!check_loader_results (loader, expected_validity))
06524 goto failed;
06525
06526 _dbus_message_loader_unref (loader);
06527 loader = NULL;
06528
06529 retval = TRUE;
06530
06531 failed:
06532
06533 if (loader)
06534 _dbus_message_loader_unref (loader);
06535
06536 return retval;
06537 }
06538
06539 static dbus_bool_t
06540 process_test_subdir (const DBusString *test_base_dir,
06541 const char *subdir,
06542 DBusMessageValidity validity,
06543 DBusForeachMessageFileFunc function,
06544 void *user_data)
06545 {
06546 DBusString test_directory;
06547 DBusString filename;
06548 DBusDirIter *dir;
06549 dbus_bool_t retval;
06550 DBusError error;
06551
06552 retval = FALSE;
06553 dir = NULL;
06554
06555 if (!_dbus_string_init (&test_directory))
06556 _dbus_assert_not_reached ("didn't allocate test_directory\n");
06557
06558 _dbus_string_init_const (&filename, subdir);
06559
06560 if (!_dbus_string_copy (test_base_dir, 0,
06561 &test_directory, 0))
06562 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
06563
06564 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
06565 _dbus_assert_not_reached ("couldn't allocate full path");
06566
06567 _dbus_string_free (&filename);
06568 if (!_dbus_string_init (&filename))
06569 _dbus_assert_not_reached ("didn't allocate filename string\n");
06570
06571 dbus_error_init (&error);
06572 dir = _dbus_directory_open (&test_directory, &error);
06573 if (dir == NULL)
06574 {
06575 _dbus_warn ("Could not open %s: %s\n",
06576 _dbus_string_get_const_data (&test_directory),
06577 error.message);
06578 dbus_error_free (&error);
06579 goto failed;
06580 }
06581
06582 printf ("Testing %s:\n", subdir);
06583
06584 next:
06585 while (_dbus_directory_get_next_file (dir, &filename, &error))
06586 {
06587 DBusString full_path;
06588 dbus_bool_t is_raw;
06589
06590 if (!_dbus_string_init (&full_path))
06591 _dbus_assert_not_reached ("couldn't init string");
06592
06593 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
06594 _dbus_assert_not_reached ("couldn't copy dir to full_path");
06595
06596 if (!_dbus_concat_dir_and_file (&full_path, &filename))
06597 _dbus_assert_not_reached ("couldn't concat file to dir");
06598
06599 if (_dbus_string_ends_with_c_str (&filename, ".message"))
06600 is_raw = FALSE;
06601 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
06602 is_raw = TRUE;
06603 else
06604 {
06605 _dbus_verbose ("Skipping non-.message file %s\n",
06606 _dbus_string_get_const_data (&filename));
06607 _dbus_string_free (&full_path);
06608 goto next;
06609 }
06610
06611 printf (" %s\n",
06612 _dbus_string_get_const_data (&filename));
06613
06614 _dbus_verbose (" expecting %s for %s\n",
06615 validity == _DBUS_MESSAGE_VALID ? "valid" :
06616 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
06617 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
06618 _dbus_string_get_const_data (&filename));
06619
06620 if (! (*function) (&full_path, is_raw, validity, user_data))
06621 {
06622 _dbus_string_free (&full_path);
06623 goto failed;
06624 }
06625 else
06626 _dbus_string_free (&full_path);
06627 }
06628
06629 if (dbus_error_is_set (&error))
06630 {
06631 _dbus_warn ("Could not get next file in %s: %s\n",
06632 _dbus_string_get_const_data (&test_directory),
06633 error.message);
06634 dbus_error_free (&error);
06635 goto failed;
06636 }
06637
06638 retval = TRUE;
06639
06640 failed:
06641
06642 if (dir)
06643 _dbus_directory_close (dir);
06644 _dbus_string_free (&test_directory);
06645 _dbus_string_free (&filename);
06646
06647 return retval;
06648 }
06649
06659 dbus_bool_t
06660 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
06661 DBusForeachMessageFileFunc func,
06662 void *user_data)
06663 {
06664 DBusString test_directory;
06665 dbus_bool_t retval;
06666
06667 retval = FALSE;
06668
06669 _dbus_string_init_const (&test_directory, test_data_dir);
06670
06671 if (!process_test_subdir (&test_directory, "valid-messages",
06672 _DBUS_MESSAGE_VALID, func, user_data))
06673 goto failed;
06674
06675 if (!process_test_subdir (&test_directory, "invalid-messages",
06676 _DBUS_MESSAGE_INVALID, func, user_data))
06677 goto failed;
06678
06679 if (!process_test_subdir (&test_directory, "incomplete-messages",
06680 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
06681 goto failed;
06682
06683 retval = TRUE;
06684
06685 failed:
06686
06687 _dbus_string_free (&test_directory);
06688
06689 return retval;
06690 }
06691
06692 static void
06693 verify_test_message (DBusMessage *message)
06694 {
06695 DBusMessageIter iter, dict;
06696 DBusError error;
06697 dbus_int32_t our_int;
06698 char *our_str;
06699 double our_double;
06700 dbus_bool_t our_bool;
06701 unsigned char our_byte_1, our_byte_2;
06702 dbus_uint32_t our_uint32;
06703 dbus_int32_t *our_uint32_array;
06704 int our_uint32_array_len;
06705 dbus_int32_t *our_int32_array;
06706 int our_int32_array_len;
06707 char **our_string_array;
06708 int our_string_array_len;
06709 #ifdef DBUS_HAVE_INT64
06710 dbus_int64_t our_int64;
06711 dbus_uint64_t our_uint64;
06712 dbus_int64_t *our_uint64_array;
06713 int our_uint64_array_len;
06714 dbus_int64_t *our_int64_array;
06715 int our_int64_array_len;
06716 #endif
06717 double *our_double_array;
06718 int our_double_array_len;
06719 unsigned char *our_byte_array;
06720 int our_byte_array_len;
06721 unsigned char *our_boolean_array;
06722 int our_boolean_array_len;
06723
06724 dbus_message_iter_init (message, &iter);
06725
06726 dbus_error_init (&error);
06727 if (!dbus_message_iter_get_args (&iter, &error,
06728 DBUS_TYPE_INT32, &our_int,
06729 #ifdef DBUS_HAVE_INT64
06730 DBUS_TYPE_INT64, &our_int64,
06731 DBUS_TYPE_UINT64, &our_uint64,
06732 #endif
06733 DBUS_TYPE_STRING, &our_str,
06734 DBUS_TYPE_DOUBLE, &our_double,
06735 DBUS_TYPE_BOOLEAN, &our_bool,
06736 DBUS_TYPE_BYTE, &our_byte_1,
06737 DBUS_TYPE_BYTE, &our_byte_2,
06738 DBUS_TYPE_NIL,
06739 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
06740 &our_uint32_array, &our_uint32_array_len,
06741 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
06742 &our_int32_array, &our_int32_array_len,
06743 #ifdef DBUS_HAVE_INT64
06744 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
06745 &our_uint64_array, &our_uint64_array_len,
06746 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
06747 &our_int64_array, &our_int64_array_len,
06748 #endif
06749 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
06750 &our_string_array, &our_string_array_len,
06751 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
06752 &our_double_array, &our_double_array_len,
06753 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
06754 &our_byte_array, &our_byte_array_len,
06755 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
06756 &our_boolean_array, &our_boolean_array_len,
06757 0))
06758 {
06759 _dbus_warn ("error: %s - %s\n", error.name,
06760 (error.message != NULL) ? error.message : "no message");
06761 _dbus_assert_not_reached ("Could not get arguments");
06762 }
06763
06764 if (our_int != -0x12345678)
06765 _dbus_assert_not_reached ("integers differ!");
06766
06767 #ifdef DBUS_HAVE_INT64
06768 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
06769 _dbus_assert_not_reached ("64-bit integers differ!");
06770 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
06771 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
06772 #endif
06773
06774 if (our_double != 3.14159)
06775 _dbus_assert_not_reached ("doubles differ!");
06776
06777 if (strcmp (our_str, "Test string") != 0)
06778 _dbus_assert_not_reached ("strings differ!");
06779 dbus_free (our_str);
06780
06781 if (!our_bool)
06782 _dbus_assert_not_reached ("booleans differ");
06783
06784 if (our_byte_1 != 42)
06785 _dbus_assert_not_reached ("bytes differ!");
06786
06787 if (our_byte_2 != 24)
06788 _dbus_assert_not_reached ("bytes differ!");
06789
06790 if (our_uint32_array_len != 4 ||
06791 our_uint32_array[0] != 0x12345678 ||
06792 our_uint32_array[1] != 0x23456781 ||
06793 our_uint32_array[2] != 0x34567812 ||
06794 our_uint32_array[3] != 0x45678123)
06795 _dbus_assert_not_reached ("uint array differs");
06796 dbus_free (our_uint32_array);
06797
06798 if (our_int32_array_len != 4 ||
06799 our_int32_array[0] != 0x12345678 ||
06800 our_int32_array[1] != -0x23456781 ||
06801 our_int32_array[2] != 0x34567812 ||
06802 our_int32_array[3] != -0x45678123)
06803 _dbus_assert_not_reached ("int array differs");
06804 dbus_free (our_int32_array);
06805
06806 #ifdef DBUS_HAVE_INT64
06807 if (our_uint64_array_len != 4 ||
06808 our_uint64_array[0] != 0x12345678 ||
06809 our_uint64_array[1] != 0x23456781 ||
06810 our_uint64_array[2] != 0x34567812 ||
06811 our_uint64_array[3] != 0x45678123)
06812 _dbus_assert_not_reached ("uint64 array differs");
06813 dbus_free (our_uint64_array);
06814
06815 if (our_int64_array_len != 4 ||
06816 our_int64_array[0] != 0x12345678 ||
06817 our_int64_array[1] != -0x23456781 ||
06818 our_int64_array[2] != 0x34567812 ||
06819 our_int64_array[3] != -0x45678123)
06820 _dbus_assert_not_reached ("int64 array differs");
06821 dbus_free (our_int64_array);
06822 #endif
06823
06824 if (our_string_array_len != 4)
06825 _dbus_assert_not_reached ("string array has wrong length");
06826
06827 if (strcmp (our_string_array[0], "Foo") != 0 ||
06828 strcmp (our_string_array[1], "bar") != 0 ||
06829 strcmp (our_string_array[2], "") != 0 ||
06830 strcmp (our_string_array[3], "woo woo woo woo") != 0)
06831 _dbus_assert_not_reached ("string array differs");
06832
06833 dbus_free_string_array (our_string_array);
06834
06835 if (our_double_array_len != 3)
06836 _dbus_assert_not_reached ("double array had wrong length");
06837
06838
06839
06840
06841 if (our_double_array[0] != 0.1234 ||
06842 our_double_array[1] != 9876.54321 ||
06843 our_double_array[2] != -300.0)
06844 _dbus_assert_not_reached ("double array had wrong values");
06845
06846 dbus_free (our_double_array);
06847
06848 if (our_byte_array_len != 4)
06849 _dbus_assert_not_reached ("byte array had wrong length");
06850
06851 if (our_byte_array[0] != 'a' ||
06852 our_byte_array[1] != 'b' ||
06853 our_byte_array[2] != 'c' ||
06854 our_byte_array[3] != 234)
06855 _dbus_assert_not_reached ("byte array had wrong values");
06856
06857 dbus_free (our_byte_array);
06858
06859 if (our_boolean_array_len != 5)
06860 _dbus_assert_not_reached ("bool array had wrong length");
06861
06862 if (our_boolean_array[0] != TRUE ||
06863 our_boolean_array[1] != FALSE ||
06864 our_boolean_array[2] != TRUE ||
06865 our_boolean_array[3] != TRUE ||
06866 our_boolean_array[4] != FALSE)
06867 _dbus_assert_not_reached ("bool array had wrong values");
06868
06869 dbus_free (our_boolean_array);
06870
06871 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06872 _dbus_assert_not_reached ("not dict type");
06873
06874 dbus_message_iter_init_dict_iterator (&iter, &dict);
06875
06876 our_str = dbus_message_iter_get_dict_key (&dict);
06877 if (our_str == NULL || strcmp (our_str, "test") != 0)
06878 _dbus_assert_not_reached ("wrong dict key");
06879 dbus_free (our_str);
06880
06881 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
06882 {
06883 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
06884 _dbus_assert_not_reached ("wrong dict entry type");
06885 }
06886
06887 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
06888 {
06889 _dbus_verbose ("dict entry val: %x\n", our_uint32);
06890 _dbus_assert_not_reached ("wrong dict entry value");
06891 }
06892
06893 if (dbus_message_iter_next (&dict))
06894 _dbus_assert_not_reached ("Didn't reach end of dict");
06895
06896 if (!dbus_message_iter_next (&iter))
06897 _dbus_assert_not_reached ("Reached end of arguments");
06898
06899 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
06900 _dbus_assert_not_reached ("wrong type after dict");
06901
06902 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
06903 _dbus_assert_not_reached ("wrong value after dict");
06904
06905 if (dbus_message_iter_next (&iter))
06906 _dbus_assert_not_reached ("Didn't reach end of arguments");
06907 }
06908
06915 dbus_bool_t
06916 _dbus_message_test (const char *test_data_dir)
06917 {
06918 DBusMessage *message;
06919 DBusMessageLoader *loader;
06920 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
06921 int i;
06922 const char *data;
06923 DBusMessage *copy;
06924 const char *name1;
06925 const char *name2;
06926 const dbus_uint32_t our_uint32_array[] =
06927 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06928 const dbus_uint32_t our_int32_array[] =
06929 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06930 #ifdef DBUS_HAVE_INT64
06931 const dbus_uint64_t our_uint64_array[] =
06932 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
06933 const dbus_uint64_t our_int64_array[] =
06934 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
06935 #endif
06936 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
06937 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
06938 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
06939 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
06940 char sig[64];
06941 const char *s;
06942 char *t;
06943 DBusError error;
06944
06945 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
06946
06947 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
06948 "/org/freedesktop/TestPath",
06949 "Foo.TestInterface",
06950 "TestMethod");
06951 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06952 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
06953 "TestMethod"));
06954 _dbus_assert (strcmp (dbus_message_get_path (message),
06955 "/org/freedesktop/TestPath") == 0);
06956 _dbus_message_set_serial (message, 1234);
06957
06958 if (!dbus_message_set_sender (message, "org.foo.bar1"))
06959 _dbus_assert_not_reached ("out of memory");
06960 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
06961 dbus_message_set_reply_serial (message, 5678);
06962 if (!dbus_message_set_sender (message, NULL))
06963 _dbus_assert_not_reached ("out of memory");
06964 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
06965 _dbus_assert (dbus_message_get_serial (message) == 1234);
06966 _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
06967 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
06968
06969 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06970 dbus_message_set_no_reply (message, TRUE);
06971 _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
06972 dbus_message_set_no_reply (message, FALSE);
06973 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
06974
06975
06976
06977 if (!dbus_message_set_path (message, "/foo"))
06978 _dbus_assert_not_reached ("out of memory");
06979 _dbus_assert (strcmp (dbus_message_get_path (message),
06980 "/foo") == 0);
06981
06982 if (!dbus_message_set_interface (message, "org.Foo"))
06983 _dbus_assert_not_reached ("out of memory");
06984 _dbus_assert (strcmp (dbus_message_get_interface (message),
06985 "org.Foo") == 0);
06986
06987 if (!dbus_message_set_member (message, "Bar"))
06988 _dbus_assert_not_reached ("out of memory");
06989 _dbus_assert (strcmp (dbus_message_get_member (message),
06990 "Bar") == 0);
06991
06992
06993 if (!dbus_message_set_path (message, "/foo/bar"))
06994 _dbus_assert_not_reached ("out of memory");
06995 _dbus_assert (strcmp (dbus_message_get_path (message),
06996 "/foo/bar") == 0);
06997
06998 if (!dbus_message_set_interface (message, "org.Foo.Bar"))
06999 _dbus_assert_not_reached ("out of memory");
07000 _dbus_assert (strcmp (dbus_message_get_interface (message),
07001 "org.Foo.Bar") == 0);
07002
07003 if (!dbus_message_set_member (message, "BarFoo"))
07004 _dbus_assert_not_reached ("out of memory");
07005 _dbus_assert (strcmp (dbus_message_get_member (message),
07006 "BarFoo") == 0);
07007
07008
07009
07010 if (!dbus_message_set_path (message, "/foo"))
07011 _dbus_assert_not_reached ("out of memory");
07012 _dbus_assert (strcmp (dbus_message_get_path (message),
07013 "/foo") == 0);
07014
07015 if (!dbus_message_set_interface (message, "org.Foo"))
07016 _dbus_assert_not_reached ("out of memory");
07017 _dbus_assert (strcmp (dbus_message_get_interface (message),
07018 "org.Foo") == 0);
07019
07020 if (!dbus_message_set_member (message, "Bar"))
07021 _dbus_assert_not_reached ("out of memory");
07022 _dbus_assert (strcmp (dbus_message_get_member (message),
07023 "Bar") == 0);
07024
07025 dbus_message_unref (message);
07026
07027
07028 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07029 "/org/freedesktop/TestPath",
07030 "Foo.TestInterface",
07031 "TestMethod");
07032 _dbus_message_set_serial (message, 1);
07033 dbus_message_append_args (message,
07034 DBUS_TYPE_INT32, -0x12345678,
07035 #ifdef DBUS_HAVE_INT64
07036 DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd),
07037 DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd),
07038 #endif
07039 DBUS_TYPE_STRING, "Test string",
07040 DBUS_TYPE_DOUBLE, 3.14159,
07041 DBUS_TYPE_BOOLEAN, TRUE,
07042 DBUS_TYPE_BYTE, (unsigned char) 42,
07043 DBUS_TYPE_BYTE, 24,
07044 DBUS_TYPE_NIL,
07045 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
07046 _DBUS_N_ELEMENTS (our_uint32_array),
07047 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
07048 _DBUS_N_ELEMENTS (our_int32_array),
07049 #ifdef DBUS_HAVE_INT64
07050 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
07051 _DBUS_N_ELEMENTS (our_uint64_array),
07052 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
07053 _DBUS_N_ELEMENTS (our_int64_array),
07054 #endif
07055 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
07056 _DBUS_N_ELEMENTS (our_string_array),
07057 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
07058 _DBUS_N_ELEMENTS (our_double_array),
07059 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
07060 _DBUS_N_ELEMENTS (our_byte_array),
07061 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
07062 _DBUS_N_ELEMENTS (our_boolean_array),
07063 0);
07064
07065 dbus_message_append_iter_init (message, &iter);
07066 dbus_message_iter_append_dict (&iter, &child_iter);
07067 dbus_message_iter_append_dict_key (&child_iter, "test");
07068 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07069 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
07070
07071 i = 0;
07072 sig[i++] = DBUS_TYPE_INT32;
07073 #ifdef DBUS_HAVE_INT64
07074 sig[i++] = DBUS_TYPE_INT64;
07075 sig[i++] = DBUS_TYPE_UINT64;
07076 #endif
07077 sig[i++] = DBUS_TYPE_STRING;
07078 sig[i++] = DBUS_TYPE_DOUBLE;
07079 sig[i++] = DBUS_TYPE_BOOLEAN;
07080 sig[i++] = DBUS_TYPE_BYTE;
07081 sig[i++] = DBUS_TYPE_BYTE;
07082 sig[i++] = DBUS_TYPE_NIL;
07083 sig[i++] = DBUS_TYPE_ARRAY;
07084 sig[i++] = DBUS_TYPE_UINT32;
07085 sig[i++] = DBUS_TYPE_ARRAY;
07086 sig[i++] = DBUS_TYPE_INT32;
07087 #ifdef DBUS_HAVE_INT64
07088 sig[i++] = DBUS_TYPE_ARRAY;
07089 sig[i++] = DBUS_TYPE_UINT64;
07090 sig[i++] = DBUS_TYPE_ARRAY;
07091 sig[i++] = DBUS_TYPE_INT64;
07092 #endif
07093 sig[i++] = DBUS_TYPE_ARRAY;
07094 sig[i++] = DBUS_TYPE_STRING;
07095 sig[i++] = DBUS_TYPE_ARRAY;
07096 sig[i++] = DBUS_TYPE_DOUBLE;
07097 sig[i++] = DBUS_TYPE_ARRAY;
07098 sig[i++] = DBUS_TYPE_BYTE;
07099 sig[i++] = DBUS_TYPE_ARRAY;
07100 sig[i++] = DBUS_TYPE_BOOLEAN;
07101 sig[i++] = DBUS_TYPE_DICT;
07102 sig[i++] = DBUS_TYPE_UINT32;
07103 sig[i++] = DBUS_TYPE_INVALID;
07104
07105 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
07106
07107 _dbus_verbose_bytes_of_string (&message->header, 0,
07108 _dbus_string_get_length (&message->header));
07109 _dbus_verbose_bytes_of_string (&message->body, 0,
07110 _dbus_string_get_length (&message->body));
07111
07112 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
07113 sig, dbus_message_get_signature (message));
07114
07115 s = dbus_message_get_signature (message);
07116
07117 _dbus_assert (dbus_message_has_signature (message, sig));
07118 _dbus_assert (strcmp (s, sig) == 0);
07119
07120 verify_test_message (message);
07121
07122 copy = dbus_message_copy (message);
07123
07124 _dbus_assert (message->client_serial == copy->client_serial);
07125 _dbus_assert (message->reply_serial == copy->reply_serial);
07126 _dbus_assert (message->header_padding == copy->header_padding);
07127
07128 _dbus_assert (_dbus_string_get_length (&message->header) ==
07129 _dbus_string_get_length (©->header));
07130
07131 _dbus_assert (_dbus_string_get_length (&message->body) ==
07132 _dbus_string_get_length (©->body));
07133
07134 verify_test_message (copy);
07135
07136 name1 = dbus_message_get_interface (message);
07137 name2 = dbus_message_get_interface (copy);
07138
07139 _dbus_assert (strcmp (name1, name2) == 0);
07140
07141 name1 = dbus_message_get_member (message);
07142 name2 = dbus_message_get_member (copy);
07143
07144 _dbus_assert (strcmp (name1, name2) == 0);
07145
07146 dbus_message_unref (message);
07147 dbus_message_unref (copy);
07148
07149 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07150 "/org/freedesktop/TestPath",
07151 "Foo.TestInterface",
07152 "TestMethod");
07153
07154 _dbus_message_set_serial (message, 1);
07155 dbus_message_set_reply_serial (message, 0x12345678);
07156
07157 dbus_message_append_iter_init (message, &iter);
07158 dbus_message_iter_append_string (&iter, "Test string");
07159 dbus_message_iter_append_int32 (&iter, -0x12345678);
07160 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
07161 dbus_message_iter_append_double (&iter, 3.14159);
07162
07163 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
07164 dbus_message_iter_append_double (&child_iter, 1.5);
07165 dbus_message_iter_append_double (&child_iter, 2.5);
07166
07167
07168 dbus_message_iter_append_dict (&iter, &child_iter);
07169 dbus_message_iter_append_dict_key (&child_iter, "test");
07170 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07171
07172
07173 dbus_message_iter_append_dict_key (&child_iter, "testdict");
07174 dbus_message_iter_append_dict (&child_iter, &child_iter2);
07175
07176 dbus_message_iter_append_dict_key (&child_iter2, "dictkey");
07177 dbus_message_iter_append_string (&child_iter2, "dictvalue");
07178
07179
07180 dbus_message_iter_append_dict_key (&child_iter, "array");
07181 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
07182 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07183 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
07184 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
07185 _dbus_warn ("next call expected to fail with wrong array type\n");
07186 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
07187 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07188 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
07189 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
07190 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
07191
07192 dbus_message_iter_append_byte (&iter, 0xF0);
07193
07194 dbus_message_iter_append_nil (&iter);
07195
07196 dbus_message_iter_append_custom (&iter, "MyTypeName",
07197 "data", 5);
07198
07199 dbus_message_iter_append_byte (&iter, 0xF0);
07200
07201 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_INT32);
07202
07203 dbus_message_iter_append_byte (&iter, 0xF0);
07204
07205 dbus_message_iter_append_dict (&iter, &child_iter);
07206
07207 dbus_message_iter_append_byte (&iter, 0xF0);
07208
07209 message_iter_test (message);
07210
07211
07212 _dbus_message_lock (message);
07213 loader = _dbus_message_loader_new ();
07214
07215
07216 _dbus_message_loader_ref (loader);
07217 _dbus_message_loader_unref (loader);
07218
07219
07220 data = _dbus_string_get_const_data (&message->header);
07221 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
07222 {
07223 DBusString *buffer;
07224
07225 _dbus_message_loader_get_buffer (loader, &buffer);
07226 _dbus_string_append_byte (buffer, data[i]);
07227 _dbus_message_loader_return_buffer (loader, buffer, 1);
07228 }
07229
07230
07231 data = _dbus_string_get_const_data (&message->body);
07232 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
07233 {
07234 DBusString *buffer;
07235
07236 _dbus_message_loader_get_buffer (loader, &buffer);
07237 _dbus_string_append_byte (buffer, data[i]);
07238 _dbus_message_loader_return_buffer (loader, buffer, 1);
07239 }
07240
07241 copy = dbus_message_copy (message);
07242 dbus_message_unref (message);
07243
07244
07245 if (!_dbus_message_loader_queue_messages (loader))
07246 _dbus_assert_not_reached ("no memory to queue messages");
07247
07248 if (_dbus_message_loader_get_is_corrupted (loader))
07249 _dbus_assert_not_reached ("message loader corrupted");
07250
07251 message = _dbus_message_loader_pop_message (loader);
07252 if (!message)
07253 _dbus_assert_not_reached ("received a NULL message");
07254
07255 if (dbus_message_get_reply_serial (message) != 0x12345678)
07256 _dbus_assert_not_reached ("reply serial fields differ");
07257
07258 message_iter_test (message);
07259
07260 dbus_message_unref (message);
07261 _dbus_message_loader_unref (loader);
07262
07263 message = dbus_message_new_method_return (copy);
07264 if (message == NULL)
07265 _dbus_assert_not_reached ("out of memory\n");
07266 dbus_message_unref (copy);
07267
07268 if (!dbus_message_append_args (message,
07269 DBUS_TYPE_STRING, "hello",
07270 DBUS_TYPE_INVALID))
07271 _dbus_assert_not_reached ("no memory");
07272
07273 if (!dbus_message_has_signature (message, "s"))
07274 _dbus_assert_not_reached ("method return has wrong signature");
07275
07276 dbus_error_init (&error);
07277 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
07278 &t, DBUS_TYPE_INVALID))
07279
07280 {
07281 _dbus_warn ("Failed to get expected string arg: %s\n", error.message);
07282 exit (1);
07283 }
07284 dbus_free (t);
07285
07286 dbus_message_unref (message);
07287
07288
07289 if (test_data_dir == NULL)
07290 return TRUE;
07291
07292 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
07293 (DBusForeachMessageFileFunc)
07294 dbus_internal_do_not_use_try_message_file,
07295 NULL);
07296 }
07297
07298 #endif