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