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
01872 void
01873 dbus_message_iter_recurse (DBusMessageIter *iter,
01874 DBusMessageIter *sub)
01875 {
01876 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01877 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01878
01879 _dbus_return_if_fail (_dbus_message_iter_check (real));
01880 _dbus_return_if_fail (sub != NULL);
01881
01882 *real_sub = *real;
01883 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01884 }
01885
01897 char *
01898 dbus_message_iter_get_signature (DBusMessageIter *iter)
01899 {
01900 const DBusString *sig;
01901 DBusString retstr;
01902 char *ret;
01903 int start, len;
01904 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01905
01906 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01907
01908 if (!_dbus_string_init (&retstr))
01909 return NULL;
01910
01911 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01912 &start, &len);
01913 if (!_dbus_string_append_len (&retstr,
01914 _dbus_string_get_const_data (sig) + start,
01915 len))
01916 return NULL;
01917 if (!_dbus_string_steal_data (&retstr, &ret))
01918 return NULL;
01919 _dbus_string_free (&retstr);
01920 return ret;
01921 }
01922
01963 void
01964 dbus_message_iter_get_basic (DBusMessageIter *iter,
01965 void *value)
01966 {
01967 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01968
01969 _dbus_return_if_fail (_dbus_message_iter_check (real));
01970 _dbus_return_if_fail (value != NULL);
01971
01972 _dbus_type_reader_read_basic (&real->u.reader,
01973 value);
01974 }
01975
01994 int
01995 dbus_message_iter_get_array_len (DBusMessageIter *iter)
01996 {
01997 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01998
01999 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02000
02001 return _dbus_type_reader_get_array_length (&real->u.reader);
02002 }
02003
02035 void
02036 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02037 void *value,
02038 int *n_elements)
02039 {
02040 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02041 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02042
02043 _dbus_return_if_fail (_dbus_message_iter_check (real));
02044 _dbus_return_if_fail (value != NULL);
02045 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02046 dbus_type_is_fixed (subtype));
02047
02048 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02049 value, n_elements);
02050 }
02051
02063 void
02064 dbus_message_iter_init_append (DBusMessage *message,
02065 DBusMessageIter *iter)
02066 {
02067 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02068
02069 _dbus_return_if_fail (message != NULL);
02070 _dbus_return_if_fail (iter != NULL);
02071
02072 _dbus_message_iter_init_common (message, real,
02073 DBUS_MESSAGE_ITER_TYPE_WRITER);
02074
02075
02076
02077
02078
02079 _dbus_type_writer_init_types_delayed (&real->u.writer,
02080 message->byte_order,
02081 &message->body,
02082 _dbus_string_get_length (&message->body));
02083 }
02084
02093 static dbus_bool_t
02094 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02095 {
02096 DBusString *str;
02097 const DBusString *current_sig;
02098 int current_sig_pos;
02099
02100 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02101
02102 if (real->u.writer.type_str != NULL)
02103 {
02104 _dbus_assert (real->sig_refcount > 0);
02105 real->sig_refcount += 1;
02106 return TRUE;
02107 }
02108
02109 str = dbus_new (DBusString, 1);
02110 if (str == NULL)
02111 return FALSE;
02112
02113 if (!_dbus_header_get_field_raw (&real->message->header,
02114 DBUS_HEADER_FIELD_SIGNATURE,
02115 ¤t_sig, ¤t_sig_pos))
02116 current_sig = NULL;
02117
02118 if (current_sig)
02119 {
02120 int current_len;
02121
02122 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02123 current_sig_pos += 1;
02124
02125 if (!_dbus_string_init_preallocated (str, current_len + 4))
02126 {
02127 dbus_free (str);
02128 return FALSE;
02129 }
02130
02131 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02132 str, 0))
02133 {
02134 _dbus_string_free (str);
02135 dbus_free (str);
02136 return FALSE;
02137 }
02138 }
02139 else
02140 {
02141 if (!_dbus_string_init_preallocated (str, 4))
02142 {
02143 dbus_free (str);
02144 return FALSE;
02145 }
02146 }
02147
02148 real->sig_refcount = 1;
02149
02150 _dbus_type_writer_add_types (&real->u.writer,
02151 str, _dbus_string_get_length (str));
02152 return TRUE;
02153 }
02154
02164 static dbus_bool_t
02165 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02166 {
02167 DBusString *str;
02168 const char *v_STRING;
02169 dbus_bool_t retval;
02170
02171 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02172 _dbus_assert (real->u.writer.type_str != NULL);
02173 _dbus_assert (real->sig_refcount > 0);
02174
02175 real->sig_refcount -= 1;
02176
02177 if (real->sig_refcount > 0)
02178 return TRUE;
02179 _dbus_assert (real->sig_refcount == 0);
02180
02181 retval = TRUE;
02182
02183 str = real->u.writer.type_str;
02184
02185 v_STRING = _dbus_string_get_const_data (str);
02186 if (!_dbus_header_set_field_basic (&real->message->header,
02187 DBUS_HEADER_FIELD_SIGNATURE,
02188 DBUS_TYPE_SIGNATURE,
02189 &v_STRING))
02190 retval = FALSE;
02191
02192 _dbus_type_writer_remove_types (&real->u.writer);
02193 _dbus_string_free (str);
02194 dbus_free (str);
02195
02196 return retval;
02197 }
02198
02199 #ifndef DBUS_DISABLE_CHECKS
02200 static dbus_bool_t
02201 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02202 {
02203 if (!_dbus_message_iter_check (iter))
02204 return FALSE;
02205
02206 if (iter->message->locked)
02207 {
02208 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02209 return FALSE;
02210 }
02211
02212 return TRUE;
02213 }
02214 #endif
02215
02231 dbus_bool_t
02232 dbus_message_iter_append_basic (DBusMessageIter *iter,
02233 int type,
02234 const void *value)
02235 {
02236 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02237 dbus_bool_t ret;
02238
02239 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02240 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02241 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02242 _dbus_return_val_if_fail (value != NULL, FALSE);
02243
02244 if (!_dbus_message_iter_open_signature (real))
02245 return FALSE;
02246
02247 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02248
02249 if (!_dbus_message_iter_close_signature (real))
02250 ret = FALSE;
02251
02252 return ret;
02253 }
02254
02290 dbus_bool_t
02291 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02292 int element_type,
02293 const void *value,
02294 int n_elements)
02295 {
02296 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02297 dbus_bool_t ret;
02298
02299 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02300 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02301 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02302 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02303 _dbus_return_val_if_fail (value != NULL, FALSE);
02304 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02305 _dbus_return_val_if_fail (n_elements <=
02306 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02307 FALSE);
02308
02309 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02310
02311 return ret;
02312 }
02313
02335 dbus_bool_t
02336 dbus_message_iter_open_container (DBusMessageIter *iter,
02337 int type,
02338 const char *contained_signature,
02339 DBusMessageIter *sub)
02340 {
02341 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02342 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02343 DBusString contained_str;
02344
02345 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02346 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02347 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02348 _dbus_return_val_if_fail (sub != NULL, FALSE);
02349 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02350 contained_signature == NULL) ||
02351 (type == DBUS_TYPE_DICT_ENTRY &&
02352 contained_signature == NULL) ||
02353 (type == DBUS_TYPE_VARIANT &&
02354 contained_signature != NULL) ||
02355 (type == DBUS_TYPE_ARRAY &&
02356 contained_signature != NULL), FALSE);
02357
02358
02359
02360
02361
02362 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02363 (contained_signature == NULL ||
02364 _dbus_check_is_valid_signature (contained_signature)),
02365 FALSE);
02366
02367 if (!_dbus_message_iter_open_signature (real))
02368 return FALSE;
02369
02370 *real_sub = *real;
02371
02372 if (contained_signature != NULL)
02373 {
02374 _dbus_string_init_const (&contained_str, contained_signature);
02375
02376 return _dbus_type_writer_recurse (&real->u.writer,
02377 type,
02378 &contained_str, 0,
02379 &real_sub->u.writer);
02380 }
02381 else
02382 {
02383 return _dbus_type_writer_recurse (&real->u.writer,
02384 type,
02385 NULL, 0,
02386 &real_sub->u.writer);
02387 }
02388 }
02389
02390
02404 dbus_bool_t
02405 dbus_message_iter_close_container (DBusMessageIter *iter,
02406 DBusMessageIter *sub)
02407 {
02408 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02409 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02410 dbus_bool_t ret;
02411
02412 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02413 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02414 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02415 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02416
02417 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02418 &real_sub->u.writer);
02419
02420 if (!_dbus_message_iter_close_signature (real))
02421 ret = FALSE;
02422
02423 return ret;
02424 }
02425
02442 void
02443 dbus_message_set_no_reply (DBusMessage *message,
02444 dbus_bool_t no_reply)
02445 {
02446 _dbus_return_if_fail (message != NULL);
02447 _dbus_return_if_fail (!message->locked);
02448
02449 _dbus_header_toggle_flag (&message->header,
02450 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02451 no_reply);
02452 }
02453
02461 dbus_bool_t
02462 dbus_message_get_no_reply (DBusMessage *message)
02463 {
02464 _dbus_return_val_if_fail (message != NULL, FALSE);
02465
02466 return _dbus_header_get_flag (&message->header,
02467 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02468 }
02469
02484 void
02485 dbus_message_set_auto_start (DBusMessage *message,
02486 dbus_bool_t auto_start)
02487 {
02488 _dbus_return_if_fail (message != NULL);
02489 _dbus_return_if_fail (!message->locked);
02490
02491 _dbus_header_toggle_flag (&message->header,
02492 DBUS_HEADER_FLAG_NO_AUTO_START,
02493 !auto_start);
02494 }
02495
02503 dbus_bool_t
02504 dbus_message_get_auto_start (DBusMessage *message)
02505 {
02506 _dbus_return_val_if_fail (message != NULL, FALSE);
02507
02508 return !_dbus_header_get_flag (&message->header,
02509 DBUS_HEADER_FLAG_NO_AUTO_START);
02510 }
02511
02512
02525 dbus_bool_t
02526 dbus_message_set_path (DBusMessage *message,
02527 const char *object_path)
02528 {
02529 _dbus_return_val_if_fail (message != NULL, FALSE);
02530 _dbus_return_val_if_fail (!message->locked, FALSE);
02531 _dbus_return_val_if_fail (object_path == NULL ||
02532 _dbus_check_is_valid_path (object_path),
02533 FALSE);
02534
02535 return set_or_delete_string_field (message,
02536 DBUS_HEADER_FIELD_PATH,
02537 DBUS_TYPE_OBJECT_PATH,
02538 object_path);
02539 }
02540
02554 const char*
02555 dbus_message_get_path (DBusMessage *message)
02556 {
02557 const char *v;
02558
02559 _dbus_return_val_if_fail (message != NULL, NULL);
02560
02561 v = NULL;
02562 _dbus_header_get_field_basic (&message->header,
02563 DBUS_HEADER_FIELD_PATH,
02564 DBUS_TYPE_OBJECT_PATH,
02565 &v);
02566 return v;
02567 }
02568
02578 dbus_bool_t
02579 dbus_message_has_path (DBusMessage *message,
02580 const char *path)
02581 {
02582 const char *msg_path;
02583 msg_path = dbus_message_get_path (message);
02584
02585 if (msg_path == NULL)
02586 {
02587 if (path == NULL)
02588 return TRUE;
02589 else
02590 return FALSE;
02591 }
02592
02593 if (path == NULL)
02594 return FALSE;
02595
02596 if (strcmp (msg_path, path) == 0)
02597 return TRUE;
02598
02599 return FALSE;
02600 }
02601
02622 dbus_bool_t
02623 dbus_message_get_path_decomposed (DBusMessage *message,
02624 char ***path)
02625 {
02626 const char *v;
02627
02628 _dbus_return_val_if_fail (message != NULL, FALSE);
02629 _dbus_return_val_if_fail (path != NULL, FALSE);
02630
02631 *path = NULL;
02632
02633 v = dbus_message_get_path (message);
02634 if (v != NULL)
02635 {
02636 if (!_dbus_decompose_path (v, strlen (v),
02637 path, NULL))
02638 return FALSE;
02639 }
02640 return TRUE;
02641 }
02642
02656 dbus_bool_t
02657 dbus_message_set_interface (DBusMessage *message,
02658 const char *interface)
02659 {
02660 _dbus_return_val_if_fail (message != NULL, FALSE);
02661 _dbus_return_val_if_fail (!message->locked, FALSE);
02662 _dbus_return_val_if_fail (interface == NULL ||
02663 _dbus_check_is_valid_interface (interface),
02664 FALSE);
02665
02666 return set_or_delete_string_field (message,
02667 DBUS_HEADER_FIELD_INTERFACE,
02668 DBUS_TYPE_STRING,
02669 interface);
02670 }
02671
02685 const char*
02686 dbus_message_get_interface (DBusMessage *message)
02687 {
02688 const char *v;
02689
02690 _dbus_return_val_if_fail (message != NULL, NULL);
02691
02692 v = NULL;
02693 _dbus_header_get_field_basic (&message->header,
02694 DBUS_HEADER_FIELD_INTERFACE,
02695 DBUS_TYPE_STRING,
02696 &v);
02697 return v;
02698 }
02699
02707 dbus_bool_t
02708 dbus_message_has_interface (DBusMessage *message,
02709 const char *interface)
02710 {
02711 const char *msg_interface;
02712 msg_interface = dbus_message_get_interface (message);
02713
02714 if (msg_interface == NULL)
02715 {
02716 if (interface == NULL)
02717 return TRUE;
02718 else
02719 return FALSE;
02720 }
02721
02722 if (interface == NULL)
02723 return FALSE;
02724
02725 if (strcmp (msg_interface, interface) == 0)
02726 return TRUE;
02727
02728 return FALSE;
02729
02730 }
02731
02744 dbus_bool_t
02745 dbus_message_set_member (DBusMessage *message,
02746 const char *member)
02747 {
02748 _dbus_return_val_if_fail (message != NULL, FALSE);
02749 _dbus_return_val_if_fail (!message->locked, FALSE);
02750 _dbus_return_val_if_fail (member == NULL ||
02751 _dbus_check_is_valid_member (member),
02752 FALSE);
02753
02754 return set_or_delete_string_field (message,
02755 DBUS_HEADER_FIELD_MEMBER,
02756 DBUS_TYPE_STRING,
02757 member);
02758 }
02759
02771 const char*
02772 dbus_message_get_member (DBusMessage *message)
02773 {
02774 const char *v;
02775
02776 _dbus_return_val_if_fail (message != NULL, NULL);
02777
02778 v = NULL;
02779 _dbus_header_get_field_basic (&message->header,
02780 DBUS_HEADER_FIELD_MEMBER,
02781 DBUS_TYPE_STRING,
02782 &v);
02783 return v;
02784 }
02785
02793 dbus_bool_t
02794 dbus_message_has_member (DBusMessage *message,
02795 const char *member)
02796 {
02797 const char *msg_member;
02798 msg_member = dbus_message_get_member (message);
02799
02800 if (msg_member == NULL)
02801 {
02802 if (member == NULL)
02803 return TRUE;
02804 else
02805 return FALSE;
02806 }
02807
02808 if (member == NULL)
02809 return FALSE;
02810
02811 if (strcmp (msg_member, member) == 0)
02812 return TRUE;
02813
02814 return FALSE;
02815
02816 }
02817
02829 dbus_bool_t
02830 dbus_message_set_error_name (DBusMessage *message,
02831 const char *error_name)
02832 {
02833 _dbus_return_val_if_fail (message != NULL, FALSE);
02834 _dbus_return_val_if_fail (!message->locked, FALSE);
02835 _dbus_return_val_if_fail (error_name == NULL ||
02836 _dbus_check_is_valid_error_name (error_name),
02837 FALSE);
02838
02839 return set_or_delete_string_field (message,
02840 DBUS_HEADER_FIELD_ERROR_NAME,
02841 DBUS_TYPE_STRING,
02842 error_name);
02843 }
02844
02855 const char*
02856 dbus_message_get_error_name (DBusMessage *message)
02857 {
02858 const char *v;
02859
02860 _dbus_return_val_if_fail (message != NULL, NULL);
02861
02862 v = NULL;
02863 _dbus_header_get_field_basic (&message->header,
02864 DBUS_HEADER_FIELD_ERROR_NAME,
02865 DBUS_TYPE_STRING,
02866 &v);
02867 return v;
02868 }
02869
02883 dbus_bool_t
02884 dbus_message_set_destination (DBusMessage *message,
02885 const char *destination)
02886 {
02887 _dbus_return_val_if_fail (message != NULL, FALSE);
02888 _dbus_return_val_if_fail (!message->locked, FALSE);
02889 _dbus_return_val_if_fail (destination == NULL ||
02890 _dbus_check_is_valid_bus_name (destination),
02891 FALSE);
02892
02893 return set_or_delete_string_field (message,
02894 DBUS_HEADER_FIELD_DESTINATION,
02895 DBUS_TYPE_STRING,
02896 destination);
02897 }
02898
02908 const char*
02909 dbus_message_get_destination (DBusMessage *message)
02910 {
02911 const char *v;
02912
02913 _dbus_return_val_if_fail (message != NULL, NULL);
02914
02915 v = NULL;
02916 _dbus_header_get_field_basic (&message->header,
02917 DBUS_HEADER_FIELD_DESTINATION,
02918 DBUS_TYPE_STRING,
02919 &v);
02920 return v;
02921 }
02922
02937 dbus_bool_t
02938 dbus_message_set_sender (DBusMessage *message,
02939 const char *sender)
02940 {
02941 _dbus_return_val_if_fail (message != NULL, FALSE);
02942 _dbus_return_val_if_fail (!message->locked, FALSE);
02943 _dbus_return_val_if_fail (sender == NULL ||
02944 _dbus_check_is_valid_bus_name (sender),
02945 FALSE);
02946
02947 return set_or_delete_string_field (message,
02948 DBUS_HEADER_FIELD_SENDER,
02949 DBUS_TYPE_STRING,
02950 sender);
02951 }
02952
02968 const char*
02969 dbus_message_get_sender (DBusMessage *message)
02970 {
02971 const char *v;
02972
02973 _dbus_return_val_if_fail (message != NULL, NULL);
02974
02975 v = NULL;
02976 _dbus_header_get_field_basic (&message->header,
02977 DBUS_HEADER_FIELD_SENDER,
02978 DBUS_TYPE_STRING,
02979 &v);
02980 return v;
02981 }
02982
03001 const char*
03002 dbus_message_get_signature (DBusMessage *message)
03003 {
03004 const DBusString *type_str;
03005 int type_pos;
03006
03007 _dbus_return_val_if_fail (message != NULL, NULL);
03008
03009 get_const_signature (&message->header, &type_str, &type_pos);
03010
03011 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03012 }
03013
03014 static dbus_bool_t
03015 _dbus_message_has_type_interface_member (DBusMessage *message,
03016 int type,
03017 const char *interface,
03018 const char *member)
03019 {
03020 const char *n;
03021
03022 _dbus_assert (message != NULL);
03023 _dbus_assert (interface != NULL);
03024 _dbus_assert (member != NULL);
03025
03026 if (dbus_message_get_type (message) != type)
03027 return FALSE;
03028
03029
03030
03031
03032
03033 n = dbus_message_get_member (message);
03034
03035 if (n && strcmp (n, member) == 0)
03036 {
03037 n = dbus_message_get_interface (message);
03038
03039 if (n == NULL || strcmp (n, interface) == 0)
03040 return TRUE;
03041 }
03042
03043 return FALSE;
03044 }
03045
03060 dbus_bool_t
03061 dbus_message_is_method_call (DBusMessage *message,
03062 const char *interface,
03063 const char *method)
03064 {
03065 _dbus_return_val_if_fail (message != NULL, FALSE);
03066 _dbus_return_val_if_fail (interface != NULL, FALSE);
03067 _dbus_return_val_if_fail (method != NULL, FALSE);
03068
03069
03070
03071
03072 return _dbus_message_has_type_interface_member (message,
03073 DBUS_MESSAGE_TYPE_METHOD_CALL,
03074 interface, method);
03075 }
03076
03088 dbus_bool_t
03089 dbus_message_is_signal (DBusMessage *message,
03090 const char *interface,
03091 const char *signal_name)
03092 {
03093 _dbus_return_val_if_fail (message != NULL, FALSE);
03094 _dbus_return_val_if_fail (interface != NULL, FALSE);
03095 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03096
03097
03098
03099
03100 return _dbus_message_has_type_interface_member (message,
03101 DBUS_MESSAGE_TYPE_SIGNAL,
03102 interface, signal_name);
03103 }
03104
03115 dbus_bool_t
03116 dbus_message_is_error (DBusMessage *message,
03117 const char *error_name)
03118 {
03119 const char *n;
03120
03121 _dbus_return_val_if_fail (message != NULL, FALSE);
03122 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03123
03124
03125
03126
03127 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03128 return FALSE;
03129
03130 n = dbus_message_get_error_name (message);
03131
03132 if (n && strcmp (n, error_name) == 0)
03133 return TRUE;
03134 else
03135 return FALSE;
03136 }
03137
03148 dbus_bool_t
03149 dbus_message_has_destination (DBusMessage *message,
03150 const char *name)
03151 {
03152 const char *s;
03153
03154 _dbus_return_val_if_fail (message != NULL, FALSE);
03155 _dbus_return_val_if_fail (name != NULL, FALSE);
03156
03157
03158
03159
03160 s = dbus_message_get_destination (message);
03161
03162 if (s && strcmp (s, name) == 0)
03163 return TRUE;
03164 else
03165 return FALSE;
03166 }
03167
03183 dbus_bool_t
03184 dbus_message_has_sender (DBusMessage *message,
03185 const char *name)
03186 {
03187 const char *s;
03188
03189 _dbus_return_val_if_fail (message != NULL, FALSE);
03190 _dbus_return_val_if_fail (name != NULL, FALSE);
03191
03192
03193
03194
03195 s = dbus_message_get_sender (message);
03196
03197 if (s && strcmp (s, name) == 0)
03198 return TRUE;
03199 else
03200 return FALSE;
03201 }
03202
03212 dbus_bool_t
03213 dbus_message_has_signature (DBusMessage *message,
03214 const char *signature)
03215 {
03216 const char *s;
03217
03218 _dbus_return_val_if_fail (message != NULL, FALSE);
03219 _dbus_return_val_if_fail (signature != NULL, FALSE);
03220
03221
03222
03223
03224 s = dbus_message_get_signature (message);
03225
03226 if (s && strcmp (s, signature) == 0)
03227 return TRUE;
03228 else
03229 return FALSE;
03230 }
03231
03254 dbus_bool_t
03255 dbus_set_error_from_message (DBusError *error,
03256 DBusMessage *message)
03257 {
03258 const char *str;
03259
03260 _dbus_return_val_if_fail (message != NULL, FALSE);
03261 _dbus_return_val_if_error_is_set (error, FALSE);
03262
03263 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03264 return FALSE;
03265
03266 str = NULL;
03267 dbus_message_get_args (message, NULL,
03268 DBUS_TYPE_STRING, &str,
03269 DBUS_TYPE_INVALID);
03270
03271 dbus_set_error (error, dbus_message_get_error_name (message),
03272 str ? "%s" : NULL, str);
03273
03274 return TRUE;
03275 }
03276
03295 #define INITIAL_LOADER_DATA_LEN 32
03296
03303 DBusMessageLoader*
03304 _dbus_message_loader_new (void)
03305 {
03306 DBusMessageLoader *loader;
03307
03308 loader = dbus_new0 (DBusMessageLoader, 1);
03309 if (loader == NULL)
03310 return NULL;
03311
03312 loader->refcount = 1;
03313
03314 loader->corrupted = FALSE;
03315 loader->corruption_reason = DBUS_VALID;
03316
03317
03318 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03319
03320 if (!_dbus_string_init (&loader->data))
03321 {
03322 dbus_free (loader);
03323 return NULL;
03324 }
03325
03326
03327 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03328 _dbus_string_set_length (&loader->data, 0);
03329
03330 return loader;
03331 }
03332
03339 DBusMessageLoader *
03340 _dbus_message_loader_ref (DBusMessageLoader *loader)
03341 {
03342 loader->refcount += 1;
03343
03344 return loader;
03345 }
03346
03353 void
03354 _dbus_message_loader_unref (DBusMessageLoader *loader)
03355 {
03356 loader->refcount -= 1;
03357 if (loader->refcount == 0)
03358 {
03359 _dbus_list_foreach (&loader->messages,
03360 (DBusForeachFunction) dbus_message_unref,
03361 NULL);
03362 _dbus_list_clear (&loader->messages);
03363 _dbus_string_free (&loader->data);
03364 dbus_free (loader);
03365 }
03366 }
03367
03386 void
03387 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03388 DBusString **buffer)
03389 {
03390 _dbus_assert (!loader->buffer_outstanding);
03391
03392 *buffer = &loader->data;
03393
03394 loader->buffer_outstanding = TRUE;
03395 }
03396
03407 void
03408 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03409 DBusString *buffer,
03410 int bytes_read)
03411 {
03412 _dbus_assert (loader->buffer_outstanding);
03413 _dbus_assert (buffer == &loader->data);
03414
03415 loader->buffer_outstanding = FALSE;
03416 }
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444 static dbus_bool_t
03445 load_message (DBusMessageLoader *loader,
03446 DBusMessage *message,
03447 int byte_order,
03448 int fields_array_len,
03449 int header_len,
03450 int body_len)
03451 {
03452 dbus_bool_t oom;
03453 DBusValidity validity;
03454 const DBusString *type_str;
03455 int type_pos;
03456 DBusValidationMode mode;
03457
03458 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03459
03460 oom = FALSE;
03461
03462 #if 0
03463 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03464 #endif
03465
03466
03467 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03468 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03469
03470 if (!_dbus_header_load (&message->header,
03471 mode,
03472 &validity,
03473 byte_order,
03474 fields_array_len,
03475 header_len,
03476 body_len,
03477 &loader->data, 0,
03478 _dbus_string_get_length (&loader->data)))
03479 {
03480 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03481
03482
03483
03484 _dbus_assert (validity != DBUS_VALID);
03485
03486 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03487 oom = TRUE;
03488 else
03489 {
03490 loader->corrupted = TRUE;
03491 loader->corruption_reason = validity;
03492 }
03493 goto failed;
03494 }
03495
03496 _dbus_assert (validity == DBUS_VALID);
03497
03498 message->byte_order = byte_order;
03499
03500
03501 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03502 {
03503 get_const_signature (&message->header, &type_str, &type_pos);
03504
03505
03506
03507
03508 validity = _dbus_validate_body_with_reason (type_str,
03509 type_pos,
03510 byte_order,
03511 NULL,
03512 &loader->data,
03513 header_len,
03514 body_len);
03515 if (validity != DBUS_VALID)
03516 {
03517 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03518
03519 loader->corrupted = TRUE;
03520 loader->corruption_reason = validity;
03521
03522 goto failed;
03523 }
03524 }
03525
03526
03527
03528 if (!_dbus_list_append (&loader->messages, message))
03529 {
03530 _dbus_verbose ("Failed to append new message to loader queue\n");
03531 oom = TRUE;
03532 goto failed;
03533 }
03534
03535 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03536 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03537 (header_len + body_len));
03538
03539 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03540 {
03541 _dbus_verbose ("Failed to move body into new message\n");
03542 oom = TRUE;
03543 goto failed;
03544 }
03545
03546 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03547
03548
03549 _dbus_string_compact (&loader->data, 2048);
03550
03551 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03552 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03553
03554 _dbus_verbose ("Loaded message %p\n", message);
03555
03556 _dbus_assert (!oom);
03557 _dbus_assert (!loader->corrupted);
03558 _dbus_assert (loader->messages != NULL);
03559 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03560
03561 return TRUE;
03562
03563 failed:
03564
03565
03566
03567
03568 _dbus_list_remove_last (&loader->messages, message);
03569
03570 if (oom)
03571 _dbus_assert (!loader->corrupted);
03572 else
03573 _dbus_assert (loader->corrupted);
03574
03575 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03576
03577 return FALSE;
03578 }
03579
03594 dbus_bool_t
03595 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03596 {
03597 while (!loader->corrupted &&
03598 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03599 {
03600 DBusValidity validity;
03601 int byte_order, fields_array_len, header_len, body_len;
03602
03603 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03604 &validity,
03605 &byte_order,
03606 &fields_array_len,
03607 &header_len,
03608 &body_len,
03609 &loader->data, 0,
03610 _dbus_string_get_length (&loader->data)))
03611 {
03612 DBusMessage *message;
03613
03614 _dbus_assert (validity == DBUS_VALID);
03615
03616 message = dbus_message_new_empty_header ();
03617 if (message == NULL)
03618 return FALSE;
03619
03620 if (!load_message (loader, message,
03621 byte_order, fields_array_len,
03622 header_len, body_len))
03623 {
03624 dbus_message_unref (message);
03625
03626
03627
03628 return loader->corrupted;
03629 }
03630
03631 _dbus_assert (loader->messages != NULL);
03632 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03633 }
03634 else
03635 {
03636 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03637 validity);
03638 if (validity != DBUS_VALID)
03639 {
03640 loader->corrupted = TRUE;
03641 loader->corruption_reason = validity;
03642 }
03643 return TRUE;
03644 }
03645 }
03646
03647 return TRUE;
03648 }
03649
03657 DBusMessage*
03658 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03659 {
03660 if (loader->messages)
03661 return loader->messages->data;
03662 else
03663 return NULL;
03664 }
03665
03674 DBusMessage*
03675 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03676 {
03677 return _dbus_list_pop_first (&loader->messages);
03678 }
03679
03688 DBusList*
03689 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03690 {
03691 return _dbus_list_pop_first_link (&loader->messages);
03692 }
03693
03700 void
03701 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03702 DBusList *link)
03703 {
03704 _dbus_list_prepend_link (&loader->messages, link);
03705 }
03706
03716 dbus_bool_t
03717 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03718 {
03719 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03720 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03721 return loader->corrupted;
03722 }
03723
03730 void
03731 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03732 long size)
03733 {
03734 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03735 {
03736 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03737 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03738 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03739 }
03740 loader->max_message_size = size;
03741 }
03742
03749 long
03750 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03751 {
03752 return loader->max_message_size;
03753 }
03754
03755 static DBusDataSlotAllocator slot_allocator;
03756 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03757
03772 dbus_bool_t
03773 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03774 {
03775 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03776 &_DBUS_LOCK_NAME (message_slots),
03777 slot_p);
03778 }
03779
03791 void
03792 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03793 {
03794 _dbus_return_if_fail (*slot_p >= 0);
03795
03796 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03797 }
03798
03812 dbus_bool_t
03813 dbus_message_set_data (DBusMessage *message,
03814 dbus_int32_t slot,
03815 void *data,
03816 DBusFreeFunction free_data_func)
03817 {
03818 DBusFreeFunction old_free_func;
03819 void *old_data;
03820 dbus_bool_t retval;
03821
03822 _dbus_return_val_if_fail (message != NULL, FALSE);
03823 _dbus_return_val_if_fail (slot >= 0, FALSE);
03824
03825 retval = _dbus_data_slot_list_set (&slot_allocator,
03826 &message->slot_list,
03827 slot, data, free_data_func,
03828 &old_free_func, &old_data);
03829
03830 if (retval)
03831 {
03832
03833 if (old_free_func)
03834 (* old_free_func) (old_data);
03835 }
03836
03837 return retval;
03838 }
03839
03848 void*
03849 dbus_message_get_data (DBusMessage *message,
03850 dbus_int32_t slot)
03851 {
03852 void *res;
03853
03854 _dbus_return_val_if_fail (message != NULL, NULL);
03855
03856 res = _dbus_data_slot_list_get (&slot_allocator,
03857 &message->slot_list,
03858 slot);
03859
03860 return res;
03861 }
03862
03876 int
03877 dbus_message_type_from_string (const char *type_str)
03878 {
03879 if (strcmp (type_str, "method_call") == 0)
03880 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03881 if (strcmp (type_str, "method_return") == 0)
03882 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03883 else if (strcmp (type_str, "signal") == 0)
03884 return DBUS_MESSAGE_TYPE_SIGNAL;
03885 else if (strcmp (type_str, "error") == 0)
03886 return DBUS_MESSAGE_TYPE_ERROR;
03887 else
03888 return DBUS_MESSAGE_TYPE_INVALID;
03889 }
03890
03904 const char *
03905 dbus_message_type_to_string (int type)
03906 {
03907 switch (type)
03908 {
03909 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03910 return "method_call";
03911 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03912 return "method_return";
03913 case DBUS_MESSAGE_TYPE_SIGNAL:
03914 return "signal";
03915 case DBUS_MESSAGE_TYPE_ERROR:
03916 return "error";
03917 default:
03918 return "invalid";
03919 }
03920 }
03921
03934 dbus_bool_t
03935 dbus_message_marshal (DBusMessage *msg,
03936 char **marshalled_data_p,
03937 int *len_p)
03938 {
03939 DBusString tmp;
03940
03941 _dbus_return_val_if_fail (msg != NULL, FALSE);
03942 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
03943 _dbus_return_val_if_fail (len_p != NULL, FALSE);
03944
03945 if (!_dbus_string_init (&tmp))
03946 return FALSE;
03947
03948 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
03949 goto fail;
03950
03951 *len_p = _dbus_string_get_length (&tmp);
03952
03953 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
03954 goto fail;
03955
03956 *len_p = _dbus_string_get_length (&tmp);
03957
03958 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
03959 goto fail;
03960
03961 _dbus_string_free (&tmp);
03962 return TRUE;
03963
03964 fail:
03965 _dbus_string_free (&tmp);
03966 return FALSE;
03967 }
03968
03981 DBusMessage *
03982 dbus_message_demarshal (const char *str,
03983 int len,
03984 DBusError *error)
03985 {
03986 DBusMessageLoader *loader;
03987 DBusString *buffer;
03988 DBusMessage *msg;
03989
03990 _dbus_return_val_if_fail (str != NULL, NULL);
03991
03992 loader = _dbus_message_loader_new ();
03993
03994 if (loader == NULL)
03995 return NULL;
03996
03997 _dbus_message_loader_get_buffer (loader, &buffer);
03998 _dbus_string_append_len (buffer, str, len);
03999 _dbus_message_loader_return_buffer (loader, buffer, len);
04000
04001 if (!_dbus_message_loader_queue_messages (loader))
04002 goto fail_oom;
04003
04004 if (_dbus_message_loader_get_is_corrupted (loader))
04005 goto fail_corrupt;
04006
04007 msg = _dbus_message_loader_pop_message (loader);
04008
04009 if (!msg)
04010 goto fail_oom;
04011
04012 _dbus_message_loader_unref (loader);
04013 return msg;
04014
04015 fail_corrupt:
04016 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted");
04017 _dbus_message_loader_unref (loader);
04018 return NULL;
04019
04020 fail_oom:
04021 _DBUS_SET_OOM (error);
04022 _dbus_message_loader_unref (loader);
04023 return NULL;
04024 }
04025
04028