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-recursive.h"
00027 #include "dbus-marshal-validate.h"
00028 #include "dbus-marshal-byteswap.h"
00029 #include "dbus-marshal-header.h"
00030 #include "dbus-signature.h"
00031 #include "dbus-message-private.h"
00032 #include "dbus-object-tree.h"
00033 #include "dbus-memory.h"
00034 #include "dbus-list.h"
00035 #include "dbus-threads-internal.h"
00036 #include <string.h>
00037
00048
00049
00051 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00052
00053
00054
00055
00056 enum {
00057 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00058 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00059 };
00060
00062 typedef struct DBusMessageRealIter DBusMessageRealIter;
00063
00069 struct DBusMessageRealIter
00070 {
00071 DBusMessage *message;
00072 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00073 dbus_uint32_t iter_type : 3;
00074 dbus_uint32_t sig_refcount : 8;
00075 union
00076 {
00077 DBusTypeWriter writer;
00078 DBusTypeReader reader;
00079 } u;
00080 };
00081
00082 static void
00083 get_const_signature (DBusHeader *header,
00084 const DBusString **type_str_p,
00085 int *type_pos_p)
00086 {
00087 if (_dbus_header_get_field_raw (header,
00088 DBUS_HEADER_FIELD_SIGNATURE,
00089 type_str_p,
00090 type_pos_p))
00091 {
00092 *type_pos_p += 1;
00093 }
00094 else
00095 {
00096 *type_str_p = &_dbus_empty_signature_str;
00097 *type_pos_p = 0;
00098 }
00099 }
00100
00106 static void
00107 _dbus_message_byteswap (DBusMessage *message)
00108 {
00109 const DBusString *type_str;
00110 int type_pos;
00111
00112 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
00113 return;
00114
00115 _dbus_verbose ("Swapping message into compiler byte order\n");
00116
00117 get_const_signature (&message->header, &type_str, &type_pos);
00118
00119 _dbus_marshal_byteswap (type_str, type_pos,
00120 message->byte_order,
00121 DBUS_COMPILER_BYTE_ORDER,
00122 &message->body, 0);
00123
00124 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00125
00126 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00127 }
00128
00129 #define ensure_byte_order(message) \
00130 if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
00131 _dbus_message_byteswap (message)
00132
00143 void
00144 _dbus_message_get_network_data (DBusMessage *message,
00145 const DBusString **header,
00146 const DBusString **body)
00147 {
00148 _dbus_assert (message->locked);
00149
00150 *header = &message->header.data;
00151 *body = &message->body;
00152 }
00153
00161 void
00162 _dbus_message_set_serial (DBusMessage *message,
00163 dbus_uint32_t serial)
00164 {
00165 _dbus_assert (message != NULL);
00166 _dbus_assert (!message->locked);
00167 _dbus_assert (dbus_message_get_serial (message) == 0);
00168
00169 _dbus_header_set_serial (&message->header, serial);
00170 }
00171
00184 void
00185 _dbus_message_add_size_counter_link (DBusMessage *message,
00186 DBusList *link)
00187 {
00188
00189
00190
00191
00192
00193
00194 if (message->size_counters == NULL)
00195 {
00196 message->size_counter_delta =
00197 _dbus_string_get_length (&message->header.data) +
00198 _dbus_string_get_length (&message->body);
00199
00200 #if 0
00201 _dbus_verbose ("message has size %ld\n",
00202 message->size_counter_delta);
00203 #endif
00204 }
00205
00206 _dbus_list_append_link (&message->size_counters, link);
00207
00208 _dbus_counter_adjust (link->data, message->size_counter_delta);
00209 }
00210
00220 dbus_bool_t
00221 _dbus_message_add_size_counter (DBusMessage *message,
00222 DBusCounter *counter)
00223 {
00224 DBusList *link;
00225
00226 link = _dbus_list_alloc_link (counter);
00227 if (link == NULL)
00228 return FALSE;
00229
00230 _dbus_counter_ref (counter);
00231 _dbus_message_add_size_counter_link (message, link);
00232
00233 return TRUE;
00234 }
00235
00244 void
00245 _dbus_message_remove_size_counter (DBusMessage *message,
00246 DBusCounter *counter,
00247 DBusList **link_return)
00248 {
00249 DBusList *link;
00250
00251 link = _dbus_list_find_last (&message->size_counters,
00252 counter);
00253 _dbus_assert (link != NULL);
00254
00255 _dbus_list_unlink (&message->size_counters,
00256 link);
00257 if (link_return)
00258 *link_return = link;
00259 else
00260 _dbus_list_free_link (link);
00261
00262 _dbus_counter_adjust (counter, - message->size_counter_delta);
00263
00264 _dbus_counter_unref (counter);
00265 }
00266
00276 void
00277 _dbus_message_lock (DBusMessage *message)
00278 {
00279 if (!message->locked)
00280 {
00281 _dbus_header_update_lengths (&message->header,
00282 _dbus_string_get_length (&message->body));
00283
00284
00285 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00286 dbus_message_get_signature (message) != NULL);
00287
00288 message->locked = TRUE;
00289 }
00290 }
00291
00292 static dbus_bool_t
00293 set_or_delete_string_field (DBusMessage *message,
00294 int field,
00295 int typecode,
00296 const char *value)
00297 {
00298 if (value == NULL)
00299 return _dbus_header_delete_field (&message->header, field);
00300 else
00301 return _dbus_header_set_field_basic (&message->header,
00302 field,
00303 typecode,
00304 &value);
00305 }
00306
00307 #if 0
00308
00332 static dbus_bool_t
00333 _dbus_message_set_signature (DBusMessage *message,
00334 const char *signature)
00335 {
00336 _dbus_return_val_if_fail (message != NULL, FALSE);
00337 _dbus_return_val_if_fail (!message->locked, FALSE);
00338 _dbus_return_val_if_fail (signature == NULL ||
00339 _dbus_check_is_valid_signature (signature));
00340
00341 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00342 signature != NULL);
00343
00344 return set_or_delete_string_field (message,
00345 DBUS_HEADER_FIELD_SIGNATURE,
00346 DBUS_TYPE_SIGNATURE,
00347 signature);
00348 }
00349 #endif
00350
00383 dbus_uint32_t
00384 dbus_message_get_serial (DBusMessage *message)
00385 {
00386 _dbus_return_val_if_fail (message != NULL, 0);
00387
00388 return _dbus_header_get_serial (&message->header);
00389 }
00390
00399 dbus_bool_t
00400 dbus_message_set_reply_serial (DBusMessage *message,
00401 dbus_uint32_t reply_serial)
00402 {
00403 _dbus_return_val_if_fail (message != NULL, FALSE);
00404 _dbus_return_val_if_fail (!message->locked, FALSE);
00405 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
00406
00407 return _dbus_header_set_field_basic (&message->header,
00408 DBUS_HEADER_FIELD_REPLY_SERIAL,
00409 DBUS_TYPE_UINT32,
00410 &reply_serial);
00411 }
00412
00419 dbus_uint32_t
00420 dbus_message_get_reply_serial (DBusMessage *message)
00421 {
00422 dbus_uint32_t v_UINT32;
00423
00424 _dbus_return_val_if_fail (message != NULL, 0);
00425
00426 if (_dbus_header_get_field_basic (&message->header,
00427 DBUS_HEADER_FIELD_REPLY_SERIAL,
00428 DBUS_TYPE_UINT32,
00429 &v_UINT32))
00430 return v_UINT32;
00431 else
00432 return 0;
00433 }
00434
00435 static void
00436 free_size_counter (void *element,
00437 void *data)
00438 {
00439 DBusCounter *counter = element;
00440 DBusMessage *message = data;
00441
00442 _dbus_counter_adjust (counter, - message->size_counter_delta);
00443
00444 _dbus_counter_unref (counter);
00445 }
00446
00447 static void
00448 dbus_message_finalize (DBusMessage *message)
00449 {
00450 _dbus_assert (message->refcount.value == 0);
00451
00452
00453 _dbus_data_slot_list_free (&message->slot_list);
00454
00455 _dbus_list_foreach (&message->size_counters,
00456 free_size_counter, message);
00457 _dbus_list_clear (&message->size_counters);
00458
00459 _dbus_header_free (&message->header);
00460 _dbus_string_free (&message->body);
00461
00462 _dbus_assert (message->refcount.value == 0);
00463
00464 dbus_free (message);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00514 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00515
00517 #define MAX_MESSAGE_CACHE_SIZE 5
00518
00519 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00520 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00521 static int message_cache_count = 0;
00522 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00523
00524 static void
00525 dbus_message_cache_shutdown (void *data)
00526 {
00527 int i;
00528
00529 _DBUS_LOCK (message_cache);
00530
00531 i = 0;
00532 while (i < MAX_MESSAGE_CACHE_SIZE)
00533 {
00534 if (message_cache[i])
00535 dbus_message_finalize (message_cache[i]);
00536
00537 ++i;
00538 }
00539
00540 message_cache_count = 0;
00541 message_cache_shutdown_registered = FALSE;
00542
00543 _DBUS_UNLOCK (message_cache);
00544 }
00545
00553 static DBusMessage*
00554 dbus_message_get_cached (void)
00555 {
00556 DBusMessage *message;
00557 int i;
00558
00559 message = NULL;
00560
00561 _DBUS_LOCK (message_cache);
00562
00563 _dbus_assert (message_cache_count >= 0);
00564
00565 if (message_cache_count == 0)
00566 {
00567 _DBUS_UNLOCK (message_cache);
00568 return NULL;
00569 }
00570
00571
00572
00573
00574
00575 _dbus_assert (message_cache_shutdown_registered);
00576
00577 i = 0;
00578 while (i < MAX_MESSAGE_CACHE_SIZE)
00579 {
00580 if (message_cache[i])
00581 {
00582 message = message_cache[i];
00583 message_cache[i] = NULL;
00584 message_cache_count -= 1;
00585 break;
00586 }
00587 ++i;
00588 }
00589 _dbus_assert (message_cache_count >= 0);
00590 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00591 _dbus_assert (message != NULL);
00592
00593 _DBUS_UNLOCK (message_cache);
00594
00595 _dbus_assert (message->refcount.value == 0);
00596 _dbus_assert (message->size_counters == NULL);
00597
00598 return message;
00599 }
00600
00606 static void
00607 dbus_message_cache_or_finalize (DBusMessage *message)
00608 {
00609 dbus_bool_t was_cached;
00610 int i;
00611
00612 _dbus_assert (message->refcount.value == 0);
00613
00614
00615
00616
00617 _dbus_data_slot_list_clear (&message->slot_list);
00618
00619 _dbus_list_foreach (&message->size_counters,
00620 free_size_counter, message);
00621 _dbus_list_clear (&message->size_counters);
00622
00623 was_cached = FALSE;
00624
00625 _DBUS_LOCK (message_cache);
00626
00627 if (!message_cache_shutdown_registered)
00628 {
00629 _dbus_assert (message_cache_count == 0);
00630
00631 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00632 goto out;
00633
00634 i = 0;
00635 while (i < MAX_MESSAGE_CACHE_SIZE)
00636 {
00637 message_cache[i] = NULL;
00638 ++i;
00639 }
00640
00641 message_cache_shutdown_registered = TRUE;
00642 }
00643
00644 _dbus_assert (message_cache_count >= 0);
00645
00646 if ((_dbus_string_get_length (&message->header.data) +
00647 _dbus_string_get_length (&message->body)) >
00648 MAX_MESSAGE_SIZE_TO_CACHE)
00649 goto out;
00650
00651 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00652 goto out;
00653
00654
00655 i = 0;
00656 while (message_cache[i] != NULL)
00657 ++i;
00658
00659 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00660
00661 _dbus_assert (message_cache[i] == NULL);
00662 message_cache[i] = message;
00663 message_cache_count += 1;
00664 was_cached = TRUE;
00665 #ifndef DBUS_DISABLE_CHECKS
00666 message->in_cache = TRUE;
00667 #endif
00668
00669 out:
00670 _DBUS_UNLOCK (message_cache);
00671
00672 _dbus_assert (message->refcount.value == 0);
00673
00674 if (!was_cached)
00675 dbus_message_finalize (message);
00676 }
00677
00678 static DBusMessage*
00679 dbus_message_new_empty_header (void)
00680 {
00681 DBusMessage *message;
00682 dbus_bool_t from_cache;
00683
00684 message = dbus_message_get_cached ();
00685
00686 if (message != NULL)
00687 {
00688 from_cache = TRUE;
00689 }
00690 else
00691 {
00692 from_cache = FALSE;
00693 message = dbus_new (DBusMessage, 1);
00694 if (message == NULL)
00695 return NULL;
00696 #ifndef DBUS_DISABLE_CHECKS
00697 message->generation = _dbus_current_generation;
00698 #endif
00699 }
00700
00701 message->refcount.value = 1;
00702 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00703 message->locked = FALSE;
00704 #ifndef DBUS_DISABLE_CHECKS
00705 message->in_cache = FALSE;
00706 #endif
00707 message->size_counters = NULL;
00708 message->size_counter_delta = 0;
00709 message->changed_stamp = 0;
00710
00711 if (!from_cache)
00712 _dbus_data_slot_list_init (&message->slot_list);
00713
00714 if (from_cache)
00715 {
00716 _dbus_header_reinit (&message->header, message->byte_order);
00717 _dbus_string_set_length (&message->body, 0);
00718 }
00719 else
00720 {
00721 if (!_dbus_header_init (&message->header, message->byte_order))
00722 {
00723 dbus_free (message);
00724 return NULL;
00725 }
00726
00727 if (!_dbus_string_init_preallocated (&message->body, 32))
00728 {
00729 _dbus_header_free (&message->header);
00730 dbus_free (message);
00731 return NULL;
00732 }
00733 }
00734
00735 return message;
00736 }
00737
00746 DBusMessage*
00747 dbus_message_new (int message_type)
00748 {
00749 DBusMessage *message;
00750
00751 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
00752
00753 message = dbus_message_new_empty_header ();
00754 if (message == NULL)
00755 return NULL;
00756
00757 if (!_dbus_header_create (&message->header,
00758 message_type,
00759 NULL, NULL, NULL, NULL, NULL))
00760 {
00761 dbus_message_unref (message);
00762 return NULL;
00763 }
00764
00765 return message;
00766 }
00767
00785 DBusMessage*
00786 dbus_message_new_method_call (const char *destination,
00787 const char *path,
00788 const char *interface,
00789 const char *method)
00790 {
00791 DBusMessage *message;
00792
00793 _dbus_return_val_if_fail (path != NULL, NULL);
00794 _dbus_return_val_if_fail (method != NULL, NULL);
00795 _dbus_return_val_if_fail (destination == NULL ||
00796 _dbus_check_is_valid_bus_name (destination), NULL);
00797 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
00798 _dbus_return_val_if_fail (interface == NULL ||
00799 _dbus_check_is_valid_interface (interface), NULL);
00800 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
00801
00802 message = dbus_message_new_empty_header ();
00803 if (message == NULL)
00804 return NULL;
00805
00806 if (!_dbus_header_create (&message->header,
00807 DBUS_MESSAGE_TYPE_METHOD_CALL,
00808 destination, path, interface, method, NULL))
00809 {
00810 dbus_message_unref (message);
00811 return NULL;
00812 }
00813
00814 return message;
00815 }
00816
00826 DBusMessage*
00827 dbus_message_new_method_return (DBusMessage *method_call)
00828 {
00829 DBusMessage *message;
00830 const char *sender;
00831
00832 _dbus_return_val_if_fail (method_call != NULL, NULL);
00833
00834 sender = dbus_message_get_sender (method_call);
00835
00836
00837
00838 message = dbus_message_new_empty_header ();
00839 if (message == NULL)
00840 return NULL;
00841
00842 if (!_dbus_header_create (&message->header,
00843 DBUS_MESSAGE_TYPE_METHOD_RETURN,
00844 sender, NULL, NULL, NULL, NULL))
00845 {
00846 dbus_message_unref (message);
00847 return NULL;
00848 }
00849
00850 dbus_message_set_no_reply (message, TRUE);
00851
00852 if (!dbus_message_set_reply_serial (message,
00853 dbus_message_get_serial (method_call)))
00854 {
00855 dbus_message_unref (message);
00856 return NULL;
00857 }
00858
00859 return message;
00860 }
00861
00874 DBusMessage*
00875 dbus_message_new_signal (const char *path,
00876 const char *interface,
00877 const char *name)
00878 {
00879 DBusMessage *message;
00880
00881 _dbus_return_val_if_fail (path != NULL, NULL);
00882 _dbus_return_val_if_fail (interface != NULL, NULL);
00883 _dbus_return_val_if_fail (name != NULL, NULL);
00884 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
00885 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
00886 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
00887
00888 message = dbus_message_new_empty_header ();
00889 if (message == NULL)
00890 return NULL;
00891
00892 if (!_dbus_header_create (&message->header,
00893 DBUS_MESSAGE_TYPE_SIGNAL,
00894 NULL, path, interface, name, NULL))
00895 {
00896 dbus_message_unref (message);
00897 return NULL;
00898 }
00899
00900 dbus_message_set_no_reply (message, TRUE);
00901
00902 return message;
00903 }
00904
00914 DBusMessage*
00915 dbus_message_new_error (DBusMessage *reply_to,
00916 const char *error_name,
00917 const char *error_message)
00918 {
00919 DBusMessage *message;
00920 const char *sender;
00921 DBusMessageIter iter;
00922
00923 _dbus_return_val_if_fail (reply_to != NULL, NULL);
00924 _dbus_return_val_if_fail (error_name != NULL, NULL);
00925 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
00926
00927 sender = dbus_message_get_sender (reply_to);
00928
00929
00930
00931
00932
00933 message = dbus_message_new_empty_header ();
00934 if (message == NULL)
00935 return NULL;
00936
00937 if (!_dbus_header_create (&message->header,
00938 DBUS_MESSAGE_TYPE_ERROR,
00939 sender, NULL, NULL, NULL, error_name))
00940 {
00941 dbus_message_unref (message);
00942 return NULL;
00943 }
00944
00945 dbus_message_set_no_reply (message, TRUE);
00946
00947 if (!dbus_message_set_reply_serial (message,
00948 dbus_message_get_serial (reply_to)))
00949 {
00950 dbus_message_unref (message);
00951 return NULL;
00952 }
00953
00954 if (error_message != NULL)
00955 {
00956 dbus_message_iter_init_append (message, &iter);
00957 if (!dbus_message_iter_append_basic (&iter,
00958 DBUS_TYPE_STRING,
00959 &error_message))
00960 {
00961 dbus_message_unref (message);
00962 return NULL;
00963 }
00964 }
00965
00966 return message;
00967 }
00968
00979 DBusMessage*
00980 dbus_message_new_error_printf (DBusMessage *reply_to,
00981 const char *error_name,
00982 const char *error_format,
00983 ...)
00984 {
00985 va_list args;
00986 DBusString str;
00987 DBusMessage *message;
00988
00989 _dbus_return_val_if_fail (reply_to != NULL, NULL);
00990 _dbus_return_val_if_fail (error_name != NULL, NULL);
00991 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
00992
00993 if (!_dbus_string_init (&str))
00994 return NULL;
00995
00996 va_start (args, error_format);
00997
00998 if (_dbus_string_append_printf_valist (&str, error_format, args))
00999 message = dbus_message_new_error (reply_to, error_name,
01000 _dbus_string_get_const_data (&str));
01001 else
01002 message = NULL;
01003
01004 _dbus_string_free (&str);
01005
01006 va_end (args);
01007
01008 return message;
01009 }
01010
01011
01022 DBusMessage *
01023 dbus_message_copy (const DBusMessage *message)
01024 {
01025 DBusMessage *retval;
01026
01027 _dbus_return_val_if_fail (message != NULL, NULL);
01028
01029 retval = dbus_new0 (DBusMessage, 1);
01030 if (retval == NULL)
01031 return NULL;
01032
01033 retval->refcount.value = 1;
01034 retval->byte_order = message->byte_order;
01035 retval->locked = FALSE;
01036 #ifndef DBUS_DISABLE_CHECKS
01037 retval->generation = message->generation;
01038 #endif
01039
01040 if (!_dbus_header_copy (&message->header, &retval->header))
01041 {
01042 dbus_free (retval);
01043 return NULL;
01044 }
01045
01046 if (!_dbus_string_init_preallocated (&retval->body,
01047 _dbus_string_get_length (&message->body)))
01048 {
01049 _dbus_header_free (&retval->header);
01050 dbus_free (retval);
01051 return NULL;
01052 }
01053
01054 if (!_dbus_string_copy (&message->body, 0,
01055 &retval->body, 0))
01056 goto failed_copy;
01057
01058 return retval;
01059
01060 failed_copy:
01061 _dbus_header_free (&retval->header);
01062 _dbus_string_free (&retval->body);
01063 dbus_free (retval);
01064
01065 return NULL;
01066 }
01067
01068
01076 DBusMessage *
01077 dbus_message_ref (DBusMessage *message)
01078 {
01079 dbus_int32_t old_refcount;
01080
01081 _dbus_return_val_if_fail (message != NULL, NULL);
01082 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01083 _dbus_return_val_if_fail (!message->in_cache, NULL);
01084
01085 old_refcount = _dbus_atomic_inc (&message->refcount);
01086 _dbus_assert (old_refcount >= 1);
01087
01088 return message;
01089 }
01090
01097 void
01098 dbus_message_unref (DBusMessage *message)
01099 {
01100 dbus_int32_t old_refcount;
01101
01102 _dbus_return_if_fail (message != NULL);
01103 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01104 _dbus_return_if_fail (!message->in_cache);
01105
01106 old_refcount = _dbus_atomic_dec (&message->refcount);
01107
01108 _dbus_assert (old_refcount >= 0);
01109
01110 if (old_refcount == 1)
01111 {
01112
01113 dbus_message_cache_or_finalize (message);
01114 }
01115 }
01116
01129 int
01130 dbus_message_get_type (DBusMessage *message)
01131 {
01132 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01133
01134 return _dbus_header_get_message_type (&message->header);
01135 }
01136
01189 dbus_bool_t
01190 dbus_message_append_args (DBusMessage *message,
01191 int first_arg_type,
01192 ...)
01193 {
01194 dbus_bool_t retval;
01195 va_list var_args;
01196
01197 _dbus_return_val_if_fail (message != NULL, FALSE);
01198
01199 va_start (var_args, first_arg_type);
01200 retval = dbus_message_append_args_valist (message,
01201 first_arg_type,
01202 var_args);
01203 va_end (var_args);
01204
01205 return retval;
01206 }
01207
01222 dbus_bool_t
01223 dbus_message_append_args_valist (DBusMessage *message,
01224 int first_arg_type,
01225 va_list var_args)
01226 {
01227 int type;
01228 DBusMessageIter iter;
01229
01230 _dbus_return_val_if_fail (message != NULL, FALSE);
01231
01232 type = first_arg_type;
01233
01234 dbus_message_iter_init_append (message, &iter);
01235
01236 while (type != DBUS_TYPE_INVALID)
01237 {
01238 if (dbus_type_is_basic (type))
01239 {
01240 const DBusBasicValue *value;
01241 value = va_arg (var_args, const DBusBasicValue*);
01242
01243 if (!dbus_message_iter_append_basic (&iter,
01244 type,
01245 value))
01246 goto failed;
01247 }
01248 else if (type == DBUS_TYPE_ARRAY)
01249 {
01250 int element_type;
01251 DBusMessageIter array;
01252 char buf[2];
01253
01254 element_type = va_arg (var_args, int);
01255
01256 buf[0] = element_type;
01257 buf[1] = '\0';
01258 if (!dbus_message_iter_open_container (&iter,
01259 DBUS_TYPE_ARRAY,
01260 buf,
01261 &array))
01262 goto failed;
01263
01264 if (dbus_type_is_fixed (element_type))
01265 {
01266 const DBusBasicValue **value;
01267 int n_elements;
01268
01269 value = va_arg (var_args, const DBusBasicValue**);
01270 n_elements = va_arg (var_args, int);
01271
01272 if (!dbus_message_iter_append_fixed_array (&array,
01273 element_type,
01274 value,
01275 n_elements))
01276 goto failed;
01277 }
01278 else if (element_type == DBUS_TYPE_STRING ||
01279 element_type == DBUS_TYPE_SIGNATURE ||
01280 element_type == DBUS_TYPE_OBJECT_PATH)
01281 {
01282 const char ***value_p;
01283 const char **value;
01284 int n_elements;
01285 int i;
01286
01287 value_p = va_arg (var_args, const char***);
01288 n_elements = va_arg (var_args, int);
01289
01290 value = *value_p;
01291
01292 i = 0;
01293 while (i < n_elements)
01294 {
01295 if (!dbus_message_iter_append_basic (&array,
01296 element_type,
01297 &value[i]))
01298 goto failed;
01299 ++i;
01300 }
01301 }
01302 else
01303 {
01304 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01305 _dbus_type_to_string (element_type),
01306 _DBUS_FUNCTION_NAME);
01307 goto failed;
01308 }
01309
01310 if (!dbus_message_iter_close_container (&iter, &array))
01311 goto failed;
01312 }
01313 #ifndef DBUS_DISABLE_CHECKS
01314 else
01315 {
01316 _dbus_warn ("type %s isn't supported yet in %s\n",
01317 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01318 goto failed;
01319 }
01320 #endif
01321
01322 type = va_arg (var_args, int);
01323 }
01324
01325 return TRUE;
01326
01327 failed:
01328 return FALSE;
01329 }
01330
01363 dbus_bool_t
01364 dbus_message_get_args (DBusMessage *message,
01365 DBusError *error,
01366 int first_arg_type,
01367 ...)
01368 {
01369 dbus_bool_t retval;
01370 va_list var_args;
01371
01372 _dbus_return_val_if_fail (message != NULL, FALSE);
01373 _dbus_return_val_if_error_is_set (error, FALSE);
01374
01375 va_start (var_args, first_arg_type);
01376 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01377 va_end (var_args);
01378
01379 return retval;
01380 }
01381
01393 dbus_bool_t
01394 dbus_message_get_args_valist (DBusMessage *message,
01395 DBusError *error,
01396 int first_arg_type,
01397 va_list var_args)
01398 {
01399 DBusMessageIter iter;
01400
01401 _dbus_return_val_if_fail (message != NULL, FALSE);
01402 _dbus_return_val_if_error_is_set (error, FALSE);
01403
01404 dbus_message_iter_init (message, &iter);
01405 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01406 }
01407
01408 static void
01409 _dbus_message_iter_init_common (DBusMessage *message,
01410 DBusMessageRealIter *real,
01411 int iter_type)
01412 {
01413 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01414
01415
01416
01417
01418 ensure_byte_order (message);
01419
01420 real->message = message;
01421 real->changed_stamp = message->changed_stamp;
01422 real->iter_type = iter_type;
01423 real->sig_refcount = 0;
01424 }
01425
01434 dbus_bool_t
01435 dbus_message_iter_init (DBusMessage *message,
01436 DBusMessageIter *iter)
01437 {
01438 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01439 const DBusString *type_str;
01440 int type_pos;
01441
01442 _dbus_return_val_if_fail (message != NULL, FALSE);
01443 _dbus_return_val_if_fail (iter != NULL, FALSE);
01444
01445 get_const_signature (&message->header, &type_str, &type_pos);
01446
01447 _dbus_message_iter_init_common (message, real,
01448 DBUS_MESSAGE_ITER_TYPE_READER);
01449
01450 _dbus_type_reader_init (&real->u.reader,
01451 message->byte_order,
01452 type_str, type_pos,
01453 &message->body,
01454 0);
01455
01456 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01457 }
01458
01459 #ifndef DBUS_DISABLE_CHECKS
01460 static dbus_bool_t
01461 _dbus_message_iter_check (DBusMessageRealIter *iter)
01462 {
01463 if (iter == NULL)
01464 {
01465 _dbus_warn ("dbus message iterator is NULL\n");
01466 return FALSE;
01467 }
01468
01469 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
01470 {
01471 if (iter->u.reader.byte_order != iter->message->byte_order)
01472 {
01473 _dbus_warn ("dbus message changed byte order since iterator was created\n");
01474 return FALSE;
01475 }
01476
01477 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
01478 }
01479 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
01480 {
01481 if (iter->u.writer.byte_order != iter->message->byte_order)
01482 {
01483 _dbus_warn ("dbus message changed byte order since append iterator was created\n");
01484 return FALSE;
01485 }
01486
01487 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
01488 }
01489 else
01490 {
01491 _dbus_warn ("dbus message iterator looks uninitialized or corrupted\n");
01492 return FALSE;
01493 }
01494
01495 if (iter->changed_stamp != iter->message->changed_stamp)
01496 {
01497 _dbus_warn ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
01498 return FALSE;
01499 }
01500
01501 return TRUE;
01502 }
01503 #endif
01504
01512 dbus_bool_t
01513 dbus_message_iter_has_next (DBusMessageIter *iter)
01514 {
01515 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01516
01517 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01518 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01519
01520 return _dbus_type_reader_has_next (&real->u.reader);
01521 }
01522
01531 dbus_bool_t
01532 dbus_message_iter_next (DBusMessageIter *iter)
01533 {
01534 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01535
01536 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01537 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01538
01539 return _dbus_type_reader_next (&real->u.reader);
01540 }
01541
01556 int
01557 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01558 {
01559 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01560
01561 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01562 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01563
01564 return _dbus_type_reader_get_current_type (&real->u.reader);
01565 }
01566
01575 int
01576 dbus_message_iter_get_element_type (DBusMessageIter *iter)
01577 {
01578 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01579
01580 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01581 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
01582 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
01583
01584 return _dbus_type_reader_get_element_type (&real->u.reader);
01585 }
01586
01602 void
01603 dbus_message_iter_recurse (DBusMessageIter *iter,
01604 DBusMessageIter *sub)
01605 {
01606 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01607 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01608
01609 _dbus_return_if_fail (_dbus_message_iter_check (real));
01610 _dbus_return_if_fail (sub != NULL);
01611
01612 *real_sub = *real;
01613 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01614 }
01615
01625 char *
01626 dbus_message_iter_get_signature (DBusMessageIter *iter)
01627 {
01628 const DBusString *sig;
01629 DBusString retstr;
01630 char *ret;
01631 int start, len;
01632 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01633
01634 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01635
01636 if (!_dbus_string_init (&retstr))
01637 return NULL;
01638
01639 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01640 &start, &len);
01641 if (!_dbus_string_append_len (&retstr,
01642 _dbus_string_get_const_data (sig) + start,
01643 len))
01644 return NULL;
01645 if (!_dbus_string_steal_data (&retstr, &ret))
01646 return NULL;
01647 _dbus_string_free (&retstr);
01648 return ret;
01649 }
01650
01686 void
01687 dbus_message_iter_get_basic (DBusMessageIter *iter,
01688 void *value)
01689 {
01690 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01691
01692 _dbus_return_if_fail (_dbus_message_iter_check (real));
01693 _dbus_return_if_fail (value != NULL);
01694
01695 _dbus_type_reader_read_basic (&real->u.reader,
01696 value);
01697 }
01698
01705 int
01706 dbus_message_iter_get_array_len (DBusMessageIter *iter)
01707 {
01708 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01709
01710 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
01711
01712 return _dbus_type_reader_get_array_length (&real->u.reader);
01713 }
01714
01732 void
01733 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
01734 void *value,
01735 int *n_elements)
01736 {
01737 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01738
01739 _dbus_return_if_fail (_dbus_message_iter_check (real));
01740 _dbus_return_if_fail (value != NULL);
01741 _dbus_return_if_fail (dbus_type_is_fixed (_dbus_type_reader_get_current_type (&real->u.reader)));
01742
01743 _dbus_type_reader_read_fixed_multi (&real->u.reader,
01744 value, n_elements);
01745 }
01746
01760 dbus_bool_t
01761 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
01762 DBusError *error,
01763 int first_arg_type,
01764 va_list var_args)
01765 {
01766 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01767 int spec_type, msg_type, i;
01768 dbus_bool_t retval;
01769
01770 _dbus_assert (_dbus_message_iter_check (real));
01771
01772 retval = FALSE;
01773
01774 spec_type = first_arg_type;
01775 i = 0;
01776
01777 while (spec_type != DBUS_TYPE_INVALID)
01778 {
01779 msg_type = dbus_message_iter_get_arg_type (iter);
01780
01781 if (msg_type != spec_type)
01782 {
01783 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01784 "Argument %d is specified to be of type \"%s\", but "
01785 "is actually of type \"%s\"\n", i,
01786 _dbus_type_to_string (spec_type),
01787 _dbus_type_to_string (msg_type));
01788
01789 goto out;
01790 }
01791
01792 if (dbus_type_is_basic (spec_type))
01793 {
01794 DBusBasicValue *ptr;
01795
01796 ptr = va_arg (var_args, DBusBasicValue*);
01797
01798 _dbus_assert (ptr != NULL);
01799
01800 _dbus_type_reader_read_basic (&real->u.reader,
01801 ptr);
01802 }
01803 else if (spec_type == DBUS_TYPE_ARRAY)
01804 {
01805 int element_type;
01806 int spec_element_type;
01807 const DBusBasicValue **ptr;
01808 int *n_elements_p;
01809 DBusTypeReader array;
01810
01811 spec_element_type = va_arg (var_args, int);
01812 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
01813
01814 if (spec_element_type != element_type)
01815 {
01816 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01817 "Argument %d is specified to be an array of \"%s\", but "
01818 "is actually an array of \"%s\"\n",
01819 i,
01820 _dbus_type_to_string (spec_element_type),
01821 _dbus_type_to_string (element_type));
01822
01823 goto out;
01824 }
01825
01826 if (dbus_type_is_fixed (spec_element_type))
01827 {
01828 ptr = va_arg (var_args, const DBusBasicValue**);
01829 n_elements_p = va_arg (var_args, int*);
01830
01831 _dbus_assert (ptr != NULL);
01832 _dbus_assert (n_elements_p != NULL);
01833
01834 _dbus_type_reader_recurse (&real->u.reader, &array);
01835
01836 _dbus_type_reader_read_fixed_multi (&array,
01837 ptr, n_elements_p);
01838 }
01839 else if (spec_element_type == DBUS_TYPE_STRING ||
01840 spec_element_type == DBUS_TYPE_SIGNATURE ||
01841 spec_element_type == DBUS_TYPE_OBJECT_PATH)
01842 {
01843 char ***str_array_p;
01844 int n_elements;
01845 char **str_array;
01846
01847 str_array_p = va_arg (var_args, char***);
01848 n_elements_p = va_arg (var_args, int*);
01849
01850 _dbus_assert (str_array_p != NULL);
01851 _dbus_assert (n_elements_p != NULL);
01852
01853
01854 _dbus_type_reader_recurse (&real->u.reader, &array);
01855
01856 n_elements = 0;
01857 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
01858 {
01859 ++n_elements;
01860 _dbus_type_reader_next (&array);
01861 }
01862
01863 str_array = dbus_new0 (char*, n_elements + 1);
01864 if (str_array == NULL)
01865 {
01866 _DBUS_SET_OOM (error);
01867 goto out;
01868 }
01869
01870
01871 _dbus_type_reader_recurse (&real->u.reader, &array);
01872
01873 i = 0;
01874 while (i < n_elements)
01875 {
01876 const char *s;
01877 _dbus_type_reader_read_basic (&array,
01878 &s);
01879
01880 str_array[i] = _dbus_strdup (s);
01881 if (str_array[i] == NULL)
01882 {
01883 dbus_free_string_array (str_array);
01884 _DBUS_SET_OOM (error);
01885 goto out;
01886 }
01887
01888 ++i;
01889
01890 if (!_dbus_type_reader_next (&array))
01891 _dbus_assert (i == n_elements);
01892 }
01893
01894 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
01895 _dbus_assert (i == n_elements);
01896 _dbus_assert (str_array[i] == NULL);
01897
01898 *str_array_p = str_array;
01899 *n_elements_p = n_elements;
01900 }
01901 #ifndef DBUS_DISABLE_CHECKS
01902 else
01903 {
01904 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
01905 _DBUS_FUNCTION_NAME);
01906 goto out;
01907 }
01908 #endif
01909 }
01910 #ifndef DBUS_DISABLE_CHECKS
01911 else
01912 {
01913 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
01914 _DBUS_FUNCTION_NAME);
01915 goto out;
01916 }
01917 #endif
01918
01919 spec_type = va_arg (var_args, int);
01920 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
01921 {
01922 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01923 "Message has only %d arguments, but more were expected", i);
01924 goto out;
01925 }
01926
01927 i++;
01928 }
01929
01930 retval = TRUE;
01931
01932 out:
01933
01934 return retval;
01935 }
01936
01948 void
01949 dbus_message_iter_init_append (DBusMessage *message,
01950 DBusMessageIter *iter)
01951 {
01952 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01953
01954 _dbus_return_if_fail (message != NULL);
01955 _dbus_return_if_fail (iter != NULL);
01956
01957 _dbus_message_iter_init_common (message, real,
01958 DBUS_MESSAGE_ITER_TYPE_WRITER);
01959
01960
01961
01962
01963
01964 _dbus_type_writer_init_types_delayed (&real->u.writer,
01965 message->byte_order,
01966 &message->body,
01967 _dbus_string_get_length (&message->body));
01968 }
01969
01978 static dbus_bool_t
01979 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
01980 {
01981 DBusString *str;
01982 const DBusString *current_sig;
01983 int current_sig_pos;
01984
01985 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
01986
01987 if (real->u.writer.type_str != NULL)
01988 {
01989 _dbus_assert (real->sig_refcount > 0);
01990 real->sig_refcount += 1;
01991 return TRUE;
01992 }
01993
01994 str = dbus_new (DBusString, 1);
01995 if (str == NULL)
01996 return FALSE;
01997
01998 if (!_dbus_header_get_field_raw (&real->message->header,
01999 DBUS_HEADER_FIELD_SIGNATURE,
02000 ¤t_sig, ¤t_sig_pos))
02001 current_sig = NULL;
02002
02003 if (current_sig)
02004 {
02005 int current_len;
02006
02007 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02008 current_sig_pos += 1;
02009
02010 if (!_dbus_string_init_preallocated (str, current_len + 4))
02011 {
02012 dbus_free (str);
02013 return FALSE;
02014 }
02015
02016 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02017 str, 0))
02018 {
02019 _dbus_string_free (str);
02020 dbus_free (str);
02021 return FALSE;
02022 }
02023 }
02024 else
02025 {
02026 if (!_dbus_string_init_preallocated (str, 4))
02027 {
02028 dbus_free (str);
02029 return FALSE;
02030 }
02031 }
02032
02033 real->sig_refcount = 1;
02034
02035 _dbus_type_writer_add_types (&real->u.writer,
02036 str, _dbus_string_get_length (str));
02037 return TRUE;
02038 }
02039
02049 static dbus_bool_t
02050 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02051 {
02052 DBusString *str;
02053 const char *v_STRING;
02054 dbus_bool_t retval;
02055
02056 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02057 _dbus_assert (real->u.writer.type_str != NULL);
02058 _dbus_assert (real->sig_refcount > 0);
02059
02060 real->sig_refcount -= 1;
02061
02062 if (real->sig_refcount > 0)
02063 return TRUE;
02064 _dbus_assert (real->sig_refcount == 0);
02065
02066 retval = TRUE;
02067
02068 str = real->u.writer.type_str;
02069
02070 v_STRING = _dbus_string_get_const_data (str);
02071 if (!_dbus_header_set_field_basic (&real->message->header,
02072 DBUS_HEADER_FIELD_SIGNATURE,
02073 DBUS_TYPE_SIGNATURE,
02074 &v_STRING))
02075 retval = FALSE;
02076
02077 _dbus_type_writer_remove_types (&real->u.writer);
02078 _dbus_string_free (str);
02079 dbus_free (str);
02080
02081 return retval;
02082 }
02083
02084 #ifndef DBUS_DISABLE_CHECKS
02085 static dbus_bool_t
02086 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02087 {
02088 if (!_dbus_message_iter_check (iter))
02089 return FALSE;
02090
02091 if (iter->message->locked)
02092 {
02093 _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02094 return FALSE;
02095 }
02096
02097 return TRUE;
02098 }
02099 #endif
02100
02116 dbus_bool_t
02117 dbus_message_iter_append_basic (DBusMessageIter *iter,
02118 int type,
02119 const void *value)
02120 {
02121 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02122 dbus_bool_t ret;
02123
02124 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02125 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02126 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02127 _dbus_return_val_if_fail (value != NULL, FALSE);
02128
02129 if (!_dbus_message_iter_open_signature (real))
02130 return FALSE;
02131
02132 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02133
02134 if (!_dbus_message_iter_close_signature (real))
02135 ret = FALSE;
02136
02137 return ret;
02138 }
02139
02175 dbus_bool_t
02176 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02177 int element_type,
02178 const void *value,
02179 int n_elements)
02180 {
02181 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02182 dbus_bool_t ret;
02183
02184 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02185 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02186 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02187 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02188 _dbus_return_val_if_fail (value != NULL, FALSE);
02189 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02190 _dbus_return_val_if_fail (n_elements <=
02191 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02192 FALSE);
02193
02194 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02195
02196 return ret;
02197 }
02198
02220 dbus_bool_t
02221 dbus_message_iter_open_container (DBusMessageIter *iter,
02222 int type,
02223 const char *contained_signature,
02224 DBusMessageIter *sub)
02225 {
02226 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02227 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02228 DBusString contained_str;
02229
02230 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02231 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02232 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02233 _dbus_return_val_if_fail (sub != NULL, FALSE);
02234 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02235 contained_signature == NULL) ||
02236 (type == DBUS_TYPE_DICT_ENTRY &&
02237 contained_signature == NULL) ||
02238 contained_signature != NULL, FALSE);
02239
02240 #if 0
02241
02242
02243
02244
02245 _dbus_return_val_if_fail (contained_signature == NULL ||
02246 _dbus_check_is_valid_signature (contained_signature));
02247 #endif
02248
02249 if (!_dbus_message_iter_open_signature (real))
02250 return FALSE;
02251
02252 *real_sub = *real;
02253
02254 if (contained_signature != NULL)
02255 {
02256 _dbus_string_init_const (&contained_str, contained_signature);
02257
02258 return _dbus_type_writer_recurse (&real->u.writer,
02259 type,
02260 &contained_str, 0,
02261 &real_sub->u.writer);
02262 }
02263 else
02264 {
02265 return _dbus_type_writer_recurse (&real->u.writer,
02266 type,
02267 NULL, 0,
02268 &real_sub->u.writer);
02269 }
02270 }
02271
02272
02286 dbus_bool_t
02287 dbus_message_iter_close_container (DBusMessageIter *iter,
02288 DBusMessageIter *sub)
02289 {
02290 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02291 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02292 dbus_bool_t ret;
02293
02294 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02295 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02296 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02297 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02298
02299 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02300 &real_sub->u.writer);
02301
02302 if (!_dbus_message_iter_close_signature (real))
02303 ret = FALSE;
02304
02305 return ret;
02306 }
02307
02319 void
02320 dbus_message_set_no_reply (DBusMessage *message,
02321 dbus_bool_t no_reply)
02322 {
02323 _dbus_return_if_fail (message != NULL);
02324 _dbus_return_if_fail (!message->locked);
02325
02326 _dbus_header_toggle_flag (&message->header,
02327 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02328 no_reply);
02329 }
02330
02338 dbus_bool_t
02339 dbus_message_get_no_reply (DBusMessage *message)
02340 {
02341 _dbus_return_val_if_fail (message != NULL, FALSE);
02342
02343 return _dbus_header_get_flag (&message->header,
02344 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02345 }
02346
02357 void
02358 dbus_message_set_auto_start (DBusMessage *message,
02359 dbus_bool_t auto_start)
02360 {
02361 _dbus_return_if_fail (message != NULL);
02362 _dbus_return_if_fail (!message->locked);
02363
02364 _dbus_header_toggle_flag (&message->header,
02365 DBUS_HEADER_FLAG_NO_AUTO_START,
02366 !auto_start);
02367 }
02368
02376 dbus_bool_t
02377 dbus_message_get_auto_start (DBusMessage *message)
02378 {
02379 _dbus_return_val_if_fail (message != NULL, FALSE);
02380
02381 return !_dbus_header_get_flag (&message->header,
02382 DBUS_HEADER_FLAG_NO_AUTO_START);
02383 }
02384
02385
02395 dbus_bool_t
02396 dbus_message_set_path (DBusMessage *message,
02397 const char *object_path)
02398 {
02399 _dbus_return_val_if_fail (message != NULL, FALSE);
02400 _dbus_return_val_if_fail (!message->locked, FALSE);
02401 _dbus_return_val_if_fail (object_path == NULL ||
02402 _dbus_check_is_valid_path (object_path),
02403 FALSE);
02404
02405 return set_or_delete_string_field (message,
02406 DBUS_HEADER_FIELD_PATH,
02407 DBUS_TYPE_OBJECT_PATH,
02408 object_path);
02409 }
02410
02419 const char*
02420 dbus_message_get_path (DBusMessage *message)
02421 {
02422 const char *v;
02423
02424 _dbus_return_val_if_fail (message != NULL, NULL);
02425
02426 v = NULL;
02427 _dbus_header_get_field_basic (&message->header,
02428 DBUS_HEADER_FIELD_PATH,
02429 DBUS_TYPE_OBJECT_PATH,
02430 &v);
02431 return v;
02432 }
02433
02441 dbus_bool_t
02442 dbus_message_has_path (DBusMessage *message,
02443 const char *path)
02444 {
02445 const char *msg_path;
02446 msg_path = dbus_message_get_path (message);
02447
02448 if (msg_path == NULL)
02449 {
02450 if (path == NULL)
02451 return TRUE;
02452 else
02453 return FALSE;
02454 }
02455
02456 if (path == NULL)
02457 return FALSE;
02458
02459 if (strcmp (msg_path, path) == 0)
02460 return TRUE;
02461
02462 return FALSE;
02463 }
02464
02483 dbus_bool_t
02484 dbus_message_get_path_decomposed (DBusMessage *message,
02485 char ***path)
02486 {
02487 const char *v;
02488
02489 _dbus_return_val_if_fail (message != NULL, FALSE);
02490 _dbus_return_val_if_fail (path != NULL, FALSE);
02491
02492 *path = NULL;
02493
02494 v = dbus_message_get_path (message);
02495 if (v != NULL)
02496 {
02497 if (!_dbus_decompose_path (v, strlen (v),
02498 path, NULL))
02499 return FALSE;
02500 }
02501 return TRUE;
02502 }
02503
02514 dbus_bool_t
02515 dbus_message_set_interface (DBusMessage *message,
02516 const char *interface)
02517 {
02518 _dbus_return_val_if_fail (message != NULL, FALSE);
02519 _dbus_return_val_if_fail (!message->locked, FALSE);
02520 _dbus_return_val_if_fail (interface == NULL ||
02521 _dbus_check_is_valid_interface (interface),
02522 FALSE);
02523
02524 return set_or_delete_string_field (message,
02525 DBUS_HEADER_FIELD_INTERFACE,
02526 DBUS_TYPE_STRING,
02527 interface);
02528 }
02529
02540 const char*
02541 dbus_message_get_interface (DBusMessage *message)
02542 {
02543 const char *v;
02544
02545 _dbus_return_val_if_fail (message != NULL, NULL);
02546
02547 v = NULL;
02548 _dbus_header_get_field_basic (&message->header,
02549 DBUS_HEADER_FIELD_INTERFACE,
02550 DBUS_TYPE_STRING,
02551 &v);
02552 return v;
02553 }
02554
02562 dbus_bool_t
02563 dbus_message_has_interface (DBusMessage *message,
02564 const char *interface)
02565 {
02566 const char *msg_interface;
02567 msg_interface = dbus_message_get_interface (message);
02568
02569 if (msg_interface == NULL)
02570 {
02571 if (interface == NULL)
02572 return TRUE;
02573 else
02574 return FALSE;
02575 }
02576
02577 if (interface == NULL)
02578 return FALSE;
02579
02580 if (strcmp (msg_interface, interface) == 0)
02581 return TRUE;
02582
02583 return FALSE;
02584
02585 }
02586
02597 dbus_bool_t
02598 dbus_message_set_member (DBusMessage *message,
02599 const char *member)
02600 {
02601 _dbus_return_val_if_fail (message != NULL, FALSE);
02602 _dbus_return_val_if_fail (!message->locked, FALSE);
02603 _dbus_return_val_if_fail (member == NULL ||
02604 _dbus_check_is_valid_member (member),
02605 FALSE);
02606
02607 return set_or_delete_string_field (message,
02608 DBUS_HEADER_FIELD_MEMBER,
02609 DBUS_TYPE_STRING,
02610 member);
02611 }
02612
02621 const char*
02622 dbus_message_get_member (DBusMessage *message)
02623 {
02624 const char *v;
02625
02626 _dbus_return_val_if_fail (message != NULL, NULL);
02627
02628 v = NULL;
02629 _dbus_header_get_field_basic (&message->header,
02630 DBUS_HEADER_FIELD_MEMBER,
02631 DBUS_TYPE_STRING,
02632 &v);
02633 return v;
02634 }
02635
02643 dbus_bool_t
02644 dbus_message_has_member (DBusMessage *message,
02645 const char *member)
02646 {
02647 const char *msg_member;
02648 msg_member = dbus_message_get_member (message);
02649
02650 if (msg_member == NULL)
02651 {
02652 if (member == NULL)
02653 return TRUE;
02654 else
02655 return FALSE;
02656 }
02657
02658 if (member == NULL)
02659 return FALSE;
02660
02661 if (strcmp (msg_member, member) == 0)
02662 return TRUE;
02663
02664 return FALSE;
02665
02666 }
02667
02676 dbus_bool_t
02677 dbus_message_set_error_name (DBusMessage *message,
02678 const char *error_name)
02679 {
02680 _dbus_return_val_if_fail (message != NULL, FALSE);
02681 _dbus_return_val_if_fail (!message->locked, FALSE);
02682 _dbus_return_val_if_fail (error_name == NULL ||
02683 _dbus_check_is_valid_error_name (error_name),
02684 FALSE);
02685
02686 return set_or_delete_string_field (message,
02687 DBUS_HEADER_FIELD_ERROR_NAME,
02688 DBUS_TYPE_STRING,
02689 error_name);
02690 }
02691
02699 const char*
02700 dbus_message_get_error_name (DBusMessage *message)
02701 {
02702 const char *v;
02703
02704 _dbus_return_val_if_fail (message != NULL, NULL);
02705
02706 v = NULL;
02707 _dbus_header_get_field_basic (&message->header,
02708 DBUS_HEADER_FIELD_ERROR_NAME,
02709 DBUS_TYPE_STRING,
02710 &v);
02711 return v;
02712 }
02713
02724 dbus_bool_t
02725 dbus_message_set_destination (DBusMessage *message,
02726 const char *destination)
02727 {
02728 _dbus_return_val_if_fail (message != NULL, FALSE);
02729 _dbus_return_val_if_fail (!message->locked, FALSE);
02730 _dbus_return_val_if_fail (destination == NULL ||
02731 _dbus_check_is_valid_bus_name (destination),
02732 FALSE);
02733
02734 return set_or_delete_string_field (message,
02735 DBUS_HEADER_FIELD_DESTINATION,
02736 DBUS_TYPE_STRING,
02737 destination);
02738 }
02739
02746 const char*
02747 dbus_message_get_destination (DBusMessage *message)
02748 {
02749 const char *v;
02750
02751 _dbus_return_val_if_fail (message != NULL, NULL);
02752
02753 v = NULL;
02754 _dbus_header_get_field_basic (&message->header,
02755 DBUS_HEADER_FIELD_DESTINATION,
02756 DBUS_TYPE_STRING,
02757 &v);
02758 return v;
02759 }
02760
02768 dbus_bool_t
02769 dbus_message_set_sender (DBusMessage *message,
02770 const char *sender)
02771 {
02772 _dbus_return_val_if_fail (message != NULL, FALSE);
02773 _dbus_return_val_if_fail (!message->locked, FALSE);
02774 _dbus_return_val_if_fail (sender == NULL ||
02775 _dbus_check_is_valid_bus_name (sender),
02776 FALSE);
02777
02778 return set_or_delete_string_field (message,
02779 DBUS_HEADER_FIELD_SENDER,
02780 DBUS_TYPE_STRING,
02781 sender);
02782 }
02783
02792 const char*
02793 dbus_message_get_sender (DBusMessage *message)
02794 {
02795 const char *v;
02796
02797 _dbus_return_val_if_fail (message != NULL, NULL);
02798
02799 v = NULL;
02800 _dbus_header_get_field_basic (&message->header,
02801 DBUS_HEADER_FIELD_SENDER,
02802 DBUS_TYPE_STRING,
02803 &v);
02804 return v;
02805 }
02806
02822 const char*
02823 dbus_message_get_signature (DBusMessage *message)
02824 {
02825 const DBusString *type_str;
02826 int type_pos;
02827
02828 _dbus_return_val_if_fail (message != NULL, NULL);
02829
02830 get_const_signature (&message->header, &type_str, &type_pos);
02831
02832 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
02833 }
02834
02835 static dbus_bool_t
02836 _dbus_message_has_type_interface_member (DBusMessage *message,
02837 int type,
02838 const char *interface,
02839 const char *member)
02840 {
02841 const char *n;
02842
02843 _dbus_assert (message != NULL);
02844 _dbus_assert (interface != NULL);
02845 _dbus_assert (member != NULL);
02846
02847 if (dbus_message_get_type (message) != type)
02848 return FALSE;
02849
02850
02851
02852
02853
02854 n = dbus_message_get_member (message);
02855
02856 if (n && strcmp (n, member) == 0)
02857 {
02858 n = dbus_message_get_interface (message);
02859
02860 if (n == NULL || strcmp (n, interface) == 0)
02861 return TRUE;
02862 }
02863
02864 return FALSE;
02865 }
02866
02881 dbus_bool_t
02882 dbus_message_is_method_call (DBusMessage *message,
02883 const char *interface,
02884 const char *method)
02885 {
02886 _dbus_return_val_if_fail (message != NULL, FALSE);
02887 _dbus_return_val_if_fail (interface != NULL, FALSE);
02888 _dbus_return_val_if_fail (method != NULL, FALSE);
02889
02890
02891
02892
02893 return _dbus_message_has_type_interface_member (message,
02894 DBUS_MESSAGE_TYPE_METHOD_CALL,
02895 interface, method);
02896 }
02897
02911 dbus_bool_t
02912 dbus_message_is_signal (DBusMessage *message,
02913 const char *interface,
02914 const char *signal_name)
02915 {
02916 _dbus_return_val_if_fail (message != NULL, FALSE);
02917 _dbus_return_val_if_fail (interface != NULL, FALSE);
02918 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
02919
02920
02921
02922
02923 return _dbus_message_has_type_interface_member (message,
02924 DBUS_MESSAGE_TYPE_SIGNAL,
02925 interface, signal_name);
02926 }
02927
02938 dbus_bool_t
02939 dbus_message_is_error (DBusMessage *message,
02940 const char *error_name)
02941 {
02942 const char *n;
02943
02944 _dbus_return_val_if_fail (message != NULL, FALSE);
02945 _dbus_return_val_if_fail (error_name != NULL, FALSE);
02946
02947
02948
02949
02950 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
02951 return FALSE;
02952
02953 n = dbus_message_get_error_name (message);
02954
02955 if (n && strcmp (n, error_name) == 0)
02956 return TRUE;
02957 else
02958 return FALSE;
02959 }
02960
02971 dbus_bool_t
02972 dbus_message_has_destination (DBusMessage *message,
02973 const char *name)
02974 {
02975 const char *s;
02976
02977 _dbus_return_val_if_fail (message != NULL, FALSE);
02978 _dbus_return_val_if_fail (name != NULL, FALSE);
02979
02980
02981
02982
02983 s = dbus_message_get_destination (message);
02984
02985 if (s && strcmp (s, name) == 0)
02986 return TRUE;
02987 else
02988 return FALSE;
02989 }
02990
03006 dbus_bool_t
03007 dbus_message_has_sender (DBusMessage *message,
03008 const char *name)
03009 {
03010 const char *s;
03011
03012 _dbus_return_val_if_fail (message != NULL, FALSE);
03013 _dbus_return_val_if_fail (name != NULL, FALSE);
03014
03015
03016
03017
03018 s = dbus_message_get_sender (message);
03019
03020 if (s && strcmp (s, name) == 0)
03021 return TRUE;
03022 else
03023 return FALSE;
03024 }
03025
03035 dbus_bool_t
03036 dbus_message_has_signature (DBusMessage *message,
03037 const char *signature)
03038 {
03039 const char *s;
03040
03041 _dbus_return_val_if_fail (message != NULL, FALSE);
03042 _dbus_return_val_if_fail (signature != NULL, FALSE);
03043
03044
03045
03046
03047 s = dbus_message_get_signature (message);
03048
03049 if (s && strcmp (s, signature) == 0)
03050 return TRUE;
03051 else
03052 return FALSE;
03053 }
03054
03077 dbus_bool_t
03078 dbus_set_error_from_message (DBusError *error,
03079 DBusMessage *message)
03080 {
03081 const char *str;
03082
03083 _dbus_return_val_if_fail (message != NULL, FALSE);
03084 _dbus_return_val_if_error_is_set (error, FALSE);
03085
03086 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03087 return FALSE;
03088
03089 str = NULL;
03090 dbus_message_get_args (message, NULL,
03091 DBUS_TYPE_STRING, &str,
03092 DBUS_TYPE_INVALID);
03093
03094 dbus_set_error (error, dbus_message_get_error_name (message),
03095 str ? "%s" : NULL, str);
03096
03097 return TRUE;
03098 }
03099
03118 #define INITIAL_LOADER_DATA_LEN 32
03119
03126 DBusMessageLoader*
03127 _dbus_message_loader_new (void)
03128 {
03129 DBusMessageLoader *loader;
03130
03131 loader = dbus_new0 (DBusMessageLoader, 1);
03132 if (loader == NULL)
03133 return NULL;
03134
03135 loader->refcount = 1;
03136
03137 loader->corrupted = FALSE;
03138 loader->corruption_reason = DBUS_VALID;
03139
03140
03141 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03142
03143 if (!_dbus_string_init (&loader->data))
03144 {
03145 dbus_free (loader);
03146 return NULL;
03147 }
03148
03149
03150 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03151 _dbus_string_set_length (&loader->data, 0);
03152
03153 return loader;
03154 }
03155
03162 DBusMessageLoader *
03163 _dbus_message_loader_ref (DBusMessageLoader *loader)
03164 {
03165 loader->refcount += 1;
03166
03167 return loader;
03168 }
03169
03176 void
03177 _dbus_message_loader_unref (DBusMessageLoader *loader)
03178 {
03179 loader->refcount -= 1;
03180 if (loader->refcount == 0)
03181 {
03182 _dbus_list_foreach (&loader->messages,
03183 (DBusForeachFunction) dbus_message_unref,
03184 NULL);
03185 _dbus_list_clear (&loader->messages);
03186 _dbus_string_free (&loader->data);
03187 dbus_free (loader);
03188 }
03189 }
03190
03209 void
03210 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03211 DBusString **buffer)
03212 {
03213 _dbus_assert (!loader->buffer_outstanding);
03214
03215 *buffer = &loader->data;
03216
03217 loader->buffer_outstanding = TRUE;
03218 }
03219
03230 void
03231 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03232 DBusString *buffer,
03233 int bytes_read)
03234 {
03235 _dbus_assert (loader->buffer_outstanding);
03236 _dbus_assert (buffer == &loader->data);
03237
03238 loader->buffer_outstanding = FALSE;
03239 }
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267 static dbus_bool_t
03268 load_message (DBusMessageLoader *loader,
03269 DBusMessage *message,
03270 int byte_order,
03271 int fields_array_len,
03272 int header_len,
03273 int body_len)
03274 {
03275 dbus_bool_t oom;
03276 DBusValidity validity;
03277 const DBusString *type_str;
03278 int type_pos;
03279 DBusValidationMode mode;
03280
03281 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03282
03283 oom = FALSE;
03284
03285 #if 0
03286 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03287 #endif
03288
03289
03290 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03291 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03292
03293 if (!_dbus_header_load (&message->header,
03294 mode,
03295 &validity,
03296 byte_order,
03297 fields_array_len,
03298 header_len,
03299 body_len,
03300 &loader->data, 0,
03301 _dbus_string_get_length (&loader->data)))
03302 {
03303 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03304
03305
03306
03307 _dbus_assert (validity != DBUS_VALID);
03308
03309 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03310 oom = TRUE;
03311 else
03312 {
03313 loader->corrupted = TRUE;
03314 loader->corruption_reason = validity;
03315 }
03316 goto failed;
03317 }
03318
03319 _dbus_assert (validity == DBUS_VALID);
03320
03321 message->byte_order = byte_order;
03322
03323
03324 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03325 {
03326 get_const_signature (&message->header, &type_str, &type_pos);
03327
03328
03329
03330
03331 validity = _dbus_validate_body_with_reason (type_str,
03332 type_pos,
03333 byte_order,
03334 NULL,
03335 &loader->data,
03336 header_len,
03337 body_len);
03338 if (validity != DBUS_VALID)
03339 {
03340 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03341
03342 loader->corrupted = TRUE;
03343 loader->corruption_reason = validity;
03344
03345 goto failed;
03346 }
03347 }
03348
03349
03350
03351 if (!_dbus_list_append (&loader->messages, message))
03352 {
03353 _dbus_verbose ("Failed to append new message to loader queue\n");
03354 oom = TRUE;
03355 goto failed;
03356 }
03357
03358 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03359 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03360 (header_len + body_len));
03361
03362 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03363 {
03364 _dbus_verbose ("Failed to move body into new message\n");
03365 oom = TRUE;
03366 goto failed;
03367 }
03368
03369 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03370
03371 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03372 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03373
03374 _dbus_verbose ("Loaded message %p\n", message);
03375
03376 _dbus_assert (!oom);
03377 _dbus_assert (!loader->corrupted);
03378 _dbus_assert (loader->messages != NULL);
03379 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03380
03381 return TRUE;
03382
03383 failed:
03384
03385
03386
03387
03388 _dbus_list_remove_last (&loader->messages, message);
03389
03390 if (oom)
03391 _dbus_assert (!loader->corrupted);
03392 else
03393 _dbus_assert (loader->corrupted);
03394
03395 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03396
03397 return FALSE;
03398 }
03399
03414 dbus_bool_t
03415 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03416 {
03417 while (!loader->corrupted &&
03418 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03419 {
03420 DBusValidity validity;
03421 int byte_order, fields_array_len, header_len, body_len;
03422
03423 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03424 &validity,
03425 &byte_order,
03426 &fields_array_len,
03427 &header_len,
03428 &body_len,
03429 &loader->data, 0,
03430 _dbus_string_get_length (&loader->data)))
03431 {
03432 DBusMessage *message;
03433
03434 _dbus_assert (validity == DBUS_VALID);
03435
03436 message = dbus_message_new_empty_header ();
03437 if (message == NULL)
03438 return FALSE;
03439
03440 if (!load_message (loader, message,
03441 byte_order, fields_array_len,
03442 header_len, body_len))
03443 {
03444 dbus_message_unref (message);
03445
03446
03447
03448 return loader->corrupted;
03449 }
03450
03451 _dbus_assert (loader->messages != NULL);
03452 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03453 }
03454 else
03455 {
03456 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03457 validity);
03458 if (validity != DBUS_VALID)
03459 {
03460 loader->corrupted = TRUE;
03461 loader->corruption_reason = validity;
03462 }
03463 return TRUE;
03464 }
03465 }
03466
03467 return TRUE;
03468 }
03469
03477 DBusMessage*
03478 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03479 {
03480 if (loader->messages)
03481 return loader->messages->data;
03482 else
03483 return NULL;
03484 }
03485
03494 DBusMessage*
03495 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03496 {
03497 return _dbus_list_pop_first (&loader->messages);
03498 }
03499
03508 DBusList*
03509 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03510 {
03511 return _dbus_list_pop_first_link (&loader->messages);
03512 }
03513
03520 void
03521 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03522 DBusList *link)
03523 {
03524 _dbus_list_prepend_link (&loader->messages, link);
03525 }
03526
03536 dbus_bool_t
03537 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03538 {
03539 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03540 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03541 return loader->corrupted;
03542 }
03543
03550 void
03551 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03552 long size)
03553 {
03554 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03555 {
03556 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03557 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03558 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03559 }
03560 loader->max_message_size = size;
03561 }
03562
03569 long
03570 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03571 {
03572 return loader->max_message_size;
03573 }
03574
03575 static DBusDataSlotAllocator slot_allocator;
03576 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03577
03592 dbus_bool_t
03593 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03594 {
03595 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03596 _DBUS_LOCK_NAME (message_slots),
03597 slot_p);
03598 }
03599
03611 void
03612 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03613 {
03614 _dbus_return_if_fail (*slot_p >= 0);
03615
03616 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03617 }
03618
03632 dbus_bool_t
03633 dbus_message_set_data (DBusMessage *message,
03634 dbus_int32_t slot,
03635 void *data,
03636 DBusFreeFunction free_data_func)
03637 {
03638 DBusFreeFunction old_free_func;
03639 void *old_data;
03640 dbus_bool_t retval;
03641
03642 _dbus_return_val_if_fail (message != NULL, FALSE);
03643 _dbus_return_val_if_fail (slot >= 0, FALSE);
03644
03645 retval = _dbus_data_slot_list_set (&slot_allocator,
03646 &message->slot_list,
03647 slot, data, free_data_func,
03648 &old_free_func, &old_data);
03649
03650 if (retval)
03651 {
03652
03653 if (old_free_func)
03654 (* old_free_func) (old_data);
03655 }
03656
03657 return retval;
03658 }
03659
03668 void*
03669 dbus_message_get_data (DBusMessage *message,
03670 dbus_int32_t slot)
03671 {
03672 void *res;
03673
03674 _dbus_return_val_if_fail (message != NULL, NULL);
03675
03676 res = _dbus_data_slot_list_get (&slot_allocator,
03677 &message->slot_list,
03678 slot);
03679
03680 return res;
03681 }
03682
03696 int
03697 dbus_message_type_from_string (const char *type_str)
03698 {
03699 if (strcmp (type_str, "method_call") == 0)
03700 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03701 if (strcmp (type_str, "method_return") == 0)
03702 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03703 else if (strcmp (type_str, "signal") == 0)
03704 return DBUS_MESSAGE_TYPE_SIGNAL;
03705 else if (strcmp (type_str, "error") == 0)
03706 return DBUS_MESSAGE_TYPE_ERROR;
03707 else
03708 return DBUS_MESSAGE_TYPE_INVALID;
03709 }
03710
03724 const char *
03725 dbus_message_type_to_string (int type)
03726 {
03727 switch (type)
03728 {
03729 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03730 return "method_call";
03731 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03732 return "method_return";
03733 case DBUS_MESSAGE_TYPE_SIGNAL:
03734 return "signal";
03735 case DBUS_MESSAGE_TYPE_ERROR:
03736 return "error";
03737 default:
03738 return "invalid";
03739 }
03740 }
03741
03744