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
00045 enum
00046 {
00047 FIELD_HEADER_LENGTH,
00048 FIELD_BODY_LENGTH,
00049 FIELD_CLIENT_SERIAL,
00050 FIELD_NAME,
00051 FIELD_SERVICE,
00052 FIELD_SENDER,
00053 FIELD_REPLY_SERIAL,
00054
00055 FIELD_LAST
00056 };
00057
00058 static dbus_bool_t field_is_named[FIELD_LAST] =
00059 {
00060 FALSE,
00061 FALSE,
00062 FALSE,
00063 TRUE,
00064 TRUE,
00065 TRUE,
00066 TRUE
00067 };
00068
00069 typedef struct
00070 {
00071 int offset;
00074 } HeaderField;
00075
00083 struct DBusMessage
00084 {
00085 DBusAtomic refcount;
00087 DBusString header;
00092 HeaderField header_fields[FIELD_LAST];
00096 dbus_uint32_t client_serial;
00097 dbus_uint32_t reply_serial;
00099 int header_padding;
00101 DBusString body;
00103 char byte_order;
00105 DBusList *size_counters;
00106 long size_counter_delta;
00108 dbus_uint32_t changed_stamp;
00110 unsigned int locked : 1;
00112 DBusDataSlotList slot_list;
00113 };
00114
00115 enum {
00116 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00117 DBUS_MESSAGE_ITER_TYPE_ARRAY,
00118 DBUS_MESSAGE_ITER_TYPE_DICT
00119 };
00120
00122 typedef struct DBusMessageRealIter DBusMessageRealIter;
00123
00129 struct DBusMessageRealIter
00130 {
00131 DBusMessageRealIter *parent_iter;
00132 DBusMessage *message;
00133 dbus_uint32_t changed_stamp;
00135
00136 int type;
00138 int pos;
00139 int end;
00140 int container_start;
00141 int container_length_pos;
00143 int wrote_dict_key;
00145 int array_type_pos;
00146 int array_type_done;
00147 };
00148
00159 void
00160 _dbus_message_get_network_data (DBusMessage *message,
00161 const DBusString **header,
00162 const DBusString **body)
00163 {
00164 _dbus_assert (message->locked);
00165
00166 *header = &message->header;
00167 *body = &message->body;
00168 }
00169
00170 static void
00171 clear_header_padding (DBusMessage *message)
00172 {
00173 _dbus_string_shorten (&message->header,
00174 message->header_padding);
00175 message->header_padding = 0;
00176 }
00177
00178 static dbus_bool_t
00179 append_header_padding (DBusMessage *message)
00180 {
00181 int old_len;
00182 old_len = _dbus_string_get_length (&message->header);
00183 if (!_dbus_string_align_length (&message->header, 8))
00184 return FALSE;
00185
00186 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00187
00188 return TRUE;
00189 }
00190
00191 static void
00192 adjust_field_offsets (DBusMessage *message,
00193 int offsets_after,
00194 int delta)
00195 {
00196 int i;
00197
00198 if (delta == 0)
00199 return;
00200
00201 i = 0;
00202 while (i < FIELD_LAST)
00203 {
00204 if (message->header_fields[i].offset > offsets_after)
00205 message->header_fields[i].offset += delta;
00206
00207 ++i;
00208 }
00209 }
00210
00211 #ifdef DBUS_BUILD_TESTS
00212
00213 static dbus_int32_t
00214 get_int_field (DBusMessage *message,
00215 int field)
00216 {
00217 int offset;
00218
00219 _dbus_assert (field < FIELD_LAST);
00220
00221 offset = message->header_fields[field].offset;
00222
00223 if (offset < 0)
00224 return -1;
00225
00226 return _dbus_demarshal_int32 (&message->header,
00227 message->byte_order,
00228 offset,
00229 NULL);
00230 }
00231 #endif
00232
00233 static dbus_uint32_t
00234 get_uint_field (DBusMessage *message,
00235 int field)
00236 {
00237 int offset;
00238
00239 _dbus_assert (field < FIELD_LAST);
00240
00241 offset = message->header_fields[field].offset;
00242
00243 if (offset < 0)
00244 return -1;
00245
00246 return _dbus_demarshal_uint32 (&message->header,
00247 message->byte_order,
00248 offset,
00249 NULL);
00250 }
00251
00252 static const char*
00253 get_string_field (DBusMessage *message,
00254 int field,
00255 int *len)
00256 {
00257 int offset;
00258 const char *data;
00259
00260 offset = message->header_fields[field].offset;
00261
00262 _dbus_assert (field < FIELD_LAST);
00263
00264 if (offset < 0)
00265 return NULL;
00266
00267
00268
00269
00270
00271
00272 if (len)
00273 *len = _dbus_demarshal_uint32 (&message->header,
00274 message->byte_order,
00275 offset,
00276 NULL);
00277
00278 data = _dbus_string_get_const_data (&message->header);
00279
00280 return data + (offset + 4);
00281 }
00282
00283 #ifdef DBUS_BUILD_TESTS
00284 static dbus_bool_t
00285 append_int_field (DBusMessage *message,
00286 int field,
00287 const char *name,
00288 int value)
00289 {
00290 int orig_len;
00291
00292 _dbus_assert (!message->locked);
00293
00294 clear_header_padding (message);
00295
00296 orig_len = _dbus_string_get_length (&message->header);
00297
00298 if (!_dbus_string_align_length (&message->header, 4))
00299 goto failed;
00300
00301 if (!_dbus_string_append_len (&message->header, name, 4))
00302 goto failed;
00303
00304 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00305 goto failed;
00306
00307 if (!_dbus_string_align_length (&message->header, 4))
00308 goto failed;
00309
00310 message->header_fields[field].offset =
00311 _dbus_string_get_length (&message->header);
00312
00313 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00314 value))
00315 goto failed;
00316
00317 if (!append_header_padding (message))
00318 goto failed;
00319
00320 return TRUE;
00321
00322 failed:
00323 message->header_fields[field].offset = -1;
00324 _dbus_string_set_length (&message->header, orig_len);
00325
00326
00327
00328
00329 if (!append_header_padding (message))
00330 _dbus_assert_not_reached ("failed to reappend header padding");
00331 return FALSE;
00332 }
00333 #endif
00334
00335 static dbus_bool_t
00336 append_uint_field (DBusMessage *message,
00337 int field,
00338 const char *name,
00339 int value)
00340 {
00341 int orig_len;
00342
00343 _dbus_assert (!message->locked);
00344
00345 clear_header_padding (message);
00346
00347 orig_len = _dbus_string_get_length (&message->header);
00348
00349 if (!_dbus_string_align_length (&message->header, 4))
00350 goto failed;
00351
00352 if (!_dbus_string_append_len (&message->header, name, 4))
00353 goto failed;
00354
00355 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00356 goto failed;
00357
00358 if (!_dbus_string_align_length (&message->header, 4))
00359 goto failed;
00360
00361 message->header_fields[field].offset =
00362 _dbus_string_get_length (&message->header);
00363
00364 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00365 value))
00366 goto failed;
00367
00368 if (!append_header_padding (message))
00369 goto failed;
00370
00371 return TRUE;
00372
00373 failed:
00374 message->header_fields[field].offset = -1;
00375 _dbus_string_set_length (&message->header, orig_len);
00376
00377
00378
00379
00380 if (!append_header_padding (message))
00381 _dbus_assert_not_reached ("failed to reappend header padding");
00382 return FALSE;
00383 }
00384
00385 static dbus_bool_t
00386 append_string_field (DBusMessage *message,
00387 int field,
00388 const char *name,
00389 const char *value)
00390 {
00391 int orig_len;
00392
00393 _dbus_assert (!message->locked);
00394
00395 clear_header_padding (message);
00396
00397 orig_len = _dbus_string_get_length (&message->header);
00398
00399 if (!_dbus_string_align_length (&message->header, 4))
00400 goto failed;
00401
00402 if (!_dbus_string_append_len (&message->header, name, 4))
00403 goto failed;
00404
00405 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING))
00406 goto failed;
00407
00408 if (!_dbus_string_align_length (&message->header, 4))
00409 goto failed;
00410
00411 message->header_fields[field].offset =
00412 _dbus_string_get_length (&message->header);
00413
00414 if (!_dbus_marshal_string (&message->header, message->byte_order,
00415 value))
00416 goto failed;
00417
00418 if (!append_header_padding (message))
00419 goto failed;
00420
00421 return TRUE;
00422
00423 failed:
00424 message->header_fields[field].offset = -1;
00425 _dbus_string_set_length (&message->header, orig_len);
00426
00427
00428
00429
00430 if (!append_header_padding (message))
00431 _dbus_assert_not_reached ("failed to reappend header padding");
00432
00433 return FALSE;
00434 }
00435
00436 #ifdef DBUS_BUILD_TESTS
00437
00438
00439
00440 static void
00441 delete_int_or_uint_field (DBusMessage *message,
00442 int field)
00443 {
00444 int offset = message->header_fields[field].offset;
00445
00446 _dbus_assert (!message->locked);
00447 _dbus_assert (field_is_named[field]);
00448
00449 if (offset < 0)
00450 return;
00451
00452 clear_header_padding (message);
00453
00454
00455 _dbus_string_delete (&message->header,
00456 offset - 8,
00457 12);
00458
00459 message->header_fields[field].offset = -1;
00460
00461 adjust_field_offsets (message,
00462 offset - 8,
00463 - 12);
00464
00465 append_header_padding (message);
00466 }
00467 #endif
00468
00469 static void
00470 delete_string_field (DBusMessage *message,
00471 int field)
00472 {
00473 int offset = message->header_fields[field].offset;
00474 int len;
00475 int delete_len;
00476
00477 _dbus_assert (!message->locked);
00478 _dbus_assert (field_is_named[field]);
00479
00480 if (offset < 0)
00481 return;
00482
00483 clear_header_padding (message);
00484
00485 get_string_field (message, field, &len);
00486
00487
00488
00489
00490 delete_len = 8 + 4 + 1 + len;
00491
00492 _dbus_string_delete (&message->header,
00493 offset - 8,
00494 delete_len);
00495
00496 message->header_fields[field].offset = -1;
00497
00498 adjust_field_offsets (message,
00499 offset - 8,
00500 - delete_len);
00501
00502 append_header_padding (message);
00503 }
00504
00505 #ifdef DBUS_BUILD_TESTS
00506 static dbus_bool_t
00507 set_int_field (DBusMessage *message,
00508 int field,
00509 int value)
00510 {
00511 int offset = message->header_fields[field].offset;
00512
00513 _dbus_assert (!message->locked);
00514
00515 if (offset < 0)
00516 {
00517
00518
00519 switch (field)
00520 {
00521 default:
00522 _dbus_assert_not_reached ("appending an int field we don't support appending");
00523 return FALSE;
00524 }
00525 }
00526 else
00527 {
00528 _dbus_marshal_set_int32 (&message->header,
00529 message->byte_order,
00530 offset, value);
00531
00532 return TRUE;
00533 }
00534 }
00535 #endif
00536
00537 static dbus_bool_t
00538 set_uint_field (DBusMessage *message,
00539 int field,
00540 dbus_uint32_t value)
00541 {
00542 int offset = message->header_fields[field].offset;
00543
00544 _dbus_assert (!message->locked);
00545
00546 if (offset < 0)
00547 {
00548
00549
00550 switch (field)
00551 {
00552 case FIELD_REPLY_SERIAL:
00553 return append_uint_field (message, field,
00554 DBUS_HEADER_FIELD_REPLY,
00555 value);
00556 default:
00557 _dbus_assert_not_reached ("appending a uint field we don't support appending");
00558 return FALSE;
00559 }
00560 }
00561 else
00562 {
00563 _dbus_marshal_set_uint32 (&message->header,
00564 message->byte_order,
00565 offset, value);
00566
00567 return TRUE;
00568 }
00569 }
00570
00571 static dbus_bool_t
00572 set_string_field (DBusMessage *message,
00573 int field,
00574 const char *value)
00575 {
00576 int offset = message->header_fields[field].offset;
00577
00578 _dbus_assert (!message->locked);
00579 _dbus_assert (value != NULL);
00580
00581 if (offset < 0)
00582 {
00583
00584
00585 switch (field)
00586 {
00587 case FIELD_SENDER:
00588 return append_string_field (message, field,
00589 DBUS_HEADER_FIELD_SENDER,
00590 value);
00591 default:
00592 _dbus_assert_not_reached ("appending a string field we don't support appending");
00593 return FALSE;
00594 }
00595 }
00596 else
00597 {
00598 DBusString v;
00599 int old_len;
00600 int new_len;
00601 int len;
00602
00603 clear_header_padding (message);
00604
00605 old_len = _dbus_string_get_length (&message->header);
00606
00607 len = strlen (value);
00608
00609 _dbus_string_init_const_len (&v, value,
00610 len + 1);
00611 if (!_dbus_marshal_set_string (&message->header,
00612 message->byte_order,
00613 offset, &v,
00614 len))
00615 goto failed;
00616
00617 new_len = _dbus_string_get_length (&message->header);
00618
00619 adjust_field_offsets (message,
00620 offset,
00621 new_len - old_len);
00622
00623 if (!append_header_padding (message))
00624 goto failed;
00625
00626 return TRUE;
00627
00628 failed:
00629
00630
00631
00632 if (!append_header_padding (message))
00633 _dbus_assert_not_reached ("failed to reappend header padding");
00634
00635 return FALSE;
00636 }
00637 }
00638
00646 void
00647 _dbus_message_set_serial (DBusMessage *message,
00648 dbus_int32_t serial)
00649 {
00650 _dbus_assert (!message->locked);
00651 _dbus_assert (dbus_message_get_serial (message) == 0);
00652
00653 set_uint_field (message, FIELD_CLIENT_SERIAL,
00654 serial);
00655 message->client_serial = serial;
00656 }
00657
00666 dbus_bool_t
00667 dbus_message_set_reply_serial (DBusMessage *message,
00668 dbus_uint32_t reply_serial)
00669 {
00670 _dbus_assert (!message->locked);
00671
00672 if (set_uint_field (message, FIELD_REPLY_SERIAL,
00673 reply_serial))
00674 {
00675 message->reply_serial = reply_serial;
00676 return TRUE;
00677 }
00678 else
00679 return FALSE;
00680 }
00681
00690 dbus_uint32_t
00691 dbus_message_get_serial (DBusMessage *message)
00692 {
00693 return message->client_serial;
00694 }
00695
00703 dbus_uint32_t
00704 dbus_message_get_reply_serial (DBusMessage *message)
00705 {
00706 return message->reply_serial;
00707 }
00708
00721 void
00722 _dbus_message_add_size_counter_link (DBusMessage *message,
00723 DBusList *link)
00724 {
00725
00726
00727
00728
00729
00730
00731 if (message->size_counters == NULL)
00732 {
00733 message->size_counter_delta =
00734 _dbus_string_get_length (&message->header) +
00735 _dbus_string_get_length (&message->body);
00736
00737 #if 0
00738 _dbus_verbose ("message has size %ld\n",
00739 message->size_counter_delta);
00740 #endif
00741 }
00742
00743 _dbus_list_append_link (&message->size_counters, link);
00744
00745 _dbus_counter_adjust (link->data, message->size_counter_delta);
00746 }
00747
00757 dbus_bool_t
00758 _dbus_message_add_size_counter (DBusMessage *message,
00759 DBusCounter *counter)
00760 {
00761 DBusList *link;
00762
00763 link = _dbus_list_alloc_link (counter);
00764 if (link == NULL)
00765 return FALSE;
00766
00767 _dbus_counter_ref (counter);
00768 _dbus_message_add_size_counter_link (message, link);
00769
00770 return TRUE;
00771 }
00772
00781 void
00782 _dbus_message_remove_size_counter (DBusMessage *message,
00783 DBusCounter *counter,
00784 DBusList **link_return)
00785 {
00786 DBusList *link;
00787
00788 link = _dbus_list_find_last (&message->size_counters,
00789 counter);
00790 _dbus_assert (link != NULL);
00791
00792 _dbus_list_unlink (&message->size_counters,
00793 link);
00794 if (link_return)
00795 *link_return = link;
00796 else
00797 _dbus_list_free_link (link);
00798
00799 _dbus_counter_adjust (counter, message->size_counter_delta);
00800
00801 _dbus_counter_unref (counter);
00802 }
00803
00804 static dbus_bool_t
00805 dbus_message_create_header (DBusMessage *message,
00806 const char *name,
00807 const char *service)
00808 {
00809 unsigned int flags;
00810
00811 if (!_dbus_string_append_byte (&message->header, message->byte_order))
00812 return FALSE;
00813
00814 flags = 0;
00815 if (!_dbus_string_append_byte (&message->header, flags))
00816 return FALSE;
00817
00818 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
00819 return FALSE;
00820
00821 if (!_dbus_string_append_byte (&message->header, 0))
00822 return FALSE;
00823
00824 message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
00825 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
00826 return FALSE;
00827
00828 message->header_fields[FIELD_BODY_LENGTH].offset = 8;
00829 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
00830 return FALSE;
00831
00832 message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
00833 if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
00834 return FALSE;
00835
00836
00837 if (service != NULL)
00838 {
00839 if (!append_string_field (message,
00840 FIELD_SERVICE,
00841 DBUS_HEADER_FIELD_SERVICE,
00842 service))
00843 return FALSE;
00844 }
00845
00846 _dbus_assert (name != NULL);
00847 if (!append_string_field (message,
00848 FIELD_NAME,
00849 DBUS_HEADER_FIELD_NAME,
00850 name))
00851 return FALSE;
00852
00853 return TRUE;
00854 }
00855
00865 void
00866 _dbus_message_lock (DBusMessage *message)
00867 {
00868 if (!message->locked)
00869 {
00870
00871 set_uint_field (message,
00872 FIELD_HEADER_LENGTH,
00873 _dbus_string_get_length (&message->header));
00874
00875 set_uint_field (message,
00876 FIELD_BODY_LENGTH,
00877 _dbus_string_get_length (&message->body));
00878
00879 message->locked = TRUE;
00880 }
00881 }
00882
00905 static DBusMessage*
00906 dbus_message_new_empty_header (void)
00907 {
00908 DBusMessage *message;
00909 int i;
00910
00911 message = dbus_new0 (DBusMessage, 1);
00912 if (message == NULL)
00913 return NULL;
00914
00915 message->refcount.value = 1;
00916 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00917 message->client_serial = 0;
00918 message->reply_serial = 0;
00919
00920 _dbus_data_slot_list_init (&message->slot_list);
00921
00922 i = 0;
00923 while (i < FIELD_LAST)
00924 {
00925 message->header_fields[i].offset = -1;
00926 ++i;
00927 }
00928
00929 if (!_dbus_string_init_preallocated (&message->header, 64))
00930 {
00931 dbus_free (message);
00932 return NULL;
00933 }
00934
00935 if (!_dbus_string_init_preallocated (&message->body, 64))
00936 {
00937 _dbus_string_free (&message->header);
00938 dbus_free (message);
00939 return NULL;
00940 }
00941
00942 return message;
00943 }
00944
00945
00957 DBusMessage*
00958 dbus_message_new (const char *name,
00959 const char *destination_service)
00960 {
00961 DBusMessage *message;
00962
00963 _dbus_return_val_if_fail (name != NULL, NULL);
00964
00965 message = dbus_message_new_empty_header ();
00966 if (message == NULL)
00967 return NULL;
00968
00969 if (!dbus_message_create_header (message, name, destination_service))
00970 {
00971 dbus_message_unref (message);
00972 return NULL;
00973 }
00974
00975 return message;
00976 }
00977
00988 DBusMessage*
00989 dbus_message_new_reply (DBusMessage *original_message)
00990 {
00991 DBusMessage *message;
00992 const char *sender, *name;
00993
00994 _dbus_return_val_if_fail (original_message != NULL, NULL);
00995
00996 sender = get_string_field (original_message,
00997 FIELD_SENDER, NULL);
00998 name = get_string_field (original_message,
00999 FIELD_NAME, NULL);
01000
01001
01002
01003 message = dbus_message_new (name, sender);
01004
01005 if (message == NULL)
01006 return NULL;
01007
01008 if (!dbus_message_set_reply_serial (message,
01009 dbus_message_get_serial (original_message)))
01010 {
01011 dbus_message_unref (message);
01012 return NULL;
01013 }
01014
01015 return message;
01016 }
01017
01026 DBusMessage*
01027 dbus_message_new_error_reply (DBusMessage *original_message,
01028 const char *error_name,
01029 const char *error_message)
01030 {
01031 DBusMessage *message;
01032 const char *sender;
01033 DBusMessageIter iter;
01034
01035 _dbus_return_val_if_fail (original_message != NULL, NULL);
01036 _dbus_return_val_if_fail (error_name != NULL, NULL);
01037
01038 sender = get_string_field (original_message,
01039 FIELD_SENDER, NULL);
01040
01041
01042
01043
01044
01045
01046 message = dbus_message_new (error_name, sender);
01047
01048 if (message == NULL)
01049 return NULL;
01050
01051 if (!dbus_message_set_reply_serial (message,
01052 dbus_message_get_serial (original_message)))
01053 {
01054 dbus_message_unref (message);
01055 return NULL;
01056 }
01057
01058 if (error_message != NULL)
01059 {
01060 dbus_message_append_iter_init (message, &iter);
01061 if (!dbus_message_iter_append_string (&iter, error_message))
01062 {
01063 dbus_message_unref (message);
01064 return NULL;
01065 }
01066 }
01067
01068 dbus_message_set_is_error (message, TRUE);
01069
01070 return message;
01071 }
01072
01080 DBusMessage *
01081 dbus_message_copy (const DBusMessage *message)
01082 {
01083 DBusMessage *retval;
01084 int i;
01085
01086 _dbus_return_val_if_fail (message != NULL, NULL);
01087
01088 retval = dbus_new0 (DBusMessage, 1);
01089 if (retval == NULL)
01090 return NULL;
01091
01092 retval->refcount.value = 1;
01093 retval->byte_order = message->byte_order;
01094 retval->client_serial = message->client_serial;
01095 retval->reply_serial = message->reply_serial;
01096 retval->header_padding = message->header_padding;
01097 retval->locked = FALSE;
01098
01099 if (!_dbus_string_init (&retval->header))
01100 {
01101 dbus_free (retval);
01102 return NULL;
01103 }
01104
01105 if (!_dbus_string_init (&retval->body))
01106 {
01107 _dbus_string_free (&retval->header);
01108 dbus_free (retval);
01109 return NULL;
01110 }
01111
01112 if (!_dbus_string_copy (&message->header, 0,
01113 &retval->header, 0))
01114 {
01115 _dbus_string_free (&retval->header);
01116 _dbus_string_free (&retval->body);
01117 dbus_free (retval);
01118
01119 return NULL;
01120 }
01121
01122 if (!_dbus_string_copy (&message->body, 0,
01123 &retval->body, 0))
01124 {
01125 _dbus_string_free (&retval->header);
01126 _dbus_string_free (&retval->body);
01127 dbus_free (retval);
01128
01129 return NULL;
01130 }
01131
01132 for (i = 0; i < FIELD_LAST; i++)
01133 {
01134 retval->header_fields[i].offset = message->header_fields[i].offset;
01135 }
01136
01137 return retval;
01138 }
01139
01140
01147 void
01148 dbus_message_ref (DBusMessage *message)
01149 {
01150 dbus_int32_t old_refcount;
01151
01152 _dbus_return_if_fail (message != NULL);
01153
01154 old_refcount = _dbus_atomic_inc (&message->refcount);
01155 _dbus_assert (old_refcount >= 1);
01156 }
01157
01158 static void
01159 free_size_counter (void *element,
01160 void *data)
01161 {
01162 DBusCounter *counter = element;
01163 DBusMessage *message = data;
01164
01165 _dbus_counter_adjust (counter, - message->size_counter_delta);
01166
01167 _dbus_counter_unref (counter);
01168 }
01169
01176 void
01177 dbus_message_unref (DBusMessage *message)
01178 {
01179 dbus_int32_t old_refcount;
01180
01181 _dbus_return_if_fail (message != NULL);
01182
01183 old_refcount = _dbus_atomic_dec (&message->refcount);
01184
01185 _dbus_assert (old_refcount >= 0);
01186
01187 if (old_refcount == 1)
01188 {
01189
01190 _dbus_data_slot_list_free (&message->slot_list);
01191
01192 _dbus_list_foreach (&message->size_counters,
01193 free_size_counter, message);
01194 _dbus_list_clear (&message->size_counters);
01195
01196 _dbus_string_free (&message->header);
01197 _dbus_string_free (&message->body);
01198
01199 dbus_free (message);
01200 }
01201 }
01202
01209 const char*
01210 dbus_message_get_name (DBusMessage *message)
01211 {
01212 _dbus_return_val_if_fail (message != NULL, NULL);
01213
01214 return get_string_field (message, FIELD_NAME, NULL);
01215 }
01216
01223 const char*
01224 dbus_message_get_destination (DBusMessage *message)
01225 {
01226 _dbus_return_val_if_fail (message != NULL, NULL);
01227
01228 return get_string_field (message, FIELD_SERVICE, NULL);
01229 }
01230
01249 dbus_bool_t
01250 dbus_message_append_args (DBusMessage *message,
01251 int first_arg_type,
01252 ...)
01253 {
01254 dbus_bool_t retval;
01255 va_list var_args;
01256
01257 _dbus_return_val_if_fail (message != NULL, FALSE);
01258
01259 va_start (var_args, first_arg_type);
01260 retval = dbus_message_append_args_valist (message,
01261 first_arg_type,
01262 var_args);
01263 va_end (var_args);
01264
01265 return retval;
01266 }
01267
01281 dbus_bool_t
01282 dbus_message_append_args_valist (DBusMessage *message,
01283 int first_arg_type,
01284 va_list var_args)
01285 {
01286 int type, old_len;
01287 DBusMessageIter iter;
01288
01289 _dbus_return_val_if_fail (message != NULL, FALSE);
01290
01291 old_len = _dbus_string_get_length (&message->body);
01292
01293 type = first_arg_type;
01294
01295 dbus_message_append_iter_init (message, &iter);
01296
01297 while (type != 0)
01298 {
01299 switch (type)
01300 {
01301 case DBUS_TYPE_NIL:
01302 if (!dbus_message_iter_append_nil (&iter))
01303 goto errorout;
01304 break;
01305 case DBUS_TYPE_BOOLEAN:
01306 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
01307 goto errorout;
01308 break;
01309 case DBUS_TYPE_INT32:
01310 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
01311 goto errorout;
01312 break;
01313 case DBUS_TYPE_UINT32:
01314 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
01315 goto errorout;
01316 break;
01317 #ifdef DBUS_HAVE_INT64
01318 case DBUS_TYPE_INT64:
01319 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
01320 goto errorout;
01321 break;
01322 case DBUS_TYPE_UINT64:
01323 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
01324 goto errorout;
01325 break;
01326 #endif
01327 case DBUS_TYPE_DOUBLE:
01328 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
01329 goto errorout;
01330 break;
01331 case DBUS_TYPE_STRING:
01332 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
01333 goto errorout;
01334 break;
01335 case DBUS_TYPE_NAMED:
01336 {
01337 const char *name;
01338 unsigned char *data;
01339 int len;
01340
01341 name = va_arg (var_args, const char *);
01342 data = va_arg (var_args, unsigned char *);
01343 len = va_arg (var_args, int);
01344
01345 if (!dbus_message_iter_append_named (&iter, name, data, len))
01346 goto errorout;
01347 break;
01348 }
01349 case DBUS_TYPE_ARRAY:
01350 {
01351 void *data;
01352 int len, type;
01353
01354 type = va_arg (var_args, int);
01355 data = va_arg (var_args, void *);
01356 len = va_arg (var_args, int);
01357
01358 switch (type)
01359 {
01360 case DBUS_TYPE_BYTE:
01361 if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len))
01362 goto errorout;
01363 break;
01364 case DBUS_TYPE_BOOLEAN:
01365 if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len))
01366 goto errorout;
01367 break;
01368 case DBUS_TYPE_INT32:
01369 if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len))
01370 goto errorout;
01371 break;
01372 case DBUS_TYPE_UINT32:
01373 if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len))
01374 goto errorout;
01375 break;
01376 #ifdef DBUS_HAVE_INT64
01377 case DBUS_TYPE_INT64:
01378 if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len))
01379 goto errorout;
01380 break;
01381 case DBUS_TYPE_UINT64:
01382 if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len))
01383 goto errorout;
01384 break;
01385 #endif
01386 case DBUS_TYPE_DOUBLE:
01387 if (!dbus_message_iter_append_double_array (&iter, (double *)data, len))
01388 goto errorout;
01389 break;
01390 case DBUS_TYPE_STRING:
01391 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
01392 goto errorout;
01393 break;
01394 case DBUS_TYPE_NIL:
01395 case DBUS_TYPE_ARRAY:
01396 case DBUS_TYPE_NAMED:
01397 case DBUS_TYPE_DICT:
01398 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
01399 goto errorout;
01400 default:
01401 _dbus_warn ("Unknown field type %d\n", type);
01402 goto errorout;
01403 }
01404 }
01405 break;
01406
01407 case DBUS_TYPE_DICT:
01408 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
01409 goto errorout;
01410 default:
01411 _dbus_warn ("Unknown field type %d\n", type);
01412 goto errorout;
01413 }
01414
01415 type = va_arg (var_args, int);
01416 }
01417
01418 return TRUE;
01419
01420 errorout:
01421 return FALSE;
01422 }
01423
01424
01437 dbus_bool_t
01438 dbus_message_get_args (DBusMessage *message,
01439 DBusError *error,
01440 int first_arg_type,
01441 ...)
01442 {
01443 dbus_bool_t retval;
01444 va_list var_args;
01445
01446 _dbus_return_val_if_fail (message != NULL, FALSE);
01447 _dbus_return_val_if_error_is_set (error, FALSE);
01448
01449 va_start (var_args, first_arg_type);
01450 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01451 va_end (var_args);
01452
01453 return retval;
01454 }
01455
01468 dbus_bool_t
01469 dbus_message_get_args_valist (DBusMessage *message,
01470 DBusError *error,
01471 int first_arg_type,
01472 va_list var_args)
01473 {
01474 DBusMessageIter iter;
01475
01476 _dbus_return_val_if_fail (message != NULL, FALSE);
01477 _dbus_return_val_if_error_is_set (error, FALSE);
01478
01479 dbus_message_iter_init (message, &iter);
01480 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01481 }
01482
01495 dbus_bool_t
01496 dbus_message_iter_get_args (DBusMessageIter *iter,
01497 DBusError *error,
01498 int first_arg_type,
01499 ...)
01500 {
01501 dbus_bool_t retval;
01502 va_list var_args;
01503
01504 _dbus_return_val_if_fail (iter != NULL, FALSE);
01505 _dbus_return_val_if_error_is_set (error, FALSE);
01506
01507 va_start (var_args, first_arg_type);
01508 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
01509 va_end (var_args);
01510
01511 return retval;
01512 }
01513
01536 dbus_bool_t
01537 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
01538 DBusError *error,
01539 int first_arg_type,
01540 va_list var_args)
01541 {
01542 int spec_type, msg_type, i;
01543 dbus_bool_t retval;
01544
01545 _dbus_return_val_if_fail (iter != NULL, FALSE);
01546 _dbus_return_val_if_error_is_set (error, FALSE);
01547
01548 retval = FALSE;
01549
01550 spec_type = first_arg_type;
01551 i = 0;
01552
01553 while (spec_type != 0)
01554 {
01555 msg_type = dbus_message_iter_get_arg_type (iter);
01556
01557 if (msg_type != spec_type)
01558 {
01559 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01560 "Argument %d is specified to be of type \"%s\", but "
01561 "is actually of type \"%s\"\n", i,
01562 _dbus_type_to_string (spec_type),
01563 _dbus_type_to_string (msg_type));
01564
01565 goto out;
01566 }
01567
01568 switch (spec_type)
01569 {
01570 case DBUS_TYPE_NIL:
01571 break;
01572 case DBUS_TYPE_BYTE:
01573 {
01574 unsigned char *ptr;
01575
01576 ptr = va_arg (var_args, unsigned char *);
01577
01578 *ptr = dbus_message_iter_get_byte (iter);
01579 break;
01580 }
01581 case DBUS_TYPE_BOOLEAN:
01582 {
01583 dbus_bool_t *ptr;
01584
01585 ptr = va_arg (var_args, dbus_bool_t *);
01586
01587 *ptr = dbus_message_iter_get_boolean (iter);
01588 break;
01589 }
01590 case DBUS_TYPE_INT32:
01591 {
01592 dbus_int32_t *ptr;
01593
01594 ptr = va_arg (var_args, dbus_int32_t *);
01595
01596 *ptr = dbus_message_iter_get_int32 (iter);
01597 break;
01598 }
01599 case DBUS_TYPE_UINT32:
01600 {
01601 dbus_uint32_t *ptr;
01602
01603 ptr = va_arg (var_args, dbus_uint32_t *);
01604
01605 *ptr = dbus_message_iter_get_uint32 (iter);
01606 break;
01607 }
01608 #ifdef DBUS_HAVE_INT64
01609 case DBUS_TYPE_INT64:
01610 {
01611 dbus_int64_t *ptr;
01612
01613 ptr = va_arg (var_args, dbus_int64_t *);
01614
01615 *ptr = dbus_message_iter_get_int64 (iter);
01616 break;
01617 }
01618 case DBUS_TYPE_UINT64:
01619 {
01620 dbus_uint64_t *ptr;
01621
01622 ptr = va_arg (var_args, dbus_uint64_t *);
01623
01624 *ptr = dbus_message_iter_get_uint64 (iter);
01625 break;
01626 }
01627 #endif
01628
01629 case DBUS_TYPE_DOUBLE:
01630 {
01631 double *ptr;
01632
01633 ptr = va_arg (var_args, double *);
01634
01635 *ptr = dbus_message_iter_get_double (iter);
01636 break;
01637 }
01638
01639 case DBUS_TYPE_STRING:
01640 {
01641 char **ptr;
01642
01643 ptr = va_arg (var_args, char **);
01644
01645 *ptr = dbus_message_iter_get_string (iter);
01646
01647 if (!*ptr)
01648 {
01649 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01650 goto out;
01651 }
01652
01653 break;
01654 }
01655
01656 case DBUS_TYPE_NAMED:
01657 {
01658 char **name;
01659 unsigned char **data;
01660 int *len;
01661
01662 name = va_arg (var_args, char **);
01663 data = va_arg (var_args, unsigned char **);
01664 len = va_arg (var_args, int *);
01665
01666 if (!dbus_message_iter_get_named (iter, name, data, len))
01667 {
01668 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01669 goto out;
01670 }
01671 }
01672 break;
01673 case DBUS_TYPE_ARRAY:
01674 {
01675 void **data;
01676 int *len, type;
01677
01678 type = va_arg (var_args, int);
01679 data = va_arg (var_args, void *);
01680 len = va_arg (var_args, int *);
01681
01682 if (dbus_message_iter_get_array_type (iter) != type)
01683 {
01684 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01685 "Argument %d is specified to be of type \"array of %s\", but "
01686 "is actually of type \"array of %s\"\n", i,
01687 _dbus_type_to_string (type),
01688 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
01689 goto out;
01690 }
01691
01692 switch (type)
01693 {
01694 case DBUS_TYPE_BYTE:
01695 if (!dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len))
01696 {
01697 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01698 goto out;
01699 }
01700 break;
01701 case DBUS_TYPE_BOOLEAN:
01702 if (!dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len))
01703 {
01704 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01705 goto out;
01706 }
01707 break;
01708 case DBUS_TYPE_INT32:
01709 if (!dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len))
01710 {
01711 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01712 goto out;
01713 }
01714 break;
01715 case DBUS_TYPE_UINT32:
01716 if (!dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len))
01717 {
01718 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01719 goto out;
01720 }
01721 break;
01722 #ifdef DBUS_HAVE_INT64
01723 case DBUS_TYPE_INT64:
01724 if (!dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len))
01725 {
01726 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01727 goto out;
01728 }
01729 break;
01730 case DBUS_TYPE_UINT64:
01731 if (!dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len))
01732 {
01733 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01734 goto out;
01735 }
01736 break;
01737 #endif
01738 case DBUS_TYPE_DOUBLE:
01739 if (!dbus_message_iter_get_double_array (iter, (double **)data, len))
01740 {
01741 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01742 goto out;
01743 }
01744 break;
01745 case DBUS_TYPE_STRING:
01746 if (!dbus_message_iter_get_string_array (iter, (char ***)data, len))
01747 {
01748 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01749 goto out;
01750 }
01751 break;
01752 case DBUS_TYPE_NIL:
01753 case DBUS_TYPE_ARRAY:
01754 case DBUS_TYPE_NAMED:
01755 case DBUS_TYPE_DICT:
01756 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
01757 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
01758 goto out;
01759 default:
01760 _dbus_warn ("Unknown field type %d\n", type);
01761 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
01762 goto out;
01763 }
01764 }
01765 break;
01766 case DBUS_TYPE_DICT:
01767 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
01768 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
01769 goto out;
01770 default:
01771 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
01772 _dbus_warn ("Unknown field type %d\n", spec_type);
01773 goto out;
01774 }
01775
01776 spec_type = va_arg (var_args, int);
01777 if (spec_type != 0 && !dbus_message_iter_next (iter))
01778 {
01779 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01780 "Message has only %d arguments, but more were expected", i);
01781 goto out;
01782 }
01783
01784 i++;
01785 }
01786
01787 retval = TRUE;
01788
01789 out:
01790
01791 return retval;
01792 }
01793
01794
01802 void
01803 dbus_message_iter_init (DBusMessage *message,
01804 DBusMessageIter *iter)
01805 {
01806 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01807
01808 _dbus_return_if_fail (message != NULL);
01809 _dbus_return_if_fail (iter != NULL);
01810
01811 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01812
01813 real->message = message;
01814 real->parent_iter = NULL;
01815 real->changed_stamp = message->changed_stamp;
01816
01817 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
01818 real->pos = 0;
01819 real->end = _dbus_string_get_length (&message->body);
01820
01821 real->container_start = 0;
01822 real->container_length_pos = 0;
01823 real->wrote_dict_key = 0;
01824 real->array_type_pos = 0;
01825 }
01826
01827 #ifndef DBUS_DISABLE_CHECKS
01828 static dbus_bool_t
01829 dbus_message_iter_check (DBusMessageRealIter *iter)
01830 {
01831 if (iter == NULL)
01832 {
01833 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
01834 return FALSE;
01835 }
01836
01837 if (iter->changed_stamp != iter->message->changed_stamp)
01838 {
01839 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
01840 return FALSE;
01841 }
01842
01843 if (iter->pos < 0 || iter->pos > iter->end)
01844 {
01845 _dbus_warn ("dbus iterator check failed: invalid position\n");
01846 return FALSE;
01847 }
01848
01849 return TRUE;
01850 }
01851 #endif
01852
01853 static int
01854 skip_array_type (DBusMessageRealIter *iter, int pos)
01855 {
01856 const char *data;
01857
01858 do
01859 {
01860 data = _dbus_string_get_const_data_len (&iter->message->body,
01861 pos++, 1);
01862 }
01863 while (*data == DBUS_TYPE_ARRAY);
01864
01865 return pos;
01866 }
01867
01868 static int
01869 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
01870 {
01871 const char *data;
01872 int pos, len;
01873
01874 switch (iter->type)
01875 {
01876 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
01877 data = _dbus_string_get_const_data_len (&iter->message->body,
01878 iter->pos, 1);
01879 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
01880 *type = *data;
01881 else
01882 *type = DBUS_TYPE_INVALID;
01883
01884 return skip_array_type (iter, iter->pos);
01885
01886 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
01887 data = _dbus_string_get_const_data_len (&iter->message->body,
01888 iter->array_type_pos, 1);
01889 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
01890 *type = *data;
01891 else
01892 *type = DBUS_TYPE_INVALID;
01893
01894 return iter->pos;
01895
01896 case DBUS_MESSAGE_ITER_TYPE_DICT:
01897
01898 len = _dbus_demarshal_uint32 (&iter->message->body,
01899 iter->message->byte_order,
01900 iter->pos, &pos);
01901 pos = pos + len + 1;
01902
01903 data = _dbus_string_get_const_data_len (&iter->message->body,
01904 pos, 1);
01905 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
01906 *type = *data;
01907 else
01908 *type = DBUS_TYPE_INVALID;
01909
01910 return skip_array_type (iter, pos);
01911
01912 default:
01913 _dbus_assert_not_reached ("Invalid iter type");
01914 break;
01915 }
01916 *type = DBUS_TYPE_INVALID;
01917 return iter->pos;
01918 }
01919
01920
01928 dbus_bool_t
01929 dbus_message_iter_has_next (DBusMessageIter *iter)
01930 {
01931 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01932 int end_pos;
01933 int type, pos;
01934
01935 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
01936
01937 if (real->pos >= real->end)
01938 return FALSE;
01939
01940 pos = dbus_message_iter_get_data_start (real, &type);
01941
01942 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
01943 real->message->byte_order,
01944 type, pos, &end_pos))
01945 return FALSE;
01946
01947 if (end_pos >= real->end)
01948 return FALSE;
01949
01950 return TRUE;
01951 }
01952
01959 dbus_bool_t
01960 dbus_message_iter_next (DBusMessageIter *iter)
01961 {
01962 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01963 int end_pos;
01964 int type, pos;
01965
01966 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
01967
01968 pos = dbus_message_iter_get_data_start (real, &type);
01969
01970 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
01971 real->message->byte_order,
01972 type, pos, &end_pos))
01973 return FALSE;
01974
01975 if (end_pos >= real->end)
01976 return FALSE;
01977
01978 real->pos = end_pos;
01979
01980 return TRUE;
01981 }
01982
01990 int
01991 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01992 {
01993 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01994 int type, pos;
01995
01996 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01997
01998 if (real->pos >= real->end)
01999 return DBUS_TYPE_INVALID;
02000
02001 pos = dbus_message_iter_get_data_start (real, &type);
02002
02003 return type;
02004 }
02005
02006 static int
02007 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02008 {
02009 const char *data;
02010 int _array_type_pos;
02011 int len, pos;
02012
02013 switch (iter->type)
02014 {
02015 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02016 _array_type_pos = iter->pos + 1;
02017 break;
02018 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02019 _array_type_pos = iter->array_type_pos + 1;
02020 break;
02021 case DBUS_MESSAGE_ITER_TYPE_DICT:
02022
02023 len = _dbus_demarshal_uint32 (&iter->message->body,
02024 iter->message->byte_order,
02025 iter->pos, &pos);
02026 pos = pos + len + 1;
02027 data = _dbus_string_get_const_data_len (&iter->message->body,
02028 pos + 1, 1);
02029 _array_type_pos = pos + 1;
02030 break;
02031 default:
02032 _dbus_assert_not_reached ("wrong iter type");
02033 return DBUS_TYPE_INVALID;
02034 }
02035
02036 if (array_type_pos != NULL)
02037 *array_type_pos = _array_type_pos;
02038
02039 data = _dbus_string_get_const_data_len (&iter->message->body,
02040 _array_type_pos, 1);
02041 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
02042 return *data;
02043
02044 return DBUS_TYPE_INVALID;
02045 }
02046
02047
02057 int
02058 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02059 {
02060 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02061 int type, pos;
02062
02063 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02064
02065 if (real->pos >= real->end)
02066 return DBUS_TYPE_INVALID;
02067
02068 pos = dbus_message_iter_get_data_start (real, &type);
02069
02070 _dbus_assert (type == DBUS_TYPE_ARRAY);
02071
02072 return iter_get_array_type (real, NULL);
02073 }
02074
02075
02085 char *
02086 dbus_message_iter_get_string (DBusMessageIter *iter)
02087 {
02088 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02089 int type, pos;
02090
02091 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02092
02093 pos = dbus_message_iter_get_data_start (real, &type);
02094
02095 _dbus_assert (type == DBUS_TYPE_STRING);
02096
02097 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02098 pos, NULL);
02099 }
02100
02115 dbus_bool_t
02116 dbus_message_iter_get_named (DBusMessageIter *iter,
02117 char **name,
02118 unsigned char **value,
02119 int *len)
02120 {
02121 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02122 int type, pos;
02123 char *_name;
02124
02125 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02126
02127 pos = dbus_message_iter_get_data_start (real, &type);
02128
02129 _dbus_assert (type == DBUS_TYPE_NAMED);
02130
02131 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02132 pos, &pos);
02133
02134 if (_name == NULL)
02135 return FALSE;
02136
02137 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02138 pos, NULL, value, len))
02139 {
02140 dbus_free (_name);
02141 return FALSE;
02142 }
02143
02144 *name = _name;
02145
02146 return TRUE;
02147 }
02148
02158 unsigned char
02159 dbus_message_iter_get_byte (DBusMessageIter *iter)
02160 {
02161 unsigned char value;
02162 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02163 int type, pos;
02164
02165 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02166
02167 pos = dbus_message_iter_get_data_start (real, &type);
02168
02169 _dbus_assert (type == DBUS_TYPE_BYTE);
02170
02171 value = _dbus_string_get_byte (&real->message->body, pos);
02172
02173 return value;
02174 }
02175
02176
02186 dbus_bool_t
02187 dbus_message_iter_get_boolean (DBusMessageIter *iter)
02188 {
02189 unsigned char value;
02190 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02191 int type, pos;
02192
02193 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02194
02195 pos = dbus_message_iter_get_data_start (real, &type);
02196
02197 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
02198
02199 value = _dbus_string_get_byte (&real->message->body, pos);
02200
02201 return value;
02202 }
02203
02213 dbus_int32_t
02214 dbus_message_iter_get_int32 (DBusMessageIter *iter)
02215 {
02216 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02217 int type, pos;
02218
02219 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02220
02221 pos = dbus_message_iter_get_data_start (real, &type);
02222
02223 _dbus_assert (type == DBUS_TYPE_INT32);
02224
02225 return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
02226 pos, NULL);
02227 }
02228
02238 dbus_uint32_t
02239 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
02240 {
02241 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02242 int type, pos;
02243
02244 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02245
02246 pos = dbus_message_iter_get_data_start (real, &type);
02247
02248 _dbus_assert (type == DBUS_TYPE_UINT32);
02249
02250 return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02251 pos, NULL);
02252 }
02253
02254 #ifdef DBUS_HAVE_INT64
02255
02267 dbus_int64_t
02268 dbus_message_iter_get_int64 (DBusMessageIter *iter)
02269 {
02270 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02271 int type, pos;
02272
02273 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02274
02275 pos = dbus_message_iter_get_data_start (real, &type);
02276
02277 _dbus_assert (type == DBUS_TYPE_INT64);
02278
02279 return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order,
02280 pos, NULL);
02281 }
02282
02294 dbus_uint64_t
02295 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
02296 {
02297 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02298 int type, pos;
02299
02300 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
02301
02302 pos = dbus_message_iter_get_data_start (real, &type);
02303
02304 _dbus_assert (type == DBUS_TYPE_UINT64);
02305
02306 return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order,
02307 pos, NULL);
02308 }
02309
02310 #endif
02311
02321 double
02322 dbus_message_iter_get_double (DBusMessageIter *iter)
02323 {
02324 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02325 int type, pos;
02326
02327 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0);
02328
02329 pos = dbus_message_iter_get_data_start (real, &type);
02330
02331 _dbus_assert (type == DBUS_TYPE_DOUBLE);
02332
02333 return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
02334 pos, NULL);
02335 }
02336
02350 dbus_bool_t
02351 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
02352 DBusMessageIter *array_iter,
02353 int *array_type)
02354 {
02355 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02356 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
02357 int type, pos, len_pos, len, array_type_pos;
02358 int _array_type;
02359
02360 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02361
02362 pos = dbus_message_iter_get_data_start (real, &type);
02363
02364 _dbus_assert (type == DBUS_TYPE_ARRAY);
02365
02366 _array_type = iter_get_array_type (real, &array_type_pos);
02367
02368 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
02369 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02370 pos, &pos);
02371
02372 array_real->parent_iter = real;
02373 array_real->message = real->message;
02374 array_real->changed_stamp = real->message->changed_stamp;
02375
02376 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
02377 array_real->pos = pos;
02378 array_real->end = pos + len;
02379
02380 array_real->container_start = pos;
02381 array_real->container_length_pos = len_pos;
02382 array_real->wrote_dict_key = 0;
02383 array_real->array_type_pos = array_type_pos;
02384 array_real->array_type_done = TRUE;
02385
02386 if (array_type != NULL)
02387 *array_type = _array_type;
02388
02389 return TRUE;
02390 }
02391
02392
02402 dbus_bool_t
02403 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
02404 DBusMessageIter *dict_iter)
02405 {
02406 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02407 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
02408 int type, pos, len_pos, len;
02409
02410 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02411
02412 pos = dbus_message_iter_get_data_start (real, &type);
02413
02414 _dbus_assert (type == DBUS_TYPE_DICT);
02415
02416 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
02417 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
02418 pos, &pos);
02419
02420 dict_real->parent_iter = real;
02421 dict_real->message = real->message;
02422 dict_real->changed_stamp = real->message->changed_stamp;
02423
02424 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
02425 dict_real->pos = pos;
02426 dict_real->end = pos + len;
02427
02428 dict_real->container_start = pos;
02429 dict_real->container_length_pos = len_pos;
02430 dict_real->wrote_dict_key = 0;
02431
02432 return TRUE;
02433 }
02434
02445 dbus_bool_t
02446 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
02447 unsigned char **value,
02448 int *len)
02449 {
02450 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02451 int type, pos;
02452
02453 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02454
02455 pos = dbus_message_iter_get_data_start (real, &type);
02456
02457 _dbus_assert (type == DBUS_TYPE_ARRAY);
02458
02459 type = iter_get_array_type (real, NULL);
02460
02461 _dbus_assert (type == DBUS_TYPE_BYTE);
02462
02463 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02464 pos, NULL, value, len))
02465 return FALSE;
02466 else
02467 return TRUE;
02468 }
02469
02480 dbus_bool_t
02481 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
02482 unsigned char **value,
02483 int *len)
02484 {
02485 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02486 int type, pos;
02487
02488 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02489
02490 pos = dbus_message_iter_get_data_start (real, &type);
02491
02492 _dbus_assert (type == DBUS_TYPE_ARRAY);
02493
02494 type = iter_get_array_type (real, NULL);
02495
02496 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
02497
02498 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02499 pos, NULL, value, len))
02500 return FALSE;
02501 else
02502 return TRUE;
02503 }
02504
02515 dbus_bool_t
02516 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
02517 dbus_int32_t **value,
02518 int *len)
02519 {
02520 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02521 int type, pos;
02522
02523 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02524
02525 pos = dbus_message_iter_get_data_start (real, &type);
02526
02527 _dbus_assert (type == DBUS_TYPE_ARRAY);
02528
02529 type = iter_get_array_type (real, NULL);
02530
02531 _dbus_assert (type == DBUS_TYPE_INT32);
02532
02533 if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
02534 pos, NULL, value, len))
02535 return FALSE;
02536 else
02537 return TRUE;
02538 }
02539
02550 dbus_bool_t
02551 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
02552 dbus_uint32_t **value,
02553 int *len)
02554 {
02555 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02556 int type, pos;
02557
02558 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02559
02560 pos = dbus_message_iter_get_data_start (real, &type);
02561
02562 _dbus_assert (type == DBUS_TYPE_ARRAY);
02563
02564 type = iter_get_array_type (real, NULL);
02565 _dbus_assert (type == DBUS_TYPE_UINT32);
02566
02567 if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
02568 pos, NULL, value, len))
02569 return FALSE;
02570 else
02571 return TRUE;
02572 }
02573
02574 #ifdef DBUS_HAVE_INT64
02575
02588 dbus_bool_t
02589 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
02590 dbus_int64_t **value,
02591 int *len)
02592 {
02593 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02594 int type, pos;
02595
02596 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02597
02598 pos = dbus_message_iter_get_data_start (real, &type);
02599
02600 _dbus_assert (type == DBUS_TYPE_ARRAY);
02601
02602 type = iter_get_array_type (real, NULL);
02603
02604 _dbus_assert (type == DBUS_TYPE_INT64);
02605
02606 if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order,
02607 pos, NULL, value, len))
02608 return FALSE;
02609 else
02610 return TRUE;
02611 }
02612
02625 dbus_bool_t
02626 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
02627 dbus_uint64_t **value,
02628 int *len)
02629 {
02630 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02631 int type, pos;
02632
02633 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02634
02635 pos = dbus_message_iter_get_data_start (real, &type);
02636
02637 _dbus_assert (type == DBUS_TYPE_ARRAY);
02638
02639 type = iter_get_array_type (real, NULL);
02640 _dbus_assert (type == DBUS_TYPE_UINT64);
02641
02642 if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order,
02643 pos, NULL, value, len))
02644 return FALSE;
02645 else
02646 return TRUE;
02647 }
02648
02649 #endif
02650
02661 dbus_bool_t
02662 dbus_message_iter_get_double_array (DBusMessageIter *iter,
02663 double **value,
02664 int *len)
02665 {
02666 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02667 int type, pos;
02668
02669 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02670
02671 pos = dbus_message_iter_get_data_start (real, &type);
02672
02673 _dbus_assert (type == DBUS_TYPE_ARRAY);
02674
02675 type = iter_get_array_type (real, NULL);
02676 _dbus_assert (type == DBUS_TYPE_DOUBLE);
02677
02678 if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
02679 pos, NULL, value, len))
02680 return FALSE;
02681 else
02682 return TRUE;
02683 }
02684
02700 dbus_bool_t
02701 dbus_message_iter_get_string_array (DBusMessageIter *iter,
02702 char ***value,
02703 int *len)
02704 {
02705 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02706 int type, pos;
02707
02708 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02709
02710 pos = dbus_message_iter_get_data_start (real, &type);
02711
02712 _dbus_assert (type == DBUS_TYPE_ARRAY);
02713
02714 type = iter_get_array_type (real, NULL);
02715 _dbus_assert (type == DBUS_TYPE_STRING);
02716
02717 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
02718 pos, NULL, value, len))
02719 return FALSE;
02720 else
02721 return TRUE;
02722 }
02723
02733 char *
02734 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
02735 {
02736 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02737
02738 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02739
02740 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
02741
02742 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02743 real->pos, NULL);
02744 }
02745
02754 void
02755 dbus_message_append_iter_init (DBusMessage *message,
02756 DBusMessageIter *iter)
02757 {
02758 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02759
02760 _dbus_return_if_fail (message != NULL);
02761 _dbus_return_if_fail (iter != NULL);
02762
02763 real->message = message;
02764 real->parent_iter = NULL;
02765 real->changed_stamp = message->changed_stamp;
02766
02767 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02768 real->end = _dbus_string_get_length (&real->message->body);
02769 real->pos = real->end;
02770
02771 real->container_length_pos = 0;
02772 real->wrote_dict_key = 0;
02773 }
02774
02775 #ifndef DBUS_DISABLE_CHECKS
02776 static dbus_bool_t
02777 dbus_message_iter_append_check (DBusMessageRealIter *iter)
02778 {
02779 if (iter == NULL)
02780 {
02781 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
02782 return FALSE;
02783 }
02784
02785 if (iter->message->locked)
02786 {
02787 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
02788 return FALSE;
02789 }
02790
02791 if (iter->changed_stamp != iter->message->changed_stamp)
02792 {
02793 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
02794 return FALSE;
02795 }
02796
02797 if (iter->pos != iter->end)
02798 {
02799 _dbus_warn ("dbus iterator check failed: can only append at end of message");
02800 return FALSE;
02801 }
02802
02803 if (iter->pos != _dbus_string_get_length (&iter->message->body))
02804 {
02805 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
02806 return FALSE;
02807 }
02808
02809 return TRUE;
02810 }
02811 #endif
02812
02813 static dbus_bool_t
02814 dbus_message_iter_append_type (DBusMessageRealIter *iter,
02815 int type)
02816 {
02817 const char *data;
02818 switch (iter->type)
02819 {
02820 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02821 if (!_dbus_string_append_byte (&iter->message->body, type))
02822 return FALSE;
02823 break;
02824
02825 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02826 data = _dbus_string_get_const_data_len (&iter->message->body,
02827 iter->array_type_pos, 1);
02828 if (type != *data)
02829 {
02830 _dbus_warn ("Appended element of wrong type for array\n");
02831 return FALSE;
02832 }
02833 break;
02834
02835 case DBUS_MESSAGE_ITER_TYPE_DICT:
02836 if (!iter->wrote_dict_key)
02837 {
02838 _dbus_warn ("Appending dict data before key name\n");
02839 return FALSE;
02840 }
02841
02842 if (!_dbus_string_append_byte (&iter->message->body, type))
02843 return FALSE;
02844
02845 break;
02846
02847 default:
02848 _dbus_assert_not_reached ("Invalid iter type");
02849 break;
02850 }
02851
02852 return TRUE;
02853 }
02854
02855 static void
02856 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
02857 {
02858 iter->changed_stamp = iter->message->changed_stamp;
02859
02860
02861 iter->end = _dbus_string_get_length (&iter->message->body);
02862 iter->pos = iter->end;
02863
02864
02865 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
02866 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
02867 _dbus_marshal_set_uint32 (&iter->message->body,
02868 iter->message->byte_order,
02869 iter->container_length_pos,
02870 iter->end - iter->container_start);
02871
02872 if (iter->parent_iter)
02873 dbus_message_iter_update_after_change (iter->parent_iter);
02874 }
02875
02876 static void
02877 dbus_message_iter_append_done (DBusMessageRealIter *iter)
02878 {
02879 iter->message->changed_stamp++;
02880 dbus_message_iter_update_after_change (iter);
02881 iter->wrote_dict_key = FALSE;
02882 }
02883
02890 dbus_bool_t
02891 dbus_message_iter_append_nil (DBusMessageIter *iter)
02892 {
02893 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02894
02895 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
02896
02897 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
02898 return FALSE;
02899
02900 dbus_message_iter_append_done (real);
02901
02902 return TRUE;
02903 }
02904
02912 dbus_bool_t
02913 dbus_message_iter_append_boolean (DBusMessageIter *iter,
02914 dbus_bool_t value)
02915 {
02916 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02917
02918 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
02919
02920 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
02921 return FALSE;
02922
02923 if (!_dbus_string_append_byte (&real->message->body, (value != FALSE)))
02924 {
02925 _dbus_string_set_length (&real->message->body, real->pos);
02926 return FALSE;
02927 }
02928
02929 dbus_message_iter_append_done (real);
02930
02931 return TRUE;
02932 }
02933
02941 dbus_bool_t
02942 dbus_message_iter_append_byte (DBusMessageIter *iter,
02943 unsigned char value)
02944 {
02945 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02946
02947 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
02948
02949 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE))
02950 return FALSE;
02951
02952 if (!_dbus_string_append_byte (&real->message->body, value))
02953 {
02954 _dbus_string_set_length (&real->message->body, real->pos);
02955 return FALSE;
02956 }
02957
02958 dbus_message_iter_append_done (real);
02959
02960 return TRUE;
02961 }
02962
02963
02971 dbus_bool_t
02972 dbus_message_iter_append_int32 (DBusMessageIter *iter,
02973 dbus_int32_t value)
02974 {
02975 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02976
02977 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
02978
02979 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32))
02980 return FALSE;
02981
02982 if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value))
02983 {
02984 _dbus_string_set_length (&real->message->body, real->pos);
02985 return FALSE;
02986 }
02987
02988 dbus_message_iter_append_done (real);
02989
02990 return TRUE;
02991 }
02992
03000 dbus_bool_t
03001 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
03002 dbus_uint32_t value)
03003 {
03004 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03005
03006 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03007
03008 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32))
03009 return FALSE;
03010
03011 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value))
03012 {
03013 _dbus_string_set_length (&real->message->body, real->pos);
03014 return FALSE;
03015 }
03016
03017 dbus_message_iter_append_done (real);
03018
03019 return TRUE;
03020 }
03021
03022 #ifdef DBUS_HAVE_INT64
03023
03033 dbus_bool_t
03034 dbus_message_iter_append_int64 (DBusMessageIter *iter,
03035 dbus_int64_t value)
03036 {
03037 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03038
03039 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03040
03041 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64))
03042 return FALSE;
03043
03044 if (!_dbus_marshal_int64 (&real->message->body, real->message->byte_order, value))
03045 {
03046 _dbus_string_set_length (&real->message->body, real->pos);
03047 return FALSE;
03048 }
03049
03050 dbus_message_iter_append_done (real);
03051
03052 return TRUE;
03053 }
03054
03064 dbus_bool_t
03065 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
03066 dbus_uint64_t value)
03067 {
03068 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03069
03070 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03071
03072 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64))
03073 return FALSE;
03074
03075 if (!_dbus_marshal_uint64 (&real->message->body, real->message->byte_order, value))
03076 {
03077 _dbus_string_set_length (&real->message->body, real->pos);
03078 return FALSE;
03079 }
03080
03081 dbus_message_iter_append_done (real);
03082
03083 return TRUE;
03084 }
03085
03086 #endif
03087
03095 dbus_bool_t
03096 dbus_message_iter_append_double (DBusMessageIter *iter,
03097 double value)
03098 {
03099 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03100
03101 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03102
03103 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE))
03104 return FALSE;
03105
03106 if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value))
03107 {
03108 _dbus_string_set_length (&real->message->body, real->pos);
03109 return FALSE;
03110 }
03111
03112 dbus_message_iter_append_done (real);
03113
03114 return TRUE;
03115 }
03116
03124 dbus_bool_t
03125 dbus_message_iter_append_string (DBusMessageIter *iter,
03126 const char *value)
03127 {
03128 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03129
03130 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03131
03132 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
03133 return FALSE;
03134
03135 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03136 {
03137 _dbus_string_set_length (&real->message->body, real->pos);
03138 return FALSE;
03139 }
03140
03141 dbus_message_iter_append_done (real);
03142
03143 return TRUE;
03144 }
03145
03158 dbus_bool_t
03159 dbus_message_iter_append_named (DBusMessageIter *iter,
03160 const char *name,
03161 const unsigned char *data,
03162 int len)
03163 {
03164 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03165
03166 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03167
03168 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NAMED))
03169 return FALSE;
03170
03171 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
03172 {
03173 _dbus_string_set_length (&real->message->body, real->pos);
03174 return FALSE;
03175 }
03176
03177 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
03178 {
03179 _dbus_string_set_length (&real->message->body, real->pos);
03180 return FALSE;
03181 }
03182
03183 dbus_message_iter_append_done (real);
03184
03185 return TRUE;
03186 }
03187
03188
03197 dbus_bool_t
03198 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
03199 const char *value)
03200 {
03201 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03202
03203 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03204 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03205
03206 if (real->wrote_dict_key)
03207 {
03208 _dbus_warn ("Appendinging multiple dict key names\n");
03209 return FALSE;
03210 }
03211
03212 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03213 {
03214 return FALSE;
03215 }
03216
03217 dbus_message_iter_append_done (real);
03218 real->wrote_dict_key = TRUE;
03219
03220 return TRUE;
03221 }
03222
03223 static dbus_bool_t
03224 array_iter_type_mark_done (DBusMessageRealIter *iter)
03225 {
03226 int len_pos;
03227
03228 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
03229 array_iter_type_mark_done (iter->parent_iter);
03230 else
03231 return TRUE;
03232
03233 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
03234 sizeof (dbus_uint32_t));
03235
03236
03237 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
03238 {
03239 _dbus_string_set_length (&iter->message->body, iter->pos);
03240 return FALSE;
03241 }
03242
03243 iter->container_start = _dbus_string_get_length (&iter->message->body);
03244 iter->container_length_pos = len_pos;
03245 iter->array_type_done = TRUE;
03246
03247 return TRUE;
03248 }
03249
03250 static dbus_bool_t
03251 append_array_type (DBusMessageRealIter *real,
03252 int element_type,
03253 dbus_bool_t *array_type_done,
03254 int *array_type_pos)
03255 {
03256 int existing_element_type;
03257
03258 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
03259 return FALSE;
03260
03261 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
03262 real->array_type_done)
03263 {
03264 existing_element_type = iter_get_array_type (real, array_type_pos);
03265 if (existing_element_type != element_type)
03266 {
03267 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
03268 _dbus_type_to_string (element_type),
03269 _dbus_type_to_string (existing_element_type));
03270 _dbus_string_set_length (&real->message->body, real->pos);
03271 return FALSE;
03272 }
03273 if (array_type_done != NULL)
03274 *array_type_done = TRUE;
03275 }
03276 else
03277 {
03278 if (array_type_pos != NULL)
03279 *array_type_pos = _dbus_string_get_length (&real->message->body);
03280
03281
03282 if (!_dbus_string_append_byte (&real->message->body, element_type))
03283 {
03284 _dbus_string_set_length (&real->message->body, real->pos);
03285 return FALSE;
03286 }
03287
03288 if (array_type_done != NULL)
03289 *array_type_done = element_type != DBUS_TYPE_ARRAY;
03290
03291 if (element_type != DBUS_TYPE_ARRAY &&
03292 !array_iter_type_mark_done (real))
03293 return FALSE;
03294 }
03295
03296 return TRUE;
03297 }
03298
03308 dbus_bool_t
03309 dbus_message_iter_append_array (DBusMessageIter *iter,
03310 DBusMessageIter *array_iter,
03311 int element_type)
03312 {
03313 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03314 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03315 int len_pos;
03316 int array_type_pos;
03317 dbus_bool_t array_type_done;
03318
03319 if (element_type == DBUS_TYPE_NIL)
03320 {
03321 _dbus_warn ("Can't create NIL arrays\n");
03322 return FALSE;
03323 }
03324
03325 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03326
03327 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
03328 return FALSE;
03329
03330 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
03331
03332 if (array_type_done)
03333 {
03334
03335 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
03336 {
03337 _dbus_string_set_length (&real->message->body, real->pos);
03338 return FALSE;
03339 }
03340 }
03341
03342 array_real->parent_iter = real;
03343 array_real->message = real->message;
03344 array_real->changed_stamp = real->message->changed_stamp;
03345
03346 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
03347 array_real->pos = _dbus_string_get_length (&real->message->body);
03348 array_real->end = array_real->end;
03349
03350 array_real->container_start = array_real->pos;
03351 array_real->container_length_pos = len_pos;
03352 array_real->wrote_dict_key = 0;
03353 array_real->array_type_done = array_type_done;
03354 array_real->array_type_pos = array_type_pos;
03355
03356 dbus_message_iter_append_done (array_real);
03357
03358 return TRUE;
03359 }
03360
03369 dbus_bool_t
03370 dbus_message_iter_append_dict (DBusMessageIter *iter,
03371 DBusMessageIter *dict_iter)
03372 {
03373 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03374 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03375 int len_pos;
03376
03377 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03378
03379 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
03380 return FALSE;
03381
03382 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
03383
03384
03385 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
03386 {
03387 _dbus_string_set_length (&real->message->body, real->pos);
03388 return FALSE;
03389 }
03390
03391 dict_real->parent_iter = real;
03392 dict_real->message = real->message;
03393 dict_real->changed_stamp = real->message->changed_stamp;
03394
03395 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03396 dict_real->pos = _dbus_string_get_length (&real->message->body);
03397 dict_real->end = dict_real->end;
03398
03399 dict_real->container_start = dict_real->pos;
03400 dict_real->container_length_pos = len_pos;
03401 dict_real->wrote_dict_key = 0;
03402
03403 dbus_message_iter_append_done (dict_real);
03404
03405 return TRUE;
03406 }
03407
03408
03417 dbus_bool_t
03418 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
03419 unsigned const char *value,
03420 int len)
03421 {
03422 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03423
03424 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03425
03426 if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))
03427 return FALSE;
03428
03429 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
03430 {
03431 _dbus_string_set_length (&real->message->body, real->pos);
03432 return FALSE;
03433 }
03434
03435 dbus_message_iter_append_done (real);
03436
03437 return TRUE;
03438 }
03439
03448 dbus_bool_t
03449 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
03450 const dbus_int32_t *value,
03451 int len)
03452 {
03453 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03454
03455 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03456
03457 if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))
03458 return FALSE;
03459
03460 if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))
03461 {
03462 _dbus_string_set_length (&real->message->body, real->pos);
03463 return FALSE;
03464 }
03465
03466 dbus_message_iter_append_done (real);
03467
03468 return TRUE;
03469 }
03470
03479 dbus_bool_t
03480 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
03481 const dbus_uint32_t *value,
03482 int len)
03483 {
03484 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03485
03486 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03487
03488 if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))
03489 return FALSE;
03490
03491 if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))
03492 {
03493 _dbus_string_set_length (&real->message->body, real->pos);
03494 return FALSE;
03495 }
03496
03497 dbus_message_iter_append_done (real);
03498
03499 return TRUE;
03500 }
03501
03502 #ifdef DBUS_HAVE_INT64
03503
03514 dbus_bool_t
03515 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
03516 const dbus_int64_t *value,
03517 int len)
03518 {
03519 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03520
03521 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03522
03523 if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL))
03524 return FALSE;
03525
03526 if (!_dbus_marshal_int64_array (&real->message->body, real->message->byte_order, value, len))
03527 {
03528 _dbus_string_set_length (&real->message->body, real->pos);
03529 return FALSE;
03530 }
03531
03532 dbus_message_iter_append_done (real);
03533
03534 return TRUE;
03535 }
03536
03547 dbus_bool_t
03548 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
03549 const dbus_uint64_t *value,
03550 int len)
03551 {
03552 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03553
03554 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03555
03556 if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL))
03557 return FALSE;
03558
03559 if (!_dbus_marshal_uint64_array (&real->message->body, real->message->byte_order, value, len))
03560 {
03561 _dbus_string_set_length (&real->message->body, real->pos);
03562 return FALSE;
03563 }
03564
03565 dbus_message_iter_append_done (real);
03566
03567 return TRUE;
03568 }
03569 #endif
03570
03579 dbus_bool_t
03580 dbus_message_iter_append_double_array (DBusMessageIter *iter,
03581 const double *value,
03582 int len)
03583 {
03584 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03585
03586 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03587
03588 if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))
03589 return FALSE;
03590
03591 if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))
03592 {
03593 _dbus_string_set_length (&real->message->body, real->pos);
03594 return FALSE;
03595 }
03596
03597 dbus_message_iter_append_done (real);
03598
03599 return TRUE;
03600 }
03601
03610 dbus_bool_t
03611 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
03612 unsigned const char *value,
03613 int len)
03614 {
03615 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03616
03617 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03618
03619 if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))
03620 return FALSE;
03621
03622 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
03623 {
03624 _dbus_string_set_length (&real->message->body, real->pos);
03625 return FALSE;
03626 }
03627
03628 dbus_message_iter_append_done (real);
03629
03630 return TRUE;
03631 }
03632
03641 dbus_bool_t
03642 dbus_message_iter_append_string_array (DBusMessageIter *iter,
03643 const char **value,
03644 int len)
03645 {
03646 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03647
03648 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03649
03650 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
03651 return FALSE;
03652
03653 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
03654 {
03655 _dbus_string_set_length (&real->message->body, real->pos);
03656 return FALSE;
03657 }
03658
03659 dbus_message_iter_append_done (real);
03660
03661 return TRUE;
03662 }
03663
03671 dbus_bool_t
03672 dbus_message_set_sender (DBusMessage *message,
03673 const char *sender)
03674 {
03675 _dbus_return_val_if_fail (message != NULL, FALSE);
03676 _dbus_return_val_if_fail (!message->locked, FALSE);
03677
03678 if (sender == NULL)
03679 {
03680 delete_string_field (message, FIELD_SENDER);
03681 return TRUE;
03682 }
03683 else
03684 {
03685 return set_string_field (message,
03686 FIELD_SENDER,
03687 sender);
03688 }
03689 }
03690
03698 void
03699 dbus_message_set_is_error (DBusMessage *message,
03700 dbus_bool_t is_error_reply)
03701 {
03702 char *header;
03703
03704 _dbus_return_if_fail (message != NULL);
03705 _dbus_return_if_fail (!message->locked);
03706
03707 header = _dbus_string_get_data_len (&message->header, 1, 1);
03708
03709 if (is_error_reply)
03710 *header |= DBUS_HEADER_FLAG_ERROR;
03711 else
03712 *header &= ~DBUS_HEADER_FLAG_ERROR;
03713 }
03714
03722 dbus_bool_t
03723 dbus_message_get_is_error (DBusMessage *message)
03724 {
03725 const char *header;
03726
03727 _dbus_return_val_if_fail (message != NULL, FALSE);
03728
03729 header = _dbus_string_get_const_data_len (&message->header, 1, 1);
03730
03731 return (*header & DBUS_HEADER_FLAG_ERROR) != 0;
03732 }
03733
03741 const char*
03742 dbus_message_get_sender (DBusMessage *message)
03743 {
03744 _dbus_return_val_if_fail (message != NULL, NULL);
03745
03746 return get_string_field (message, FIELD_SENDER, NULL);
03747 }
03748
03759 dbus_bool_t
03760 dbus_message_has_name (DBusMessage *message,
03761 const char *name)
03762 {
03763 const char *n;
03764
03765 _dbus_return_val_if_fail (message != NULL, FALSE);
03766 _dbus_return_val_if_fail (name != NULL, FALSE);
03767
03768 n = dbus_message_get_name (message);
03769
03770 if (n && strcmp (n, name) == 0)
03771 return TRUE;
03772 else
03773 return FALSE;
03774 }
03775
03786 dbus_bool_t
03787 dbus_message_has_destination (DBusMessage *message,
03788 const char *service)
03789 {
03790 const char *s;
03791
03792 _dbus_return_val_if_fail (message != NULL, FALSE);
03793 _dbus_return_val_if_fail (service != NULL, FALSE);
03794
03795 s = dbus_message_get_destination (message);
03796
03797 if (s && strcmp (s, service) == 0)
03798 return TRUE;
03799 else
03800 return FALSE;
03801 }
03802
03817 dbus_bool_t
03818 dbus_message_has_sender (DBusMessage *message,
03819 const char *service)
03820 {
03821 const char *s;
03822
03823 _dbus_assert (service != NULL);
03824
03825 s = dbus_message_get_sender (message);
03826
03827 if (s && strcmp (s, service) == 0)
03828 return TRUE;
03829 else
03830 return FALSE;
03831 }
03832
03850 dbus_bool_t
03851 dbus_set_error_from_message (DBusError *error,
03852 DBusMessage *message)
03853 {
03854 char *str;
03855
03856 _dbus_return_val_if_fail (message != NULL, FALSE);
03857 _dbus_return_val_if_error_is_set (error, FALSE);
03858
03859 if (!dbus_message_get_is_error (message))
03860 return FALSE;
03861
03862 str = NULL;
03863 dbus_message_get_args (message, NULL,
03864 DBUS_TYPE_STRING, &str,
03865 DBUS_TYPE_INVALID);
03866
03867 dbus_set_error (error, dbus_message_get_name (message),
03868 str ? "%s" : NULL, str);
03869
03870 dbus_free (str);
03871
03872 return TRUE;
03873 }
03874
03899
03900
03901
03902
03903
03907 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
03908
03913 struct DBusMessageLoader
03914 {
03915 int refcount;
03917 DBusString data;
03919 DBusList *messages;
03921 long max_message_size;
03923 unsigned int buffer_outstanding : 1;
03925 unsigned int corrupted : 1;
03926 };
03927
03938 #define INITIAL_LOADER_DATA_LEN 32
03939
03946 DBusMessageLoader*
03947 _dbus_message_loader_new (void)
03948 {
03949 DBusMessageLoader *loader;
03950
03951 loader = dbus_new0 (DBusMessageLoader, 1);
03952 if (loader == NULL)
03953 return NULL;
03954
03955 loader->refcount = 1;
03956
03957
03958
03959
03960 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
03961
03962 if (!_dbus_string_init (&loader->data))
03963 {
03964 dbus_free (loader);
03965 return NULL;
03966 }
03967
03968
03969 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03970 _dbus_string_set_length (&loader->data, 0);
03971
03972 return loader;
03973 }
03974
03980 void
03981 _dbus_message_loader_ref (DBusMessageLoader *loader)
03982 {
03983 loader->refcount += 1;
03984 }
03985
03992 void
03993 _dbus_message_loader_unref (DBusMessageLoader *loader)
03994 {
03995 loader->refcount -= 1;
03996 if (loader->refcount == 0)
03997 {
03998 _dbus_list_foreach (&loader->messages,
03999 (DBusForeachFunction) dbus_message_unref,
04000 NULL);
04001 _dbus_list_clear (&loader->messages);
04002 _dbus_string_free (&loader->data);
04003 dbus_free (loader);
04004 }
04005 }
04006
04025 void
04026 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
04027 DBusString **buffer)
04028 {
04029 _dbus_assert (!loader->buffer_outstanding);
04030
04031 *buffer = &loader->data;
04032
04033 loader->buffer_outstanding = TRUE;
04034 }
04035
04040 #define DBUS_MINIMUM_HEADER_SIZE 16
04041
04043 #define FOUR_CHARS_TO_UINT32(a, b, c, d) \
04044 ((((dbus_uint32_t)a) << 24) | \
04045 (((dbus_uint32_t)b) << 16) | \
04046 (((dbus_uint32_t)c) << 8) | \
04047 ((dbus_uint32_t)d))
04048
04050 #define DBUS_HEADER_FIELD_NAME_AS_UINT32 \
04051 FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
04052
04054 #define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
04055 FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
04056
04058 #define DBUS_HEADER_FIELD_REPLY_AS_UINT32 \
04059 FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
04060
04062 #define DBUS_HEADER_FIELD_SENDER_AS_UINT32 \
04063 FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
04064
04065 static dbus_bool_t
04066 decode_string_field (const DBusString *data,
04067 HeaderField fields[FIELD_LAST],
04068 int pos,
04069 int type,
04070 int field,
04071 const char *field_name)
04072 {
04073 DBusString tmp;
04074 int string_data_pos;
04075
04076 if (fields[field].offset >= 0)
04077 {
04078 _dbus_verbose ("%s field provided twice\n",
04079 field_name);
04080 return FALSE;
04081 }
04082
04083 if (type != DBUS_TYPE_STRING)
04084 {
04085 _dbus_verbose ("%s field has wrong type %s\n",
04086 field_name, _dbus_type_to_string (type));
04087 return FALSE;
04088 }
04089
04090
04091
04092
04093
04094 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
04095 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
04096
04097 _dbus_string_init_const (&tmp,
04098 _dbus_string_get_const_data (data) + string_data_pos);
04099
04100 if (field == FIELD_NAME)
04101 {
04102 if (!_dbus_string_validate_name (&tmp, 0, _dbus_string_get_length (&tmp)))
04103 {
04104 _dbus_verbose ("%s field has invalid content \"%s\"\n",
04105 field_name, _dbus_string_get_const_data (&tmp));
04106 return FALSE;
04107 }
04108
04109 if (_dbus_string_starts_with_c_str (&tmp,
04110 DBUS_NAMESPACE_LOCAL_MESSAGE))
04111 {
04112 _dbus_verbose ("Message is in the local namespace\n");
04113 return FALSE;
04114 }
04115 }
04116 else
04117 {
04118 if (!_dbus_string_validate_service (&tmp, 0, _dbus_string_get_length (&tmp)))
04119 {
04120 _dbus_verbose ("%s field has invalid content \"%s\"\n",
04121 field_name, _dbus_string_get_const_data (&tmp));
04122 return FALSE;
04123 }
04124 }
04125
04126 fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
04127
04128 #if 0
04129 _dbus_verbose ("Found field %s name at offset %d\n",
04130 field_name, fields[field].offset);
04131 #endif
04132
04133 return TRUE;
04134 }
04135
04136 static dbus_bool_t
04137 decode_header_data (const DBusString *data,
04138 int header_len,
04139 int byte_order,
04140 HeaderField fields[FIELD_LAST],
04141 int *message_padding)
04142 {
04143 const char *field;
04144 int pos, new_pos;
04145 int i;
04146 int type;
04147
04148 if (header_len < 16)
04149 return FALSE;
04150
04151 i = 0;
04152 while (i < FIELD_LAST)
04153 {
04154 fields[i].offset = -1;
04155 ++i;
04156 }
04157
04158 fields[FIELD_HEADER_LENGTH].offset = 4;
04159 fields[FIELD_BODY_LENGTH].offset = 8;
04160 fields[FIELD_CLIENT_SERIAL].offset = 12;
04161
04162
04163
04164
04165
04166
04167
04168 pos = 16;
04169 while ((pos + 7) < header_len)
04170 {
04171 pos = _DBUS_ALIGN_VALUE (pos, 4);
04172
04173 if ((pos + 4) > header_len)
04174 return FALSE;
04175
04176 field =_dbus_string_get_const_data_len (data, pos, 4);
04177 pos += 4;
04178
04179 _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
04180
04181 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
04182 {
04183 _dbus_verbose ("Failed to validate type of named header field\n");
04184 return FALSE;
04185 }
04186
04187 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
04188 {
04189 _dbus_verbose ("Failed to validate argument to named header field\n");
04190 return FALSE;
04191 }
04192
04193 if (new_pos > header_len)
04194 {
04195 _dbus_verbose ("Named header field tries to extend beyond header length\n");
04196 return FALSE;
04197 }
04198
04199 switch (DBUS_UINT32_FROM_BE (*(int*)field))
04200 {
04201 case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
04202 if (!decode_string_field (data, fields, pos, type,
04203 FIELD_SERVICE,
04204 DBUS_HEADER_FIELD_SERVICE))
04205 return FALSE;
04206 break;
04207
04208 case DBUS_HEADER_FIELD_NAME_AS_UINT32:
04209 if (!decode_string_field (data, fields, pos, type,
04210 FIELD_NAME,
04211 DBUS_HEADER_FIELD_NAME))
04212 return FALSE;
04213 break;
04214
04215 case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
04216 if (!decode_string_field (data, fields, pos, type,
04217 FIELD_SENDER,
04218 DBUS_HEADER_FIELD_SENDER))
04219 return FALSE;
04220 break;
04221
04222 case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
04223 if (fields[FIELD_REPLY_SERIAL].offset >= 0)
04224 {
04225 _dbus_verbose ("%s field provided twice\n",
04226 DBUS_HEADER_FIELD_REPLY);
04227 return FALSE;
04228 }
04229
04230 if (type != DBUS_TYPE_UINT32)
04231 {
04232 _dbus_verbose ("%s field has wrong type\n", DBUS_HEADER_FIELD_REPLY);
04233 return FALSE;
04234 }
04235
04236 fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos, 4);
04237
04238 _dbus_verbose ("Found reply serial at offset %d\n",
04239 fields[FIELD_REPLY_SERIAL].offset);
04240 break;
04241
04242 default:
04243 _dbus_verbose ("Ignoring an unknown header field: %.4s at offset %d\n",
04244 field, pos);
04245 }
04246
04247 pos = new_pos;
04248 }
04249
04250 if (pos < header_len)
04251 {
04252
04253 _dbus_assert ((header_len - pos) < 8);
04254
04255 if (!_dbus_string_validate_nul (data,
04256 pos, (header_len - pos)))
04257 {
04258 _dbus_verbose ("header alignment padding is not nul\n");
04259 return FALSE;
04260 }
04261 }
04262
04263
04264 if (fields[FIELD_NAME].offset < 0)
04265 {
04266 _dbus_verbose ("No %s field provided\n",
04267 DBUS_HEADER_FIELD_NAME);
04268 return FALSE;
04269 }
04270
04271 if (message_padding)
04272 *message_padding = header_len - pos;
04273
04274 return TRUE;
04275 }
04276
04287 void
04288 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
04289 DBusString *buffer,
04290 int bytes_read)
04291 {
04292 _dbus_assert (loader->buffer_outstanding);
04293 _dbus_assert (buffer == &loader->data);
04294
04295 loader->buffer_outstanding = FALSE;
04296 }
04297
04304 dbus_bool_t
04305 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
04306 {
04307 if (loader->corrupted)
04308 return TRUE;
04309
04310 while (_dbus_string_get_length (&loader->data) >= 16)
04311 {
04312 DBusMessage *message;
04313 const char *header_data;
04314 int byte_order, header_len, body_len, header_padding;
04315 dbus_uint32_t header_len_unsigned, body_len_unsigned;
04316
04317 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
04318
04319 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
04320
04321 if (header_data[2] != DBUS_MAJOR_PROTOCOL_VERSION)
04322 {
04323 _dbus_verbose ("Message has protocol version %d ours is %d\n",
04324 (int) header_data[2], DBUS_MAJOR_PROTOCOL_VERSION);
04325 loader->corrupted = TRUE;
04326 return TRUE;
04327 }
04328
04329 byte_order = header_data[0];
04330
04331 if (byte_order != DBUS_LITTLE_ENDIAN &&
04332 byte_order != DBUS_BIG_ENDIAN)
04333 {
04334 _dbus_verbose ("Message with bad byte order '%c' received\n",
04335 byte_order);
04336 loader->corrupted = TRUE;
04337 return TRUE;
04338 }
04339
04340 header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
04341 body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
04342
04343 if (header_len_unsigned < 16)
04344 {
04345 _dbus_verbose ("Message had broken too-small header length %u\n",
04346 header_len_unsigned);
04347 loader->corrupted = TRUE;
04348 return TRUE;
04349 }
04350
04351 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
04352 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
04353 {
04354 _dbus_verbose ("Header or body length too large (%u %u)\n",
04355 header_len_unsigned,
04356 body_len_unsigned);
04357 loader->corrupted = TRUE;
04358 return TRUE;
04359 }
04360
04361
04362
04363
04364 header_len = header_len_unsigned;
04365 body_len = body_len_unsigned;
04366
04367 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
04368 {
04369
04370 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
04371 header_len);
04372 loader->corrupted = TRUE;
04373 return TRUE;
04374 }
04375
04376 if (header_len + body_len > loader->max_message_size)
04377 {
04378 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
04379 header_len, body_len, loader->max_message_size);
04380 loader->corrupted = TRUE;
04381 return TRUE;
04382 }
04383
04384 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
04385 {
04386 HeaderField fields[FIELD_LAST];
04387 int i;
04388 int next_arg;
04389
04390 #if 0
04391 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
04392 #endif
04393 if (!decode_header_data (&loader->data, header_len, byte_order,
04394 fields, &header_padding))
04395 {
04396 _dbus_verbose ("Header was invalid\n");
04397 loader->corrupted = TRUE;
04398 return TRUE;
04399 }
04400
04401 next_arg = header_len;
04402 while (next_arg < (header_len + body_len))
04403 {
04404 int type;
04405 int prev = next_arg;
04406
04407 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
04408 &type, &next_arg))
04409 {
04410 _dbus_verbose ("invalid typecode at offset %d\n", prev);
04411 loader->corrupted = TRUE;
04412 return TRUE;
04413 }
04414
04415 if (!_dbus_marshal_validate_arg (&loader->data,
04416 byte_order,
04417 0,
04418 type, -1,
04419 next_arg,
04420 &next_arg))
04421 {
04422 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
04423 loader->corrupted = TRUE;
04424 return TRUE;
04425 }
04426
04427 _dbus_assert (next_arg > prev);
04428 }
04429
04430 if (next_arg > (header_len + body_len))
04431 {
04432 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
04433 next_arg, header_len, body_len,
04434 header_len + body_len);
04435 loader->corrupted = TRUE;
04436 return TRUE;
04437 }
04438
04439 message = dbus_message_new_empty_header ();
04440 if (message == NULL)
04441 {
04442 _dbus_verbose ("Failed to allocate empty message\n");
04443 return FALSE;
04444 }
04445
04446 message->byte_order = byte_order;
04447 message->header_padding = header_padding;
04448
04449
04450 i = 0;
04451 while (i < FIELD_LAST)
04452 {
04453 message->header_fields[i] = fields[i];
04454 ++i;
04455 }
04456
04457 if (!_dbus_list_append (&loader->messages, message))
04458 {
04459 _dbus_verbose ("Failed to append new message to loader queue\n");
04460 dbus_message_unref (message);
04461 return FALSE;
04462 }
04463
04464 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
04465 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
04466
04467 _dbus_assert (_dbus_string_get_length (&loader->data) >=
04468 (header_len + body_len));
04469
04470 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
04471 {
04472 _dbus_verbose ("Failed to move header into new message\n");
04473 _dbus_list_remove_last (&loader->messages, message);
04474 dbus_message_unref (message);
04475 return FALSE;
04476 }
04477
04478 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
04479 {
04480 dbus_bool_t result;
04481
04482 _dbus_verbose ("Failed to move body into new message\n");
04483
04484
04485 result = _dbus_string_copy_len (&message->header, 0, header_len,
04486 &loader->data, 0);
04487 _dbus_assert (result);
04488
04489 _dbus_list_remove_last (&loader->messages, message);
04490 dbus_message_unref (message);
04491 return FALSE;
04492 }
04493
04494 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
04495 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
04496
04497
04498
04499
04500 message->reply_serial = get_uint_field (message,
04501 FIELD_REPLY_SERIAL);
04502 message->client_serial = get_uint_field (message,
04503 FIELD_CLIENT_SERIAL);
04504
04505 _dbus_verbose ("Loaded message %p\n", message);
04506 }
04507 else
04508 return TRUE;
04509 }
04510
04511 return TRUE;
04512 }
04513
04521 DBusMessage*
04522 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
04523 {
04524 if (loader->messages)
04525 return loader->messages->data;
04526 else
04527 return NULL;
04528 }
04529
04538 DBusMessage*
04539 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
04540 {
04541 return _dbus_list_pop_first (&loader->messages);
04542 }
04543
04552 DBusList*
04553 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
04554 {
04555 return _dbus_list_pop_first_link (&loader->messages);
04556 }
04557
04564 void
04565 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
04566 DBusList *link)
04567 {
04568 _dbus_list_prepend_link (&loader->messages, link);
04569 }
04570
04580 dbus_bool_t
04581 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
04582 {
04583 return loader->corrupted;
04584 }
04585
04592 void
04593 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
04594 long size)
04595 {
04596 if (size > MAX_SANE_MESSAGE_SIZE)
04597 {
04598 _dbus_verbose ("clamping requested max message size %ld to %d\n",
04599 size, MAX_SANE_MESSAGE_SIZE);
04600 size = MAX_SANE_MESSAGE_SIZE;
04601 }
04602 loader->max_message_size = size;
04603 }
04604
04611 long
04612 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
04613 {
04614 return loader->max_message_size;
04615 }
04616
04617 static DBusDataSlotAllocator slot_allocator;
04618 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
04619
04634 dbus_bool_t
04635 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
04636 {
04637 return _dbus_data_slot_allocator_alloc (&slot_allocator,
04638 _DBUS_LOCK_NAME (message_slots),
04639 slot_p);
04640 }
04641
04653 void
04654 dbus_message_free_data_slot (dbus_int32_t *slot_p)
04655 {
04656 _dbus_return_if_fail (*slot_p >= 0);
04657
04658 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
04659 }
04660
04674 dbus_bool_t
04675 dbus_message_set_data (DBusMessage *message,
04676 dbus_int32_t slot,
04677 void *data,
04678 DBusFreeFunction free_data_func)
04679 {
04680 DBusFreeFunction old_free_func;
04681 void *old_data;
04682 dbus_bool_t retval;
04683
04684 _dbus_return_val_if_fail (message != NULL, FALSE);
04685 _dbus_return_val_if_fail (slot >= 0, FALSE);
04686
04687 retval = _dbus_data_slot_list_set (&slot_allocator,
04688 &message->slot_list,
04689 slot, data, free_data_func,
04690 &old_free_func, &old_data);
04691
04692 if (retval)
04693 {
04694
04695 if (old_free_func)
04696 (* old_free_func) (old_data);
04697 }
04698
04699 return retval;
04700 }
04701
04710 void*
04711 dbus_message_get_data (DBusMessage *message,
04712 dbus_int32_t slot)
04713 {
04714 void *res;
04715
04716 _dbus_return_val_if_fail (message != NULL, NULL);
04717
04718 res = _dbus_data_slot_list_get (&slot_allocator,
04719 &message->slot_list,
04720 slot);
04721
04722 return res;
04723 }
04724
04726 #ifdef DBUS_BUILD_TESTS
04727 #include "dbus-test.h"
04728 #include <stdio.h>
04729
04730 static void
04731 message_iter_test (DBusMessage *message)
04732 {
04733 DBusMessageIter iter, dict, array, array2;
04734 char *str;
04735 unsigned char *data;
04736 dbus_int32_t *our_int_array;
04737 int len;
04738
04739 dbus_message_iter_init (message, &iter);
04740
04741
04742 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
04743 _dbus_assert_not_reached ("Argument type isn't string");
04744
04745 str = dbus_message_iter_get_string (&iter);
04746 if (strcmp (str, "Test string") != 0)
04747 _dbus_assert_not_reached ("Strings differ");
04748 dbus_free (str);
04749
04750 if (!dbus_message_iter_next (&iter))
04751 _dbus_assert_not_reached ("Reached end of arguments");
04752
04753
04754 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
04755 _dbus_assert_not_reached ("Argument type isn't int32");
04756
04757 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
04758 _dbus_assert_not_reached ("Signed integers differ");
04759
04760 if (!dbus_message_iter_next (&iter))
04761 _dbus_assert_not_reached ("Reached end of fields");
04762
04763
04764 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
04765 _dbus_assert_not_reached ("Argument type isn't int32");
04766
04767 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
04768 _dbus_assert_not_reached ("Unsigned integers differ");
04769
04770 if (!dbus_message_iter_next (&iter))
04771 _dbus_assert_not_reached ("Reached end of arguments");
04772
04773
04774 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
04775 _dbus_assert_not_reached ("Argument type isn't double");
04776
04777 if (dbus_message_iter_get_double (&iter) != 3.14159)
04778 _dbus_assert_not_reached ("Doubles differ");
04779
04780 if (!dbus_message_iter_next (&iter))
04781 _dbus_assert_not_reached ("Reached end of arguments");
04782
04783 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
04784 _dbus_assert_not_reached ("Argument type not an array");
04785
04786 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
04787 _dbus_assert_not_reached ("Array type not double");
04788
04789
04790 if (!dbus_message_iter_init_array_iterator (&iter, &array, NULL))
04791 _dbus_assert_not_reached ("Array init failed");
04792
04793 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
04794 _dbus_assert_not_reached ("Argument type isn't double");
04795
04796 if (dbus_message_iter_get_double (&array) != 1.5)
04797 _dbus_assert_not_reached ("Unsigned integers differ");
04798
04799 if (!dbus_message_iter_next (&array))
04800 _dbus_assert_not_reached ("Reached end of arguments");
04801
04802 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
04803 _dbus_assert_not_reached ("Argument type isn't double");
04804
04805 if (dbus_message_iter_get_double (&array) != 2.5)
04806 _dbus_assert_not_reached ("Unsigned integers differ");
04807
04808 if (dbus_message_iter_next (&array))
04809 _dbus_assert_not_reached ("Didn't reach end of arguments");
04810
04811 if (!dbus_message_iter_next (&iter))
04812 _dbus_assert_not_reached ("Reached end of arguments");
04813
04814
04815
04816
04817 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
04818 _dbus_assert_not_reached ("not dict type");
04819
04820 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
04821 _dbus_assert_not_reached ("dict iter failed");
04822
04823 str = dbus_message_iter_get_dict_key (&dict);
04824 if (str == NULL || strcmp (str, "test") != 0)
04825 _dbus_assert_not_reached ("wrong dict key");
04826 dbus_free (str);
04827
04828 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
04829 _dbus_assert_not_reached ("wrong dict entry type");
04830
04831 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
04832 _dbus_assert_not_reached ("wrong dict entry value");
04833
04834 if (!dbus_message_iter_next (&dict))
04835 _dbus_assert_not_reached ("reached end of dict");
04836
04837
04838
04839 str = dbus_message_iter_get_dict_key (&dict);
04840 if (str == NULL || strcmp (str, "array") != 0)
04841 _dbus_assert_not_reached ("wrong dict key");
04842 dbus_free (str);
04843
04844 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
04845 _dbus_assert_not_reached ("Argument type not an array");
04846
04847 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
04848 _dbus_assert_not_reached ("Array type not array");
04849
04850 if (!dbus_message_iter_init_array_iterator (&dict, &array, NULL))
04851 _dbus_assert_not_reached ("Array init failed");
04852
04853 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
04854 _dbus_assert_not_reached ("Argument type isn't array");
04855
04856 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
04857 _dbus_assert_not_reached ("Array type not int32");
04858
04859 if (!dbus_message_iter_init_array_iterator (&array, &array2, NULL))
04860 _dbus_assert_not_reached ("Array init failed");
04861
04862 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
04863 _dbus_assert_not_reached ("Argument type isn't int32");
04864
04865 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
04866 _dbus_assert_not_reached ("Signed integers differ");
04867
04868 if (!dbus_message_iter_next (&array2))
04869 _dbus_assert_not_reached ("Reached end of arguments");
04870
04871 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
04872 _dbus_assert_not_reached ("Signed integers differ");
04873
04874 if (dbus_message_iter_next (&array2))
04875 _dbus_assert_not_reached ("Didn't reached end of arguments");
04876
04877 if (!dbus_message_iter_next (&array))
04878 _dbus_assert_not_reached ("Reached end of arguments");
04879
04880 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
04881 _dbus_assert_not_reached ("Array type not int32");
04882
04883 if (!dbus_message_iter_get_int32_array (&array,
04884 &our_int_array,
04885 &len))
04886 _dbus_assert_not_reached ("couldn't get int32 array");
04887
04888 _dbus_assert (len == 3);
04889 _dbus_assert (our_int_array[0] == 0x34567812 &&
04890 our_int_array[1] == 0x45678123 &&
04891 our_int_array[2] == 0x56781234);
04892 dbus_free (our_int_array);
04893
04894 if (dbus_message_iter_next (&array))
04895 _dbus_assert_not_reached ("Didn't reach end of array");
04896
04897 if (dbus_message_iter_next (&dict))
04898 _dbus_assert_not_reached ("Didn't reach end of dict");
04899
04900 if (!dbus_message_iter_next (&iter))
04901 _dbus_assert_not_reached ("Reached end of arguments");
04902
04903 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
04904 {
04905 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
04906 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
04907 }
04908
04909 if (dbus_message_iter_get_byte (&iter) != 0xF0)
04910 _dbus_assert_not_reached ("wrong value after dict");
04911
04912
04913 if (!dbus_message_iter_next (&iter))
04914 _dbus_assert_not_reached ("Reached end of arguments");
04915
04916 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
04917 _dbus_assert_not_reached ("not a nil type");
04918
04919 if (!dbus_message_iter_next (&iter))
04920 _dbus_assert_not_reached ("Reached end of arguments");
04921
04922 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NAMED)
04923 _dbus_assert_not_reached ("wrong type after dict");
04924
04925 if (!dbus_message_iter_get_named (&iter, &str, &data, &len))
04926 _dbus_assert_not_reached ("failed to get named");
04927
04928 _dbus_assert (strcmp (str, "named")==0);
04929 _dbus_assert (len == 5);
04930 _dbus_assert (strcmp (data, "data")==0);
04931 dbus_free (str);
04932 dbus_free (data);
04933
04934 if (dbus_message_iter_next (&iter))
04935 _dbus_assert_not_reached ("Didn't reach end of arguments");
04936 }
04937
04938
04939 static dbus_bool_t
04940 check_message_handling_type (DBusMessageIter *iter,
04941 int type)
04942 {
04943 DBusMessageIter child_iter;
04944
04945 switch (type)
04946 {
04947 case DBUS_TYPE_NIL:
04948 break;
04949 case DBUS_TYPE_BYTE:
04950 dbus_message_iter_get_byte (iter);
04951 break;
04952 case DBUS_TYPE_BOOLEAN:
04953 dbus_message_iter_get_boolean (iter);
04954 break;
04955 case DBUS_TYPE_INT32:
04956 dbus_message_iter_get_int32 (iter);
04957 break;
04958 case DBUS_TYPE_UINT32:
04959 dbus_message_iter_get_uint32 (iter);
04960 break;
04961 case DBUS_TYPE_INT64:
04962 #ifdef DBUS_HAVE_INT64
04963 dbus_message_iter_get_int64 (iter);
04964 #endif
04965 break;
04966 case DBUS_TYPE_UINT64:
04967 #ifdef DBUS_HAVE_INT64
04968 dbus_message_iter_get_uint64 (iter);
04969 #endif
04970 break;
04971 case DBUS_TYPE_DOUBLE:
04972 dbus_message_iter_get_double (iter);
04973 break;
04974 case DBUS_TYPE_STRING:
04975 {
04976 char *str;
04977 str = dbus_message_iter_get_string (iter);
04978 if (str == NULL)
04979 {
04980 _dbus_warn ("NULL string in message\n");
04981 return FALSE;
04982 }
04983 dbus_free (str);
04984 }
04985 break;
04986 case DBUS_TYPE_NAMED:
04987 {
04988 char *name;
04989 unsigned char *data;
04990 int len;
04991
04992 if (!dbus_message_iter_get_named (iter, &name, &data, &len))
04993 {
04994 _dbus_warn ("error reading name from named type\n");
04995 return FALSE;
04996 }
04997 dbus_free (data);
04998 dbus_free (name);
04999 }
05000 break;
05001 case DBUS_TYPE_ARRAY:
05002 {
05003 int array_type;
05004
05005 if (!dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type))
05006 {
05007 _dbus_warn ("Failed to init array iterator\n");
05008 return FALSE;
05009 }
05010
05011 while (dbus_message_iter_has_next (&child_iter))
05012 {
05013 if (!check_message_handling_type (&child_iter, array_type))
05014 {
05015 _dbus_warn ("error in array element\n");
05016 return FALSE;
05017 }
05018
05019 if (!dbus_message_iter_next (&child_iter))
05020 break;
05021 }
05022 }
05023 break;
05024 case DBUS_TYPE_DICT:
05025 {
05026 int entry_type;
05027 char *key;
05028
05029 if (!dbus_message_iter_init_dict_iterator (iter, &child_iter))
05030 {
05031 _dbus_warn ("Failed to init dict iterator\n");
05032 return FALSE;
05033 }
05034
05035 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
05036 {
05037 key = dbus_message_iter_get_dict_key (&child_iter);
05038 if (key == NULL)
05039 {
05040 _dbus_warn ("error reading dict key\n");
05041 return FALSE;
05042 }
05043 dbus_free (key);
05044
05045 if (!check_message_handling_type (&child_iter, entry_type))
05046 {
05047 _dbus_warn ("error in dict value\n");
05048 return FALSE;
05049 }
05050
05051 if (!dbus_message_iter_next (&child_iter))
05052 break;
05053 }
05054 }
05055 break;
05056
05057 default:
05058 _dbus_warn ("unknown type %d\n", type);
05059 return FALSE;
05060 break;
05061 }
05062 return TRUE;
05063 }
05064
05065
05066 static dbus_bool_t
05067 check_message_handling (DBusMessage *message)
05068 {
05069 DBusMessageIter iter;
05070 int type;
05071 dbus_bool_t retval;
05072 dbus_uint32_t client_serial;
05073
05074 retval = FALSE;
05075
05076 client_serial = dbus_message_get_serial (message);
05077
05078
05079 set_uint_field (message, FIELD_CLIENT_SERIAL,
05080 client_serial);
05081
05082 if (client_serial != dbus_message_get_serial (message))
05083 {
05084 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
05085 goto failed;
05086 }
05087
05088
05089
05090
05091
05092 dbus_message_iter_init (message, &iter);
05093 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
05094 {
05095 if (!check_message_handling_type (&iter, type))
05096 goto failed;
05097
05098 if (!dbus_message_iter_next (&iter))
05099 break;
05100 }
05101
05102 retval = TRUE;
05103
05104 failed:
05105 return retval;
05106 }
05107
05108 static dbus_bool_t
05109 check_have_valid_message (DBusMessageLoader *loader)
05110 {
05111 DBusMessage *message;
05112 dbus_bool_t retval;
05113
05114 message = NULL;
05115 retval = FALSE;
05116
05117 if (!_dbus_message_loader_queue_messages (loader))
05118 _dbus_assert_not_reached ("no memory to queue messages");
05119
05120 if (_dbus_message_loader_get_is_corrupted (loader))
05121 {
05122 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
05123 goto failed;
05124 }
05125
05126 message = _dbus_message_loader_pop_message (loader);
05127 if (message == NULL)
05128 {
05129 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
05130 goto failed;
05131 }
05132
05133 if (_dbus_string_get_length (&loader->data) > 0)
05134 {
05135 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
05136 goto failed;
05137 }
05138
05139
05140
05141
05142
05143 if (!check_message_handling (message))
05144 goto failed;
05145
05146 retval = TRUE;
05147
05148 failed:
05149 if (message)
05150 dbus_message_unref (message);
05151
05152 return retval;
05153 }
05154
05155 static dbus_bool_t
05156 check_invalid_message (DBusMessageLoader *loader)
05157 {
05158 dbus_bool_t retval;
05159
05160 retval = FALSE;
05161
05162 if (!_dbus_message_loader_queue_messages (loader))
05163 _dbus_assert_not_reached ("no memory to queue messages");
05164
05165 if (!_dbus_message_loader_get_is_corrupted (loader))
05166 {
05167 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
05168 goto failed;
05169 }
05170
05171 retval = TRUE;
05172
05173 failed:
05174 return retval;
05175 }
05176
05177 static dbus_bool_t
05178 check_incomplete_message (DBusMessageLoader *loader)
05179 {
05180 DBusMessage *message;
05181 dbus_bool_t retval;
05182
05183 message = NULL;
05184 retval = FALSE;
05185
05186 if (!_dbus_message_loader_queue_messages (loader))
05187 _dbus_assert_not_reached ("no memory to queue messages");
05188
05189 if (_dbus_message_loader_get_is_corrupted (loader))
05190 {
05191 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
05192 goto failed;
05193 }
05194
05195 message = _dbus_message_loader_pop_message (loader);
05196 if (message != NULL)
05197 {
05198 _dbus_warn ("loaded message that was expected to be incomplete\n");
05199 goto failed;
05200 }
05201
05202 retval = TRUE;
05203
05204 failed:
05205 if (message)
05206 dbus_message_unref (message);
05207 return retval;
05208 }
05209
05210 static dbus_bool_t
05211 check_loader_results (DBusMessageLoader *loader,
05212 DBusMessageValidity validity)
05213 {
05214 if (!_dbus_message_loader_queue_messages (loader))
05215 _dbus_assert_not_reached ("no memory to queue messages");
05216
05217 switch (validity)
05218 {
05219 case _DBUS_MESSAGE_VALID:
05220 return check_have_valid_message (loader);
05221 case _DBUS_MESSAGE_INVALID:
05222 return check_invalid_message (loader);
05223 case _DBUS_MESSAGE_INCOMPLETE:
05224 return check_incomplete_message (loader);
05225 case _DBUS_MESSAGE_UNKNOWN:
05226 return TRUE;
05227 }
05228
05229 _dbus_assert_not_reached ("bad DBusMessageValidity");
05230 return FALSE;
05231 }
05232
05233
05242 dbus_bool_t
05243 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
05244 dbus_bool_t is_raw,
05245 DBusString *data)
05246 {
05247 dbus_bool_t retval;
05248
05249 retval = FALSE;
05250
05251 if (is_raw)
05252 {
05253 DBusError error;
05254
05255 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
05256 dbus_error_init (&error);
05257 if (!_dbus_file_get_contents (data, filename, &error))
05258 {
05259 _dbus_warn ("Could not load message file %s: %s\n",
05260 _dbus_string_get_const_data (filename),
05261 error.message);
05262 dbus_error_free (&error);
05263 goto failed;
05264 }
05265 }
05266 else
05267 {
05268 if (!_dbus_message_data_load (data, filename))
05269 {
05270 _dbus_warn ("Could not load message file %s\n",
05271 _dbus_string_get_const_data (filename));
05272 goto failed;
05273 }
05274 }
05275
05276 retval = TRUE;
05277
05278 failed:
05279
05280 return retval;
05281 }
05282
05292 dbus_bool_t
05293 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
05294 dbus_bool_t is_raw,
05295 DBusMessageValidity expected_validity)
05296 {
05297 DBusString data;
05298 dbus_bool_t retval;
05299
05300 retval = FALSE;
05301
05302 if (!_dbus_string_init (&data))
05303 _dbus_assert_not_reached ("could not allocate string\n");
05304
05305 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
05306 &data))
05307 goto failed;
05308
05309 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
05310
05311 failed:
05312
05313 if (!retval)
05314 {
05315 if (_dbus_string_get_length (&data) > 0)
05316 _dbus_verbose_bytes_of_string (&data, 0,
05317 _dbus_string_get_length (&data));
05318
05319 _dbus_warn ("Failed message loader test on %s\n",
05320 _dbus_string_get_const_data (filename));
05321 }
05322
05323 _dbus_string_free (&data);
05324
05325 return retval;
05326 }
05327
05336 dbus_bool_t
05337 dbus_internal_do_not_use_try_message_data (const DBusString *data,
05338 DBusMessageValidity expected_validity)
05339 {
05340 DBusMessageLoader *loader;
05341 dbus_bool_t retval;
05342 int len;
05343 int i;
05344
05345 loader = NULL;
05346 retval = FALSE;
05347
05348
05349
05350 loader = _dbus_message_loader_new ();
05351
05352
05353 _dbus_message_loader_ref (loader);
05354 _dbus_message_loader_unref (loader);
05355 _dbus_message_loader_get_max_message_size (loader);
05356
05357 len = _dbus_string_get_length (data);
05358 for (i = 0; i < len; i++)
05359 {
05360 DBusString *buffer;
05361
05362 _dbus_message_loader_get_buffer (loader, &buffer);
05363 _dbus_string_append_byte (buffer,
05364 _dbus_string_get_byte (data, i));
05365 _dbus_message_loader_return_buffer (loader, buffer, 1);
05366 }
05367
05368 if (!check_loader_results (loader, expected_validity))
05369 goto failed;
05370
05371 _dbus_message_loader_unref (loader);
05372 loader = NULL;
05373
05374
05375
05376 loader = _dbus_message_loader_new ();
05377
05378 {
05379 DBusString *buffer;
05380
05381 _dbus_message_loader_get_buffer (loader, &buffer);
05382 _dbus_string_copy (data, 0, buffer,
05383 _dbus_string_get_length (buffer));
05384 _dbus_message_loader_return_buffer (loader, buffer, 1);
05385 }
05386
05387 if (!check_loader_results (loader, expected_validity))
05388 goto failed;
05389
05390 _dbus_message_loader_unref (loader);
05391 loader = NULL;
05392
05393
05394
05395 loader = _dbus_message_loader_new ();
05396
05397 len = _dbus_string_get_length (data);
05398 for (i = 0; i < len; i += 2)
05399 {
05400 DBusString *buffer;
05401
05402 _dbus_message_loader_get_buffer (loader, &buffer);
05403 _dbus_string_append_byte (buffer,
05404 _dbus_string_get_byte (data, i));
05405 if ((i+1) < len)
05406 _dbus_string_append_byte (buffer,
05407 _dbus_string_get_byte (data, i+1));
05408 _dbus_message_loader_return_buffer (loader, buffer, 1);
05409 }
05410
05411 if (!check_loader_results (loader, expected_validity))
05412 goto failed;
05413
05414 _dbus_message_loader_unref (loader);
05415 loader = NULL;
05416
05417 retval = TRUE;
05418
05419 failed:
05420
05421 if (loader)
05422 _dbus_message_loader_unref (loader);
05423
05424 return retval;
05425 }
05426
05427 static dbus_bool_t
05428 process_test_subdir (const DBusString *test_base_dir,
05429 const char *subdir,
05430 DBusMessageValidity validity,
05431 DBusForeachMessageFileFunc function,
05432 void *user_data)
05433 {
05434 DBusString test_directory;
05435 DBusString filename;
05436 DBusDirIter *dir;
05437 dbus_bool_t retval;
05438 DBusError error;
05439
05440 retval = FALSE;
05441 dir = NULL;
05442
05443 if (!_dbus_string_init (&test_directory))
05444 _dbus_assert_not_reached ("didn't allocate test_directory\n");
05445
05446 _dbus_string_init_const (&filename, subdir);
05447
05448 if (!_dbus_string_copy (test_base_dir, 0,
05449 &test_directory, 0))
05450 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
05451
05452 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
05453 _dbus_assert_not_reached ("couldn't allocate full path");
05454
05455 _dbus_string_free (&filename);
05456 if (!_dbus_string_init (&filename))
05457 _dbus_assert_not_reached ("didn't allocate filename string\n");
05458
05459 dbus_error_init (&error);
05460 dir = _dbus_directory_open (&test_directory, &error);
05461 if (dir == NULL)
05462 {
05463 _dbus_warn ("Could not open %s: %s\n",
05464 _dbus_string_get_const_data (&test_directory),
05465 error.message);
05466 dbus_error_free (&error);
05467 goto failed;
05468 }
05469
05470 printf ("Testing:\n");
05471
05472 next:
05473 while (_dbus_directory_get_next_file (dir, &filename, &error))
05474 {
05475 DBusString full_path;
05476 dbus_bool_t is_raw;
05477
05478 if (!_dbus_string_init (&full_path))
05479 _dbus_assert_not_reached ("couldn't init string");
05480
05481 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
05482 _dbus_assert_not_reached ("couldn't copy dir to full_path");
05483
05484 if (!_dbus_concat_dir_and_file (&full_path, &filename))
05485 _dbus_assert_not_reached ("couldn't concat file to dir");
05486
05487 if (_dbus_string_ends_with_c_str (&filename, ".message"))
05488 is_raw = FALSE;
05489 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
05490 is_raw = TRUE;
05491 else
05492 {
05493 _dbus_verbose ("Skipping non-.message file %s\n",
05494 _dbus_string_get_const_data (&filename));
05495 _dbus_string_free (&full_path);
05496 goto next;
05497 }
05498
05499 printf (" %s\n",
05500 _dbus_string_get_const_data (&filename));
05501
05502 _dbus_verbose (" expecting %s\n",
05503 validity == _DBUS_MESSAGE_VALID ? "valid" :
05504 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
05505 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")));
05506
05507 if (! (*function) (&full_path, is_raw, validity, user_data))
05508 {
05509 _dbus_string_free (&full_path);
05510 goto failed;
05511 }
05512 else
05513 _dbus_string_free (&full_path);
05514 }
05515
05516 if (dbus_error_is_set (&error))
05517 {
05518 _dbus_warn ("Could not get next file in %s: %s\n",
05519 _dbus_string_get_const_data (&test_directory),
05520 error.message);
05521 dbus_error_free (&error);
05522 goto failed;
05523 }
05524
05525 retval = TRUE;
05526
05527 failed:
05528
05529 if (dir)
05530 _dbus_directory_close (dir);
05531 _dbus_string_free (&test_directory);
05532 _dbus_string_free (&filename);
05533
05534 return retval;
05535 }
05536
05546 dbus_bool_t
05547 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
05548 DBusForeachMessageFileFunc func,
05549 void *user_data)
05550 {
05551 DBusString test_directory;
05552 dbus_bool_t retval;
05553
05554 retval = FALSE;
05555
05556 _dbus_string_init_const (&test_directory, test_data_dir);
05557
05558 if (!process_test_subdir (&test_directory, "valid-messages",
05559 _DBUS_MESSAGE_VALID, func, user_data))
05560 goto failed;
05561
05562 if (!process_test_subdir (&test_directory, "invalid-messages",
05563 _DBUS_MESSAGE_INVALID, func, user_data))
05564 goto failed;
05565
05566 if (!process_test_subdir (&test_directory, "incomplete-messages",
05567 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
05568 goto failed;
05569
05570 retval = TRUE;
05571
05572 failed:
05573
05574 _dbus_string_free (&test_directory);
05575
05576 return retval;
05577 }
05578
05579 static void
05580 verify_test_message (DBusMessage *message)
05581 {
05582 DBusMessageIter iter, dict;
05583 DBusError error;
05584 dbus_int32_t our_int;
05585 char *our_str;
05586 double our_double;
05587 dbus_bool_t our_bool;
05588 dbus_uint32_t our_uint32;
05589 dbus_int32_t *our_uint32_array;
05590 int our_uint32_array_len;
05591 dbus_int32_t *our_int32_array;
05592 int our_int32_array_len;
05593 char **our_string_array;
05594 int our_string_array_len;
05595 #ifdef DBUS_HAVE_INT64
05596 dbus_int64_t our_int64;
05597 dbus_uint64_t our_uint64;
05598 dbus_int64_t *our_uint64_array;
05599 int our_uint64_array_len;
05600 dbus_int64_t *our_int64_array;
05601 int our_int64_array_len;
05602 #endif
05603 double *our_double_array;
05604 int our_double_array_len;
05605 unsigned char *our_byte_array;
05606 int our_byte_array_len;
05607 unsigned char *our_boolean_array;
05608 int our_boolean_array_len;
05609
05610 dbus_message_iter_init (message, &iter);
05611
05612 dbus_error_init (&error);
05613 if (!dbus_message_iter_get_args (&iter, &error,
05614 DBUS_TYPE_INT32, &our_int,
05615 #ifdef DBUS_HAVE_INT64
05616 DBUS_TYPE_INT64, &our_int64,
05617 DBUS_TYPE_UINT64, &our_uint64,
05618 #endif
05619 DBUS_TYPE_STRING, &our_str,
05620 DBUS_TYPE_DOUBLE, &our_double,
05621 DBUS_TYPE_BOOLEAN, &our_bool,
05622 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
05623 &our_uint32_array, &our_uint32_array_len,
05624 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
05625 &our_int32_array, &our_int32_array_len,
05626 #ifdef DBUS_HAVE_INT64
05627 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
05628 &our_uint64_array, &our_uint64_array_len,
05629 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
05630 &our_int64_array, &our_int64_array_len,
05631 #endif
05632 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
05633 &our_string_array, &our_string_array_len,
05634 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
05635 &our_double_array, &our_double_array_len,
05636 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
05637 &our_byte_array, &our_byte_array_len,
05638 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
05639 &our_boolean_array, &our_boolean_array_len,
05640 0))
05641 {
05642 _dbus_warn ("error: %s - %s\n", error.name,
05643 (error.message != NULL) ? error.message : "no message");
05644 _dbus_assert_not_reached ("Could not get arguments");
05645 }
05646
05647 if (our_int != -0x12345678)
05648 _dbus_assert_not_reached ("integers differ!");
05649
05650 #ifdef DBUS_HAVE_INT64
05651 if (our_int64 != -0x123456789abcd)
05652 _dbus_assert_not_reached ("64-bit integers differ!");
05653 if (our_uint64 != 0x123456789abcd)
05654 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
05655 #endif
05656
05657 if (our_double != 3.14159)
05658 _dbus_assert_not_reached ("doubles differ!");
05659
05660 if (strcmp (our_str, "Test string") != 0)
05661 _dbus_assert_not_reached ("strings differ!");
05662 dbus_free (our_str);
05663
05664 if (!our_bool)
05665 _dbus_assert_not_reached ("booleans differ");
05666
05667 if (our_uint32_array_len != 4 ||
05668 our_uint32_array[0] != 0x12345678 ||
05669 our_uint32_array[1] != 0x23456781 ||
05670 our_uint32_array[2] != 0x34567812 ||
05671 our_uint32_array[3] != 0x45678123)
05672 _dbus_assert_not_reached ("uint array differs");
05673 dbus_free (our_uint32_array);
05674
05675 if (our_int32_array_len != 4 ||
05676 our_int32_array[0] != 0x12345678 ||
05677 our_int32_array[1] != -0x23456781 ||
05678 our_int32_array[2] != 0x34567812 ||
05679 our_int32_array[3] != -0x45678123)
05680 _dbus_assert_not_reached ("int array differs");
05681 dbus_free (our_int32_array);
05682
05683 #ifdef DBUS_HAVE_INT64
05684 if (our_uint64_array_len != 4 ||
05685 our_uint64_array[0] != 0x12345678 ||
05686 our_uint64_array[1] != 0x23456781 ||
05687 our_uint64_array[2] != 0x34567812 ||
05688 our_uint64_array[3] != 0x45678123)
05689 _dbus_assert_not_reached ("uint64 array differs");
05690 dbus_free (our_uint64_array);
05691
05692 if (our_int64_array_len != 4 ||
05693 our_int64_array[0] != 0x12345678 ||
05694 our_int64_array[1] != -0x23456781 ||
05695 our_int64_array[2] != 0x34567812 ||
05696 our_int64_array[3] != -0x45678123)
05697 _dbus_assert_not_reached ("int64 array differs");
05698 dbus_free (our_int64_array);
05699 #endif
05700
05701 if (our_string_array_len != 4)
05702 _dbus_assert_not_reached ("string array has wrong length");
05703
05704 if (strcmp (our_string_array[0], "Foo") != 0 ||
05705 strcmp (our_string_array[1], "bar") != 0 ||
05706 strcmp (our_string_array[2], "") != 0 ||
05707 strcmp (our_string_array[3], "woo woo woo woo") != 0)
05708 _dbus_assert_not_reached ("string array differs");
05709
05710 dbus_free_string_array (our_string_array);
05711
05712 if (our_double_array_len != 3)
05713 _dbus_assert_not_reached ("double array had wrong length");
05714
05715
05716
05717
05718 if (our_double_array[0] != 0.1234 ||
05719 our_double_array[1] != 9876.54321 ||
05720 our_double_array[2] != -300.0)
05721 _dbus_assert_not_reached ("double array had wrong values");
05722
05723 dbus_free (our_double_array);
05724
05725 if (our_byte_array_len != 4)
05726 _dbus_assert_not_reached ("byte array had wrong length");
05727
05728 if (our_byte_array[0] != 'a' ||
05729 our_byte_array[1] != 'b' ||
05730 our_byte_array[2] != 'c' ||
05731 our_byte_array[3] != 234)
05732 _dbus_assert_not_reached ("byte array had wrong values");
05733
05734 dbus_free (our_byte_array);
05735
05736 if (our_boolean_array_len != 5)
05737 _dbus_assert_not_reached ("bool array had wrong length");
05738
05739 if (our_boolean_array[0] != TRUE ||
05740 our_boolean_array[1] != FALSE ||
05741 our_boolean_array[2] != TRUE ||
05742 our_boolean_array[3] != TRUE ||
05743 our_boolean_array[4] != FALSE)
05744 _dbus_assert_not_reached ("bool array had wrong values");
05745
05746 dbus_free (our_boolean_array);
05747
05748 if (!dbus_message_iter_next (&iter))
05749 _dbus_assert_not_reached ("Reached end of arguments");
05750
05751 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
05752 _dbus_assert_not_reached ("not dict type");
05753
05754 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
05755 _dbus_assert_not_reached ("dict iter failed");
05756
05757 our_str = dbus_message_iter_get_dict_key (&dict);
05758 if (our_str == NULL || strcmp (our_str, "test") != 0)
05759 _dbus_assert_not_reached ("wrong dict key");
05760 dbus_free (our_str);
05761
05762 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
05763 {
05764 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
05765 _dbus_assert_not_reached ("wrong dict entry type");
05766 }
05767
05768 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
05769 {
05770 _dbus_verbose ("dict entry val: %x\n", our_uint32);
05771 _dbus_assert_not_reached ("wrong dict entry value");
05772 }
05773
05774 if (dbus_message_iter_next (&dict))
05775 _dbus_assert_not_reached ("Didn't reach end of dict");
05776
05777 if (!dbus_message_iter_next (&iter))
05778 _dbus_assert_not_reached ("Reached end of arguments");
05779
05780 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
05781 _dbus_assert_not_reached ("wrong type after dict");
05782
05783 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
05784 _dbus_assert_not_reached ("wrong value after dict");
05785
05786 if (dbus_message_iter_next (&iter))
05787 _dbus_assert_not_reached ("Didn't reach end of arguments");
05788 }
05789
05796 dbus_bool_t
05797 _dbus_message_test (const char *test_data_dir)
05798 {
05799 DBusMessage *message;
05800 DBusMessageLoader *loader;
05801 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
05802 int i;
05803 const char *data;
05804 DBusMessage *copy;
05805 const char *name1;
05806 const char *name2;
05807 const dbus_uint32_t our_uint32_array[] =
05808 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
05809 const dbus_uint32_t our_int32_array[] =
05810 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
05811 #ifdef DBUS_HAVE_INT64
05812 const dbus_uint64_t our_uint64_array[] =
05813 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
05814 const dbus_uint64_t our_int64_array[] =
05815 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
05816 #endif
05817 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
05818 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
05819 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
05820 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
05821
05822 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
05823
05824 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
05825 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
05826 _dbus_message_set_serial (message, 1234);
05827 dbus_message_set_sender (message, "org.foo.bar");
05828 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar"));
05829 dbus_message_set_sender (message, NULL);
05830 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar"));
05831 _dbus_assert (dbus_message_get_serial (message) == 1234);
05832 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
05833
05834 _dbus_assert (dbus_message_get_is_error (message) == FALSE);
05835 dbus_message_set_is_error (message, TRUE);
05836 _dbus_assert (dbus_message_get_is_error (message) == TRUE);
05837 dbus_message_set_is_error (message, FALSE);
05838 _dbus_assert (dbus_message_get_is_error (message) == FALSE);
05839
05840 dbus_message_unref (message);
05841
05842
05843 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
05844 _dbus_message_set_serial (message, 1);
05845 dbus_message_append_args (message,
05846 DBUS_TYPE_INT32, -0x12345678,
05847 #ifdef DBUS_HAVE_INT64
05848 DBUS_TYPE_INT64, -0x123456789abcd,
05849 DBUS_TYPE_UINT64, 0x123456789abcd,
05850 #endif
05851 DBUS_TYPE_STRING, "Test string",
05852 DBUS_TYPE_DOUBLE, 3.14159,
05853 DBUS_TYPE_BOOLEAN, TRUE,
05854 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
05855 _DBUS_N_ELEMENTS (our_uint32_array),
05856 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
05857 _DBUS_N_ELEMENTS (our_int32_array),
05858 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
05859 _DBUS_N_ELEMENTS (our_uint64_array),
05860 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
05861 _DBUS_N_ELEMENTS (our_int64_array),
05862 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
05863 _DBUS_N_ELEMENTS (our_string_array),
05864 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
05865 _DBUS_N_ELEMENTS (our_double_array),
05866 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
05867 _DBUS_N_ELEMENTS (our_byte_array),
05868 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
05869 _DBUS_N_ELEMENTS (our_boolean_array),
05870 0);
05871
05872 dbus_message_append_iter_init (message, &iter);
05873 dbus_message_iter_append_dict (&iter, &child_iter);
05874 dbus_message_iter_append_dict_key (&child_iter, "test");
05875 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
05876 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
05877
05878 _dbus_verbose_bytes_of_string (&message->header, 0,
05879 _dbus_string_get_length (&message->header));
05880 _dbus_verbose_bytes_of_string (&message->body, 0,
05881 _dbus_string_get_length (&message->body));
05882
05883 verify_test_message (message);
05884
05885 copy = dbus_message_copy (message);
05886
05887 _dbus_assert (message->client_serial == copy->client_serial);
05888 _dbus_assert (message->reply_serial == copy->reply_serial);
05889 _dbus_assert (message->header_padding == copy->header_padding);
05890
05891 _dbus_assert (_dbus_string_get_length (&message->header) ==
05892 _dbus_string_get_length (©->header));
05893
05894 _dbus_assert (_dbus_string_get_length (&message->body) ==
05895 _dbus_string_get_length (©->body));
05896
05897 verify_test_message (copy);
05898
05899 name1 = dbus_message_get_name (message);
05900 name2 = dbus_message_get_name (copy);
05901
05902 _dbus_assert (strcmp (name1, name2) == 0);
05903
05904 dbus_message_unref (message);
05905 dbus_message_unref (copy);
05906
05907 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
05908 _dbus_message_set_serial (message, 1);
05909 dbus_message_set_reply_serial (message, 0x12345678);
05910
05911 dbus_message_append_iter_init (message, &iter);
05912 dbus_message_iter_append_string (&iter, "Test string");
05913 dbus_message_iter_append_int32 (&iter, -0x12345678);
05914 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
05915 dbus_message_iter_append_double (&iter, 3.14159);
05916
05917 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
05918 dbus_message_iter_append_double (&child_iter, 1.5);
05919 dbus_message_iter_append_double (&child_iter, 2.5);
05920
05921
05922 dbus_message_iter_append_dict (&iter, &child_iter);
05923 dbus_message_iter_append_dict_key (&child_iter, "test");
05924 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
05925
05926
05927 dbus_message_iter_append_dict_key (&child_iter, "array");
05928 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
05929 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
05930 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
05931 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
05932 _dbus_warn ("next call expected to fail with wrong array type\n");
05933 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
05934 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
05935 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
05936 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
05937 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
05938
05939 dbus_message_iter_append_byte (&iter, 0xF0);
05940
05941 dbus_message_iter_append_nil (&iter);
05942
05943 dbus_message_iter_append_named (&iter, "named",
05944 "data", 5);
05945
05946 message_iter_test (message);
05947
05948
05949 _dbus_message_lock (message);
05950 loader = _dbus_message_loader_new ();
05951
05952
05953 _dbus_message_loader_ref (loader);
05954 _dbus_message_loader_unref (loader);
05955
05956
05957 data = _dbus_string_get_const_data (&message->header);
05958 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
05959 {
05960 DBusString *buffer;
05961
05962 _dbus_message_loader_get_buffer (loader, &buffer);
05963 _dbus_string_append_byte (buffer, data[i]);
05964 _dbus_message_loader_return_buffer (loader, buffer, 1);
05965 }
05966
05967
05968 data = _dbus_string_get_const_data (&message->body);
05969 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
05970 {
05971 DBusString *buffer;
05972
05973 _dbus_message_loader_get_buffer (loader, &buffer);
05974 _dbus_string_append_byte (buffer, data[i]);
05975 _dbus_message_loader_return_buffer (loader, buffer, 1);
05976 }
05977
05978 dbus_message_unref (message);
05979
05980
05981 if (!_dbus_message_loader_queue_messages (loader))
05982 _dbus_assert_not_reached ("no memory to queue messages");
05983
05984 if (_dbus_message_loader_get_is_corrupted (loader))
05985 _dbus_assert_not_reached ("message loader corrupted");
05986
05987 message = _dbus_message_loader_pop_message (loader);
05988 if (!message)
05989 _dbus_assert_not_reached ("received a NULL message");
05990
05991 if (dbus_message_get_reply_serial (message) != 0x12345678)
05992 _dbus_assert_not_reached ("reply serial fields differ");
05993
05994 message_iter_test (message);
05995
05996 dbus_message_unref (message);
05997 _dbus_message_loader_unref (loader);
05998
05999
06000 if (test_data_dir == NULL)
06001 return TRUE;
06002
06003 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
06004 (DBusForeachMessageFileFunc)
06005 dbus_internal_do_not_use_try_message_file,
06006 NULL);
06007 }
06008
06009 #endif