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 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
01739
01740 _dbus_return_if_fail (_dbus_message_iter_check (real));
01741 _dbus_return_if_fail (value != NULL);
01742 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
01743 dbus_type_is_fixed (subtype));
01744
01745 _dbus_type_reader_read_fixed_multi (&real->u.reader,
01746 value, n_elements);
01747 }
01748
01762 dbus_bool_t
01763 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
01764 DBusError *error,
01765 int first_arg_type,
01766 va_list var_args)
01767 {
01768 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01769 int spec_type, msg_type, i;
01770 dbus_bool_t retval;
01771
01772 _dbus_assert (_dbus_message_iter_check (real));
01773
01774 retval = FALSE;
01775
01776 spec_type = first_arg_type;
01777 i = 0;
01778
01779 while (spec_type != DBUS_TYPE_INVALID)
01780 {
01781 msg_type = dbus_message_iter_get_arg_type (iter);
01782
01783 if (msg_type != spec_type)
01784 {
01785 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01786 "Argument %d is specified to be of type \"%s\", but "
01787 "is actually of type \"%s\"\n", i,
01788 _dbus_type_to_string (spec_type),
01789 _dbus_type_to_string (msg_type));
01790
01791 goto out;
01792 }
01793
01794 if (dbus_type_is_basic (spec_type))
01795 {
01796 DBusBasicValue *ptr;
01797
01798 ptr = va_arg (var_args, DBusBasicValue*);
01799
01800 _dbus_assert (ptr != NULL);
01801
01802 _dbus_type_reader_read_basic (&real->u.reader,
01803 ptr);
01804 }
01805 else if (spec_type == DBUS_TYPE_ARRAY)
01806 {
01807 int element_type;
01808 int spec_element_type;
01809 const DBusBasicValue **ptr;
01810 int *n_elements_p;
01811 DBusTypeReader array;
01812
01813 spec_element_type = va_arg (var_args, int);
01814 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
01815
01816 if (spec_element_type != element_type)
01817 {
01818 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01819 "Argument %d is specified to be an array of \"%s\", but "
01820 "is actually an array of \"%s\"\n",
01821 i,
01822 _dbus_type_to_string (spec_element_type),
01823 _dbus_type_to_string (element_type));
01824
01825 goto out;
01826 }
01827
01828 if (dbus_type_is_fixed (spec_element_type))
01829 {
01830 ptr = va_arg (var_args, const DBusBasicValue**);
01831 n_elements_p = va_arg (var_args, int*);
01832
01833 _dbus_assert (ptr != NULL);
01834 _dbus_assert (n_elements_p != NULL);
01835
01836 _dbus_type_reader_recurse (&real->u.reader, &array);
01837
01838 _dbus_type_reader_read_fixed_multi (&array,
01839 ptr, n_elements_p);
01840 }
01841 else if (spec_element_type == DBUS_TYPE_STRING ||
01842 spec_element_type == DBUS_TYPE_SIGNATURE ||
01843 spec_element_type == DBUS_TYPE_OBJECT_PATH)
01844 {
01845 char ***str_array_p;
01846 int n_elements;
01847 char **str_array;
01848
01849 str_array_p = va_arg (var_args, char***);
01850 n_elements_p = va_arg (var_args, int*);
01851
01852 _dbus_assert (str_array_p != NULL);
01853 _dbus_assert (n_elements_p != NULL);
01854
01855
01856 _dbus_type_reader_recurse (&real->u.reader, &array);
01857
01858 n_elements = 0;
01859 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
01860 {
01861 ++n_elements;
01862 _dbus_type_reader_next (&array);
01863 }
01864
01865 str_array = dbus_new0 (char*, n_elements + 1);
01866 if (str_array == NULL)
01867 {
01868 _DBUS_SET_OOM (error);
01869 goto out;
01870 }
01871
01872
01873 _dbus_type_reader_recurse (&real->u.reader, &array);
01874
01875 i = 0;
01876 while (i < n_elements)
01877 {
01878 const char *s;
01879 _dbus_type_reader_read_basic (&array,
01880 &s);
01881
01882 str_array[i] = _dbus_strdup (s);
01883 if (str_array[i] == NULL)
01884 {
01885 dbus_free_string_array (str_array);
01886 _DBUS_SET_OOM (error);
01887 goto out;
01888 }
01889
01890 ++i;
01891
01892 if (!_dbus_type_reader_next (&array))
01893 _dbus_assert (i == n_elements);
01894 }
01895
01896 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
01897 _dbus_assert (i == n_elements);
01898 _dbus_assert (str_array[i] == NULL);
01899
01900 *str_array_p = str_array;
01901 *n_elements_p = n_elements;
01902 }
01903 #ifndef DBUS_DISABLE_CHECKS
01904 else
01905 {
01906 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
01907 _DBUS_FUNCTION_NAME);
01908 goto out;
01909 }
01910 #endif
01911 }
01912 #ifndef DBUS_DISABLE_CHECKS
01913 else
01914 {
01915 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
01916 _DBUS_FUNCTION_NAME);
01917 goto out;
01918 }
01919 #endif
01920
01921 spec_type = va_arg (var_args, int);
01922 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
01923 {
01924 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01925 "Message has only %d arguments, but more were expected", i);
01926 goto out;
01927 }
01928
01929 i++;
01930 }
01931
01932 retval = TRUE;
01933
01934 out:
01935
01936 return retval;
01937 }
01938
01950 void
01951 dbus_message_iter_init_append (DBusMessage *message,
01952 DBusMessageIter *iter)
01953 {
01954 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01955
01956 _dbus_return_if_fail (message != NULL);
01957 _dbus_return_if_fail (iter != NULL);
01958
01959 _dbus_message_iter_init_common (message, real,
01960 DBUS_MESSAGE_ITER_TYPE_WRITER);
01961
01962
01963
01964
01965
01966 _dbus_type_writer_init_types_delayed (&real->u.writer,
01967 message->byte_order,
01968 &message->body,
01969 _dbus_string_get_length (&message->body));
01970 }
01971
01980 static dbus_bool_t
01981 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
01982 {
01983 DBusString *str;
01984 const DBusString *current_sig;
01985 int current_sig_pos;
01986
01987 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
01988
01989 if (real->u.writer.type_str != NULL)
01990 {
01991 _dbus_assert (real->sig_refcount > 0);
01992 real->sig_refcount += 1;
01993 return TRUE;
01994 }
01995
01996 str = dbus_new (DBusString, 1);
01997 if (str == NULL)
01998 return FALSE;
01999
02000 if (!_dbus_header_get_field_raw (&real->message->header,
02001 DBUS_HEADER_FIELD_SIGNATURE,
02002 ¤t_sig, ¤t_sig_pos))
02003 current_sig = NULL;
02004
02005 if (current_sig)
02006 {
02007 int current_len;
02008
02009 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02010 current_sig_pos += 1;
02011
02012 if (!_dbus_string_init_preallocated (str, current_len + 4))
02013 {
02014 dbus_free (str);
02015 return FALSE;
02016 }
02017
02018 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02019 str, 0))
02020 {
02021 _dbus_string_free (str);
02022 dbus_free (str);
02023 return FALSE;
02024 }
02025 }
02026 else
02027 {
02028 if (!_dbus_string_init_preallocated (str, 4))
02029 {
02030 dbus_free (str);
02031 return FALSE;
02032 }
02033 }
02034
02035 real->sig_refcount = 1;
02036
02037 _dbus_type_writer_add_types (&real->u.writer,
02038 str, _dbus_string_get_length (str));
02039 return TRUE;
02040 }
02041
02051 static dbus_bool_t
02052 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02053 {
02054 DBusString *str;
02055 const char *v_STRING;
02056 dbus_bool_t retval;
02057
02058 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02059 _dbus_assert (real->u.writer.type_str != NULL);
02060 _dbus_assert (real->sig_refcount > 0);
02061
02062 real->sig_refcount -= 1;
02063
02064 if (real->sig_refcount > 0)
02065 return TRUE;
02066 _dbus_assert (real->sig_refcount == 0);
02067
02068 retval = TRUE;
02069
02070 str = real->u.writer.type_str;
02071
02072 v_STRING = _dbus_string_get_const_data (str);
02073 if (!_dbus_header_set_field_basic (&real->message->header,
02074 DBUS_HEADER_FIELD_SIGNATURE,
02075 DBUS_TYPE_SIGNATURE,
02076 &v_STRING))
02077 retval = FALSE;
02078
02079 _dbus_type_writer_remove_types (&real->u.writer);
02080 _dbus_string_free (str);
02081 dbus_free (str);
02082
02083 return retval;
02084 }
02085
02086 #ifndef DBUS_DISABLE_CHECKS
02087 static dbus_bool_t
02088 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02089 {
02090 if (!_dbus_message_iter_check (iter))
02091 return FALSE;
02092
02093 if (iter->message->locked)
02094 {
02095 _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02096 return FALSE;
02097 }
02098
02099 return TRUE;
02100 }
02101 #endif
02102
02118 dbus_bool_t
02119 dbus_message_iter_append_basic (DBusMessageIter *iter,
02120 int type,
02121 const void *value)
02122 {
02123 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02124 dbus_bool_t ret;
02125
02126 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02127 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02128 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02129 _dbus_return_val_if_fail (value != NULL, FALSE);
02130
02131 if (!_dbus_message_iter_open_signature (real))
02132 return FALSE;
02133
02134 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02135
02136 if (!_dbus_message_iter_close_signature (real))
02137 ret = FALSE;
02138
02139 return ret;
02140 }
02141
02177 dbus_bool_t
02178 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02179 int element_type,
02180 const void *value,
02181 int n_elements)
02182 {
02183 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02184 dbus_bool_t ret;
02185
02186 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02187 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02188 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02189 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02190 _dbus_return_val_if_fail (value != NULL, FALSE);
02191 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02192 _dbus_return_val_if_fail (n_elements <=
02193 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02194 FALSE);
02195
02196 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02197
02198 return ret;
02199 }
02200
02222 dbus_bool_t
02223 dbus_message_iter_open_container (DBusMessageIter *iter,
02224 int type,
02225 const char *contained_signature,
02226 DBusMessageIter *sub)
02227 {
02228 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02229 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02230 DBusString contained_str;
02231
02232 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02233 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02234 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02235 _dbus_return_val_if_fail (sub != NULL, FALSE);
02236 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02237 contained_signature == NULL) ||
02238 (type == DBUS_TYPE_DICT_ENTRY &&
02239 contained_signature == NULL) ||
02240 contained_signature != NULL, FALSE);
02241
02242 #if 0
02243
02244
02245
02246
02247 _dbus_return_val_if_fail (contained_signature == NULL ||
02248 _dbus_check_is_valid_signature (contained_signature));
02249 #endif
02250
02251 if (!_dbus_message_iter_open_signature (real))
02252 return FALSE;
02253
02254 *real_sub = *real;
02255
02256 if (contained_signature != NULL)
02257 {
02258 _dbus_string_init_const (&contained_str, contained_signature);
02259
02260 return _dbus_type_writer_recurse (&real->u.writer,
02261 type,
02262 &contained_str, 0,
02263 &real_sub->u.writer);
02264 }
02265 else
02266 {
02267 return _dbus_type_writer_recurse (&real->u.writer,
02268 type,
02269 NULL, 0,
02270 &real_sub->u.writer);
02271 }
02272 }
02273
02274
02288 dbus_bool_t
02289 dbus_message_iter_close_container (DBusMessageIter *iter,
02290 DBusMessageIter *sub)
02291 {
02292 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02293 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02294 dbus_bool_t ret;
02295
02296 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02297 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02298 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02299 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02300
02301 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02302 &real_sub->u.writer);
02303
02304 if (!_dbus_message_iter_close_signature (real))
02305 ret = FALSE;
02306
02307 return ret;
02308 }
02309
02321 void
02322 dbus_message_set_no_reply (DBusMessage *message,
02323 dbus_bool_t no_reply)
02324 {
02325 _dbus_return_if_fail (message != NULL);
02326 _dbus_return_if_fail (!message->locked);
02327
02328 _dbus_header_toggle_flag (&message->header,
02329 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02330 no_reply);
02331 }
02332
02340 dbus_bool_t
02341 dbus_message_get_no_reply (DBusMessage *message)
02342 {
02343 _dbus_return_val_if_fail (message != NULL, FALSE);
02344
02345 return _dbus_header_get_flag (&message->header,
02346 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02347 }
02348
02359 void
02360 dbus_message_set_auto_start (DBusMessage *message,
02361 dbus_bool_t auto_start)
02362 {
02363 _dbus_return_if_fail (message != NULL);
02364 _dbus_return_if_fail (!message->locked);
02365
02366 _dbus_header_toggle_flag (&message->header,
02367 DBUS_HEADER_FLAG_NO_AUTO_START,
02368 !auto_start);
02369 }
02370
02378 dbus_bool_t
02379 dbus_message_get_auto_start (DBusMessage *message)
02380 {
02381 _dbus_return_val_if_fail (message != NULL, FALSE);
02382
02383 return !_dbus_header_get_flag (&message->header,
02384 DBUS_HEADER_FLAG_NO_AUTO_START);
02385 }
02386
02387
02397 dbus_bool_t
02398 dbus_message_set_path (DBusMessage *message,
02399 const char *object_path)
02400 {
02401 _dbus_return_val_if_fail (message != NULL, FALSE);
02402 _dbus_return_val_if_fail (!message->locked, FALSE);
02403 _dbus_return_val_if_fail (object_path == NULL ||
02404 _dbus_check_is_valid_path (object_path),
02405 FALSE);
02406
02407 return set_or_delete_string_field (message,
02408 DBUS_HEADER_FIELD_PATH,
02409 DBUS_TYPE_OBJECT_PATH,
02410 object_path);
02411 }
02412
02421 const char*
02422 dbus_message_get_path (DBusMessage *message)
02423 {
02424 const char *v;
02425
02426 _dbus_return_val_if_fail (message != NULL, NULL);
02427
02428 v = NULL;
02429 _dbus_header_get_field_basic (&message->header,
02430 DBUS_HEADER_FIELD_PATH,
02431 DBUS_TYPE_OBJECT_PATH,
02432 &v);
02433 return v;
02434 }
02435
02443 dbus_bool_t
02444 dbus_message_has_path (DBusMessage *message,
02445 const char *path)
02446 {
02447 const char *msg_path;
02448 msg_path = dbus_message_get_path (message);
02449
02450 if (msg_path == NULL)
02451 {
02452 if (path == NULL)
02453 return TRUE;
02454 else
02455 return FALSE;
02456 }
02457
02458 if (path == NULL)
02459 return FALSE;
02460
02461 if (strcmp (msg_path, path) == 0)
02462 return TRUE;
02463
02464 return FALSE;
02465 }
02466
02485 dbus_bool_t
02486 dbus_message_get_path_decomposed (DBusMessage *message,
02487 char ***path)
02488 {
02489 const char *v;
02490
02491 _dbus_return_val_if_fail (message != NULL, FALSE);
02492 _dbus_return_val_if_fail (path != NULL, FALSE);
02493
02494 *path = NULL;
02495
02496 v = dbus_message_get_path (message);
02497 if (v != NULL)
02498 {
02499 if (!_dbus_decompose_path (v, strlen (v),
02500 path, NULL))
02501 return FALSE;
02502 }
02503 return TRUE;
02504 }
02505
02516 dbus_bool_t
02517 dbus_message_set_interface (DBusMessage *message,
02518 const char *interface)
02519 {
02520 _dbus_return_val_if_fail (message != NULL, FALSE);
02521 _dbus_return_val_if_fail (!message->locked, FALSE);
02522 _dbus_return_val_if_fail (interface == NULL ||
02523 _dbus_check_is_valid_interface (interface),
02524 FALSE);
02525
02526 return set_or_delete_string_field (message,
02527 DBUS_HEADER_FIELD_INTERFACE,
02528 DBUS_TYPE_STRING,
02529 interface);
02530 }
02531
02542 const char*
02543 dbus_message_get_interface (DBusMessage *message)
02544 {
02545 const char *v;
02546
02547 _dbus_return_val_if_fail (message != NULL, NULL);
02548
02549 v = NULL;
02550 _dbus_header_get_field_basic (&message->header,
02551 DBUS_HEADER_FIELD_INTERFACE,
02552 DBUS_TYPE_STRING,
02553 &v);
02554 return v;
02555 }
02556
02564 dbus_bool_t
02565 dbus_message_has_interface (DBusMessage *message,
02566 const char *interface)
02567 {
02568 const char *msg_interface;
02569 msg_interface = dbus_message_get_interface (message);
02570
02571 if (msg_interface == NULL)
02572 {
02573 if (interface == NULL)
02574 return TRUE;
02575 else
02576 return FALSE;
02577 }
02578
02579 if (interface == NULL)
02580 return FALSE;
02581
02582 if (strcmp (msg_interface, interface) == 0)
02583 return TRUE;
02584
02585 return FALSE;
02586
02587 }
02588
02599 dbus_bool_t
02600 dbus_message_set_member (DBusMessage *message,
02601 const char *member)
02602 {
02603 _dbus_return_val_if_fail (message != NULL, FALSE);
02604 _dbus_return_val_if_fail (!message->locked, FALSE);
02605 _dbus_return_val_if_fail (member == NULL ||
02606 _dbus_check_is_valid_member (member),
02607 FALSE);
02608
02609 return set_or_delete_string_field (message,
02610 DBUS_HEADER_FIELD_MEMBER,
02611 DBUS_TYPE_STRING,
02612 member);
02613 }
02614
02623 const char*
02624 dbus_message_get_member (DBusMessage *message)
02625 {
02626 const char *v;
02627
02628 _dbus_return_val_if_fail (message != NULL, NULL);
02629
02630 v = NULL;
02631 _dbus_header_get_field_basic (&message->header,
02632 DBUS_HEADER_FIELD_MEMBER,
02633 DBUS_TYPE_STRING,
02634 &v);
02635 return v;
02636 }
02637
02645 dbus_bool_t
02646 dbus_message_has_member (DBusMessage *message,
02647 const char *member)
02648 {
02649 const char *msg_member;
02650 msg_member = dbus_message_get_member (message);
02651
02652 if (msg_member == NULL)
02653 {
02654 if (member == NULL)
02655 return TRUE;
02656 else
02657 return FALSE;
02658 }
02659
02660 if (member == NULL)
02661 return FALSE;
02662
02663 if (strcmp (msg_member, member) == 0)
02664 return TRUE;
02665
02666 return FALSE;
02667
02668 }
02669
02678 dbus_bool_t
02679 dbus_message_set_error_name (DBusMessage *message,
02680 const char *error_name)
02681 {
02682 _dbus_return_val_if_fail (message != NULL, FALSE);
02683 _dbus_return_val_if_fail (!message->locked, FALSE);
02684 _dbus_return_val_if_fail (error_name == NULL ||
02685 _dbus_check_is_valid_error_name (error_name),
02686 FALSE);
02687
02688 return set_or_delete_string_field (message,
02689 DBUS_HEADER_FIELD_ERROR_NAME,
02690 DBUS_TYPE_STRING,
02691 error_name);
02692 }
02693
02701 const char*
02702 dbus_message_get_error_name (DBusMessage *message)
02703 {
02704 const char *v;
02705
02706 _dbus_return_val_if_fail (message != NULL, NULL);
02707
02708 v = NULL;
02709 _dbus_header_get_field_basic (&message->header,
02710 DBUS_HEADER_FIELD_ERROR_NAME,
02711 DBUS_TYPE_STRING,
02712 &v);
02713 return v;
02714 }
02715
02726 dbus_bool_t
02727 dbus_message_set_destination (DBusMessage *message,
02728 const char *destination)
02729 {
02730 _dbus_return_val_if_fail (message != NULL, FALSE);
02731 _dbus_return_val_if_fail (!message->locked, FALSE);
02732 _dbus_return_val_if_fail (destination == NULL ||
02733 _dbus_check_is_valid_bus_name (destination),
02734 FALSE);
02735
02736 return set_or_delete_string_field (message,
02737 DBUS_HEADER_FIELD_DESTINATION,
02738 DBUS_TYPE_STRING,
02739 destination);
02740 }
02741
02748 const char*
02749 dbus_message_get_destination (DBusMessage *message)
02750 {
02751 const char *v;
02752
02753 _dbus_return_val_if_fail (message != NULL, NULL);
02754
02755 v = NULL;
02756 _dbus_header_get_field_basic (&message->header,
02757 DBUS_HEADER_FIELD_DESTINATION,
02758 DBUS_TYPE_STRING,
02759 &v);
02760 return v;
02761 }
02762
02770 dbus_bool_t
02771 dbus_message_set_sender (DBusMessage *message,
02772 const char *sender)
02773 {
02774 _dbus_return_val_if_fail (message != NULL, FALSE);
02775 _dbus_return_val_if_fail (!message->locked, FALSE);
02776 _dbus_return_val_if_fail (sender == NULL ||
02777 _dbus_check_is_valid_bus_name (sender),
02778 FALSE);
02779
02780 return set_or_delete_string_field (message,
02781 DBUS_HEADER_FIELD_SENDER,
02782 DBUS_TYPE_STRING,
02783 sender);
02784 }
02785
02794 const char*
02795 dbus_message_get_sender (DBusMessage *message)
02796 {
02797 const char *v;
02798
02799 _dbus_return_val_if_fail (message != NULL, NULL);
02800
02801 v = NULL;
02802 _dbus_header_get_field_basic (&message->header,
02803 DBUS_HEADER_FIELD_SENDER,
02804 DBUS_TYPE_STRING,
02805 &v);
02806 return v;
02807 }
02808
02824 const char*
02825 dbus_message_get_signature (DBusMessage *message)
02826 {
02827 const DBusString *type_str;
02828 int type_pos;
02829
02830 _dbus_return_val_if_fail (message != NULL, NULL);
02831
02832 get_const_signature (&message->header, &type_str, &type_pos);
02833
02834 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
02835 }
02836
02837 static dbus_bool_t
02838 _dbus_message_has_type_interface_member (DBusMessage *message,
02839 int type,
02840 const char *interface,
02841 const char *member)
02842 {
02843 const char *n;
02844
02845 _dbus_assert (message != NULL);
02846 _dbus_assert (interface != NULL);
02847 _dbus_assert (member != NULL);
02848
02849 if (dbus_message_get_type (message) != type)
02850 return FALSE;
02851
02852
02853
02854
02855
02856 n = dbus_message_get_member (message);
02857
02858 if (n && strcmp (n, member) == 0)
02859 {
02860 n = dbus_message_get_interface (message);
02861
02862 if (n == NULL || strcmp (n, interface) == 0)
02863 return TRUE;
02864 }
02865
02866 return FALSE;
02867 }
02868
02883 dbus_bool_t
02884 dbus_message_is_method_call (DBusMessage *message,
02885 const char *interface,
02886 const char *method)
02887 {
02888 _dbus_return_val_if_fail (message != NULL, FALSE);
02889 _dbus_return_val_if_fail (interface != NULL, FALSE);
02890 _dbus_return_val_if_fail (method != NULL, FALSE);
02891
02892
02893
02894
02895 return _dbus_message_has_type_interface_member (message,
02896 DBUS_MESSAGE_TYPE_METHOD_CALL,
02897 interface, method);
02898 }
02899
02913 dbus_bool_t
02914 dbus_message_is_signal (DBusMessage *message,
02915 const char *interface,
02916 const char *signal_name)
02917 {
02918 _dbus_return_val_if_fail (message != NULL, FALSE);
02919 _dbus_return_val_if_fail (interface != NULL, FALSE);
02920 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
02921
02922
02923
02924
02925 return _dbus_message_has_type_interface_member (message,
02926 DBUS_MESSAGE_TYPE_SIGNAL,
02927 interface, signal_name);
02928 }
02929
02940 dbus_bool_t
02941 dbus_message_is_error (DBusMessage *message,
02942 const char *error_name)
02943 {
02944 const char *n;
02945
02946 _dbus_return_val_if_fail (message != NULL, FALSE);
02947 _dbus_return_val_if_fail (error_name != NULL, FALSE);
02948
02949
02950
02951
02952 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
02953 return FALSE;
02954
02955 n = dbus_message_get_error_name (message);
02956
02957 if (n && strcmp (n, error_name) == 0)
02958 return TRUE;
02959 else
02960 return FALSE;
02961 }
02962
02973 dbus_bool_t
02974 dbus_message_has_destination (DBusMessage *message,
02975 const char *name)
02976 {
02977 const char *s;
02978
02979 _dbus_return_val_if_fail (message != NULL, FALSE);
02980 _dbus_return_val_if_fail (name != NULL, FALSE);
02981
02982
02983
02984
02985 s = dbus_message_get_destination (message);
02986
02987 if (s && strcmp (s, name) == 0)
02988 return TRUE;
02989 else
02990 return FALSE;
02991 }
02992
03008 dbus_bool_t
03009 dbus_message_has_sender (DBusMessage *message,
03010 const char *name)
03011 {
03012 const char *s;
03013
03014 _dbus_return_val_if_fail (message != NULL, FALSE);
03015 _dbus_return_val_if_fail (name != NULL, FALSE);
03016
03017
03018
03019
03020 s = dbus_message_get_sender (message);
03021
03022 if (s && strcmp (s, name) == 0)
03023 return TRUE;
03024 else
03025 return FALSE;
03026 }
03027
03037 dbus_bool_t
03038 dbus_message_has_signature (DBusMessage *message,
03039 const char *signature)
03040 {
03041 const char *s;
03042
03043 _dbus_return_val_if_fail (message != NULL, FALSE);
03044 _dbus_return_val_if_fail (signature != NULL, FALSE);
03045
03046
03047
03048
03049 s = dbus_message_get_signature (message);
03050
03051 if (s && strcmp (s, signature) == 0)
03052 return TRUE;
03053 else
03054 return FALSE;
03055 }
03056
03079 dbus_bool_t
03080 dbus_set_error_from_message (DBusError *error,
03081 DBusMessage *message)
03082 {
03083 const char *str;
03084
03085 _dbus_return_val_if_fail (message != NULL, FALSE);
03086 _dbus_return_val_if_error_is_set (error, FALSE);
03087
03088 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03089 return FALSE;
03090
03091 str = NULL;
03092 dbus_message_get_args (message, NULL,
03093 DBUS_TYPE_STRING, &str,
03094 DBUS_TYPE_INVALID);
03095
03096 dbus_set_error (error, dbus_message_get_error_name (message),
03097 str ? "%s" : NULL, str);
03098
03099 return TRUE;
03100 }
03101
03120 #define INITIAL_LOADER_DATA_LEN 32
03121
03128 DBusMessageLoader*
03129 _dbus_message_loader_new (void)
03130 {
03131 DBusMessageLoader *loader;
03132
03133 loader = dbus_new0 (DBusMessageLoader, 1);
03134 if (loader == NULL)
03135 return NULL;
03136
03137 loader->refcount = 1;
03138
03139 loader->corrupted = FALSE;
03140 loader->corruption_reason = DBUS_VALID;
03141
03142
03143 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03144
03145 if (!_dbus_string_init (&loader->data))
03146 {
03147 dbus_free (loader);
03148 return NULL;
03149 }
03150
03151
03152 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03153 _dbus_string_set_length (&loader->data, 0);
03154
03155 return loader;
03156 }
03157
03164 DBusMessageLoader *
03165 _dbus_message_loader_ref (DBusMessageLoader *loader)
03166 {
03167 loader->refcount += 1;
03168
03169 return loader;
03170 }
03171
03178 void
03179 _dbus_message_loader_unref (DBusMessageLoader *loader)
03180 {
03181 loader->refcount -= 1;
03182 if (loader->refcount == 0)
03183 {
03184 _dbus_list_foreach (&loader->messages,
03185 (DBusForeachFunction) dbus_message_unref,
03186 NULL);
03187 _dbus_list_clear (&loader->messages);
03188 _dbus_string_free (&loader->data);
03189 dbus_free (loader);
03190 }
03191 }
03192
03211 void
03212 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03213 DBusString **buffer)
03214 {
03215 _dbus_assert (!loader->buffer_outstanding);
03216
03217 *buffer = &loader->data;
03218
03219 loader->buffer_outstanding = TRUE;
03220 }
03221
03232 void
03233 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03234 DBusString *buffer,
03235 int bytes_read)
03236 {
03237 _dbus_assert (loader->buffer_outstanding);
03238 _dbus_assert (buffer == &loader->data);
03239
03240 loader->buffer_outstanding = FALSE;
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
03268
03269 static dbus_bool_t
03270 load_message (DBusMessageLoader *loader,
03271 DBusMessage *message,
03272 int byte_order,
03273 int fields_array_len,
03274 int header_len,
03275 int body_len)
03276 {
03277 dbus_bool_t oom;
03278 DBusValidity validity;
03279 const DBusString *type_str;
03280 int type_pos;
03281 DBusValidationMode mode;
03282
03283 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03284
03285 oom = FALSE;
03286
03287 #if 0
03288 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03289 #endif
03290
03291
03292 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03293 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03294
03295 if (!_dbus_header_load (&message->header,
03296 mode,
03297 &validity,
03298 byte_order,
03299 fields_array_len,
03300 header_len,
03301 body_len,
03302 &loader->data, 0,
03303 _dbus_string_get_length (&loader->data)))
03304 {
03305 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03306
03307
03308
03309 _dbus_assert (validity != DBUS_VALID);
03310
03311 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03312 oom = TRUE;
03313 else
03314 {
03315 loader->corrupted = TRUE;
03316 loader->corruption_reason = validity;
03317 }
03318 goto failed;
03319 }
03320
03321 _dbus_assert (validity == DBUS_VALID);
03322
03323 message->byte_order = byte_order;
03324
03325
03326 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03327 {
03328 get_const_signature (&message->header, &type_str, &type_pos);
03329
03330
03331
03332
03333 validity = _dbus_validate_body_with_reason (type_str,
03334 type_pos,
03335 byte_order,
03336 NULL,
03337 &loader->data,
03338 header_len,
03339 body_len);
03340 if (validity != DBUS_VALID)
03341 {
03342 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03343
03344 loader->corrupted = TRUE;
03345 loader->corruption_reason = validity;
03346
03347 goto failed;
03348 }
03349 }
03350
03351
03352
03353 if (!_dbus_list_append (&loader->messages, message))
03354 {
03355 _dbus_verbose ("Failed to append new message to loader queue\n");
03356 oom = TRUE;
03357 goto failed;
03358 }
03359
03360 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03361 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03362 (header_len + body_len));
03363
03364 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03365 {
03366 _dbus_verbose ("Failed to move body into new message\n");
03367 oom = TRUE;
03368 goto failed;
03369 }
03370
03371 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03372
03373 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03374 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03375
03376 _dbus_verbose ("Loaded message %p\n", message);
03377
03378 _dbus_assert (!oom);
03379 _dbus_assert (!loader->corrupted);
03380 _dbus_assert (loader->messages != NULL);
03381 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03382
03383 return TRUE;
03384
03385 failed:
03386
03387
03388
03389
03390 _dbus_list_remove_last (&loader->messages, message);
03391
03392 if (oom)
03393 _dbus_assert (!loader->corrupted);
03394 else
03395 _dbus_assert (loader->corrupted);
03396
03397 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03398
03399 return FALSE;
03400 }
03401
03416 dbus_bool_t
03417 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03418 {
03419 while (!loader->corrupted &&
03420 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03421 {
03422 DBusValidity validity;
03423 int byte_order, fields_array_len, header_len, body_len;
03424
03425 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03426 &validity,
03427 &byte_order,
03428 &fields_array_len,
03429 &header_len,
03430 &body_len,
03431 &loader->data, 0,
03432 _dbus_string_get_length (&loader->data)))
03433 {
03434 DBusMessage *message;
03435
03436 _dbus_assert (validity == DBUS_VALID);
03437
03438 message = dbus_message_new_empty_header ();
03439 if (message == NULL)
03440 return FALSE;
03441
03442 if (!load_message (loader, message,
03443 byte_order, fields_array_len,
03444 header_len, body_len))
03445 {
03446 dbus_message_unref (message);
03447
03448
03449
03450 return loader->corrupted;
03451 }
03452
03453 _dbus_assert (loader->messages != NULL);
03454 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03455 }
03456 else
03457 {
03458 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03459 validity);
03460 if (validity != DBUS_VALID)
03461 {
03462 loader->corrupted = TRUE;
03463 loader->corruption_reason = validity;
03464 }
03465 return TRUE;
03466 }
03467 }
03468
03469 return TRUE;
03470 }
03471
03479 DBusMessage*
03480 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03481 {
03482 if (loader->messages)
03483 return loader->messages->data;
03484 else
03485 return NULL;
03486 }
03487
03496 DBusMessage*
03497 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03498 {
03499 return _dbus_list_pop_first (&loader->messages);
03500 }
03501
03510 DBusList*
03511 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03512 {
03513 return _dbus_list_pop_first_link (&loader->messages);
03514 }
03515
03522 void
03523 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03524 DBusList *link)
03525 {
03526 _dbus_list_prepend_link (&loader->messages, link);
03527 }
03528
03538 dbus_bool_t
03539 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03540 {
03541 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03542 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03543 return loader->corrupted;
03544 }
03545
03552 void
03553 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03554 long size)
03555 {
03556 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03557 {
03558 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03559 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03560 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03561 }
03562 loader->max_message_size = size;
03563 }
03564
03571 long
03572 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03573 {
03574 return loader->max_message_size;
03575 }
03576
03577 static DBusDataSlotAllocator slot_allocator;
03578 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03579
03594 dbus_bool_t
03595 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03596 {
03597 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03598 &_DBUS_LOCK_NAME (message_slots),
03599 slot_p);
03600 }
03601
03613 void
03614 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03615 {
03616 _dbus_return_if_fail (*slot_p >= 0);
03617
03618 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03619 }
03620
03634 dbus_bool_t
03635 dbus_message_set_data (DBusMessage *message,
03636 dbus_int32_t slot,
03637 void *data,
03638 DBusFreeFunction free_data_func)
03639 {
03640 DBusFreeFunction old_free_func;
03641 void *old_data;
03642 dbus_bool_t retval;
03643
03644 _dbus_return_val_if_fail (message != NULL, FALSE);
03645 _dbus_return_val_if_fail (slot >= 0, FALSE);
03646
03647 retval = _dbus_data_slot_list_set (&slot_allocator,
03648 &message->slot_list,
03649 slot, data, free_data_func,
03650 &old_free_func, &old_data);
03651
03652 if (retval)
03653 {
03654
03655 if (old_free_func)
03656 (* old_free_func) (old_data);
03657 }
03658
03659 return retval;
03660 }
03661
03670 void*
03671 dbus_message_get_data (DBusMessage *message,
03672 dbus_int32_t slot)
03673 {
03674 void *res;
03675
03676 _dbus_return_val_if_fail (message != NULL, NULL);
03677
03678 res = _dbus_data_slot_list_get (&slot_allocator,
03679 &message->slot_list,
03680 slot);
03681
03682 return res;
03683 }
03684
03698 int
03699 dbus_message_type_from_string (const char *type_str)
03700 {
03701 if (strcmp (type_str, "method_call") == 0)
03702 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03703 if (strcmp (type_str, "method_return") == 0)
03704 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03705 else if (strcmp (type_str, "signal") == 0)
03706 return DBUS_MESSAGE_TYPE_SIGNAL;
03707 else if (strcmp (type_str, "error") == 0)
03708 return DBUS_MESSAGE_TYPE_ERROR;
03709 else
03710 return DBUS_MESSAGE_TYPE_INVALID;
03711 }
03712
03726 const char *
03727 dbus_message_type_to_string (int type)
03728 {
03729 switch (type)
03730 {
03731 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03732 return "method_call";
03733 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03734 return "method_return";
03735 case DBUS_MESSAGE_TYPE_SIGNAL:
03736 return "signal";
03737 case DBUS_MESSAGE_TYPE_ERROR:
03738 return "error";
03739 default:
03740 return "invalid";
03741 }
03742 }
03743
03746