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 unsigned int locked : 1;
00101 DBusList *size_counters;
00102 long size_counter_delta;
00104 dbus_uint32_t changed_stamp;
00106 DBusDataSlotList slot_list;
00108 #ifndef DBUS_DISABLE_CHECKS
00109 int generation;
00110 #endif
00111 };
00112
00113 enum {
00114 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00115 DBUS_MESSAGE_ITER_TYPE_ARRAY,
00116 DBUS_MESSAGE_ITER_TYPE_DICT
00117 };
00118
00120 typedef struct DBusMessageRealIter DBusMessageRealIter;
00121
00127 struct DBusMessageRealIter
00128 {
00129 DBusMessageRealIter *parent_iter;
00130 DBusMessage *message;
00131 dbus_uint32_t changed_stamp;
00133
00134 int type;
00136 int pos;
00137 int end;
00138 int container_start;
00139 int container_length_pos;
00141 int wrote_dict_key;
00143 int array_type_pos;
00144 int array_type_done;
00145 };
00146
00157 void
00158 _dbus_message_get_network_data (DBusMessage *message,
00159 const DBusString **header,
00160 const DBusString **body)
00161 {
00162 _dbus_assert (message->locked);
00163
00164 *header = &message->header;
00165 *body = &message->body;
00166 }
00167
00168 static void
00169 clear_header_padding (DBusMessage *message)
00170 {
00171 _dbus_string_shorten (&message->header,
00172 message->header_padding);
00173 message->header_padding = 0;
00174 }
00175
00176 #ifdef DBUS_DISABLE_CHECKS
00177 #define is_valid_error_name(x) TRUE
00178 #else
00179 static dbus_bool_t
00180 is_valid_error_name (const char *error_name)
00181 {
00182 DBusString the_error_name;
00183
00184 if (error_name == NULL)
00185 return FALSE;
00186
00187 _dbus_string_init_const (&the_error_name, error_name);
00188 return _dbus_string_validate_error_name (&the_error_name, 0,
00189 _dbus_string_get_length (&the_error_name));
00190 }
00191 #endif
00192
00193 static dbus_bool_t
00194 append_header_padding (DBusMessage *message)
00195 {
00196 int old_len;
00197 old_len = _dbus_string_get_length (&message->header);
00198 if (!_dbus_string_align_length (&message->header, 8))
00199 return FALSE;
00200
00201 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00202
00203 return TRUE;
00204 }
00205
00206 #ifdef DBUS_BUILD_TESTS
00207
00208 static dbus_int32_t
00209 get_int_field (DBusMessage *message,
00210 int field)
00211 {
00212 int offset;
00213
00214 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00215
00216 offset = message->header_fields[field].value_offset;
00217
00218 if (offset < 0)
00219 return -1;
00220
00221 return _dbus_demarshal_int32 (&message->header,
00222 message->byte_order,
00223 offset,
00224 NULL);
00225 }
00226 #endif
00227
00228 static dbus_uint32_t
00229 get_uint_field (DBusMessage *message,
00230 int field)
00231 {
00232 int offset;
00233
00234 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00235
00236 offset = message->header_fields[field].value_offset;
00237
00238 if (offset < 0)
00239 return 0;
00240
00241 return _dbus_demarshal_uint32 (&message->header,
00242 message->byte_order,
00243 offset,
00244 NULL);
00245 }
00246
00247 static const char*
00248 get_string_field (DBusMessage *message,
00249 int field,
00250 int *len)
00251 {
00252 int offset;
00253 const char *data;
00254
00255 _dbus_return_val_if_fail (message->generation == _dbus_current_generation,
00256 NULL);
00257
00258 offset = message->header_fields[field].value_offset;
00259
00260 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00261
00262 if (offset < 0)
00263 return NULL;
00264
00265
00266
00267
00268
00269
00270 if (len)
00271 *len = _dbus_demarshal_uint32 (&message->header,
00272 message->byte_order,
00273 offset,
00274 NULL);
00275
00276 data = _dbus_string_get_const_data (&message->header);
00277
00278 return data + (offset + 4);
00279 }
00280
00281
00282 static dbus_bool_t
00283 get_path_field_decomposed (DBusMessage *message,
00284 int field,
00285 char ***path)
00286 {
00287 int offset;
00288
00289 offset = message->header_fields[field].value_offset;
00290
00291 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00292
00293 if (offset < 0)
00294 {
00295 *path = NULL;
00296 return TRUE;
00297 }
00298
00299 return _dbus_demarshal_object_path (&message->header,
00300 message->byte_order,
00301 offset,
00302 NULL,
00303 path, NULL);
00304 }
00305
00306 #ifdef DBUS_BUILD_TESTS
00307 static dbus_bool_t
00308 append_int_field (DBusMessage *message,
00309 int field,
00310 int value)
00311 {
00312 _dbus_assert (!message->locked);
00313
00314 clear_header_padding (message);
00315
00316 message->header_fields[field].name_offset =
00317 _dbus_string_get_length (&message->header);
00318
00319 if (!_dbus_string_append_byte (&message->header, field))
00320 goto failed;
00321
00322 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00323 goto failed;
00324
00325 if (!_dbus_string_align_length (&message->header, 4))
00326 goto failed;
00327
00328 message->header_fields[field].value_offset =
00329 _dbus_string_get_length (&message->header);
00330
00331 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00332 value))
00333 goto failed;
00334
00335 if (!append_header_padding (message))
00336 goto failed;
00337
00338 return TRUE;
00339
00340 failed:
00341 _dbus_string_set_length (&message->header,
00342 message->header_fields[field].name_offset);
00343 message->header_fields[field].name_offset = -1;
00344 message->header_fields[field].value_offset = -1;
00345
00346
00347
00348
00349 if (!append_header_padding (message))
00350 _dbus_assert_not_reached ("failed to reappend header padding");
00351 return FALSE;
00352 }
00353 #endif
00354
00355 static dbus_bool_t
00356 append_uint_field (DBusMessage *message,
00357 int field,
00358 int value)
00359 {
00360 _dbus_assert (!message->locked);
00361
00362 clear_header_padding (message);
00363
00364 message->header_fields[field].name_offset =
00365 _dbus_string_get_length (&message->header);
00366
00367 if (!_dbus_string_append_byte (&message->header, field))
00368 goto failed;
00369
00370 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00371 goto failed;
00372
00373 if (!_dbus_string_align_length (&message->header, 4))
00374 goto failed;
00375
00376 message->header_fields[field].value_offset =
00377 _dbus_string_get_length (&message->header);
00378
00379 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00380 value))
00381 goto failed;
00382
00383 if (!append_header_padding (message))
00384 goto failed;
00385
00386 return TRUE;
00387
00388 failed:
00389 _dbus_string_set_length (&message->header,
00390 message->header_fields[field].name_offset);
00391 message->header_fields[field].name_offset = -1;
00392 message->header_fields[field].value_offset = -1;
00393
00394
00395
00396
00397 if (!append_header_padding (message))
00398 _dbus_assert_not_reached ("failed to reappend header padding");
00399 return FALSE;
00400 }
00401
00405 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8)
00406
00407 static dbus_bool_t
00408 append_string_field_len (DBusMessage *message,
00409 int field,
00410 int type,
00411 const char *value,
00412 int value_len)
00413 {
00414 _dbus_assert (!message->locked);
00415
00416 clear_header_padding (message);
00417
00418 message->header_fields[field].name_offset =
00419 _dbus_string_get_length (&message->header);
00420
00421 if (!_dbus_string_append_byte (&message->header, field))
00422 goto failed;
00423
00424 if (!_dbus_string_append_byte (&message->header, type))
00425 goto failed;
00426
00427 if (!_dbus_string_align_length (&message->header, 4))
00428 goto failed;
00429
00430 message->header_fields[field].value_offset =
00431 _dbus_string_get_length (&message->header);
00432
00433 if (!_dbus_marshal_string_len (&message->header, message->byte_order,
00434 value, value_len))
00435 goto failed;
00436
00437 if (!append_header_padding (message))
00438 goto failed;
00439
00440 return TRUE;
00441
00442 failed:
00443 _dbus_string_set_length (&message->header,
00444 message->header_fields[field].name_offset);
00445 message->header_fields[field].name_offset = -1;
00446 message->header_fields[field].value_offset = -1;
00447
00448
00449
00450
00451 if (!append_header_padding (message))
00452 _dbus_assert_not_reached ("failed to reappend header padding");
00453
00454 return FALSE;
00455 }
00456
00457 static dbus_bool_t
00458 append_string_field (DBusMessage *message,
00459 int field,
00460 int type,
00461 const char *value)
00462 {
00463 int value_len;
00464
00465 value_len = strlen (value);
00466
00467 return append_string_field_len (message, field, type, value, value_len);
00468 }
00469
00470 static int
00471 get_type_alignment (int type)
00472 {
00473 int alignment;
00474
00475 switch (type)
00476 {
00477 case DBUS_TYPE_NIL:
00478 case DBUS_TYPE_BYTE:
00479 case DBUS_TYPE_BOOLEAN:
00480 alignment = 0;
00481 break;
00482
00483 case DBUS_TYPE_INT32:
00484 case DBUS_TYPE_UINT32:
00485 case DBUS_TYPE_STRING:
00486 case DBUS_TYPE_OBJECT_PATH:
00487
00488
00489
00490 case DBUS_TYPE_CUSTOM:
00491 case DBUS_TYPE_DICT:
00492 alignment = 4;
00493 break;
00494
00495 case DBUS_TYPE_INT64:
00496 case DBUS_TYPE_UINT64:
00497 case DBUS_TYPE_DOUBLE:
00498 alignment = 8;
00499 break;
00500
00501 case DBUS_TYPE_ARRAY:
00502 _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
00503 alignment = 0;
00504 break;
00505
00506 case DBUS_TYPE_INVALID:
00507 default:
00508 _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
00509 alignment = 0;
00510 break;
00511 }
00512
00513 return alignment;
00514 }
00515
00516 static dbus_bool_t
00517 iterate_one_field (const DBusString *str,
00518 int byte_order,
00519 int name_offset,
00520 int *next_offset_p,
00521 int *field_name_p,
00522 DBusString *append_copy_to,
00523 int *copy_name_offset_p,
00524 int *copy_value_offset_p)
00525 {
00526 int name, type, array_type;
00527 int alignment;
00528 int type_len;
00529 int type_pos;
00530 int value_pos;
00531 int value_len;
00532 int value_end;
00533 int pos;
00534
00535 #if 0
00536 _dbus_verbose ("%s: name_offset=%d, append to %p\n",
00537 _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
00538 #endif
00539
00540 pos = name_offset;
00541
00542 name = _dbus_string_get_byte (str, name_offset);
00543 pos++;
00544
00545 type_pos = pos;
00546 type = _dbus_string_get_byte (str, type_pos);
00547 pos++;
00548 type_len = 1;
00549
00550 array_type = type;
00551
00552 while (array_type == DBUS_TYPE_ARRAY)
00553 {
00554 pos++;
00555 type_len++;
00556 array_type = _dbus_string_get_byte (str, pos);
00557 }
00558
00559 #if 0
00560 _dbus_verbose ("%s: name %s, type '%c' %d at %d len %d, array type '%c' %d\n",
00561 _DBUS_FUNCTION_NAME,
00562 _dbus_header_field_to_string (name),
00563 type, type, type_pos, type_len, array_type, array_type);
00564 #endif
00565
00566 #ifndef DBUS_DISABLE_ASSERT
00567 if (!_dbus_type_is_valid (array_type))
00568 {
00569 _dbus_warn ("type '%c' %d is not valid in %s\n",
00570 array_type, array_type, _DBUS_FUNCTION_NAME);
00571 _dbus_assert_not_reached ("invalid type");
00572 }
00573 #endif
00574
00575 alignment = get_type_alignment (array_type);
00576
00577 if (alignment > 0)
00578 pos = _DBUS_ALIGN_VALUE (pos, alignment);
00579
00580 _dbus_verbose ("%s: alignment %d value at pos %d\n",
00581 _DBUS_FUNCTION_NAME, alignment, pos);
00582
00583
00584 if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
00585 type, pos, &value_end))
00586 _dbus_assert_not_reached ("failed to get the byte after this header");
00587
00588 value_pos = pos;
00589 value_len = value_end - value_pos;
00590
00591 _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
00592 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
00593
00594 if (next_offset_p)
00595 *next_offset_p = pos + value_len;
00596
00597 if (field_name_p)
00598 *field_name_p = name;
00599
00600 if (append_copy_to)
00601 {
00602 int orig_len;
00603
00604 orig_len = _dbus_string_get_length (append_copy_to);
00605
00606 if (copy_name_offset_p)
00607 *copy_name_offset_p = orig_len;
00608
00609 if (!_dbus_string_append_byte (append_copy_to, name))
00610 goto failed_copy;
00611
00612 if (!_dbus_string_copy_len (str, type_pos, type_len,
00613 append_copy_to,
00614 _dbus_string_get_length (append_copy_to)))
00615 goto failed_copy;
00616
00617 if (!_dbus_string_align_length (append_copy_to, alignment))
00618 goto failed_copy;
00619
00620 if (copy_value_offset_p)
00621 *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
00622
00623 if (!_dbus_string_copy_len (str, value_pos, value_len,
00624 append_copy_to,
00625 _dbus_string_get_length (append_copy_to)))
00626 goto failed_copy;
00627
00628 return TRUE;
00629
00630 failed_copy:
00631 _dbus_verbose ("%s: Failed copying old fields to new string\n",
00632 _DBUS_FUNCTION_NAME);
00633 _dbus_string_set_length (append_copy_to, orig_len);
00634 return FALSE;
00635 }
00636 else
00637 return TRUE;
00638 }
00639
00640 #ifndef DBUS_DISABLE_ASSERT
00641 static void
00642 verify_header_fields (DBusMessage *message)
00643 {
00644 int i;
00645 i = 0;
00646 while (i <= DBUS_HEADER_FIELD_LAST)
00647 {
00648 if (message->header_fields[i].name_offset >= 0)
00649 _dbus_assert (_dbus_string_get_byte (&message->header,
00650 message->header_fields[i].name_offset) ==
00651 i);
00652 ++i;
00653 }
00654 }
00655 #else
00656 #define verify_header_fields(x)
00657 #endif
00658
00659
00660
00661
00662 static dbus_bool_t
00663 delete_one_and_re_align (DBusMessage *message,
00664 int name_offset_to_delete)
00665 {
00666 DBusString copy;
00667 int new_fields_front_padding;
00668 int next_offset;
00669 int field_name;
00670 dbus_bool_t retval;
00671 HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST+1];
00672
00673 _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
00674 verify_header_fields (message);
00675
00676 _dbus_verbose ("%s: Deleting one field at offset %d\n",
00677 _DBUS_FUNCTION_NAME,
00678 name_offset_to_delete);
00679
00680 retval = FALSE;
00681
00682 clear_header_padding (message);
00683
00684 if (!_dbus_string_init_preallocated (©,
00685 _dbus_string_get_length (&message->header) -
00686 name_offset_to_delete + 8))
00687 {
00688 _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
00689 _DBUS_FUNCTION_NAME);
00690 goto out_0;
00691 }
00692
00693
00694
00695
00696 new_fields_front_padding = name_offset_to_delete % 8;
00697
00698 if (!_dbus_string_insert_bytes (©, 0, new_fields_front_padding,
00699 '\0'))
00700 _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
00701
00702 memcpy (new_header_fields, message->header_fields,
00703 sizeof (new_header_fields));
00704
00705
00706
00707
00708
00709
00710
00711 if (!iterate_one_field (&message->header,
00712 message->byte_order,
00713 name_offset_to_delete,
00714 &next_offset,
00715 &field_name, NULL, NULL, NULL))
00716 _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
00717
00718 _dbus_verbose (" Skipping %s field which will be deleted; next_offset = %d\n",
00719 _dbus_header_field_to_string (field_name), next_offset);
00720
00721
00722 if (field_name <= DBUS_HEADER_FIELD_LAST)
00723 {
00724 new_header_fields[field_name].name_offset = -1;
00725 new_header_fields[field_name].value_offset = -1;
00726 }
00727
00728 while (next_offset < _dbus_string_get_length (&message->header))
00729 {
00730 int copy_name_offset;
00731 int copy_value_offset;
00732
00733 if (!iterate_one_field (&message->header,
00734 message->byte_order,
00735 next_offset,
00736 &next_offset,
00737 &field_name,
00738 ©,
00739 ©_name_offset,
00740 ©_value_offset))
00741 {
00742 _dbus_verbose ("%s: OOM iterating one field\n",
00743 _DBUS_FUNCTION_NAME);
00744 goto out_1;
00745 }
00746
00747 if (field_name <= DBUS_HEADER_FIELD_LAST)
00748 {
00749 new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
00750 new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
00751
00752 _dbus_verbose (" Re-adding %s field at name_offset = %d value_offset = %d; next_offset = %d\n",
00753 _dbus_header_field_to_string (field_name),
00754 new_header_fields[field_name].name_offset,
00755 new_header_fields[field_name].value_offset,
00756 next_offset);
00757 }
00758 }
00759
00760 if (!_dbus_string_replace_len (©,
00761 new_fields_front_padding,
00762 _dbus_string_get_length (©) - new_fields_front_padding,
00763 &message->header,
00764 name_offset_to_delete,
00765 _dbus_string_get_length (&message->header) - name_offset_to_delete))
00766 {
00767 _dbus_verbose ("%s: OOM moving copy back into header\n",
00768 _DBUS_FUNCTION_NAME);
00769 goto out_1;
00770 }
00771
00772 memcpy (message->header_fields, new_header_fields,
00773 sizeof (new_header_fields));
00774 verify_header_fields (message);
00775
00776 retval = TRUE;
00777
00778 out_1:
00779 _dbus_string_free (©);
00780
00781 out_0:
00782 if (!append_header_padding (message))
00783 _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
00784
00785 return retval;
00786 }
00787
00788 static dbus_bool_t
00789 delete_field (DBusMessage *message,
00790 int field,
00791 int prealloc_header_space)
00792 {
00793 int offset;
00794
00795 _dbus_assert (!message->locked);
00796
00797
00798 if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
00799 {
00800 _dbus_verbose ("failed to prealloc %d bytes header space\n",
00801 prealloc_header_space);
00802 return FALSE;
00803 }
00804 _dbus_string_shorten (&message->header, prealloc_header_space);
00805
00806
00807 offset = message->header_fields[field].name_offset;
00808 if (offset < 0)
00809 {
00810 _dbus_verbose ("header field didn't exist, no need to delete\n");
00811 return TRUE;
00812 }
00813
00814 return delete_one_and_re_align (message, offset);
00815 }
00816
00817 #ifdef DBUS_BUILD_TESTS
00818 static dbus_bool_t
00819 set_int_field (DBusMessage *message,
00820 int field,
00821 int value)
00822 {
00823 int offset = message->header_fields[field].value_offset;
00824
00825 _dbus_assert (!message->locked);
00826
00827 _dbus_verbose ("set_int_field() field %d value '%d'\n",
00828 field, value);
00829
00830 if (offset < 0)
00831 {
00832
00833 return append_int_field (message, field, value);
00834 }
00835 else
00836 {
00837 _dbus_marshal_set_int32 (&message->header,
00838 message->byte_order,
00839 offset, value);
00840
00841 return TRUE;
00842 }
00843 }
00844 #endif
00845
00846 static dbus_bool_t
00847 set_uint_field (DBusMessage *message,
00848 int field,
00849 dbus_uint32_t value)
00850 {
00851 int offset = message->header_fields[field].value_offset;
00852
00853 _dbus_assert (!message->locked);
00854
00855 _dbus_verbose ("set_uint_field() field %d value '%u'\n",
00856 field, value);
00857
00858 if (offset < 0)
00859 {
00860
00861 return append_uint_field (message, field, value);
00862 }
00863 else
00864 {
00865 _dbus_marshal_set_uint32 (&message->header,
00866 message->byte_order,
00867 offset, value);
00868
00869 return TRUE;
00870 }
00871 }
00872
00873 static dbus_bool_t
00874 set_string_field (DBusMessage *message,
00875 int field,
00876 int type,
00877 const char *value)
00878 {
00879 int prealloc;
00880 int value_len;
00881
00882 _dbus_assert (!message->locked);
00883
00884 value_len = value ? strlen (value) : 0;
00885
00886
00887
00888
00889 prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
00890
00891 _dbus_verbose ("set_string_field() field %d prealloc %d value '%s'\n",
00892 field, prealloc, value);
00893
00894 if (!delete_field (message, field, prealloc))
00895 return FALSE;
00896
00897 if (value != NULL)
00898 {
00899
00900 if (!append_string_field_len (message, field, type, value, value_len))
00901 _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
00902 }
00903
00904 return TRUE;
00905 }
00906
00914 void
00915 _dbus_message_set_serial (DBusMessage *message,
00916 dbus_int32_t serial)
00917 {
00918 _dbus_assert (!message->locked);
00919 _dbus_assert (dbus_message_get_serial (message) == 0);
00920
00921 _dbus_marshal_set_uint32 (&message->header,
00922 message->byte_order,
00923 CLIENT_SERIAL_OFFSET,
00924 serial);
00925
00926 message->client_serial = serial;
00927 }
00928
00937 dbus_bool_t
00938 dbus_message_set_reply_serial (DBusMessage *message,
00939 dbus_uint32_t reply_serial)
00940 {
00941 _dbus_assert (!message->locked);
00942
00943 if (set_uint_field (message,
00944 DBUS_HEADER_FIELD_REPLY_SERIAL,
00945 reply_serial))
00946 {
00947 message->reply_serial = reply_serial;
00948 return TRUE;
00949 }
00950 else
00951 return FALSE;
00952 }
00953
00964 dbus_uint32_t
00965 dbus_message_get_serial (DBusMessage *message)
00966 {
00967 return message->client_serial;
00968 }
00969
00976 dbus_uint32_t
00977 dbus_message_get_reply_serial (DBusMessage *message)
00978 {
00979 return message->reply_serial;
00980 }
00981
00994 void
00995 _dbus_message_add_size_counter_link (DBusMessage *message,
00996 DBusList *link)
00997 {
00998
00999
01000
01001
01002
01003
01004 if (message->size_counters == NULL)
01005 {
01006 message->size_counter_delta =
01007 _dbus_string_get_length (&message->header) +
01008 _dbus_string_get_length (&message->body);
01009
01010 #if 0
01011 _dbus_verbose ("message has size %ld\n",
01012 message->size_counter_delta);
01013 #endif
01014 }
01015
01016 _dbus_list_append_link (&message->size_counters, link);
01017
01018 _dbus_counter_adjust (link->data, message->size_counter_delta);
01019 }
01020
01030 dbus_bool_t
01031 _dbus_message_add_size_counter (DBusMessage *message,
01032 DBusCounter *counter)
01033 {
01034 DBusList *link;
01035
01036 link = _dbus_list_alloc_link (counter);
01037 if (link == NULL)
01038 return FALSE;
01039
01040 _dbus_counter_ref (counter);
01041 _dbus_message_add_size_counter_link (message, link);
01042
01043 return TRUE;
01044 }
01045
01054 void
01055 _dbus_message_remove_size_counter (DBusMessage *message,
01056 DBusCounter *counter,
01057 DBusList **link_return)
01058 {
01059 DBusList *link;
01060
01061 link = _dbus_list_find_last (&message->size_counters,
01062 counter);
01063 _dbus_assert (link != NULL);
01064
01065 _dbus_list_unlink (&message->size_counters,
01066 link);
01067 if (link_return)
01068 *link_return = link;
01069 else
01070 _dbus_list_free_link (link);
01071
01072 _dbus_counter_adjust (counter, - message->size_counter_delta);
01073
01074 _dbus_counter_unref (counter);
01075 }
01076
01077 static dbus_bool_t
01078 dbus_message_create_header (DBusMessage *message,
01079 int type,
01080 const char *service,
01081 const char *path,
01082 const char *interface,
01083 const char *member,
01084 const char *error_name)
01085 {
01086 unsigned int flags;
01087
01088 _dbus_assert ((interface && member) ||
01089 (error_name) ||
01090 !(interface || member || error_name));
01091 _dbus_assert (error_name == NULL || is_valid_error_name (error_name));
01092
01093 if (!_dbus_string_append_byte (&message->header, message->byte_order))
01094 return FALSE;
01095
01096 if (!_dbus_string_append_byte (&message->header, type))
01097 return FALSE;
01098
01099 flags = 0;
01100 if (!_dbus_string_append_byte (&message->header, flags))
01101 return FALSE;
01102
01103 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
01104 return FALSE;
01105
01106
01107 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01108 return FALSE;
01109
01110
01111 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01112 return FALSE;
01113
01114
01115 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01116 return FALSE;
01117
01118
01119
01120 if (path != NULL)
01121 {
01122 if (!append_string_field (message,
01123 DBUS_HEADER_FIELD_PATH,
01124 DBUS_TYPE_OBJECT_PATH,
01125 path))
01126 return FALSE;
01127 }
01128
01129 if (service != NULL)
01130 {
01131 if (!append_string_field (message,
01132 DBUS_HEADER_FIELD_DESTINATION,
01133 DBUS_TYPE_STRING,
01134 service))
01135 return FALSE;
01136 }
01137
01138 if (interface != NULL)
01139 {
01140 if (!append_string_field (message,
01141 DBUS_HEADER_FIELD_INTERFACE,
01142 DBUS_TYPE_STRING,
01143 interface))
01144 return FALSE;
01145 }
01146
01147 if (member != NULL)
01148 {
01149 if (!append_string_field (message,
01150 DBUS_HEADER_FIELD_MEMBER,
01151 DBUS_TYPE_STRING,
01152 member))
01153 return FALSE;
01154 }
01155
01156 if (error_name != NULL)
01157 {
01158 if (!append_string_field (message,
01159 DBUS_HEADER_FIELD_ERROR_NAME,
01160 DBUS_TYPE_STRING,
01161 error_name))
01162 return FALSE;
01163 }
01164
01165
01166
01167
01168 if (!append_string_field (message,
01169 DBUS_HEADER_FIELD_SIGNATURE,
01170 DBUS_TYPE_STRING,
01171 ""))
01172 return FALSE;
01173
01174 return TRUE;
01175 }
01176
01186 void
01187 _dbus_message_lock (DBusMessage *message)
01188 {
01189 if (!message->locked)
01190 {
01191
01192 _dbus_marshal_set_uint32 (&message->header,
01193 message->byte_order,
01194 HEADER_LENGTH_OFFSET,
01195 _dbus_string_get_length (&message->header));
01196
01197 _dbus_marshal_set_uint32 (&message->header,
01198 message->byte_order,
01199 BODY_LENGTH_OFFSET,
01200 _dbus_string_get_length (&message->body));
01201
01202 message->locked = TRUE;
01203 }
01204 }
01205
01237 static dbus_bool_t
01238 dbus_message_set_signature (DBusMessage *message,
01239 const char *signature)
01240 {
01241 _dbus_return_val_if_fail (message != NULL, FALSE);
01242 _dbus_return_val_if_fail (!message->locked, FALSE);
01243
01244 return set_string_field (message,
01245 DBUS_HEADER_FIELD_SIGNATURE,
01246 DBUS_TYPE_STRING,
01247 signature);
01248 }
01249
01258 static dbus_bool_t
01259 dbus_message_append_to_signature (DBusMessage *message,
01260 const char *append_bytes)
01261 {
01262 const char *signature;
01263 DBusString append_str;
01264 dbus_bool_t retval;
01265
01266 _dbus_return_val_if_fail (append_bytes != NULL, FALSE);
01267 _dbus_return_val_if_fail (message != NULL, FALSE);
01268 _dbus_return_val_if_fail (!message->locked, FALSE);
01269
01270 retval = FALSE;
01271
01272
01273
01274
01275 signature = dbus_message_get_signature (message);
01276
01277 if (!_dbus_string_init (&append_str))
01278 return FALSE;
01279
01280 if (signature && !_dbus_string_append (&append_str, signature))
01281 goto out;
01282
01283 if (!_dbus_string_append (&append_str, append_bytes))
01284 goto out;
01285
01286 if (!set_string_field (message,
01287 DBUS_HEADER_FIELD_SIGNATURE,
01288 DBUS_TYPE_STRING,
01289 _dbus_string_get_const_data (&append_str)))
01290 goto out;
01291
01292 retval = TRUE;
01293
01294 out:
01295
01296 _dbus_string_free (&append_str);
01297
01298 return retval;
01299 }
01300
01309 static dbus_bool_t
01310 _dbus_message_append_byte_to_signature (DBusMessage *message,
01311 unsigned char append_byte)
01312 {
01313 char buf[2];
01314
01315 _dbus_return_val_if_fail (message != NULL, FALSE);
01316 _dbus_return_val_if_fail (!message->locked, FALSE);
01317
01318 buf[0] = append_byte;
01319 buf[1] = '\0';
01320
01321 return dbus_message_append_to_signature (message, buf);
01322 }
01323
01330 static void
01331 _dbus_message_remove_byte_from_signature (DBusMessage *message)
01332 {
01333 const char *signature;
01334
01335 _dbus_return_if_fail (message != NULL);
01336 _dbus_return_if_fail (!message->locked);
01337
01338 signature = dbus_message_get_signature (message);
01339
01340 _dbus_return_if_fail (signature != NULL);
01341
01342 if (!delete_field (message,
01343 DBUS_HEADER_FIELD_SIGNATURE,
01344 0))
01345 _dbus_assert_not_reached ("failed to delete signature field");
01346
01347
01348
01349
01350 if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE,
01351 DBUS_TYPE_STRING, signature,
01352 strlen (signature) - 1))
01353 _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed");
01354 }
01355
01363 static void
01364 free_size_counter (void *element,
01365 void *data)
01366 {
01367 DBusCounter *counter = element;
01368 DBusMessage *message = data;
01369
01370 _dbus_counter_adjust (counter, - message->size_counter_delta);
01371
01372 _dbus_counter_unref (counter);
01373 }
01374
01375 static void
01376 dbus_message_finalize (DBusMessage *message)
01377 {
01378 _dbus_assert (message->refcount.value == 0);
01379
01380
01381 _dbus_data_slot_list_free (&message->slot_list);
01382
01383 _dbus_list_foreach (&message->size_counters,
01384 free_size_counter, message);
01385 _dbus_list_clear (&message->size_counters);
01386
01387 _dbus_string_free (&message->header);
01388 _dbus_string_free (&message->body);
01389
01390 dbus_free (message);
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440 #define MAX_MESSAGE_SIZE_TO_CACHE _DBUS_ONE_MEGABYTE
01441
01442 #define MAX_MESSAGE_CACHE_SIZE 5
01443
01444 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
01445 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
01446 static int message_cache_count = 0;
01447 static dbus_bool_t message_cache_shutdown_registered = FALSE;
01448
01449 static void
01450 dbus_message_cache_shutdown (void *data)
01451 {
01452 int i;
01453
01454 _DBUS_LOCK (message_cache);
01455
01456 i = 0;
01457 while (i < MAX_MESSAGE_CACHE_SIZE)
01458 {
01459 if (message_cache[i])
01460 dbus_message_finalize (message_cache[i]);
01461
01462 ++i;
01463 }
01464
01465 message_cache_count = 0;
01466 message_cache_shutdown_registered = FALSE;
01467
01468 _DBUS_UNLOCK (message_cache);
01469 }
01470
01478 static DBusMessage*
01479 dbus_message_get_cached (void)
01480 {
01481 DBusMessage *message;
01482 int i;
01483
01484 message = NULL;
01485
01486 _DBUS_LOCK (message_cache);
01487
01488 _dbus_assert (message_cache_count >= 0);
01489
01490 if (message_cache_count == 0)
01491 {
01492 _DBUS_UNLOCK (message_cache);
01493 return NULL;
01494 }
01495
01496
01497
01498
01499
01500 _dbus_assert (message_cache_shutdown_registered);
01501
01502 i = 0;
01503 while (i < MAX_MESSAGE_CACHE_SIZE)
01504 {
01505 if (message_cache[i])
01506 {
01507 message = message_cache[i];
01508 message_cache[i] = NULL;
01509 message_cache_count -= 1;
01510 break;
01511 }
01512 ++i;
01513 }
01514 _dbus_assert (message_cache_count >= 0);
01515 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01516 _dbus_assert (message != NULL);
01517
01518 _DBUS_UNLOCK (message_cache);
01519
01520 _dbus_assert (message->refcount.value == 0);
01521 _dbus_assert (message->size_counters == NULL);
01522
01523 return message;
01524 }
01525
01531 static void
01532 dbus_message_cache_or_finalize (DBusMessage *message)
01533 {
01534 dbus_bool_t was_cached;
01535 int i;
01536
01537 _dbus_assert (message->refcount.value == 0);
01538
01539
01540
01541
01542 _dbus_data_slot_list_clear (&message->slot_list);
01543
01544 _dbus_list_foreach (&message->size_counters,
01545 free_size_counter, message);
01546 _dbus_list_clear (&message->size_counters);
01547
01548 was_cached = FALSE;
01549
01550 _DBUS_LOCK (message_cache);
01551
01552 if (!message_cache_shutdown_registered)
01553 {
01554 _dbus_assert (message_cache_count == 0);
01555
01556 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
01557 goto out;
01558
01559 i = 0;
01560 while (i < MAX_MESSAGE_CACHE_SIZE)
01561 {
01562 message_cache[i] = NULL;
01563 ++i;
01564 }
01565
01566 message_cache_shutdown_registered = TRUE;
01567 }
01568
01569 _dbus_assert (message_cache_count >= 0);
01570
01571 if ((_dbus_string_get_length (&message->header) +
01572 _dbus_string_get_length (&message->body)) >
01573 MAX_MESSAGE_SIZE_TO_CACHE)
01574 goto out;
01575
01576 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
01577 goto out;
01578
01579
01580 i = 0;
01581 while (message_cache[i] != NULL)
01582 ++i;
01583
01584 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01585
01586 _dbus_assert (message_cache[i] == NULL);
01587 message_cache[i] = message;
01588 message_cache_count += 1;
01589 was_cached = TRUE;
01590
01591 out:
01592 _DBUS_UNLOCK (message_cache);
01593
01594 if (!was_cached)
01595 dbus_message_finalize (message);
01596 }
01597
01598 static DBusMessage*
01599 dbus_message_new_empty_header (void)
01600 {
01601 DBusMessage *message;
01602 int i;
01603 dbus_bool_t from_cache;
01604
01605 message = dbus_message_get_cached ();
01606
01607 if (message != NULL)
01608 {
01609 from_cache = TRUE;
01610 }
01611 else
01612 {
01613 from_cache = FALSE;
01614 message = dbus_new (DBusMessage, 1);
01615 if (message == NULL)
01616 return NULL;
01617 #ifndef DBUS_DISABLE_CHECKS
01618 message->generation = _dbus_current_generation;
01619 #endif
01620 }
01621
01622 message->refcount.value = 1;
01623 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01624 message->client_serial = 0;
01625 message->reply_serial = 0;
01626 message->locked = FALSE;
01627 message->header_padding = 0;
01628 message->size_counters = NULL;
01629 message->size_counter_delta = 0;
01630 message->changed_stamp = 0;
01631
01632 if (!from_cache)
01633 _dbus_data_slot_list_init (&message->slot_list);
01634
01635 i = 0;
01636 while (i <= DBUS_HEADER_FIELD_LAST)
01637 {
01638 message->header_fields[i].name_offset = -1;
01639 message->header_fields[i].value_offset = -1;
01640 ++i;
01641 }
01642
01643 if (from_cache)
01644 {
01645
01646 _dbus_string_set_length (&message->header, 0);
01647 _dbus_string_set_length (&message->body, 0);
01648 }
01649 else
01650 {
01651 if (!_dbus_string_init_preallocated (&message->header, 32))
01652 {
01653 dbus_free (message);
01654 return NULL;
01655 }
01656
01657 if (!_dbus_string_init_preallocated (&message->body, 32))
01658 {
01659 _dbus_string_free (&message->header);
01660 dbus_free (message);
01661 return NULL;
01662 }
01663 }
01664
01665 return message;
01666 }
01667
01676 DBusMessage*
01677 dbus_message_new (int message_type)
01678 {
01679 DBusMessage *message;
01680
01681 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01682
01683 message = dbus_message_new_empty_header ();
01684 if (message == NULL)
01685 return NULL;
01686
01687 if (!dbus_message_create_header (message,
01688 message_type,
01689 NULL, NULL, NULL, NULL, NULL))
01690 {
01691 dbus_message_unref (message);
01692 return NULL;
01693 }
01694
01695 return message;
01696 }
01697
01715 DBusMessage*
01716 dbus_message_new_method_call (const char *service,
01717 const char *path,
01718 const char *interface,
01719 const char *method)
01720 {
01721 DBusMessage *message;
01722
01723 _dbus_return_val_if_fail (path != NULL, NULL);
01724 _dbus_return_val_if_fail (method != NULL, NULL);
01725
01726 message = dbus_message_new_empty_header ();
01727 if (message == NULL)
01728 return NULL;
01729
01730 if (!dbus_message_create_header (message,
01731 DBUS_MESSAGE_TYPE_METHOD_CALL,
01732 service, path, interface, method, NULL))
01733 {
01734 dbus_message_unref (message);
01735 return NULL;
01736 }
01737
01738 return message;
01739 }
01740
01750 DBusMessage*
01751 dbus_message_new_method_return (DBusMessage *method_call)
01752 {
01753 DBusMessage *message;
01754 const char *sender;
01755
01756 _dbus_return_val_if_fail (method_call != NULL, NULL);
01757
01758 sender = get_string_field (method_call,
01759 DBUS_HEADER_FIELD_SENDER,
01760 NULL);
01761
01762
01763
01764 message = dbus_message_new_empty_header ();
01765 if (message == NULL)
01766 return NULL;
01767
01768 if (!dbus_message_create_header (message,
01769 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01770 sender, NULL, NULL, NULL, NULL))
01771 {
01772 dbus_message_unref (message);
01773 return NULL;
01774 }
01775
01776 dbus_message_set_no_reply (message, TRUE);
01777
01778 if (!dbus_message_set_reply_serial (message,
01779 dbus_message_get_serial (method_call)))
01780 {
01781 dbus_message_unref (message);
01782 return NULL;
01783 }
01784
01785 return message;
01786 }
01787
01800 DBusMessage*
01801 dbus_message_new_signal (const char *path,
01802 const char *interface,
01803 const char *name)
01804 {
01805 DBusMessage *message;
01806
01807 _dbus_return_val_if_fail (path != NULL, NULL);
01808 _dbus_return_val_if_fail (interface != NULL, NULL);
01809 _dbus_return_val_if_fail (name != NULL, NULL);
01810
01811 message = dbus_message_new_empty_header ();
01812 if (message == NULL)
01813 return NULL;
01814
01815 if (!dbus_message_create_header (message,
01816 DBUS_MESSAGE_TYPE_SIGNAL,
01817 NULL, path, interface, name, NULL))
01818 {
01819 dbus_message_unref (message);
01820 return NULL;
01821 }
01822
01823 dbus_message_set_no_reply (message, TRUE);
01824
01825 return message;
01826 }
01827
01837 DBusMessage*
01838 dbus_message_new_error (DBusMessage *reply_to,
01839 const char *error_name,
01840 const char *error_message)
01841 {
01842 DBusMessage *message;
01843 const char *sender;
01844 DBusMessageIter iter;
01845
01846 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01847 _dbus_return_val_if_fail (error_name != NULL, NULL);
01848 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01849
01850 sender = get_string_field (reply_to,
01851 DBUS_HEADER_FIELD_SENDER,
01852 NULL);
01853
01854
01855
01856
01857
01858 message = dbus_message_new_empty_header ();
01859 if (message == NULL)
01860 return NULL;
01861
01862 if (!dbus_message_create_header (message,
01863 DBUS_MESSAGE_TYPE_ERROR,
01864 sender, NULL, NULL, NULL, error_name))
01865 {
01866 dbus_message_unref (message);
01867 return NULL;
01868 }
01869
01870 dbus_message_set_no_reply (message, TRUE);
01871
01872 if (!dbus_message_set_reply_serial (message,
01873 dbus_message_get_serial (reply_to)))
01874 {
01875 dbus_message_unref (message);
01876 return NULL;
01877 }
01878
01879 if (error_message != NULL)
01880 {
01881 dbus_message_append_iter_init (message, &iter);
01882 if (!dbus_message_iter_append_string (&iter, error_message))
01883 {
01884 dbus_message_unref (message);
01885 return NULL;
01886 }
01887 }
01888
01889 return message;
01890 }
01891
01902 DBusMessage*
01903 dbus_message_new_error_printf (DBusMessage *reply_to,
01904 const char *error_name,
01905 const char *error_format,
01906 ...)
01907 {
01908 va_list args;
01909 DBusString str;
01910 DBusMessage *message;
01911
01912 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01913 _dbus_return_val_if_fail (error_name != NULL, NULL);
01914 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01915
01916 if (!_dbus_string_init (&str))
01917 return NULL;
01918
01919 va_start (args, error_format);
01920
01921 if (_dbus_string_append_printf_valist (&str, error_format, args))
01922 message = dbus_message_new_error (reply_to, error_name,
01923 _dbus_string_get_const_data (&str));
01924 else
01925 message = NULL;
01926
01927 _dbus_string_free (&str);
01928
01929 va_end (args);
01930
01931 return message;
01932 }
01933
01934
01942 DBusMessage *
01943 dbus_message_copy (const DBusMessage *message)
01944 {
01945 DBusMessage *retval;
01946 int i;
01947
01948 _dbus_return_val_if_fail (message != NULL, NULL);
01949
01950 retval = dbus_new0 (DBusMessage, 1);
01951 if (retval == NULL)
01952 return NULL;
01953
01954 retval->refcount.value = 1;
01955 retval->byte_order = message->byte_order;
01956 retval->client_serial = message->client_serial;
01957 retval->reply_serial = message->reply_serial;
01958 retval->header_padding = message->header_padding;
01959 retval->locked = FALSE;
01960 #ifndef DBUS_DISABLE_CHECKS
01961 retval->generation = message->generation;
01962 #endif
01963
01964 if (!_dbus_string_init_preallocated (&retval->header,
01965 _dbus_string_get_length (&message->header)))
01966 {
01967 dbus_free (retval);
01968 return NULL;
01969 }
01970
01971 if (!_dbus_string_init_preallocated (&retval->body,
01972 _dbus_string_get_length (&message->body)))
01973 {
01974 _dbus_string_free (&retval->header);
01975 dbus_free (retval);
01976 return NULL;
01977 }
01978
01979 if (!_dbus_string_copy (&message->header, 0,
01980 &retval->header, 0))
01981 goto failed_copy;
01982
01983 if (!_dbus_string_copy (&message->body, 0,
01984 &retval->body, 0))
01985 goto failed_copy;
01986
01987 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
01988 {
01989 retval->header_fields[i] = message->header_fields[i];
01990 }
01991
01992 return retval;
01993
01994 failed_copy:
01995 _dbus_string_free (&retval->header);
01996 _dbus_string_free (&retval->body);
01997 dbus_free (retval);
01998
01999 return NULL;
02000 }
02001
02002
02010 DBusMessage *
02011 dbus_message_ref (DBusMessage *message)
02012 {
02013 dbus_int32_t old_refcount;
02014
02015 _dbus_return_val_if_fail (message != NULL, NULL);
02016 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
02017
02018 old_refcount = _dbus_atomic_inc (&message->refcount);
02019 _dbus_assert (old_refcount >= 1);
02020
02021 return message;
02022 }
02023
02030 void
02031 dbus_message_unref (DBusMessage *message)
02032 {
02033 dbus_int32_t old_refcount;
02034
02035 _dbus_return_if_fail (message != NULL);
02036 _dbus_return_if_fail (message->generation == _dbus_current_generation);
02037
02038 old_refcount = _dbus_atomic_dec (&message->refcount);
02039
02040 _dbus_assert (old_refcount >= 0);
02041
02042 if (old_refcount == 1)
02043 {
02044
02045 dbus_message_cache_or_finalize (message);
02046 }
02047 }
02048
02060 int
02061 dbus_message_get_type (DBusMessage *message)
02062 {
02063 int type;
02064
02065 type = _dbus_string_get_byte (&message->header, 1);
02066 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
02067
02068 return type;
02069 }
02070
02080 dbus_bool_t
02081 dbus_message_set_path (DBusMessage *message,
02082 const char *object_path)
02083 {
02084 _dbus_return_val_if_fail (message != NULL, FALSE);
02085 _dbus_return_val_if_fail (!message->locked, FALSE);
02086
02087 return set_string_field (message,
02088 DBUS_HEADER_FIELD_PATH,
02089 DBUS_TYPE_OBJECT_PATH,
02090 object_path);
02091 }
02092
02101 const char*
02102 dbus_message_get_path (DBusMessage *message)
02103 {
02104 _dbus_return_val_if_fail (message != NULL, NULL);
02105
02106 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
02107 }
02108
02124 dbus_bool_t
02125 dbus_message_get_path_decomposed (DBusMessage *message,
02126 char ***path)
02127 {
02128 _dbus_return_val_if_fail (message != NULL, FALSE);
02129 _dbus_return_val_if_fail (path != NULL, FALSE);
02130
02131 return get_path_field_decomposed (message,
02132 DBUS_HEADER_FIELD_PATH,
02133 path);
02134 }
02135
02146 dbus_bool_t
02147 dbus_message_set_interface (DBusMessage *message,
02148 const char *interface)
02149 {
02150 _dbus_return_val_if_fail (message != NULL, FALSE);
02151 _dbus_return_val_if_fail (!message->locked, FALSE);
02152
02153 return set_string_field (message,
02154 DBUS_HEADER_FIELD_INTERFACE,
02155 DBUS_TYPE_STRING,
02156 interface);
02157 }
02158
02168 const char*
02169 dbus_message_get_interface (DBusMessage *message)
02170 {
02171 _dbus_return_val_if_fail (message != NULL, NULL);
02172
02173 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
02174 }
02175
02186 dbus_bool_t
02187 dbus_message_set_member (DBusMessage *message,
02188 const char *member)
02189 {
02190 _dbus_return_val_if_fail (message != NULL, FALSE);
02191 _dbus_return_val_if_fail (!message->locked, FALSE);
02192
02193 return set_string_field (message,
02194 DBUS_HEADER_FIELD_MEMBER,
02195 DBUS_TYPE_STRING,
02196 member);
02197 }
02198
02207 const char*
02208 dbus_message_get_member (DBusMessage *message)
02209 {
02210 _dbus_return_val_if_fail (message != NULL, NULL);
02211
02212 return get_string_field (message,
02213 DBUS_HEADER_FIELD_MEMBER,
02214 NULL);
02215 }
02216
02225 dbus_bool_t
02226 dbus_message_set_error_name (DBusMessage *message,
02227 const char *error_name)
02228 {
02229 _dbus_return_val_if_fail (message != NULL, FALSE);
02230 _dbus_return_val_if_fail (!message->locked, FALSE);
02231 _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE);
02232
02233 return set_string_field (message,
02234 DBUS_HEADER_FIELD_ERROR_NAME,
02235 DBUS_TYPE_STRING,
02236 error_name);
02237 }
02238
02245 const char*
02246 dbus_message_get_error_name (DBusMessage *message)
02247 {
02248 _dbus_return_val_if_fail (message != NULL, NULL);
02249
02250 return get_string_field (message,
02251 DBUS_HEADER_FIELD_ERROR_NAME,
02252 NULL);
02253 }
02254
02262 dbus_bool_t
02263 dbus_message_set_destination (DBusMessage *message,
02264 const char *destination)
02265 {
02266 _dbus_return_val_if_fail (message != NULL, FALSE);
02267 _dbus_return_val_if_fail (!message->locked, FALSE);
02268
02269 return set_string_field (message,
02270 DBUS_HEADER_FIELD_DESTINATION,
02271 DBUS_TYPE_STRING,
02272 destination);
02273 }
02274
02281 const char*
02282 dbus_message_get_destination (DBusMessage *message)
02283 {
02284 _dbus_return_val_if_fail (message != NULL, NULL);
02285
02286 return get_string_field (message,
02287 DBUS_HEADER_FIELD_DESTINATION,
02288 NULL);
02289 }
02290
02309 dbus_bool_t
02310 dbus_message_append_args (DBusMessage *message,
02311 int first_arg_type,
02312 ...)
02313 {
02314 dbus_bool_t retval;
02315 va_list var_args;
02316
02317 _dbus_return_val_if_fail (message != NULL, FALSE);
02318
02319 va_start (var_args, first_arg_type);
02320 retval = dbus_message_append_args_valist (message,
02321 first_arg_type,
02322 var_args);
02323 va_end (var_args);
02324
02325 return retval;
02326 }
02327
02328
02329
02330
02331
02332 static void
02333 _dbus_message_ensure_our_byte_order (DBusMessage *message)
02334 {
02335 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
02336 return;
02337
02338
02339
02340
02341 }
02342
02355 dbus_bool_t
02356 dbus_message_get_args (DBusMessage *message,
02357 DBusError *error,
02358 int first_arg_type,
02359 ...)
02360 {
02361 dbus_bool_t retval;
02362 va_list var_args;
02363
02364 _dbus_return_val_if_fail (message != NULL, FALSE);
02365 _dbus_return_val_if_error_is_set (error, FALSE);
02366
02367 va_start (var_args, first_arg_type);
02368 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02369 va_end (var_args);
02370
02371 return retval;
02372 }
02373
02386 dbus_bool_t
02387 dbus_message_get_args_valist (DBusMessage *message,
02388 DBusError *error,
02389 int first_arg_type,
02390 va_list var_args)
02391 {
02392 DBusMessageIter iter;
02393
02394 _dbus_return_val_if_fail (message != NULL, FALSE);
02395 _dbus_return_val_if_error_is_set (error, FALSE);
02396
02397 dbus_message_iter_init (message, &iter);
02398 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02399 }
02400
02413 dbus_bool_t
02414 dbus_message_iter_get_args (DBusMessageIter *iter,
02415 DBusError *error,
02416 int first_arg_type,
02417 ...)
02418 {
02419 dbus_bool_t retval;
02420 va_list var_args;
02421
02422 _dbus_return_val_if_fail (iter != NULL, FALSE);
02423 _dbus_return_val_if_error_is_set (error, FALSE);
02424
02425 va_start (var_args, first_arg_type);
02426 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
02427 va_end (var_args);
02428
02429 return retval;
02430 }
02431
02440 dbus_bool_t
02441 dbus_message_iter_init (DBusMessage *message,
02442 DBusMessageIter *iter)
02443 {
02444 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02445
02446 _dbus_return_val_if_fail (message != NULL, FALSE);
02447 _dbus_return_val_if_fail (iter != NULL, FALSE);
02448
02449 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02450
02451 real->message = message;
02452 real->parent_iter = NULL;
02453 real->changed_stamp = message->changed_stamp;
02454
02455 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02456 real->pos = 0;
02457 real->end = _dbus_string_get_length (&message->body);
02458
02459 real->container_start = 0;
02460 real->container_length_pos = 0;
02461 real->wrote_dict_key = 0;
02462 real->array_type_pos = 0;
02463
02464 return real->end > real->pos;
02465 }
02466
02467 #ifndef DBUS_DISABLE_CHECKS
02468 static dbus_bool_t
02469 dbus_message_iter_check (DBusMessageRealIter *iter)
02470 {
02471 if (iter == NULL)
02472 {
02473 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
02474 return FALSE;
02475 }
02476
02477 if (iter->changed_stamp != iter->message->changed_stamp)
02478 {
02479 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
02480 return FALSE;
02481 }
02482
02483 if (iter->pos < 0 || iter->pos > iter->end)
02484 {
02485 _dbus_warn ("dbus iterator check failed: invalid position\n");
02486 return FALSE;
02487 }
02488
02489 return TRUE;
02490 }
02491 #endif
02492
02493 static int
02494 skip_array_type (DBusMessageRealIter *iter, int pos)
02495 {
02496 const char *data;
02497
02498 do
02499 {
02500 data = _dbus_string_get_const_data_len (&iter->message->body,
02501 pos++, 1);
02502 }
02503 while (*data == DBUS_TYPE_ARRAY);
02504
02505 return pos;
02506 }
02507
02508
02509
02510
02511 static int
02512 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
02513 {
02514 const char *data;
02515 int pos, len;
02516
02517 switch (iter->type)
02518 {
02519 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02520 data = _dbus_string_get_const_data_len (&iter->message->body,
02521 iter->pos, 1);
02522 if (_dbus_type_is_valid (*data))
02523 *type = *data;
02524 else
02525 *type = DBUS_TYPE_INVALID;
02526
02527 return skip_array_type (iter, iter->pos);
02528
02529 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02530 data = _dbus_string_get_const_data_len (&iter->message->body,
02531 iter->array_type_pos, 1);
02532 if (_dbus_type_is_valid (*data))
02533 *type = *data;
02534 else
02535 *type = DBUS_TYPE_INVALID;
02536
02537 return iter->pos;
02538
02539 case DBUS_MESSAGE_ITER_TYPE_DICT:
02540
02541 len = _dbus_demarshal_uint32 (&iter->message->body,
02542 iter->message->byte_order,
02543 iter->pos, &pos);
02544 pos = pos + len + 1;
02545
02546 data = _dbus_string_get_const_data_len (&iter->message->body,
02547 pos, 1);
02548 if (_dbus_type_is_valid (*data))
02549 *type = *data;
02550 else
02551 *type = DBUS_TYPE_INVALID;
02552
02553 return skip_array_type (iter, pos);
02554
02555 default:
02556 _dbus_assert_not_reached ("Invalid iter type");
02557 break;
02558 }
02559 *type = DBUS_TYPE_INVALID;
02560 return iter->pos;
02561 }
02562
02563
02571 dbus_bool_t
02572 dbus_message_iter_has_next (DBusMessageIter *iter)
02573 {
02574 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02575 int end_pos;
02576 int type, pos;
02577
02578 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02579
02580 if (real->pos >= real->end)
02581 return FALSE;
02582
02583 pos = dbus_message_iter_get_data_start (real, &type);
02584
02585 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02586 real->message->byte_order,
02587 type, pos, &end_pos))
02588 return FALSE;
02589
02590 if (end_pos >= real->end)
02591 return FALSE;
02592
02593 return TRUE;
02594 }
02595
02602 dbus_bool_t
02603 dbus_message_iter_next (DBusMessageIter *iter)
02604 {
02605 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02606 int end_pos;
02607 int type, pos;
02608
02609 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02610
02611 pos = dbus_message_iter_get_data_start (real, &type);
02612
02613 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02614 real->message->byte_order,
02615 type, pos, &end_pos))
02616 return FALSE;
02617
02618 if (end_pos >= real->end)
02619 return FALSE;
02620
02621 real->pos = end_pos;
02622
02623 return TRUE;
02624 }
02625
02633 int
02634 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02635 {
02636 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02637 int type, pos;
02638
02639 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02640
02641 if (real->pos >= real->end)
02642 {
02643 _dbus_verbose (" iterator at or beyond end of message\n");
02644 return DBUS_TYPE_INVALID;
02645 }
02646
02647 pos = dbus_message_iter_get_data_start (real, &type);
02648
02649 return type;
02650 }
02651
02652
02653
02654
02655 static int
02656 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02657 {
02658 const char *data;
02659 int _array_type_pos;
02660 int len, pos;
02661
02662 switch (iter->type)
02663 {
02664 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02665 _array_type_pos = iter->pos + 1;
02666 break;
02667 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02668 _array_type_pos = iter->array_type_pos + 1;
02669 break;
02670 case DBUS_MESSAGE_ITER_TYPE_DICT:
02671
02672 len = _dbus_demarshal_uint32 (&iter->message->body,
02673 iter->message->byte_order,
02674 iter->pos, &pos);
02675 pos = pos + len + 1;
02676 data = _dbus_string_get_const_data_len (&iter->message->body,
02677 pos + 1, 1);
02678 _array_type_pos = pos + 1;
02679 break;
02680 default:
02681 _dbus_assert_not_reached ("wrong iter type");
02682 return DBUS_TYPE_INVALID;
02683 }
02684
02685 if (array_type_pos != NULL)
02686 *array_type_pos = _array_type_pos;
02687
02688 data = _dbus_string_get_const_data_len (&iter->message->body,
02689 _array_type_pos, 1);
02690 if (_dbus_type_is_valid (*data))
02691 return *data;
02692
02693 return DBUS_TYPE_INVALID;
02694 }
02695
02696
02706 int
02707 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02708 {
02709 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02710 int type, pos;
02711
02712 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02713
02714 if (real->pos >= real->end)
02715 return DBUS_TYPE_INVALID;
02716
02717 pos = dbus_message_iter_get_data_start (real, &type);
02718
02719 _dbus_assert (type == DBUS_TYPE_ARRAY);
02720
02721 return iter_get_array_type (real, NULL);
02722 }
02723
02724
02734 char *
02735 dbus_message_iter_get_string (DBusMessageIter *iter)
02736 {
02737 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02738 int type, pos;
02739
02740 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02741 pos = dbus_message_iter_get_data_start (real, &type);
02742
02743 _dbus_assert (type == DBUS_TYPE_STRING);
02744
02745 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02746 pos, NULL);
02747 }
02748
02758 char *
02759 dbus_message_iter_get_object_path (DBusMessageIter *iter)
02760 {
02761 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02762 int type, pos;
02763
02764 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02765
02766 pos = dbus_message_iter_get_data_start (real, &type);
02767
02768 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
02769
02770 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02771 pos, NULL);
02772 }
02773
02787 dbus_bool_t
02788 dbus_message_iter_get_custom (DBusMessageIter *iter,
02789 char **name,
02790 unsigned char **value,
02791 int *len)
02792 {
02793 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02794 int type, pos;
02795 char *_name;
02796
02797 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02798
02799 pos = dbus_message_iter_get_data_start (real, &type);
02800
02801 _dbus_assert (type == DBUS_TYPE_CUSTOM);
02802
02803 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02804 pos, &pos);
02805
02806 if (_name == NULL)
02807 return FALSE;
02808
02809 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02810 pos, NULL, value, len))
02811 {
02812 dbus_free (_name);
02813 return FALSE;
02814 }
02815
02816 *name = _name;
02817
02818 return TRUE;
02819 }
02820
02821 static void
02822 _dbus_message_iter_get_basic_type (DBusMessageIter *iter,
02823 char type,
02824 void *value)
02825 {
02826 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02827 int item_type, pos;
02828
02829 _dbus_return_if_fail (dbus_message_iter_check (real));
02830
02831 pos = dbus_message_iter_get_data_start (real, &item_type);
02832
02833 _dbus_assert (type == item_type);
02834
02835 _dbus_demarshal_basic_type (&real->message->body,
02836 type, value,
02837 real->message->byte_order,
02838 &pos);
02839 }
02840
02841
02864 dbus_bool_t
02865 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
02866 DBusError *error,
02867 int first_arg_type,
02868 va_list var_args)
02869 {
02870 int spec_type, msg_type, i;
02871 dbus_bool_t retval;
02872
02873 _dbus_return_val_if_fail (iter != NULL, FALSE);
02874 _dbus_return_val_if_error_is_set (error, FALSE);
02875
02876 retval = FALSE;
02877
02878 spec_type = first_arg_type;
02879 i = 0;
02880
02881 while (spec_type != DBUS_TYPE_INVALID)
02882 {
02883 msg_type = dbus_message_iter_get_arg_type (iter);
02884
02885 if (msg_type != spec_type)
02886 {
02887 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02888 "Argument %d is specified to be of type \"%s\", but "
02889 "is actually of type \"%s\"\n", i,
02890 _dbus_type_to_string (spec_type),
02891 _dbus_type_to_string (msg_type));
02892
02893 goto out;
02894 }
02895
02896 switch (spec_type)
02897 {
02898 case DBUS_TYPE_NIL:
02899 break;
02900 case DBUS_TYPE_BOOLEAN:
02901 {
02902 dbus_bool_t *ptr;
02903
02904 ptr = va_arg (var_args, dbus_bool_t *);
02905
02906 *ptr = dbus_message_iter_get_boolean (iter);
02907 break;
02908 }
02909 case DBUS_TYPE_BYTE:
02910 case DBUS_TYPE_INT32:
02911 case DBUS_TYPE_UINT32:
02912 #ifdef DBUS_HAVE_INT64
02913 case DBUS_TYPE_INT64:
02914 case DBUS_TYPE_UINT64:
02915 #endif
02916 case DBUS_TYPE_DOUBLE:
02917 {
02918 void *ptr = va_arg (var_args, double *);
02919 _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
02920 break;
02921 }
02922
02923 case DBUS_TYPE_STRING:
02924 {
02925 char **ptr;
02926
02927 ptr = va_arg (var_args, char **);
02928
02929 *ptr = dbus_message_iter_get_string (iter);
02930
02931 if (!*ptr)
02932 {
02933 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02934 goto out;
02935 }
02936
02937 break;
02938 }
02939
02940 case DBUS_TYPE_OBJECT_PATH:
02941 {
02942 char **ptr;
02943
02944 ptr = va_arg (var_args, char **);
02945
02946 *ptr = dbus_message_iter_get_object_path (iter);
02947
02948 if (!*ptr)
02949 {
02950 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02951 goto out;
02952 }
02953
02954 break;
02955 }
02956
02957 case DBUS_TYPE_CUSTOM:
02958 {
02959 char **name;
02960 unsigned char **data;
02961 int *len;
02962
02963 name = va_arg (var_args, char **);
02964 data = va_arg (var_args, unsigned char **);
02965 len = va_arg (var_args, int *);
02966
02967 if (!dbus_message_iter_get_custom (iter, name, data, len))
02968 {
02969 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02970 goto out;
02971 }
02972 }
02973 break;
02974 case DBUS_TYPE_ARRAY:
02975 {
02976 void **data;
02977 int *len, type;
02978 dbus_bool_t err = FALSE;
02979
02980 type = va_arg (var_args, int);
02981 data = va_arg (var_args, void *);
02982 len = va_arg (var_args, int *);
02983
02984 _dbus_return_val_if_fail (data != NULL, FALSE);
02985 _dbus_return_val_if_fail (len != NULL, FALSE);
02986
02987 if (dbus_message_iter_get_array_type (iter) != type)
02988 {
02989 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02990 "Argument %d is specified to be of type \"array of %s\", but "
02991 "is actually of type \"array of %s\"\n", i,
02992 _dbus_type_to_string (type),
02993 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
02994 goto out;
02995 }
02996
02997 switch (type)
02998 {
02999 case DBUS_TYPE_BYTE:
03000 err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
03001 break;
03002 case DBUS_TYPE_BOOLEAN:
03003 err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
03004 break;
03005 case DBUS_TYPE_INT32:
03006 err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
03007 break;
03008 case DBUS_TYPE_UINT32:
03009 err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
03010 break;
03011 #ifdef DBUS_HAVE_INT64
03012 case DBUS_TYPE_INT64:
03013 err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
03014 break;
03015 case DBUS_TYPE_UINT64:
03016 err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
03017 break;
03018 #endif
03019 case DBUS_TYPE_DOUBLE:
03020 err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
03021 break;
03022 case DBUS_TYPE_STRING:
03023 err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
03024 break;
03025 case DBUS_TYPE_OBJECT_PATH:
03026 err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
03027 break;
03028
03029 case DBUS_TYPE_NIL:
03030 case DBUS_TYPE_ARRAY:
03031 case DBUS_TYPE_CUSTOM:
03032 case DBUS_TYPE_DICT:
03033 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
03034 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03035 goto out;
03036 default:
03037 _dbus_warn ("Unknown field type %d\n", type);
03038 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03039 goto out;
03040 }
03041 if (err)
03042 {
03043 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
03044 goto out;
03045 }
03046 }
03047 break;
03048 case DBUS_TYPE_DICT:
03049 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
03050 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03051 goto out;
03052 default:
03053 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03054 _dbus_warn ("Unknown field type %d\n", spec_type);
03055 goto out;
03056 }
03057
03058 spec_type = va_arg (var_args, int);
03059 if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
03060 {
03061 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
03062 "Message has only %d arguments, but more were expected", i);
03063 goto out;
03064 }
03065
03066 i++;
03067 }
03068
03069 retval = TRUE;
03070
03071 out:
03072
03073 return retval;
03074 }
03075
03085 unsigned char
03086 dbus_message_iter_get_byte (DBusMessageIter *iter)
03087 {
03088 unsigned char value = 0;
03089
03090 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value);
03091
03092 return value;
03093 }
03094
03104 dbus_bool_t
03105 dbus_message_iter_get_boolean (DBusMessageIter *iter)
03106 {
03107 unsigned char value = 0;
03108
03109 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value);
03110
03111 return (value != FALSE);
03112 }
03113
03123 dbus_int32_t
03124 dbus_message_iter_get_int32 (DBusMessageIter *iter)
03125 {
03126 dbus_int32_t value = 0;
03127
03128 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value);
03129
03130 return value;
03131 }
03132
03142 dbus_uint32_t
03143 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
03144 {
03145 dbus_int32_t value = 0;
03146
03147 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value);
03148
03149 return value;
03150 }
03151
03152 #ifdef DBUS_HAVE_INT64
03153
03165 dbus_int64_t
03166 dbus_message_iter_get_int64 (DBusMessageIter *iter)
03167 {
03168 dbus_int64_t value = 0;
03169
03170 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value);
03171
03172 return value;
03173 }
03174
03186 dbus_uint64_t
03187 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
03188 {
03189 dbus_uint64_t value = 0;
03190
03191 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value);
03192
03193 return value;
03194 }
03195
03196 #endif
03197
03207 double
03208 dbus_message_iter_get_double (DBusMessageIter *iter)
03209 {
03210 double value = 0.0;
03211
03212 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value);
03213
03214 return value;
03215 }
03216
03230 dbus_bool_t
03231 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
03232 DBusMessageIter *array_iter,
03233 int *array_type)
03234 {
03235 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03236 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03237 int type, pos, len_pos, len, array_type_pos;
03238 int _array_type;
03239
03240 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03241
03242 pos = dbus_message_iter_get_data_start (real, &type);
03243
03244 _dbus_assert (type == DBUS_TYPE_ARRAY);
03245
03246 _array_type = iter_get_array_type (real, &array_type_pos);
03247
03248 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03249 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03250 pos, &pos);
03251
03252 array_real->parent_iter = real;
03253 array_real->message = real->message;
03254 array_real->changed_stamp = real->message->changed_stamp;
03255
03256 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
03257 array_real->pos = pos;
03258 array_real->end = pos + len;
03259
03260 array_real->container_start = pos;
03261 array_real->container_length_pos = len_pos;
03262 array_real->wrote_dict_key = 0;
03263 array_real->array_type_pos = array_type_pos;
03264 array_real->array_type_done = TRUE;
03265
03266 if (array_type != NULL)
03267 *array_type = _array_type;
03268
03269 return len > 0;
03270 }
03271
03272
03282 dbus_bool_t
03283 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
03284 DBusMessageIter *dict_iter)
03285 {
03286 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03287 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03288 int type, pos, len_pos, len;
03289
03290 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03291
03292 pos = dbus_message_iter_get_data_start (real, &type);
03293
03294 _dbus_assert (type == DBUS_TYPE_DICT);
03295
03296 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03297 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03298 pos, &pos);
03299
03300 dict_real->parent_iter = real;
03301 dict_real->message = real->message;
03302 dict_real->changed_stamp = real->message->changed_stamp;
03303
03304 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03305 dict_real->pos = pos;
03306 dict_real->end = pos + len;
03307
03308 dict_real->container_start = pos;
03309 dict_real->container_length_pos = len_pos;
03310 dict_real->wrote_dict_key = 0;
03311
03312 return len > 0;
03313 }
03314
03315 static dbus_bool_t
03316 _dbus_message_iter_get_basic_type_array (DBusMessageIter *iter,
03317 char type,
03318 void **array,
03319 int *array_len)
03320 {
03321 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03322 int item_type, pos;
03323
03324 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03325
03326 pos = dbus_message_iter_get_data_start (real, &item_type);
03327
03328 _dbus_assert (item_type == DBUS_TYPE_ARRAY);
03329
03330 item_type = iter_get_array_type (real, NULL);
03331
03332 _dbus_assert (type == item_type);
03333
03334 return _dbus_demarshal_basic_type_array (&real->message->body,
03335 item_type, array, array_len,
03336 real->message->byte_order, &pos);
03337 }
03338
03349 dbus_bool_t
03350 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
03351 unsigned char **value,
03352 int *len)
03353 {
03354 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE,
03355 (void **) value, len);
03356 }
03357
03368 dbus_bool_t
03369 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
03370 unsigned char **value,
03371 int *len)
03372 {
03373 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN,
03374 (void **) value, len);
03375 }
03376
03387 dbus_bool_t
03388 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
03389 dbus_int32_t **value,
03390 int *len)
03391 {
03392 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393 (void **) value, len);
03394 }
03395
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
03408 dbus_uint32_t **value,
03409 int *len)
03410 {
03411 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412 (void **) value, len);
03413 }
03414
03415 #ifdef DBUS_HAVE_INT64
03416
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
03431 dbus_int64_t **value,
03432 int *len)
03433 {
03434 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435 (void **) value, len);
03436 }
03437
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
03452 dbus_uint64_t **value,
03453 int *len)
03454 {
03455 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456 (void **) value, len);
03457 }
03458
03459 #endif
03460
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array (DBusMessageIter *iter,
03473 double **value,
03474 int *len)
03475 {
03476 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477 (void **) value, len);
03478 }
03479
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497 char ***value,
03498 int *len)
03499 {
03500 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501 int type, pos;
03502
03503 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504
03505 pos = dbus_message_iter_get_data_start (real, &type);
03506
03507 _dbus_assert (type == DBUS_TYPE_ARRAY);
03508
03509 type = iter_get_array_type (real, NULL);
03510 _dbus_assert (type == DBUS_TYPE_STRING);
03511
03512 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513 pos, NULL, value, len))
03514 return FALSE;
03515 else
03516 return TRUE;
03517 }
03518
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536 char ***value,
03537 int *len)
03538 {
03539 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540 int type, pos;
03541
03542 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543
03544 pos = dbus_message_iter_get_data_start (real, &type);
03545
03546 _dbus_assert (type == DBUS_TYPE_ARRAY);
03547
03548 type = iter_get_array_type (real, NULL);
03549 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550
03551 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552 pos, NULL, value, len))
03553 return FALSE;
03554 else
03555 return TRUE;
03556 }
03557
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
03569 {
03570 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571
03572 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573
03574 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575
03576 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577 real->pos, NULL);
03578 }
03579
03588 void
03589 dbus_message_append_iter_init (DBusMessage *message,
03590 DBusMessageIter *iter)
03591 {
03592 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593
03594 _dbus_return_if_fail (message != NULL);
03595 _dbus_return_if_fail (iter != NULL);
03596
03597 real->message = message;
03598 real->parent_iter = NULL;
03599 real->changed_stamp = message->changed_stamp;
03600
03601 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602 real->end = _dbus_string_get_length (&real->message->body);
03603 real->pos = real->end;
03604
03605 real->container_length_pos = 0;
03606 real->wrote_dict_key = 0;
03607 }
03608
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613 if (iter == NULL)
03614 {
03615 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616 return FALSE;
03617 }
03618
03619 if (iter->message->locked)
03620 {
03621 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622 return FALSE;
03623 }
03624
03625 if (iter->changed_stamp != iter->message->changed_stamp)
03626 {
03627 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628 return FALSE;
03629 }
03630
03631 if (iter->pos != iter->end)
03632 {
03633 _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634 return FALSE;
03635 }
03636
03637 if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638 {
03639 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640 return FALSE;
03641 }
03642
03643 return TRUE;
03644 }
03645 #endif
03646
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649 int type)
03650 {
03651 const char *data;
03652
03653 switch (iter->type)
03654 {
03655 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656 if (!_dbus_string_append_byte (&iter->message->body, type))
03657 return FALSE;
03658
03659 if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660 {
03661 _dbus_string_shorten (&iter->message->body, 1);
03662 return FALSE;
03663 }
03664 break;
03665
03666 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667 data = _dbus_string_get_const_data_len (&iter->message->body,
03668 iter->array_type_pos, 1);
03669 if (type != *data)
03670 {
03671 _dbus_warn ("Appended element of wrong type for array\n");
03672 return FALSE;
03673 }
03674 break;
03675
03676 case DBUS_MESSAGE_ITER_TYPE_DICT:
03677 if (!iter->wrote_dict_key)
03678 {
03679 _dbus_warn ("Appending dict data before key name\n");
03680 return FALSE;
03681 }
03682
03683 if (!_dbus_string_append_byte (&iter->message->body, type))
03684 return FALSE;
03685
03686 break;
03687
03688 default:
03689 _dbus_assert_not_reached ("Invalid iter type");
03690 break;
03691 }
03692
03693 return TRUE;
03694 }
03695
03696 static void
03697 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
03698 {
03699 iter->changed_stamp = iter->message->changed_stamp;
03700
03701
03702 iter->end = _dbus_string_get_length (&iter->message->body);
03703 iter->pos = iter->end;
03704
03705
03706 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
03707 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
03708 _dbus_marshal_set_uint32 (&iter->message->body,
03709 iter->message->byte_order,
03710 iter->container_length_pos,
03711 iter->end - iter->container_start);
03712
03713 if (iter->parent_iter)
03714 dbus_message_iter_update_after_change (iter->parent_iter);
03715 }
03716
03717 static void
03718 dbus_message_iter_append_done (DBusMessageRealIter *iter)
03719 {
03720 iter->message->changed_stamp++;
03721 dbus_message_iter_update_after_change (iter);
03722 iter->wrote_dict_key = FALSE;
03723 }
03724
03731 dbus_bool_t
03732 dbus_message_iter_append_nil (DBusMessageIter *iter)
03733 {
03734 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03735
03736 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03737
03738 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
03739 return FALSE;
03740
03741 dbus_message_iter_append_done (real);
03742
03743 return TRUE;
03744 }
03745
03746 static dbus_bool_t
03747 dbus_message_iter_append_basic (DBusMessageIter *iter,
03748 char type,
03749 void *value)
03750 {
03751 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03752
03753 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03754
03755 if (!dbus_message_iter_append_type (real, type))
03756 return FALSE;
03757
03758 if (!_dbus_marshal_basic_type (&real->message->body,
03759 type, value,
03760 real->message->byte_order))
03761 {
03762 _dbus_string_set_length (&real->message->body, real->pos);
03763 return FALSE;
03764 }
03765
03766 dbus_message_iter_append_done (real);
03767
03768 return TRUE;
03769 }
03770
03778 dbus_bool_t
03779 dbus_message_iter_append_boolean (DBusMessageIter *iter,
03780 dbus_bool_t value)
03781 {
03782 unsigned char val = (value != FALSE);
03783 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val);
03784 }
03785
03793 dbus_bool_t
03794 dbus_message_iter_append_byte (DBusMessageIter *iter,
03795 unsigned char value)
03796 {
03797 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value);
03798 }
03799
03807 dbus_bool_t
03808 dbus_message_iter_append_int32 (DBusMessageIter *iter,
03809 dbus_int32_t value)
03810 {
03811 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value);
03812 }
03813
03821 dbus_bool_t
03822 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
03823 dbus_uint32_t value)
03824 {
03825 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value);
03826 }
03827
03828 #ifdef DBUS_HAVE_INT64
03829
03839 dbus_bool_t
03840 dbus_message_iter_append_int64 (DBusMessageIter *iter,
03841 dbus_int64_t value)
03842 {
03843 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
03844 }
03845
03855 dbus_bool_t
03856 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
03857 dbus_uint64_t value)
03858 {
03859 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value);
03860 }
03861
03862 #endif
03863
03871 dbus_bool_t
03872 dbus_message_iter_append_double (DBusMessageIter *iter,
03873 double value)
03874 {
03875 return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value);
03876 }
03877
03887 dbus_bool_t
03888 dbus_message_iter_append_string (DBusMessageIter *iter,
03889 const char *value)
03890 {
03891 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03892
03893 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03894
03895 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
03896 return FALSE;
03897
03898 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03899 {
03900 _dbus_string_set_length (&real->message->body, real->pos);
03901 return FALSE;
03902 }
03903
03904 dbus_message_iter_append_done (real);
03905
03906 return TRUE;
03907 }
03908
03918 dbus_bool_t
03919 dbus_message_iter_append_object_path (DBusMessageIter *iter,
03920 const char *value)
03921 {
03922 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03923
03924 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03925
03926 if (!dbus_message_iter_append_type (real, DBUS_TYPE_OBJECT_PATH))
03927 return FALSE;
03928
03929 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03930 {
03931 _dbus_string_set_length (&real->message->body, real->pos);
03932 return FALSE;
03933 }
03934
03935 dbus_message_iter_append_done (real);
03936
03937 return TRUE;
03938 }
03939
03952 dbus_bool_t
03953 dbus_message_iter_append_custom (DBusMessageIter *iter,
03954 const char *name,
03955 const unsigned char *data,
03956 int len)
03957 {
03958 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03959
03960 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03961
03962 if (!dbus_message_iter_append_type (real, DBUS_TYPE_CUSTOM))
03963 return FALSE;
03964
03965 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
03966 {
03967 _dbus_string_set_length (&real->message->body, real->pos);
03968 return FALSE;
03969 }
03970
03971 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
03972 {
03973 _dbus_string_set_length (&real->message->body, real->pos);
03974 return FALSE;
03975 }
03976
03977 dbus_message_iter_append_done (real);
03978
03979 return TRUE;
03980 }
03981
03982
03991 dbus_bool_t
03992 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
03993 const char *value)
03994 {
03995 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03996
03997 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03998 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03999
04000 if (real->wrote_dict_key)
04001 {
04002 _dbus_warn ("Appending multiple dict key names\n");
04003 return FALSE;
04004 }
04005
04006 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
04007 {
04008 return FALSE;
04009 }
04010
04011 dbus_message_iter_append_done (real);
04012 real->wrote_dict_key = TRUE;
04013
04014 return TRUE;
04015 }
04016
04017 static dbus_bool_t
04018 array_iter_type_mark_done (DBusMessageRealIter *iter)
04019 {
04020 int len_pos;
04021
04022 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
04023 array_iter_type_mark_done (iter->parent_iter);
04024 else
04025 return TRUE;
04026
04027 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
04028 sizeof (dbus_uint32_t));
04029
04030
04031 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
04032 {
04033 _dbus_string_set_length (&iter->message->body, iter->pos);
04034 return FALSE;
04035 }
04036
04037 iter->container_start = _dbus_string_get_length (&iter->message->body);
04038 iter->container_length_pos = len_pos;
04039 iter->array_type_done = TRUE;
04040
04041 return TRUE;
04042 }
04043
04044 static dbus_bool_t
04045 append_array_type (DBusMessageRealIter *real,
04046 int element_type,
04047 dbus_bool_t *array_type_done,
04048 int *array_type_pos)
04049 {
04050 int existing_element_type;
04051
04052 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
04053 return FALSE;
04054
04055 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
04056 real->array_type_done)
04057 {
04058 existing_element_type = iter_get_array_type (real, array_type_pos);
04059 if (existing_element_type != element_type)
04060 {
04061 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
04062 _dbus_type_to_string (element_type),
04063 _dbus_type_to_string (existing_element_type));
04064 _dbus_string_set_length (&real->message->body, real->pos);
04065 return FALSE;
04066 }
04067 if (array_type_done != NULL)
04068 *array_type_done = TRUE;
04069 }
04070 else
04071 {
04072 if (array_type_pos != NULL)
04073 *array_type_pos = _dbus_string_get_length (&real->message->body);
04074
04075
04076 if (!_dbus_message_append_byte_to_signature (real->message, element_type))
04077 {
04078 _dbus_string_set_length (&real->message->body, real->pos);
04079 return FALSE;
04080 }
04081
04082
04083 if (!_dbus_string_append_byte (&real->message->body, element_type))
04084 {
04085 _dbus_message_remove_byte_from_signature (real->message);
04086 _dbus_string_set_length (&real->message->body, real->pos);
04087 return FALSE;
04088 }
04089
04090 if (array_type_done != NULL)
04091 *array_type_done = element_type != DBUS_TYPE_ARRAY;
04092
04093 if (element_type != DBUS_TYPE_ARRAY &&
04094 !array_iter_type_mark_done (real))
04095 {
04096 _dbus_message_remove_byte_from_signature (real->message);
04097 return FALSE;
04098 }
04099 }
04100
04101 return TRUE;
04102 }
04103
04113 dbus_bool_t
04114 dbus_message_iter_append_array (DBusMessageIter *iter,
04115 DBusMessageIter *array_iter,
04116 int element_type)
04117 {
04118 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04119 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
04120 int len_pos;
04121 int array_type_pos;
04122 dbus_bool_t array_type_done;
04123
04124 if (element_type == DBUS_TYPE_NIL)
04125 {
04126 _dbus_warn ("Can't create NIL arrays\n");
04127 return FALSE;
04128 }
04129
04130 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04131
04132 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
04133 return FALSE;
04134
04135 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04136
04137 if (array_type_done)
04138 {
04139
04140 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04141 {
04142 _dbus_string_set_length (&real->message->body, real->pos);
04143 return FALSE;
04144 }
04145 }
04146
04147 array_real->parent_iter = real;
04148 array_real->message = real->message;
04149 array_real->changed_stamp = real->message->changed_stamp;
04150
04151 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
04152 array_real->pos = _dbus_string_get_length (&real->message->body);
04153 array_real->end = array_real->end;
04154
04155 array_real->container_start = array_real->pos;
04156 array_real->container_length_pos = len_pos;
04157 array_real->wrote_dict_key = 0;
04158 array_real->array_type_done = array_type_done;
04159 array_real->array_type_pos = array_type_pos;
04160
04161 dbus_message_iter_append_done (array_real);
04162
04163 return TRUE;
04164 }
04165
04174 dbus_bool_t
04175 dbus_message_iter_append_dict (DBusMessageIter *iter,
04176 DBusMessageIter *dict_iter)
04177 {
04178 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04179 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
04180 int len_pos;
04181
04182 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04183
04184 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
04185 return FALSE;
04186
04187 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04188
04189
04190 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04191 {
04192 _dbus_string_set_length (&real->message->body, real->pos);
04193 return FALSE;
04194 }
04195
04196 dict_real->parent_iter = real;
04197 dict_real->message = real->message;
04198 dict_real->changed_stamp = real->message->changed_stamp;
04199
04200 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
04201 dict_real->pos = _dbus_string_get_length (&real->message->body);
04202 dict_real->end = dict_real->end;
04203
04204 dict_real->container_start = dict_real->pos;
04205 dict_real->container_length_pos = len_pos;
04206 dict_real->wrote_dict_key = 0;
04207
04208 dbus_message_iter_append_done (dict_real);
04209
04210 real->wrote_dict_key = FALSE;
04211
04212 return TRUE;
04213 }
04214
04215 static dbus_bool_t
04216 _dbus_message_iter_append_basic_array (DBusMessageIter *iter,
04217 char type,
04218 const void *value,
04219 int len)
04220 {
04221 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04222
04223 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04224
04225 if (!append_array_type (real, type, NULL, NULL))
04226 return FALSE;
04227
04228 if (!_dbus_marshal_basic_type_array (&real->message->body,
04229 type, value, len,
04230 real->message->byte_order))
04231 {
04232 _dbus_string_set_length (&real->message->body, real->pos);
04233 return FALSE;
04234 }
04235
04236 dbus_message_iter_append_done (real);
04237
04238 return TRUE;
04239 }
04240
04241
04255 dbus_bool_t
04256 dbus_message_append_args_valist (DBusMessage *message,
04257 int first_arg_type,
04258 va_list var_args)
04259 {
04260 int type, old_len;
04261 DBusMessageIter iter;
04262
04263 _dbus_return_val_if_fail (message != NULL, FALSE);
04264
04265 old_len = _dbus_string_get_length (&message->body);
04266
04267 type = first_arg_type;
04268
04269 dbus_message_append_iter_init (message, &iter);
04270
04271 while (type != DBUS_TYPE_INVALID)
04272 {
04273 switch (type)
04274 {
04275 case DBUS_TYPE_NIL:
04276 if (!dbus_message_iter_append_nil (&iter))
04277 goto errorout;
04278 break;
04279 case DBUS_TYPE_BYTE:
04280
04281
04282 if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, int)))
04283 goto errorout;
04284 break;
04285 case DBUS_TYPE_BOOLEAN:
04286 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
04287 goto errorout;
04288 break;
04289 case DBUS_TYPE_INT32:
04290
04291
04292
04293 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
04294 goto errorout;
04295 break;
04296 case DBUS_TYPE_UINT32:
04297
04298
04299
04300 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
04301 goto errorout;
04302 break;
04303 #ifdef DBUS_HAVE_INT64
04304 case DBUS_TYPE_INT64:
04305 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
04306 goto errorout;
04307 break;
04308 case DBUS_TYPE_UINT64:
04309 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
04310 goto errorout;
04311 break;
04312 #endif
04313 case DBUS_TYPE_DOUBLE:
04314 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
04315 goto errorout;
04316 break;
04317 case DBUS_TYPE_STRING:
04318 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
04319 goto errorout;
04320 break;
04321 case DBUS_TYPE_OBJECT_PATH:
04322 if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
04323 goto errorout;
04324 break;
04325 case DBUS_TYPE_CUSTOM:
04326 {
04327 const char *name;
04328 unsigned char *data;
04329 int len;
04330
04331 name = va_arg (var_args, const char *);
04332 data = va_arg (var_args, unsigned char *);
04333 len = va_arg (var_args, int);
04334
04335 if (!dbus_message_iter_append_custom (&iter, name, data, len))
04336 goto errorout;
04337 break;
04338 }
04339 case DBUS_TYPE_ARRAY:
04340 {
04341 void *data;
04342 int len, type;
04343
04344 type = va_arg (var_args, int);
04345 data = va_arg (var_args, void *);
04346 len = va_arg (var_args, int);
04347
04348 switch (type)
04349 {
04350 case DBUS_TYPE_BYTE:
04351 case DBUS_TYPE_BOOLEAN:
04352 case DBUS_TYPE_INT32:
04353 case DBUS_TYPE_UINT32:
04354 #ifdef DBUS_HAVE_INT64
04355 case DBUS_TYPE_INT64:
04356 case DBUS_TYPE_UINT64:
04357 #endif
04358 case DBUS_TYPE_DOUBLE:
04359 if (!_dbus_message_iter_append_basic_array (&iter, type, data, len))
04360 goto errorout;
04361 break;
04362 case DBUS_TYPE_STRING:
04363 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
04364 goto errorout;
04365 break;
04366 case DBUS_TYPE_OBJECT_PATH:
04367 if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
04368 goto errorout;
04369 break;
04370 case DBUS_TYPE_NIL:
04371 case DBUS_TYPE_ARRAY:
04372 case DBUS_TYPE_CUSTOM:
04373 case DBUS_TYPE_DICT:
04374 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
04375 goto errorout;
04376 default:
04377 _dbus_warn ("Unknown field type %d\n", type);
04378 goto errorout;
04379 }
04380 }
04381 break;
04382
04383 case DBUS_TYPE_DICT:
04384 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
04385 goto errorout;
04386 default:
04387 _dbus_warn ("Unknown field type %d\n", type);
04388 goto errorout;
04389 }
04390
04391 type = va_arg (var_args, int);
04392 }
04393
04394 return TRUE;
04395
04396 errorout:
04397 return FALSE;
04398 }
04399
04408 dbus_bool_t
04409 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
04410 unsigned const char *value,
04411 int len)
04412 {
04413 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN,
04414 value, len);
04415 }
04416
04425 dbus_bool_t
04426 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
04427 const dbus_int32_t *value,
04428 int len)
04429 {
04430 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32,
04431 value, len);
04432 }
04433
04442 dbus_bool_t
04443 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
04444 const dbus_uint32_t *value,
04445 int len)
04446 {
04447 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32,
04448 value, len);
04449 }
04450
04451 #ifdef DBUS_HAVE_INT64
04452
04463 dbus_bool_t
04464 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
04465 const dbus_int64_t *value,
04466 int len)
04467 {
04468 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64,
04469 value, len);
04470 }
04471
04482 dbus_bool_t
04483 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
04484 const dbus_uint64_t *value,
04485 int len)
04486 {
04487 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64,
04488 value, len);
04489 }
04490 #endif
04491
04500 dbus_bool_t
04501 dbus_message_iter_append_double_array (DBusMessageIter *iter,
04502 const double *value,
04503 int len)
04504 {
04505 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE,
04506 value, len);
04507 }
04508
04517 dbus_bool_t
04518 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
04519 unsigned const char *value,
04520 int len)
04521 {
04522 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE,
04523 value, len);
04524 }
04525
04534 dbus_bool_t
04535 dbus_message_iter_append_string_array (DBusMessageIter *iter,
04536 const char **value,
04537 int len)
04538 {
04539 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04540
04541 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04542
04543 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
04544 return FALSE;
04545
04546 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04547 {
04548 _dbus_string_set_length (&real->message->body, real->pos);
04549 return FALSE;
04550 }
04551
04552 dbus_message_iter_append_done (real);
04553
04554 return TRUE;
04555 }
04556
04565 dbus_bool_t
04566 dbus_message_iter_append_object_path_array (DBusMessageIter *iter,
04567 const char **value,
04568 int len)
04569 {
04570 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04571
04572 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04573
04574 if (!append_array_type (real, DBUS_TYPE_OBJECT_PATH, NULL, NULL))
04575 return FALSE;
04576
04577 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04578 {
04579 _dbus_string_set_length (&real->message->body, real->pos);
04580 return FALSE;
04581 }
04582
04583 dbus_message_iter_append_done (real);
04584
04585 return TRUE;
04586 }
04587
04595 dbus_bool_t
04596 dbus_message_set_sender (DBusMessage *message,
04597 const char *sender)
04598 {
04599 _dbus_return_val_if_fail (message != NULL, FALSE);
04600 _dbus_return_val_if_fail (!message->locked, FALSE);
04601
04602 return set_string_field (message,
04603 DBUS_HEADER_FIELD_SENDER,
04604 DBUS_TYPE_STRING,
04605 sender);
04606 }
04607
04618 void
04619 dbus_message_set_no_reply (DBusMessage *message,
04620 dbus_bool_t no_reply)
04621 {
04622 char *header;
04623
04624 _dbus_return_if_fail (message != NULL);
04625 _dbus_return_if_fail (!message->locked);
04626
04627 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04628
04629 if (no_reply)
04630 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04631 else
04632 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04633 }
04634
04642 dbus_bool_t
04643 dbus_message_get_no_reply (DBusMessage *message)
04644 {
04645 const char *header;
04646
04647 _dbus_return_val_if_fail (message != NULL, FALSE);
04648
04649 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04650
04651 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
04652 }
04653
04654
04664 void
04665 dbus_message_set_auto_activation (DBusMessage *message,
04666 dbus_bool_t auto_activation)
04667 {
04668 char *header;
04669
04670 _dbus_return_if_fail (message != NULL);
04671 _dbus_return_if_fail (!message->locked);
04672
04673 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04674
04675 if (auto_activation)
04676 *header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04677 else
04678 *header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04679 }
04680
04688 dbus_bool_t
04689 dbus_message_get_auto_activation (DBusMessage *message)
04690 {
04691 const char *header;
04692
04693 _dbus_return_val_if_fail (message != NULL, FALSE);
04694
04695 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04696
04697 return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0;
04698 }
04699
04707 const char*
04708 dbus_message_get_sender (DBusMessage *message)
04709 {
04710 _dbus_return_val_if_fail (message != NULL, NULL);
04711
04712 return get_string_field (message,
04713 DBUS_HEADER_FIELD_SENDER,
04714 NULL);
04715 }
04716
04732 const char*
04733 dbus_message_get_signature (DBusMessage *message)
04734 {
04735 _dbus_return_val_if_fail (message != NULL, NULL);
04736
04737 return get_string_field (message,
04738 DBUS_HEADER_FIELD_SIGNATURE,
04739 NULL);
04740 }
04741
04742 static dbus_bool_t
04743 _dbus_message_has_type_interface_member (DBusMessage *message,
04744 int type,
04745 const char *interface,
04746 const char *method)
04747 {
04748 const char *n;
04749
04750 _dbus_assert (message != NULL);
04751 _dbus_assert (interface != NULL);
04752 _dbus_assert (method != NULL);
04753
04754 if (dbus_message_get_type (message) != type)
04755 return FALSE;
04756
04757
04758
04759
04760
04761 n = dbus_message_get_member (message);
04762
04763 if (n && strcmp (n, method) == 0)
04764 {
04765 n = dbus_message_get_interface (message);
04766
04767 if (n && strcmp (n, interface) == 0)
04768 return TRUE;
04769 }
04770
04771 return FALSE;
04772 }
04773
04786 dbus_bool_t
04787 dbus_message_is_method_call (DBusMessage *message,
04788 const char *interface,
04789 const char *method)
04790 {
04791 _dbus_return_val_if_fail (message != NULL, FALSE);
04792 _dbus_return_val_if_fail (interface != NULL, FALSE);
04793 _dbus_return_val_if_fail (method != NULL, FALSE);
04794
04795 return _dbus_message_has_type_interface_member (message,
04796 DBUS_MESSAGE_TYPE_METHOD_CALL,
04797 interface, method);
04798 }
04799
04812 dbus_bool_t
04813 dbus_message_is_signal (DBusMessage *message,
04814 const char *interface,
04815 const char *signal_name)
04816 {
04817 _dbus_return_val_if_fail (message != NULL, FALSE);
04818 _dbus_return_val_if_fail (interface != NULL, FALSE);
04819 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
04820
04821 return _dbus_message_has_type_interface_member (message,
04822 DBUS_MESSAGE_TYPE_SIGNAL,
04823 interface, signal_name);
04824 }
04825
04836 dbus_bool_t
04837 dbus_message_is_error (DBusMessage *message,
04838 const char *error_name)
04839 {
04840 const char *n;
04841
04842 _dbus_return_val_if_fail (message != NULL, FALSE);
04843 _dbus_return_val_if_fail (error_name != NULL, FALSE);
04844 _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE);
04845
04846 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04847 return FALSE;
04848
04849 n = dbus_message_get_error_name (message);
04850
04851 if (n && strcmp (n, error_name) == 0)
04852 return TRUE;
04853 else
04854 return FALSE;
04855 }
04856
04867 dbus_bool_t
04868 dbus_message_has_destination (DBusMessage *message,
04869 const char *service)
04870 {
04871 const char *s;
04872
04873 _dbus_return_val_if_fail (message != NULL, FALSE);
04874 _dbus_return_val_if_fail (service != NULL, FALSE);
04875
04876 s = dbus_message_get_destination (message);
04877
04878 if (s && strcmp (s, service) == 0)
04879 return TRUE;
04880 else
04881 return FALSE;
04882 }
04883
04898 dbus_bool_t
04899 dbus_message_has_sender (DBusMessage *message,
04900 const char *service)
04901 {
04902 const char *s;
04903
04904 _dbus_return_val_if_fail (message != NULL, FALSE);
04905 _dbus_return_val_if_fail (service != NULL, FALSE);
04906
04907 s = dbus_message_get_sender (message);
04908
04909 if (s && strcmp (s, service) == 0)
04910 return TRUE;
04911 else
04912 return FALSE;
04913 }
04914
04924 dbus_bool_t
04925 dbus_message_has_signature (DBusMessage *message,
04926 const char *signature)
04927 {
04928 const char *s;
04929
04930 _dbus_return_val_if_fail (message != NULL, FALSE);
04931 _dbus_return_val_if_fail (signature != NULL, FALSE);
04932
04933 s = dbus_message_get_signature (message);
04934
04935 if (s && strcmp (s, signature) == 0)
04936 return TRUE;
04937 else
04938 return FALSE;
04939 }
04940
04958 dbus_bool_t
04959 dbus_set_error_from_message (DBusError *error,
04960 DBusMessage *message)
04961 {
04962 char *str;
04963
04964 _dbus_return_val_if_fail (message != NULL, FALSE);
04965 _dbus_return_val_if_error_is_set (error, FALSE);
04966
04967 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04968 return FALSE;
04969
04970 str = NULL;
04971 dbus_message_get_args (message, NULL,
04972 DBUS_TYPE_STRING, &str,
04973 DBUS_TYPE_INVALID);
04974
04975 dbus_set_error (error, dbus_message_get_error_name (message),
04976 str ? "%s" : NULL, str);
04977
04978 dbus_free (str);
04979
04980 return TRUE;
04981 }
04982
05007
05008
05009
05010
05011
05015 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
05016
05021 struct DBusMessageLoader
05022 {
05023 int refcount;
05025 DBusString data;
05027 DBusList *messages;
05029 long max_message_size;
05031 unsigned int buffer_outstanding : 1;
05033 unsigned int corrupted : 1;
05034 };
05035
05046 #define INITIAL_LOADER_DATA_LEN 32
05047
05054 DBusMessageLoader*
05055 _dbus_message_loader_new (void)
05056 {
05057 DBusMessageLoader *loader;
05058
05059 loader = dbus_new0 (DBusMessageLoader, 1);
05060 if (loader == NULL)
05061 return NULL;
05062
05063 loader->refcount = 1;
05064
05065
05066
05067
05068 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
05069
05070 if (!_dbus_string_init (&loader->data))
05071 {
05072 dbus_free (loader);
05073 return NULL;
05074 }
05075
05076
05077 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
05078 _dbus_string_set_length (&loader->data, 0);
05079
05080 return loader;
05081 }
05082
05089 DBusMessageLoader *
05090 _dbus_message_loader_ref (DBusMessageLoader *loader)
05091 {
05092 loader->refcount += 1;
05093
05094 return loader;
05095 }
05096
05103 void
05104 _dbus_message_loader_unref (DBusMessageLoader *loader)
05105 {
05106 loader->refcount -= 1;
05107 if (loader->refcount == 0)
05108 {
05109 _dbus_list_foreach (&loader->messages,
05110 (DBusForeachFunction) dbus_message_unref,
05111 NULL);
05112 _dbus_list_clear (&loader->messages);
05113 _dbus_string_free (&loader->data);
05114 dbus_free (loader);
05115 }
05116 }
05117
05136 void
05137 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
05138 DBusString **buffer)
05139 {
05140 _dbus_assert (!loader->buffer_outstanding);
05141
05142 *buffer = &loader->data;
05143
05144 loader->buffer_outstanding = TRUE;
05145 }
05146
05151 #define DBUS_MINIMUM_HEADER_SIZE 16
05152
05153 static dbus_bool_t
05154 decode_string_field (const DBusString *data,
05155 int field,
05156 HeaderField *header_field,
05157 DBusString *field_data,
05158 int pos,
05159 int type)
05160 {
05161 int string_data_pos;
05162
05163 _dbus_assert (header_field != NULL);
05164 _dbus_assert (field_data != NULL);
05165
05166 if (header_field->name_offset >= 0)
05167 {
05168 _dbus_verbose ("%s field provided twice\n",
05169 _dbus_header_field_to_string (field));
05170 return FALSE;
05171 }
05172
05173 if (type != DBUS_TYPE_STRING)
05174 {
05175 _dbus_verbose ("%s field has wrong type %s\n",
05176 _dbus_header_field_to_string (field),
05177 _dbus_type_to_string (type));
05178 return FALSE;
05179 }
05180
05181
05182
05183
05184
05185 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
05186 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
05187
05188 _dbus_string_init_const (field_data,
05189 _dbus_string_get_const_data (data) + string_data_pos);
05190
05191 header_field->name_offset = pos - 2;
05192 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05193
05194 #if 0
05195 _dbus_verbose ("Found field %s at offset %d\n",
05196 _dbus_header_field_to_string (field),
05197 header_field->value_offset);
05198 #endif
05199
05200 return TRUE;
05201 }
05202
05203
05204
05205
05206
05207
05208
05209 static dbus_bool_t
05210 decode_header_data (const DBusString *data,
05211 int header_len,
05212 int byte_order,
05213 int message_type,
05214 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
05215 int *message_padding)
05216 {
05217 DBusString field_data;
05218 int pos, new_pos;
05219 int i;
05220 int field;
05221 int type;
05222 dbus_bool_t signature_required;
05223
05224 if (header_len < 16)
05225 {
05226 _dbus_verbose ("Header length %d is too short\n", header_len);
05227 return FALSE;
05228 }
05229
05230 i = 0;
05231 while (i <= DBUS_HEADER_FIELD_LAST)
05232 {
05233 fields[i].name_offset = -1;
05234 fields[i].value_offset = -1;
05235 ++i;
05236 }
05237
05238 pos = 16;
05239 while (pos < header_len)
05240 {
05241 field = _dbus_string_get_byte (data, pos);
05242 if (field == DBUS_HEADER_FIELD_INVALID)
05243 break;
05244 pos++;
05245
05246 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
05247 {
05248 _dbus_verbose ("Failed to validate type of named header field pos = %d\n",
05249 pos);
05250 return FALSE;
05251 }
05252
05253 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
05254 {
05255 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n",
05256 pos);
05257 return FALSE;
05258 }
05259
05260 if (new_pos > header_len)
05261 {
05262 _dbus_verbose ("Named header field tries to extend beyond header length\n");
05263 return FALSE;
05264 }
05265
05266 switch (field)
05267 {
05268 case DBUS_HEADER_FIELD_DESTINATION:
05269 if (!decode_string_field (data, field, &fields[field],
05270 &field_data, pos, type))
05271 return FALSE;
05272
05273 if (!_dbus_string_validate_service (&field_data, 0,
05274 _dbus_string_get_length (&field_data)))
05275 {
05276 _dbus_verbose ("service field has invalid content \"%s\"\n",
05277 _dbus_string_get_const_data (&field_data));
05278 return FALSE;
05279 }
05280 break;
05281
05282 case DBUS_HEADER_FIELD_INTERFACE:
05283 if (!decode_string_field (data, field, &fields[field],
05284 &field_data, pos, type))
05285 return FALSE;
05286
05287 if (!_dbus_string_validate_interface (&field_data, 0,
05288 _dbus_string_get_length (&field_data)))
05289 {
05290 _dbus_verbose ("interface field has invalid content \"%s\"\n",
05291 _dbus_string_get_const_data (&field_data));
05292 return FALSE;
05293 }
05294
05295 if (_dbus_string_equal_c_str (&field_data,
05296 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
05297 {
05298 _dbus_verbose ("Message is on the local interface\n");
05299 return FALSE;
05300 }
05301 break;
05302
05303 case DBUS_HEADER_FIELD_MEMBER:
05304 if (!decode_string_field (data, field, &fields[field],
05305 &field_data, pos, type))
05306 return FALSE;
05307
05308 if (!_dbus_string_validate_member (&field_data, 0,
05309 _dbus_string_get_length (&field_data)))
05310 {
05311 _dbus_verbose ("member field has invalid content \"%s\"\n",
05312 _dbus_string_get_const_data (&field_data));
05313 return FALSE;
05314 }
05315 break;
05316
05317 case DBUS_HEADER_FIELD_ERROR_NAME:
05318 if (!decode_string_field (data, field, &fields[field],
05319 &field_data, pos, type))
05320 return FALSE;
05321
05322 if (!_dbus_string_validate_error_name (&field_data, 0,
05323 _dbus_string_get_length (&field_data)))
05324 {
05325 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
05326 _dbus_string_get_const_data (&field_data));
05327 return FALSE;
05328 }
05329 break;
05330
05331 case DBUS_HEADER_FIELD_SENDER:
05332 if (!decode_string_field (data, field, &fields[field],
05333 &field_data, pos, type))
05334 return FALSE;
05335
05336 if (!_dbus_string_validate_service (&field_data, 0,
05337 _dbus_string_get_length (&field_data)))
05338 {
05339 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
05340 _dbus_string_get_const_data (&field_data));
05341 return FALSE;
05342 }
05343 break;
05344
05345 case DBUS_HEADER_FIELD_PATH:
05346
05347
05348
05349
05350
05351
05352 if (fields[field].name_offset >= 0)
05353 {
05354 _dbus_verbose ("path field provided twice\n");
05355 return FALSE;
05356 }
05357 if (type != DBUS_TYPE_OBJECT_PATH)
05358 {
05359 _dbus_verbose ("path field has wrong type\n");
05360 return FALSE;
05361 }
05362
05363 fields[field].name_offset = pos - 2;
05364 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05365
05366
05367 {
05368 const char *s;
05369 s = _dbus_string_get_const_data_len (data,
05370 fields[field].value_offset,
05371 _dbus_string_get_length (data) -
05372 fields[field].value_offset);
05373 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
05374 {
05375 _dbus_verbose ("Message is on the local path\n");
05376 return FALSE;
05377 }
05378 }
05379
05380 _dbus_verbose ("Found path at offset %d\n",
05381 fields[field].value_offset);
05382 break;
05383
05384 case DBUS_HEADER_FIELD_REPLY_SERIAL:
05385 if (fields[field].name_offset >= 0)
05386 {
05387 _dbus_verbose ("reply field provided twice\n");
05388 return FALSE;
05389 }
05390
05391 if (type != DBUS_TYPE_UINT32)
05392 {
05393 _dbus_verbose ("reply field has wrong type\n");
05394 return FALSE;
05395 }
05396
05397 fields[field].name_offset = pos - 2;
05398 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05399
05400 _dbus_verbose ("Found reply serial %u at offset %d\n",
05401 _dbus_demarshal_uint32 (data,
05402 byte_order,
05403 fields[field].value_offset,
05404 NULL),
05405 fields[field].value_offset);
05406 break;
05407
05408 case DBUS_HEADER_FIELD_SIGNATURE:
05409 if (!decode_string_field (data, field, &fields[field],
05410 &field_data, pos, type))
05411 return FALSE;
05412
05413 if (!_dbus_string_validate_signature (&field_data, 0,
05414 _dbus_string_get_length (&field_data)))
05415 {
05416 _dbus_verbose ("signature field has invalid content \"%s\"\n",
05417 _dbus_string_get_const_data (&field_data));
05418 return FALSE;
05419 }
05420 break;
05421
05422 default:
05423 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
05424 field, pos);
05425 }
05426
05427 pos = new_pos;
05428 }
05429
05430 if (pos < header_len)
05431 {
05432
05433 if ((header_len - pos) >= 8)
05434 {
05435 _dbus_verbose ("too much header alignment padding\n");
05436 return FALSE;
05437 }
05438
05439 if (!_dbus_string_validate_nul (data,
05440 pos, (header_len - pos)))
05441 {
05442 _dbus_verbose ("header alignment padding is not nul\n");
05443 return FALSE;
05444 }
05445 }
05446
05447
05448 signature_required = TRUE;
05449
05450 switch (message_type)
05451 {
05452 case DBUS_MESSAGE_TYPE_SIGNAL:
05453 case DBUS_MESSAGE_TYPE_METHOD_CALL:
05454 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
05455 {
05456 _dbus_verbose ("No path field provided\n");
05457 return FALSE;
05458 }
05459
05460 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
05461 {
05462 _dbus_verbose ("No interface field provided\n");
05463 return FALSE;
05464 }
05465 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
05466 {
05467 _dbus_verbose ("No member field provided\n");
05468 return FALSE;
05469 }
05470 break;
05471 case DBUS_MESSAGE_TYPE_ERROR:
05472 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
05473 {
05474 _dbus_verbose ("No error-name field provided\n");
05475 return FALSE;
05476 }
05477 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05478 {
05479 _dbus_verbose ("No reply serial field provided in error\n");
05480 return FALSE;
05481 }
05482 break;
05483 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
05484 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05485 {
05486 _dbus_verbose ("No reply serial field provided in method return\n");
05487 return FALSE;
05488 }
05489 break;
05490 default:
05491
05492 signature_required = FALSE;
05493 break;
05494 }
05495
05496
05497 if (signature_required)
05498 {
05499 if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0)
05500 {
05501 _dbus_verbose ("No signature field provided\n");
05502 return FALSE;
05503 }
05504 }
05505
05506 if (message_padding)
05507 *message_padding = header_len - pos;
05508
05509 return TRUE;
05510 }
05511
05522 void
05523 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
05524 DBusString *buffer,
05525 int bytes_read)
05526 {
05527 _dbus_assert (loader->buffer_outstanding);
05528 _dbus_assert (buffer == &loader->data);
05529
05530 loader->buffer_outstanding = FALSE;
05531 }
05532
05533 static dbus_bool_t
05534 load_one_message (DBusMessageLoader *loader,
05535 int byte_order,
05536 int message_type,
05537 int header_len,
05538 int body_len)
05539 {
05540 DBusMessage *message;
05541 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
05542 int i;
05543 int next_arg;
05544 dbus_bool_t oom;
05545 int header_padding;
05546
05547 message = NULL;
05548 oom = FALSE;
05549
05550 #if 0
05551 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
05552 #endif
05553
05554 if (!decode_header_data (&loader->data,
05555 header_len, byte_order,
05556 message_type,
05557 fields, &header_padding))
05558 {
05559 _dbus_verbose ("Header was invalid\n");
05560 loader->corrupted = TRUE;
05561 goto failed;
05562 }
05563
05564 next_arg = header_len;
05565 while (next_arg < (header_len + body_len))
05566 {
05567 int type;
05568 int prev = next_arg;
05569
05570 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
05571 &type, &next_arg))
05572 {
05573 _dbus_verbose ("invalid typecode at offset %d\n", prev);
05574 loader->corrupted = TRUE;
05575 goto failed;
05576 }
05577
05578 if (!_dbus_marshal_validate_arg (&loader->data,
05579 byte_order,
05580 0,
05581 type, -1,
05582 next_arg,
05583 &next_arg))
05584 {
05585 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
05586 loader->corrupted = TRUE;
05587 goto failed;
05588 }
05589
05590 _dbus_assert (next_arg > prev);
05591 }
05592
05593 if (next_arg > (header_len + body_len))
05594 {
05595 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
05596 next_arg, header_len, body_len,
05597 header_len + body_len);
05598 loader->corrupted = TRUE;
05599 goto failed;
05600 }
05601
05602 message = dbus_message_new_empty_header ();
05603 if (message == NULL)
05604 {
05605 _dbus_verbose ("Failed to allocate empty message\n");
05606 oom = TRUE;
05607 goto failed;
05608 }
05609
05610 message->byte_order = byte_order;
05611 message->header_padding = header_padding;
05612
05613
05614 i = 0;
05615 while (i <= DBUS_HEADER_FIELD_LAST)
05616 {
05617 message->header_fields[i] = fields[i];
05618 ++i;
05619 }
05620
05621 if (!_dbus_list_append (&loader->messages, message))
05622 {
05623 _dbus_verbose ("Failed to append new message to loader queue\n");
05624 oom = TRUE;
05625 goto failed;
05626 }
05627
05628 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
05629 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
05630
05631 _dbus_assert (_dbus_string_get_length (&loader->data) >=
05632 (header_len + body_len));
05633
05634 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
05635 {
05636 _dbus_verbose ("Failed to move header into new message\n");
05637 oom = TRUE;
05638 goto failed;
05639 }
05640
05641 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
05642 {
05643 _dbus_verbose ("Failed to move body into new message\n");
05644
05645 oom = TRUE;
05646 goto failed;
05647 }
05648
05649 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
05650 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
05651
05652
05653
05654
05655 message->reply_serial = get_uint_field (message,
05656 DBUS_HEADER_FIELD_REPLY_SERIAL);
05657
05658 message->client_serial = _dbus_demarshal_uint32 (&message->header,
05659 message->byte_order,
05660 CLIENT_SERIAL_OFFSET,
05661 NULL);
05662 if (message->client_serial == 0 ||
05663 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0))
05664 {
05665 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n",
05666 message->client_serial,
05667 message->reply_serial);
05668
05669 loader->corrupted = TRUE;
05670 goto failed;
05671 }
05672
05673 _dbus_verbose ("Loaded message %p\n", message);
05674
05675 _dbus_assert (!oom);
05676 _dbus_assert (!loader->corrupted);
05677
05678 return TRUE;
05679
05680 failed:
05681
05682
05683
05684 if (message != NULL)
05685 {
05686
05687 if (_dbus_string_get_length (&message->body) > 0)
05688 {
05689 dbus_bool_t result;
05690
05691 result = _dbus_string_copy_len (&message->body, 0, body_len,
05692 &loader->data, 0);
05693
05694 _dbus_assert (result);
05695 }
05696
05697 if (_dbus_string_get_length (&message->header) > 0)
05698 {
05699 dbus_bool_t result;
05700
05701 result = _dbus_string_copy_len (&message->header, 0, header_len,
05702 &loader->data, 0);
05703
05704 _dbus_assert (result);
05705 }
05706
05707
05708 _dbus_list_remove_last (&loader->messages, message);
05709
05710 dbus_message_unref (message);
05711 }
05712
05713
05714 return !oom;
05715 }
05716
05730 dbus_bool_t
05731 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
05732 {
05733 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16)
05734 {
05735 const char *header_data;
05736 int byte_order, message_type, header_len, body_len;
05737 dbus_uint32_t header_len_unsigned, body_len_unsigned;
05738
05739 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
05740
05741 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
05742
05743 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
05744 {
05745 _dbus_verbose ("Message has protocol version %d ours is %d\n",
05746 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
05747 loader->corrupted = TRUE;
05748 return TRUE;
05749 }
05750
05751 byte_order = header_data[BYTE_ORDER_OFFSET];
05752
05753 if (byte_order != DBUS_LITTLE_ENDIAN &&
05754 byte_order != DBUS_BIG_ENDIAN)
05755 {
05756 _dbus_verbose ("Message with bad byte order '%c' received\n",
05757 byte_order);
05758 loader->corrupted = TRUE;
05759 return TRUE;
05760 }
05761
05762
05763
05764
05765 message_type = header_data[TYPE_OFFSET];
05766 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
05767 {
05768 _dbus_verbose ("Message with bad type '%d' received\n",
05769 message_type);
05770 loader->corrupted = TRUE;
05771 return TRUE;
05772 }
05773
05774 header_len_unsigned = _dbus_unpack_uint32 (byte_order,
05775 (const unsigned char *) header_data + 4);
05776 body_len_unsigned = _dbus_unpack_uint32 (byte_order,
05777 (const unsigned char *) header_data + 8);
05778
05779 if (header_len_unsigned < 16)
05780 {
05781 _dbus_verbose ("Message had broken too-small header length %u\n",
05782 header_len_unsigned);
05783 loader->corrupted = TRUE;
05784 return TRUE;
05785 }
05786
05787 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
05788 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
05789 {
05790 _dbus_verbose ("Header or body length too large (%u %u)\n",
05791 header_len_unsigned,
05792 body_len_unsigned);
05793 loader->corrupted = TRUE;
05794 return TRUE;
05795 }
05796
05797
05798
05799
05800 header_len = header_len_unsigned;
05801 body_len = body_len_unsigned;
05802
05803 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
05804 {
05805
05806 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
05807 header_len);
05808 loader->corrupted = TRUE;
05809 return TRUE;
05810 }
05811
05812 if (header_len + body_len > loader->max_message_size)
05813 {
05814 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
05815 header_len, body_len, loader->max_message_size);
05816 loader->corrupted = TRUE;
05817 return TRUE;
05818 }
05819
05820 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
05821 {
05822 if (!load_one_message (loader, byte_order, message_type,
05823 header_len, body_len))
05824 return FALSE;
05825 }
05826 else
05827 return TRUE;
05828 }
05829
05830 return TRUE;
05831 }
05832
05840 DBusMessage*
05841 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
05842 {
05843 if (loader->messages)
05844 return loader->messages->data;
05845 else
05846 return NULL;
05847 }
05848
05857 DBusMessage*
05858 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
05859 {
05860 return _dbus_list_pop_first (&loader->messages);
05861 }
05862
05871 DBusList*
05872 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
05873 {
05874 return _dbus_list_pop_first_link (&loader->messages);
05875 }
05876
05883 void
05884 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
05885 DBusList *link)
05886 {
05887 _dbus_list_prepend_link (&loader->messages, link);
05888 }
05889
05899 dbus_bool_t
05900 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
05901 {
05902 return loader->corrupted;
05903 }
05904
05911 void
05912 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
05913 long size)
05914 {
05915 if (size > MAX_SANE_MESSAGE_SIZE)
05916 {
05917 _dbus_verbose ("clamping requested max message size %ld to %d\n",
05918 size, MAX_SANE_MESSAGE_SIZE);
05919 size = MAX_SANE_MESSAGE_SIZE;
05920 }
05921 loader->max_message_size = size;
05922 }
05923
05930 long
05931 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
05932 {
05933 return loader->max_message_size;
05934 }
05935
05936 static DBusDataSlotAllocator slot_allocator;
05937 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
05938
05953 dbus_bool_t
05954 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
05955 {
05956 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05957 _DBUS_LOCK_NAME (message_slots),
05958 slot_p);
05959 }
05960
05972 void
05973 dbus_message_free_data_slot (dbus_int32_t *slot_p)
05974 {
05975 _dbus_return_if_fail (*slot_p >= 0);
05976
05977 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05978 }
05979
05993 dbus_bool_t
05994 dbus_message_set_data (DBusMessage *message,
05995 dbus_int32_t slot,
05996 void *data,
05997 DBusFreeFunction free_data_func)
05998 {
05999 DBusFreeFunction old_free_func;
06000 void *old_data;
06001 dbus_bool_t retval;
06002
06003 _dbus_return_val_if_fail (message != NULL, FALSE);
06004 _dbus_return_val_if_fail (slot >= 0, FALSE);
06005
06006 retval = _dbus_data_slot_list_set (&slot_allocator,
06007 &message->slot_list,
06008 slot, data, free_data_func,
06009 &old_free_func, &old_data);
06010
06011 if (retval)
06012 {
06013
06014 if (old_free_func)
06015 (* old_free_func) (old_data);
06016 }
06017
06018 return retval;
06019 }
06020
06029 void*
06030 dbus_message_get_data (DBusMessage *message,
06031 dbus_int32_t slot)
06032 {
06033 void *res;
06034
06035 _dbus_return_val_if_fail (message != NULL, NULL);
06036
06037 res = _dbus_data_slot_list_get (&slot_allocator,
06038 &message->slot_list,
06039 slot);
06040
06041 return res;
06042 }
06043
06057 int
06058 dbus_message_type_from_string (const char *type_str)
06059 {
06060 if (strcmp (type_str, "method_call") == 0)
06061 return DBUS_MESSAGE_TYPE_METHOD_CALL;
06062 if (strcmp (type_str, "method_return") == 0)
06063 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
06064 else if (strcmp (type_str, "signal") == 0)
06065 return DBUS_MESSAGE_TYPE_SIGNAL;
06066 else if (strcmp (type_str, "error") == 0)
06067 return DBUS_MESSAGE_TYPE_ERROR;
06068 else
06069 return DBUS_MESSAGE_TYPE_INVALID;
06070 }
06071
06085 const char *
06086 dbus_message_type_to_string (int type)
06087 {
06088 switch (type)
06089 {
06090 case DBUS_MESSAGE_TYPE_METHOD_CALL:
06091 return "method_call";
06092 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
06093 return "method_return";
06094 case DBUS_MESSAGE_TYPE_SIGNAL:
06095 return "signal";
06096 case DBUS_MESSAGE_TYPE_ERROR:
06097 return "error";
06098 default:
06099 return "invalid";
06100 }
06101 }
06102
06104 #ifdef DBUS_BUILD_TESTS
06105 #include "dbus-test.h"
06106 #include <stdio.h>
06107 #include <stdlib.h>
06108
06109 static void
06110 message_iter_test (DBusMessage *message)
06111 {
06112 DBusMessageIter iter, dict, dict2, array, array2;
06113 char *str;
06114 unsigned char *data;
06115 dbus_int32_t *our_int_array;
06116 int len;
06117
06118 dbus_message_iter_init (message, &iter);
06119
06120
06121 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
06122 _dbus_assert_not_reached ("Argument type isn't string");
06123
06124 str = dbus_message_iter_get_string (&iter);
06125 if (strcmp (str, "Test string") != 0)
06126 _dbus_assert_not_reached ("Strings differ");
06127 dbus_free (str);
06128
06129 if (!dbus_message_iter_next (&iter))
06130 _dbus_assert_not_reached ("Reached end of arguments");
06131
06132
06133 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
06134 _dbus_assert_not_reached ("Argument type isn't int32");
06135
06136 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
06137 _dbus_assert_not_reached ("Signed integers differ");
06138
06139 if (!dbus_message_iter_next (&iter))
06140 _dbus_assert_not_reached ("Reached end of fields");
06141
06142
06143 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
06144 _dbus_assert_not_reached ("Argument type isn't int32");
06145
06146 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
06147 _dbus_assert_not_reached ("Unsigned integers differ");
06148
06149 if (!dbus_message_iter_next (&iter))
06150 _dbus_assert_not_reached ("Reached end of arguments");
06151
06152
06153 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
06154 _dbus_assert_not_reached ("Argument type isn't double");
06155
06156 if (dbus_message_iter_get_double (&iter) != 3.14159)
06157 _dbus_assert_not_reached ("Doubles differ");
06158
06159 if (!dbus_message_iter_next (&iter))
06160 _dbus_assert_not_reached ("Reached end of arguments");
06161
06162 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
06163 _dbus_assert_not_reached ("Argument type not an array");
06164
06165 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
06166 _dbus_assert_not_reached ("Array type not double");
06167
06168
06169 dbus_message_iter_init_array_iterator (&iter, &array, NULL);
06170
06171 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
06172 _dbus_assert_not_reached ("Argument type isn't double");
06173
06174 if (dbus_message_iter_get_double (&array) != 1.5)
06175 _dbus_assert_not_reached ("Unsigned integers differ");
06176
06177 if (!dbus_message_iter_next (&array))
06178 _dbus_assert_not_reached ("Reached end of arguments");
06179
06180 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
06181 _dbus_assert_not_reached ("Argument type isn't double");
06182
06183 if (dbus_message_iter_get_double (&array) != 2.5)
06184 _dbus_assert_not_reached ("Unsigned integers differ");
06185
06186 if (dbus_message_iter_next (&array))
06187 _dbus_assert_not_reached ("Didn't reach end of arguments");
06188
06189 if (!dbus_message_iter_next (&iter))
06190 _dbus_assert_not_reached ("Reached end of arguments");
06191
06192
06193
06194
06195 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06196 _dbus_assert_not_reached ("not dict type");
06197
06198 dbus_message_iter_init_dict_iterator (&iter, &dict);
06199
06200 str = dbus_message_iter_get_dict_key (&dict);
06201 if (str == NULL || strcmp (str, "test") != 0)
06202 _dbus_assert_not_reached ("wrong dict key");
06203 dbus_free (str);
06204
06205 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
06206 _dbus_assert_not_reached ("wrong dict entry type");
06207
06208 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
06209 _dbus_assert_not_reached ("wrong dict entry value");
06210
06211
06212
06213 if (!dbus_message_iter_next (&dict))
06214 _dbus_assert_not_reached ("reached end of dict");
06215
06216 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_DICT)
06217 _dbus_assert_not_reached ("not dict type");
06218
06219 dbus_message_iter_init_dict_iterator (&dict, &dict2);
06220
06221 str = dbus_message_iter_get_dict_key (&dict2);
06222 if (str == NULL || strcmp (str, "dictkey") != 0)
06223 _dbus_assert_not_reached ("wrong dict key");
06224 dbus_free (str);
06225
06226 if (dbus_message_iter_get_arg_type (&dict2) != DBUS_TYPE_STRING)
06227 _dbus_assert_not_reached ("wrong dict entry type");
06228
06229 str = dbus_message_iter_get_string (&dict2);
06230 if (str == NULL || strcmp (str, "dictvalue") != 0)
06231 _dbus_assert_not_reached ("wrong dict entry value");
06232 dbus_free (str);
06233
06234 if (dbus_message_iter_next (&dict2))
06235 _dbus_assert_not_reached ("didn't reach end of dict");
06236
06237 if (!dbus_message_iter_next (&dict))
06238 _dbus_assert_not_reached ("reached end of dict");
06239
06240
06241
06242 str = dbus_message_iter_get_dict_key (&dict);
06243 if (str == NULL || strcmp (str, "array") != 0)
06244 _dbus_assert_not_reached ("wrong dict key");
06245 dbus_free (str);
06246
06247 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
06248 _dbus_assert_not_reached ("Argument type not an array");
06249
06250 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
06251 _dbus_assert_not_reached ("Array type not array");
06252
06253 dbus_message_iter_init_array_iterator (&dict, &array, NULL);
06254
06255 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
06256 _dbus_assert_not_reached ("Argument type isn't array");
06257
06258 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
06259 _dbus_assert_not_reached ("Array type not int32");
06260
06261 dbus_message_iter_init_array_iterator (&array, &array2, NULL);
06262
06263 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
06264 _dbus_assert_not_reached ("Argument type isn't int32");
06265
06266 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
06267 _dbus_assert_not_reached ("Signed integers differ");
06268
06269 if (!dbus_message_iter_next (&array2))
06270 _dbus_assert_not_reached ("Reached end of arguments");
06271
06272 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
06273 _dbus_assert_not_reached ("Signed integers differ");
06274
06275 if (dbus_message_iter_next (&array2))
06276 _dbus_assert_not_reached ("Didn't reached end of arguments");
06277
06278 if (!dbus_message_iter_next (&array))
06279 _dbus_assert_not_reached ("Reached end of arguments");
06280
06281 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
06282 _dbus_assert_not_reached ("Array type not int32");
06283
06284 if (!dbus_message_iter_get_int32_array (&array,
06285 &our_int_array,
06286 &len))
06287 _dbus_assert_not_reached ("couldn't get int32 array");
06288
06289 _dbus_assert (len == 3);
06290 _dbus_assert (our_int_array[0] == 0x34567812 &&
06291 our_int_array[1] == 0x45678123 &&
06292 our_int_array[2] == 0x56781234);
06293 dbus_free (our_int_array);
06294
06295 if (dbus_message_iter_next (&array))
06296 _dbus_assert_not_reached ("Didn't reach end of array");
06297
06298 if (dbus_message_iter_next (&dict))
06299 _dbus_assert_not_reached ("Didn't reach end of dict");
06300
06301 if (!dbus_message_iter_next (&iter))
06302 _dbus_assert_not_reached ("Reached end of arguments");
06303
06304 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
06305 {
06306 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
06307 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
06308 }
06309
06310 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06311 _dbus_assert_not_reached ("wrong value after dict");
06312
06313
06314 if (!dbus_message_iter_next (&iter))
06315 _dbus_assert_not_reached ("Reached end of arguments");
06316
06317 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
06318 _dbus_assert_not_reached ("not a nil type");
06319
06320 if (!dbus_message_iter_next (&iter))
06321 _dbus_assert_not_reached ("Reached end of arguments");
06322
06323 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_CUSTOM)
06324 _dbus_assert_not_reached ("wrong type after dict");
06325
06326 if (!dbus_message_iter_get_custom (&iter, &str, &data, &len))
06327 _dbus_assert_not_reached ("failed to get custom type");
06328
06329 _dbus_assert (strcmp (str, "MyTypeName")==0);
06330 _dbus_assert (len == 5);
06331 _dbus_assert (strcmp (data, "data")==0);
06332 dbus_free (str);
06333 dbus_free (data);
06334
06335 if (!dbus_message_iter_next (&iter))
06336 _dbus_assert_not_reached ("Reached end of arguments");
06337
06338 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06339 _dbus_assert_not_reached ("wrong value after custom");
06340
06341 if (!dbus_message_iter_next (&iter))
06342 _dbus_assert_not_reached ("Reached end of arguments");
06343
06344 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
06345 _dbus_assert_not_reached ("no array");
06346
06347 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_INT32)
06348 _dbus_assert_not_reached ("Array type not int32");
06349
06350 if (dbus_message_iter_init_array_iterator (&iter, &array, NULL))
06351 _dbus_assert_not_reached ("non empty array");
06352
06353 if (!dbus_message_iter_next (&iter))
06354 _dbus_assert_not_reached ("Reached end of arguments");
06355
06356 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06357 _dbus_assert_not_reached ("wrong value after empty array");
06358
06359 if (!dbus_message_iter_next (&iter))
06360 _dbus_assert_not_reached ("Reached end of arguments");
06361
06362 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
06363 _dbus_assert_not_reached ("non dict");
06364
06365 if (dbus_message_iter_init_dict_iterator (&iter, &dict))
06366 _dbus_assert_not_reached ("non empty dict");
06367
06368 if (!dbus_message_iter_next (&iter))
06369 _dbus_assert_not_reached ("Reached end of arguments");
06370
06371 if (dbus_message_iter_get_byte (&iter) != 0xF0)
06372 _dbus_assert_not_reached ("wrong value after empty dict");
06373
06374 if (dbus_message_iter_next (&iter))
06375 _dbus_assert_not_reached ("Didn't reach end of arguments");
06376 }
06377
06378
06379 static dbus_bool_t
06380 check_message_handling_type (DBusMessageIter *iter,
06381 int type)
06382 {
06383 DBusMessageIter child_iter;
06384
06385 switch (type)
06386 {
06387 case DBUS_TYPE_NIL:
06388 break;
06389 case DBUS_TYPE_BYTE:
06390 dbus_message_iter_get_byte (iter);
06391 break;
06392 case DBUS_TYPE_BOOLEAN:
06393 dbus_message_iter_get_boolean (iter);
06394 break;
06395 case DBUS_TYPE_INT32:
06396 dbus_message_iter_get_int32 (iter);
06397 break;
06398 case DBUS_TYPE_UINT32:
06399 dbus_message_iter_get_uint32 (iter);
06400 break;
06401 case DBUS_TYPE_INT64:
06402 #ifdef DBUS_HAVE_INT64
06403 dbus_message_iter_get_int64 (iter);
06404 #endif
06405 break;
06406 case DBUS_TYPE_UINT64:
06407 #ifdef DBUS_HAVE_INT64
06408 dbus_message_iter_get_uint64 (iter);
06409 #endif
06410 break;
06411 case DBUS_TYPE_DOUBLE:
06412 dbus_message_iter_get_double (iter);
06413 break;
06414 case DBUS_TYPE_STRING:
06415 {
06416 char *str;
06417 str = dbus_message_iter_get_string (iter);
06418 if (str == NULL)
06419 {
06420 _dbus_warn ("NULL string in message\n");
06421 return FALSE;
06422 }
06423 dbus_free (str);
06424 }
06425 break;
06426 case DBUS_TYPE_CUSTOM:
06427 {
06428 char *name;
06429 unsigned char *data;
06430 int len;
06431
06432 if (!dbus_message_iter_get_custom (iter, &name, &data, &len))
06433 {
06434 _dbus_warn ("error reading name from custom type\n");
06435 return FALSE;
06436 }
06437 dbus_free (data);
06438 dbus_free (name);
06439 }
06440 break;
06441 case DBUS_TYPE_ARRAY:
06442 {
06443 int array_type;
06444
06445 dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type);
06446
06447 while (dbus_message_iter_has_next (&child_iter))
06448 {
06449 if (!check_message_handling_type (&child_iter, array_type))
06450 {
06451 _dbus_warn ("error in array element\n");
06452 return FALSE;
06453 }
06454
06455 if (!dbus_message_iter_next (&child_iter))
06456 break;
06457 }
06458 }
06459 break;
06460 case DBUS_TYPE_DICT:
06461 {
06462 int entry_type;
06463 char *key;
06464
06465 dbus_message_iter_init_dict_iterator (iter, &child_iter);
06466
06467 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
06468 {
06469 key = dbus_message_iter_get_dict_key (&child_iter);
06470 if (key == NULL)
06471 {
06472 _dbus_warn ("error reading dict key\n");
06473 return FALSE;
06474 }
06475 dbus_free (key);
06476
06477 if (!check_message_handling_type (&child_iter, entry_type))
06478 {
06479 _dbus_warn ("error in dict value\n");
06480 return FALSE;
06481 }
06482
06483 if (!dbus_message_iter_next (&child_iter))
06484 break;
06485 }
06486 }
06487 break;
06488
06489 default:
06490 _dbus_warn ("unknown type %d\n", type);
06491 return FALSE;
06492 break;
06493 }
06494 return TRUE;
06495 }
06496
06497
06498 static dbus_bool_t
06499 check_message_handling (DBusMessage *message)
06500 {
06501 DBusMessageIter iter;
06502 int type;
06503 dbus_bool_t retval;
06504 dbus_uint32_t client_serial;
06505
06506 retval = FALSE;
06507
06508 client_serial = dbus_message_get_serial (message);
06509
06510
06511 _dbus_marshal_set_uint32 (&message->header,
06512 message->byte_order,
06513 CLIENT_SERIAL_OFFSET,
06514 client_serial);
06515
06516 if (client_serial != dbus_message_get_serial (message))
06517 {
06518 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
06519 goto failed;
06520 }
06521
06522
06523
06524
06525
06526 dbus_message_iter_init (message, &iter);
06527 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
06528 {
06529 if (!check_message_handling_type (&iter, type))
06530 goto failed;
06531
06532 if (!dbus_message_iter_next (&iter))
06533 break;
06534 }
06535
06536 retval = TRUE;
06537
06538 failed:
06539 return retval;
06540 }
06541
06542 static dbus_bool_t
06543 check_have_valid_message (DBusMessageLoader *loader)
06544 {
06545 DBusMessage *message;
06546 dbus_bool_t retval;
06547
06548 message = NULL;
06549 retval = FALSE;
06550
06551 if (!_dbus_message_loader_queue_messages (loader))
06552 _dbus_assert_not_reached ("no memory to queue messages");
06553
06554 if (_dbus_message_loader_get_is_corrupted (loader))
06555 {
06556 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
06557 goto failed;
06558 }
06559
06560 message = _dbus_message_loader_pop_message (loader);
06561 if (message == NULL)
06562 {
06563 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
06564 goto failed;
06565 }
06566
06567 if (_dbus_string_get_length (&loader->data) > 0)
06568 {
06569 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
06570 goto failed;
06571 }
06572
06573
06574
06575
06576
06577 if (!check_message_handling (message))
06578 goto failed;
06579
06580 retval = TRUE;
06581
06582 failed:
06583 if (message)
06584 dbus_message_unref (message);
06585
06586 return retval;
06587 }
06588
06589 static dbus_bool_t
06590 check_invalid_message (DBusMessageLoader *loader)
06591 {
06592 dbus_bool_t retval;
06593
06594 retval = FALSE;
06595
06596 if (!_dbus_message_loader_queue_messages (loader))
06597 _dbus_assert_not_reached ("no memory to queue messages");
06598
06599 if (!_dbus_message_loader_get_is_corrupted (loader))
06600 {
06601 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
06602 goto failed;
06603 }
06604
06605 retval = TRUE;
06606
06607 failed:
06608 return retval;
06609 }
06610
06611 static dbus_bool_t
06612 check_incomplete_message (DBusMessageLoader *loader)
06613 {
06614 DBusMessage *message;
06615 dbus_bool_t retval;
06616
06617 message = NULL;
06618 retval = FALSE;
06619
06620 if (!_dbus_message_loader_queue_messages (loader))
06621 _dbus_assert_not_reached ("no memory to queue messages");
06622
06623 if (_dbus_message_loader_get_is_corrupted (loader))
06624 {
06625 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
06626 goto failed;
06627 }
06628
06629 message = _dbus_message_loader_pop_message (loader);
06630 if (message != NULL)
06631 {
06632 _dbus_warn ("loaded message that was expected to be incomplete\n");
06633 goto failed;
06634 }
06635
06636 retval = TRUE;
06637
06638 failed:
06639 if (message)
06640 dbus_message_unref (message);
06641 return retval;
06642 }
06643
06644 static dbus_bool_t
06645 check_loader_results (DBusMessageLoader *loader,
06646 DBusMessageValidity validity)
06647 {
06648 if (!_dbus_message_loader_queue_messages (loader))
06649 _dbus_assert_not_reached ("no memory to queue messages");
06650
06651 switch (validity)
06652 {
06653 case _DBUS_MESSAGE_VALID:
06654 return check_have_valid_message (loader);
06655 case _DBUS_MESSAGE_INVALID:
06656 return check_invalid_message (loader);
06657 case _DBUS_MESSAGE_INCOMPLETE:
06658 return check_incomplete_message (loader);
06659 case _DBUS_MESSAGE_UNKNOWN:
06660 return TRUE;
06661 }
06662
06663 _dbus_assert_not_reached ("bad DBusMessageValidity");
06664 return FALSE;
06665 }
06666
06667
06676 dbus_bool_t
06677 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
06678 dbus_bool_t is_raw,
06679 DBusString *data)
06680 {
06681 dbus_bool_t retval;
06682
06683 retval = FALSE;
06684
06685 if (is_raw)
06686 {
06687 DBusError error;
06688
06689 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
06690 dbus_error_init (&error);
06691 if (!_dbus_file_get_contents (data, filename, &error))
06692 {
06693 _dbus_warn ("Could not load message file %s: %s\n",
06694 _dbus_string_get_const_data (filename),
06695 error.message);
06696 dbus_error_free (&error);
06697 goto failed;
06698 }
06699 }
06700 else
06701 {
06702 if (!_dbus_message_data_load (data, filename))
06703 {
06704 _dbus_warn ("Could not load message file %s\n",
06705 _dbus_string_get_const_data (filename));
06706 goto failed;
06707 }
06708 }
06709
06710 retval = TRUE;
06711
06712 failed:
06713
06714 return retval;
06715 }
06716
06726 dbus_bool_t
06727 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
06728 dbus_bool_t is_raw,
06729 DBusMessageValidity expected_validity)
06730 {
06731 DBusString data;
06732 dbus_bool_t retval;
06733
06734 retval = FALSE;
06735
06736 if (!_dbus_string_init (&data))
06737 _dbus_assert_not_reached ("could not allocate string\n");
06738
06739 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
06740 &data))
06741 goto failed;
06742
06743 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
06744
06745 failed:
06746
06747 if (!retval)
06748 {
06749 if (_dbus_string_get_length (&data) > 0)
06750 _dbus_verbose_bytes_of_string (&data, 0,
06751 _dbus_string_get_length (&data));
06752
06753 _dbus_warn ("Failed message loader test on %s\n",
06754 _dbus_string_get_const_data (filename));
06755 }
06756
06757 _dbus_string_free (&data);
06758
06759 return retval;
06760 }
06761
06770 dbus_bool_t
06771 dbus_internal_do_not_use_try_message_data (const DBusString *data,
06772 DBusMessageValidity expected_validity)
06773 {
06774 DBusMessageLoader *loader;
06775 dbus_bool_t retval;
06776 int len;
06777 int i;
06778
06779 loader = NULL;
06780 retval = FALSE;
06781
06782
06783
06784 loader = _dbus_message_loader_new ();
06785
06786
06787 _dbus_message_loader_ref (loader);
06788 _dbus_message_loader_unref (loader);
06789 _dbus_message_loader_get_max_message_size (loader);
06790
06791 len = _dbus_string_get_length (data);
06792 for (i = 0; i < len; i++)
06793 {
06794 DBusString *buffer;
06795
06796 _dbus_message_loader_get_buffer (loader, &buffer);
06797 _dbus_string_append_byte (buffer,
06798 _dbus_string_get_byte (data, i));
06799 _dbus_message_loader_return_buffer (loader, buffer, 1);
06800 }
06801
06802 if (!check_loader_results (loader, expected_validity))
06803 goto failed;
06804
06805 _dbus_message_loader_unref (loader);
06806 loader = NULL;
06807
06808
06809
06810 loader = _dbus_message_loader_new ();
06811
06812 {
06813 DBusString *buffer;
06814
06815 _dbus_message_loader_get_buffer (loader, &buffer);
06816 _dbus_string_copy (data, 0, buffer,
06817 _dbus_string_get_length (buffer));
06818 _dbus_message_loader_return_buffer (loader, buffer, 1);
06819 }
06820
06821 if (!check_loader_results (loader, expected_validity))
06822 goto failed;
06823
06824 _dbus_message_loader_unref (loader);
06825 loader = NULL;
06826
06827
06828
06829 loader = _dbus_message_loader_new ();
06830
06831 len = _dbus_string_get_length (data);
06832 for (i = 0; i < len; i += 2)
06833 {
06834 DBusString *buffer;
06835
06836 _dbus_message_loader_get_buffer (loader, &buffer);
06837 _dbus_string_append_byte (buffer,
06838 _dbus_string_get_byte (data, i));
06839 if ((i+1) < len)
06840 _dbus_string_append_byte (buffer,
06841 _dbus_string_get_byte (data, i+1));
06842 _dbus_message_loader_return_buffer (loader, buffer, 1);
06843 }
06844
06845 if (!check_loader_results (loader, expected_validity))
06846 goto failed;
06847
06848 _dbus_message_loader_unref (loader);
06849 loader = NULL;
06850
06851 retval = TRUE;
06852
06853 failed:
06854
06855 if (loader)
06856 _dbus_message_loader_unref (loader);
06857
06858 return retval;
06859 }
06860
06861 static dbus_bool_t
06862 process_test_subdir (const DBusString *test_base_dir,
06863 const char *subdir,
06864 DBusMessageValidity validity,
06865 DBusForeachMessageFileFunc function,
06866 void *user_data)
06867 {
06868 DBusString test_directory;
06869 DBusString filename;
06870 DBusDirIter *dir;
06871 dbus_bool_t retval;
06872 DBusError error;
06873
06874 retval = FALSE;
06875 dir = NULL;
06876
06877 if (!_dbus_string_init (&test_directory))
06878 _dbus_assert_not_reached ("didn't allocate test_directory\n");
06879
06880 _dbus_string_init_const (&filename, subdir);
06881
06882 if (!_dbus_string_copy (test_base_dir, 0,
06883 &test_directory, 0))
06884 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
06885
06886 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
06887 _dbus_assert_not_reached ("couldn't allocate full path");
06888
06889 _dbus_string_free (&filename);
06890 if (!_dbus_string_init (&filename))
06891 _dbus_assert_not_reached ("didn't allocate filename string\n");
06892
06893 dbus_error_init (&error);
06894 dir = _dbus_directory_open (&test_directory, &error);
06895 if (dir == NULL)
06896 {
06897 _dbus_warn ("Could not open %s: %s\n",
06898 _dbus_string_get_const_data (&test_directory),
06899 error.message);
06900 dbus_error_free (&error);
06901 goto failed;
06902 }
06903
06904 printf ("Testing %s:\n", subdir);
06905
06906 next:
06907 while (_dbus_directory_get_next_file (dir, &filename, &error))
06908 {
06909 DBusString full_path;
06910 dbus_bool_t is_raw;
06911
06912 if (!_dbus_string_init (&full_path))
06913 _dbus_assert_not_reached ("couldn't init string");
06914
06915 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
06916 _dbus_assert_not_reached ("couldn't copy dir to full_path");
06917
06918 if (!_dbus_concat_dir_and_file (&full_path, &filename))
06919 _dbus_assert_not_reached ("couldn't concat file to dir");
06920
06921 if (_dbus_string_ends_with_c_str (&filename, ".message"))
06922 is_raw = FALSE;
06923 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
06924 is_raw = TRUE;
06925 else
06926 {
06927 _dbus_verbose ("Skipping non-.message file %s\n",
06928 _dbus_string_get_const_data (&filename));
06929 _dbus_string_free (&full_path);
06930 goto next;
06931 }
06932
06933 printf (" %s\n",
06934 _dbus_string_get_const_data (&filename));
06935
06936 _dbus_verbose (" expecting %s for %s\n",
06937 validity == _DBUS_MESSAGE_VALID ? "valid" :
06938 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
06939 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
06940 _dbus_string_get_const_data (&filename));
06941
06942 if (! (*function) (&full_path, is_raw, validity, user_data))
06943 {
06944 _dbus_string_free (&full_path);
06945 goto failed;
06946 }
06947 else
06948 _dbus_string_free (&full_path);
06949 }
06950
06951 if (dbus_error_is_set (&error))
06952 {
06953 _dbus_warn ("Could not get next file in %s: %s\n",
06954 _dbus_string_get_const_data (&test_directory),
06955 error.message);
06956 dbus_error_free (&error);
06957 goto failed;
06958 }
06959
06960 retval = TRUE;
06961
06962 failed:
06963
06964 if (dir)
06965 _dbus_directory_close (dir);
06966 _dbus_string_free (&test_directory);
06967 _dbus_string_free (&filename);
06968
06969 return retval;
06970 }
06971
06981 dbus_bool_t
06982 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
06983 DBusForeachMessageFileFunc func,
06984 void *user_data)
06985 {
06986 DBusString test_directory;
06987 dbus_bool_t retval;
06988
06989 retval = FALSE;
06990
06991 _dbus_string_init_const (&test_directory, test_data_dir);
06992
06993 if (!process_test_subdir (&test_directory, "valid-messages",
06994 _DBUS_MESSAGE_VALID, func, user_data))
06995 goto failed;
06996
06997 if (!process_test_subdir (&test_directory, "invalid-messages",
06998 _DBUS_MESSAGE_INVALID, func, user_data))
06999 goto failed;
07000
07001 if (!process_test_subdir (&test_directory, "incomplete-messages",
07002 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
07003 goto failed;
07004
07005 retval = TRUE;
07006
07007 failed:
07008
07009 _dbus_string_free (&test_directory);
07010
07011 return retval;
07012 }
07013
07014 static void
07015 verify_test_message (DBusMessage *message)
07016 {
07017 DBusMessageIter iter, dict;
07018 DBusError error;
07019 dbus_int32_t our_int;
07020 char *our_str;
07021 double our_double;
07022 dbus_bool_t our_bool;
07023 unsigned char our_byte_1, our_byte_2;
07024 dbus_uint32_t our_uint32;
07025 dbus_int32_t *our_uint32_array;
07026 int our_uint32_array_len;
07027 dbus_int32_t *our_int32_array;
07028 int our_int32_array_len;
07029 char **our_string_array;
07030 int our_string_array_len;
07031 #ifdef DBUS_HAVE_INT64
07032 dbus_int64_t our_int64;
07033 dbus_uint64_t our_uint64;
07034 dbus_int64_t *our_uint64_array;
07035 int our_uint64_array_len;
07036 dbus_int64_t *our_int64_array;
07037 int our_int64_array_len;
07038 #endif
07039 double *our_double_array;
07040 int our_double_array_len;
07041 unsigned char *our_byte_array;
07042 int our_byte_array_len;
07043 unsigned char *our_boolean_array;
07044 int our_boolean_array_len;
07045
07046 dbus_message_iter_init (message, &iter);
07047
07048 dbus_error_init (&error);
07049 if (!dbus_message_iter_get_args (&iter, &error,
07050 DBUS_TYPE_INT32, &our_int,
07051 #ifdef DBUS_HAVE_INT64
07052 DBUS_TYPE_INT64, &our_int64,
07053 DBUS_TYPE_UINT64, &our_uint64,
07054 #endif
07055 DBUS_TYPE_STRING, &our_str,
07056 DBUS_TYPE_DOUBLE, &our_double,
07057 DBUS_TYPE_BOOLEAN, &our_bool,
07058 DBUS_TYPE_BYTE, &our_byte_1,
07059 DBUS_TYPE_BYTE, &our_byte_2,
07060 DBUS_TYPE_NIL,
07061 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
07062 &our_uint32_array, &our_uint32_array_len,
07063 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
07064 &our_int32_array, &our_int32_array_len,
07065 #ifdef DBUS_HAVE_INT64
07066 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
07067 &our_uint64_array, &our_uint64_array_len,
07068 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
07069 &our_int64_array, &our_int64_array_len,
07070 #endif
07071 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
07072 &our_string_array, &our_string_array_len,
07073 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
07074 &our_double_array, &our_double_array_len,
07075 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
07076 &our_byte_array, &our_byte_array_len,
07077 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
07078 &our_boolean_array, &our_boolean_array_len,
07079 0))
07080 {
07081 _dbus_warn ("error: %s - %s\n", error.name,
07082 (error.message != NULL) ? error.message : "no message");
07083 _dbus_assert_not_reached ("Could not get arguments");
07084 }
07085
07086 if (our_int != -0x12345678)
07087 _dbus_assert_not_reached ("integers differ!");
07088
07089 #ifdef DBUS_HAVE_INT64
07090 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
07091 _dbus_assert_not_reached ("64-bit integers differ!");
07092 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
07093 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
07094 #endif
07095
07096 if (our_double != 3.14159)
07097 _dbus_assert_not_reached ("doubles differ!");
07098
07099 if (strcmp (our_str, "Test string") != 0)
07100 _dbus_assert_not_reached ("strings differ!");
07101 dbus_free (our_str);
07102
07103 if (!our_bool)
07104 _dbus_assert_not_reached ("booleans differ");
07105
07106 if (our_byte_1 != 42)
07107 _dbus_assert_not_reached ("bytes differ!");
07108
07109 if (our_byte_2 != 24)
07110 _dbus_assert_not_reached ("bytes differ!");
07111
07112 if (our_uint32_array_len != 4 ||
07113 our_uint32_array[0] != 0x12345678 ||
07114 our_uint32_array[1] != 0x23456781 ||
07115 our_uint32_array[2] != 0x34567812 ||
07116 our_uint32_array[3] != 0x45678123)
07117 _dbus_assert_not_reached ("uint array differs");
07118 dbus_free (our_uint32_array);
07119
07120 if (our_int32_array_len != 4 ||
07121 our_int32_array[0] != 0x12345678 ||
07122 our_int32_array[1] != -0x23456781 ||
07123 our_int32_array[2] != 0x34567812 ||
07124 our_int32_array[3] != -0x45678123)
07125 _dbus_assert_not_reached ("int array differs");
07126 dbus_free (our_int32_array);
07127
07128 #ifdef DBUS_HAVE_INT64
07129 if (our_uint64_array_len != 4 ||
07130 our_uint64_array[0] != 0x12345678 ||
07131 our_uint64_array[1] != 0x23456781 ||
07132 our_uint64_array[2] != 0x34567812 ||
07133 our_uint64_array[3] != 0x45678123)
07134 _dbus_assert_not_reached ("uint64 array differs");
07135 dbus_free (our_uint64_array);
07136
07137 if (our_int64_array_len != 4 ||
07138 our_int64_array[0] != 0x12345678 ||
07139 our_int64_array[1] != -0x23456781 ||
07140 our_int64_array[2] != 0x34567812 ||
07141 our_int64_array[3] != -0x45678123)
07142 _dbus_assert_not_reached ("int64 array differs");
07143 dbus_free (our_int64_array);
07144 #endif
07145
07146 if (our_string_array_len != 4)
07147 _dbus_assert_not_reached ("string array has wrong length");
07148
07149 if (strcmp (our_string_array[0], "Foo") != 0 ||
07150 strcmp (our_string_array[1], "bar") != 0 ||
07151 strcmp (our_string_array[2], "") != 0 ||
07152 strcmp (our_string_array[3], "woo woo woo woo") != 0)
07153 _dbus_assert_not_reached ("string array differs");
07154
07155 dbus_free_string_array (our_string_array);
07156
07157 if (our_double_array_len != 3)
07158 _dbus_assert_not_reached ("double array had wrong length");
07159
07160
07161
07162
07163 if (our_double_array[0] != 0.1234 ||
07164 our_double_array[1] != 9876.54321 ||
07165 our_double_array[2] != -300.0)
07166 _dbus_assert_not_reached ("double array had wrong values");
07167
07168 dbus_free (our_double_array);
07169
07170 if (our_byte_array_len != 4)
07171 _dbus_assert_not_reached ("byte array had wrong length");
07172
07173 if (our_byte_array[0] != 'a' ||
07174 our_byte_array[1] != 'b' ||
07175 our_byte_array[2] != 'c' ||
07176 our_byte_array[3] != 234)
07177 _dbus_assert_not_reached ("byte array had wrong values");
07178
07179 dbus_free (our_byte_array);
07180
07181 if (our_boolean_array_len != 5)
07182 _dbus_assert_not_reached ("bool array had wrong length");
07183
07184 if (our_boolean_array[0] != TRUE ||
07185 our_boolean_array[1] != FALSE ||
07186 our_boolean_array[2] != TRUE ||
07187 our_boolean_array[3] != TRUE ||
07188 our_boolean_array[4] != FALSE)
07189 _dbus_assert_not_reached ("bool array had wrong values");
07190
07191 dbus_free (our_boolean_array);
07192
07193 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
07194 _dbus_assert_not_reached ("not dict type");
07195
07196 dbus_message_iter_init_dict_iterator (&iter, &dict);
07197
07198 our_str = dbus_message_iter_get_dict_key (&dict);
07199 if (our_str == NULL || strcmp (our_str, "test") != 0)
07200 _dbus_assert_not_reached ("wrong dict key");
07201 dbus_free (our_str);
07202
07203 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
07204 {
07205 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
07206 _dbus_assert_not_reached ("wrong dict entry type");
07207 }
07208
07209 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
07210 {
07211 _dbus_verbose ("dict entry val: %x\n", our_uint32);
07212 _dbus_assert_not_reached ("wrong dict entry value");
07213 }
07214
07215 if (dbus_message_iter_next (&dict))
07216 _dbus_assert_not_reached ("Didn't reach end of dict");
07217
07218 if (!dbus_message_iter_next (&iter))
07219 _dbus_assert_not_reached ("Reached end of arguments");
07220
07221 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
07222 _dbus_assert_not_reached ("wrong type after dict");
07223
07224 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
07225 _dbus_assert_not_reached ("wrong value after dict");
07226
07227 if (dbus_message_iter_next (&iter))
07228 _dbus_assert_not_reached ("Didn't reach end of arguments");
07229 }
07230
07237 dbus_bool_t
07238 _dbus_message_test (const char *test_data_dir)
07239 {
07240 DBusMessage *message;
07241 DBusMessageLoader *loader;
07242 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
07243 int i;
07244 const char *data;
07245 DBusMessage *copy;
07246 const char *name1;
07247 const char *name2;
07248 const dbus_uint32_t our_uint32_array[] =
07249 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
07250 const dbus_uint32_t our_int32_array[] =
07251 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
07252 #ifdef DBUS_HAVE_INT64
07253 const dbus_uint64_t our_uint64_array[] =
07254 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
07255 const dbus_uint64_t our_int64_array[] =
07256 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
07257 #endif
07258 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
07259 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
07260 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
07261 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
07262 char sig[64];
07263 const char *s;
07264 char *t;
07265 DBusError error;
07266
07267 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
07268
07269 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07270 "/org/freedesktop/TestPath",
07271 "Foo.TestInterface",
07272 "TestMethod");
07273 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
07274 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
07275 "TestMethod"));
07276 _dbus_assert (strcmp (dbus_message_get_path (message),
07277 "/org/freedesktop/TestPath") == 0);
07278 _dbus_message_set_serial (message, 1234);
07279
07280 if (!dbus_message_set_sender (message, "org.foo.bar1"))
07281 _dbus_assert_not_reached ("out of memory");
07282 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
07283 dbus_message_set_reply_serial (message, 5678);
07284 if (!dbus_message_set_sender (message, NULL))
07285 _dbus_assert_not_reached ("out of memory");
07286 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
07287 _dbus_assert (dbus_message_get_serial (message) == 1234);
07288 _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
07289 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
07290
07291 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
07292 dbus_message_set_no_reply (message, TRUE);
07293 _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
07294 dbus_message_set_no_reply (message, FALSE);
07295 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
07296
07297
07298
07299 if (!dbus_message_set_path (message, "/foo"))
07300 _dbus_assert_not_reached ("out of memory");
07301 _dbus_assert (strcmp (dbus_message_get_path (message),
07302 "/foo") == 0);
07303
07304 if (!dbus_message_set_interface (message, "org.Foo"))
07305 _dbus_assert_not_reached ("out of memory");
07306 _dbus_assert (strcmp (dbus_message_get_interface (message),
07307 "org.Foo") == 0);
07308
07309 if (!dbus_message_set_member (message, "Bar"))
07310 _dbus_assert_not_reached ("out of memory");
07311 _dbus_assert (strcmp (dbus_message_get_member (message),
07312 "Bar") == 0);
07313
07314
07315 if (!dbus_message_set_path (message, "/foo/bar"))
07316 _dbus_assert_not_reached ("out of memory");
07317 _dbus_assert (strcmp (dbus_message_get_path (message),
07318 "/foo/bar") == 0);
07319
07320 if (!dbus_message_set_interface (message, "org.Foo.Bar"))
07321 _dbus_assert_not_reached ("out of memory");
07322 _dbus_assert (strcmp (dbus_message_get_interface (message),
07323 "org.Foo.Bar") == 0);
07324
07325 if (!dbus_message_set_member (message, "BarFoo"))
07326 _dbus_assert_not_reached ("out of memory");
07327 _dbus_assert (strcmp (dbus_message_get_member (message),
07328 "BarFoo") == 0);
07329
07330
07331
07332 if (!dbus_message_set_path (message, "/foo"))
07333 _dbus_assert_not_reached ("out of memory");
07334 _dbus_assert (strcmp (dbus_message_get_path (message),
07335 "/foo") == 0);
07336
07337 if (!dbus_message_set_interface (message, "org.Foo"))
07338 _dbus_assert_not_reached ("out of memory");
07339 _dbus_assert (strcmp (dbus_message_get_interface (message),
07340 "org.Foo") == 0);
07341
07342 if (!dbus_message_set_member (message, "Bar"))
07343 _dbus_assert_not_reached ("out of memory");
07344 _dbus_assert (strcmp (dbus_message_get_member (message),
07345 "Bar") == 0);
07346
07347 dbus_message_unref (message);
07348
07349
07350 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07351 "/org/freedesktop/TestPath",
07352 "Foo.TestInterface",
07353 "TestMethod");
07354 _dbus_message_set_serial (message, 1);
07355 dbus_message_append_args (message,
07356 DBUS_TYPE_INT32, -0x12345678,
07357 #ifdef DBUS_HAVE_INT64
07358 DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd),
07359 DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd),
07360 #endif
07361 DBUS_TYPE_STRING, "Test string",
07362 DBUS_TYPE_DOUBLE, 3.14159,
07363 DBUS_TYPE_BOOLEAN, TRUE,
07364 DBUS_TYPE_BYTE, (unsigned char) 42,
07365 DBUS_TYPE_BYTE, 24,
07366 DBUS_TYPE_NIL,
07367 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
07368 _DBUS_N_ELEMENTS (our_uint32_array),
07369 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
07370 _DBUS_N_ELEMENTS (our_int32_array),
07371 #ifdef DBUS_HAVE_INT64
07372 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
07373 _DBUS_N_ELEMENTS (our_uint64_array),
07374 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
07375 _DBUS_N_ELEMENTS (our_int64_array),
07376 #endif
07377 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
07378 _DBUS_N_ELEMENTS (our_string_array),
07379 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
07380 _DBUS_N_ELEMENTS (our_double_array),
07381 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
07382 _DBUS_N_ELEMENTS (our_byte_array),
07383 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
07384 _DBUS_N_ELEMENTS (our_boolean_array),
07385 0);
07386
07387 dbus_message_append_iter_init (message, &iter);
07388 dbus_message_iter_append_dict (&iter, &child_iter);
07389 dbus_message_iter_append_dict_key (&child_iter, "test");
07390 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07391 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
07392
07393 i = 0;
07394 sig[i++] = DBUS_TYPE_INT32;
07395 #ifdef DBUS_HAVE_INT64
07396 sig[i++] = DBUS_TYPE_INT64;
07397 sig[i++] = DBUS_TYPE_UINT64;
07398 #endif
07399 sig[i++] = DBUS_TYPE_STRING;
07400 sig[i++] = DBUS_TYPE_DOUBLE;
07401 sig[i++] = DBUS_TYPE_BOOLEAN;
07402 sig[i++] = DBUS_TYPE_BYTE;
07403 sig[i++] = DBUS_TYPE_BYTE;
07404 sig[i++] = DBUS_TYPE_NIL;
07405 sig[i++] = DBUS_TYPE_ARRAY;
07406 sig[i++] = DBUS_TYPE_UINT32;
07407 sig[i++] = DBUS_TYPE_ARRAY;
07408 sig[i++] = DBUS_TYPE_INT32;
07409 #ifdef DBUS_HAVE_INT64
07410 sig[i++] = DBUS_TYPE_ARRAY;
07411 sig[i++] = DBUS_TYPE_UINT64;
07412 sig[i++] = DBUS_TYPE_ARRAY;
07413 sig[i++] = DBUS_TYPE_INT64;
07414 #endif
07415 sig[i++] = DBUS_TYPE_ARRAY;
07416 sig[i++] = DBUS_TYPE_STRING;
07417 sig[i++] = DBUS_TYPE_ARRAY;
07418 sig[i++] = DBUS_TYPE_DOUBLE;
07419 sig[i++] = DBUS_TYPE_ARRAY;
07420 sig[i++] = DBUS_TYPE_BYTE;
07421 sig[i++] = DBUS_TYPE_ARRAY;
07422 sig[i++] = DBUS_TYPE_BOOLEAN;
07423 sig[i++] = DBUS_TYPE_DICT;
07424 sig[i++] = DBUS_TYPE_UINT32;
07425 sig[i++] = DBUS_TYPE_INVALID;
07426
07427 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
07428
07429 _dbus_verbose_bytes_of_string (&message->header, 0,
07430 _dbus_string_get_length (&message->header));
07431 _dbus_verbose_bytes_of_string (&message->body, 0,
07432 _dbus_string_get_length (&message->body));
07433
07434 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
07435 sig, dbus_message_get_signature (message));
07436
07437 s = dbus_message_get_signature (message);
07438
07439 _dbus_assert (dbus_message_has_signature (message, sig));
07440 _dbus_assert (strcmp (s, sig) == 0);
07441
07442 verify_test_message (message);
07443
07444 copy = dbus_message_copy (message);
07445
07446 _dbus_assert (message->client_serial == copy->client_serial);
07447 _dbus_assert (message->reply_serial == copy->reply_serial);
07448 _dbus_assert (message->header_padding == copy->header_padding);
07449
07450 _dbus_assert (_dbus_string_get_length (&message->header) ==
07451 _dbus_string_get_length (©->header));
07452
07453 _dbus_assert (_dbus_string_get_length (&message->body) ==
07454 _dbus_string_get_length (©->body));
07455
07456 verify_test_message (copy);
07457
07458 name1 = dbus_message_get_interface (message);
07459 name2 = dbus_message_get_interface (copy);
07460
07461 _dbus_assert (strcmp (name1, name2) == 0);
07462
07463 name1 = dbus_message_get_member (message);
07464 name2 = dbus_message_get_member (copy);
07465
07466 _dbus_assert (strcmp (name1, name2) == 0);
07467
07468 dbus_message_unref (message);
07469 dbus_message_unref (copy);
07470
07471 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
07472 "/org/freedesktop/TestPath",
07473 "Foo.TestInterface",
07474 "TestMethod");
07475
07476 _dbus_message_set_serial (message, 1);
07477 dbus_message_set_reply_serial (message, 0x12345678);
07478
07479 dbus_message_append_iter_init (message, &iter);
07480 dbus_message_iter_append_string (&iter, "Test string");
07481 dbus_message_iter_append_int32 (&iter, -0x12345678);
07482 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
07483 dbus_message_iter_append_double (&iter, 3.14159);
07484
07485 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
07486 dbus_message_iter_append_double (&child_iter, 1.5);
07487 dbus_message_iter_append_double (&child_iter, 2.5);
07488
07489
07490 dbus_message_iter_append_dict (&iter, &child_iter);
07491 dbus_message_iter_append_dict_key (&child_iter, "test");
07492 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
07493
07494
07495 dbus_message_iter_append_dict_key (&child_iter, "testdict");
07496 dbus_message_iter_append_dict (&child_iter, &child_iter2);
07497
07498 dbus_message_iter_append_dict_key (&child_iter2, "dictkey");
07499 dbus_message_iter_append_string (&child_iter2, "dictvalue");
07500
07501
07502 dbus_message_iter_append_dict_key (&child_iter, "array");
07503 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
07504 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07505 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
07506 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
07507 _dbus_warn ("next call expected to fail with wrong array type\n");
07508 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
07509 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
07510 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
07511 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
07512 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
07513
07514 dbus_message_iter_append_byte (&iter, 0xF0);
07515
07516 dbus_message_iter_append_nil (&iter);
07517
07518 dbus_message_iter_append_custom (&iter, "MyTypeName",
07519 "data", 5);
07520
07521 dbus_message_iter_append_byte (&iter, 0xF0);
07522
07523 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_INT32);
07524
07525 dbus_message_iter_append_byte (&iter, 0xF0);
07526
07527 dbus_message_iter_append_dict (&iter, &child_iter);
07528
07529 dbus_message_iter_append_byte (&iter, 0xF0);
07530
07531 message_iter_test (message);
07532
07533
07534 _dbus_message_lock (message);
07535 loader = _dbus_message_loader_new ();
07536
07537
07538 _dbus_message_loader_ref (loader);
07539 _dbus_message_loader_unref (loader);
07540
07541
07542 data = _dbus_string_get_const_data (&message->header);
07543 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
07544 {
07545 DBusString *buffer;
07546
07547 _dbus_message_loader_get_buffer (loader, &buffer);
07548 _dbus_string_append_byte (buffer, data[i]);
07549 _dbus_message_loader_return_buffer (loader, buffer, 1);
07550 }
07551
07552
07553 data = _dbus_string_get_const_data (&message->body);
07554 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
07555 {
07556 DBusString *buffer;
07557
07558 _dbus_message_loader_get_buffer (loader, &buffer);
07559 _dbus_string_append_byte (buffer, data[i]);
07560 _dbus_message_loader_return_buffer (loader, buffer, 1);
07561 }
07562
07563 copy = dbus_message_copy (message);
07564 dbus_message_unref (message);
07565
07566
07567 if (!_dbus_message_loader_queue_messages (loader))
07568 _dbus_assert_not_reached ("no memory to queue messages");
07569
07570 if (_dbus_message_loader_get_is_corrupted (loader))
07571 _dbus_assert_not_reached ("message loader corrupted");
07572
07573 message = _dbus_message_loader_pop_message (loader);
07574 if (!message)
07575 _dbus_assert_not_reached ("received a NULL message");
07576
07577 if (dbus_message_get_reply_serial (message) != 0x12345678)
07578 _dbus_assert_not_reached ("reply serial fields differ");
07579
07580 message_iter_test (message);
07581
07582 dbus_message_unref (message);
07583 _dbus_message_loader_unref (loader);
07584
07585 message = dbus_message_new_method_return (copy);
07586 if (message == NULL)
07587 _dbus_assert_not_reached ("out of memory\n");
07588 dbus_message_unref (copy);
07589
07590 if (!dbus_message_append_args (message,
07591 DBUS_TYPE_STRING, "hello",
07592 DBUS_TYPE_INVALID))
07593 _dbus_assert_not_reached ("no memory");
07594
07595 if (!dbus_message_has_signature (message, "s"))
07596 _dbus_assert_not_reached ("method return has wrong signature");
07597
07598 dbus_error_init (&error);
07599 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
07600 &t, DBUS_TYPE_INVALID))
07601
07602 {
07603 _dbus_warn ("Failed to get expected string arg: %s\n", error.message);
07604 exit (1);
07605 }
07606 dbus_free (t);
07607
07608 dbus_message_unref (message);
07609
07610
07611
07612
07613 message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
07614 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
07615 "ServiceAcquired");
07616
07617 if (message == NULL)
07618 _dbus_assert_not_reached ("out of memory");
07619
07620 _dbus_verbose ("Bytes after creation\n");
07621 _dbus_verbose_bytes_of_string (&message->header, 0,
07622 _dbus_string_get_length (&message->header));
07623
07624 if (!dbus_message_set_destination (message, ":1.0") ||
07625 !dbus_message_append_args (message,
07626 DBUS_TYPE_STRING, ":1.0",
07627 DBUS_TYPE_INVALID))
07628 _dbus_assert_not_reached ("out of memory");
07629
07630 _dbus_verbose ("Bytes after set_destination() and append_args()\n");
07631 _dbus_verbose_bytes_of_string (&message->header, 0,
07632 _dbus_string_get_length (&message->header));
07633
07634 if (!dbus_message_set_sender (message, "org.freedesktop.DBus"))
07635 _dbus_assert_not_reached ("out of memory");
07636
07637 _dbus_verbose ("Bytes after set_sender()\n");
07638 _dbus_verbose_bytes_of_string (&message->header, 0,
07639 _dbus_string_get_length (&message->header));
07640
07641
07642
07643
07644 if (!dbus_message_has_signature (message, "s"))
07645 {
07646 _dbus_warn ("Signature should be 's' but is '%s'\n",
07647 dbus_message_get_signature (message));
07648 _dbus_assert_not_reached ("signal has wrong signature");
07649 }
07650
07651
07652 if (!dbus_message_set_destination (message, ":1.0"))
07653 _dbus_assert_not_reached ("out of memory");
07654
07655 _dbus_verbose ("Bytes after set_destination()\n");
07656 _dbus_verbose_bytes_of_string (&message->header, 0,
07657 _dbus_string_get_length (&message->header));
07658
07659
07660
07661
07662 if (!dbus_message_has_signature (message, "s"))
07663 {
07664 _dbus_warn ("Signature should be 's' but is '%s'\n",
07665 dbus_message_get_signature (message));
07666 _dbus_assert_not_reached ("signal has wrong signature");
07667 }
07668
07669 dbus_error_init (&error);
07670 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
07671 &t, DBUS_TYPE_INVALID))
07672
07673 {
07674 _dbus_warn ("Failed to get expected string arg for signal: %s\n", error.message);
07675 exit (1);
07676 }
07677 dbus_free (t);
07678
07679 dbus_message_unref (message);
07680
07681
07682 if (test_data_dir == NULL)
07683 return TRUE;
07684
07685 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
07686 (DBusForeachMessageFileFunc)
07687 dbus_internal_do_not_use_try_message_file,
07688 NULL);
07689 }
07690
07691 #endif