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
00406 return _dbus_header_set_field_basic (&message->header,
00407 DBUS_HEADER_FIELD_REPLY_SERIAL,
00408 DBUS_TYPE_UINT32,
00409 &reply_serial);
00410 }
00411
00418 dbus_uint32_t
00419 dbus_message_get_reply_serial (DBusMessage *message)
00420 {
00421 dbus_uint32_t v_UINT32;
00422
00423 _dbus_return_val_if_fail (message != NULL, 0);
00424
00425 if (_dbus_header_get_field_basic (&message->header,
00426 DBUS_HEADER_FIELD_REPLY_SERIAL,
00427 DBUS_TYPE_UINT32,
00428 &v_UINT32))
00429 return v_UINT32;
00430 else
00431 return 0;
00432 }
00433
00434 static void
00435 free_size_counter (void *element,
00436 void *data)
00437 {
00438 DBusCounter *counter = element;
00439 DBusMessage *message = data;
00440
00441 _dbus_counter_adjust (counter, - message->size_counter_delta);
00442
00443 _dbus_counter_unref (counter);
00444 }
00445
00446 static void
00447 dbus_message_finalize (DBusMessage *message)
00448 {
00449 _dbus_assert (message->refcount.value == 0);
00450
00451
00452 _dbus_data_slot_list_free (&message->slot_list);
00453
00454 _dbus_list_foreach (&message->size_counters,
00455 free_size_counter, message);
00456 _dbus_list_clear (&message->size_counters);
00457
00458 _dbus_header_free (&message->header);
00459 _dbus_string_free (&message->body);
00460
00461 _dbus_assert (message->refcount.value == 0);
00462
00463 dbus_free (message);
00464 }
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
00513 #define MAX_MESSAGE_SIZE_TO_CACHE _DBUS_ONE_MEGABYTE
00514
00516 #define MAX_MESSAGE_CACHE_SIZE 5
00517
00518 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00519 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00520 static int message_cache_count = 0;
00521 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00522
00523 static void
00524 dbus_message_cache_shutdown (void *data)
00525 {
00526 int i;
00527
00528 _DBUS_LOCK (message_cache);
00529
00530 i = 0;
00531 while (i < MAX_MESSAGE_CACHE_SIZE)
00532 {
00533 if (message_cache[i])
00534 dbus_message_finalize (message_cache[i]);
00535
00536 ++i;
00537 }
00538
00539 message_cache_count = 0;
00540 message_cache_shutdown_registered = FALSE;
00541
00542 _DBUS_UNLOCK (message_cache);
00543 }
00544
00552 static DBusMessage*
00553 dbus_message_get_cached (void)
00554 {
00555 DBusMessage *message;
00556 int i;
00557
00558 message = NULL;
00559
00560 _DBUS_LOCK (message_cache);
00561
00562 _dbus_assert (message_cache_count >= 0);
00563
00564 if (message_cache_count == 0)
00565 {
00566 _DBUS_UNLOCK (message_cache);
00567 return NULL;
00568 }
00569
00570
00571
00572
00573
00574 _dbus_assert (message_cache_shutdown_registered);
00575
00576 i = 0;
00577 while (i < MAX_MESSAGE_CACHE_SIZE)
00578 {
00579 if (message_cache[i])
00580 {
00581 message = message_cache[i];
00582 message_cache[i] = NULL;
00583 message_cache_count -= 1;
00584 break;
00585 }
00586 ++i;
00587 }
00588 _dbus_assert (message_cache_count >= 0);
00589 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00590 _dbus_assert (message != NULL);
00591
00592 _DBUS_UNLOCK (message_cache);
00593
00594 _dbus_assert (message->refcount.value == 0);
00595 _dbus_assert (message->size_counters == NULL);
00596
00597 return message;
00598 }
00599
00605 static void
00606 dbus_message_cache_or_finalize (DBusMessage *message)
00607 {
00608 dbus_bool_t was_cached;
00609 int i;
00610
00611 _dbus_assert (message->refcount.value == 0);
00612
00613
00614
00615
00616 _dbus_data_slot_list_clear (&message->slot_list);
00617
00618 _dbus_list_foreach (&message->size_counters,
00619 free_size_counter, message);
00620 _dbus_list_clear (&message->size_counters);
00621
00622 was_cached = FALSE;
00623
00624 _DBUS_LOCK (message_cache);
00625
00626 if (!message_cache_shutdown_registered)
00627 {
00628 _dbus_assert (message_cache_count == 0);
00629
00630 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00631 goto out;
00632
00633 i = 0;
00634 while (i < MAX_MESSAGE_CACHE_SIZE)
00635 {
00636 message_cache[i] = NULL;
00637 ++i;
00638 }
00639
00640 message_cache_shutdown_registered = TRUE;
00641 }
00642
00643 _dbus_assert (message_cache_count >= 0);
00644
00645 if ((_dbus_string_get_length (&message->header.data) +
00646 _dbus_string_get_length (&message->body)) >
00647 MAX_MESSAGE_SIZE_TO_CACHE)
00648 goto out;
00649
00650 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00651 goto out;
00652
00653
00654 i = 0;
00655 while (message_cache[i] != NULL)
00656 ++i;
00657
00658 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00659
00660 _dbus_assert (message_cache[i] == NULL);
00661 message_cache[i] = message;
00662 message_cache_count += 1;
00663 was_cached = TRUE;
00664 #ifndef DBUS_DISABLE_CHECKS
00665 message->in_cache = TRUE;
00666 #endif
00667
00668 out:
00669 _DBUS_UNLOCK (message_cache);
00670
00671 _dbus_assert (message->refcount.value == 0);
00672
00673 if (!was_cached)
00674 dbus_message_finalize (message);
00675 }
00676
00677 static DBusMessage*
00678 dbus_message_new_empty_header (void)
00679 {
00680 DBusMessage *message;
00681 dbus_bool_t from_cache;
00682
00683 message = dbus_message_get_cached ();
00684
00685 if (message != NULL)
00686 {
00687 from_cache = TRUE;
00688 }
00689 else
00690 {
00691 from_cache = FALSE;
00692 message = dbus_new (DBusMessage, 1);
00693 if (message == NULL)
00694 return NULL;
00695 #ifndef DBUS_DISABLE_CHECKS
00696 message->generation = _dbus_current_generation;
00697 #endif
00698 }
00699
00700 message->refcount.value = 1;
00701 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00702 message->locked = FALSE;
00703 #ifndef DBUS_DISABLE_CHECKS
00704 message->in_cache = FALSE;
00705 #endif
00706 message->size_counters = NULL;
00707 message->size_counter_delta = 0;
00708 message->changed_stamp = 0;
00709
00710 if (!from_cache)
00711 _dbus_data_slot_list_init (&message->slot_list);
00712
00713 if (from_cache)
00714 {
00715 _dbus_header_reinit (&message->header, message->byte_order);
00716 _dbus_string_set_length (&message->body, 0);
00717 }
00718 else
00719 {
00720 if (!_dbus_header_init (&message->header, message->byte_order))
00721 {
00722 dbus_free (message);
00723 return NULL;
00724 }
00725
00726 if (!_dbus_string_init_preallocated (&message->body, 32))
00727 {
00728 _dbus_header_free (&message->header);
00729 dbus_free (message);
00730 return NULL;
00731 }
00732 }
00733
00734 return message;
00735 }
00736
00745 DBusMessage*
00746 dbus_message_new (int message_type)
00747 {
00748 DBusMessage *message;
00749
00750 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
00751
00752 message = dbus_message_new_empty_header ();
00753 if (message == NULL)
00754 return NULL;
00755
00756 if (!_dbus_header_create (&message->header,
00757 message_type,
00758 NULL, NULL, NULL, NULL, NULL))
00759 {
00760 dbus_message_unref (message);
00761 return NULL;
00762 }
00763
00764 return message;
00765 }
00766
00784 DBusMessage*
00785 dbus_message_new_method_call (const char *destination,
00786 const char *path,
00787 const char *interface,
00788 const char *method)
00789 {
00790 DBusMessage *message;
00791
00792 _dbus_return_val_if_fail (path != NULL, NULL);
00793 _dbus_return_val_if_fail (method != NULL, NULL);
00794 _dbus_return_val_if_fail (destination == NULL ||
00795 _dbus_check_is_valid_bus_name (destination), NULL);
00796 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
00797 _dbus_return_val_if_fail (interface == NULL ||
00798 _dbus_check_is_valid_interface (interface), NULL);
00799 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
00800
00801 message = dbus_message_new_empty_header ();
00802 if (message == NULL)
00803 return NULL;
00804
00805 if (!_dbus_header_create (&message->header,
00806 DBUS_MESSAGE_TYPE_METHOD_CALL,
00807 destination, path, interface, method, NULL))
00808 {
00809 dbus_message_unref (message);
00810 return NULL;
00811 }
00812
00813 return message;
00814 }
00815
00825 DBusMessage*
00826 dbus_message_new_method_return (DBusMessage *method_call)
00827 {
00828 DBusMessage *message;
00829 const char *sender;
00830
00831 _dbus_return_val_if_fail (method_call != NULL, NULL);
00832
00833 sender = dbus_message_get_sender (method_call);
00834
00835
00836
00837 message = dbus_message_new_empty_header ();
00838 if (message == NULL)
00839 return NULL;
00840
00841 if (!_dbus_header_create (&message->header,
00842 DBUS_MESSAGE_TYPE_METHOD_RETURN,
00843 sender, NULL, NULL, NULL, NULL))
00844 {
00845 dbus_message_unref (message);
00846 return NULL;
00847 }
00848
00849 dbus_message_set_no_reply (message, TRUE);
00850
00851 if (!dbus_message_set_reply_serial (message,
00852 dbus_message_get_serial (method_call)))
00853 {
00854 dbus_message_unref (message);
00855 return NULL;
00856 }
00857
00858 return message;
00859 }
00860
00873 DBusMessage*
00874 dbus_message_new_signal (const char *path,
00875 const char *interface,
00876 const char *name)
00877 {
00878 DBusMessage *message;
00879
00880 _dbus_return_val_if_fail (path != NULL, NULL);
00881 _dbus_return_val_if_fail (interface != NULL, NULL);
00882 _dbus_return_val_if_fail (name != NULL, NULL);
00883 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
00884 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
00885 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
00886
00887 message = dbus_message_new_empty_header ();
00888 if (message == NULL)
00889 return NULL;
00890
00891 if (!_dbus_header_create (&message->header,
00892 DBUS_MESSAGE_TYPE_SIGNAL,
00893 NULL, path, interface, name, NULL))
00894 {
00895 dbus_message_unref (message);
00896 return NULL;
00897 }
00898
00899 dbus_message_set_no_reply (message, TRUE);
00900
00901 return message;
00902 }
00903
00913 DBusMessage*
00914 dbus_message_new_error (DBusMessage *reply_to,
00915 const char *error_name,
00916 const char *error_message)
00917 {
00918 DBusMessage *message;
00919 const char *sender;
00920 DBusMessageIter iter;
00921
00922 _dbus_return_val_if_fail (reply_to != NULL, NULL);
00923 _dbus_return_val_if_fail (error_name != NULL, NULL);
00924 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
00925
00926 sender = dbus_message_get_sender (reply_to);
00927
00928
00929
00930
00931
00932 message = dbus_message_new_empty_header ();
00933 if (message == NULL)
00934 return NULL;
00935
00936 if (!_dbus_header_create (&message->header,
00937 DBUS_MESSAGE_TYPE_ERROR,
00938 sender, NULL, NULL, NULL, error_name))
00939 {
00940 dbus_message_unref (message);
00941 return NULL;
00942 }
00943
00944 dbus_message_set_no_reply (message, TRUE);
00945
00946 if (!dbus_message_set_reply_serial (message,
00947 dbus_message_get_serial (reply_to)))
00948 {
00949 dbus_message_unref (message);
00950 return NULL;
00951 }
00952
00953 if (error_message != NULL)
00954 {
00955 dbus_message_iter_init_append (message, &iter);
00956 if (!dbus_message_iter_append_basic (&iter,
00957 DBUS_TYPE_STRING,
00958 &error_message))
00959 {
00960 dbus_message_unref (message);
00961 return NULL;
00962 }
00963 }
00964
00965 return message;
00966 }
00967
00978 DBusMessage*
00979 dbus_message_new_error_printf (DBusMessage *reply_to,
00980 const char *error_name,
00981 const char *error_format,
00982 ...)
00983 {
00984 va_list args;
00985 DBusString str;
00986 DBusMessage *message;
00987
00988 _dbus_return_val_if_fail (reply_to != NULL, NULL);
00989 _dbus_return_val_if_fail (error_name != NULL, NULL);
00990 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
00991
00992 if (!_dbus_string_init (&str))
00993 return NULL;
00994
00995 va_start (args, error_format);
00996
00997 if (_dbus_string_append_printf_valist (&str, error_format, args))
00998 message = dbus_message_new_error (reply_to, error_name,
00999 _dbus_string_get_const_data (&str));
01000 else
01001 message = NULL;
01002
01003 _dbus_string_free (&str);
01004
01005 va_end (args);
01006
01007 return message;
01008 }
01009
01010
01021 DBusMessage *
01022 dbus_message_copy (const DBusMessage *message)
01023 {
01024 DBusMessage *retval;
01025
01026 _dbus_return_val_if_fail (message != NULL, NULL);
01027
01028 retval = dbus_new0 (DBusMessage, 1);
01029 if (retval == NULL)
01030 return NULL;
01031
01032 retval->refcount.value = 1;
01033 retval->byte_order = message->byte_order;
01034 retval->locked = FALSE;
01035 #ifndef DBUS_DISABLE_CHECKS
01036 retval->generation = message->generation;
01037 #endif
01038
01039 if (!_dbus_header_copy (&message->header, &retval->header))
01040 {
01041 dbus_free (retval);
01042 return NULL;
01043 }
01044
01045 if (!_dbus_string_init_preallocated (&retval->body,
01046 _dbus_string_get_length (&message->body)))
01047 {
01048 _dbus_header_free (&retval->header);
01049 dbus_free (retval);
01050 return NULL;
01051 }
01052
01053 if (!_dbus_string_copy (&message->body, 0,
01054 &retval->body, 0))
01055 goto failed_copy;
01056
01057 return retval;
01058
01059 failed_copy:
01060 _dbus_header_free (&retval->header);
01061 _dbus_string_free (&retval->body);
01062 dbus_free (retval);
01063
01064 return NULL;
01065 }
01066
01067
01075 DBusMessage *
01076 dbus_message_ref (DBusMessage *message)
01077 {
01078 dbus_int32_t old_refcount;
01079
01080 _dbus_return_val_if_fail (message != NULL, NULL);
01081 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01082 _dbus_return_val_if_fail (!message->in_cache, NULL);
01083
01084 old_refcount = _dbus_atomic_inc (&message->refcount);
01085 _dbus_assert (old_refcount >= 1);
01086
01087 return message;
01088 }
01089
01096 void
01097 dbus_message_unref (DBusMessage *message)
01098 {
01099 dbus_int32_t old_refcount;
01100
01101 _dbus_return_if_fail (message != NULL);
01102 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01103 _dbus_return_if_fail (!message->in_cache);
01104
01105 old_refcount = _dbus_atomic_dec (&message->refcount);
01106
01107 _dbus_assert (old_refcount >= 0);
01108
01109 if (old_refcount == 1)
01110 {
01111
01112 dbus_message_cache_or_finalize (message);
01113 }
01114 }
01115
01128 int
01129 dbus_message_get_type (DBusMessage *message)
01130 {
01131 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01132
01133 return _dbus_header_get_message_type (&message->header);
01134 }
01135
01188 dbus_bool_t
01189 dbus_message_append_args (DBusMessage *message,
01190 int first_arg_type,
01191 ...)
01192 {
01193 dbus_bool_t retval;
01194 va_list var_args;
01195
01196 _dbus_return_val_if_fail (message != NULL, FALSE);
01197
01198 va_start (var_args, first_arg_type);
01199 retval = dbus_message_append_args_valist (message,
01200 first_arg_type,
01201 var_args);
01202 va_end (var_args);
01203
01204 return retval;
01205 }
01206
01221 dbus_bool_t
01222 dbus_message_append_args_valist (DBusMessage *message,
01223 int first_arg_type,
01224 va_list var_args)
01225 {
01226 int type;
01227 DBusMessageIter iter;
01228
01229 _dbus_return_val_if_fail (message != NULL, FALSE);
01230
01231 type = first_arg_type;
01232
01233 dbus_message_iter_init_append (message, &iter);
01234
01235 while (type != DBUS_TYPE_INVALID)
01236 {
01237 if (dbus_type_is_basic (type))
01238 {
01239 const DBusBasicValue *value;
01240 value = va_arg (var_args, const DBusBasicValue*);
01241
01242 if (!dbus_message_iter_append_basic (&iter,
01243 type,
01244 value))
01245 goto failed;
01246 }
01247 else if (type == DBUS_TYPE_ARRAY)
01248 {
01249 int element_type;
01250 DBusMessageIter array;
01251 char buf[2];
01252
01253 element_type = va_arg (var_args, int);
01254
01255 buf[0] = element_type;
01256 buf[1] = '\0';
01257 if (!dbus_message_iter_open_container (&iter,
01258 DBUS_TYPE_ARRAY,
01259 buf,
01260 &array))
01261 goto failed;
01262
01263 if (dbus_type_is_fixed (element_type))
01264 {
01265 const DBusBasicValue **value;
01266 int n_elements;
01267
01268 value = va_arg (var_args, const DBusBasicValue**);
01269 n_elements = va_arg (var_args, int);
01270
01271 if (!dbus_message_iter_append_fixed_array (&array,
01272 element_type,
01273 value,
01274 n_elements))
01275 goto failed;
01276 }
01277 else if (element_type == DBUS_TYPE_STRING ||
01278 element_type == DBUS_TYPE_SIGNATURE ||
01279 element_type == DBUS_TYPE_OBJECT_PATH)
01280 {
01281 const char ***value_p;
01282 const char **value;
01283 int n_elements;
01284 int i;
01285
01286 value_p = va_arg (var_args, const char***);
01287 n_elements = va_arg (var_args, int);
01288
01289 value = *value_p;
01290
01291 i = 0;
01292 while (i < n_elements)
01293 {
01294 if (!dbus_message_iter_append_basic (&array,
01295 element_type,
01296 &value[i]))
01297 goto failed;
01298 ++i;
01299 }
01300 }
01301 else
01302 {
01303 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01304 _dbus_type_to_string (element_type),
01305 _DBUS_FUNCTION_NAME);
01306 goto failed;
01307 }
01308
01309 if (!dbus_message_iter_close_container (&iter, &array))
01310 goto failed;
01311 }
01312 #ifndef DBUS_DISABLE_CHECKS
01313 else
01314 {
01315 _dbus_warn ("type %s isn't supported yet in %s\n",
01316 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01317 goto failed;
01318 }
01319 #endif
01320
01321 type = va_arg (var_args, int);
01322 }
01323
01324 return TRUE;
01325
01326 failed:
01327 return FALSE;
01328 }
01329
01362 dbus_bool_t
01363 dbus_message_get_args (DBusMessage *message,
01364 DBusError *error,
01365 int first_arg_type,
01366 ...)
01367 {
01368 dbus_bool_t retval;
01369 va_list var_args;
01370
01371 _dbus_return_val_if_fail (message != NULL, FALSE);
01372 _dbus_return_val_if_error_is_set (error, FALSE);
01373
01374 va_start (var_args, first_arg_type);
01375 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01376 va_end (var_args);
01377
01378 return retval;
01379 }
01380
01392 dbus_bool_t
01393 dbus_message_get_args_valist (DBusMessage *message,
01394 DBusError *error,
01395 int first_arg_type,
01396 va_list var_args)
01397 {
01398 DBusMessageIter iter;
01399
01400 _dbus_return_val_if_fail (message != NULL, FALSE);
01401 _dbus_return_val_if_error_is_set (error, FALSE);
01402
01403 dbus_message_iter_init (message, &iter);
01404 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01405 }
01406
01407 static void
01408 _dbus_message_iter_init_common (DBusMessage *message,
01409 DBusMessageRealIter *real,
01410 int iter_type)
01411 {
01412 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01413
01414
01415
01416
01417 ensure_byte_order (message);
01418
01419 real->message = message;
01420 real->changed_stamp = message->changed_stamp;
01421 real->iter_type = iter_type;
01422 real->sig_refcount = 0;
01423 }
01424
01433 dbus_bool_t
01434 dbus_message_iter_init (DBusMessage *message,
01435 DBusMessageIter *iter)
01436 {
01437 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01438 const DBusString *type_str;
01439 int type_pos;
01440
01441 _dbus_return_val_if_fail (message != NULL, FALSE);
01442 _dbus_return_val_if_fail (iter != NULL, FALSE);
01443
01444 get_const_signature (&message->header, &type_str, &type_pos);
01445
01446 _dbus_message_iter_init_common (message, real,
01447 DBUS_MESSAGE_ITER_TYPE_READER);
01448
01449 _dbus_type_reader_init (&real->u.reader,
01450 message->byte_order,
01451 type_str, type_pos,
01452 &message->body,
01453 0);
01454
01455 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01456 }
01457
01458 #ifndef DBUS_DISABLE_CHECKS
01459 static dbus_bool_t
01460 _dbus_message_iter_check (DBusMessageRealIter *iter)
01461 {
01462 if (iter == NULL)
01463 {
01464 _dbus_warn ("dbus message iterator is NULL\n");
01465 return FALSE;
01466 }
01467
01468 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
01469 {
01470 if (iter->u.reader.byte_order != iter->message->byte_order)
01471 {
01472 _dbus_warn ("dbus message changed byte order since iterator was created\n");
01473 return FALSE;
01474 }
01475
01476 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
01477 }
01478 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
01479 {
01480 if (iter->u.writer.byte_order != iter->message->byte_order)
01481 {
01482 _dbus_warn ("dbus message changed byte order since append iterator was created\n");
01483 return FALSE;
01484 }
01485
01486 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
01487 }
01488 else
01489 {
01490 _dbus_warn ("dbus message iterator looks uninitialized or corrupted\n");
01491 return FALSE;
01492 }
01493
01494 if (iter->changed_stamp != iter->message->changed_stamp)
01495 {
01496 _dbus_warn ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
01497 return FALSE;
01498 }
01499
01500 return TRUE;
01501 }
01502 #endif
01503
01511 dbus_bool_t
01512 dbus_message_iter_has_next (DBusMessageIter *iter)
01513 {
01514 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01515
01516 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01517 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01518
01519 return _dbus_type_reader_has_next (&real->u.reader);
01520 }
01521
01530 dbus_bool_t
01531 dbus_message_iter_next (DBusMessageIter *iter)
01532 {
01533 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01534
01535 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01536 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01537
01538 return _dbus_type_reader_next (&real->u.reader);
01539 }
01540
01555 int
01556 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01557 {
01558 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01559
01560 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01561 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01562
01563 return _dbus_type_reader_get_current_type (&real->u.reader);
01564 }
01565
01574 int
01575 dbus_message_iter_get_element_type (DBusMessageIter *iter)
01576 {
01577 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01578
01579 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01580 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
01581 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
01582
01583 return _dbus_type_reader_get_element_type (&real->u.reader);
01584 }
01585
01601 void
01602 dbus_message_iter_recurse (DBusMessageIter *iter,
01603 DBusMessageIter *sub)
01604 {
01605 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01606 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01607
01608 _dbus_return_if_fail (_dbus_message_iter_check (real));
01609 _dbus_return_if_fail (sub != NULL);
01610
01611 *real_sub = *real;
01612 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01613 }
01614
01624 char *
01625 dbus_message_iter_get_signature (DBusMessageIter *iter)
01626 {
01627 const DBusString *sig;
01628 DBusString retstr;
01629 char *ret;
01630 int start, len;
01631 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01632
01633 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01634
01635 if (!_dbus_string_init (&retstr))
01636 return NULL;
01637
01638 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01639 &start, &len);
01640 if (!_dbus_string_append_len (&retstr,
01641 _dbus_string_get_const_data (sig) + start,
01642 len))
01643 return NULL;
01644 if (!_dbus_string_steal_data (&retstr, &ret))
01645 return NULL;
01646 _dbus_string_free (&retstr);
01647 return ret;
01648 }
01649
01685 void
01686 dbus_message_iter_get_basic (DBusMessageIter *iter,
01687 void *value)
01688 {
01689 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01690
01691 _dbus_return_if_fail (_dbus_message_iter_check (real));
01692 _dbus_return_if_fail (value != NULL);
01693
01694 _dbus_type_reader_read_basic (&real->u.reader,
01695 value);
01696 }
01697
01704 int
01705 dbus_message_iter_get_array_len (DBusMessageIter *iter)
01706 {
01707 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01708
01709 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
01710
01711 return _dbus_type_reader_get_array_length (&real->u.reader);
01712 }
01713
01731 void
01732 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
01733 void *value,
01734 int *n_elements)
01735 {
01736 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01737
01738 _dbus_return_if_fail (_dbus_message_iter_check (real));
01739 _dbus_return_if_fail (value != NULL);
01740 _dbus_return_if_fail (dbus_type_is_fixed (_dbus_type_reader_get_current_type (&real->u.reader)));
01741
01742 _dbus_type_reader_read_fixed_multi (&real->u.reader,
01743 value, n_elements);
01744 }
01745
01759 dbus_bool_t
01760 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
01761 DBusError *error,
01762 int first_arg_type,
01763 va_list var_args)
01764 {
01765 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01766 int spec_type, msg_type, i;
01767 dbus_bool_t retval;
01768
01769 _dbus_assert (_dbus_message_iter_check (real));
01770
01771 retval = FALSE;
01772
01773 spec_type = first_arg_type;
01774 i = 0;
01775
01776 while (spec_type != DBUS_TYPE_INVALID)
01777 {
01778 msg_type = dbus_message_iter_get_arg_type (iter);
01779
01780 if (msg_type != spec_type)
01781 {
01782 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01783 "Argument %d is specified to be of type \"%s\", but "
01784 "is actually of type \"%s\"\n", i,
01785 _dbus_type_to_string (spec_type),
01786 _dbus_type_to_string (msg_type));
01787
01788 goto out;
01789 }
01790
01791 if (dbus_type_is_basic (spec_type))
01792 {
01793 DBusBasicValue *ptr;
01794
01795 ptr = va_arg (var_args, DBusBasicValue*);
01796
01797 _dbus_assert (ptr != NULL);
01798
01799 _dbus_type_reader_read_basic (&real->u.reader,
01800 ptr);
01801 }
01802 else if (spec_type == DBUS_TYPE_ARRAY)
01803 {
01804 int element_type;
01805 int spec_element_type;
01806 const DBusBasicValue **ptr;
01807 int *n_elements_p;
01808 DBusTypeReader array;
01809
01810 spec_element_type = va_arg (var_args, int);
01811 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
01812
01813 if (spec_element_type != element_type)
01814 {
01815 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01816 "Argument %d is specified to be an array of \"%s\", but "
01817 "is actually an array of \"%s\"\n",
01818 i,
01819 _dbus_type_to_string (spec_element_type),
01820 _dbus_type_to_string (element_type));
01821
01822 goto out;
01823 }
01824
01825 if (dbus_type_is_fixed (spec_element_type))
01826 {
01827 ptr = va_arg (var_args, const DBusBasicValue**);
01828 n_elements_p = va_arg (var_args, int*);
01829
01830 _dbus_assert (ptr != NULL);
01831 _dbus_assert (n_elements_p != NULL);
01832
01833 _dbus_type_reader_recurse (&real->u.reader, &array);
01834
01835 _dbus_type_reader_read_fixed_multi (&array,
01836 ptr, n_elements_p);
01837 }
01838 else if (spec_element_type == DBUS_TYPE_STRING ||
01839 spec_element_type == DBUS_TYPE_SIGNATURE ||
01840 spec_element_type == DBUS_TYPE_OBJECT_PATH)
01841 {
01842 char ***str_array_p;
01843 int n_elements;
01844 char **str_array;
01845
01846 str_array_p = va_arg (var_args, char***);
01847 n_elements_p = va_arg (var_args, int*);
01848
01849 _dbus_assert (str_array_p != NULL);
01850 _dbus_assert (n_elements_p != NULL);
01851
01852
01853 _dbus_type_reader_recurse (&real->u.reader, &array);
01854
01855 n_elements = 0;
01856 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
01857 {
01858 ++n_elements;
01859 _dbus_type_reader_next (&array);
01860 }
01861
01862 str_array = dbus_new0 (char*, n_elements + 1);
01863 if (str_array == NULL)
01864 {
01865 _DBUS_SET_OOM (error);
01866 goto out;
01867 }
01868
01869
01870 _dbus_type_reader_recurse (&real->u.reader, &array);
01871
01872 i = 0;
01873 while (i < n_elements)
01874 {
01875 const char *s;
01876 _dbus_type_reader_read_basic (&array,
01877 &s);
01878
01879 str_array[i] = _dbus_strdup (s);
01880 if (str_array[i] == NULL)
01881 {
01882 dbus_free_string_array (str_array);
01883 _DBUS_SET_OOM (error);
01884 goto out;
01885 }
01886
01887 ++i;
01888
01889 if (!_dbus_type_reader_next (&array))
01890 _dbus_assert (i == n_elements);
01891 }
01892
01893 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
01894 _dbus_assert (i == n_elements);
01895 _dbus_assert (str_array[i] == NULL);
01896
01897 *str_array_p = str_array;
01898 *n_elements_p = n_elements;
01899 }
01900 #ifndef DBUS_DISABLE_CHECKS
01901 else
01902 {
01903 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
01904 _DBUS_FUNCTION_NAME);
01905 goto out;
01906 }
01907 #endif
01908 }
01909 #ifndef DBUS_DISABLE_CHECKS
01910 else
01911 {
01912 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
01913 _DBUS_FUNCTION_NAME);
01914 goto out;
01915 }
01916 #endif
01917
01918 spec_type = va_arg (var_args, int);
01919 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
01920 {
01921 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
01922 "Message has only %d arguments, but more were expected", i);
01923 goto out;
01924 }
01925
01926 i++;
01927 }
01928
01929 retval = TRUE;
01930
01931 out:
01932
01933 return retval;
01934 }
01935
01947 void
01948 dbus_message_iter_init_append (DBusMessage *message,
01949 DBusMessageIter *iter)
01950 {
01951 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01952
01953 _dbus_return_if_fail (message != NULL);
01954 _dbus_return_if_fail (iter != NULL);
01955
01956 _dbus_message_iter_init_common (message, real,
01957 DBUS_MESSAGE_ITER_TYPE_WRITER);
01958
01959
01960
01961
01962
01963 _dbus_type_writer_init_types_delayed (&real->u.writer,
01964 message->byte_order,
01965 &message->body,
01966 _dbus_string_get_length (&message->body));
01967 }
01968
01977 static dbus_bool_t
01978 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
01979 {
01980 DBusString *str;
01981 const DBusString *current_sig;
01982 int current_sig_pos;
01983
01984 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
01985
01986 if (real->u.writer.type_str != NULL)
01987 {
01988 _dbus_assert (real->sig_refcount > 0);
01989 real->sig_refcount += 1;
01990 return TRUE;
01991 }
01992
01993 str = dbus_new (DBusString, 1);
01994 if (str == NULL)
01995 return FALSE;
01996
01997 if (!_dbus_header_get_field_raw (&real->message->header,
01998 DBUS_HEADER_FIELD_SIGNATURE,
01999 ¤t_sig, ¤t_sig_pos))
02000 current_sig = NULL;
02001
02002 if (current_sig)
02003 {
02004 int current_len;
02005
02006 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02007 current_sig_pos += 1;
02008
02009 if (!_dbus_string_init_preallocated (str, current_len + 4))
02010 {
02011 dbus_free (str);
02012 return FALSE;
02013 }
02014
02015 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02016 str, 0))
02017 {
02018 _dbus_string_free (str);
02019 dbus_free (str);
02020 return FALSE;
02021 }
02022 }
02023 else
02024 {
02025 if (!_dbus_string_init_preallocated (str, 4))
02026 {
02027 dbus_free (str);
02028 return FALSE;
02029 }
02030 }
02031
02032 real->sig_refcount = 1;
02033
02034 _dbus_type_writer_add_types (&real->u.writer,
02035 str, _dbus_string_get_length (str));
02036 return TRUE;
02037 }
02038
02048 static dbus_bool_t
02049 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02050 {
02051 DBusString *str;
02052 const char *v_STRING;
02053 dbus_bool_t retval;
02054
02055 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02056 _dbus_assert (real->u.writer.type_str != NULL);
02057 _dbus_assert (real->sig_refcount > 0);
02058
02059 real->sig_refcount -= 1;
02060
02061 if (real->sig_refcount > 0)
02062 return TRUE;
02063 _dbus_assert (real->sig_refcount == 0);
02064
02065 retval = TRUE;
02066
02067 str = real->u.writer.type_str;
02068
02069 v_STRING = _dbus_string_get_const_data (str);
02070 if (!_dbus_header_set_field_basic (&real->message->header,
02071 DBUS_HEADER_FIELD_SIGNATURE,
02072 DBUS_TYPE_SIGNATURE,
02073 &v_STRING))
02074 retval = FALSE;
02075
02076 _dbus_type_writer_remove_types (&real->u.writer);
02077 _dbus_string_free (str);
02078 dbus_free (str);
02079
02080 return retval;
02081 }
02082
02083 #ifndef DBUS_DISABLE_CHECKS
02084 static dbus_bool_t
02085 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02086 {
02087 if (!_dbus_message_iter_check (iter))
02088 return FALSE;
02089
02090 if (iter->message->locked)
02091 {
02092 _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02093 return FALSE;
02094 }
02095
02096 return TRUE;
02097 }
02098 #endif
02099
02115 dbus_bool_t
02116 dbus_message_iter_append_basic (DBusMessageIter *iter,
02117 int type,
02118 const void *value)
02119 {
02120 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02121 dbus_bool_t ret;
02122
02123 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02124 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02125 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02126 _dbus_return_val_if_fail (value != NULL, FALSE);
02127
02128 if (!_dbus_message_iter_open_signature (real))
02129 return FALSE;
02130
02131 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02132
02133 if (!_dbus_message_iter_close_signature (real))
02134 ret = FALSE;
02135
02136 return ret;
02137 }
02138
02174 dbus_bool_t
02175 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02176 int element_type,
02177 const void *value,
02178 int n_elements)
02179 {
02180 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02181 dbus_bool_t ret;
02182
02183 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02184 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02185 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02186 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02187 _dbus_return_val_if_fail (value != NULL, FALSE);
02188 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02189 _dbus_return_val_if_fail (n_elements <=
02190 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02191 FALSE);
02192
02193 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02194
02195 return ret;
02196 }
02197
02219 dbus_bool_t
02220 dbus_message_iter_open_container (DBusMessageIter *iter,
02221 int type,
02222 const char *contained_signature,
02223 DBusMessageIter *sub)
02224 {
02225 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02226 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02227 DBusString contained_str;
02228
02229 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02230 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02231 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02232 _dbus_return_val_if_fail (sub != NULL, FALSE);
02233 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02234 contained_signature == NULL) ||
02235 (type == DBUS_TYPE_DICT_ENTRY &&
02236 contained_signature == NULL) ||
02237 contained_signature != NULL, FALSE);
02238
02239 #if 0
02240
02241
02242
02243
02244 _dbus_return_val_if_fail (contained_signature == NULL ||
02245 _dbus_check_is_valid_signature (contained_signature));
02246 #endif
02247
02248 if (!_dbus_message_iter_open_signature (real))
02249 return FALSE;
02250
02251 *real_sub = *real;
02252
02253 if (contained_signature != NULL)
02254 {
02255 _dbus_string_init_const (&contained_str, contained_signature);
02256
02257 return _dbus_type_writer_recurse (&real->u.writer,
02258 type,
02259 &contained_str, 0,
02260 &real_sub->u.writer);
02261 }
02262 else
02263 {
02264 return _dbus_type_writer_recurse (&real->u.writer,
02265 type,
02266 NULL, 0,
02267 &real_sub->u.writer);
02268 }
02269 }
02270
02271
02285 dbus_bool_t
02286 dbus_message_iter_close_container (DBusMessageIter *iter,
02287 DBusMessageIter *sub)
02288 {
02289 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02290 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02291 dbus_bool_t ret;
02292
02293 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02294 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02295 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02296 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02297
02298 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02299 &real_sub->u.writer);
02300
02301 if (!_dbus_message_iter_close_signature (real))
02302 ret = FALSE;
02303
02304 return ret;
02305 }
02306
02318 void
02319 dbus_message_set_no_reply (DBusMessage *message,
02320 dbus_bool_t no_reply)
02321 {
02322 _dbus_return_if_fail (message != NULL);
02323 _dbus_return_if_fail (!message->locked);
02324
02325 _dbus_header_toggle_flag (&message->header,
02326 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02327 no_reply);
02328 }
02329
02337 dbus_bool_t
02338 dbus_message_get_no_reply (DBusMessage *message)
02339 {
02340 _dbus_return_val_if_fail (message != NULL, FALSE);
02341
02342 return _dbus_header_get_flag (&message->header,
02343 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02344 }
02345
02356 void
02357 dbus_message_set_auto_start (DBusMessage *message,
02358 dbus_bool_t auto_start)
02359 {
02360 _dbus_return_if_fail (message != NULL);
02361 _dbus_return_if_fail (!message->locked);
02362
02363 _dbus_header_toggle_flag (&message->header,
02364 DBUS_HEADER_FLAG_NO_AUTO_START,
02365 !auto_start);
02366 }
02367
02375 dbus_bool_t
02376 dbus_message_get_auto_start (DBusMessage *message)
02377 {
02378 _dbus_return_val_if_fail (message != NULL, FALSE);
02379
02380 return !_dbus_header_get_flag (&message->header,
02381 DBUS_HEADER_FLAG_NO_AUTO_START);
02382 }
02383
02384
02394 dbus_bool_t
02395 dbus_message_set_path (DBusMessage *message,
02396 const char *object_path)
02397 {
02398 _dbus_return_val_if_fail (message != NULL, FALSE);
02399 _dbus_return_val_if_fail (!message->locked, FALSE);
02400 _dbus_return_val_if_fail (object_path == NULL ||
02401 _dbus_check_is_valid_path (object_path),
02402 FALSE);
02403
02404 return set_or_delete_string_field (message,
02405 DBUS_HEADER_FIELD_PATH,
02406 DBUS_TYPE_OBJECT_PATH,
02407 object_path);
02408 }
02409
02418 const char*
02419 dbus_message_get_path (DBusMessage *message)
02420 {
02421 const char *v;
02422
02423 _dbus_return_val_if_fail (message != NULL, NULL);
02424
02425 v = NULL;
02426 _dbus_header_get_field_basic (&message->header,
02427 DBUS_HEADER_FIELD_PATH,
02428 DBUS_TYPE_OBJECT_PATH,
02429 &v);
02430 return v;
02431 }
02432
02439 dbus_bool_t
02440 dbus_message_has_path (DBusMessage *message,
02441 const char *path)
02442 {
02443 const char *msg_path;
02444 msg_path = dbus_message_get_path (message);
02445
02446 if (msg_path == NULL)
02447 {
02448 if (path == NULL)
02449 return TRUE;
02450 else
02451 return FALSE;
02452 }
02453
02454 if (path == NULL)
02455 return FALSE;
02456
02457 if (strcmp (msg_path, path) == 0)
02458 return TRUE;
02459
02460 return FALSE;
02461 }
02462
02481 dbus_bool_t
02482 dbus_message_get_path_decomposed (DBusMessage *message,
02483 char ***path)
02484 {
02485 const char *v;
02486
02487 _dbus_return_val_if_fail (message != NULL, FALSE);
02488 _dbus_return_val_if_fail (path != NULL, FALSE);
02489
02490 *path = NULL;
02491
02492 v = dbus_message_get_path (message);
02493 if (v != NULL)
02494 {
02495 if (!_dbus_decompose_path (v, strlen (v),
02496 path, NULL))
02497 return FALSE;
02498 }
02499 return TRUE;
02500 }
02501
02512 dbus_bool_t
02513 dbus_message_set_interface (DBusMessage *message,
02514 const char *interface)
02515 {
02516 _dbus_return_val_if_fail (message != NULL, FALSE);
02517 _dbus_return_val_if_fail (!message->locked, FALSE);
02518 _dbus_return_val_if_fail (interface == NULL ||
02519 _dbus_check_is_valid_interface (interface),
02520 FALSE);
02521
02522 return set_or_delete_string_field (message,
02523 DBUS_HEADER_FIELD_INTERFACE,
02524 DBUS_TYPE_STRING,
02525 interface);
02526 }
02527
02538 const char*
02539 dbus_message_get_interface (DBusMessage *message)
02540 {
02541 const char *v;
02542
02543 _dbus_return_val_if_fail (message != NULL, NULL);
02544
02545 v = NULL;
02546 _dbus_header_get_field_basic (&message->header,
02547 DBUS_HEADER_FIELD_INTERFACE,
02548 DBUS_TYPE_STRING,
02549 &v);
02550 return v;
02551 }
02552
02559 dbus_bool_t
02560 dbus_message_has_interface (DBusMessage *message,
02561 const char *interface)
02562 {
02563 const char *msg_interface;
02564 msg_interface = dbus_message_get_interface (message);
02565
02566 if (msg_interface == NULL)
02567 {
02568 if (interface == NULL)
02569 return TRUE;
02570 else
02571 return FALSE;
02572 }
02573
02574 if (interface == NULL)
02575 return FALSE;
02576
02577 if (strcmp (msg_interface, interface) == 0)
02578 return TRUE;
02579
02580 return FALSE;
02581
02582 }
02583
02594 dbus_bool_t
02595 dbus_message_set_member (DBusMessage *message,
02596 const char *member)
02597 {
02598 _dbus_return_val_if_fail (message != NULL, FALSE);
02599 _dbus_return_val_if_fail (!message->locked, FALSE);
02600 _dbus_return_val_if_fail (member == NULL ||
02601 _dbus_check_is_valid_member (member),
02602 FALSE);
02603
02604 return set_or_delete_string_field (message,
02605 DBUS_HEADER_FIELD_MEMBER,
02606 DBUS_TYPE_STRING,
02607 member);
02608 }
02609
02618 const char*
02619 dbus_message_get_member (DBusMessage *message)
02620 {
02621 const char *v;
02622
02623 _dbus_return_val_if_fail (message != NULL, NULL);
02624
02625 v = NULL;
02626 _dbus_header_get_field_basic (&message->header,
02627 DBUS_HEADER_FIELD_MEMBER,
02628 DBUS_TYPE_STRING,
02629 &v);
02630 return v;
02631 }
02632
02639 dbus_bool_t
02640 dbus_message_has_member (DBusMessage *message,
02641 const char *member)
02642 {
02643 const char *msg_member;
02644 msg_member = dbus_message_get_member (message);
02645
02646 if (msg_member == NULL)
02647 {
02648 if (member == NULL)
02649 return TRUE;
02650 else
02651 return FALSE;
02652 }
02653
02654 if (member == NULL)
02655 return FALSE;
02656
02657 if (strcmp (msg_member, member) == 0)
02658 return TRUE;
02659
02660 return FALSE;
02661
02662 }
02663
02672 dbus_bool_t
02673 dbus_message_set_error_name (DBusMessage *message,
02674 const char *error_name)
02675 {
02676 _dbus_return_val_if_fail (message != NULL, FALSE);
02677 _dbus_return_val_if_fail (!message->locked, FALSE);
02678 _dbus_return_val_if_fail (error_name == NULL ||
02679 _dbus_check_is_valid_error_name (error_name),
02680 FALSE);
02681
02682 return set_or_delete_string_field (message,
02683 DBUS_HEADER_FIELD_ERROR_NAME,
02684 DBUS_TYPE_STRING,
02685 error_name);
02686 }
02687
02695 const char*
02696 dbus_message_get_error_name (DBusMessage *message)
02697 {
02698 const char *v;
02699
02700 _dbus_return_val_if_fail (message != NULL, NULL);
02701
02702 v = NULL;
02703 _dbus_header_get_field_basic (&message->header,
02704 DBUS_HEADER_FIELD_ERROR_NAME,
02705 DBUS_TYPE_STRING,
02706 &v);
02707 return v;
02708 }
02709
02720 dbus_bool_t
02721 dbus_message_set_destination (DBusMessage *message,
02722 const char *destination)
02723 {
02724 _dbus_return_val_if_fail (message != NULL, FALSE);
02725 _dbus_return_val_if_fail (!message->locked, FALSE);
02726 _dbus_return_val_if_fail (destination == NULL ||
02727 _dbus_check_is_valid_bus_name (destination),
02728 FALSE);
02729
02730 return set_or_delete_string_field (message,
02731 DBUS_HEADER_FIELD_DESTINATION,
02732 DBUS_TYPE_STRING,
02733 destination);
02734 }
02735
02742 const char*
02743 dbus_message_get_destination (DBusMessage *message)
02744 {
02745 const char *v;
02746
02747 _dbus_return_val_if_fail (message != NULL, NULL);
02748
02749 v = NULL;
02750 _dbus_header_get_field_basic (&message->header,
02751 DBUS_HEADER_FIELD_DESTINATION,
02752 DBUS_TYPE_STRING,
02753 &v);
02754 return v;
02755 }
02756
02764 dbus_bool_t
02765 dbus_message_set_sender (DBusMessage *message,
02766 const char *sender)
02767 {
02768 _dbus_return_val_if_fail (message != NULL, FALSE);
02769 _dbus_return_val_if_fail (!message->locked, FALSE);
02770 _dbus_return_val_if_fail (sender == NULL ||
02771 _dbus_check_is_valid_bus_name (sender),
02772 FALSE);
02773
02774 return set_or_delete_string_field (message,
02775 DBUS_HEADER_FIELD_SENDER,
02776 DBUS_TYPE_STRING,
02777 sender);
02778 }
02779
02788 const char*
02789 dbus_message_get_sender (DBusMessage *message)
02790 {
02791 const char *v;
02792
02793 _dbus_return_val_if_fail (message != NULL, NULL);
02794
02795 v = NULL;
02796 _dbus_header_get_field_basic (&message->header,
02797 DBUS_HEADER_FIELD_SENDER,
02798 DBUS_TYPE_STRING,
02799 &v);
02800 return v;
02801 }
02802
02818 const char*
02819 dbus_message_get_signature (DBusMessage *message)
02820 {
02821 const DBusString *type_str;
02822 int type_pos;
02823
02824 _dbus_return_val_if_fail (message != NULL, NULL);
02825
02826 get_const_signature (&message->header, &type_str, &type_pos);
02827
02828 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
02829 }
02830
02831 static dbus_bool_t
02832 _dbus_message_has_type_interface_member (DBusMessage *message,
02833 int type,
02834 const char *interface,
02835 const char *member)
02836 {
02837 const char *n;
02838
02839 _dbus_assert (message != NULL);
02840 _dbus_assert (interface != NULL);
02841 _dbus_assert (member != NULL);
02842
02843 if (dbus_message_get_type (message) != type)
02844 return FALSE;
02845
02846
02847
02848
02849
02850 n = dbus_message_get_member (message);
02851
02852 if (n && strcmp (n, member) == 0)
02853 {
02854 n = dbus_message_get_interface (message);
02855
02856 if (n == NULL || strcmp (n, interface) == 0)
02857 return TRUE;
02858 }
02859
02860 return FALSE;
02861 }
02862
02877 dbus_bool_t
02878 dbus_message_is_method_call (DBusMessage *message,
02879 const char *interface,
02880 const char *method)
02881 {
02882 _dbus_return_val_if_fail (message != NULL, FALSE);
02883 _dbus_return_val_if_fail (interface != NULL, FALSE);
02884 _dbus_return_val_if_fail (method != NULL, FALSE);
02885
02886
02887
02888
02889 return _dbus_message_has_type_interface_member (message,
02890 DBUS_MESSAGE_TYPE_METHOD_CALL,
02891 interface, method);
02892 }
02893
02907 dbus_bool_t
02908 dbus_message_is_signal (DBusMessage *message,
02909 const char *interface,
02910 const char *signal_name)
02911 {
02912 _dbus_return_val_if_fail (message != NULL, FALSE);
02913 _dbus_return_val_if_fail (interface != NULL, FALSE);
02914 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
02915
02916
02917
02918
02919 return _dbus_message_has_type_interface_member (message,
02920 DBUS_MESSAGE_TYPE_SIGNAL,
02921 interface, signal_name);
02922 }
02923
02934 dbus_bool_t
02935 dbus_message_is_error (DBusMessage *message,
02936 const char *error_name)
02937 {
02938 const char *n;
02939
02940 _dbus_return_val_if_fail (message != NULL, FALSE);
02941 _dbus_return_val_if_fail (error_name != NULL, FALSE);
02942
02943
02944
02945
02946 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
02947 return FALSE;
02948
02949 n = dbus_message_get_error_name (message);
02950
02951 if (n && strcmp (n, error_name) == 0)
02952 return TRUE;
02953 else
02954 return FALSE;
02955 }
02956
02967 dbus_bool_t
02968 dbus_message_has_destination (DBusMessage *message,
02969 const char *name)
02970 {
02971 const char *s;
02972
02973 _dbus_return_val_if_fail (message != NULL, FALSE);
02974 _dbus_return_val_if_fail (name != NULL, FALSE);
02975
02976
02977
02978
02979 s = dbus_message_get_destination (message);
02980
02981 if (s && strcmp (s, name) == 0)
02982 return TRUE;
02983 else
02984 return FALSE;
02985 }
02986
03002 dbus_bool_t
03003 dbus_message_has_sender (DBusMessage *message,
03004 const char *name)
03005 {
03006 const char *s;
03007
03008 _dbus_return_val_if_fail (message != NULL, FALSE);
03009 _dbus_return_val_if_fail (name != NULL, FALSE);
03010
03011
03012
03013
03014 s = dbus_message_get_sender (message);
03015
03016 if (s && strcmp (s, name) == 0)
03017 return TRUE;
03018 else
03019 return FALSE;
03020 }
03021
03031 dbus_bool_t
03032 dbus_message_has_signature (DBusMessage *message,
03033 const char *signature)
03034 {
03035 const char *s;
03036
03037 _dbus_return_val_if_fail (message != NULL, FALSE);
03038 _dbus_return_val_if_fail (signature != NULL, FALSE);
03039
03040
03041
03042
03043 s = dbus_message_get_signature (message);
03044
03045 if (s && strcmp (s, signature) == 0)
03046 return TRUE;
03047 else
03048 return FALSE;
03049 }
03050
03073 dbus_bool_t
03074 dbus_set_error_from_message (DBusError *error,
03075 DBusMessage *message)
03076 {
03077 const char *str;
03078
03079 _dbus_return_val_if_fail (message != NULL, FALSE);
03080 _dbus_return_val_if_error_is_set (error, FALSE);
03081
03082 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03083 return FALSE;
03084
03085 str = NULL;
03086 dbus_message_get_args (message, NULL,
03087 DBUS_TYPE_STRING, &str,
03088 DBUS_TYPE_INVALID);
03089
03090 dbus_set_error (error, dbus_message_get_error_name (message),
03091 str ? "%s" : NULL, str);
03092
03093 return TRUE;
03094 }
03095
03114 #define INITIAL_LOADER_DATA_LEN 32
03115
03122 DBusMessageLoader*
03123 _dbus_message_loader_new (void)
03124 {
03125 DBusMessageLoader *loader;
03126
03127 loader = dbus_new0 (DBusMessageLoader, 1);
03128 if (loader == NULL)
03129 return NULL;
03130
03131 loader->refcount = 1;
03132
03133 loader->corrupted = FALSE;
03134 loader->corruption_reason = DBUS_VALID;
03135
03136
03137 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03138
03139 if (!_dbus_string_init (&loader->data))
03140 {
03141 dbus_free (loader);
03142 return NULL;
03143 }
03144
03145
03146 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03147 _dbus_string_set_length (&loader->data, 0);
03148
03149 return loader;
03150 }
03151
03158 DBusMessageLoader *
03159 _dbus_message_loader_ref (DBusMessageLoader *loader)
03160 {
03161 loader->refcount += 1;
03162
03163 return loader;
03164 }
03165
03172 void
03173 _dbus_message_loader_unref (DBusMessageLoader *loader)
03174 {
03175 loader->refcount -= 1;
03176 if (loader->refcount == 0)
03177 {
03178 _dbus_list_foreach (&loader->messages,
03179 (DBusForeachFunction) dbus_message_unref,
03180 NULL);
03181 _dbus_list_clear (&loader->messages);
03182 _dbus_string_free (&loader->data);
03183 dbus_free (loader);
03184 }
03185 }
03186
03205 void
03206 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03207 DBusString **buffer)
03208 {
03209 _dbus_assert (!loader->buffer_outstanding);
03210
03211 *buffer = &loader->data;
03212
03213 loader->buffer_outstanding = TRUE;
03214 }
03215
03226 void
03227 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03228 DBusString *buffer,
03229 int bytes_read)
03230 {
03231 _dbus_assert (loader->buffer_outstanding);
03232 _dbus_assert (buffer == &loader->data);
03233
03234 loader->buffer_outstanding = FALSE;
03235 }
03236
03237
03238
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 static dbus_bool_t
03264 load_message (DBusMessageLoader *loader,
03265 DBusMessage *message,
03266 int byte_order,
03267 int fields_array_len,
03268 int header_len,
03269 int body_len)
03270 {
03271 dbus_bool_t oom;
03272 DBusValidity validity;
03273 const DBusString *type_str;
03274 int type_pos;
03275 DBusValidationMode mode;
03276
03277 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03278
03279 oom = FALSE;
03280
03281 #if 0
03282 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03283 #endif
03284
03285
03286 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03287 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03288
03289 if (!_dbus_header_load (&message->header,
03290 mode,
03291 &validity,
03292 byte_order,
03293 fields_array_len,
03294 header_len,
03295 body_len,
03296 &loader->data, 0,
03297 _dbus_string_get_length (&loader->data)))
03298 {
03299 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03300
03301
03302
03303 _dbus_assert (validity != DBUS_VALID);
03304
03305 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03306 oom = TRUE;
03307 else
03308 {
03309 loader->corrupted = TRUE;
03310 loader->corruption_reason = validity;
03311 }
03312 goto failed;
03313 }
03314
03315 _dbus_assert (validity == DBUS_VALID);
03316
03317 message->byte_order = byte_order;
03318
03319
03320 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03321 {
03322 get_const_signature (&message->header, &type_str, &type_pos);
03323
03324
03325
03326
03327 validity = _dbus_validate_body_with_reason (type_str,
03328 type_pos,
03329 byte_order,
03330 NULL,
03331 &loader->data,
03332 header_len,
03333 body_len);
03334 if (validity != DBUS_VALID)
03335 {
03336 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03337
03338 loader->corrupted = TRUE;
03339 loader->corruption_reason = validity;
03340
03341 goto failed;
03342 }
03343 }
03344
03345
03346
03347 if (!_dbus_list_append (&loader->messages, message))
03348 {
03349 _dbus_verbose ("Failed to append new message to loader queue\n");
03350 oom = TRUE;
03351 goto failed;
03352 }
03353
03354 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03355 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03356 (header_len + body_len));
03357
03358 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03359 {
03360 _dbus_verbose ("Failed to move body into new message\n");
03361 oom = TRUE;
03362 goto failed;
03363 }
03364
03365 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03366
03367 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03368 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03369
03370 _dbus_verbose ("Loaded message %p\n", message);
03371
03372 _dbus_assert (!oom);
03373 _dbus_assert (!loader->corrupted);
03374 _dbus_assert (loader->messages != NULL);
03375 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03376
03377 return TRUE;
03378
03379 failed:
03380
03381
03382
03383
03384 _dbus_list_remove_last (&loader->messages, message);
03385
03386 if (oom)
03387 _dbus_assert (!loader->corrupted);
03388 else
03389 _dbus_assert (loader->corrupted);
03390
03391 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03392
03393 return FALSE;
03394 }
03395
03410 dbus_bool_t
03411 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03412 {
03413 while (!loader->corrupted &&
03414 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03415 {
03416 DBusValidity validity;
03417 int byte_order, fields_array_len, header_len, body_len;
03418
03419 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03420 &validity,
03421 &byte_order,
03422 &fields_array_len,
03423 &header_len,
03424 &body_len,
03425 &loader->data, 0,
03426 _dbus_string_get_length (&loader->data)))
03427 {
03428 DBusMessage *message;
03429
03430 _dbus_assert (validity == DBUS_VALID);
03431
03432 message = dbus_message_new_empty_header ();
03433 if (message == NULL)
03434 return FALSE;
03435
03436 if (!load_message (loader, message,
03437 byte_order, fields_array_len,
03438 header_len, body_len))
03439 {
03440 dbus_message_unref (message);
03441
03442
03443
03444 return loader->corrupted;
03445 }
03446
03447 _dbus_assert (loader->messages != NULL);
03448 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03449 }
03450 else
03451 {
03452 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03453 validity);
03454 if (validity != DBUS_VALID)
03455 {
03456 loader->corrupted = TRUE;
03457 loader->corruption_reason = validity;
03458 }
03459 return TRUE;
03460 }
03461 }
03462
03463 return TRUE;
03464 }
03465
03473 DBusMessage*
03474 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03475 {
03476 if (loader->messages)
03477 return loader->messages->data;
03478 else
03479 return NULL;
03480 }
03481
03490 DBusMessage*
03491 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03492 {
03493 return _dbus_list_pop_first (&loader->messages);
03494 }
03495
03504 DBusList*
03505 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03506 {
03507 return _dbus_list_pop_first_link (&loader->messages);
03508 }
03509
03516 void
03517 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03518 DBusList *link)
03519 {
03520 _dbus_list_prepend_link (&loader->messages, link);
03521 }
03522
03532 dbus_bool_t
03533 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03534 {
03535 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03536 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03537 return loader->corrupted;
03538 }
03539
03546 void
03547 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03548 long size)
03549 {
03550 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03551 {
03552 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03553 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03554 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03555 }
03556 loader->max_message_size = size;
03557 }
03558
03565 long
03566 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03567 {
03568 return loader->max_message_size;
03569 }
03570
03571 static DBusDataSlotAllocator slot_allocator;
03572 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03573
03588 dbus_bool_t
03589 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03590 {
03591 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03592 _DBUS_LOCK_NAME (message_slots),
03593 slot_p);
03594 }
03595
03607 void
03608 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03609 {
03610 _dbus_return_if_fail (*slot_p >= 0);
03611
03612 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03613 }
03614
03628 dbus_bool_t
03629 dbus_message_set_data (DBusMessage *message,
03630 dbus_int32_t slot,
03631 void *data,
03632 DBusFreeFunction free_data_func)
03633 {
03634 DBusFreeFunction old_free_func;
03635 void *old_data;
03636 dbus_bool_t retval;
03637
03638 _dbus_return_val_if_fail (message != NULL, FALSE);
03639 _dbus_return_val_if_fail (slot >= 0, FALSE);
03640
03641 retval = _dbus_data_slot_list_set (&slot_allocator,
03642 &message->slot_list,
03643 slot, data, free_data_func,
03644 &old_free_func, &old_data);
03645
03646 if (retval)
03647 {
03648
03649 if (old_free_func)
03650 (* old_free_func) (old_data);
03651 }
03652
03653 return retval;
03654 }
03655
03664 void*
03665 dbus_message_get_data (DBusMessage *message,
03666 dbus_int32_t slot)
03667 {
03668 void *res;
03669
03670 _dbus_return_val_if_fail (message != NULL, NULL);
03671
03672 res = _dbus_data_slot_list_get (&slot_allocator,
03673 &message->slot_list,
03674 slot);
03675
03676 return res;
03677 }
03678
03692 int
03693 dbus_message_type_from_string (const char *type_str)
03694 {
03695 if (strcmp (type_str, "method_call") == 0)
03696 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03697 if (strcmp (type_str, "method_return") == 0)
03698 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03699 else if (strcmp (type_str, "signal") == 0)
03700 return DBUS_MESSAGE_TYPE_SIGNAL;
03701 else if (strcmp (type_str, "error") == 0)
03702 return DBUS_MESSAGE_TYPE_ERROR;
03703 else
03704 return DBUS_MESSAGE_TYPE_INVALID;
03705 }
03706
03720 const char *
03721 dbus_message_type_to_string (int type)
03722 {
03723 switch (type)
03724 {
03725 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03726 return "method_call";
03727 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03728 return "method_return";
03729 case DBUS_MESSAGE_TYPE_SIGNAL:
03730 return "signal";
03731 case DBUS_MESSAGE_TYPE_ERROR:
03732 return "error";
03733 default:
03734 return "invalid";
03735 }
03736 }
03737
03740