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