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 goto failed;
01572 }
01573 else if (element_type == DBUS_TYPE_STRING ||
01574 element_type == DBUS_TYPE_SIGNATURE ||
01575 element_type == DBUS_TYPE_OBJECT_PATH)
01576 {
01577 const char ***value_p;
01578 const char **value;
01579 int n_elements;
01580 int i;
01581
01582 value_p = va_arg (var_args, const char***);
01583 n_elements = va_arg (var_args, int);
01584
01585 value = *value_p;
01586
01587 i = 0;
01588 while (i < n_elements)
01589 {
01590 if (!dbus_message_iter_append_basic (&array,
01591 element_type,
01592 &value[i]))
01593 goto failed;
01594 ++i;
01595 }
01596 }
01597 else
01598 {
01599 _dbus_warn ("arrays of %s can't be appended with %s for now\n",
01600 _dbus_type_to_string (element_type),
01601 _DBUS_FUNCTION_NAME);
01602 goto failed;
01603 }
01604
01605 if (!dbus_message_iter_close_container (&iter, &array))
01606 goto failed;
01607 }
01608 #ifndef DBUS_DISABLE_CHECKS
01609 else
01610 {
01611 _dbus_warn ("type %s isn't supported yet in %s\n",
01612 _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
01613 goto failed;
01614 }
01615 #endif
01616
01617 type = va_arg (var_args, int);
01618 }
01619
01620 return TRUE;
01621
01622 failed:
01623 return FALSE;
01624 }
01625
01661 dbus_bool_t
01662 dbus_message_get_args (DBusMessage *message,
01663 DBusError *error,
01664 int first_arg_type,
01665 ...)
01666 {
01667 dbus_bool_t retval;
01668 va_list var_args;
01669
01670 _dbus_return_val_if_fail (message != NULL, FALSE);
01671 _dbus_return_val_if_error_is_set (error, FALSE);
01672
01673 va_start (var_args, first_arg_type);
01674 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
01675 va_end (var_args);
01676
01677 return retval;
01678 }
01679
01690 dbus_bool_t
01691 dbus_message_get_args_valist (DBusMessage *message,
01692 DBusError *error,
01693 int first_arg_type,
01694 va_list var_args)
01695 {
01696 DBusMessageIter iter;
01697
01698 _dbus_return_val_if_fail (message != NULL, FALSE);
01699 _dbus_return_val_if_error_is_set (error, FALSE);
01700
01701 dbus_message_iter_init (message, &iter);
01702 return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
01703 }
01704
01705 static void
01706 _dbus_message_iter_init_common (DBusMessage *message,
01707 DBusMessageRealIter *real,
01708 int iter_type)
01709 {
01710 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
01711
01712
01713
01714
01715 ensure_byte_order (message);
01716
01717 real->message = message;
01718 real->changed_stamp = message->changed_stamp;
01719 real->iter_type = iter_type;
01720 real->sig_refcount = 0;
01721 }
01722
01745 dbus_bool_t
01746 dbus_message_iter_init (DBusMessage *message,
01747 DBusMessageIter *iter)
01748 {
01749 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01750 const DBusString *type_str;
01751 int type_pos;
01752
01753 _dbus_return_val_if_fail (message != NULL, FALSE);
01754 _dbus_return_val_if_fail (iter != NULL, FALSE);
01755
01756 get_const_signature (&message->header, &type_str, &type_pos);
01757
01758 _dbus_message_iter_init_common (message, real,
01759 DBUS_MESSAGE_ITER_TYPE_READER);
01760
01761 _dbus_type_reader_init (&real->u.reader,
01762 message->byte_order,
01763 type_str, type_pos,
01764 &message->body,
01765 0);
01766
01767 return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
01768 }
01769
01776 dbus_bool_t
01777 dbus_message_iter_has_next (DBusMessageIter *iter)
01778 {
01779 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01780
01781 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01782 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01783
01784 return _dbus_type_reader_has_next (&real->u.reader);
01785 }
01786
01795 dbus_bool_t
01796 dbus_message_iter_next (DBusMessageIter *iter)
01797 {
01798 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01799
01800 _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
01801 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01802
01803 return _dbus_type_reader_next (&real->u.reader);
01804 }
01805
01820 int
01821 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
01822 {
01823 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01824
01825 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01826 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
01827
01828 return _dbus_type_reader_get_current_type (&real->u.reader);
01829 }
01830
01839 int
01840 dbus_message_iter_get_element_type (DBusMessageIter *iter)
01841 {
01842 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01843
01844 _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
01845 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
01846 _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
01847
01848 return _dbus_type_reader_get_element_type (&real->u.reader);
01849 }
01850
01876 void
01877 dbus_message_iter_recurse (DBusMessageIter *iter,
01878 DBusMessageIter *sub)
01879 {
01880 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01881 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
01882
01883 _dbus_return_if_fail (_dbus_message_iter_check (real));
01884 _dbus_return_if_fail (sub != NULL);
01885
01886 *real_sub = *real;
01887 _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
01888 }
01889
01901 char *
01902 dbus_message_iter_get_signature (DBusMessageIter *iter)
01903 {
01904 const DBusString *sig;
01905 DBusString retstr;
01906 char *ret;
01907 int start, len;
01908 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01909
01910 _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
01911
01912 if (!_dbus_string_init (&retstr))
01913 return NULL;
01914
01915 _dbus_type_reader_get_signature (&real->u.reader, &sig,
01916 &start, &len);
01917 if (!_dbus_string_append_len (&retstr,
01918 _dbus_string_get_const_data (sig) + start,
01919 len))
01920 return NULL;
01921 if (!_dbus_string_steal_data (&retstr, &ret))
01922 return NULL;
01923 _dbus_string_free (&retstr);
01924 return ret;
01925 }
01926
01967 void
01968 dbus_message_iter_get_basic (DBusMessageIter *iter,
01969 void *value)
01970 {
01971 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
01972
01973 _dbus_return_if_fail (_dbus_message_iter_check (real));
01974 _dbus_return_if_fail (value != NULL);
01975
01976 _dbus_type_reader_read_basic (&real->u.reader,
01977 value);
01978 }
01979
01998 int
01999 dbus_message_iter_get_array_len (DBusMessageIter *iter)
02000 {
02001 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02002
02003 _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
02004
02005 return _dbus_type_reader_get_array_length (&real->u.reader);
02006 }
02007
02039 void
02040 dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
02041 void *value,
02042 int *n_elements)
02043 {
02044 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02045 int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
02046
02047 _dbus_return_if_fail (_dbus_message_iter_check (real));
02048 _dbus_return_if_fail (value != NULL);
02049 _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
02050 dbus_type_is_fixed (subtype));
02051
02052 _dbus_type_reader_read_fixed_multi (&real->u.reader,
02053 value, n_elements);
02054 }
02055
02067 void
02068 dbus_message_iter_init_append (DBusMessage *message,
02069 DBusMessageIter *iter)
02070 {
02071 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02072
02073 _dbus_return_if_fail (message != NULL);
02074 _dbus_return_if_fail (iter != NULL);
02075
02076 _dbus_message_iter_init_common (message, real,
02077 DBUS_MESSAGE_ITER_TYPE_WRITER);
02078
02079
02080
02081
02082
02083 _dbus_type_writer_init_types_delayed (&real->u.writer,
02084 message->byte_order,
02085 &message->body,
02086 _dbus_string_get_length (&message->body));
02087 }
02088
02097 static dbus_bool_t
02098 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
02099 {
02100 DBusString *str;
02101 const DBusString *current_sig;
02102 int current_sig_pos;
02103
02104 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02105
02106 if (real->u.writer.type_str != NULL)
02107 {
02108 _dbus_assert (real->sig_refcount > 0);
02109 real->sig_refcount += 1;
02110 return TRUE;
02111 }
02112
02113 str = dbus_new (DBusString, 1);
02114 if (str == NULL)
02115 return FALSE;
02116
02117 if (!_dbus_header_get_field_raw (&real->message->header,
02118 DBUS_HEADER_FIELD_SIGNATURE,
02119 ¤t_sig, ¤t_sig_pos))
02120 current_sig = NULL;
02121
02122 if (current_sig)
02123 {
02124 int current_len;
02125
02126 current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
02127 current_sig_pos += 1;
02128
02129 if (!_dbus_string_init_preallocated (str, current_len + 4))
02130 {
02131 dbus_free (str);
02132 return FALSE;
02133 }
02134
02135 if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
02136 str, 0))
02137 {
02138 _dbus_string_free (str);
02139 dbus_free (str);
02140 return FALSE;
02141 }
02142 }
02143 else
02144 {
02145 if (!_dbus_string_init_preallocated (str, 4))
02146 {
02147 dbus_free (str);
02148 return FALSE;
02149 }
02150 }
02151
02152 real->sig_refcount = 1;
02153
02154 _dbus_type_writer_add_types (&real->u.writer,
02155 str, _dbus_string_get_length (str));
02156 return TRUE;
02157 }
02158
02168 static dbus_bool_t
02169 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
02170 {
02171 DBusString *str;
02172 const char *v_STRING;
02173 dbus_bool_t retval;
02174
02175 _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
02176 _dbus_assert (real->u.writer.type_str != NULL);
02177 _dbus_assert (real->sig_refcount > 0);
02178
02179 real->sig_refcount -= 1;
02180
02181 if (real->sig_refcount > 0)
02182 return TRUE;
02183 _dbus_assert (real->sig_refcount == 0);
02184
02185 retval = TRUE;
02186
02187 str = real->u.writer.type_str;
02188
02189 v_STRING = _dbus_string_get_const_data (str);
02190 if (!_dbus_header_set_field_basic (&real->message->header,
02191 DBUS_HEADER_FIELD_SIGNATURE,
02192 DBUS_TYPE_SIGNATURE,
02193 &v_STRING))
02194 retval = FALSE;
02195
02196 _dbus_type_writer_remove_types (&real->u.writer);
02197 _dbus_string_free (str);
02198 dbus_free (str);
02199
02200 return retval;
02201 }
02202
02203 #ifndef DBUS_DISABLE_CHECKS
02204 static dbus_bool_t
02205 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
02206 {
02207 if (!_dbus_message_iter_check (iter))
02208 return FALSE;
02209
02210 if (iter->message->locked)
02211 {
02212 _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
02213 return FALSE;
02214 }
02215
02216 return TRUE;
02217 }
02218 #endif
02219
02235 dbus_bool_t
02236 dbus_message_iter_append_basic (DBusMessageIter *iter,
02237 int type,
02238 const void *value)
02239 {
02240 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02241 dbus_bool_t ret;
02242
02243 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02244 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02245 _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
02246 _dbus_return_val_if_fail (value != NULL, FALSE);
02247
02248 if (!_dbus_message_iter_open_signature (real))
02249 return FALSE;
02250
02251 ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
02252
02253 if (!_dbus_message_iter_close_signature (real))
02254 ret = FALSE;
02255
02256 return ret;
02257 }
02258
02294 dbus_bool_t
02295 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
02296 int element_type,
02297 const void *value,
02298 int n_elements)
02299 {
02300 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02301 dbus_bool_t ret;
02302
02303 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02304 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02305 _dbus_return_val_if_fail (dbus_type_is_fixed (element_type), FALSE);
02306 _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
02307 _dbus_return_val_if_fail (value != NULL, FALSE);
02308 _dbus_return_val_if_fail (n_elements >= 0, FALSE);
02309 _dbus_return_val_if_fail (n_elements <=
02310 DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
02311 FALSE);
02312
02313 ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
02314
02315 return ret;
02316 }
02317
02339 dbus_bool_t
02340 dbus_message_iter_open_container (DBusMessageIter *iter,
02341 int type,
02342 const char *contained_signature,
02343 DBusMessageIter *sub)
02344 {
02345 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02346 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02347 DBusString contained_str;
02348
02349 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02350 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02351 _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
02352 _dbus_return_val_if_fail (sub != NULL, FALSE);
02353 _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
02354 contained_signature == NULL) ||
02355 (type == DBUS_TYPE_DICT_ENTRY &&
02356 contained_signature == NULL) ||
02357 (type == DBUS_TYPE_VARIANT &&
02358 contained_signature != NULL) ||
02359 (type == DBUS_TYPE_ARRAY &&
02360 contained_signature != NULL), FALSE);
02361
02362
02363
02364
02365
02366 _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
02367 (contained_signature == NULL ||
02368 _dbus_check_is_valid_signature (contained_signature)),
02369 FALSE);
02370
02371 if (!_dbus_message_iter_open_signature (real))
02372 return FALSE;
02373
02374 *real_sub = *real;
02375
02376 if (contained_signature != NULL)
02377 {
02378 _dbus_string_init_const (&contained_str, contained_signature);
02379
02380 return _dbus_type_writer_recurse (&real->u.writer,
02381 type,
02382 &contained_str, 0,
02383 &real_sub->u.writer);
02384 }
02385 else
02386 {
02387 return _dbus_type_writer_recurse (&real->u.writer,
02388 type,
02389 NULL, 0,
02390 &real_sub->u.writer);
02391 }
02392 }
02393
02394
02408 dbus_bool_t
02409 dbus_message_iter_close_container (DBusMessageIter *iter,
02410 DBusMessageIter *sub)
02411 {
02412 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02413 DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
02414 dbus_bool_t ret;
02415
02416 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
02417 _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02418 _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
02419 _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
02420
02421 ret = _dbus_type_writer_unrecurse (&real->u.writer,
02422 &real_sub->u.writer);
02423
02424 if (!_dbus_message_iter_close_signature (real))
02425 ret = FALSE;
02426
02427 return ret;
02428 }
02429
02446 void
02447 dbus_message_set_no_reply (DBusMessage *message,
02448 dbus_bool_t no_reply)
02449 {
02450 _dbus_return_if_fail (message != NULL);
02451 _dbus_return_if_fail (!message->locked);
02452
02453 _dbus_header_toggle_flag (&message->header,
02454 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
02455 no_reply);
02456 }
02457
02465 dbus_bool_t
02466 dbus_message_get_no_reply (DBusMessage *message)
02467 {
02468 _dbus_return_val_if_fail (message != NULL, FALSE);
02469
02470 return _dbus_header_get_flag (&message->header,
02471 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
02472 }
02473
02488 void
02489 dbus_message_set_auto_start (DBusMessage *message,
02490 dbus_bool_t auto_start)
02491 {
02492 _dbus_return_if_fail (message != NULL);
02493 _dbus_return_if_fail (!message->locked);
02494
02495 _dbus_header_toggle_flag (&message->header,
02496 DBUS_HEADER_FLAG_NO_AUTO_START,
02497 !auto_start);
02498 }
02499
02507 dbus_bool_t
02508 dbus_message_get_auto_start (DBusMessage *message)
02509 {
02510 _dbus_return_val_if_fail (message != NULL, FALSE);
02511
02512 return !_dbus_header_get_flag (&message->header,
02513 DBUS_HEADER_FLAG_NO_AUTO_START);
02514 }
02515
02516
02529 dbus_bool_t
02530 dbus_message_set_path (DBusMessage *message,
02531 const char *object_path)
02532 {
02533 _dbus_return_val_if_fail (message != NULL, FALSE);
02534 _dbus_return_val_if_fail (!message->locked, FALSE);
02535 _dbus_return_val_if_fail (object_path == NULL ||
02536 _dbus_check_is_valid_path (object_path),
02537 FALSE);
02538
02539 return set_or_delete_string_field (message,
02540 DBUS_HEADER_FIELD_PATH,
02541 DBUS_TYPE_OBJECT_PATH,
02542 object_path);
02543 }
02544
02558 const char*
02559 dbus_message_get_path (DBusMessage *message)
02560 {
02561 const char *v;
02562
02563 _dbus_return_val_if_fail (message != NULL, NULL);
02564
02565 v = NULL;
02566 _dbus_header_get_field_basic (&message->header,
02567 DBUS_HEADER_FIELD_PATH,
02568 DBUS_TYPE_OBJECT_PATH,
02569 &v);
02570 return v;
02571 }
02572
02582 dbus_bool_t
02583 dbus_message_has_path (DBusMessage *message,
02584 const char *path)
02585 {
02586 const char *msg_path;
02587 msg_path = dbus_message_get_path (message);
02588
02589 if (msg_path == NULL)
02590 {
02591 if (path == NULL)
02592 return TRUE;
02593 else
02594 return FALSE;
02595 }
02596
02597 if (path == NULL)
02598 return FALSE;
02599
02600 if (strcmp (msg_path, path) == 0)
02601 return TRUE;
02602
02603 return FALSE;
02604 }
02605
02626 dbus_bool_t
02627 dbus_message_get_path_decomposed (DBusMessage *message,
02628 char ***path)
02629 {
02630 const char *v;
02631
02632 _dbus_return_val_if_fail (message != NULL, FALSE);
02633 _dbus_return_val_if_fail (path != NULL, FALSE);
02634
02635 *path = NULL;
02636
02637 v = dbus_message_get_path (message);
02638 if (v != NULL)
02639 {
02640 if (!_dbus_decompose_path (v, strlen (v),
02641 path, NULL))
02642 return FALSE;
02643 }
02644 return TRUE;
02645 }
02646
02660 dbus_bool_t
02661 dbus_message_set_interface (DBusMessage *message,
02662 const char *interface)
02663 {
02664 _dbus_return_val_if_fail (message != NULL, FALSE);
02665 _dbus_return_val_if_fail (!message->locked, FALSE);
02666 _dbus_return_val_if_fail (interface == NULL ||
02667 _dbus_check_is_valid_interface (interface),
02668 FALSE);
02669
02670 return set_or_delete_string_field (message,
02671 DBUS_HEADER_FIELD_INTERFACE,
02672 DBUS_TYPE_STRING,
02673 interface);
02674 }
02675
02689 const char*
02690 dbus_message_get_interface (DBusMessage *message)
02691 {
02692 const char *v;
02693
02694 _dbus_return_val_if_fail (message != NULL, NULL);
02695
02696 v = NULL;
02697 _dbus_header_get_field_basic (&message->header,
02698 DBUS_HEADER_FIELD_INTERFACE,
02699 DBUS_TYPE_STRING,
02700 &v);
02701 return v;
02702 }
02703
02711 dbus_bool_t
02712 dbus_message_has_interface (DBusMessage *message,
02713 const char *interface)
02714 {
02715 const char *msg_interface;
02716 msg_interface = dbus_message_get_interface (message);
02717
02718 if (msg_interface == NULL)
02719 {
02720 if (interface == NULL)
02721 return TRUE;
02722 else
02723 return FALSE;
02724 }
02725
02726 if (interface == NULL)
02727 return FALSE;
02728
02729 if (strcmp (msg_interface, interface) == 0)
02730 return TRUE;
02731
02732 return FALSE;
02733
02734 }
02735
02748 dbus_bool_t
02749 dbus_message_set_member (DBusMessage *message,
02750 const char *member)
02751 {
02752 _dbus_return_val_if_fail (message != NULL, FALSE);
02753 _dbus_return_val_if_fail (!message->locked, FALSE);
02754 _dbus_return_val_if_fail (member == NULL ||
02755 _dbus_check_is_valid_member (member),
02756 FALSE);
02757
02758 return set_or_delete_string_field (message,
02759 DBUS_HEADER_FIELD_MEMBER,
02760 DBUS_TYPE_STRING,
02761 member);
02762 }
02763
02775 const char*
02776 dbus_message_get_member (DBusMessage *message)
02777 {
02778 const char *v;
02779
02780 _dbus_return_val_if_fail (message != NULL, NULL);
02781
02782 v = NULL;
02783 _dbus_header_get_field_basic (&message->header,
02784 DBUS_HEADER_FIELD_MEMBER,
02785 DBUS_TYPE_STRING,
02786 &v);
02787 return v;
02788 }
02789
02797 dbus_bool_t
02798 dbus_message_has_member (DBusMessage *message,
02799 const char *member)
02800 {
02801 const char *msg_member;
02802 msg_member = dbus_message_get_member (message);
02803
02804 if (msg_member == NULL)
02805 {
02806 if (member == NULL)
02807 return TRUE;
02808 else
02809 return FALSE;
02810 }
02811
02812 if (member == NULL)
02813 return FALSE;
02814
02815 if (strcmp (msg_member, member) == 0)
02816 return TRUE;
02817
02818 return FALSE;
02819
02820 }
02821
02833 dbus_bool_t
02834 dbus_message_set_error_name (DBusMessage *message,
02835 const char *error_name)
02836 {
02837 _dbus_return_val_if_fail (message != NULL, FALSE);
02838 _dbus_return_val_if_fail (!message->locked, FALSE);
02839 _dbus_return_val_if_fail (error_name == NULL ||
02840 _dbus_check_is_valid_error_name (error_name),
02841 FALSE);
02842
02843 return set_or_delete_string_field (message,
02844 DBUS_HEADER_FIELD_ERROR_NAME,
02845 DBUS_TYPE_STRING,
02846 error_name);
02847 }
02848
02859 const char*
02860 dbus_message_get_error_name (DBusMessage *message)
02861 {
02862 const char *v;
02863
02864 _dbus_return_val_if_fail (message != NULL, NULL);
02865
02866 v = NULL;
02867 _dbus_header_get_field_basic (&message->header,
02868 DBUS_HEADER_FIELD_ERROR_NAME,
02869 DBUS_TYPE_STRING,
02870 &v);
02871 return v;
02872 }
02873
02887 dbus_bool_t
02888 dbus_message_set_destination (DBusMessage *message,
02889 const char *destination)
02890 {
02891 _dbus_return_val_if_fail (message != NULL, FALSE);
02892 _dbus_return_val_if_fail (!message->locked, FALSE);
02893 _dbus_return_val_if_fail (destination == NULL ||
02894 _dbus_check_is_valid_bus_name (destination),
02895 FALSE);
02896
02897 return set_or_delete_string_field (message,
02898 DBUS_HEADER_FIELD_DESTINATION,
02899 DBUS_TYPE_STRING,
02900 destination);
02901 }
02902
02912 const char*
02913 dbus_message_get_destination (DBusMessage *message)
02914 {
02915 const char *v;
02916
02917 _dbus_return_val_if_fail (message != NULL, NULL);
02918
02919 v = NULL;
02920 _dbus_header_get_field_basic (&message->header,
02921 DBUS_HEADER_FIELD_DESTINATION,
02922 DBUS_TYPE_STRING,
02923 &v);
02924 return v;
02925 }
02926
02941 dbus_bool_t
02942 dbus_message_set_sender (DBusMessage *message,
02943 const char *sender)
02944 {
02945 _dbus_return_val_if_fail (message != NULL, FALSE);
02946 _dbus_return_val_if_fail (!message->locked, FALSE);
02947 _dbus_return_val_if_fail (sender == NULL ||
02948 _dbus_check_is_valid_bus_name (sender),
02949 FALSE);
02950
02951 return set_or_delete_string_field (message,
02952 DBUS_HEADER_FIELD_SENDER,
02953 DBUS_TYPE_STRING,
02954 sender);
02955 }
02956
02972 const char*
02973 dbus_message_get_sender (DBusMessage *message)
02974 {
02975 const char *v;
02976
02977 _dbus_return_val_if_fail (message != NULL, NULL);
02978
02979 v = NULL;
02980 _dbus_header_get_field_basic (&message->header,
02981 DBUS_HEADER_FIELD_SENDER,
02982 DBUS_TYPE_STRING,
02983 &v);
02984 return v;
02985 }
02986
03005 const char*
03006 dbus_message_get_signature (DBusMessage *message)
03007 {
03008 const DBusString *type_str;
03009 int type_pos;
03010
03011 _dbus_return_val_if_fail (message != NULL, NULL);
03012
03013 get_const_signature (&message->header, &type_str, &type_pos);
03014
03015 return _dbus_string_get_const_data_len (type_str, type_pos, 0);
03016 }
03017
03018 static dbus_bool_t
03019 _dbus_message_has_type_interface_member (DBusMessage *message,
03020 int type,
03021 const char *interface,
03022 const char *member)
03023 {
03024 const char *n;
03025
03026 _dbus_assert (message != NULL);
03027 _dbus_assert (interface != NULL);
03028 _dbus_assert (member != NULL);
03029
03030 if (dbus_message_get_type (message) != type)
03031 return FALSE;
03032
03033
03034
03035
03036
03037 n = dbus_message_get_member (message);
03038
03039 if (n && strcmp (n, member) == 0)
03040 {
03041 n = dbus_message_get_interface (message);
03042
03043 if (n == NULL || strcmp (n, interface) == 0)
03044 return TRUE;
03045 }
03046
03047 return FALSE;
03048 }
03049
03064 dbus_bool_t
03065 dbus_message_is_method_call (DBusMessage *message,
03066 const char *interface,
03067 const char *method)
03068 {
03069 _dbus_return_val_if_fail (message != NULL, FALSE);
03070 _dbus_return_val_if_fail (interface != NULL, FALSE);
03071 _dbus_return_val_if_fail (method != NULL, FALSE);
03072
03073
03074
03075
03076 return _dbus_message_has_type_interface_member (message,
03077 DBUS_MESSAGE_TYPE_METHOD_CALL,
03078 interface, method);
03079 }
03080
03092 dbus_bool_t
03093 dbus_message_is_signal (DBusMessage *message,
03094 const char *interface,
03095 const char *signal_name)
03096 {
03097 _dbus_return_val_if_fail (message != NULL, FALSE);
03098 _dbus_return_val_if_fail (interface != NULL, FALSE);
03099 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
03100
03101
03102
03103
03104 return _dbus_message_has_type_interface_member (message,
03105 DBUS_MESSAGE_TYPE_SIGNAL,
03106 interface, signal_name);
03107 }
03108
03119 dbus_bool_t
03120 dbus_message_is_error (DBusMessage *message,
03121 const char *error_name)
03122 {
03123 const char *n;
03124
03125 _dbus_return_val_if_fail (message != NULL, FALSE);
03126 _dbus_return_val_if_fail (error_name != NULL, FALSE);
03127
03128
03129
03130
03131 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03132 return FALSE;
03133
03134 n = dbus_message_get_error_name (message);
03135
03136 if (n && strcmp (n, error_name) == 0)
03137 return TRUE;
03138 else
03139 return FALSE;
03140 }
03141
03152 dbus_bool_t
03153 dbus_message_has_destination (DBusMessage *message,
03154 const char *name)
03155 {
03156 const char *s;
03157
03158 _dbus_return_val_if_fail (message != NULL, FALSE);
03159 _dbus_return_val_if_fail (name != NULL, FALSE);
03160
03161
03162
03163
03164 s = dbus_message_get_destination (message);
03165
03166 if (s && strcmp (s, name) == 0)
03167 return TRUE;
03168 else
03169 return FALSE;
03170 }
03171
03187 dbus_bool_t
03188 dbus_message_has_sender (DBusMessage *message,
03189 const char *name)
03190 {
03191 const char *s;
03192
03193 _dbus_return_val_if_fail (message != NULL, FALSE);
03194 _dbus_return_val_if_fail (name != NULL, FALSE);
03195
03196
03197
03198
03199 s = dbus_message_get_sender (message);
03200
03201 if (s && strcmp (s, name) == 0)
03202 return TRUE;
03203 else
03204 return FALSE;
03205 }
03206
03216 dbus_bool_t
03217 dbus_message_has_signature (DBusMessage *message,
03218 const char *signature)
03219 {
03220 const char *s;
03221
03222 _dbus_return_val_if_fail (message != NULL, FALSE);
03223 _dbus_return_val_if_fail (signature != NULL, FALSE);
03224
03225
03226
03227
03228 s = dbus_message_get_signature (message);
03229
03230 if (s && strcmp (s, signature) == 0)
03231 return TRUE;
03232 else
03233 return FALSE;
03234 }
03235
03258 dbus_bool_t
03259 dbus_set_error_from_message (DBusError *error,
03260 DBusMessage *message)
03261 {
03262 const char *str;
03263
03264 _dbus_return_val_if_fail (message != NULL, FALSE);
03265 _dbus_return_val_if_error_is_set (error, FALSE);
03266
03267 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
03268 return FALSE;
03269
03270 str = NULL;
03271 dbus_message_get_args (message, NULL,
03272 DBUS_TYPE_STRING, &str,
03273 DBUS_TYPE_INVALID);
03274
03275 dbus_set_error (error, dbus_message_get_error_name (message),
03276 str ? "%s" : NULL, str);
03277
03278 return TRUE;
03279 }
03280
03299 #define INITIAL_LOADER_DATA_LEN 32
03300
03307 DBusMessageLoader*
03308 _dbus_message_loader_new (void)
03309 {
03310 DBusMessageLoader *loader;
03311
03312 loader = dbus_new0 (DBusMessageLoader, 1);
03313 if (loader == NULL)
03314 return NULL;
03315
03316 loader->refcount = 1;
03317
03318 loader->corrupted = FALSE;
03319 loader->corruption_reason = DBUS_VALID;
03320
03321
03322 loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03323
03324 if (!_dbus_string_init (&loader->data))
03325 {
03326 dbus_free (loader);
03327 return NULL;
03328 }
03329
03330
03331 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
03332 _dbus_string_set_length (&loader->data, 0);
03333
03334 return loader;
03335 }
03336
03343 DBusMessageLoader *
03344 _dbus_message_loader_ref (DBusMessageLoader *loader)
03345 {
03346 loader->refcount += 1;
03347
03348 return loader;
03349 }
03350
03357 void
03358 _dbus_message_loader_unref (DBusMessageLoader *loader)
03359 {
03360 loader->refcount -= 1;
03361 if (loader->refcount == 0)
03362 {
03363 _dbus_list_foreach (&loader->messages,
03364 (DBusForeachFunction) dbus_message_unref,
03365 NULL);
03366 _dbus_list_clear (&loader->messages);
03367 _dbus_string_free (&loader->data);
03368 dbus_free (loader);
03369 }
03370 }
03371
03390 void
03391 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
03392 DBusString **buffer)
03393 {
03394 _dbus_assert (!loader->buffer_outstanding);
03395
03396 *buffer = &loader->data;
03397
03398 loader->buffer_outstanding = TRUE;
03399 }
03400
03411 void
03412 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
03413 DBusString *buffer,
03414 int bytes_read)
03415 {
03416 _dbus_assert (loader->buffer_outstanding);
03417 _dbus_assert (buffer == &loader->data);
03418
03419 loader->buffer_outstanding = FALSE;
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
03445
03446
03447
03448 static dbus_bool_t
03449 load_message (DBusMessageLoader *loader,
03450 DBusMessage *message,
03451 int byte_order,
03452 int fields_array_len,
03453 int header_len,
03454 int body_len)
03455 {
03456 dbus_bool_t oom;
03457 DBusValidity validity;
03458 const DBusString *type_str;
03459 int type_pos;
03460 DBusValidationMode mode;
03461
03462 mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
03463
03464 oom = FALSE;
03465
03466 #if 0
03467 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
03468 #endif
03469
03470
03471 _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
03472 _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
03473
03474 if (!_dbus_header_load (&message->header,
03475 mode,
03476 &validity,
03477 byte_order,
03478 fields_array_len,
03479 header_len,
03480 body_len,
03481 &loader->data, 0,
03482 _dbus_string_get_length (&loader->data)))
03483 {
03484 _dbus_verbose ("Failed to load header for new message code %d\n", validity);
03485
03486
03487
03488 _dbus_assert (validity != DBUS_VALID);
03489
03490 if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
03491 oom = TRUE;
03492 else
03493 {
03494 loader->corrupted = TRUE;
03495 loader->corruption_reason = validity;
03496 }
03497 goto failed;
03498 }
03499
03500 _dbus_assert (validity == DBUS_VALID);
03501
03502 message->byte_order = byte_order;
03503
03504
03505 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
03506 {
03507 get_const_signature (&message->header, &type_str, &type_pos);
03508
03509
03510
03511
03512 validity = _dbus_validate_body_with_reason (type_str,
03513 type_pos,
03514 byte_order,
03515 NULL,
03516 &loader->data,
03517 header_len,
03518 body_len);
03519 if (validity != DBUS_VALID)
03520 {
03521 _dbus_verbose ("Failed to validate message body code %d\n", validity);
03522
03523 loader->corrupted = TRUE;
03524 loader->corruption_reason = validity;
03525
03526 goto failed;
03527 }
03528 }
03529
03530
03531
03532 if (!_dbus_list_append (&loader->messages, message))
03533 {
03534 _dbus_verbose ("Failed to append new message to loader queue\n");
03535 oom = TRUE;
03536 goto failed;
03537 }
03538
03539 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
03540 _dbus_assert (_dbus_string_get_length (&loader->data) >=
03541 (header_len + body_len));
03542
03543 if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
03544 {
03545 _dbus_verbose ("Failed to move body into new message\n");
03546 oom = TRUE;
03547 goto failed;
03548 }
03549
03550 _dbus_string_delete (&loader->data, 0, header_len + body_len);
03551
03552
03553 _dbus_string_compact (&loader->data, 2048);
03554
03555 _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
03556 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
03557
03558 _dbus_verbose ("Loaded message %p\n", message);
03559
03560 _dbus_assert (!oom);
03561 _dbus_assert (!loader->corrupted);
03562 _dbus_assert (loader->messages != NULL);
03563 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03564
03565 return TRUE;
03566
03567 failed:
03568
03569
03570
03571
03572 _dbus_list_remove_last (&loader->messages, message);
03573
03574 if (oom)
03575 _dbus_assert (!loader->corrupted);
03576 else
03577 _dbus_assert (loader->corrupted);
03578
03579 _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
03580
03581 return FALSE;
03582 }
03583
03598 dbus_bool_t
03599 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
03600 {
03601 while (!loader->corrupted &&
03602 _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
03603 {
03604 DBusValidity validity;
03605 int byte_order, fields_array_len, header_len, body_len;
03606
03607 if (_dbus_header_have_message_untrusted (loader->max_message_size,
03608 &validity,
03609 &byte_order,
03610 &fields_array_len,
03611 &header_len,
03612 &body_len,
03613 &loader->data, 0,
03614 _dbus_string_get_length (&loader->data)))
03615 {
03616 DBusMessage *message;
03617
03618 _dbus_assert (validity == DBUS_VALID);
03619
03620 message = dbus_message_new_empty_header ();
03621 if (message == NULL)
03622 return FALSE;
03623
03624 if (!load_message (loader, message,
03625 byte_order, fields_array_len,
03626 header_len, body_len))
03627 {
03628 dbus_message_unref (message);
03629
03630
03631
03632 return loader->corrupted;
03633 }
03634
03635 _dbus_assert (loader->messages != NULL);
03636 _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
03637 }
03638 else
03639 {
03640 _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
03641 validity);
03642 if (validity != DBUS_VALID)
03643 {
03644 loader->corrupted = TRUE;
03645 loader->corruption_reason = validity;
03646 }
03647 return TRUE;
03648 }
03649 }
03650
03651 return TRUE;
03652 }
03653
03661 DBusMessage*
03662 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
03663 {
03664 if (loader->messages)
03665 return loader->messages->data;
03666 else
03667 return NULL;
03668 }
03669
03678 DBusMessage*
03679 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
03680 {
03681 return _dbus_list_pop_first (&loader->messages);
03682 }
03683
03692 DBusList*
03693 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
03694 {
03695 return _dbus_list_pop_first_link (&loader->messages);
03696 }
03697
03704 void
03705 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
03706 DBusList *link)
03707 {
03708 _dbus_list_prepend_link (&loader->messages, link);
03709 }
03710
03720 dbus_bool_t
03721 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
03722 {
03723 _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
03724 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
03725 return loader->corrupted;
03726 }
03727
03734 void
03735 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
03736 long size)
03737 {
03738 if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
03739 {
03740 _dbus_verbose ("clamping requested max message size %ld to %d\n",
03741 size, DBUS_MAXIMUM_MESSAGE_LENGTH);
03742 size = DBUS_MAXIMUM_MESSAGE_LENGTH;
03743 }
03744 loader->max_message_size = size;
03745 }
03746
03753 long
03754 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
03755 {
03756 return loader->max_message_size;
03757 }
03758
03759 static DBusDataSlotAllocator slot_allocator;
03760 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
03761
03776 dbus_bool_t
03777 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
03778 {
03779 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03780 &_DBUS_LOCK_NAME (message_slots),
03781 slot_p);
03782 }
03783
03795 void
03796 dbus_message_free_data_slot (dbus_int32_t *slot_p)
03797 {
03798 _dbus_return_if_fail (*slot_p >= 0);
03799
03800 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03801 }
03802
03816 dbus_bool_t
03817 dbus_message_set_data (DBusMessage *message,
03818 dbus_int32_t slot,
03819 void *data,
03820 DBusFreeFunction free_data_func)
03821 {
03822 DBusFreeFunction old_free_func;
03823 void *old_data;
03824 dbus_bool_t retval;
03825
03826 _dbus_return_val_if_fail (message != NULL, FALSE);
03827 _dbus_return_val_if_fail (slot >= 0, FALSE);
03828
03829 retval = _dbus_data_slot_list_set (&slot_allocator,
03830 &message->slot_list,
03831 slot, data, free_data_func,
03832 &old_free_func, &old_data);
03833
03834 if (retval)
03835 {
03836
03837 if (old_free_func)
03838 (* old_free_func) (old_data);
03839 }
03840
03841 return retval;
03842 }
03843
03852 void*
03853 dbus_message_get_data (DBusMessage *message,
03854 dbus_int32_t slot)
03855 {
03856 void *res;
03857
03858 _dbus_return_val_if_fail (message != NULL, NULL);
03859
03860 res = _dbus_data_slot_list_get (&slot_allocator,
03861 &message->slot_list,
03862 slot);
03863
03864 return res;
03865 }
03866
03880 int
03881 dbus_message_type_from_string (const char *type_str)
03882 {
03883 if (strcmp (type_str, "method_call") == 0)
03884 return DBUS_MESSAGE_TYPE_METHOD_CALL;
03885 if (strcmp (type_str, "method_return") == 0)
03886 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
03887 else if (strcmp (type_str, "signal") == 0)
03888 return DBUS_MESSAGE_TYPE_SIGNAL;
03889 else if (strcmp (type_str, "error") == 0)
03890 return DBUS_MESSAGE_TYPE_ERROR;
03891 else
03892 return DBUS_MESSAGE_TYPE_INVALID;
03893 }
03894
03908 const char *
03909 dbus_message_type_to_string (int type)
03910 {
03911 switch (type)
03912 {
03913 case DBUS_MESSAGE_TYPE_METHOD_CALL:
03914 return "method_call";
03915 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
03916 return "method_return";
03917 case DBUS_MESSAGE_TYPE_SIGNAL:
03918 return "signal";
03919 case DBUS_MESSAGE_TYPE_ERROR:
03920 return "error";
03921 default:
03922 return "invalid";
03923 }
03924 }
03925
03938 dbus_bool_t
03939 dbus_message_marshal (DBusMessage *msg,
03940 char **marshalled_data_p,
03941 int *len_p)
03942 {
03943 DBusString tmp;
03944
03945 _dbus_return_val_if_fail (msg != NULL, FALSE);
03946 _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
03947 _dbus_return_val_if_fail (len_p != NULL, FALSE);
03948
03949 if (!_dbus_string_init (&tmp))
03950 return FALSE;
03951
03952 if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
03953 goto fail;
03954
03955 *len_p = _dbus_string_get_length (&tmp);
03956
03957 if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
03958 goto fail;
03959
03960 *len_p = _dbus_string_get_length (&tmp);
03961
03962 if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
03963 goto fail;
03964
03965 _dbus_string_free (&tmp);
03966 return TRUE;
03967
03968 fail:
03969 _dbus_string_free (&tmp);
03970 return FALSE;
03971 }
03972
03985 DBusMessage *
03986 dbus_message_demarshal (const char *str,
03987 int len,
03988 DBusError *error)
03989 {
03990 DBusMessageLoader *loader;
03991 DBusString *buffer;
03992 DBusMessage *msg;
03993
03994 _dbus_return_val_if_fail (str != NULL, NULL);
03995
03996 loader = _dbus_message_loader_new ();
03997
03998 if (loader == NULL)
03999 return NULL;
04000
04001 _dbus_message_loader_get_buffer (loader, &buffer);
04002 _dbus_string_append_len (buffer, str, len);
04003 _dbus_message_loader_return_buffer (loader, buffer, len);
04004
04005 if (!_dbus_message_loader_queue_messages (loader))
04006 goto fail_oom;
04007
04008 if (_dbus_message_loader_get_is_corrupted (loader))
04009 goto fail_corrupt;
04010
04011 msg = _dbus_message_loader_pop_message (loader);
04012
04013 if (!msg)
04014 goto fail_oom;
04015
04016 _dbus_message_loader_unref (loader);
04017 return msg;
04018
04019 fail_corrupt:
04020 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted");
04021 _dbus_message_loader_unref (loader);
04022 return NULL;
04023
04024 fail_oom:
04025 _DBUS_SET_OOM (error);
04026 _dbus_message_loader_unref (loader);
04027 return NULL;
04028 }
04029
04043 int
04044 dbus_message_demarshal_bytes_needed(const char *buf,
04045 int len)
04046 {
04047 DBusString str;
04048 int byte_order, fields_array_len, header_len, body_len;
04049 DBusValidity validity = DBUS_VALID;
04050 int have_message;
04051
04052 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
04053 return 0;
04054
04055 if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
04056 len = DBUS_MAXIMUM_MESSAGE_LENGTH;
04057 _dbus_string_init_const_len (&str, buf, len);
04058
04059 validity = DBUS_VALID;
04060 have_message
04061 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
04062 &validity, &byte_order,
04063 &fields_array_len,
04064 &header_len,
04065 &body_len,
04066 &str, 0,
04067 len);
04068 _dbus_string_free (&str);
04069
04070 if (validity == DBUS_VALID)
04071 {
04072 _dbus_assert(have_message);
04073 return header_len + body_len;
04074 }
04075 else
04076 {
04077 return -1;
04078 }
04079 }
04080
04083