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
00173 void
00174 dbus_message_set_serial (DBusMessage *message,
00175 dbus_uint32_t serial)
00176 {
00177 _dbus_return_if_fail (message != NULL);
00178 _dbus_return_if_fail (!message->locked);
00179
00180 _dbus_header_set_serial (&message->header, serial);
00181 }
00182
00195 void
00196 _dbus_message_add_size_counter_link (DBusMessage *message,
00197 DBusList *link)
00198 {
00199
00200
00201
00202
00203
00204
00205 if (message->size_counters == NULL)
00206 {
00207 message->size_counter_delta =
00208 _dbus_string_get_length (&message->header.data) +
00209 _dbus_string_get_length (&message->body);
00210
00211 #if 0
00212 _dbus_verbose ("message has size %ld\n",
00213 message->size_counter_delta);
00214 #endif
00215 }
00216
00217 _dbus_list_append_link (&message->size_counters, link);
00218
00219 _dbus_counter_adjust (link->data, message->size_counter_delta);
00220 }
00221
00231 dbus_bool_t
00232 _dbus_message_add_size_counter (DBusMessage *message,
00233 DBusCounter *counter)
00234 {
00235 DBusList *link;
00236
00237 link = _dbus_list_alloc_link (counter);
00238 if (link == NULL)
00239 return FALSE;
00240
00241 _dbus_counter_ref (counter);
00242 _dbus_message_add_size_counter_link (message, link);
00243
00244 return TRUE;
00245 }
00246
00255 void
00256 _dbus_message_remove_size_counter (DBusMessage *message,
00257 DBusCounter *counter,
00258 DBusList **link_return)
00259 {
00260 DBusList *link;
00261
00262 link = _dbus_list_find_last (&message->size_counters,
00263 counter);
00264 _dbus_assert (link != NULL);
00265
00266 _dbus_list_unlink (&message->size_counters,
00267 link);
00268 if (link_return)
00269 *link_return = link;
00270 else
00271 _dbus_list_free_link (link);
00272
00273 _dbus_counter_adjust (counter, - message->size_counter_delta);
00274
00275 _dbus_counter_unref (counter);
00276 }
00277
00288 void
00289 dbus_message_lock (DBusMessage *message)
00290 {
00291 if (!message->locked)
00292 {
00293 _dbus_header_update_lengths (&message->header,
00294 _dbus_string_get_length (&message->body));
00295
00296
00297 _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
00298 dbus_message_get_signature (message) != NULL);
00299
00300 message->locked = TRUE;
00301 }
00302 }
00303
00304 static dbus_bool_t
00305 set_or_delete_string_field (DBusMessage *message,
00306 int field,
00307 int typecode,
00308 const char *value)
00309 {
00310 if (value == NULL)
00311 return _dbus_header_delete_field (&message->header, field);
00312 else
00313 return _dbus_header_set_field_basic (&message->header,
00314 field,
00315 typecode,
00316 &value);
00317 }
00318
00319 #if 0
00320
00344 static dbus_bool_t
00345 _dbus_message_set_signature (DBusMessage *message,
00346 const char *signature)
00347 {
00348 _dbus_return_val_if_fail (message != NULL, FALSE);
00349 _dbus_return_val_if_fail (!message->locked, FALSE);
00350 _dbus_return_val_if_fail (signature == NULL ||
00351 _dbus_check_is_valid_signature (signature));
00352
00353 _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
00354 signature != NULL);
00355
00356 return set_or_delete_string_field (message,
00357 DBUS_HEADER_FIELD_SIGNATURE,
00358 DBUS_TYPE_SIGNATURE,
00359 signature);
00360 }
00361 #endif
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
00405
00406
00407
00408
00410 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
00411
00413 #define MAX_MESSAGE_CACHE_SIZE 5
00414
00415 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
00416 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
00417 static int message_cache_count = 0;
00418 static dbus_bool_t message_cache_shutdown_registered = FALSE;
00419
00420 static void
00421 dbus_message_cache_shutdown (void *data)
00422 {
00423 int i;
00424
00425 _DBUS_LOCK (message_cache);
00426
00427 i = 0;
00428 while (i < MAX_MESSAGE_CACHE_SIZE)
00429 {
00430 if (message_cache[i])
00431 dbus_message_finalize (message_cache[i]);
00432
00433 ++i;
00434 }
00435
00436 message_cache_count = 0;
00437 message_cache_shutdown_registered = FALSE;
00438
00439 _DBUS_UNLOCK (message_cache);
00440 }
00441
00449 static DBusMessage*
00450 dbus_message_get_cached (void)
00451 {
00452 DBusMessage *message;
00453 int i;
00454
00455 message = NULL;
00456
00457 _DBUS_LOCK (message_cache);
00458
00459 _dbus_assert (message_cache_count >= 0);
00460
00461 if (message_cache_count == 0)
00462 {
00463 _DBUS_UNLOCK (message_cache);
00464 return NULL;
00465 }
00466
00467
00468
00469
00470
00471 _dbus_assert (message_cache_shutdown_registered);
00472
00473 i = 0;
00474 while (i < MAX_MESSAGE_CACHE_SIZE)
00475 {
00476 if (message_cache[i])
00477 {
00478 message = message_cache[i];
00479 message_cache[i] = NULL;
00480 message_cache_count -= 1;
00481 break;
00482 }
00483 ++i;
00484 }
00485 _dbus_assert (message_cache_count >= 0);
00486 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00487 _dbus_assert (message != NULL);
00488
00489 _dbus_assert (message->refcount.value == 0);
00490 _dbus_assert (message->size_counters == NULL);
00491
00492 _DBUS_UNLOCK (message_cache);
00493
00494 return message;
00495 }
00496
00497 static void
00498 free_size_counter (void *element,
00499 void *data)
00500 {
00501 DBusCounter *counter = element;
00502 DBusMessage *message = data;
00503
00504 _dbus_counter_adjust (counter, - message->size_counter_delta);
00505
00506 _dbus_counter_unref (counter);
00507 }
00508
00514 static void
00515 dbus_message_cache_or_finalize (DBusMessage *message)
00516 {
00517 dbus_bool_t was_cached;
00518 int i;
00519
00520 _dbus_assert (message->refcount.value == 0);
00521
00522
00523
00524
00525 _dbus_data_slot_list_clear (&message->slot_list);
00526
00527 _dbus_list_foreach (&message->size_counters,
00528 free_size_counter, message);
00529 _dbus_list_clear (&message->size_counters);
00530
00531 was_cached = FALSE;
00532
00533 _DBUS_LOCK (message_cache);
00534
00535 if (!message_cache_shutdown_registered)
00536 {
00537 _dbus_assert (message_cache_count == 0);
00538
00539 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
00540 goto out;
00541
00542 i = 0;
00543 while (i < MAX_MESSAGE_CACHE_SIZE)
00544 {
00545 message_cache[i] = NULL;
00546 ++i;
00547 }
00548
00549 message_cache_shutdown_registered = TRUE;
00550 }
00551
00552 _dbus_assert (message_cache_count >= 0);
00553
00554 if ((_dbus_string_get_length (&message->header.data) +
00555 _dbus_string_get_length (&message->body)) >
00556 MAX_MESSAGE_SIZE_TO_CACHE)
00557 goto out;
00558
00559 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
00560 goto out;
00561
00562
00563 i = 0;
00564 while (message_cache[i] != NULL)
00565 ++i;
00566
00567 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
00568
00569 _dbus_assert (message_cache[i] == NULL);
00570 message_cache[i] = message;
00571 message_cache_count += 1;
00572 was_cached = TRUE;
00573 #ifndef DBUS_DISABLE_CHECKS
00574 message->in_cache = TRUE;
00575 #endif
00576
00577 out:
00578 _dbus_assert (message->refcount.value == 0);
00579
00580 _DBUS_UNLOCK (message_cache);
00581
00582 if (!was_cached)
00583 dbus_message_finalize (message);
00584 }
00585
00586 #ifndef DBUS_DISABLE_CHECKS
00587 static dbus_bool_t
00588 _dbus_message_iter_check (DBusMessageRealIter *iter)
00589 {
00590 if (iter == NULL)
00591 {
00592 _dbus_warn_check_failed ("dbus message iterator is NULL\n");
00593 return FALSE;
00594 }
00595
00596 if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
00597 {
00598 if (iter->u.reader.byte_order != iter->message->byte_order)
00599 {
00600 _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
00601 return FALSE;
00602 }
00603
00604 _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
00605 }
00606 else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
00607 {
00608 if (iter->u.writer.byte_order != iter->message->byte_order)
00609 {
00610 _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
00611 return FALSE;
00612 }
00613
00614 _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
00615 }
00616 else
00617 {
00618 _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
00619 return FALSE;
00620 }
00621
00622 if (iter->changed_stamp != iter->message->changed_stamp)
00623 {
00624 _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
00625 return FALSE;
00626 }
00627
00628 return TRUE;
00629 }
00630 #endif
00631
00644 dbus_bool_t
00645 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
00646 DBusError *error,
00647 int first_arg_type,
00648 va_list var_args)
00649 {
00650 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
00651 int spec_type, msg_type, i;
00652 dbus_bool_t retval;
00653
00654 _dbus_assert (_dbus_message_iter_check (real));
00655
00656 retval = FALSE;
00657
00658 spec_type = first_arg_type;
00659 i = 0;
00660
00661 while (spec_type != DBUS_TYPE_INVALID)
00662 {
00663 msg_type = dbus_message_iter_get_arg_type (iter);
00664
00665 if (msg_type != spec_type)
00666 {
00667 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00668 "Argument %d is specified to be of type \"%s\", but "
00669 "is actually of type \"%s\"\n", i,
00670 _dbus_type_to_string (spec_type),
00671 _dbus_type_to_string (msg_type));
00672
00673 goto out;
00674 }
00675
00676 if (dbus_type_is_basic (spec_type))
00677 {
00678 DBusBasicValue *ptr;
00679
00680 ptr = va_arg (var_args, DBusBasicValue*);
00681
00682 _dbus_assert (ptr != NULL);
00683
00684 _dbus_type_reader_read_basic (&real->u.reader,
00685 ptr);
00686 }
00687 else if (spec_type == DBUS_TYPE_ARRAY)
00688 {
00689 int element_type;
00690 int spec_element_type;
00691 const DBusBasicValue **ptr;
00692 int *n_elements_p;
00693 DBusTypeReader array;
00694
00695 spec_element_type = va_arg (var_args, int);
00696 element_type = _dbus_type_reader_get_element_type (&real->u.reader);
00697
00698 if (spec_element_type != element_type)
00699 {
00700 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00701 "Argument %d is specified to be an array of \"%s\", but "
00702 "is actually an array of \"%s\"\n",
00703 i,
00704 _dbus_type_to_string (spec_element_type),
00705 _dbus_type_to_string (element_type));
00706
00707 goto out;
00708 }
00709
00710 if (dbus_type_is_fixed (spec_element_type))
00711 {
00712 ptr = va_arg (var_args, const DBusBasicValue**);
00713 n_elements_p = va_arg (var_args, int*);
00714
00715 _dbus_assert (ptr != NULL);
00716 _dbus_assert (n_elements_p != NULL);
00717
00718 _dbus_type_reader_recurse (&real->u.reader, &array);
00719
00720 _dbus_type_reader_read_fixed_multi (&array,
00721 ptr, n_elements_p);
00722 }
00723 else if (spec_element_type == DBUS_TYPE_STRING ||
00724 spec_element_type == DBUS_TYPE_SIGNATURE ||
00725 spec_element_type == DBUS_TYPE_OBJECT_PATH)
00726 {
00727 char ***str_array_p;
00728 int n_elements;
00729 char **str_array;
00730
00731 str_array_p = va_arg (var_args, char***);
00732 n_elements_p = va_arg (var_args, int*);
00733
00734 _dbus_assert (str_array_p != NULL);
00735 _dbus_assert (n_elements_p != NULL);
00736
00737
00738 _dbus_type_reader_recurse (&real->u.reader, &array);
00739
00740 n_elements = 0;
00741 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00742 {
00743 ++n_elements;
00744 _dbus_type_reader_next (&array);
00745 }
00746
00747 str_array = dbus_new0 (char*, n_elements + 1);
00748 if (str_array == NULL)
00749 {
00750 _DBUS_SET_OOM (error);
00751 goto out;
00752 }
00753
00754
00755 _dbus_type_reader_recurse (&real->u.reader, &array);
00756
00757 i = 0;
00758 while (i < n_elements)
00759 {
00760 const char *s;
00761 _dbus_type_reader_read_basic (&array,
00762 &s);
00763
00764 str_array[i] = _dbus_strdup (s);
00765 if (str_array[i] == NULL)
00766 {
00767 dbus_free_string_array (str_array);
00768 _DBUS_SET_OOM (error);
00769 goto out;
00770 }
00771
00772 ++i;
00773
00774 if (!_dbus_type_reader_next (&array))
00775 _dbus_assert (i == n_elements);
00776 }
00777
00778 _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
00779 _dbus_assert (i == n_elements);
00780 _dbus_assert (str_array[i] == NULL);
00781
00782 *str_array_p = str_array;
00783 *n_elements_p = n_elements;
00784 }
00785 #ifndef DBUS_DISABLE_CHECKS
00786 else
00787 {
00788 _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
00789 _DBUS_FUNCTION_NAME);
00790 goto out;
00791 }
00792 #endif
00793 }
00794 #ifndef DBUS_DISABLE_CHECKS
00795 else
00796 {
00797 _dbus_warn ("you can only read arrays and basic types with %s for now\n",
00798 _DBUS_FUNCTION_NAME);
00799 goto out;
00800 }
00801 #endif
00802
00803 spec_type = va_arg (var_args, int);
00804 if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
00805 {
00806 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
00807 "Message has only %d arguments, but more were expected", i);
00808 goto out;
00809 }
00810
00811 i++;
00812 }
00813
00814 retval = TRUE;
00815
00816 out:
00817
00818 return retval;
00819 }
00820
00879 dbus_uint32_t
00880 dbus_message_get_serial (DBusMessage *message)
00881 {
00882 _dbus_return_val_if_fail (message != NULL, 0);
00883
00884 return _dbus_header_get_serial (&message->header);
00885 }
00886
00895 dbus_bool_t
00896 dbus_message_set_reply_serial (DBusMessage *message,
00897 dbus_uint32_t reply_serial)
00898 {
00899 _dbus_return_val_if_fail (message != NULL, FALSE);
00900 _dbus_return_val_if_fail (!message->locked, FALSE);
00901 _dbus_return_val_if_fail (reply_serial != 0, FALSE);
00902
00903 return _dbus_header_set_field_basic (&message->header,
00904 DBUS_HEADER_FIELD_REPLY_SERIAL,
00905 DBUS_TYPE_UINT32,
00906 &reply_serial);
00907 }
00908
00915 dbus_uint32_t
00916 dbus_message_get_reply_serial (DBusMessage *message)
00917 {
00918 dbus_uint32_t v_UINT32;
00919
00920 _dbus_return_val_if_fail (message != NULL, 0);
00921
00922 if (_dbus_header_get_field_basic (&message->header,
00923 DBUS_HEADER_FIELD_REPLY_SERIAL,
00924 DBUS_TYPE_UINT32,
00925 &v_UINT32))
00926 return v_UINT32;
00927 else
00928 return 0;
00929 }
00930
00931 static void
00932 dbus_message_finalize (DBusMessage *message)
00933 {
00934 _dbus_assert (message->refcount.value == 0);
00935
00936
00937 _dbus_data_slot_list_free (&message->slot_list);
00938
00939 _dbus_list_foreach (&message->size_counters,
00940 free_size_counter, message);
00941 _dbus_list_clear (&message->size_counters);
00942
00943 _dbus_header_free (&message->header);
00944 _dbus_string_free (&message->body);
00945
00946 _dbus_assert (message->refcount.value == 0);
00947
00948 dbus_free (message);
00949 }
00950
00951 static DBusMessage*
00952 dbus_message_new_empty_header (void)
00953 {
00954 DBusMessage *message;
00955 dbus_bool_t from_cache;
00956
00957 message = dbus_message_get_cached ();
00958
00959 if (message != NULL)
00960 {
00961 from_cache = TRUE;
00962 }
00963 else
00964 {
00965 from_cache = FALSE;
00966 message = dbus_new (DBusMessage, 1);
00967 if (message == NULL)
00968 return NULL;
00969 #ifndef DBUS_DISABLE_CHECKS
00970 message->generation = _dbus_current_generation;
00971 #endif
00972 }
00973
00974 message->refcount.value = 1;
00975 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
00976 message->locked = FALSE;
00977 #ifndef DBUS_DISABLE_CHECKS
00978 message->in_cache = FALSE;
00979 #endif
00980 message->size_counters = NULL;
00981 message->size_counter_delta = 0;
00982 message->changed_stamp = 0;
00983
00984 if (!from_cache)
00985 _dbus_data_slot_list_init (&message->slot_list);
00986
00987 if (from_cache)
00988 {
00989 _dbus_header_reinit (&message->header, message->byte_order);
00990 _dbus_string_set_length (&message->body, 0);
00991 }
00992 else
00993 {
00994 if (!_dbus_header_init (&message->header, message->byte_order))
00995 {
00996 dbus_free (message);
00997 return NULL;
00998 }
00999
01000 if (!_dbus_string_init_preallocated (&message->body, 32))
01001 {
01002 _dbus_header_free (&message->header);
01003 dbus_free (message);
01004 return NULL;
01005 }
01006 }
01007
01008 return message;
01009 }
01010
01023 DBusMessage*
01024 dbus_message_new (int message_type)
01025 {
01026 DBusMessage *message;
01027
01028 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01029
01030 message = dbus_message_new_empty_header ();
01031 if (message == NULL)
01032 return NULL;
01033
01034 if (!_dbus_header_create (&message->header,
01035 message_type,
01036 NULL, NULL, NULL, NULL, NULL))
01037 {
01038 dbus_message_unref (message);
01039 return NULL;
01040 }
01041
01042 return message;
01043 }
01044
01066 DBusMessage*
01067 dbus_message_new_method_call (const char *destination,
01068 const char *path,
01069 const char *interface,
01070 const char *method)
01071 {
01072 DBusMessage *message;
01073
01074 _dbus_return_val_if_fail (path != NULL, NULL);
01075 _dbus_return_val_if_fail (method != NULL, NULL);
01076 _dbus_return_val_if_fail (destination == NULL ||
01077 _dbus_check_is_valid_bus_name (destination), NULL);
01078 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01079 _dbus_return_val_if_fail (interface == NULL ||
01080 _dbus_check_is_valid_interface (interface), NULL);
01081 _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
01082
01083 message = dbus_message_new_empty_header ();
01084 if (message == NULL)
01085 return NULL;
01086
01087 if (!_dbus_header_create (&message->header,
01088 DBUS_MESSAGE_TYPE_METHOD_CALL,
01089 destination, path, interface, method, NULL))
01090 {
01091 dbus_message_unref (message);
01092 return NULL;
01093 }
01094
01095 return message;
01096 }
01097
01105 DBusMessage*
01106 dbus_message_new_method_return (DBusMessage *method_call)
01107 {
01108 DBusMessage *message;
01109 const char *sender;
01110
01111 _dbus_return_val_if_fail (method_call != NULL, NULL);
01112
01113 sender = dbus_message_get_sender (method_call);
01114
01115
01116
01117 message = dbus_message_new_empty_header ();
01118 if (message == NULL)
01119 return NULL;
01120
01121 if (!_dbus_header_create (&message->header,
01122 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01123 sender, NULL, NULL, NULL, NULL))
01124 {
01125 dbus_message_unref (message);
01126 return NULL;
01127 }
01128
01129 dbus_message_set_no_reply (message, TRUE);
01130
01131 if (!dbus_message_set_reply_serial (message,
01132 dbus_message_get_serial (method_call)))
01133 {
01134 dbus_message_unref (message);
01135 return NULL;
01136 }
01137
01138 return message;
01139 }
01140
01155 DBusMessage*
01156 dbus_message_new_signal (const char *path,
01157 const char *interface,
01158 const char *name)
01159 {
01160 DBusMessage *message;
01161
01162 _dbus_return_val_if_fail (path != NULL, NULL);
01163 _dbus_return_val_if_fail (interface != NULL, NULL);
01164 _dbus_return_val_if_fail (name != NULL, NULL);
01165 _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
01166 _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
01167 _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
01168
01169 message = dbus_message_new_empty_header ();
01170 if (message == NULL)
01171 return NULL;
01172
01173 if (!_dbus_header_create (&message->header,
01174 DBUS_MESSAGE_TYPE_SIGNAL,
01175 NULL, path, interface, name, NULL))
01176 {
01177 dbus_message_unref (message);
01178 return NULL;
01179 }
01180
01181 dbus_message_set_no_reply (message, TRUE);
01182
01183 return message;
01184 }
01185
01200 DBusMessage*
01201 dbus_message_new_error (DBusMessage *reply_to,
01202 const char *error_name,
01203 const char *error_message)
01204 {
01205 DBusMessage *message;
01206 const char *sender;
01207 DBusMessageIter iter;
01208
01209 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01210 _dbus_return_val_if_fail (error_name != NULL, NULL);
01211 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01212
01213 sender = dbus_message_get_sender (reply_to);
01214
01215
01216
01217
01218
01219 message = dbus_message_new_empty_header ();
01220 if (message == NULL)
01221 return NULL;
01222
01223 if (!_dbus_header_create (&message->header,
01224 DBUS_MESSAGE_TYPE_ERROR,
01225 sender, NULL, NULL, NULL, error_name))
01226 {
01227 dbus_message_unref (message);
01228 return NULL;
01229 }
01230
01231 dbus_message_set_no_reply (message, TRUE);
01232
01233 if (!dbus_message_set_reply_serial (message,
01234 dbus_message_get_serial (reply_to)))
01235 {
01236 dbus_message_unref (message);
01237 return NULL;
01238 }
01239
01240 if (error_message != NULL)
01241 {
01242 dbus_message_iter_init_append (message, &iter);
01243 if (!dbus_message_iter_append_basic (&iter,
01244 DBUS_TYPE_STRING,
01245 &error_message))
01246 {
01247 dbus_message_unref (message);
01248 return NULL;
01249 }
01250 }
01251
01252 return message;
01253 }
01254
01271 DBusMessage*
01272 dbus_message_new_error_printf (DBusMessage *reply_to,
01273 const char *error_name,
01274 const char *error_format,
01275 ...)
01276 {
01277 va_list args;
01278 DBusString str;
01279 DBusMessage *message;
01280
01281 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01282 _dbus_return_val_if_fail (error_name != NULL, NULL);
01283 _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
01284
01285 if (!_dbus_string_init (&str))
01286 return NULL;
01287
01288 va_start (args, error_format);
01289
01290 if (_dbus_string_append_printf_valist (&str, error_format, args))
01291 message = dbus_message_new_error (reply_to, error_name,
01292 _dbus_string_get_const_data (&str));
01293 else
01294 message = NULL;
01295
01296 _dbus_string_free (&str);
01297
01298 va_end (args);
01299
01300 return message;
01301 }
01302
01303
01314 DBusMessage *
01315 dbus_message_copy (const DBusMessage *message)
01316 {
01317 DBusMessage *retval;
01318
01319 _dbus_return_val_if_fail (message != NULL, NULL);
01320
01321 retval = dbus_new0 (DBusMessage, 1);
01322 if (retval == NULL)
01323 return NULL;
01324
01325 retval->refcount.value = 1;
01326 retval->byte_order = message->byte_order;
01327 retval->locked = FALSE;
01328 #ifndef DBUS_DISABLE_CHECKS
01329 retval->generation = message->generation;
01330 #endif
01331
01332 if (!_dbus_header_copy (&message->header, &retval->header))
01333 {
01334 dbus_free (retval);
01335 return NULL;
01336 }
01337
01338 if (!_dbus_string_init_preallocated (&retval->body,
01339 _dbus_string_get_length (&message->body)))
01340 {
01341 _dbus_header_free (&retval->header);
01342 dbus_free (retval);
01343 return NULL;
01344 }
01345
01346 if (!_dbus_string_copy (&message->body, 0,
01347 &retval->body, 0))
01348 goto failed_copy;
01349
01350 return retval;
01351
01352 failed_copy:
01353 _dbus_header_free (&retval->header);
01354 _dbus_string_free (&retval->body);
01355 dbus_free (retval);
01356
01357 return NULL;
01358 }
01359
01360
01368 DBusMessage *
01369 dbus_message_ref (DBusMessage *message)
01370 {
01371 dbus_int32_t old_refcount;
01372
01373 _dbus_return_val_if_fail (message != NULL, NULL);
01374 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
01375 _dbus_return_val_if_fail (!message->in_cache, NULL);
01376
01377 old_refcount = _dbus_atomic_inc (&message->refcount);
01378 _dbus_assert (old_refcount >= 1);
01379
01380 return message;
01381 }
01382
01390 void
01391 dbus_message_unref (DBusMessage *message)
01392 {
01393 dbus_int32_t old_refcount;
01394
01395 _dbus_return_if_fail (message != NULL);
01396 _dbus_return_if_fail (message->generation == _dbus_current_generation);
01397 _dbus_return_if_fail (!message->in_cache);
01398
01399 old_refcount = _dbus_atomic_dec (&message->refcount);
01400
01401 _dbus_assert (old_refcount >= 0);
01402
01403 if (old_refcount == 1)
01404 {
01405
01406 dbus_message_cache_or_finalize (message);
01407 }
01408 }
01409
01420 int
01421 dbus_message_get_type (DBusMessage *message)
01422 {
01423 _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
01424
01425 return _dbus_header_get_message_type (&message->header);
01426 }
01427
01485 dbus_bool_t
01486 dbus_message_append_args (DBusMessage *message,
01487 int first_arg_type,
01488 ...)
01489 {
01490 dbus_bool_t retval;
01491 va_list var_args;
01492
01493 _dbus_return_val_if_fail (message != NULL, FALSE);
01494
01495 va_start (var_args, first_arg_type);
01496 retval = dbus_message_append_args_valist (message,
01497 first_arg_type,
01498 var_args);
01499 va_end (var_args);
01500
01501 return retval;
01502 }
01503
01517 dbus_bool_t
01518 dbus_message_append_args_valist (DBusMessage *message,
01519 int first_arg_type,
01520 va_list var_args)
01521 {
01522 int type;
01523 DBusMessageIter iter;
01524
01525 _dbus_return_val_if_fail (message != NULL, FALSE);
01526
01527 type = first_arg_type;
01528
01529 dbus_message_iter_init_append (message, &iter);
01530
01531 while (type != DBUS_TYPE_INVALID)
01532 {
01533 if (dbus_type_is_basic (type))
01534 {
01535 const DBusBasicValue *value;
01536 value = va_arg (var_args, const DBusBasicValue*);
01537
01538 if (!dbus_message_iter_append_basic (&iter,
01539 type,
01540 value))
01541 goto failed;
01542 }
01543 else if (type == DBUS_TYPE_ARRAY)
01544 {
01545 int element_type;
01546 DBusMessageIter array;
01547 char buf[2];
01548
01549 element_type = va_arg (var_args, int);
01550
01551 buf[0] = element_type;
01552 buf[1] = '\0';
01553 if (!dbus_message_iter_open_container (&iter,
01554 DBUS_TYPE_ARRAY,
01555 buf,
01556 &array))
01557 goto failed;
01558
01559 if (dbus_type_is_fixed (element_type))
01560 {
01561 const DBusBasicValue **value;
01562 int n_elements;
01563
01564 value = va_arg (var_args, const DBusBasicValue**);
01565 n_elements = va_arg (var_args, int);
01566
01567 if (!dbus_message_iter_append_fixed_array (&array,
01568 element_type,
01569 value,
01570 n_elements)) {
01571 dbus_message_iter_abandon_container (&iter, &array);
01572 goto failed;
01573 }
01574 }
01575 else if (element_type == DBUS_TYPE_STRING ||
01576 element_type == DBUS_TYPE_SIGNATURE ||
01577 element_type == DBUS_TYPE_OBJECT_PATH)
01578 {
01579 const char ***value_p;
01580 const char **value;
01581 int n_elements;
01582 int i;
01583
01584 value_p = va_arg (var_args, const char***);
01585 n_elements = va_arg (var_args, int);
01586
01587 value = *value_p;
01588
01589 i = 0;
01590 while (i < n_elements)
01591 {
01592 if (!dbus_message_iter_append_basic (&array,
01593 element_type,
01594 &value[i])) {
01595 dbus_message_iter_abandon_container (&iter, &array);
01596 goto failed;
01597 }
01598 ++i;
01599 }
01600 }
01601 else
01602 {
01603 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01604 _dbus_type_to_string (element_type),
01605 _DBUS_FUNCTION_NAME);
01606 goto failed;
01607 }
01608
01609 if (!dbus_message_iter_close_container (&iter, &array))
01610 goto failed;
01611 }
01612 #ifndef DBUS_DISABLE_CHECKS
01613 else
01614 {
01615 _dbus_warn ("type %s isn't supported yet in %s\n",
01616 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01617 goto failed;
01618 }
01619 #endif
01620
01621 type = va_arg (var_args, int);
01622 }
01623
01624 return TRUE;
01625
01626 failed:
01627 return FALSE;
01628 }
01629
01665 dbus_bool_t
01666 dbus_message_get_args (DBusMessage *message,
01667 DBusError *error,
01668 int first_arg_type,
01669 ...)
01670 {
01671 dbus_bool_t retval;
01672 va_list var_args;
01673
01674 _dbus_return_val_if_fail (message != NULL, FALSE);
01675 _dbus_return_val_if_error_is_set (error, FALSE);
01676
01677 va_start (var_args, first_arg_type);
01678 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01679 va_end (var_args);
01680
01681 return retval;
01682 }
01683
01694 dbus_bool_t
01695 dbus_message_get_args_valist (DBusMessage *message,
01696 DBusError *error,
01697 int first_arg_type,
01698 va_list var_args)
01699 {
01700 DBusMessageIter iter;
01701
01702 _dbus_return_val_if_fail (message != NULL, FALSE);
01703 _dbus_return_val_if_error_is_set (error, FALSE);
01704
01705 dbus_message_iter_init (message, &iter);
01706 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01707 }
01708
01709 static void
01710 _dbus_message_iter_init_common (DBusMessage *message,
01711 DBusMessageRealIter *real,
01712 int iter_type)
01713 {
01714 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01715
01716
01717
01718
01719 ensure_byte_order (message);
01720
01721 real->message = message;
01722 real->changed_stamp = message->changed_stamp;
01723 real->iter_type = iter_type;
01724 real->sig_refcount = 0;
01725 }
01726
01749 dbus_bool_t
01750 dbus_message_iter_init (DBusMessage *message,
01751 DBusMessageIter *iter)
01752 {
01753 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01754 const DBusString *type_str;
01755 int type_pos;
01756
01757 _dbus_return_val_if_fail (message != NULL, FALSE);
01758 _dbus_return_val_if_fail (iter != NULL, FALSE);
01759
01760 get_const_signature (&message->header, &type_str, &type_pos);
01761
01762 _dbus_message_iter_init_common (message, real,
01763 DBUS_MESSAGE_ITER_TYPE_READER);
01764
01765 _dbus_type_reader_init (&real->u.reader,
01766 message->byte_order,
01767 type_str, type_pos,
01768 &message->body,
01769 0);
01770
01771 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01772 }
01773
01780 dbus_bool_t
01781 dbus_message_iter_has_next (DBusMessageIter *iter)
01782 {
01783 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01784
01785 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01786 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01787
01788 return _dbus_type_reader_has_next (&real->u.reader);
01789 }
01790
01799 dbus_bool_t
01800 dbus_message_iter_next (DBusMessageIter *iter)
01801 {
01802 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01803
01804 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01805 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01806
01807 return _dbus_type_reader_next (&real->u.reader);
01808 }
01809
01824 int
01825 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01826 {
01827 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01828
01829 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01830 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01831
01832 return _dbus_type_reader_get_current_type (&real->u.reader);
01833 }
01834
01843 int
01844 dbus_message_iter_get_element_type (DBusMessageIter *iter)
01845 {
01846 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01847
01848 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01849 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
01850 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
01851
01852 return _dbus_type_reader_get_element_type (&real->u.reader);
01853 }
01854
01880 void
01881 dbus_message_iter_recurse (DBusMessageIter *iter,
01882 DBusMessageIter *sub)
01883 {
01884 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01885 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01886
01887 _dbus_return_if_fail (_dbus_message_iter_check (real));
01888 _dbus_return_if_fail (sub != NULL);
01889
01890 *real_sub = *real;
01891 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01892 }
01893
01905 char *
01906 dbus_message_iter_get_signature (DBusMessageIter *iter)
01907 {
01908 const DBusString *sig;
01909 DBusString retstr;
01910 char *ret;
01911 int start, len;
01912 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01913
01914 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01915
01916 if (!_dbus_string_init (&retstr))
01917 return NULL;
01918
01919 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01920 &start, &len);
01921 if (!_dbus_string_append_len (&retstr,
01922 _dbus_string_get_const_data (sig) + start,
01923 len))
01924 return NULL;
01925 if (!_dbus_string_steal_data (&retstr, &ret))
01926 return NULL;
01927 _dbus_string_free (&retstr);
01928 return ret;
01929 }
01930
01971 void
01972 dbus_message_iter_get_basic (DBusMessageIter *iter,
01973 void *value)
01974 {
01975 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01976
01977 _dbus_return_if_fail (_dbus_message_iter_check (real));
01978 _dbus_return_if_fail (value != NULL);
01979
01980 _dbus_type_reader_read_basic (&real->u.reader,
01981 value);
01982 }
01983
02002 int
02003 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02004 {
02005 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02006
02007 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02008
02009 return _dbus_type_reader_get_array_length (&real->u.reader);
02010 }
02011
02043 void
02044 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02045 void *value,
02046 int *n_elements)
02047 {
02048 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02049 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02050
02051 _dbus_return_if_fail (_dbus_message_iter_check (real));
02052 _dbus_return_if_fail (value != NULL);
02053 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02054 dbus_type_is_fixed (subtype));
02055
02056 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02057 value, n_elements);
02058 }
02059
02071 void
02072 dbus_message_iter_init_append (DBusMessage *message,
02073 DBusMessageIter *iter)
02074 {
02075 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02076
02077 _dbus_return_if_fail (message != NULL);
02078 _dbus_return_if_fail (iter != NULL);
02079
02080 _dbus_message_iter_init_common (message, real,
02081 DBUS_MESSAGE_ITER_TYPE_WRITER);
02082
02083
02084
02085
02086
02087 _dbus_type_writer_init_types_delayed (&real->u.writer,
02088 message->byte_order,
02089 &message->body,
02090 _dbus_string_get_length (&message->body));
02091 }
02092
02101 static dbus_bool_t
02102 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02103 {
02104 DBusString *str;
02105 const DBusString *current_sig;
02106 int current_sig_pos;
02107
02108 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02109
02110 if (real->u.writer.type_str != NULL)
02111 {
02112 _dbus_assert (real->sig_refcount > 0);
02113 real->sig_refcount += 1;
02114 return TRUE;
02115 }
02116
02117 str = dbus_new (DBusString, 1);
02118 if (str == NULL)
02119 return FALSE;
02120
02121 if (!_dbus_header_get_field_raw (&real->message->header,
02122 DBUS_HEADER_FIELD_SIGNATURE,
02123 ¤t_sig, ¤t_sig_pos))
02124 current_sig = NULL;
02125
02126 if (current_sig)
02127 {
02128 int current_len;
02129
02130 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02131 current_sig_pos += 1;
02132
02133 if (!_dbus_string_init_preallocated (str, current_len + 4))
02134 {
02135 dbus_free (str);
02136 return FALSE;
02137 }
02138
02139 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02140 str, 0))
02141 {
02142 _dbus_string_free (str);
02143 dbus_free (str);
02144 return FALSE;
02145 }
02146 }
02147 else
02148 {
02149 if (!_dbus_string_init_preallocated (str, 4))
02150 {
02151 dbus_free (str);
02152 return FALSE;
02153 }
02154 }
02155
02156 real->sig_refcount = 1;
02157
02158 _dbus_type_writer_add_types (&real->u.writer,
02159 str, _dbus_string_get_length (str));
02160 return TRUE;
02161 }
02162
02172 static dbus_bool_t
02173 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02174 {
02175 DBusString *str;
02176 const char *v_STRING;
02177 dbus_bool_t retval;
02178
02179 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02180 _dbus_assert (real->u.writer.type_str != NULL);
02181 _dbus_assert (real->sig_refcount > 0);
02182
02183 real->sig_refcount -= 1;
02184
02185 if (real->sig_refcount > 0)
02186 return TRUE;
02187 _dbus_assert (real->sig_refcount == 0);
02188
02189 retval = TRUE;
02190
02191 str = real->u.writer.type_str;
02192
02193 v_STRING = _dbus_string_get_const_data (str);
02194 if (!_dbus_header_set_field_basic (&real->message->header,
02195 DBUS_HEADER_FIELD_SIGNATURE,
02196 DBUS_TYPE_SIGNATURE,
02197 &v_STRING))
02198 retval = FALSE;
02199
02200 _dbus_type_writer_remove_types (&real->u.writer);
02201 _dbus_string_free (str);
02202 dbus_free (str);
02203
02204 return retval;
02205 }
02206
02214 static void
02215 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
02216 {
02217 DBusString *str;
02218
02219 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02220 _dbus_assert (real->u.writer.type_str != NULL);
02221 _dbus_assert (real->sig_refcount > 0);
02222
02223 real->sig_refcount -= 1;
02224
02225 if (real->sig_refcount > 0)
02226 return;
02227 _dbus_assert (real->sig_refcount == 0);
02228
02229 str = real->u.writer.type_str;
02230
02231 _dbus_type_writer_remove_types (&real->u.writer);
02232 _dbus_string_free (str);
02233 dbus_free (str);
02234 }
02235
02236 #ifndef DBUS_DISABLE_CHECKS
02237 static dbus_bool_t
02238 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02239 {
02240 if (!_dbus_message_iter_check (iter))
02241 return FALSE;
02242
02243 if (iter->message->locked)
02244 {
02245 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02246 return FALSE;
02247 }
02248
02249 return TRUE;
02250 }
02251 #endif
02252
02268 dbus_bool_t
02269 dbus_message_iter_append_basic (DBusMessageIter *iter,
02270 int type,
02271 const void *value)
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_basic (type), FALSE);
02279 _dbus_return_val_if_fail (value != NULL, FALSE);
02280
02281 if (!_dbus_message_iter_open_signature (real))
02282 return FALSE;
02283
02284 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02285
02286 if (!_dbus_message_iter_close_signature (real))
02287 ret = FALSE;
02288
02289 return ret;
02290 }
02291
02327 dbus_bool_t
02328 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02329 int element_type,
02330 const void *value,
02331 int n_elements)
02332 {
02333 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02334 dbus_bool_t ret;
02335
02336 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02337 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02338 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02339 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02340 _dbus_return_val_if_fail (value != NULL, FALSE);
02341 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02342 _dbus_return_val_if_fail (n_elements <=
02343 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02344 FALSE);
02345
02346 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02347
02348 return ret;
02349 }
02350
02372 dbus_bool_t
02373 dbus_message_iter_open_container (DBusMessageIter *iter,
02374 int type,
02375 const char *contained_signature,
02376 DBusMessageIter *sub)
02377 {
02378 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02379 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02380 DBusString contained_str;
02381
02382 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02383 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02384 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02385 _dbus_return_val_if_fail (sub != NULL, FALSE);
02386 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02387 contained_signature == NULL) ||
02388 (type == DBUS_TYPE_DICT_ENTRY &&
02389 contained_signature == NULL) ||
02390 (type == DBUS_TYPE_VARIANT &&
02391 contained_signature != NULL) ||
02392 (type == DBUS_TYPE_ARRAY &&
02393 contained_signature != NULL), FALSE);
02394
02395
02396
02397
02398
02399 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02400 (contained_signature == NULL ||
02401 _dbus_check_is_valid_signature (contained_signature)),
02402 FALSE);
02403
02404 if (!_dbus_message_iter_open_signature (real))
02405 return FALSE;
02406
02407 *real_sub = *real;
02408
02409 if (contained_signature != NULL)
02410 {
02411 _dbus_string_init_const (&contained_str, contained_signature);
02412
02413 return _dbus_type_writer_recurse (&real->u.writer,
02414 type,
02415 &contained_str, 0,
02416 &real_sub->u.writer);
02417 }
02418 else
02419 {
02420 return _dbus_type_writer_recurse (&real->u.writer,
02421 type,
02422 NULL, 0,
02423 &real_sub->u.writer);
02424 }
02425 }
02426
02427
02441 dbus_bool_t
02442 dbus_message_iter_close_container (DBusMessageIter *iter,
02443 DBusMessageIter *sub)
02444 {
02445 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02446 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02447 dbus_bool_t ret;
02448
02449 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02450 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02451 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02452 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02453
02454 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02455 &real_sub->u.writer);
02456
02457 if (!_dbus_message_iter_close_signature (real))
02458 ret = FALSE;
02459
02460 return ret;
02461 }
02462
02474 void
02475 dbus_message_iter_abandon_container (DBusMessageIter *iter,
02476 DBusMessageIter *sub)
02477 {
02478 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02479 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02480
02481 _dbus_return_if_fail (_dbus_message_iter_append_check (real));
02482 _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02483 _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
02484 _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02485
02486 _dbus_message_iter_abandon_signature (real);
02487 }
02488
02505 void
02506 dbus_message_set_no_reply (DBusMessage *message,
02507 dbus_bool_t no_reply)
02508 {
02509 _dbus_return_if_fail (message != NULL);
02510 _dbus_return_if_fail (!message->locked);
02511
02512 _dbus_header_toggle_flag (&message->header,
02513 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02514 no_reply);
02515 }
02516
02524 dbus_bool_t
02525 dbus_message_get_no_reply (DBusMessage *message)
02526 {
02527 _dbus_return_val_if_fail (message != NULL, FALSE);
02528
02529 return _dbus_header_get_flag (&message->header,
02530 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02531 }
02532
02547 void
02548 dbus_message_set_auto_start (DBusMessage *message,
02549 dbus_bool_t auto_start)
02550 {
02551 _dbus_return_if_fail (message != NULL);
02552 _dbus_return_if_fail (!message->locked);
02553
02554 _dbus_header_toggle_flag (&message->header,
02555 DBUS_HEADER_FLAG_NO_AUTO_START,
02556 !auto_start);
02557 }
02558
02566 dbus_bool_t
02567 dbus_message_get_auto_start (DBusMessage *message)
02568 {
02569 _dbus_return_val_if_fail (message != NULL, FALSE);
02570
02571 return !_dbus_header_get_flag (&message->header,
02572 DBUS_HEADER_FLAG_NO_AUTO_START);
02573 }
02574
02575
02588 dbus_bool_t
02589 dbus_message_set_path (DBusMessage *message,
02590 const char *object_path)
02591 {
02592 _dbus_return_val_if_fail (message != NULL, FALSE);
02593 _dbus_return_val_if_fail (!message->locked, FALSE);
02594 _dbus_return_val_if_fail (object_path == NULL ||
02595 _dbus_check_is_valid_path (object_path),
02596 FALSE);
02597
02598 return set_or_delete_string_field (message,
02599 DBUS_HEADER_FIELD_PATH,
02600 DBUS_TYPE_OBJECT_PATH,
02601 object_path);
02602 }
02603
02617 const char*
02618 dbus_message_get_path (DBusMessage *message)
02619 {
02620 const char *v;
02621
02622 _dbus_return_val_if_fail (message != NULL, NULL);
02623
02624 v = NULL;
02625 _dbus_header_get_field_basic (&message->header,
02626 DBUS_HEADER_FIELD_PATH,
02627 DBUS_TYPE_OBJECT_PATH,
02628 &v);
02629 return v;
02630 }
02631
02641 dbus_bool_t
02642 dbus_message_has_path (DBusMessage *message,
02643 const char *path)
02644 {
02645 const char *msg_path;
02646 msg_path = dbus_message_get_path (message);
02647
02648 if (msg_path == NULL)
02649 {
02650 if (path == NULL)
02651 return TRUE;
02652 else
02653 return FALSE;
02654 }
02655
02656 if (path == NULL)
02657 return FALSE;
02658
02659 if (strcmp (msg_path, path) == 0)
02660 return TRUE;
02661
02662 return FALSE;
02663 }
02664
02685 dbus_bool_t
02686 dbus_message_get_path_decomposed (DBusMessage *message,
02687 char ***path)
02688 {
02689 const char *v;
02690
02691 _dbus_return_val_if_fail (message != NULL, FALSE);
02692 _dbus_return_val_if_fail (path != NULL, FALSE);
02693
02694 *path = NULL;
02695
02696 v = dbus_message_get_path (message);
02697 if (v != NULL)
02698 {
02699 if (!_dbus_decompose_path (v, strlen (v),
02700 path, NULL))
02701 return FALSE;
02702 }
02703 return TRUE;
02704 }
02705
02719 dbus_bool_t
02720 dbus_message_set_interface (DBusMessage *message,
02721 const char *interface)
02722 {
02723 _dbus_return_val_if_fail (message != NULL, FALSE);
02724 _dbus_return_val_if_fail (!message->locked, FALSE);
02725 _dbus_return_val_if_fail (interface == NULL ||
02726 _dbus_check_is_valid_interface (interface),
02727 FALSE);
02728
02729 return set_or_delete_string_field (message,
02730 DBUS_HEADER_FIELD_INTERFACE,
02731 DBUS_TYPE_STRING,
02732 interface);
02733 }
02734
02748 const char*
02749 dbus_message_get_interface (DBusMessage *message)
02750 {
02751 const char *v;
02752
02753 _dbus_return_val_if_fail (message != NULL, NULL);
02754
02755 v = NULL;
02756 _dbus_header_get_field_basic (&message->header,
02757 DBUS_HEADER_FIELD_INTERFACE,
02758 DBUS_TYPE_STRING,
02759 &v);
02760 return v;
02761 }
02762
02770 dbus_bool_t
02771 dbus_message_has_interface (DBusMessage *message,
02772 const char *interface)
02773 {
02774 const char *msg_interface;
02775 msg_interface = dbus_message_get_interface (message);
02776
02777 if (msg_interface == NULL)
02778 {
02779 if (interface == NULL)
02780 return TRUE;
02781 else
02782 return FALSE;
02783 }
02784
02785 if (interface == NULL)
02786 return FALSE;
02787
02788 if (strcmp (msg_interface, interface) == 0)
02789 return TRUE;
02790
02791 return FALSE;
02792
02793 }
02794
02807 dbus_bool_t
02808 dbus_message_set_member (DBusMessage *message,
02809 const char *member)
02810 {
02811 _dbus_return_val_if_fail (message != NULL, FALSE);
02812 _dbus_return_val_if_fail (!message->locked, FALSE);
02813 _dbus_return_val_if_fail (member == NULL ||
02814 _dbus_check_is_valid_member (member),
02815 FALSE);
02816
02817 return set_or_delete_string_field (message,
02818 DBUS_HEADER_FIELD_MEMBER,
02819 DBUS_TYPE_STRING,
02820 member);
02821 }
02822
02834 const char*
02835 dbus_message_get_member (DBusMessage *message)
02836 {
02837 const char *v;
02838
02839 _dbus_return_val_if_fail (message != NULL, NULL);
02840
02841 v = NULL;
02842 _dbus_header_get_field_basic (&message->header,
02843 DBUS_HEADER_FIELD_MEMBER,
02844 DBUS_TYPE_STRING,
02845 &v);
02846 return v;
02847 }
02848
02856 dbus_bool_t
02857 dbus_message_has_member (DBusMessage *message,
02858 const char *member)
02859 {
02860 const char *msg_member;
02861 msg_member = dbus_message_get_member (message);
02862
02863 if (msg_member == NULL)
02864 {
02865 if (member == NULL)
02866 return TRUE;
02867 else
02868 return FALSE;
02869 }
02870
02871 if (member == NULL)
02872 return FALSE;
02873
02874 if (strcmp (msg_member, member) == 0)
02875 return TRUE;
02876
02877 return FALSE;
02878
02879 }
02880
02892 dbus_bool_t
02893 dbus_message_set_error_name (DBusMessage *message,
02894 const char *error_name)
02895 {
02896 _dbus_return_val_if_fail (message != NULL, FALSE);
02897 _dbus_return_val_if_fail (!message->locked, FALSE);
02898 _dbus_return_val_if_fail (error_name == NULL ||
02899 _dbus_check_is_valid_error_name (error_name),
02900 FALSE);
02901
02902 return set_or_delete_string_field (message,
02903 DBUS_HEADER_FIELD_ERROR_NAME,
02904 DBUS_TYPE_STRING,
02905 error_name);
02906 }
02907
02918 const char*
02919 dbus_message_get_error_name (DBusMessage *message)
02920 {
02921 const char *v;
02922
02923 _dbus_return_val_if_fail (message != NULL, NULL);
02924
02925 v = NULL;
02926 _dbus_header_get_field_basic (&message->header,
02927 DBUS_HEADER_FIELD_ERROR_NAME,
02928 DBUS_TYPE_STRING,
02929 &v);
02930 return v;
02931 }
02932
02946 dbus_bool_t
02947 dbus_message_set_destination (DBusMessage *message,
02948 const char *destination)
02949 {
02950 _dbus_return_val_if_fail (message != NULL, FALSE);
02951 _dbus_return_val_if_fail (!message->locked, FALSE);
02952 _dbus_return_val_if_fail (destination == NULL ||
02953 _dbus_check_is_valid_bus_name (destination),
02954 FALSE);
02955
02956 return set_or_delete_string_field (message,
02957 DBUS_HEADER_FIELD_DESTINATION,
02958 DBUS_TYPE_STRING,
02959 destination);
02960 }
02961
02971 const char*
02972 dbus_message_get_destination (DBusMessage *message)
02973 {
02974 const char *v;
02975
02976 _dbus_return_val_if_fail (message != NULL, NULL);
02977
02978 v = NULL;
02979 _dbus_header_get_field_basic (&message->header,
02980 DBUS_HEADER_FIELD_DESTINATION,
02981 DBUS_TYPE_STRING,
02982 &v);
02983 return v;
02984 }
02985
03000 dbus_bool_t
03001 dbus_message_set_sender (DBusMessage *message,
03002 const char *sender)
03003 {
03004 _dbus_return_val_if_fail (message != NULL, FALSE);
03005 _dbus_return_val_if_fail (!message->locked, FALSE);
03006 _dbus_return_val_if_fail (sender == NULL ||
03007 _dbus_check_is_valid_bus_name (sender),
03008 FALSE);
03009
03010 return set_or_delete_string_field (message,
03011 DBUS_HEADER_FIELD_SENDER,
03012 DBUS_TYPE_STRING,
03013 sender);
03014 }
03015
03031 const char*
03032 dbus_message_get_sender (DBusMessage *message)
03033 {
03034 const char *v;
03035
03036 _dbus_return_val_if_fail (message != NULL, NULL);
03037
03038 v = NULL;
03039 _dbus_header_get_field_basic (&message->header,
03040 DBUS_HEADER_FIELD_SENDER,
03041 DBUS_TYPE_STRING,
03042 &v);
03043 return v;
03044 }
03045
03064 const char*
03065 dbus_message_get_signature (DBusMessage *message)
03066 {
03067 const DBusString *type_str;
03068 int type_pos;
03069
03070 _dbus_return_val_if_fail (message != NULL, NULL);
03071
03072 get_const_signature (&message->header, &type_str, &type_pos);
03073
03074 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03075 }
03076
03077 static dbus_bool_t
03078 _dbus_message_has_type_interface_member (DBusMessage *message,
03079 int type,
03080 const char *interface,
03081 const char *member)
03082 {
03083 const char *n;
03084
03085 _dbus_assert (message != NULL);
03086 _dbus_assert (interface != NULL);
03087 _dbus_assert (member != NULL);
03088
03089 if (dbus_message_get_type (message) != type)
03090 return FALSE;
03091
03092
03093
03094
03095
03096 n = dbus_message_get_member (message);
03097
03098 if (n && strcmp (n, member) == 0)
03099 {
03100 n = dbus_message_get_interface (message);
03101
03102 if (n == NULL || strcmp (n, interface) == 0)
03103 return TRUE;
03104 }
03105
03106 return FALSE;
03107 }
03108
03123 dbus_bool_t
03124 dbus_message_is_method_call (DBusMessage *message,
03125 const char *interface,
03126 const char *method)
03127 {
03128 _dbus_return_val_if_fail (message != NULL, FALSE);
03129 _dbus_return_val_if_fail (interface != NULL, FALSE);
03130 _dbus_return_val_if_fail (method != NULL, FALSE);
03131
03132
03133
03134
03135 return _dbus_message_has_type_interface_member (message,
03136 DBUS_MESSAGE_TYPE_METHOD_CALL,
03137 interface, method);
03138 }
03139
03151 dbus_bool_t
03152 dbus_message_is_signal (DBusMessage *message,
03153 const char *interface,
03154 const char *signal_name)
03155 {
03156 _dbus_return_val_if_fail (message != NULL, FALSE);
03157 _dbus_return_val_if_fail (interface != NULL, FALSE);
03158 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03159
03160
03161
03162
03163 return _dbus_message_has_type_interface_member (message,
03164 DBUS_MESSAGE_TYPE_SIGNAL,
03165 interface, signal_name);
03166 }
03167
03178 dbus_bool_t
03179 dbus_message_is_error (DBusMessage *message,
03180 const char *error_name)
03181 {
03182 const char *n;
03183
03184 _dbus_return_val_if_fail (message != NULL, FALSE);
03185 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03186
03187
03188
03189
03190 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03191 return FALSE;
03192
03193 n = dbus_message_get_error_name (message);
03194
03195 if (n && strcmp (n, error_name) == 0)
03196 return TRUE;
03197 else
03198 return FALSE;
03199 }
03200
03211 dbus_bool_t
03212 dbus_message_has_destination (DBusMessage *message,
03213 const char *name)
03214 {
03215 const char *s;
03216
03217 _dbus_return_val_if_fail (message != NULL, FALSE);
03218 _dbus_return_val_if_fail (name != NULL, FALSE);
03219
03220
03221
03222
03223 s = dbus_message_get_destination (message);
03224
03225 if (s && strcmp (s, name) == 0)
03226 return TRUE;
03227 else
03228 return FALSE;
03229 }
03230
03246 dbus_bool_t
03247 dbus_message_has_sender (DBusMessage *message,
03248 const char *name)
03249 {
03250 const char *s;
03251
03252 _dbus_return_val_if_fail (message != NULL, FALSE);
03253 _dbus_return_val_if_fail (name != NULL, FALSE);
03254
03255
03256
03257
03258 s = dbus_message_get_sender (message);
03259
03260 if (s && strcmp (s, name) == 0)
03261 return TRUE;
03262 else
03263 return FALSE;
03264 }
03265
03275 dbus_bool_t
03276 dbus_message_has_signature (DBusMessage *message,
03277 const char *signature)
03278 {
03279 const char *s;
03280
03281 _dbus_return_val_if_fail (message != NULL, FALSE);
03282 _dbus_return_val_if_fail (signature != NULL, FALSE);
03283
03284
03285
03286
03287 s = dbus_message_get_signature (message);
03288
03289 if (s && strcmp (s, signature) == 0)
03290 return TRUE;
03291 else
03292 return FALSE;
03293 }
03294
03317 dbus_bool_t
03318 dbus_set_error_from_message (DBusError *error,
03319 DBusMessage *message)
03320 {
03321 const char *str;
03322
03323 _dbus_return_val_if_fail (message != NULL, FALSE);
03324 _dbus_return_val_if_error_is_set (error, FALSE);
03325
03326 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03327 return FALSE;
03328
03329 str = NULL;
03330 dbus_message_get_args (message, NULL,
03331 DBUS_TYPE_STRING, &str,
03332 DBUS_TYPE_INVALID);
03333
03334 dbus_set_error (error, dbus_message_get_error_name (message),
03335 str ? "%s" : NULL, str);
03336
03337 return TRUE;
03338 }
03339
03358 #define INITIAL_LOADER_DATA_LEN 32
03359
03366 DBusMessageLoader*
03367 _dbus_message_loader_new (void)
03368 {
03369 DBusMessageLoader *loader;
03370
03371 loader = dbus_new0 (DBusMessageLoader, 1);
03372 if (loader == NULL)
03373 return NULL;
03374
03375 loader->refcount = 1;
03376
03377 loader->corrupted = FALSE;
03378 loader->corruption_reason = DBUS_VALID;
03379
03380
03381 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03382
03383 if (!_dbus_string_init (&loader->data))
03384 {
03385 dbus_free (loader);
03386 return NULL;
03387 }
03388
03389
03390 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03391 _dbus_string_set_length (&loader->data, 0);
03392
03393 return loader;
03394 }
03395
03402 DBusMessageLoader *
03403 _dbus_message_loader_ref (DBusMessageLoader *loader)
03404 {
03405 loader->refcount += 1;
03406
03407 return loader;
03408 }
03409
03416 void
03417 _dbus_message_loader_unref (DBusMessageLoader *loader)
03418 {
03419 loader->refcount -= 1;
03420 if (loader->refcount == 0)
03421 {
03422 _dbus_list_foreach (&loader->messages,
03423 (DBusForeachFunction) dbus_message_unref,
03424 NULL);
03425 _dbus_list_clear (&loader->messages);
03426 _dbus_string_free (&loader->data);
03427 dbus_free (loader);
03428 }
03429 }
03430
03449 void
03450 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03451 DBusString **buffer)
03452 {
03453 _dbus_assert (!loader->buffer_outstanding);
03454
03455 *buffer = &loader->data;
03456
03457 loader->buffer_outstanding = TRUE;
03458 }
03459
03470 void
03471 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03472 DBusString *buffer,
03473 int bytes_read)
03474 {
03475 _dbus_assert (loader->buffer_outstanding);
03476 _dbus_assert (buffer == &loader->data);
03477
03478 loader->buffer_outstanding = FALSE;
03479 }
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507 static dbus_bool_t
03508 load_message (DBusMessageLoader *loader,
03509 DBusMessage *message,
03510 int byte_order,
03511 int fields_array_len,
03512 int header_len,
03513 int body_len)
03514 {
03515 dbus_bool_t oom;
03516 DBusValidity validity;
03517 const DBusString *type_str;
03518 int type_pos;
03519 DBusValidationMode mode;
03520
03521 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03522
03523 oom = FALSE;
03524
03525 #if 0
03526 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03527 #endif
03528
03529
03530 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03531 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03532
03533 if (!_dbus_header_load (&message->header,
03534 mode,
03535 &validity,
03536 byte_order,
03537 fields_array_len,
03538 header_len,
03539 body_len,
03540 &loader->data, 0,
03541 _dbus_string_get_length (&loader->data)))
03542 {
03543 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03544
03545
03546
03547 _dbus_assert (validity != DBUS_VALID);
03548
03549 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03550 oom = TRUE;
03551 else
03552 {
03553 loader->corrupted = TRUE;
03554 loader->corruption_reason = validity;
03555 }
03556 goto failed;
03557 }
03558
03559 _dbus_assert (validity == DBUS_VALID);
03560
03561 message->byte_order = byte_order;
03562
03563
03564 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03565 {
03566 get_const_signature (&message->header, &type_str, &type_pos);
03567
03568
03569
03570
03571 validity = _dbus_validate_body_with_reason (type_str,
03572 type_pos,
03573 byte_order,
03574 NULL,
03575 &loader->data,
03576 header_len,
03577 body_len);
03578 if (validity != DBUS_VALID)
03579 {
03580 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03581
03582 loader->corrupted = TRUE;
03583 loader->corruption_reason = validity;
03584
03585 goto failed;
03586 }
03587 }
03588
03589
03590
03591 if (!_dbus_list_append (&loader->messages, message))
03592 {
03593 _dbus_verbose ("Failed to append new message to loader queue\n");
03594 oom = TRUE;
03595 goto failed;
03596 }
03597
03598 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03599 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03600 (header_len + body_len));
03601
03602 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03603 {
03604 _dbus_verbose ("Failed to move body into new message\n");
03605 oom = TRUE;
03606 goto failed;
03607 }
03608
03609 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03610
03611
03612 _dbus_string_compact (&loader->data, 2048);
03613
03614 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03615 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03616
03617 _dbus_verbose ("Loaded message %p\n", message);
03618
03619 _dbus_assert (!oom);
03620 _dbus_assert (!loader->corrupted);
03621 _dbus_assert (loader->messages != NULL);
03622 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03623
03624 return TRUE;
03625
03626 failed:
03627
03628
03629
03630
03631 _dbus_list_remove_last (&loader->messages, message);
03632
03633 if (oom)
03634 _dbus_assert (!loader->corrupted);
03635 else
03636 _dbus_assert (loader->corrupted);
03637
03638 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03639
03640 return FALSE;
03641 }
03642
03657 dbus_bool_t
03658 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03659 {
03660 while (!loader->corrupted &&
03661 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03662 {
03663 DBusValidity validity;
03664 int byte_order, fields_array_len, header_len, body_len;
03665
03666 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03667 &validity,
03668 &byte_order,
03669 &fields_array_len,
03670 &header_len,
03671 &body_len,
03672 &loader->data, 0,
03673 _dbus_string_get_length (&loader->data)))
03674 {
03675 DBusMessage *message;
03676
03677 _dbus_assert (validity == DBUS_VALID);
03678
03679 message = dbus_message_new_empty_header ();
03680 if (message == NULL)
03681 return FALSE;
03682
03683 if (!load_message (loader, message,
03684 byte_order, fields_array_len,
03685 header_len, body_len))
03686 {
03687 dbus_message_unref (message);
03688
03689
03690
03691 return loader->corrupted;
03692 }
03693
03694 _dbus_assert (loader->messages != NULL);
03695 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03696 }
03697 else
03698 {
03699 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03700 validity);
03701 if (validity != DBUS_VALID)
03702 {
03703 loader->corrupted = TRUE;
03704 loader->corruption_reason = validity;
03705 }
03706 return TRUE;
03707 }
03708 }
03709
03710 return TRUE;
03711 }
03712
03720 DBusMessage*
03721 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03722 {
03723 if (loader->messages)
03724 return loader->messages->data;
03725 else
03726 return NULL;
03727 }
03728
03737 DBusMessage*
03738 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03739 {
03740 return _dbus_list_pop_first (&loader->messages);
03741 }
03742
03751 DBusList*
03752 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03753 {
03754 return _dbus_list_pop_first_link (&loader->messages);
03755 }
03756
03763 void
03764 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03765 DBusList *link)
03766 {
03767 _dbus_list_prepend_link (&loader->messages, link);
03768 }
03769
03779 dbus_bool_t
03780 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03781 {
03782 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03783 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03784 return loader->corrupted;
03785 }
03786
03793 void
03794 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03795 long size)
03796 {
03797 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03798 {
03799 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03800 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03801 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03802 }
03803 loader->max_message_size = size;
03804 }
03805
03812 long
03813 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03814 {
03815 return loader->max_message_size;
03816 }
03817
03818 static DBusDataSlotAllocator slot_allocator;
03819 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03820
03835 dbus_bool_t
03836 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03837 {
03838 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03839 &_DBUS_LOCK_NAME (message_slots),
03840 slot_p);
03841 }
03842
03854 void
03855 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03856 {
03857 _dbus_return_if_fail (*slot_p >= 0);
03858
03859 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03860 }
03861
03875 dbus_bool_t
03876 dbus_message_set_data (DBusMessage *message,
03877 dbus_int32_t slot,
03878 void *data,
03879 DBusFreeFunction free_data_func)
03880 {
03881 DBusFreeFunction old_free_func;
03882 void *old_data;
03883 dbus_bool_t retval;
03884
03885 _dbus_return_val_if_fail (message != NULL, FALSE);
03886 _dbus_return_val_if_fail (slot >= 0, FALSE);
03887
03888 retval = _dbus_data_slot_list_set (&slot_allocator,
03889 &message->slot_list,
03890 slot, data, free_data_func,
03891 &old_free_func, &old_data);
03892
03893 if (retval)
03894 {
03895
03896 if (old_free_func)
03897 (* old_free_func) (old_data);
03898 }
03899
03900 return retval;
03901 }
03902
03911 void*
03912 dbus_message_get_data (DBusMessage *message,
03913 dbus_int32_t slot)
03914 {
03915 void *res;
03916
03917 _dbus_return_val_if_fail (message != NULL, NULL);
03918
03919 res = _dbus_data_slot_list_get (&slot_allocator,
03920 &message->slot_list,
03921 slot);
03922
03923 return res;
03924 }
03925
03939 int
03940 dbus_message_type_from_string (const char *type_str)
03941 {
03942 if (strcmp (type_str, "method_call") == 0)
03943 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03944 if (strcmp (type_str, "method_return") == 0)
03945 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03946 else if (strcmp (type_str, "signal") == 0)
03947 return DBUS_MESSAGE_TYPE_SIGNAL;
03948 else if (strcmp (type_str, "error") == 0)
03949 return DBUS_MESSAGE_TYPE_ERROR;
03950 else
03951 return DBUS_MESSAGE_TYPE_INVALID;
03952 }
03953
03967 const char *
03968 dbus_message_type_to_string (int type)
03969 {
03970 switch (type)
03971 {
03972 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03973 return "method_call";
03974 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03975 return "method_return";
03976 case DBUS_MESSAGE_TYPE_SIGNAL:
03977 return "signal";
03978 case DBUS_MESSAGE_TYPE_ERROR:
03979 return "error";
03980 default:
03981 return "invalid";
03982 }
03983 }
03984
03997 dbus_bool_t
03998 dbus_message_marshal (DBusMessage *msg,
03999 char **marshalled_data_p,
04000 int *len_p)
04001 {
04002 DBusString tmp;
04003 dbus_bool_t was_locked;
04004
04005 _dbus_return_val_if_fail (msg != NULL, FALSE);
04006 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
04007 _dbus_return_val_if_fail (len_p != NULL, FALSE);
04008
04009 if (!_dbus_string_init (&tmp))
04010 return FALSE;
04011
04012
04013 was_locked = msg->locked;
04014
04015 if (!was_locked)
04016 dbus_message_lock (msg);
04017
04018 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
04019 goto fail;
04020
04021 *len_p = _dbus_string_get_length (&tmp);
04022
04023 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
04024 goto fail;
04025
04026 *len_p = _dbus_string_get_length (&tmp);
04027
04028 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
04029 goto fail;
04030
04031 _dbus_string_free (&tmp);
04032
04033 if (!was_locked)
04034 msg->locked = FALSE;
04035
04036 return TRUE;
04037
04038 fail:
04039 _dbus_string_free (&tmp);
04040
04041 if (!was_locked)
04042 msg->locked = FALSE;
04043
04044 return FALSE;
04045 }
04046
04059 DBusMessage *
04060 dbus_message_demarshal (const char *str,
04061 int len,
04062 DBusError *error)
04063 {
04064 DBusMessageLoader *loader;
04065 DBusString *buffer;
04066 DBusMessage *msg;
04067
04068 _dbus_return_val_if_fail (str != NULL, NULL);
04069
04070 loader = _dbus_message_loader_new ();
04071
04072 if (loader == NULL)
04073 return NULL;
04074
04075 _dbus_message_loader_get_buffer (loader, &buffer);
04076 _dbus_string_append_len (buffer, str, len);
04077 _dbus_message_loader_return_buffer (loader, buffer, len);
04078
04079 if (!_dbus_message_loader_queue_messages (loader))
04080 goto fail_oom;
04081
04082 if (_dbus_message_loader_get_is_corrupted (loader))
04083 goto fail_corrupt;
04084
04085 msg = _dbus_message_loader_pop_message (loader);
04086
04087 if (!msg)
04088 goto fail_oom;
04089
04090 _dbus_message_loader_unref (loader);
04091 return msg;
04092
04093 fail_corrupt:
04094 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted");
04095 _dbus_message_loader_unref (loader);
04096 return NULL;
04097
04098 fail_oom:
04099 _DBUS_SET_OOM (error);
04100 _dbus_message_loader_unref (loader);
04101 return NULL;
04102 }
04103
04117 int
04118 dbus_message_demarshal_bytes_needed(const char *buf,
04119 int len)
04120 {
04121 DBusString str;
04122 int byte_order, fields_array_len, header_len, body_len;
04123 DBusValidity validity = DBUS_VALID;
04124 int have_message;
04125
04126 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04127 return 0;
04128
04129 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04130 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04131 _dbus_string_init_const_len (&str, buf, len);
04132
04133 validity = DBUS_VALID;
04134 have_message
04135 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04136 &validity, &byte_order,
04137 &fields_array_len,
04138 &header_len,
04139 &body_len,
04140 &str, 0,
04141 len);
04142 _dbus_string_free (&str);
04143
04144 if (validity == DBUS_VALID)
04145 {
04146 _dbus_assert(have_message);
04147 return header_len + body_len;
04148 }
04149 else
04150 {
04151 return -1;
04152 }
04153 }
04154
04157