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
00038 static void dbus_message_finalize (DBusMessage *message);
00039
00050
00051
00053 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
00054
00055
00056
00057
00058 enum {
00059 DBUS_MESSAGE_ITER_TYPE_READER = 3,
00060 DBUS_MESSAGE_ITER_TYPE_WRITER = 7
00061 };
00062
00064 typedef struct DBusMessageRealIter DBusMessageRealIter;
00065
00071 struct DBusMessageRealIter
00072 {
00073 DBusMessage *message;
00074 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
00075 dbus_uint32_t iter_type : 3;
00076 dbus_uint32_t sig_refcount : 8;
00077 union
00078 {
00079 DBusTypeWriter writer;
00080 DBusTypeReader reader;
00081 } u;
00082 };
00083
00084 static void
00085 get_const_signature (DBusHeader *header,
00086 const DBusString **type_str_p,
00087 int *type_pos_p)
00088 {
00089 if (_dbus_header_get_field_raw (header,
00090 DBUS_HEADER_FIELD_SIGNATURE,
00091 type_str_p,
00092 type_pos_p))
00093 {
00094 *type_pos_p += 1;
00095 }
00096 else
00097 {
00098 *type_str_p = &_dbus_empty_signature_str;
00099 *type_pos_p = 0;
00100 }
00101 }
00102
00108 static void
00109 _dbus_message_byteswap (DBusMessage *message)
00110 {
00111 const DBusString *type_str;
00112 int type_pos;
00113
00114 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
00115 return;
00116
00117 _dbus_verbose ("Swapping message into compiler byte order\n");
00118
00119 get_const_signature (&message->header, &type_str, &type_pos);
00120
00121 _dbus_marshal_byteswap (type_str, type_pos,
00122 message->byte_order,
00123 DBUS_COMPILER_BYTE_ORDER,
00124 &message->body, 0);
00125
00126 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00127
00128 _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
00129 }
00130
00137 #define ensure_byte_order(message) \
00138 if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
00139 _dbus_message_byteswap (message)
00140
00151 void
00152 _dbus_message_get_network_data (DBusMessage *message,
00153 const DBusString **header,
00154 const DBusString **body)
00155 {
00156 _dbus_assert (message->locked);
00157
00158 *header = &message->header.data;
00159 *body = &message->body;
00160 }
00161
00169 void
00170 _dbus_message_set_serial (DBusMessage *message,
00171 dbus_uint32_t serial)
00172 {
00173 _dbus_assert (message != NULL);
00174 _dbus_assert (!message->locked);
00175 _dbus_assert (dbus_message_get_serial (message) == 0);
00176
00177 _dbus_header_set_serial (&message->header, serial);
00178 }
00179
00192 void
00193 _dbus_message_add_size_counter_link (DBusMessage *message,
00194 DBusList *link)
00195 {
00196
00197
00198
00199
00200
00201
00202 if (message->size_counters == NULL)
00203 {
00204 message->size_counter_delta =
00205 _dbus_string_get_length (&message->header.data) +
00206 _dbus_string_get_length (&message->body);
00207
00208 #if 0
00209 _dbus_verbose ("message has size %ld\n",
00210 message->size_counter_delta);
00211 #endif
00212 }
00213
00214 _dbus_list_append_link (&message->size_counters, link);
00215
00216 _dbus_counter_adjust (link->data, message->size_counter_delta);
00217 }
00218
00228 dbus_bool_t
00229 _dbus_message_add_size_counter (DBusMessage *message,
00230 DBusCounter *counter)
00231 {
00232 DBusList *link;
00233
00234 link = _dbus_list_alloc_link (counter);
00235 if (link == NULL)
00236 return FALSE;
00237
00238 _dbus_counter_ref (counter);
00239 _dbus_message_add_size_counter_link (message, link);
00240
00241 return TRUE;
00242 }
00243
00252 void
00253 _dbus_message_remove_size_counter (DBusMessage *message,
00254 DBusCounter *counter,
00255 DBusList **link_return)
00256 {
00257 DBusList *link;
00258
00259 link = _dbus_list_find_last (&message->size_counters,
00260 counter);
00261 _dbus_assert (link != NULL);
00262
00263 _dbus_list_unlink (&message->size_counters,
00264 link);
00265 if (link_return)
00266 *link_return = link;
00267 else
00268 _dbus_list_free_link (link);
00269
00270 _dbus_counter_adjust (counter, - message->size_counter_delta);
00271
00272 _dbus_counter_unref (counter);
00273 }
00274
00284 void
00285 _dbus_message_lock (DBusMessage *message)
00286 {
00287 if (!message->locked)
00288 {
00289 _dbus_header_update_lengths (&message->header,
00290 _dbus_string_get_length (&message->body));
00291
00292
00293 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00294 dbus_message_get_signature (message) != NULL);
00295
00296 message->locked = TRUE;
00297 }
00298 }
00299
00300 static dbus_bool_t
00301 set_or_delete_string_field (DBusMessage *message,
00302 int field,
00303 int typecode,
00304 const char *value)
00305 {
00306 if (value == NULL)
00307 return _dbus_header_delete_field (&message->header, field);
00308 else
00309 return _dbus_header_set_field_basic (&message->header,
00310 field,
00311 typecode,
00312 &value);
00313 }
00314
00315 #if 0
00316
00340 static dbus_bool_t
00341 _dbus_message_set_signature (DBusMessage *message,
00342 const char *signature)
00343 {
00344 _dbus_return_val_if_fail (message != NULL, FALSE);
00345 _dbus_return_val_if_fail (!message->locked, FALSE);
00346 _dbus_return_val_if_fail (signature == NULL ||
00347 _dbus_check_is_valid_signature (signature));
00348
00349 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00350 signature != NULL);
00351
00352 return set_or_delete_string_field (message,
00353 DBUS_HEADER_FIELD_SIGNATURE,
00354 DBUS_TYPE_SIGNATURE,
00355 signature);
00356 }
00357 #endif
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00406 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00407
00409 #define MAX_MESSAGE_CACHE_SIZE 5
00410
00411 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00412 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00413 static int message_cache_count = 0;
00414 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00415
00416 static void
00417 dbus_message_cache_shutdown (void *data)
00418 {
00419 int i;
00420
00421 _DBUS_LOCK (message_cache);
00422
00423 i = 0;
00424 while (i < MAX_MESSAGE_CACHE_SIZE)
00425 {
00426 if (message_cache[i])
00427 dbus_message_finalize (message_cache[i]);
00428
00429 ++i;
00430 }
00431
00432 message_cache_count = 0;
00433 message_cache_shutdown_registered = FALSE;
00434
00435 _DBUS_UNLOCK (message_cache);
00436 }
00437
00445 static DBusMessage*
00446 dbus_message_get_cached (void)
00447 {
00448 DBusMessage *message;
00449 int i;
00450
00451 message = NULL;
00452
00453 _DBUS_LOCK (message_cache);
00454
00455 _dbus_assert (message_cache_count >= 0);
00456
00457 if (message_cache_count == 0)
00458 {
00459 _DBUS_UNLOCK (message_cache);
00460 return NULL;
00461 }
00462
00463
00464
00465
00466
00467 _dbus_assert (message_cache_shutdown_registered);
00468
00469 i = 0;
00470 while (i < MAX_MESSAGE_CACHE_SIZE)
00471 {
00472 if (message_cache[i])
00473 {
00474 message = message_cache[i];
00475 message_cache[i] = NULL;
00476 message_cache_count -= 1;
00477 break;
00478 }
00479 ++i;
00480 }
00481 _dbus_assert (message_cache_count >= 0);
00482 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00483 _dbus_assert (message != NULL);
00484
00485 _dbus_assert (message->refcount.value == 0);
00486 _dbus_assert (message->size_counters == NULL);
00487
00488 _DBUS_UNLOCK (message_cache);
00489
00490 return message;
00491 }
00492
00493 static void
00494 free_size_counter (void *element,
00495 void *data)
00496 {
00497 DBusCounter *counter = element;
00498 DBusMessage *message = data;
00499
00500 _dbus_counter_adjust (counter, - message->size_counter_delta);
00501
00502 _dbus_counter_unref (counter);
00503 }
00504
00510 static void
00511 dbus_message_cache_or_finalize (DBusMessage *message)
00512 {
00513 dbus_bool_t was_cached;
00514 int i;
00515
00516 _dbus_assert (message->refcount.value == 0);
00517
00518
00519
00520
00521 _dbus_data_slot_list_clear (&message->slot_list);
00522
00523 _dbus_list_foreach (&message->size_counters,
00524 free_size_counter, message);
00525 _dbus_list_clear (&message->size_counters);
00526
00527 was_cached = FALSE;
00528
00529 _DBUS_LOCK (message_cache);
00530
00531 if (!message_cache_shutdown_registered)
00532 {
00533 _dbus_assert (message_cache_count == 0);
00534
00535 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00536 goto out;
00537
00538 i = 0;
00539 while (i < MAX_MESSAGE_CACHE_SIZE)
00540 {
00541 message_cache[i] = NULL;
00542 ++i;
00543 }
00544
00545 message_cache_shutdown_registered = TRUE;
00546 }
00547
00548 _dbus_assert (message_cache_count >= 0);
00549
00550 if ((_dbus_string_get_length (&message->header.data) +
00551 _dbus_string_get_length (&message->body)) >
00552 MAX_MESSAGE_SIZE_TO_CACHE)
00553 goto out;
00554
00555 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00556 goto out;
00557
00558
00559 i = 0;
00560 while (message_cache[i] != NULL)
00561 ++i;
00562
00563 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00564
00565 _dbus_assert (message_cache[i] == NULL);
00566 message_cache[i] = message;
00567 message_cache_count += 1;
00568 was_cached = TRUE;
00569 #ifndef DBUS_DISABLE_CHECKS
00570 message->in_cache = TRUE;
00571 #endif
00572
00573 out:
00574 _dbus_assert (message->refcount.value == 0);
00575
00576 _DBUS_UNLOCK (message_cache);
00577
00578 if (!was_cached)
00579 dbus_message_finalize (message);
00580 }
00581
00582 #ifndef DBUS_DISABLE_CHECKS
00583 static dbus_bool_t
00584 _dbus_message_iter_check (DBusMessageRealIter *iter)
00585 {
00586 if (iter == NULL)
00587 {
00588 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00589 return FALSE;
00590 }
00591
00592 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00593 {
00594 if (iter->u.reader.byte_order != iter->message->byte_order)
00595 {
00596 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00597 return FALSE;
00598 }
00599
00600 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00601 }
00602 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00603 {
00604 if (iter->u.writer.byte_order != iter->message->byte_order)
00605 {
00606 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00607 return FALSE;
00608 }
00609
00610 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00611 }
00612 else
00613 {
00614 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00615 return FALSE;
00616 }
00617
00618 if (iter->changed_stamp != iter->message->changed_stamp)
00619 {
00620 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00621 return FALSE;
00622 }
00623
00624 return TRUE;
00625 }
00626 #endif
00627
00640 dbus_bool_t
00641 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00642 DBusError *error,
00643 int first_arg_type,
00644 va_list var_args)
00645 {
00646 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00647 int spec_type, msg_type, i;
00648 dbus_bool_t retval;
00649
00650 _dbus_assert (_dbus_message_iter_check (real));
00651
00652 retval = FALSE;
00653
00654 spec_type = first_arg_type;
00655 i = 0;
00656
00657 while (spec_type != DBUS_TYPE_INVALID)
00658 {
00659 msg_type = dbus_message_iter_get_arg_type (iter);
00660
00661 if (msg_type != spec_type)
00662 {
00663 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00664 "Argument %d is specified to be of type \"%s\", but "
00665 "is actually of type \"%s\"\n", i,
00666 _dbus_type_to_string (spec_type),
00667 _dbus_type_to_string (msg_type));
00668
00669 goto out;
00670 }
00671
00672 if (dbus_type_is_basic (spec_type))
00673 {
00674 DBusBasicValue *ptr;
00675
00676 ptr = va_arg (var_args, DBusBasicValue*);
00677
00678 _dbus_assert (ptr != NULL);
00679
00680 _dbus_type_reader_read_basic (&real->u.reader,
00681 ptr);
00682 }
00683 else if (spec_type == DBUS_TYPE_ARRAY)
00684 {
00685 int element_type;
00686 int spec_element_type;
00687 const DBusBasicValue **ptr;
00688 int *n_elements_p;
00689 DBusTypeReader array;
00690
00691 spec_element_type = va_arg (var_args, int);
00692 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00693
00694 if (spec_element_type != element_type)
00695 {
00696 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00697 "Argument %d is specified to be an array of \"%s\", but "
00698 "is actually an array of \"%s\"\n",
00699 i,
00700 _dbus_type_to_string (spec_element_type),
00701 _dbus_type_to_string (element_type));
00702
00703 goto out;
00704 }
00705
00706 if (dbus_type_is_fixed (spec_element_type))
00707 {
00708 ptr = va_arg (var_args, const DBusBasicValue**);
00709 n_elements_p = va_arg (var_args, int*);
00710
00711 _dbus_assert (ptr != NULL);
00712 _dbus_assert (n_elements_p != NULL);
00713
00714 _dbus_type_reader_recurse (&real->u.reader, &array);
00715
00716 _dbus_type_reader_read_fixed_multi (&array,
00717 ptr, n_elements_p);
00718 }
00719 else if (spec_element_type == DBUS_TYPE_STRING ||
00720 spec_element_type == DBUS_TYPE_SIGNATURE ||
00721 spec_element_type == DBUS_TYPE_OBJECT_PATH)
00722 {
00723 char ***str_array_p;
00724 int n_elements;
00725 char **str_array;
00726
00727 str_array_p = va_arg (var_args, char***);
00728 n_elements_p = va_arg (var_args, int*);
00729
00730 _dbus_assert (str_array_p != NULL);
00731 _dbus_assert (n_elements_p != NULL);
00732
00733
00734 _dbus_type_reader_recurse (&real->u.reader, &array);
00735
00736 n_elements = 0;
00737 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00738 {
00739 ++n_elements;
00740 _dbus_type_reader_next (&array);
00741 }
00742
00743 str_array = dbus_new0 (char*, n_elements + 1);
00744 if (str_array == NULL)
00745 {
00746 _DBUS_SET_OOM (error);
00747 goto out;
00748 }
00749
00750
00751 _dbus_type_reader_recurse (&real->u.reader, &array);
00752
00753 i = 0;
00754 while (i < n_elements)
00755 {
00756 const char *s;
00757 _dbus_type_reader_read_basic (&array,
00758 &s);
00759
00760 str_array[i] = _dbus_strdup (s);
00761 if (str_array[i] == NULL)
00762 {
00763 dbus_free_string_array (str_array);
00764 _DBUS_SET_OOM (error);
00765 goto out;
00766 }
00767
00768 ++i;
00769
00770 if (!_dbus_type_reader_next (&array))
00771 _dbus_assert (i == n_elements);
00772 }
00773
00774 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00775 _dbus_assert (i == n_elements);
00776 _dbus_assert (str_array[i] == NULL);
00777
00778 *str_array_p = str_array;
00779 *n_elements_p = n_elements;
00780 }
00781 #ifndef DBUS_DISABLE_CHECKS
00782 else
00783 {
00784 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00785 _DBUS_FUNCTION_NAME);
00786 goto out;
00787 }
00788 #endif
00789 }
00790 #ifndef DBUS_DISABLE_CHECKS
00791 else
00792 {
00793 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00794 _DBUS_FUNCTION_NAME);
00795 goto out;
00796 }
00797 #endif
00798
00799 spec_type = va_arg (var_args, int);
00800 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00801 {
00802 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00803 "Message has only %d arguments, but more were expected", i);
00804 goto out;
00805 }
00806
00807 i++;
00808 }
00809
00810 retval = TRUE;
00811
00812 out:
00813
00814 return retval;
00815 }
00816
00875 dbus_uint32_t
00876 dbus_message_get_serial (DBusMessage *message)
00877 {
00878 _dbus_return_val_if_fail (message != NULL, 0);
00879
00880 return _dbus_header_get_serial (&message->header);
00881 }
00882
00891 dbus_bool_t
00892 dbus_message_set_reply_serial (DBusMessage *message,
00893 dbus_uint32_t reply_serial)
00894 {
00895 _dbus_return_val_if_fail (message != NULL, FALSE);
00896 _dbus_return_val_if_fail (!message->locked, FALSE);
00897 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
00898
00899 return _dbus_header_set_field_basic (&message->header,
00900 DBUS_HEADER_FIELD_REPLY_SERIAL,
00901 DBUS_TYPE_UINT32,
00902 &reply_serial);
00903 }
00904
00911 dbus_uint32_t
00912 dbus_message_get_reply_serial (DBusMessage *message)
00913 {
00914 dbus_uint32_t v_UINT32;
00915
00916 _dbus_return_val_if_fail (message != NULL, 0);
00917
00918 if (_dbus_header_get_field_basic (&message->header,
00919 DBUS_HEADER_FIELD_REPLY_SERIAL,
00920 DBUS_TYPE_UINT32,
00921 &v_UINT32))
00922 return v_UINT32;
00923 else
00924 return 0;
00925 }
00926
00927 static void
00928 dbus_message_finalize (DBusMessage *message)
00929 {
00930 _dbus_assert (message->refcount.value == 0);
00931
00932
00933 _dbus_data_slot_list_free (&message->slot_list);
00934
00935 _dbus_list_foreach (&message->size_counters,
00936 free_size_counter, message);
00937 _dbus_list_clear (&message->size_counters);
00938
00939 _dbus_header_free (&message->header);
00940 _dbus_string_free (&message->body);
00941
00942 _dbus_assert (message->refcount.value == 0);
00943
00944 dbus_free (message);
00945 }
00946
00947 static DBusMessage*
00948 dbus_message_new_empty_header (void)
00949 {
00950 DBusMessage *message;
00951 dbus_bool_t from_cache;
00952
00953 message = dbus_message_get_cached ();
00954
00955 if (message != NULL)
00956 {
00957 from_cache = TRUE;
00958 }
00959 else
00960 {
00961 from_cache = FALSE;
00962 message = dbus_new (DBusMessage, 1);
00963 if (message == NULL)
00964 return NULL;
00965 #ifndef DBUS_DISABLE_CHECKS
00966 message->generation = _dbus_current_generation;
00967 #endif
00968 }
00969
00970 message->refcount.value = 1;
00971 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00972 message->locked = FALSE;
00973 #ifndef DBUS_DISABLE_CHECKS
00974 message->in_cache = FALSE;
00975 #endif
00976 message->size_counters = NULL;
00977 message->size_counter_delta = 0;
00978 message->changed_stamp = 0;
00979
00980 if (!from_cache)
00981 _dbus_data_slot_list_init (&message->slot_list);
00982
00983 if (from_cache)
00984 {
00985 _dbus_header_reinit (&message->header, message->byte_order);
00986 _dbus_string_set_length (&message->body, 0);
00987 }
00988 else
00989 {
00990 if (!_dbus_header_init (&message->header, message->byte_order))
00991 {
00992 dbus_free (message);
00993 return NULL;
00994 }
00995
00996 if (!_dbus_string_init_preallocated (&message->body, 32))
00997 {
00998 _dbus_header_free (&message->header);
00999 dbus_free (message);
01000 return NULL;
01001 }
01002 }
01003
01004 return message;
01005 }
01006
01019 DBusMessage*
01020 dbus_message_new (int message_type)
01021 {
01022 DBusMessage *message;
01023
01024 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01025
01026 message = dbus_message_new_empty_header ();
01027 if (message == NULL)
01028 return NULL;
01029
01030 if (!_dbus_header_create (&message->header,
01031 message_type,
01032 NULL, NULL, NULL, NULL, NULL))
01033 {
01034 dbus_message_unref (message);
01035 return NULL;
01036 }
01037
01038 return message;
01039 }
01040
01062 DBusMessage*
01063 dbus_message_new_method_call (const char *destination,
01064 const char *path,
01065 const char *interface,
01066 const char *method)
01067 {
01068 DBusMessage *message;
01069
01070 _dbus_return_val_if_fail (path != NULL, NULL);
01071 _dbus_return_val_if_fail (method != NULL, NULL);
01072 _dbus_return_val_if_fail (destination == NULL ||
01073 _dbus_check_is_valid_bus_name (destination), NULL);
01074 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01075 _dbus_return_val_if_fail (interface == NULL ||
01076 _dbus_check_is_valid_interface (interface), NULL);
01077 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01078
01079 message = dbus_message_new_empty_header ();
01080 if (message == NULL)
01081 return NULL;
01082
01083 if (!_dbus_header_create (&message->header,
01084 DBUS_MESSAGE_TYPE_METHOD_CALL,
01085 destination, path, interface, method, NULL))
01086 {
01087 dbus_message_unref (message);
01088 return NULL;
01089 }
01090
01091 return message;
01092 }
01093
01101 DBusMessage*
01102 dbus_message_new_method_return (DBusMessage *method_call)
01103 {
01104 DBusMessage *message;
01105 const char *sender;
01106
01107 _dbus_return_val_if_fail (method_call != NULL, NULL);
01108
01109 sender = dbus_message_get_sender (method_call);
01110
01111
01112
01113 message = dbus_message_new_empty_header ();
01114 if (message == NULL)
01115 return NULL;
01116
01117 if (!_dbus_header_create (&message->header,
01118 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01119 sender, NULL, NULL, NULL, NULL))
01120 {
01121 dbus_message_unref (message);
01122 return NULL;
01123 }
01124
01125 dbus_message_set_no_reply (message, TRUE);
01126
01127 if (!dbus_message_set_reply_serial (message,
01128 dbus_message_get_serial (method_call)))
01129 {
01130 dbus_message_unref (message);
01131 return NULL;
01132 }
01133
01134 return message;
01135 }
01136
01151 DBusMessage*
01152 dbus_message_new_signal (const char *path,
01153 const char *interface,
01154 const char *name)
01155 {
01156 DBusMessage *message;
01157
01158 _dbus_return_val_if_fail (path != NULL, NULL);
01159 _dbus_return_val_if_fail (interface != NULL, NULL);
01160 _dbus_return_val_if_fail (name != NULL, NULL);
01161 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01162 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01163 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01164
01165 message = dbus_message_new_empty_header ();
01166 if (message == NULL)
01167 return NULL;
01168
01169 if (!_dbus_header_create (&message->header,
01170 DBUS_MESSAGE_TYPE_SIGNAL,
01171 NULL, path, interface, name, NULL))
01172 {
01173 dbus_message_unref (message);
01174 return NULL;
01175 }
01176
01177 dbus_message_set_no_reply (message, TRUE);
01178
01179 return message;
01180 }
01181
01196 DBusMessage*
01197 dbus_message_new_error (DBusMessage *reply_to,
01198 const char *error_name,
01199 const char *error_message)
01200 {
01201 DBusMessage *message;
01202 const char *sender;
01203 DBusMessageIter iter;
01204
01205 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01206 _dbus_return_val_if_fail (error_name != NULL, NULL);
01207 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01208
01209 sender = dbus_message_get_sender (reply_to);
01210
01211
01212
01213
01214
01215 message = dbus_message_new_empty_header ();
01216 if (message == NULL)
01217 return NULL;
01218
01219 if (!_dbus_header_create (&message->header,
01220 DBUS_MESSAGE_TYPE_ERROR,
01221 sender, NULL, NULL, NULL, error_name))
01222 {
01223 dbus_message_unref (message);
01224 return NULL;
01225 }
01226
01227 dbus_message_set_no_reply (message, TRUE);
01228
01229 if (!dbus_message_set_reply_serial (message,
01230 dbus_message_get_serial (reply_to)))
01231 {
01232 dbus_message_unref (message);
01233 return NULL;
01234 }
01235
01236 if (error_message != NULL)
01237 {
01238 dbus_message_iter_init_append (message, &iter);
01239 if (!dbus_message_iter_append_basic (&iter,
01240 DBUS_TYPE_STRING,
01241 &error_message))
01242 {
01243 dbus_message_unref (message);
01244 return NULL;
01245 }
01246 }
01247
01248 return message;
01249 }
01250
01267 DBusMessage*
01268 dbus_message_new_error_printf (DBusMessage *reply_to,
01269 const char *error_name,
01270 const char *error_format,
01271 ...)
01272 {
01273 va_list args;
01274 DBusString str;
01275 DBusMessage *message;
01276
01277 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01278 _dbus_return_val_if_fail (error_name != NULL, NULL);
01279 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01280
01281 if (!_dbus_string_init (&str))
01282 return NULL;
01283
01284 va_start (args, error_format);
01285
01286 if (_dbus_string_append_printf_valist (&str, error_format, args))
01287 message = dbus_message_new_error (reply_to, error_name,
01288 _dbus_string_get_const_data (&str));
01289 else
01290 message = NULL;
01291
01292 _dbus_string_free (&str);
01293
01294 va_end (args);
01295
01296 return message;
01297 }
01298
01299
01310 DBusMessage *
01311 dbus_message_copy (const DBusMessage *message)
01312 {
01313 DBusMessage *retval;
01314
01315 _dbus_return_val_if_fail (message != NULL, NULL);
01316
01317 retval = dbus_new0 (DBusMessage, 1);
01318 if (retval == NULL)
01319 return NULL;
01320
01321 retval->refcount.value = 1;
01322 retval->byte_order = message->byte_order;
01323 retval->locked = FALSE;
01324 #ifndef DBUS_DISABLE_CHECKS
01325 retval->generation = message->generation;
01326 #endif
01327
01328 if (!_dbus_header_copy (&message->header, &retval->header))
01329 {
01330 dbus_free (retval);
01331 return NULL;
01332 }
01333
01334 if (!_dbus_string_init_preallocated (&retval->body,
01335 _dbus_string_get_length (&message->body)))
01336 {
01337 _dbus_header_free (&retval->header);
01338 dbus_free (retval);
01339 return NULL;
01340 }
01341
01342 if (!_dbus_string_copy (&message->body, 0,
01343 &retval->body, 0))
01344 goto failed_copy;
01345
01346 return retval;
01347
01348 failed_copy:
01349 _dbus_header_free (&retval->header);
01350 _dbus_string_free (&retval->body);
01351 dbus_free (retval);
01352
01353 return NULL;
01354 }
01355
01356
01364 DBusMessage *
01365 dbus_message_ref (DBusMessage *message)
01366 {
01367 dbus_int32_t old_refcount;
01368
01369 _dbus_return_val_if_fail (message != NULL, NULL);
01370 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01371 _dbus_return_val_if_fail (!message->in_cache, NULL);
01372
01373 old_refcount = _dbus_atomic_inc (&message->refcount);
01374 _dbus_assert (old_refcount >= 1);
01375
01376 return message;
01377 }
01378
01386 void
01387 dbus_message_unref (DBusMessage *message)
01388 {
01389 dbus_int32_t old_refcount;
01390
01391 _dbus_return_if_fail (message != NULL);
01392 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01393 _dbus_return_if_fail (!message->in_cache);
01394
01395 old_refcount = _dbus_atomic_dec (&message->refcount);
01396
01397 _dbus_assert (old_refcount >= 0);
01398
01399 if (old_refcount == 1)
01400 {
01401
01402 dbus_message_cache_or_finalize (message);
01403 }
01404 }
01405
01416 int
01417 dbus_message_get_type (DBusMessage *message)
01418 {
01419 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01420
01421 return _dbus_header_get_message_type (&message->header);
01422 }
01423
01481 dbus_bool_t
01482 dbus_message_append_args (DBusMessage *message,
01483 int first_arg_type,
01484 ...)
01485 {
01486 dbus_bool_t retval;
01487 va_list var_args;
01488
01489 _dbus_return_val_if_fail (message != NULL, FALSE);
01490
01491 va_start (var_args, first_arg_type);
01492 retval = dbus_message_append_args_valist (message,
01493 first_arg_type,
01494 var_args);
01495 va_end (var_args);
01496
01497 return retval;
01498 }
01499
01513 dbus_bool_t
01514 dbus_message_append_args_valist (DBusMessage *message,
01515 int first_arg_type,
01516 va_list var_args)
01517 {
01518 int type;
01519 DBusMessageIter iter;
01520
01521 _dbus_return_val_if_fail (message != NULL, FALSE);
01522
01523 type = first_arg_type;
01524
01525 dbus_message_iter_init_append (message, &iter);
01526
01527 while (type != DBUS_TYPE_INVALID)
01528 {
01529 if (dbus_type_is_basic (type))
01530 {
01531 const DBusBasicValue *value;
01532 value = va_arg (var_args, const DBusBasicValue*);
01533
01534 if (!dbus_message_iter_append_basic (&iter,
01535 type,
01536 value))
01537 goto failed;
01538 }
01539 else if (type == DBUS_TYPE_ARRAY)
01540 {
01541 int element_type;
01542 DBusMessageIter array;
01543 char buf[2];
01544
01545 element_type = va_arg (var_args, int);
01546
01547 buf[0] = element_type;
01548 buf[1] = '\0';
01549 if (!dbus_message_iter_open_container (&iter,
01550 DBUS_TYPE_ARRAY,
01551 buf,
01552 &array))
01553 goto failed;
01554
01555 if (dbus_type_is_fixed (element_type))
01556 {
01557 const DBusBasicValue **value;
01558 int n_elements;
01559
01560 value = va_arg (var_args, const DBusBasicValue**);
01561 n_elements = va_arg (var_args, int);
01562
01563 if (!dbus_message_iter_append_fixed_array (&array,
01564 element_type,
01565 value,
01566 n_elements))
01567 goto failed;
01568 }
01569 else if (element_type == DBUS_TYPE_STRING ||
01570 element_type == DBUS_TYPE_SIGNATURE ||
01571 element_type == DBUS_TYPE_OBJECT_PATH)
01572 {
01573 const char ***value_p;
01574 const char **value;
01575 int n_elements;
01576 int i;
01577
01578 value_p = va_arg (var_args, const char***);
01579 n_elements = va_arg (var_args, int);
01580
01581 value = *value_p;
01582
01583 i = 0;
01584 while (i < n_elements)
01585 {
01586 if (!dbus_message_iter_append_basic (&array,
01587 element_type,
01588 &value[i]))
01589 goto failed;
01590 ++i;
01591 }
01592 }
01593 else
01594 {
01595 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01596 _dbus_type_to_string (element_type),
01597 _DBUS_FUNCTION_NAME);
01598 goto failed;
01599 }
01600
01601 if (!dbus_message_iter_close_container (&iter, &array))
01602 goto failed;
01603 }
01604 #ifndef DBUS_DISABLE_CHECKS
01605 else
01606 {
01607 _dbus_warn ("type %s isn't supported yet in %s\n",
01608 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01609 goto failed;
01610 }
01611 #endif
01612
01613 type = va_arg (var_args, int);
01614 }
01615
01616 return TRUE;
01617
01618 failed:
01619 return FALSE;
01620 }
01621
01657 dbus_bool_t
01658 dbus_message_get_args (DBusMessage *message,
01659 DBusError *error,
01660 int first_arg_type,
01661 ...)
01662 {
01663 dbus_bool_t retval;
01664 va_list var_args;
01665
01666 _dbus_return_val_if_fail (message != NULL, FALSE);
01667 _dbus_return_val_if_error_is_set (error, FALSE);
01668
01669 va_start (var_args, first_arg_type);
01670 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01671 va_end (var_args);
01672
01673 return retval;
01674 }
01675
01686 dbus_bool_t
01687 dbus_message_get_args_valist (DBusMessage *message,
01688 DBusError *error,
01689 int first_arg_type,
01690 va_list var_args)
01691 {
01692 DBusMessageIter iter;
01693
01694 _dbus_return_val_if_fail (message != NULL, FALSE);
01695 _dbus_return_val_if_error_is_set (error, FALSE);
01696
01697 dbus_message_iter_init (message, &iter);
01698 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01699 }
01700
01701 static void
01702 _dbus_message_iter_init_common (DBusMessage *message,
01703 DBusMessageRealIter *real,
01704 int iter_type)
01705 {
01706 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01707
01708
01709
01710
01711 ensure_byte_order (message);
01712
01713 real->message = message;
01714 real->changed_stamp = message->changed_stamp;
01715 real->iter_type = iter_type;
01716 real->sig_refcount = 0;
01717 }
01718
01741 dbus_bool_t
01742 dbus_message_iter_init (DBusMessage *message,
01743 DBusMessageIter *iter)
01744 {
01745 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01746 const DBusString *type_str;
01747 int type_pos;
01748
01749 _dbus_return_val_if_fail (message != NULL, FALSE);
01750 _dbus_return_val_if_fail (iter != NULL, FALSE);
01751
01752 get_const_signature (&message->header, &type_str, &type_pos);
01753
01754 _dbus_message_iter_init_common (message, real,
01755 DBUS_MESSAGE_ITER_TYPE_READER);
01756
01757 _dbus_type_reader_init (&real->u.reader,
01758 message->byte_order,
01759 type_str, type_pos,
01760 &message->body,
01761 0);
01762
01763 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01764 }
01765
01772 dbus_bool_t
01773 dbus_message_iter_has_next (DBusMessageIter *iter)
01774 {
01775 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01776
01777 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01778 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01779
01780 return _dbus_type_reader_has_next (&real->u.reader);
01781 }
01782
01791 dbus_bool_t
01792 dbus_message_iter_next (DBusMessageIter *iter)
01793 {
01794 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01795
01796 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01797 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01798
01799 return _dbus_type_reader_next (&real->u.reader);
01800 }
01801
01816 int
01817 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01818 {
01819 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01820
01821 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01822 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01823
01824 return _dbus_type_reader_get_current_type (&real->u.reader);
01825 }
01826
01835 int
01836 dbus_message_iter_get_element_type (DBusMessageIter *iter)
01837 {
01838 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01839
01840 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01841 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
01842 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
01843
01844 return _dbus_type_reader_get_element_type (&real->u.reader);
01845 }
01846
01862 void
01863 dbus_message_iter_recurse (DBusMessageIter *iter,
01864 DBusMessageIter *sub)
01865 {
01866 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01867 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01868
01869 _dbus_return_if_fail (_dbus_message_iter_check (real));
01870 _dbus_return_if_fail (sub != NULL);
01871
01872 *real_sub = *real;
01873 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01874 }
01875
01887 char *
01888 dbus_message_iter_get_signature (DBusMessageIter *iter)
01889 {
01890 const DBusString *sig;
01891 DBusString retstr;
01892 char *ret;
01893 int start, len;
01894 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01895
01896 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01897
01898 if (!_dbus_string_init (&retstr))
01899 return NULL;
01900
01901 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01902 &start, &len);
01903 if (!_dbus_string_append_len (&retstr,
01904 _dbus_string_get_const_data (sig) + start,
01905 len))
01906 return NULL;
01907 if (!_dbus_string_steal_data (&retstr, &ret))
01908 return NULL;
01909 _dbus_string_free (&retstr);
01910 return ret;
01911 }
01912
01950 void
01951 dbus_message_iter_get_basic (DBusMessageIter *iter,
01952 void *value)
01953 {
01954 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01955
01956 _dbus_return_if_fail (_dbus_message_iter_check (real));
01957 _dbus_return_if_fail (value != NULL);
01958
01959 _dbus_type_reader_read_basic (&real->u.reader,
01960 value);
01961 }
01962
01981 int
01982 dbus_message_iter_get_array_len (DBusMessageIter *iter)
01983 {
01984 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01985
01986 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
01987
01988 return _dbus_type_reader_get_array_length (&real->u.reader);
01989 }
01990
02012 void
02013 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02014 void *value,
02015 int *n_elements)
02016 {
02017 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02018 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02019
02020 _dbus_return_if_fail (_dbus_message_iter_check (real));
02021 _dbus_return_if_fail (value != NULL);
02022 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02023 dbus_type_is_fixed (subtype));
02024
02025 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02026 value, n_elements);
02027 }
02028
02040 void
02041 dbus_message_iter_init_append (DBusMessage *message,
02042 DBusMessageIter *iter)
02043 {
02044 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02045
02046 _dbus_return_if_fail (message != NULL);
02047 _dbus_return_if_fail (iter != NULL);
02048
02049 _dbus_message_iter_init_common (message, real,
02050 DBUS_MESSAGE_ITER_TYPE_WRITER);
02051
02052
02053
02054
02055
02056 _dbus_type_writer_init_types_delayed (&real->u.writer,
02057 message->byte_order,
02058 &message->body,
02059 _dbus_string_get_length (&message->body));
02060 }
02061
02070 static dbus_bool_t
02071 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02072 {
02073 DBusString *str;
02074 const DBusString *current_sig;
02075 int current_sig_pos;
02076
02077 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02078
02079 if (real->u.writer.type_str != NULL)
02080 {
02081 _dbus_assert (real->sig_refcount > 0);
02082 real->sig_refcount += 1;
02083 return TRUE;
02084 }
02085
02086 str = dbus_new (DBusString, 1);
02087 if (str == NULL)
02088 return FALSE;
02089
02090 if (!_dbus_header_get_field_raw (&real->message->header,
02091 DBUS_HEADER_FIELD_SIGNATURE,
02092 ¤t_sig, ¤t_sig_pos))
02093 current_sig = NULL;
02094
02095 if (current_sig)
02096 {
02097 int current_len;
02098
02099 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02100 current_sig_pos += 1;
02101
02102 if (!_dbus_string_init_preallocated (str, current_len + 4))
02103 {
02104 dbus_free (str);
02105 return FALSE;
02106 }
02107
02108 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02109 str, 0))
02110 {
02111 _dbus_string_free (str);
02112 dbus_free (str);
02113 return FALSE;
02114 }
02115 }
02116 else
02117 {
02118 if (!_dbus_string_init_preallocated (str, 4))
02119 {
02120 dbus_free (str);
02121 return FALSE;
02122 }
02123 }
02124
02125 real->sig_refcount = 1;
02126
02127 _dbus_type_writer_add_types (&real->u.writer,
02128 str, _dbus_string_get_length (str));
02129 return TRUE;
02130 }
02131
02141 static dbus_bool_t
02142 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02143 {
02144 DBusString *str;
02145 const char *v_STRING;
02146 dbus_bool_t retval;
02147
02148 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02149 _dbus_assert (real->u.writer.type_str != NULL);
02150 _dbus_assert (real->sig_refcount > 0);
02151
02152 real->sig_refcount -= 1;
02153
02154 if (real->sig_refcount > 0)
02155 return TRUE;
02156 _dbus_assert (real->sig_refcount == 0);
02157
02158 retval = TRUE;
02159
02160 str = real->u.writer.type_str;
02161
02162 v_STRING = _dbus_string_get_const_data (str);
02163 if (!_dbus_header_set_field_basic (&real->message->header,
02164 DBUS_HEADER_FIELD_SIGNATURE,
02165 DBUS_TYPE_SIGNATURE,
02166 &v_STRING))
02167 retval = FALSE;
02168
02169 _dbus_type_writer_remove_types (&real->u.writer);
02170 _dbus_string_free (str);
02171 dbus_free (str);
02172
02173 return retval;
02174 }
02175
02176 #ifndef DBUS_DISABLE_CHECKS
02177 static dbus_bool_t
02178 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02179 {
02180 if (!_dbus_message_iter_check (iter))
02181 return FALSE;
02182
02183 if (iter->message->locked)
02184 {
02185 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02186 return FALSE;
02187 }
02188
02189 return TRUE;
02190 }
02191 #endif
02192
02208 dbus_bool_t
02209 dbus_message_iter_append_basic (DBusMessageIter *iter,
02210 int type,
02211 const void *value)
02212 {
02213 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02214 dbus_bool_t ret;
02215
02216 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02217 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02218 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02219 _dbus_return_val_if_fail (value != NULL, FALSE);
02220
02221 if (!_dbus_message_iter_open_signature (real))
02222 return FALSE;
02223
02224 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02225
02226 if (!_dbus_message_iter_close_signature (real))
02227 ret = FALSE;
02228
02229 return ret;
02230 }
02231
02267 dbus_bool_t
02268 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02269 int element_type,
02270 const void *value,
02271 int n_elements)
02272 {
02273 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02274 dbus_bool_t ret;
02275
02276 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02277 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02278 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02279 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02280 _dbus_return_val_if_fail (value != NULL, FALSE);
02281 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02282 _dbus_return_val_if_fail (n_elements <=
02283 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02284 FALSE);
02285
02286 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02287
02288 return ret;
02289 }
02290
02312 dbus_bool_t
02313 dbus_message_iter_open_container (DBusMessageIter *iter,
02314 int type,
02315 const char *contained_signature,
02316 DBusMessageIter *sub)
02317 {
02318 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02319 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02320 DBusString contained_str;
02321
02322 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02323 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02324 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02325 _dbus_return_val_if_fail (sub != NULL, FALSE);
02326 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02327 contained_signature == NULL) ||
02328 (type == DBUS_TYPE_DICT_ENTRY &&
02329 contained_signature == NULL) ||
02330 contained_signature != NULL, FALSE);
02331
02332 #if 0
02333
02334
02335
02336
02337 _dbus_return_val_if_fail (contained_signature == NULL ||
02338 _dbus_check_is_valid_signature (contained_signature));
02339 #endif
02340
02341 if (!_dbus_message_iter_open_signature (real))
02342 return FALSE;
02343
02344 *real_sub = *real;
02345
02346 if (contained_signature != NULL)
02347 {
02348 _dbus_string_init_const (&contained_str, contained_signature);
02349
02350 return _dbus_type_writer_recurse (&real->u.writer,
02351 type,
02352 &contained_str, 0,
02353 &real_sub->u.writer);
02354 }
02355 else
02356 {
02357 return _dbus_type_writer_recurse (&real->u.writer,
02358 type,
02359 NULL, 0,
02360 &real_sub->u.writer);
02361 }
02362 }
02363
02364
02378 dbus_bool_t
02379 dbus_message_iter_close_container (DBusMessageIter *iter,
02380 DBusMessageIter *sub)
02381 {
02382 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02383 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02384 dbus_bool_t ret;
02385
02386 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02387 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02388 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02389 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02390
02391 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02392 &real_sub->u.writer);
02393
02394 if (!_dbus_message_iter_close_signature (real))
02395 ret = FALSE;
02396
02397 return ret;
02398 }
02399
02416 void
02417 dbus_message_set_no_reply (DBusMessage *message,
02418 dbus_bool_t no_reply)
02419 {
02420 _dbus_return_if_fail (message != NULL);
02421 _dbus_return_if_fail (!message->locked);
02422
02423 _dbus_header_toggle_flag (&message->header,
02424 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02425 no_reply);
02426 }
02427
02435 dbus_bool_t
02436 dbus_message_get_no_reply (DBusMessage *message)
02437 {
02438 _dbus_return_val_if_fail (message != NULL, FALSE);
02439
02440 return _dbus_header_get_flag (&message->header,
02441 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02442 }
02443
02458 void
02459 dbus_message_set_auto_start (DBusMessage *message,
02460 dbus_bool_t auto_start)
02461 {
02462 _dbus_return_if_fail (message != NULL);
02463 _dbus_return_if_fail (!message->locked);
02464
02465 _dbus_header_toggle_flag (&message->header,
02466 DBUS_HEADER_FLAG_NO_AUTO_START,
02467 !auto_start);
02468 }
02469
02477 dbus_bool_t
02478 dbus_message_get_auto_start (DBusMessage *message)
02479 {
02480 _dbus_return_val_if_fail (message != NULL, FALSE);
02481
02482 return !_dbus_header_get_flag (&message->header,
02483 DBUS_HEADER_FLAG_NO_AUTO_START);
02484 }
02485
02486
02499 dbus_bool_t
02500 dbus_message_set_path (DBusMessage *message,
02501 const char *object_path)
02502 {
02503 _dbus_return_val_if_fail (message != NULL, FALSE);
02504 _dbus_return_val_if_fail (!message->locked, FALSE);
02505 _dbus_return_val_if_fail (object_path == NULL ||
02506 _dbus_check_is_valid_path (object_path),
02507 FALSE);
02508
02509 return set_or_delete_string_field (message,
02510 DBUS_HEADER_FIELD_PATH,
02511 DBUS_TYPE_OBJECT_PATH,
02512 object_path);
02513 }
02514
02528 const char*
02529 dbus_message_get_path (DBusMessage *message)
02530 {
02531 const char *v;
02532
02533 _dbus_return_val_if_fail (message != NULL, NULL);
02534
02535 v = NULL;
02536 _dbus_header_get_field_basic (&message->header,
02537 DBUS_HEADER_FIELD_PATH,
02538 DBUS_TYPE_OBJECT_PATH,
02539 &v);
02540 return v;
02541 }
02542
02552 dbus_bool_t
02553 dbus_message_has_path (DBusMessage *message,
02554 const char *path)
02555 {
02556 const char *msg_path;
02557 msg_path = dbus_message_get_path (message);
02558
02559 if (msg_path == NULL)
02560 {
02561 if (path == NULL)
02562 return TRUE;
02563 else
02564 return FALSE;
02565 }
02566
02567 if (path == NULL)
02568 return FALSE;
02569
02570 if (strcmp (msg_path, path) == 0)
02571 return TRUE;
02572
02573 return FALSE;
02574 }
02575
02596 dbus_bool_t
02597 dbus_message_get_path_decomposed (DBusMessage *message,
02598 char ***path)
02599 {
02600 const char *v;
02601
02602 _dbus_return_val_if_fail (message != NULL, FALSE);
02603 _dbus_return_val_if_fail (path != NULL, FALSE);
02604
02605 *path = NULL;
02606
02607 v = dbus_message_get_path (message);
02608 if (v != NULL)
02609 {
02610 if (!_dbus_decompose_path (v, strlen (v),
02611 path, NULL))
02612 return FALSE;
02613 }
02614 return TRUE;
02615 }
02616
02630 dbus_bool_t
02631 dbus_message_set_interface (DBusMessage *message,
02632 const char *interface)
02633 {
02634 _dbus_return_val_if_fail (message != NULL, FALSE);
02635 _dbus_return_val_if_fail (!message->locked, FALSE);
02636 _dbus_return_val_if_fail (interface == NULL ||
02637 _dbus_check_is_valid_interface (interface),
02638 FALSE);
02639
02640 return set_or_delete_string_field (message,
02641 DBUS_HEADER_FIELD_INTERFACE,
02642 DBUS_TYPE_STRING,
02643 interface);
02644 }
02645
02659 const char*
02660 dbus_message_get_interface (DBusMessage *message)
02661 {
02662 const char *v;
02663
02664 _dbus_return_val_if_fail (message != NULL, NULL);
02665
02666 v = NULL;
02667 _dbus_header_get_field_basic (&message->header,
02668 DBUS_HEADER_FIELD_INTERFACE,
02669 DBUS_TYPE_STRING,
02670 &v);
02671 return v;
02672 }
02673
02681 dbus_bool_t
02682 dbus_message_has_interface (DBusMessage *message,
02683 const char *interface)
02684 {
02685 const char *msg_interface;
02686 msg_interface = dbus_message_get_interface (message);
02687
02688 if (msg_interface == NULL)
02689 {
02690 if (interface == NULL)
02691 return TRUE;
02692 else
02693 return FALSE;
02694 }
02695
02696 if (interface == NULL)
02697 return FALSE;
02698
02699 if (strcmp (msg_interface, interface) == 0)
02700 return TRUE;
02701
02702 return FALSE;
02703
02704 }
02705
02718 dbus_bool_t
02719 dbus_message_set_member (DBusMessage *message,
02720 const char *member)
02721 {
02722 _dbus_return_val_if_fail (message != NULL, FALSE);
02723 _dbus_return_val_if_fail (!message->locked, FALSE);
02724 _dbus_return_val_if_fail (member == NULL ||
02725 _dbus_check_is_valid_member (member),
02726 FALSE);
02727
02728 return set_or_delete_string_field (message,
02729 DBUS_HEADER_FIELD_MEMBER,
02730 DBUS_TYPE_STRING,
02731 member);
02732 }
02733
02745 const char*
02746 dbus_message_get_member (DBusMessage *message)
02747 {
02748 const char *v;
02749
02750 _dbus_return_val_if_fail (message != NULL, NULL);
02751
02752 v = NULL;
02753 _dbus_header_get_field_basic (&message->header,
02754 DBUS_HEADER_FIELD_MEMBER,
02755 DBUS_TYPE_STRING,
02756 &v);
02757 return v;
02758 }
02759
02767 dbus_bool_t
02768 dbus_message_has_member (DBusMessage *message,
02769 const char *member)
02770 {
02771 const char *msg_member;
02772 msg_member = dbus_message_get_member (message);
02773
02774 if (msg_member == NULL)
02775 {
02776 if (member == NULL)
02777 return TRUE;
02778 else
02779 return FALSE;
02780 }
02781
02782 if (member == NULL)
02783 return FALSE;
02784
02785 if (strcmp (msg_member, member) == 0)
02786 return TRUE;
02787
02788 return FALSE;
02789
02790 }
02791
02803 dbus_bool_t
02804 dbus_message_set_error_name (DBusMessage *message,
02805 const char *error_name)
02806 {
02807 _dbus_return_val_if_fail (message != NULL, FALSE);
02808 _dbus_return_val_if_fail (!message->locked, FALSE);
02809 _dbus_return_val_if_fail (error_name == NULL ||
02810 _dbus_check_is_valid_error_name (error_name),
02811 FALSE);
02812
02813 return set_or_delete_string_field (message,
02814 DBUS_HEADER_FIELD_ERROR_NAME,
02815 DBUS_TYPE_STRING,
02816 error_name);
02817 }
02818
02829 const char*
02830 dbus_message_get_error_name (DBusMessage *message)
02831 {
02832 const char *v;
02833
02834 _dbus_return_val_if_fail (message != NULL, NULL);
02835
02836 v = NULL;
02837 _dbus_header_get_field_basic (&message->header,
02838 DBUS_HEADER_FIELD_ERROR_NAME,
02839 DBUS_TYPE_STRING,
02840 &v);
02841 return v;
02842 }
02843
02857 dbus_bool_t
02858 dbus_message_set_destination (DBusMessage *message,
02859 const char *destination)
02860 {
02861 _dbus_return_val_if_fail (message != NULL, FALSE);
02862 _dbus_return_val_if_fail (!message->locked, FALSE);
02863 _dbus_return_val_if_fail (destination == NULL ||
02864 _dbus_check_is_valid_bus_name (destination),
02865 FALSE);
02866
02867 return set_or_delete_string_field (message,
02868 DBUS_HEADER_FIELD_DESTINATION,
02869 DBUS_TYPE_STRING,
02870 destination);
02871 }
02872
02882 const char*
02883 dbus_message_get_destination (DBusMessage *message)
02884 {
02885 const char *v;
02886
02887 _dbus_return_val_if_fail (message != NULL, NULL);
02888
02889 v = NULL;
02890 _dbus_header_get_field_basic (&message->header,
02891 DBUS_HEADER_FIELD_DESTINATION,
02892 DBUS_TYPE_STRING,
02893 &v);
02894 return v;
02895 }
02896
02911 dbus_bool_t
02912 dbus_message_set_sender (DBusMessage *message,
02913 const char *sender)
02914 {
02915 _dbus_return_val_if_fail (message != NULL, FALSE);
02916 _dbus_return_val_if_fail (!message->locked, FALSE);
02917 _dbus_return_val_if_fail (sender == NULL ||
02918 _dbus_check_is_valid_bus_name (sender),
02919 FALSE);
02920
02921 return set_or_delete_string_field (message,
02922 DBUS_HEADER_FIELD_SENDER,
02923 DBUS_TYPE_STRING,
02924 sender);
02925 }
02926
02942 const char*
02943 dbus_message_get_sender (DBusMessage *message)
02944 {
02945 const char *v;
02946
02947 _dbus_return_val_if_fail (message != NULL, NULL);
02948
02949 v = NULL;
02950 _dbus_header_get_field_basic (&message->header,
02951 DBUS_HEADER_FIELD_SENDER,
02952 DBUS_TYPE_STRING,
02953 &v);
02954 return v;
02955 }
02956
02975 const char*
02976 dbus_message_get_signature (DBusMessage *message)
02977 {
02978 const DBusString *type_str;
02979 int type_pos;
02980
02981 _dbus_return_val_if_fail (message != NULL, NULL);
02982
02983 get_const_signature (&message->header, &type_str, &type_pos);
02984
02985 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
02986 }
02987
02988 static dbus_bool_t
02989 _dbus_message_has_type_interface_member (DBusMessage *message,
02990 int type,
02991 const char *interface,
02992 const char *member)
02993 {
02994 const char *n;
02995
02996 _dbus_assert (message != NULL);
02997 _dbus_assert (interface != NULL);
02998 _dbus_assert (member != NULL);
02999
03000 if (dbus_message_get_type (message) != type)
03001 return FALSE;
03002
03003
03004
03005
03006
03007 n = dbus_message_get_member (message);
03008
03009 if (n && strcmp (n, member) == 0)
03010 {
03011 n = dbus_message_get_interface (message);
03012
03013 if (n == NULL || strcmp (n, interface) == 0)
03014 return TRUE;
03015 }
03016
03017 return FALSE;
03018 }
03019
03034 dbus_bool_t
03035 dbus_message_is_method_call (DBusMessage *message,
03036 const char *interface,
03037 const char *method)
03038 {
03039 _dbus_return_val_if_fail (message != NULL, FALSE);
03040 _dbus_return_val_if_fail (interface != NULL, FALSE);
03041 _dbus_return_val_if_fail (method != NULL, FALSE);
03042
03043
03044
03045
03046 return _dbus_message_has_type_interface_member (message,
03047 DBUS_MESSAGE_TYPE_METHOD_CALL,
03048 interface, method);
03049 }
03050
03062 dbus_bool_t
03063 dbus_message_is_signal (DBusMessage *message,
03064 const char *interface,
03065 const char *signal_name)
03066 {
03067 _dbus_return_val_if_fail (message != NULL, FALSE);
03068 _dbus_return_val_if_fail (interface != NULL, FALSE);
03069 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03070
03071
03072
03073
03074 return _dbus_message_has_type_interface_member (message,
03075 DBUS_MESSAGE_TYPE_SIGNAL,
03076 interface, signal_name);
03077 }
03078
03089 dbus_bool_t
03090 dbus_message_is_error (DBusMessage *message,
03091 const char *error_name)
03092 {
03093 const char *n;
03094
03095 _dbus_return_val_if_fail (message != NULL, FALSE);
03096 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03097
03098
03099
03100
03101 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03102 return FALSE;
03103
03104 n = dbus_message_get_error_name (message);
03105
03106 if (n && strcmp (n, error_name) == 0)
03107 return TRUE;
03108 else
03109 return FALSE;
03110 }
03111
03122 dbus_bool_t
03123 dbus_message_has_destination (DBusMessage *message,
03124 const char *name)
03125 {
03126 const char *s;
03127
03128 _dbus_return_val_if_fail (message != NULL, FALSE);
03129 _dbus_return_val_if_fail (name != NULL, FALSE);
03130
03131
03132
03133
03134 s = dbus_message_get_destination (message);
03135
03136 if (s && strcmp (s, name) == 0)
03137 return TRUE;
03138 else
03139 return FALSE;
03140 }
03141
03157 dbus_bool_t
03158 dbus_message_has_sender (DBusMessage *message,
03159 const char *name)
03160 {
03161 const char *s;
03162
03163 _dbus_return_val_if_fail (message != NULL, FALSE);
03164 _dbus_return_val_if_fail (name != NULL, FALSE);
03165
03166
03167
03168
03169 s = dbus_message_get_sender (message);
03170
03171 if (s && strcmp (s, name) == 0)
03172 return TRUE;
03173 else
03174 return FALSE;
03175 }
03176
03186 dbus_bool_t
03187 dbus_message_has_signature (DBusMessage *message,
03188 const char *signature)
03189 {
03190 const char *s;
03191
03192 _dbus_return_val_if_fail (message != NULL, FALSE);
03193 _dbus_return_val_if_fail (signature != NULL, FALSE);
03194
03195
03196
03197
03198 s = dbus_message_get_signature (message);
03199
03200 if (s && strcmp (s, signature) == 0)
03201 return TRUE;
03202 else
03203 return FALSE;
03204 }
03205
03228 dbus_bool_t
03229 dbus_set_error_from_message (DBusError *error,
03230 DBusMessage *message)
03231 {
03232 const char *str;
03233
03234 _dbus_return_val_if_fail (message != NULL, FALSE);
03235 _dbus_return_val_if_error_is_set (error, FALSE);
03236
03237 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03238 return FALSE;
03239
03240 str = NULL;
03241 dbus_message_get_args (message, NULL,
03242 DBUS_TYPE_STRING, &str,
03243 DBUS_TYPE_INVALID);
03244
03245 dbus_set_error (error, dbus_message_get_error_name (message),
03246 str ? "%s" : NULL, str);
03247
03248 return TRUE;
03249 }
03250
03269 #define INITIAL_LOADER_DATA_LEN 32
03270
03277 DBusMessageLoader*
03278 _dbus_message_loader_new (void)
03279 {
03280 DBusMessageLoader *loader;
03281
03282 loader = dbus_new0 (DBusMessageLoader, 1);
03283 if (loader == NULL)
03284 return NULL;
03285
03286 loader->refcount = 1;
03287
03288 loader->corrupted = FALSE;
03289 loader->corruption_reason = DBUS_VALID;
03290
03291
03292 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03293
03294 if (!_dbus_string_init (&loader->data))
03295 {
03296 dbus_free (loader);
03297 return NULL;
03298 }
03299
03300
03301 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03302 _dbus_string_set_length (&loader->data, 0);
03303
03304 return loader;
03305 }
03306
03313 DBusMessageLoader *
03314 _dbus_message_loader_ref (DBusMessageLoader *loader)
03315 {
03316 loader->refcount += 1;
03317
03318 return loader;
03319 }
03320
03327 void
03328 _dbus_message_loader_unref (DBusMessageLoader *loader)
03329 {
03330 loader->refcount -= 1;
03331 if (loader->refcount == 0)
03332 {
03333 _dbus_list_foreach (&loader->messages,
03334 (DBusForeachFunction) dbus_message_unref,
03335 NULL);
03336 _dbus_list_clear (&loader->messages);
03337 _dbus_string_free (&loader->data);
03338 dbus_free (loader);
03339 }
03340 }
03341
03360 void
03361 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03362 DBusString **buffer)
03363 {
03364 _dbus_assert (!loader->buffer_outstanding);
03365
03366 *buffer = &loader->data;
03367
03368 loader->buffer_outstanding = TRUE;
03369 }
03370
03381 void
03382 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03383 DBusString *buffer,
03384 int bytes_read)
03385 {
03386 _dbus_assert (loader->buffer_outstanding);
03387 _dbus_assert (buffer == &loader->data);
03388
03389 loader->buffer_outstanding = FALSE;
03390 }
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418 static dbus_bool_t
03419 load_message (DBusMessageLoader *loader,
03420 DBusMessage *message,
03421 int byte_order,
03422 int fields_array_len,
03423 int header_len,
03424 int body_len)
03425 {
03426 dbus_bool_t oom;
03427 DBusValidity validity;
03428 const DBusString *type_str;
03429 int type_pos;
03430 DBusValidationMode mode;
03431
03432 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03433
03434 oom = FALSE;
03435
03436 #if 0
03437 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03438 #endif
03439
03440
03441 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03442 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03443
03444 if (!_dbus_header_load (&message->header,
03445 mode,
03446 &validity,
03447 byte_order,
03448 fields_array_len,
03449 header_len,
03450 body_len,
03451 &loader->data, 0,
03452 _dbus_string_get_length (&loader->data)))
03453 {
03454 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03455
03456
03457
03458 _dbus_assert (validity != DBUS_VALID);
03459
03460 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03461 oom = TRUE;
03462 else
03463 {
03464 loader->corrupted = TRUE;
03465 loader->corruption_reason = validity;
03466 }
03467 goto failed;
03468 }
03469
03470 _dbus_assert (validity == DBUS_VALID);
03471
03472 message->byte_order = byte_order;
03473
03474
03475 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03476 {
03477 get_const_signature (&message->header, &type_str, &type_pos);
03478
03479
03480
03481
03482 validity = _dbus_validate_body_with_reason (type_str,
03483 type_pos,
03484 byte_order,
03485 NULL,
03486 &loader->data,
03487 header_len,
03488 body_len);
03489 if (validity != DBUS_VALID)
03490 {
03491 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03492
03493 loader->corrupted = TRUE;
03494 loader->corruption_reason = validity;
03495
03496 goto failed;
03497 }
03498 }
03499
03500
03501
03502 if (!_dbus_list_append (&loader->messages, message))
03503 {
03504 _dbus_verbose ("Failed to append new message to loader queue\n");
03505 oom = TRUE;
03506 goto failed;
03507 }
03508
03509 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03510 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03511 (header_len + body_len));
03512
03513 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03514 {
03515 _dbus_verbose ("Failed to move body into new message\n");
03516 oom = TRUE;
03517 goto failed;
03518 }
03519
03520 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03521
03522 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03523 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03524
03525 _dbus_verbose ("Loaded message %p\n", message);
03526
03527 _dbus_assert (!oom);
03528 _dbus_assert (!loader->corrupted);
03529 _dbus_assert (loader->messages != NULL);
03530 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03531
03532 return TRUE;
03533
03534 failed:
03535
03536
03537
03538
03539 _dbus_list_remove_last (&loader->messages, message);
03540
03541 if (oom)
03542 _dbus_assert (!loader->corrupted);
03543 else
03544 _dbus_assert (loader->corrupted);
03545
03546 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03547
03548 return FALSE;
03549 }
03550
03565 dbus_bool_t
03566 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03567 {
03568 while (!loader->corrupted &&
03569 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03570 {
03571 DBusValidity validity;
03572 int byte_order, fields_array_len, header_len, body_len;
03573
03574 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03575 &validity,
03576 &byte_order,
03577 &fields_array_len,
03578 &header_len,
03579 &body_len,
03580 &loader->data, 0,
03581 _dbus_string_get_length (&loader->data)))
03582 {
03583 DBusMessage *message;
03584
03585 _dbus_assert (validity == DBUS_VALID);
03586
03587 message = dbus_message_new_empty_header ();
03588 if (message == NULL)
03589 return FALSE;
03590
03591 if (!load_message (loader, message,
03592 byte_order, fields_array_len,
03593 header_len, body_len))
03594 {
03595 dbus_message_unref (message);
03596
03597
03598
03599 return loader->corrupted;
03600 }
03601
03602 _dbus_assert (loader->messages != NULL);
03603 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03604 }
03605 else
03606 {
03607 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03608 validity);
03609 if (validity != DBUS_VALID)
03610 {
03611 loader->corrupted = TRUE;
03612 loader->corruption_reason = validity;
03613 }
03614 return TRUE;
03615 }
03616 }
03617
03618 return TRUE;
03619 }
03620
03628 DBusMessage*
03629 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03630 {
03631 if (loader->messages)
03632 return loader->messages->data;
03633 else
03634 return NULL;
03635 }
03636
03645 DBusMessage*
03646 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03647 {
03648 return _dbus_list_pop_first (&loader->messages);
03649 }
03650
03659 DBusList*
03660 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03661 {
03662 return _dbus_list_pop_first_link (&loader->messages);
03663 }
03664
03671 void
03672 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03673 DBusList *link)
03674 {
03675 _dbus_list_prepend_link (&loader->messages, link);
03676 }
03677
03687 dbus_bool_t
03688 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03689 {
03690 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03691 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03692 return loader->corrupted;
03693 }
03694
03701 void
03702 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03703 long size)
03704 {
03705 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03706 {
03707 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03708 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03709 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03710 }
03711 loader->max_message_size = size;
03712 }
03713
03720 long
03721 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03722 {
03723 return loader->max_message_size;
03724 }
03725
03726 static DBusDataSlotAllocator slot_allocator;
03727 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03728
03743 dbus_bool_t
03744 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03745 {
03746 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03747 &_DBUS_LOCK_NAME (message_slots),
03748 slot_p);
03749 }
03750
03762 void
03763 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03764 {
03765 _dbus_return_if_fail (*slot_p >= 0);
03766
03767 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03768 }
03769
03783 dbus_bool_t
03784 dbus_message_set_data (DBusMessage *message,
03785 dbus_int32_t slot,
03786 void *data,
03787 DBusFreeFunction free_data_func)
03788 {
03789 DBusFreeFunction old_free_func;
03790 void *old_data;
03791 dbus_bool_t retval;
03792
03793 _dbus_return_val_if_fail (message != NULL, FALSE);
03794 _dbus_return_val_if_fail (slot >= 0, FALSE);
03795
03796 retval = _dbus_data_slot_list_set (&slot_allocator,
03797 &message->slot_list,
03798 slot, data, free_data_func,
03799 &old_free_func, &old_data);
03800
03801 if (retval)
03802 {
03803
03804 if (old_free_func)
03805 (* old_free_func) (old_data);
03806 }
03807
03808 return retval;
03809 }
03810
03819 void*
03820 dbus_message_get_data (DBusMessage *message,
03821 dbus_int32_t slot)
03822 {
03823 void *res;
03824
03825 _dbus_return_val_if_fail (message != NULL, NULL);
03826
03827 res = _dbus_data_slot_list_get (&slot_allocator,
03828 &message->slot_list,
03829 slot);
03830
03831 return res;
03832 }
03833
03847 int
03848 dbus_message_type_from_string (const char *type_str)
03849 {
03850 if (strcmp (type_str, "method_call") == 0)
03851 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03852 if (strcmp (type_str, "method_return") == 0)
03853 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03854 else if (strcmp (type_str, "signal") == 0)
03855 return DBUS_MESSAGE_TYPE_SIGNAL;
03856 else if (strcmp (type_str, "error") == 0)
03857 return DBUS_MESSAGE_TYPE_ERROR;
03858 else
03859 return DBUS_MESSAGE_TYPE_INVALID;
03860 }
03861
03875 const char *
03876 dbus_message_type_to_string (int type)
03877 {
03878 switch (type)
03879 {
03880 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03881 return "method_call";
03882 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03883 return "method_return";
03884 case DBUS_MESSAGE_TYPE_SIGNAL:
03885 return "signal";
03886 case DBUS_MESSAGE_TYPE_ERROR:
03887 return "error";
03888 default:
03889 return "invalid";
03890 }
03891 }
03892
03895