Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

dbus-message.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-message.c  DBusMessage object
00003  *
00004  * Copyright (C) 2002, 2003, 2004  Red Hat Inc.
00005  * Copyright (C) 2002, 2003  CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "dbus-internals.h"
00026 #include "dbus-marshal.h"
00027 #include "dbus-message.h"
00028 #include "dbus-message-internal.h"
00029 #include "dbus-memory.h"
00030 #include "dbus-list.h"
00031 #include "dbus-message-builder.h"
00032 #include "dbus-dataslot.h"
00033 #include <string.h>
00034 
00048 typedef struct
00049 {
00050   int name_offset;  
00051   int value_offset; 
00052 } HeaderField;
00053 
00055 #define BYTE_ORDER_OFFSET    0
00056 
00057 #define TYPE_OFFSET          1
00058 
00059 #define FLAGS_OFFSET         2
00060 
00061 #define VERSION_OFFSET       3
00062 
00063 #define HEADER_LENGTH_OFFSET 4
00064 
00065 #define BODY_LENGTH_OFFSET   8
00066 
00067 #define CLIENT_SERIAL_OFFSET 12
00068 
00069 
00077 struct DBusMessage
00078 {
00079   DBusAtomic refcount; 
00081   DBusString header; 
00086   HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1]; 
00090   dbus_uint32_t client_serial; 
00091   dbus_uint32_t reply_serial;  
00093   int header_padding; 
00095   DBusString body;   
00097   char byte_order; 
00099   unsigned int locked : 1; 
00101   DBusList *size_counters;   
00102   long size_counter_delta;   
00104   dbus_uint32_t changed_stamp; 
00106   DBusDataSlotList slot_list;   
00108 #ifndef DBUS_DISABLE_CHECKS
00109   int generation; 
00110 #endif
00111 };
00112 
00113 enum {
00114   DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00115   DBUS_MESSAGE_ITER_TYPE_ARRAY,
00116   DBUS_MESSAGE_ITER_TYPE_DICT
00117 };
00118 
00120 typedef struct DBusMessageRealIter DBusMessageRealIter;
00121 
00127 struct DBusMessageRealIter
00128 {
00129   DBusMessageRealIter *parent_iter; 
00130   DBusMessage *message; 
00131   dbus_uint32_t changed_stamp; 
00133   /* This is an int instead of an enum to get a guaranteed size for the dummy: */
00134   int type; 
00136   int pos; 
00137   int end; 
00138   int container_start; 
00139   int container_length_pos; 
00141   int wrote_dict_key; 
00143   int array_type_pos; 
00144   int array_type_done; 
00145 };
00146 
00157 void
00158 _dbus_message_get_network_data (DBusMessage          *message,
00159                                 const DBusString    **header,
00160                                 const DBusString    **body)
00161 {
00162   _dbus_assert (message->locked);
00163   
00164   *header = &message->header;
00165   *body = &message->body;
00166 }
00167 
00168 static void
00169 clear_header_padding (DBusMessage *message)
00170 {
00171   _dbus_string_shorten (&message->header,
00172                         message->header_padding);
00173   message->header_padding = 0;
00174 }              
00175 
00176 #ifdef DBUS_DISABLE_CHECKS
00177 #define is_valid_error_name(x) TRUE
00178 #else
00179 static dbus_bool_t
00180 is_valid_error_name (const char *error_name)                                          
00181 {
00182   DBusString the_error_name;
00183 
00184   if (error_name == NULL)
00185     return FALSE;
00186   
00187   _dbus_string_init_const (&the_error_name, error_name);
00188   return _dbus_string_validate_error_name (&the_error_name, 0,   
00189                                            _dbus_string_get_length (&the_error_name));
00190 }
00191 #endif
00192 
00193 static dbus_bool_t
00194 append_header_padding (DBusMessage *message)
00195 {
00196   int old_len;
00197   old_len = _dbus_string_get_length (&message->header);
00198   if (!_dbus_string_align_length (&message->header, 8))
00199     return FALSE;
00200 
00201   message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00202 
00203   return TRUE;
00204 }
00205 
00206 #ifdef DBUS_BUILD_TESTS
00207 /* tests-only until it's actually used */
00208 static dbus_int32_t
00209 get_int_field (DBusMessage *message,
00210                int          field)
00211 {
00212   int offset;
00213 
00214   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00215   
00216   offset = message->header_fields[field].value_offset;
00217   
00218   if (offset < 0)
00219     return -1; /* useless if -1 is a valid value of course */
00220   
00221   return _dbus_demarshal_int32 (&message->header,
00222                                 message->byte_order,
00223                                 offset,
00224                                 NULL);
00225 }
00226 #endif
00227 
00228 static dbus_uint32_t
00229 get_uint_field (DBusMessage *message,
00230                 int          field)
00231 {
00232   int offset;
00233   
00234   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00235   
00236   offset = message->header_fields[field].value_offset;
00237   
00238   if (offset < 0)
00239     return 0; /* useless if 0 is a valid value of course */
00240   
00241   return _dbus_demarshal_uint32 (&message->header,
00242                                  message->byte_order,
00243                                  offset,
00244                                  NULL);
00245 }
00246 
00247 static const char*
00248 get_string_field (DBusMessage *message,
00249                   int          field,
00250                   int         *len)
00251 {
00252   int offset;
00253   const char *data;
00254 
00255   _dbus_return_val_if_fail (message->generation == _dbus_current_generation,
00256                             NULL);
00257   
00258   offset = message->header_fields[field].value_offset;
00259 
00260   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00261   
00262   if (offset < 0)
00263     return NULL;
00264 
00265   /* offset points to string length, string data follows it */
00266   /* FIXME _dbus_demarshal_const_string() that returned
00267    * a reference to the string plus its len might be nice.
00268    */
00269   
00270   if (len)
00271     *len = _dbus_demarshal_uint32 (&message->header,
00272                                    message->byte_order,
00273                                    offset,
00274                                    NULL);
00275 
00276   data = _dbus_string_get_const_data (&message->header);
00277   
00278   return data + (offset + 4); 
00279 }
00280 
00281 /* returns FALSE if no memory, TRUE with NULL path if no field */
00282 static dbus_bool_t
00283 get_path_field_decomposed (DBusMessage  *message,
00284                            int           field,
00285                            char       ***path)
00286 {
00287   int offset;
00288 
00289   offset = message->header_fields[field].value_offset;
00290 
00291   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00292   
00293   if (offset < 0)
00294     {
00295       *path = NULL;
00296       return TRUE;
00297     }
00298 
00299   return _dbus_demarshal_object_path (&message->header,
00300                                       message->byte_order,
00301                                       offset,
00302                                       NULL,
00303                                       path, NULL);
00304 }
00305 
00306 #ifdef DBUS_BUILD_TESTS
00307 static dbus_bool_t
00308 append_int_field (DBusMessage *message,
00309                   int          field,
00310                   int          value)
00311 {
00312   _dbus_assert (!message->locked);
00313 
00314   clear_header_padding (message);
00315   
00316   message->header_fields[field].name_offset =
00317     _dbus_string_get_length (&message->header);
00318   
00319   if (!_dbus_string_append_byte (&message->header, field))
00320     goto failed;
00321 
00322   if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00323     goto failed;
00324 
00325   if (!_dbus_string_align_length (&message->header, 4))
00326     goto failed;
00327   
00328   message->header_fields[field].value_offset =
00329     _dbus_string_get_length (&message->header);
00330   
00331   if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00332                             value))
00333     goto failed;
00334 
00335   if (!append_header_padding (message))
00336     goto failed;
00337   
00338   return TRUE;
00339   
00340  failed:
00341   _dbus_string_set_length (&message->header,
00342                            message->header_fields[field].name_offset);
00343   message->header_fields[field].name_offset  = -1;
00344   message->header_fields[field].value_offset = -1;
00345 
00346   /* this must succeed because it was allocated on function entry and
00347    * DBusString doesn't ever realloc smaller
00348    */
00349   if (!append_header_padding (message))
00350     _dbus_assert_not_reached ("failed to reappend header padding");
00351   return FALSE;
00352 }
00353 #endif
00354 
00355 static dbus_bool_t
00356 append_uint_field (DBusMessage *message,
00357                    int          field,
00358                    int          value)
00359 {
00360   _dbus_assert (!message->locked);
00361 
00362   clear_header_padding (message);
00363   
00364   message->header_fields[field].name_offset =
00365     _dbus_string_get_length (&message->header);
00366   
00367   if (!_dbus_string_append_byte (&message->header, field))
00368     goto failed;
00369 
00370   if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00371     goto failed;
00372 
00373   if (!_dbus_string_align_length (&message->header, 4))
00374     goto failed;
00375   
00376   message->header_fields[field].value_offset =
00377     _dbus_string_get_length (&message->header);
00378   
00379   if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00380                              value))
00381     goto failed;
00382 
00383   if (!append_header_padding (message))
00384     goto failed;
00385   
00386   return TRUE;
00387   
00388  failed:
00389   _dbus_string_set_length (&message->header,
00390                            message->header_fields[field].name_offset);
00391   message->header_fields[field].name_offset  = -1;
00392   message->header_fields[field].value_offset = -1;
00393 
00394   /* this must succeed because it was allocated on function entry and
00395    * DBusString doesn't ever realloc smaller
00396    */
00397   if (!append_header_padding (message))
00398     _dbus_assert_not_reached ("failed to reappend header padding");
00399   return FALSE;
00400 }
00401 
00405 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8)
00406 
00407 static dbus_bool_t
00408 append_string_field_len (DBusMessage *message,
00409                          int          field,
00410                          int          type,
00411                          const char  *value,
00412                          int          value_len)
00413 {
00414   _dbus_assert (!message->locked);
00415 
00416   clear_header_padding (message);
00417   
00418   message->header_fields[field].name_offset =
00419     _dbus_string_get_length (&message->header);
00420   
00421   if (!_dbus_string_append_byte (&message->header, field))
00422     goto failed;
00423   
00424   if (!_dbus_string_append_byte (&message->header, type))
00425     goto failed;
00426 
00427   if (!_dbus_string_align_length (&message->header, 4))
00428     goto failed;
00429   
00430   message->header_fields[field].value_offset =
00431     _dbus_string_get_length (&message->header);
00432   
00433   if (!_dbus_marshal_string_len (&message->header, message->byte_order,
00434                                  value, value_len))
00435     goto failed;
00436 
00437   if (!append_header_padding (message))
00438     goto failed;
00439   
00440   return TRUE;
00441   
00442  failed:
00443   _dbus_string_set_length (&message->header,
00444                            message->header_fields[field].name_offset);
00445   message->header_fields[field].name_offset  = -1;
00446   message->header_fields[field].value_offset = -1;
00447 
00448   /* this must succeed because it was allocated on function entry and
00449    * DBusString doesn't ever realloc smaller
00450    */
00451   if (!append_header_padding (message))
00452     _dbus_assert_not_reached ("failed to reappend header padding");
00453   
00454   return FALSE;
00455 }
00456 
00457 static dbus_bool_t
00458 append_string_field (DBusMessage *message,
00459                      int          field,
00460                      int          type,
00461                      const char  *value)
00462 {
00463   int value_len;
00464 
00465   value_len = strlen (value);
00466 
00467   return append_string_field_len (message, field, type, value, value_len);
00468 }
00469 
00470 static int
00471 get_type_alignment (int type)
00472 {
00473   int alignment;
00474   
00475   switch (type)
00476     {
00477     case DBUS_TYPE_NIL:
00478     case DBUS_TYPE_BYTE:
00479     case DBUS_TYPE_BOOLEAN:
00480       alignment = 0;
00481       break;
00482 
00483     case DBUS_TYPE_INT32:
00484     case DBUS_TYPE_UINT32:
00485     case DBUS_TYPE_STRING:
00486     case DBUS_TYPE_OBJECT_PATH:
00487       /* These are aligned 4 because they have a length as the
00488        * first field;
00489        */
00490     case DBUS_TYPE_CUSTOM:
00491     case DBUS_TYPE_DICT:
00492       alignment = 4;
00493       break;
00494 
00495     case DBUS_TYPE_INT64:
00496     case DBUS_TYPE_UINT64:
00497     case DBUS_TYPE_DOUBLE:
00498       alignment = 8;
00499       break;
00500 
00501     case DBUS_TYPE_ARRAY:
00502       _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
00503       alignment = 0; /* quiet gcc */
00504       break;
00505 
00506     case DBUS_TYPE_INVALID:
00507     default:
00508       _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
00509       alignment = 0; /* quiet gcc */
00510       break;
00511     }
00512 
00513   return alignment;
00514 }
00515 
00516 static dbus_bool_t
00517 iterate_one_field (const DBusString *str,
00518                    int               byte_order,
00519                    int               name_offset,
00520                    int              *next_offset_p,
00521                    int              *field_name_p,
00522                    DBusString       *append_copy_to,
00523                    int              *copy_name_offset_p,
00524                    int              *copy_value_offset_p)
00525 {
00526   int name, type, array_type;
00527   int alignment;
00528   int type_len;
00529   int type_pos;
00530   int value_pos;
00531   int value_len;
00532   int value_end;
00533   int pos;
00534 
00535 #if 0
00536   _dbus_verbose ("%s: name_offset=%d, append to %p\n",
00537                  _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
00538 #endif
00539   
00540   pos = name_offset;
00541   
00542   name = _dbus_string_get_byte (str, name_offset);
00543   pos++;
00544 
00545   type_pos = pos;
00546   type = _dbus_string_get_byte (str, type_pos);
00547   pos++;
00548   type_len = 1;
00549 
00550   array_type = type;
00551   /* find out the type of our array */
00552   while (array_type == DBUS_TYPE_ARRAY)
00553     {
00554       pos++;
00555       type_len++;
00556       array_type = _dbus_string_get_byte (str, pos);
00557     }
00558 
00559 #if 0
00560   _dbus_verbose ("%s: name %s, type '%c' %d at %d len %d, array type '%c' %d\n",
00561                  _DBUS_FUNCTION_NAME,
00562                  _dbus_header_field_to_string (name),
00563                  type, type, type_pos, type_len, array_type, array_type);
00564 #endif
00565   
00566 #ifndef DBUS_DISABLE_ASSERT
00567   if (!_dbus_type_is_valid (array_type))
00568     {
00569       _dbus_warn ("type '%c' %d is not valid in %s\n",
00570                   array_type, array_type, _DBUS_FUNCTION_NAME);
00571       _dbus_assert_not_reached ("invalid type");
00572     }
00573 #endif
00574       
00575   alignment = get_type_alignment (array_type);
00576       
00577   if (alignment > 0)
00578     pos = _DBUS_ALIGN_VALUE (pos, alignment);
00579 
00580   _dbus_verbose ("%s: alignment %d value at pos %d\n",
00581                  _DBUS_FUNCTION_NAME, alignment, pos);
00582   
00583   /* pos now points to our value */
00584   if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
00585                                       type, pos, &value_end))
00586     _dbus_assert_not_reached ("failed to get the byte after this header");
00587 
00588   value_pos = pos;
00589   value_len = value_end - value_pos;
00590 
00591   _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
00592                  _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
00593   
00594   if (next_offset_p)
00595     *next_offset_p = pos + value_len;
00596 
00597   if (field_name_p)
00598     *field_name_p = name;
00599 
00600   if (append_copy_to)
00601     {
00602       int orig_len;
00603 
00604       orig_len = _dbus_string_get_length (append_copy_to);
00605 
00606       if (copy_name_offset_p)
00607         *copy_name_offset_p = orig_len;
00608       
00609       if (!_dbus_string_append_byte (append_copy_to, name))
00610         goto failed_copy;
00611 
00612       if (!_dbus_string_copy_len (str, type_pos, type_len,
00613                                   append_copy_to,
00614                                   _dbus_string_get_length (append_copy_to)))
00615         goto failed_copy;
00616 
00617       if (!_dbus_string_align_length (append_copy_to, alignment))
00618         goto failed_copy;
00619 
00620       if (copy_value_offset_p)
00621         *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
00622       
00623       if (!_dbus_string_copy_len (str, value_pos, value_len,
00624                                   append_copy_to,
00625                                   _dbus_string_get_length (append_copy_to)))
00626         goto failed_copy;
00627       
00628       return TRUE;
00629 
00630     failed_copy:
00631       _dbus_verbose ("%s: Failed copying old fields to new string\n",
00632                      _DBUS_FUNCTION_NAME);
00633       _dbus_string_set_length (append_copy_to, orig_len);
00634       return FALSE;
00635     }
00636   else
00637     return TRUE;
00638 }
00639 
00640 #ifndef DBUS_DISABLE_ASSERT
00641 static void
00642 verify_header_fields (DBusMessage *message)
00643 {
00644   int i;
00645   i = 0;
00646   while (i <= DBUS_HEADER_FIELD_LAST)
00647     {
00648       if (message->header_fields[i].name_offset >= 0)
00649         _dbus_assert (_dbus_string_get_byte (&message->header,
00650                                              message->header_fields[i].name_offset) ==
00651                       i);
00652       ++i;
00653     }
00654 }
00655 #else /* DBUS_DISABLE_ASSERT */
00656 #define verify_header_fields(x)
00657 #endif /* DBUS_DISABLE_ASSERT */
00658 
00659 /* In this function we delete one field and re-align all the fields
00660  * following it.
00661  */
00662 static dbus_bool_t
00663 delete_one_and_re_align (DBusMessage *message,
00664                          int          name_offset_to_delete)
00665 {
00666   DBusString copy;
00667   int new_fields_front_padding;
00668   int next_offset;
00669   int field_name;
00670   dbus_bool_t retval;
00671   HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST+1];
00672   
00673   _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
00674   verify_header_fields (message);
00675 
00676   _dbus_verbose ("%s: Deleting one field at offset %d\n",
00677                  _DBUS_FUNCTION_NAME,
00678                  name_offset_to_delete);
00679   
00680   retval = FALSE;
00681 
00682   clear_header_padding (message);
00683   
00684   if (!_dbus_string_init_preallocated (&copy,
00685                                        _dbus_string_get_length (&message->header) -
00686                                        name_offset_to_delete + 8))
00687     {
00688       _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
00689                      _DBUS_FUNCTION_NAME);
00690       goto out_0;
00691     }
00692   
00693   /* Align the name offset of the first field in the same way it's
00694    * aligned in the real header
00695    */
00696   new_fields_front_padding = name_offset_to_delete % 8;
00697 
00698   if (!_dbus_string_insert_bytes (&copy, 0, new_fields_front_padding,
00699                                   '\0'))
00700     _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
00701 
00702   memcpy (new_header_fields, message->header_fields,
00703           sizeof (new_header_fields));
00704   
00705   /* Now just re-marshal each field in the header to our temporary
00706    * buffer, skipping the first one. The tricky part is that the
00707    * fields are padded as if for previous_name_offset, but are in fact
00708    * at unaligned_name_offset
00709    */
00710 
00711   if (!iterate_one_field (&message->header,
00712                           message->byte_order,
00713                           name_offset_to_delete,
00714                           &next_offset,
00715                           &field_name, NULL, NULL, NULL))
00716     _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
00717 
00718   _dbus_verbose ("  Skipping %s field which will be deleted; next_offset = %d\n",
00719                  _dbus_header_field_to_string (field_name), next_offset);
00720   
00721   /* This field no longer exists */
00722   if (field_name <= DBUS_HEADER_FIELD_LAST)
00723     {
00724       new_header_fields[field_name].name_offset = -1;
00725       new_header_fields[field_name].value_offset = -1;
00726     }
00727   
00728   while (next_offset < _dbus_string_get_length (&message->header))
00729     {
00730       int copy_name_offset;
00731       int copy_value_offset;
00732 
00733       if (!iterate_one_field (&message->header,
00734                               message->byte_order,
00735                               next_offset,
00736                               &next_offset,
00737                               &field_name,
00738                               &copy,
00739                               &copy_name_offset,
00740                               &copy_value_offset))
00741         {
00742           _dbus_verbose ("%s: OOM iterating one field\n",
00743                          _DBUS_FUNCTION_NAME);
00744           goto out_1;
00745         }
00746       
00747       if (field_name <= DBUS_HEADER_FIELD_LAST)
00748         {
00749           new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
00750           new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
00751           
00752           _dbus_verbose ("  Re-adding %s field at name_offset = %d value_offset = %d; next_offset = %d\n",
00753                          _dbus_header_field_to_string (field_name),
00754                          new_header_fields[field_name].name_offset,
00755                          new_header_fields[field_name].value_offset,
00756                          next_offset);
00757         }
00758     }
00759 
00760   if (!_dbus_string_replace_len (&copy,
00761                                  new_fields_front_padding,
00762                                  _dbus_string_get_length (&copy) - new_fields_front_padding,
00763                                  &message->header,
00764                                  name_offset_to_delete,
00765                                  _dbus_string_get_length (&message->header) - name_offset_to_delete))
00766     {
00767       _dbus_verbose ("%s: OOM moving copy back into header\n",
00768                      _DBUS_FUNCTION_NAME);
00769       goto out_1;
00770     }
00771   
00772   memcpy (message->header_fields, new_header_fields,
00773           sizeof (new_header_fields));
00774   verify_header_fields (message);
00775   
00776   retval = TRUE;
00777   
00778  out_1:
00779   _dbus_string_free (&copy);
00780   
00781  out_0:
00782   if (!append_header_padding (message))
00783     _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
00784   
00785   return retval;
00786 }
00787 
00788 static dbus_bool_t
00789 delete_field (DBusMessage *message,
00790               int          field,
00791               int          prealloc_header_space)
00792 {
00793   int offset;
00794 
00795   _dbus_assert (!message->locked);
00796 
00797   /* Prealloc */
00798   if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
00799     {
00800       _dbus_verbose ("failed to prealloc %d bytes header space\n",
00801                      prealloc_header_space);
00802       return FALSE;
00803     }
00804   _dbus_string_shorten (&message->header, prealloc_header_space);
00805 
00806   /* Delete */
00807   offset = message->header_fields[field].name_offset;
00808   if (offset < 0)
00809     {
00810       _dbus_verbose ("header field didn't exist, no need to delete\n");
00811       return TRUE; /* field didn't exist */
00812     }
00813 
00814   return delete_one_and_re_align (message, offset);
00815 }
00816 
00817 #ifdef DBUS_BUILD_TESTS
00818 static dbus_bool_t
00819 set_int_field (DBusMessage *message,
00820                int          field,
00821                int          value)
00822 {
00823   int offset = message->header_fields[field].value_offset;
00824 
00825   _dbus_assert (!message->locked);
00826 
00827   _dbus_verbose ("set_int_field() field %d value '%d'\n",
00828                  field, value);
00829   
00830   if (offset < 0)
00831     {
00832       /* need to append the field */
00833       return append_int_field (message, field, value);
00834     }
00835   else
00836     {
00837       _dbus_marshal_set_int32 (&message->header,
00838                                message->byte_order,
00839                                offset, value);
00840 
00841       return TRUE;
00842     }
00843 }
00844 #endif
00845 
00846 static dbus_bool_t
00847 set_uint_field (DBusMessage  *message,
00848                 int           field,
00849                 dbus_uint32_t value)
00850 {
00851   int offset = message->header_fields[field].value_offset;
00852 
00853   _dbus_assert (!message->locked);
00854 
00855   _dbus_verbose ("set_uint_field() field %d value '%u'\n",
00856                  field, value);
00857   
00858   if (offset < 0)
00859     {
00860       /* need to append the field */
00861       return append_uint_field (message, field, value);
00862     }
00863   else
00864     {
00865       _dbus_marshal_set_uint32 (&message->header,
00866                                 message->byte_order,
00867                                 offset, value);
00868 
00869       return TRUE;
00870     }
00871 }
00872 
00873 static dbus_bool_t
00874 set_string_field (DBusMessage *message,
00875                   int          field,
00876                   int          type,
00877                   const char  *value)
00878 {
00879   int prealloc;
00880   int value_len;
00881   
00882   _dbus_assert (!message->locked);
00883 
00884   value_len = value ? strlen (value) : 0;
00885   
00886   /* the prealloc is so the append_string_field()
00887    * below won't fail, leaving us in inconsistent state
00888    */
00889   prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
00890 
00891   _dbus_verbose ("set_string_field() field %d prealloc %d value '%s'\n",
00892                  field, prealloc, value);
00893   
00894   if (!delete_field (message, field, prealloc))
00895     return FALSE;
00896 
00897   if (value != NULL)
00898     {
00899       /* need to append the field */
00900       if (!append_string_field_len (message, field, type, value, value_len))
00901         _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
00902     }
00903   
00904   return TRUE;
00905 }
00906 
00914 void
00915 _dbus_message_set_serial (DBusMessage  *message,
00916                           dbus_int32_t  serial)
00917 {
00918   _dbus_assert (!message->locked);
00919   _dbus_assert (dbus_message_get_serial (message) == 0);
00920 
00921   _dbus_marshal_set_uint32 (&message->header,
00922                             message->byte_order,
00923                             CLIENT_SERIAL_OFFSET,
00924                             serial);
00925 
00926   message->client_serial = serial;
00927 }
00928 
00937 dbus_bool_t
00938 dbus_message_set_reply_serial (DBusMessage   *message,
00939                                dbus_uint32_t  reply_serial)
00940 {
00941   _dbus_assert (!message->locked);
00942 
00943   if (set_uint_field (message,
00944                       DBUS_HEADER_FIELD_REPLY_SERIAL,
00945                       reply_serial))
00946     {
00947       message->reply_serial = reply_serial;
00948       return TRUE;
00949     }
00950   else
00951     return FALSE;
00952 }
00953 
00964 dbus_uint32_t
00965 dbus_message_get_serial (DBusMessage *message)
00966 {
00967   return message->client_serial;
00968 }
00969 
00976 dbus_uint32_t
00977 dbus_message_get_reply_serial  (DBusMessage *message)
00978 {
00979   return message->reply_serial;
00980 }
00981 
00994 void
00995 _dbus_message_add_size_counter_link (DBusMessage  *message,
00996                                      DBusList     *link)
00997 {
00998   /* right now we don't recompute the delta when message
00999    * size changes, and that's OK for current purposes
01000    * I think, but could be important to change later.
01001    * Do recompute it whenever there are no outstanding counters,
01002    * since it's basically free.
01003    */
01004   if (message->size_counters == NULL)
01005     {
01006       message->size_counter_delta =
01007         _dbus_string_get_length (&message->header) +
01008         _dbus_string_get_length (&message->body);
01009       
01010 #if 0
01011       _dbus_verbose ("message has size %ld\n",
01012                      message->size_counter_delta);
01013 #endif
01014     }
01015   
01016   _dbus_list_append_link (&message->size_counters, link);
01017   
01018   _dbus_counter_adjust (link->data, message->size_counter_delta);
01019 }
01020 
01030 dbus_bool_t
01031 _dbus_message_add_size_counter (DBusMessage *message,
01032                                 DBusCounter *counter)
01033 {
01034   DBusList *link;
01035 
01036   link = _dbus_list_alloc_link (counter);
01037   if (link == NULL)
01038     return FALSE;
01039 
01040   _dbus_counter_ref (counter);
01041   _dbus_message_add_size_counter_link (message, link);
01042 
01043   return TRUE;
01044 }
01045 
01054 void
01055 _dbus_message_remove_size_counter (DBusMessage  *message,
01056                                    DBusCounter  *counter,
01057                                    DBusList    **link_return)
01058 {
01059   DBusList *link;
01060 
01061   link = _dbus_list_find_last (&message->size_counters,
01062                                counter);
01063   _dbus_assert (link != NULL);
01064 
01065   _dbus_list_unlink (&message->size_counters,
01066                      link);
01067   if (link_return)
01068     *link_return = link;
01069   else
01070     _dbus_list_free_link (link);
01071 
01072   _dbus_counter_adjust (counter, - message->size_counter_delta);
01073 
01074   _dbus_counter_unref (counter);
01075 }
01076 
01077 static dbus_bool_t
01078 dbus_message_create_header (DBusMessage *message,
01079                             int          type,
01080                             const char  *service,
01081                             const char  *path,
01082                             const char  *interface,
01083                             const char  *member,
01084                             const char  *error_name)
01085 {
01086   unsigned int flags;
01087 
01088   _dbus_assert ((interface && member) ||
01089                 (error_name) ||
01090                 !(interface || member || error_name));
01091   _dbus_assert (error_name == NULL || is_valid_error_name (error_name));
01092   
01093   if (!_dbus_string_append_byte (&message->header, message->byte_order))
01094     return FALSE;
01095 
01096   if (!_dbus_string_append_byte (&message->header, type))
01097     return FALSE;
01098   
01099   flags = 0;
01100   if (!_dbus_string_append_byte (&message->header, flags))
01101     return FALSE;
01102 
01103   if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
01104     return FALSE;
01105 
01106   /* header length */
01107   if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01108     return FALSE;
01109 
01110   /* body length */
01111   if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01112     return FALSE;
01113 
01114   /* serial */
01115   if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01116     return FALSE;
01117   
01118   /* Marshal all the fields (Marshall Fields?) */
01119   
01120   if (path != NULL)
01121     {
01122       if (!append_string_field (message,
01123                                 DBUS_HEADER_FIELD_PATH,
01124                                 DBUS_TYPE_OBJECT_PATH,
01125                                 path))
01126         return FALSE;
01127     }
01128   
01129   if (service != NULL)
01130     {
01131       if (!append_string_field (message,
01132                                 DBUS_HEADER_FIELD_DESTINATION,
01133                                 DBUS_TYPE_STRING,
01134                                 service))
01135         return FALSE;
01136     }
01137 
01138   if (interface != NULL)
01139     {
01140       if (!append_string_field (message,
01141                                 DBUS_HEADER_FIELD_INTERFACE,
01142                                 DBUS_TYPE_STRING,
01143                                 interface))
01144         return FALSE;
01145     }
01146 
01147   if (member != NULL)
01148     {
01149       if (!append_string_field (message,
01150                                 DBUS_HEADER_FIELD_MEMBER,
01151                                 DBUS_TYPE_STRING,
01152                                 member))
01153         return FALSE;
01154     }
01155 
01156   if (error_name != NULL)
01157     {
01158       if (!append_string_field (message,
01159                                 DBUS_HEADER_FIELD_ERROR_NAME,
01160                                 DBUS_TYPE_STRING,
01161                                 error_name))
01162         return FALSE;
01163     }
01164 
01165   /* @todo if we make signature optional when body is empty, we don't
01166    * need to do this here.
01167    */
01168   if (!append_string_field (message,
01169                             DBUS_HEADER_FIELD_SIGNATURE,
01170                             DBUS_TYPE_STRING,
01171                             ""))
01172     return FALSE;
01173   
01174   return TRUE;
01175 }
01176 
01186 void
01187 _dbus_message_lock (DBusMessage  *message)
01188 {
01189   if (!message->locked)
01190     {
01191       /* Fill in our lengths */
01192       _dbus_marshal_set_uint32 (&message->header,
01193                                 message->byte_order,
01194                                 HEADER_LENGTH_OFFSET,
01195                                 _dbus_string_get_length (&message->header));
01196 
01197       _dbus_marshal_set_uint32 (&message->header,
01198                                 message->byte_order,
01199                                 BODY_LENGTH_OFFSET,
01200                                 _dbus_string_get_length (&message->body));
01201 
01202       message->locked = TRUE;
01203     }
01204 }
01205 
01237 static dbus_bool_t
01238 dbus_message_set_signature (DBusMessage *message,
01239                             const char  *signature)
01240 {
01241   _dbus_return_val_if_fail (message != NULL, FALSE);
01242   _dbus_return_val_if_fail (!message->locked, FALSE);
01243   
01244   return set_string_field (message,
01245                            DBUS_HEADER_FIELD_SIGNATURE,
01246                            DBUS_TYPE_STRING,
01247                            signature);
01248 }
01249 
01258 static dbus_bool_t
01259 dbus_message_append_to_signature (DBusMessage *message,
01260                                   const char  *append_bytes)
01261 {
01262   const char *signature;
01263   DBusString append_str;
01264   dbus_bool_t retval;
01265   
01266   _dbus_return_val_if_fail (append_bytes != NULL, FALSE);
01267   _dbus_return_val_if_fail (message != NULL, FALSE);
01268   _dbus_return_val_if_fail (!message->locked, FALSE);
01269 
01270   retval = FALSE;
01271   
01272   /* FIXME Just really inefficient for the moment; later we could
01273    * speed it up a lot by poking more directly at the header data
01274    */
01275   signature = dbus_message_get_signature (message);
01276 
01277   if (!_dbus_string_init (&append_str))
01278     return FALSE;
01279 
01280   if (signature && !_dbus_string_append (&append_str, signature))
01281     goto out;
01282 
01283   if (!_dbus_string_append (&append_str, append_bytes))
01284     goto out;
01285   
01286   if (!set_string_field (message,
01287                          DBUS_HEADER_FIELD_SIGNATURE,
01288                          DBUS_TYPE_STRING,
01289                          _dbus_string_get_const_data (&append_str)))
01290     goto out;
01291 
01292   retval = TRUE;
01293   
01294  out:
01295   
01296   _dbus_string_free (&append_str);
01297 
01298   return retval;
01299 }
01300 
01309 static dbus_bool_t
01310 _dbus_message_append_byte_to_signature (DBusMessage  *message,
01311                                         unsigned char append_byte)
01312 {
01313   char buf[2];
01314   
01315   _dbus_return_val_if_fail (message != NULL, FALSE);
01316   _dbus_return_val_if_fail (!message->locked, FALSE);
01317   
01318   buf[0] = append_byte;
01319   buf[1] = '\0';
01320 
01321   return dbus_message_append_to_signature (message, buf);
01322 }
01323 
01330 static void
01331 _dbus_message_remove_byte_from_signature (DBusMessage  *message)
01332 {
01333   const char *signature;
01334   
01335   _dbus_return_if_fail (message != NULL);
01336   _dbus_return_if_fail (!message->locked);
01337 
01338   signature = dbus_message_get_signature (message);
01339 
01340   _dbus_return_if_fail (signature != NULL);
01341   
01342   if (!delete_field (message,
01343                      DBUS_HEADER_FIELD_SIGNATURE,
01344                      0))
01345     _dbus_assert_not_reached ("failed to delete signature field");
01346 
01347   /* reappend one shorter (could this be any less efficient? the code will
01348    * go away later anyhow)
01349    */
01350   if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE,
01351                                 DBUS_TYPE_STRING, signature,
01352                                 strlen (signature) - 1))
01353     _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed");
01354 }
01355 
01363 static void
01364 free_size_counter (void *element,
01365                    void *data)
01366 {
01367   DBusCounter *counter = element;
01368   DBusMessage *message = data;
01369   
01370   _dbus_counter_adjust (counter, - message->size_counter_delta);
01371 
01372   _dbus_counter_unref (counter);
01373 }
01374 
01375 static void
01376 dbus_message_finalize (DBusMessage *message)
01377 {
01378   _dbus_assert (message->refcount.value == 0);
01379   
01380   /* This calls application callbacks! */
01381   _dbus_data_slot_list_free (&message->slot_list);
01382   
01383   _dbus_list_foreach (&message->size_counters,
01384                       free_size_counter, message);
01385   _dbus_list_clear (&message->size_counters);
01386   
01387   _dbus_string_free (&message->header);
01388   _dbus_string_free (&message->body);
01389   
01390   dbus_free (message);
01391 }
01392 
01393 /* Message Cache
01394  * 
01395  * We cache some DBusMessage to reduce the overhead of allocating
01396  * them.  In my profiling this consistently made about an 8%
01397  * difference.  It avoids the malloc for the message, the malloc for
01398  * the slot list, the malloc for the header string and body string,
01399  * and the associated free() calls. It does introduce another global
01400  * lock which could be a performance issue in certain cases.
01401  *
01402  * For the echo client/server the round trip time goes from around
01403  * .000077 to .000069 with the message cache on my laptop. The sysprof
01404  * change is as follows (numbers are cumulative percentage):
01405  *
01406  *  with message cache implemented as array as it is now (0.000069 per):
01407  *    new_empty_header           1.46
01408  *      mutex_lock               0.56    # i.e. _DBUS_LOCK(message_cache)
01409  *      mutex_unlock             0.25
01410  *      self                     0.41
01411  *    unref                      2.24
01412  *      self                     0.68
01413  *      list_clear               0.43
01414  *      mutex_lock               0.33    # i.e. _DBUS_LOCK(message_cache)
01415  *      mutex_unlock             0.25
01416  *
01417  *  with message cache implemented as list (0.000070 per roundtrip):
01418  *    new_empty_header           2.72
01419  *      list_pop_first           1.88
01420  *    unref                      3.3
01421  *      list_prepend             1.63
01422  *
01423  * without cache (0.000077 per roundtrip):
01424  *    new_empty_header           6.7
01425  *      string_init_preallocated 3.43
01426  *        dbus_malloc            2.43
01427  *      dbus_malloc0             2.59
01428  * 
01429  *    unref                      4.02
01430  *      string_free              1.82
01431  *        dbus_free              1.63
01432  *      dbus_free                0.71
01433  *
01434  * If you implement the message_cache with a list, the primary reason
01435  * it's slower is that you add another thread lock (on the DBusList
01436  * mempool).
01437  */
01438 
01439 /* Avoid caching huge messages */
01440 #define MAX_MESSAGE_SIZE_TO_CACHE _DBUS_ONE_MEGABYTE
01441 /* Avoid caching too many messages */
01442 #define MAX_MESSAGE_CACHE_SIZE    5
01443 
01444 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
01445 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
01446 static int message_cache_count = 0;
01447 static dbus_bool_t message_cache_shutdown_registered = FALSE;
01448 
01449 static void
01450 dbus_message_cache_shutdown (void *data)
01451 {
01452   int i;
01453 
01454   _DBUS_LOCK (message_cache);
01455 
01456   i = 0;
01457   while (i < MAX_MESSAGE_CACHE_SIZE)
01458     {
01459       if (message_cache[i])
01460         dbus_message_finalize (message_cache[i]);
01461       
01462       ++i;
01463     }
01464 
01465   message_cache_count = 0;
01466   message_cache_shutdown_registered = FALSE;
01467   
01468   _DBUS_UNLOCK (message_cache);
01469 }
01470 
01478 static DBusMessage*
01479 dbus_message_get_cached (void)
01480 {
01481   DBusMessage *message;
01482   int i;
01483 
01484   message = NULL;
01485   
01486   _DBUS_LOCK (message_cache);
01487 
01488   _dbus_assert (message_cache_count >= 0);
01489   
01490   if (message_cache_count == 0)
01491     {
01492       _DBUS_UNLOCK (message_cache);
01493       return NULL;
01494     }
01495 
01496   /* This is not necessarily true unless count > 0, and
01497    * message_cache is uninitialized until the shutdown is
01498    * registered
01499    */
01500   _dbus_assert (message_cache_shutdown_registered);
01501   
01502   i = 0;
01503   while (i < MAX_MESSAGE_CACHE_SIZE)
01504     {
01505       if (message_cache[i])
01506         {
01507           message = message_cache[i];
01508           message_cache[i] = NULL;
01509           message_cache_count -= 1;
01510           break;
01511         }
01512       ++i;
01513     }
01514   _dbus_assert (message_cache_count >= 0);
01515   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01516   _dbus_assert (message != NULL);
01517 
01518   _DBUS_UNLOCK (message_cache);
01519 
01520   _dbus_assert (message->refcount.value == 0);
01521   _dbus_assert (message->size_counters == NULL);
01522   
01523   return message;
01524 }
01525 
01531 static void
01532 dbus_message_cache_or_finalize (DBusMessage *message)
01533 {
01534   dbus_bool_t was_cached;
01535   int i;
01536 
01537   _dbus_assert (message->refcount.value == 0);
01538   
01539   /* This calls application code and has to be done first thing
01540    * without holding the lock
01541    */
01542   _dbus_data_slot_list_clear (&message->slot_list);
01543   
01544   _dbus_list_foreach (&message->size_counters,
01545                       free_size_counter, message);
01546   _dbus_list_clear (&message->size_counters);
01547   
01548   was_cached = FALSE;
01549 
01550   _DBUS_LOCK (message_cache);
01551 
01552   if (!message_cache_shutdown_registered)
01553     {
01554       _dbus_assert (message_cache_count == 0);
01555       
01556       if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
01557         goto out;
01558 
01559       i = 0;
01560       while (i < MAX_MESSAGE_CACHE_SIZE)
01561         {
01562           message_cache[i] = NULL;
01563           ++i;
01564         }
01565       
01566       message_cache_shutdown_registered = TRUE;
01567     }
01568 
01569   _dbus_assert (message_cache_count >= 0);
01570   
01571   if ((_dbus_string_get_length (&message->header) +
01572        _dbus_string_get_length (&message->body)) >
01573       MAX_MESSAGE_SIZE_TO_CACHE)
01574     goto out;
01575   
01576   if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
01577     goto out;
01578 
01579   /* Find empty slot */
01580   i = 0;
01581   while (message_cache[i] != NULL)
01582     ++i;
01583 
01584   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01585 
01586   _dbus_assert (message_cache[i] == NULL);
01587   message_cache[i] = message;
01588   message_cache_count += 1;
01589   was_cached = TRUE;
01590   
01591  out:
01592   _DBUS_UNLOCK (message_cache);
01593 
01594   if (!was_cached)
01595     dbus_message_finalize (message);
01596 }
01597 
01598 static DBusMessage*
01599 dbus_message_new_empty_header (void)
01600 {
01601   DBusMessage *message;
01602   int i;
01603   dbus_bool_t from_cache;
01604 
01605   message = dbus_message_get_cached ();
01606 
01607   if (message != NULL)
01608     {
01609       from_cache = TRUE;
01610     }
01611   else
01612     {
01613       from_cache = FALSE;
01614       message = dbus_new (DBusMessage, 1);
01615       if (message == NULL)
01616         return NULL;
01617 #ifndef DBUS_DISABLE_CHECKS
01618       message->generation = _dbus_current_generation;
01619 #endif
01620     }
01621 
01622   message->refcount.value = 1;
01623   message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01624   message->client_serial = 0;
01625   message->reply_serial = 0;
01626   message->locked = FALSE;
01627   message->header_padding = 0;
01628   message->size_counters = NULL;
01629   message->size_counter_delta = 0;
01630   message->changed_stamp = 0;
01631 
01632   if (!from_cache)
01633     _dbus_data_slot_list_init (&message->slot_list);
01634   
01635   i = 0;
01636   while (i <= DBUS_HEADER_FIELD_LAST)
01637     {
01638       message->header_fields[i].name_offset  = -1;
01639       message->header_fields[i].value_offset = -1;
01640       ++i;
01641     }
01642 
01643   if (from_cache)
01644     {
01645       /* These can't fail since they shorten the string */
01646       _dbus_string_set_length (&message->header, 0);
01647       _dbus_string_set_length (&message->body, 0);
01648     }
01649   else
01650     {
01651       if (!_dbus_string_init_preallocated (&message->header, 32))
01652         {
01653           dbus_free (message);
01654           return NULL;
01655         }
01656       
01657       if (!_dbus_string_init_preallocated (&message->body, 32))
01658         {
01659           _dbus_string_free (&message->header);
01660           dbus_free (message);
01661           return NULL;
01662         }
01663     }
01664   
01665   return message;
01666 }
01667 
01676 DBusMessage*
01677 dbus_message_new (int message_type)
01678 {
01679   DBusMessage *message;
01680 
01681   _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01682   
01683   message = dbus_message_new_empty_header ();
01684   if (message == NULL)
01685     return NULL;
01686   
01687   if (!dbus_message_create_header (message,
01688                                    message_type,
01689                                    NULL, NULL, NULL, NULL, NULL))
01690     {
01691       dbus_message_unref (message);
01692       return NULL;
01693     }
01694   
01695   return message;
01696 }
01697 
01715 DBusMessage*
01716 dbus_message_new_method_call (const char *service,
01717                               const char *path,
01718                               const char *interface,
01719                               const char *method)
01720 {
01721   DBusMessage *message;
01722 
01723   _dbus_return_val_if_fail (path != NULL, NULL);
01724   _dbus_return_val_if_fail (method != NULL, NULL);
01725   
01726   message = dbus_message_new_empty_header ();
01727   if (message == NULL)
01728     return NULL;
01729   
01730   if (!dbus_message_create_header (message,
01731                                    DBUS_MESSAGE_TYPE_METHOD_CALL,
01732                                    service, path, interface, method, NULL))
01733     {
01734       dbus_message_unref (message);
01735       return NULL;
01736     }
01737   
01738   return message;
01739 }
01740 
01750 DBusMessage*
01751 dbus_message_new_method_return (DBusMessage *method_call)
01752 {
01753   DBusMessage *message;
01754   const char *sender;
01755 
01756   _dbus_return_val_if_fail (method_call != NULL, NULL);
01757   
01758   sender = get_string_field (method_call,
01759                              DBUS_HEADER_FIELD_SENDER,
01760                              NULL);
01761   
01762   /* sender is allowed to be null here in peer-to-peer case */
01763 
01764   message = dbus_message_new_empty_header ();
01765   if (message == NULL)
01766     return NULL;
01767   
01768   if (!dbus_message_create_header (message,
01769                                    DBUS_MESSAGE_TYPE_METHOD_RETURN,
01770                                    sender, NULL, NULL, NULL, NULL))
01771     {
01772       dbus_message_unref (message);
01773       return NULL;
01774     }
01775 
01776   dbus_message_set_no_reply (message, TRUE);
01777 
01778   if (!dbus_message_set_reply_serial (message,
01779                                       dbus_message_get_serial (method_call)))
01780     {
01781       dbus_message_unref (message);
01782       return NULL;
01783     }
01784 
01785   return message;
01786 }
01787 
01800 DBusMessage*
01801 dbus_message_new_signal (const char *path,
01802                          const char *interface,
01803                          const char *name)
01804 {
01805   DBusMessage *message;
01806 
01807   _dbus_return_val_if_fail (path != NULL, NULL);
01808   _dbus_return_val_if_fail (interface != NULL, NULL);
01809   _dbus_return_val_if_fail (name != NULL, NULL);
01810   
01811   message = dbus_message_new_empty_header ();
01812   if (message == NULL)
01813     return NULL;
01814   
01815   if (!dbus_message_create_header (message,
01816                                    DBUS_MESSAGE_TYPE_SIGNAL,
01817                                    NULL, path, interface, name, NULL))
01818     {
01819       dbus_message_unref (message);
01820       return NULL;
01821     }
01822 
01823   dbus_message_set_no_reply (message, TRUE);
01824   
01825   return message;
01826 }
01827 
01837 DBusMessage*
01838 dbus_message_new_error (DBusMessage *reply_to,
01839                         const char  *error_name,
01840                         const char  *error_message)
01841 {
01842   DBusMessage *message;
01843   const char *sender;
01844   DBusMessageIter iter;
01845 
01846   _dbus_return_val_if_fail (reply_to != NULL, NULL);
01847   _dbus_return_val_if_fail (error_name != NULL, NULL);
01848   _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01849   
01850   sender = get_string_field (reply_to,
01851                              DBUS_HEADER_FIELD_SENDER,
01852                              NULL);
01853 
01854   /* sender may be NULL for non-message-bus case or
01855    * when the message bus is dealing with an unregistered
01856    * connection.
01857    */
01858   message = dbus_message_new_empty_header ();
01859   if (message == NULL)
01860     return NULL;
01861   
01862   if (!dbus_message_create_header (message,
01863                                    DBUS_MESSAGE_TYPE_ERROR,
01864                                    sender, NULL, NULL, NULL, error_name))
01865     {
01866       dbus_message_unref (message);
01867       return NULL;
01868     }
01869 
01870   dbus_message_set_no_reply (message, TRUE);
01871   
01872   if (!dbus_message_set_reply_serial (message,
01873                                       dbus_message_get_serial (reply_to)))
01874     {
01875       dbus_message_unref (message);
01876       return NULL;
01877     }
01878 
01879   if (error_message != NULL)
01880     {
01881       dbus_message_append_iter_init (message, &iter);
01882       if (!dbus_message_iter_append_string (&iter, error_message))
01883         {
01884           dbus_message_unref (message);
01885           return NULL;
01886         }
01887     }
01888   
01889   return message;
01890 }
01891 
01902 DBusMessage*
01903 dbus_message_new_error_printf (DBusMessage *reply_to,
01904                                const char  *error_name,
01905                                const char  *error_format,
01906                                ...)
01907 {
01908   va_list args;
01909   DBusString str;
01910   DBusMessage *message;
01911 
01912   _dbus_return_val_if_fail (reply_to != NULL, NULL);
01913   _dbus_return_val_if_fail (error_name != NULL, NULL);
01914   _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01915   
01916   if (!_dbus_string_init (&str))
01917     return NULL;
01918 
01919   va_start (args, error_format);
01920 
01921   if (_dbus_string_append_printf_valist (&str, error_format, args))
01922     message = dbus_message_new_error (reply_to, error_name,
01923                                       _dbus_string_get_const_data (&str));
01924   else
01925     message = NULL;
01926   
01927   _dbus_string_free (&str);
01928 
01929   va_end (args);
01930 
01931   return message;
01932 }
01933 
01934 
01942 DBusMessage *
01943 dbus_message_copy (const DBusMessage *message)
01944 {
01945   DBusMessage *retval;
01946   int i;
01947 
01948   _dbus_return_val_if_fail (message != NULL, NULL);
01949   
01950   retval = dbus_new0 (DBusMessage, 1);
01951   if (retval == NULL)
01952     return NULL;
01953   
01954   retval->refcount.value = 1;
01955   retval->byte_order = message->byte_order;
01956   retval->client_serial = message->client_serial;
01957   retval->reply_serial = message->reply_serial;
01958   retval->header_padding = message->header_padding;
01959   retval->locked = FALSE;
01960 #ifndef DBUS_DISABLE_CHECKS
01961   retval->generation = message->generation;
01962 #endif
01963   
01964   if (!_dbus_string_init_preallocated (&retval->header,
01965                                        _dbus_string_get_length (&message->header)))
01966     {
01967       dbus_free (retval);
01968       return NULL;
01969     }
01970   
01971   if (!_dbus_string_init_preallocated (&retval->body,
01972                                        _dbus_string_get_length (&message->body)))
01973     {
01974       _dbus_string_free (&retval->header);
01975       dbus_free (retval);
01976       return NULL;
01977     }
01978   
01979   if (!_dbus_string_copy (&message->header, 0,
01980                           &retval->header, 0))
01981     goto failed_copy;
01982 
01983   if (!_dbus_string_copy (&message->body, 0,
01984                           &retval->body, 0))
01985     goto failed_copy;
01986   
01987   for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
01988     {
01989       retval->header_fields[i] = message->header_fields[i];
01990     }
01991   
01992   return retval;
01993 
01994  failed_copy:
01995   _dbus_string_free (&retval->header);
01996   _dbus_string_free (&retval->body);
01997   dbus_free (retval);
01998   
01999   return NULL;  
02000 }
02001 
02002 
02010 DBusMessage *
02011 dbus_message_ref (DBusMessage *message)
02012 {
02013   dbus_int32_t old_refcount;
02014 
02015   _dbus_return_val_if_fail (message != NULL, NULL);
02016   _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
02017   
02018   old_refcount = _dbus_atomic_inc (&message->refcount);
02019   _dbus_assert (old_refcount >= 1);
02020 
02021   return message;
02022 }
02023 
02030 void
02031 dbus_message_unref (DBusMessage *message)
02032 {
02033  dbus_int32_t old_refcount;
02034 
02035   _dbus_return_if_fail (message != NULL);
02036   _dbus_return_if_fail (message->generation == _dbus_current_generation);
02037   
02038   old_refcount = _dbus_atomic_dec (&message->refcount);
02039   
02040   _dbus_assert (old_refcount >= 0);
02041 
02042   if (old_refcount == 1)
02043     {
02044       /* Calls application callbacks! */
02045       dbus_message_cache_or_finalize (message);
02046     }
02047 }
02048 
02060 int
02061 dbus_message_get_type (DBusMessage *message)
02062 {
02063   int type;
02064 
02065   type = _dbus_string_get_byte (&message->header, 1);
02066   _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
02067 
02068   return type;
02069 }
02070 
02080 dbus_bool_t
02081 dbus_message_set_path (DBusMessage   *message,
02082                        const char    *object_path)
02083 {
02084   _dbus_return_val_if_fail (message != NULL, FALSE);
02085   _dbus_return_val_if_fail (!message->locked, FALSE);
02086 
02087   return set_string_field (message,
02088                            DBUS_HEADER_FIELD_PATH,
02089                            DBUS_TYPE_OBJECT_PATH,
02090                            object_path);
02091 }
02092 
02101 const char*
02102 dbus_message_get_path (DBusMessage   *message)
02103 {
02104   _dbus_return_val_if_fail (message != NULL, NULL);
02105   
02106   return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
02107 }
02108 
02124 dbus_bool_t
02125 dbus_message_get_path_decomposed (DBusMessage   *message,
02126                                   char        ***path)
02127 {
02128   _dbus_return_val_if_fail (message != NULL, FALSE);
02129   _dbus_return_val_if_fail (path != NULL, FALSE);
02130 
02131   return get_path_field_decomposed (message,
02132                                     DBUS_HEADER_FIELD_PATH,
02133                                     path);
02134 }
02135 
02146 dbus_bool_t
02147 dbus_message_set_interface (DBusMessage  *message,
02148                             const char   *interface)
02149 {
02150   _dbus_return_val_if_fail (message != NULL, FALSE);
02151   _dbus_return_val_if_fail (!message->locked, FALSE);
02152 
02153   return set_string_field (message,
02154                            DBUS_HEADER_FIELD_INTERFACE,
02155                            DBUS_TYPE_STRING,
02156                            interface);
02157 }
02158 
02168 const char*
02169 dbus_message_get_interface (DBusMessage *message)
02170 {
02171   _dbus_return_val_if_fail (message != NULL, NULL);
02172   
02173   return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
02174 }
02175 
02186 dbus_bool_t
02187 dbus_message_set_member (DBusMessage  *message,
02188                        const char   *member)
02189 {
02190   _dbus_return_val_if_fail (message != NULL, FALSE);
02191   _dbus_return_val_if_fail (!message->locked, FALSE);
02192 
02193   return set_string_field (message,
02194                            DBUS_HEADER_FIELD_MEMBER,
02195                            DBUS_TYPE_STRING,
02196                            member);
02197 }
02198 
02207 const char*
02208 dbus_message_get_member (DBusMessage *message)
02209 {
02210   _dbus_return_val_if_fail (message != NULL, NULL);
02211   
02212   return get_string_field (message,
02213                            DBUS_HEADER_FIELD_MEMBER,
02214                            NULL);
02215 }
02216 
02225 dbus_bool_t
02226 dbus_message_set_error_name (DBusMessage  *message,
02227                              const char   *error_name)
02228 {
02229   _dbus_return_val_if_fail (message != NULL, FALSE);
02230   _dbus_return_val_if_fail (!message->locked, FALSE);
02231   _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE);
02232   
02233   return set_string_field (message,
02234                            DBUS_HEADER_FIELD_ERROR_NAME,
02235                            DBUS_TYPE_STRING,
02236                            error_name);
02237 }
02238 
02245 const char*
02246 dbus_message_get_error_name (DBusMessage *message)
02247 {
02248   _dbus_return_val_if_fail (message != NULL, NULL);
02249   
02250   return get_string_field (message,
02251                            DBUS_HEADER_FIELD_ERROR_NAME,
02252                            NULL);
02253 }
02254 
02262 dbus_bool_t
02263 dbus_message_set_destination (DBusMessage  *message,
02264                               const char   *destination)
02265 {
02266   _dbus_return_val_if_fail (message != NULL, FALSE);
02267   _dbus_return_val_if_fail (!message->locked, FALSE);
02268 
02269   return set_string_field (message,
02270                            DBUS_HEADER_FIELD_DESTINATION,
02271                            DBUS_TYPE_STRING,
02272                            destination);
02273 }
02274 
02281 const char*
02282 dbus_message_get_destination (DBusMessage *message)
02283 {
02284   _dbus_return_val_if_fail (message != NULL, NULL);
02285   
02286   return get_string_field (message,
02287                            DBUS_HEADER_FIELD_DESTINATION,
02288                            NULL);
02289 }
02290 
02309 dbus_bool_t
02310 dbus_message_append_args (DBusMessage *message,
02311                           int first_arg_type,
02312                           ...)
02313 {
02314   dbus_bool_t retval;
02315   va_list var_args;
02316 
02317   _dbus_return_val_if_fail (message != NULL, FALSE);
02318   
02319   va_start (var_args, first_arg_type);
02320   retval = dbus_message_append_args_valist (message,
02321                                             first_arg_type,
02322                                             var_args);
02323   va_end (var_args);
02324 
02325   return retval;
02326 }
02327 
02328 /* Swap into our byte order if message isn't already.
02329  * Done only when required, which allows the bus to avoid
02330  * ever doing this as it routes messages.
02331  */
02332 static void
02333 _dbus_message_ensure_our_byte_order (DBusMessage *message)
02334 {
02335   if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
02336     return;
02337 
02338   
02339 
02340 
02341 }
02342 
02355 dbus_bool_t
02356 dbus_message_get_args (DBusMessage     *message,
02357                        DBusError       *error,
02358                        int              first_arg_type,
02359                        ...)
02360 {
02361   dbus_bool_t retval;
02362   va_list var_args;
02363 
02364   _dbus_return_val_if_fail (message != NULL, FALSE);
02365   _dbus_return_val_if_error_is_set (error, FALSE);
02366   
02367   va_start (var_args, first_arg_type);
02368   retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02369   va_end (var_args);
02370 
02371   return retval;
02372 }
02373 
02386 dbus_bool_t
02387 dbus_message_get_args_valist (DBusMessage     *message,
02388                               DBusError       *error,
02389                               int              first_arg_type,
02390                               va_list          var_args)
02391 {
02392   DBusMessageIter iter;
02393 
02394   _dbus_return_val_if_fail (message != NULL, FALSE);
02395   _dbus_return_val_if_error_is_set (error, FALSE);
02396   
02397   dbus_message_iter_init (message, &iter);
02398   return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02399 }
02400 
02413 dbus_bool_t
02414 dbus_message_iter_get_args (DBusMessageIter *iter,
02415                             DBusError       *error,
02416                             int              first_arg_type,
02417                             ...)
02418 {
02419   dbus_bool_t retval;
02420   va_list var_args;
02421 
02422   _dbus_return_val_if_fail (iter != NULL, FALSE);
02423   _dbus_return_val_if_error_is_set (error, FALSE);
02424   
02425   va_start (var_args, first_arg_type);
02426   retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
02427   va_end (var_args);
02428 
02429   return retval;
02430 }
02431 
02440 dbus_bool_t
02441 dbus_message_iter_init (DBusMessage     *message,
02442                         DBusMessageIter *iter)
02443 {
02444   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02445 
02446   _dbus_return_val_if_fail (message != NULL, FALSE);
02447   _dbus_return_val_if_fail (iter != NULL, FALSE);
02448   
02449   _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02450   
02451   real->message = message;
02452   real->parent_iter = NULL;
02453   real->changed_stamp = message->changed_stamp;
02454   
02455   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02456   real->pos = 0;
02457   real->end = _dbus_string_get_length (&message->body);
02458   
02459   real->container_start = 0;
02460   real->container_length_pos = 0;
02461   real->wrote_dict_key = 0;
02462   real->array_type_pos = 0;
02463 
02464   return real->end > real->pos;
02465 }
02466 
02467 #ifndef DBUS_DISABLE_CHECKS
02468 static dbus_bool_t
02469 dbus_message_iter_check (DBusMessageRealIter *iter)
02470 {
02471   if (iter == NULL)
02472     {
02473       _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
02474       return FALSE;
02475     }
02476   
02477   if (iter->changed_stamp != iter->message->changed_stamp)
02478     {
02479       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
02480       return FALSE;
02481     }
02482   
02483   if (iter->pos < 0 || iter->pos > iter->end)
02484     {
02485       _dbus_warn ("dbus iterator check failed: invalid position\n");
02486       return FALSE;
02487     }
02488 
02489   return TRUE;
02490 }
02491 #endif /* DBUS_DISABLE_CHECKS */
02492 
02493 static int
02494 skip_array_type (DBusMessageRealIter *iter, int pos)
02495 {
02496   const char *data;
02497 
02498   do
02499     {
02500       data = _dbus_string_get_const_data_len (&iter->message->body,
02501                                               pos++, 1);
02502     }
02503   while (*data == DBUS_TYPE_ARRAY);
02504   
02505   return pos;
02506 }
02507 
02508 /* FIXME what are these _dbus_type_is_valid() checks for?
02509  * haven't we validated the message?
02510  */
02511 static int
02512 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
02513 {
02514   const char *data;
02515   int pos, len;
02516   
02517   switch (iter->type)
02518     {
02519     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02520       data = _dbus_string_get_const_data_len (&iter->message->body,
02521                                               iter->pos, 1);
02522       if (_dbus_type_is_valid (*data))
02523         *type = *data;
02524       else
02525         *type = DBUS_TYPE_INVALID;
02526       
02527       return skip_array_type (iter, iter->pos);
02528       
02529     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02530       data = _dbus_string_get_const_data_len (&iter->message->body,
02531                                               iter->array_type_pos, 1);
02532       if (_dbus_type_is_valid (*data))
02533         *type = *data;
02534       else
02535         *type = DBUS_TYPE_INVALID;
02536       
02537       return iter->pos;
02538       
02539     case DBUS_MESSAGE_ITER_TYPE_DICT:
02540       /* Get the length of the string */
02541       len = _dbus_demarshal_uint32 (&iter->message->body,
02542                                     iter->message->byte_order,
02543                                     iter->pos, &pos);
02544       pos = pos + len + 1;
02545 
02546       data = _dbus_string_get_const_data_len (&iter->message->body,
02547                                               pos, 1);
02548       if (_dbus_type_is_valid (*data))
02549         *type = *data;
02550       else
02551         *type = DBUS_TYPE_INVALID;
02552 
02553       return skip_array_type (iter, pos);
02554       
02555     default:
02556       _dbus_assert_not_reached ("Invalid iter type");
02557       break;
02558     }
02559   *type = DBUS_TYPE_INVALID;
02560   return iter->pos;
02561 }
02562 
02563 
02571 dbus_bool_t
02572 dbus_message_iter_has_next (DBusMessageIter *iter)
02573 {
02574   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02575   int end_pos;
02576   int type, pos;
02577 
02578   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02579 
02580   if (real->pos >= real->end)
02581     return FALSE;
02582   
02583   pos = dbus_message_iter_get_data_start (real, &type);
02584   
02585   if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02586                                       real->message->byte_order,
02587                                       type, pos, &end_pos))
02588     return FALSE;
02589   
02590   if (end_pos >= real->end)
02591     return FALSE;
02592 
02593   return TRUE;  
02594 }
02595 
02602 dbus_bool_t
02603 dbus_message_iter_next (DBusMessageIter *iter)
02604 {
02605   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02606   int end_pos;
02607   int type, pos;
02608 
02609   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02610 
02611   pos = dbus_message_iter_get_data_start (real, &type);
02612   
02613   if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02614                                       real->message->byte_order,
02615                                       type, pos, &end_pos))
02616     return FALSE;
02617 
02618   if (end_pos >= real->end)
02619     return FALSE;
02620 
02621   real->pos = end_pos;
02622 
02623   return TRUE;
02624 }
02625 
02633 int
02634 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02635 {
02636   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02637   int type, pos;
02638 
02639   _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02640 
02641   if (real->pos >= real->end)
02642     {
02643       _dbus_verbose ("  iterator at or beyond end of message\n");
02644       return DBUS_TYPE_INVALID;
02645     }
02646 
02647   pos = dbus_message_iter_get_data_start (real, &type);
02648   
02649   return type;
02650 }
02651 
02652 /* FIXME why do we validate the typecode in here, hasn't the message
02653  * already been verified?
02654  */
02655 static int
02656 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02657 {
02658   const char *data;
02659   int _array_type_pos;
02660   int len, pos;
02661   
02662   switch (iter->type)
02663     {
02664     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02665       _array_type_pos = iter->pos + 1;
02666       break;
02667     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02668       _array_type_pos = iter->array_type_pos + 1;
02669       break;
02670     case DBUS_MESSAGE_ITER_TYPE_DICT:
02671       /* Get the length of the string */
02672       len = _dbus_demarshal_uint32 (&iter->message->body,
02673                                     iter->message->byte_order,
02674                                     iter->pos, &pos);
02675       pos = pos + len + 1;
02676       data = _dbus_string_get_const_data_len (&iter->message->body,
02677                                               pos + 1, 1);
02678       _array_type_pos = pos + 1;
02679       break;
02680     default:
02681       _dbus_assert_not_reached ("wrong iter type");
02682       return DBUS_TYPE_INVALID;
02683     }
02684 
02685   if (array_type_pos != NULL)
02686     *array_type_pos = _array_type_pos;
02687   
02688   data = _dbus_string_get_const_data_len (&iter->message->body,
02689                                           _array_type_pos, 1);
02690   if (_dbus_type_is_valid (*data))
02691     return  *data;
02692   
02693   return DBUS_TYPE_INVALID;
02694 }
02695 
02696 
02706 int
02707 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02708 {
02709   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02710   int type, pos;
02711 
02712   _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02713 
02714   if (real->pos >= real->end)
02715     return DBUS_TYPE_INVALID;
02716 
02717   pos = dbus_message_iter_get_data_start (real, &type);
02718 
02719   _dbus_assert (type == DBUS_TYPE_ARRAY);
02720 
02721   return iter_get_array_type (real, NULL);
02722 }
02723 
02724 
02734 char *
02735 dbus_message_iter_get_string (DBusMessageIter *iter)
02736 {
02737   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02738   int type, pos;
02739 
02740   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02741   pos = dbus_message_iter_get_data_start (real, &type);
02742   
02743   _dbus_assert (type == DBUS_TYPE_STRING);
02744 
02745   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02746                                  pos, NULL);
02747 }
02748 
02758 char *
02759 dbus_message_iter_get_object_path (DBusMessageIter  *iter)
02760 {
02761   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02762   int type, pos;
02763 
02764   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02765 
02766   pos = dbus_message_iter_get_data_start (real, &type);
02767   
02768   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
02769 
02770   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02771                                  pos, NULL);
02772 }
02773 
02787 dbus_bool_t
02788 dbus_message_iter_get_custom (DBusMessageIter   *iter,
02789                               char             **name,
02790                               unsigned char    **value,
02791                               int               *len)
02792 {
02793   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02794   int type, pos;
02795   char *_name;
02796 
02797   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02798 
02799   pos = dbus_message_iter_get_data_start (real, &type);
02800   
02801   _dbus_assert (type == DBUS_TYPE_CUSTOM);
02802   
02803   _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02804                                   pos, &pos);
02805 
02806   if (_name == NULL)
02807     return FALSE;
02808   
02809   if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02810                                    pos, NULL, value, len))
02811     {
02812       dbus_free (_name);
02813       return FALSE;
02814     }
02815 
02816   *name = _name;
02817   
02818   return TRUE;
02819 }
02820 
02821 static void
02822 _dbus_message_iter_get_basic_type (DBusMessageIter *iter,
02823                                    char             type,
02824                                    void            *value)
02825 {
02826   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02827   int item_type, pos;
02828 
02829   _dbus_return_if_fail (dbus_message_iter_check (real));
02830 
02831   pos = dbus_message_iter_get_data_start (real, &item_type);
02832   
02833   _dbus_assert (type == item_type);
02834   
02835   _dbus_demarshal_basic_type (&real->message->body,
02836                               type, value,
02837                               real->message->byte_order,
02838                               &pos);
02839 }
02840 
02841 
02864 dbus_bool_t
02865 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
02866                                    DBusError       *error,
02867                                    int              first_arg_type,
02868                                    va_list          var_args)
02869 {
02870   int spec_type, msg_type, i;
02871   dbus_bool_t retval;
02872 
02873   _dbus_return_val_if_fail (iter != NULL, FALSE);
02874   _dbus_return_val_if_error_is_set (error, FALSE);
02875 
02876   retval = FALSE;
02877   
02878   spec_type = first_arg_type;
02879   i = 0;
02880   
02881   while (spec_type != DBUS_TYPE_INVALID)
02882     {
02883       msg_type = dbus_message_iter_get_arg_type (iter);      
02884       
02885       if (msg_type != spec_type)
02886         {
02887           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02888                           "Argument %d is specified to be of type \"%s\", but "
02889                           "is actually of type \"%s\"\n", i,
02890                           _dbus_type_to_string (spec_type),
02891                           _dbus_type_to_string (msg_type));
02892 
02893           goto out;
02894         }
02895 
02896       switch (spec_type)
02897         {
02898         case DBUS_TYPE_NIL:
02899           break;
02900         case DBUS_TYPE_BOOLEAN:
02901           {
02902             dbus_bool_t *ptr;
02903 
02904             ptr = va_arg (var_args, dbus_bool_t *);
02905 
02906             *ptr = dbus_message_iter_get_boolean (iter);
02907             break;
02908           }
02909         case DBUS_TYPE_BYTE:
02910         case DBUS_TYPE_INT32:
02911         case DBUS_TYPE_UINT32:
02912 #ifdef DBUS_HAVE_INT64
02913         case DBUS_TYPE_INT64:
02914         case DBUS_TYPE_UINT64:
02915 #endif /* DBUS_HAVE_INT64 */
02916         case DBUS_TYPE_DOUBLE:
02917           {
02918             void *ptr = va_arg (var_args, double *);
02919             _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
02920             break;
02921           }
02922 
02923         case DBUS_TYPE_STRING:
02924           {
02925             char **ptr;
02926 
02927             ptr = va_arg (var_args, char **);
02928 
02929             *ptr = dbus_message_iter_get_string (iter);
02930 
02931             if (!*ptr)
02932               {
02933                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02934                 goto out;
02935               }
02936             
02937             break;
02938           }
02939 
02940           case DBUS_TYPE_OBJECT_PATH:
02941           {
02942             char **ptr;
02943 
02944             ptr = va_arg (var_args, char **);
02945 
02946             *ptr = dbus_message_iter_get_object_path (iter);
02947 
02948             if (!*ptr)
02949               {
02950                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02951                 goto out;
02952               }
02953 
02954             break;
02955           }
02956 
02957         case DBUS_TYPE_CUSTOM:
02958           {
02959             char **name;
02960             unsigned char **data;
02961             int *len;
02962  
02963             name = va_arg (var_args, char **);
02964             data = va_arg (var_args, unsigned char **);
02965             len = va_arg (var_args, int *);
02966 
02967             if (!dbus_message_iter_get_custom (iter, name, data, len))
02968               {
02969                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02970                 goto out;
02971               }
02972           }
02973           break;
02974         case DBUS_TYPE_ARRAY:
02975           {
02976             void **data;
02977             int *len, type;
02978             dbus_bool_t err = FALSE;
02979  
02980             type = va_arg (var_args, int);
02981             data = va_arg (var_args, void *);
02982             len = va_arg (var_args, int *);
02983 
02984             _dbus_return_val_if_fail (data != NULL, FALSE);
02985             _dbus_return_val_if_fail (len != NULL, FALSE);
02986             
02987             if (dbus_message_iter_get_array_type (iter) != type)
02988               {
02989                 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02990                                 "Argument %d is specified to be of type \"array of %s\", but "
02991                                 "is actually of type \"array of %s\"\n", i,
02992                                 _dbus_type_to_string (type),
02993                                 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
02994                 goto out;
02995               }
02996             
02997             switch (type)
02998               {
02999               case DBUS_TYPE_BYTE:
03000                 err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
03001                 break;
03002               case DBUS_TYPE_BOOLEAN:
03003                 err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
03004                 break;
03005               case DBUS_TYPE_INT32:
03006                 err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
03007                 break;
03008               case DBUS_TYPE_UINT32:
03009                 err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
03010                 break;
03011 #ifdef DBUS_HAVE_INT64
03012               case DBUS_TYPE_INT64:
03013                 err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
03014                 break;
03015               case DBUS_TYPE_UINT64:
03016                 err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
03017                 break;
03018 #endif /* DBUS_HAVE_INT64 */
03019               case DBUS_TYPE_DOUBLE:
03020                 err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
03021                 break;
03022               case DBUS_TYPE_STRING:
03023                 err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
03024                 break;
03025               case DBUS_TYPE_OBJECT_PATH:
03026                 err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
03027                 break;
03028 
03029               case DBUS_TYPE_NIL:
03030               case DBUS_TYPE_ARRAY:
03031               case DBUS_TYPE_CUSTOM:
03032               case DBUS_TYPE_DICT:
03033                 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
03034                 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03035                 goto out;
03036               default:
03037                 _dbus_warn ("Unknown field type %d\n", type);
03038                 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03039                 goto out;
03040               }
03041             if (err)
03042               {
03043                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
03044                 goto out;
03045               }
03046           }
03047           break;
03048         case DBUS_TYPE_DICT:
03049           _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
03050           dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03051           goto out;
03052         default:          
03053           dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03054           _dbus_warn ("Unknown field type %d\n", spec_type);
03055           goto out;
03056         }
03057 
03058       spec_type = va_arg (var_args, int);
03059       if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
03060         {
03061           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
03062                           "Message has only %d arguments, but more were expected", i);
03063           goto out;
03064         }
03065 
03066       i++;
03067     }
03068   
03069   retval = TRUE;
03070   
03071  out:
03072   
03073   return retval;
03074 }
03075 
03085 unsigned char
03086 dbus_message_iter_get_byte (DBusMessageIter *iter)
03087 {
03088   unsigned char value = 0;
03089 
03090   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value);
03091 
03092   return value;
03093 }
03094 
03104 dbus_bool_t
03105 dbus_message_iter_get_boolean (DBusMessageIter *iter)
03106 {
03107   unsigned char value = 0;
03108 
03109   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value);
03110 
03111   return (value != FALSE);
03112 }
03113 
03123 dbus_int32_t
03124 dbus_message_iter_get_int32 (DBusMessageIter *iter)
03125 {
03126   dbus_int32_t value = 0;
03127 
03128   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value);
03129 
03130   return value;
03131 }
03132 
03142 dbus_uint32_t
03143 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
03144 {
03145   dbus_int32_t value = 0;
03146 
03147   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value);
03148 
03149   return value;
03150 }
03151 
03152 #ifdef DBUS_HAVE_INT64
03153 
03165 dbus_int64_t
03166 dbus_message_iter_get_int64 (DBusMessageIter *iter)
03167 {
03168   dbus_int64_t value = 0;
03169 
03170   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value);
03171 
03172   return value;
03173 }
03174 
03186 dbus_uint64_t
03187 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
03188 {
03189   dbus_uint64_t value = 0;
03190 
03191   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value);
03192 
03193   return value;
03194 }
03195 
03196 #endif /* DBUS_HAVE_INT64 */
03197 
03207 double
03208 dbus_message_iter_get_double (DBusMessageIter *iter)
03209 {
03210   double value = 0.0;
03211 
03212   _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value);
03213 
03214   return value;
03215 }
03216 
03230 dbus_bool_t
03231 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
03232                                        DBusMessageIter *array_iter,
03233                                        int             *array_type)
03234 {
03235   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03236   DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03237   int type, pos, len_pos, len, array_type_pos;
03238   int _array_type;
03239 
03240   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03241 
03242   pos = dbus_message_iter_get_data_start (real, &type);
03243   
03244   _dbus_assert (type == DBUS_TYPE_ARRAY);
03245 
03246   _array_type = iter_get_array_type (real, &array_type_pos);
03247   
03248   len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03249   len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03250                                 pos, &pos);
03251   
03252   array_real->parent_iter = real;
03253   array_real->message = real->message;
03254   array_real->changed_stamp = real->message->changed_stamp;
03255   
03256   array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
03257   array_real->pos = pos;
03258   array_real->end = pos + len;
03259   
03260   array_real->container_start = pos;
03261   array_real->container_length_pos = len_pos;
03262   array_real->wrote_dict_key = 0;
03263   array_real->array_type_pos = array_type_pos;
03264   array_real->array_type_done = TRUE;
03265   
03266   if (array_type != NULL)
03267     *array_type = _array_type;
03268 
03269   return len > 0;
03270 }
03271 
03272 
03282 dbus_bool_t
03283 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
03284                                       DBusMessageIter *dict_iter)
03285 {
03286   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03287   DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03288   int type, pos, len_pos, len;
03289 
03290   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03291 
03292   pos = dbus_message_iter_get_data_start (real, &type);
03293   
03294   _dbus_assert (type == DBUS_TYPE_DICT);
03295 
03296   len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03297   len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03298                                 pos, &pos);
03299   
03300   dict_real->parent_iter = real;
03301   dict_real->message = real->message;
03302   dict_real->changed_stamp = real->message->changed_stamp;
03303   
03304   dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03305   dict_real->pos = pos;
03306   dict_real->end = pos + len;
03307   
03308   dict_real->container_start = pos;
03309   dict_real->container_length_pos = len_pos;
03310   dict_real->wrote_dict_key = 0;
03311 
03312   return len > 0;
03313 }
03314 
03315 static dbus_bool_t
03316 _dbus_message_iter_get_basic_type_array  (DBusMessageIter *iter,
03317                                           char             type,
03318                                           void           **array,
03319                                           int             *array_len)
03320 {
03321   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03322   int item_type, pos;
03323 
03324   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03325 
03326   pos = dbus_message_iter_get_data_start (real, &item_type);
03327   
03328   _dbus_assert (item_type == DBUS_TYPE_ARRAY);
03329 
03330   item_type = iter_get_array_type (real, NULL);
03331   
03332   _dbus_assert (type == item_type);
03333 
03334   return _dbus_demarshal_basic_type_array (&real->message->body,
03335                                            item_type, array, array_len,
03336                                            real->message->byte_order, &pos);
03337 }
03338 
03349 dbus_bool_t
03350 dbus_message_iter_get_byte_array (DBusMessageIter  *iter,
03351                                   unsigned char   **value,
03352                                   int              *len)
03353 {
03354   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE,
03355                                                   (void **) value, len);
03356 }
03357 
03368 dbus_bool_t
03369 dbus_message_iter_get_boolean_array (DBusMessageIter   *iter,
03370                                      unsigned char    **value,
03371                                      int               *len)
03372 {
03373   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN,
03374                                                   (void **) value, len);
03375 }
03376 
03387 dbus_bool_t
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504 
03505   pos = dbus_message_iter_get_data_start (real, &type);
03506   
03507   _dbus_assert (type == DBUS_TYPE_ARRAY);
03508 
03509   type = iter_get_array_type (real, NULL);
03510   _dbus_assert (type == DBUS_TYPE_STRING);
03511 
03512   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513                                      pos, NULL, value, len))
03514     return FALSE;
03515   else
03516     return TRUE;
03517 }
03518 
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536                                          char          ***value,
03537                                          int             *len)
03538 {
03539   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540   int type, pos;
03541 
03542   _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543 
03544   pos = dbus_message_iter_get_data_start (real, &type);
03545   
03546   _dbus_assert (type == DBUS_TYPE_ARRAY);
03547 
03548   type = iter_get_array_type (real, NULL);
03549   _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550 
03551   if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552                                      pos, NULL, value, len))
03553     return FALSE;
03554   else
03555     return TRUE;
03556 }
03557 
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter   *iter)
03569 {
03570   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571 
03572   _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573 
03574   _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575 
03576   return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577                                  real->pos, NULL);
03578 }
03579 
03588 void
03589 dbus_message_append_iter_init (DBusMessage     *message,
03590                                DBusMessageIter *iter)
03591 {
03592   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593 
03594   _dbus_return_if_fail (message != NULL);
03595   _dbus_return_if_fail (iter != NULL);
03596   
03597   real->message = message;
03598   real->parent_iter = NULL;
03599   real->changed_stamp = message->changed_stamp;
03600   
03601   real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602   real->end = _dbus_string_get_length (&real->message->body);
03603   real->pos = real->end;
03604   
03605   real->container_length_pos = 0;
03606   real->wrote_dict_key = 0;
03607 }
03608 
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613   if (iter == NULL)
03614     {
03615       _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616       return FALSE;
03617     }
03618   
03619   if (iter->message->locked)
03620     {
03621       _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622       return FALSE;
03623     }
03624       
03625   if (iter->changed_stamp != iter->message->changed_stamp)
03626     {
03627       _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628       return FALSE;
03629     }
03630   
03631   if (iter->pos != iter->end)
03632     {
03633       _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634       return FALSE;
03635     }
03636   
03637   if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638     {
03639       _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640       return FALSE;
03641     }
03642 
03643   return TRUE;
03644 }
03645 #endif /* DBUS_DISABLE_CHECKS */
03646 
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649                                int                  type)
03650 {
03651   const char *data;
03652 
03653   switch (iter->type)
03654     {
03655     case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656       if (!_dbus_string_append_byte (&iter->message->body, type))
03657         return FALSE;
03658 
03659       if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660         {
03661           _dbus_string_shorten (&iter->message->body, 1);
03662           return FALSE;
03663         }
03664       break;
03665       
03666     case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667       data = _dbus_string_get_const_data_len (&iter->message->body,
03668                                               iter->array_type_pos, 1);
03669       if (type != *data)
03670         {
03671           _dbus_warn ("Appended element of wrong type for array\n");
03672           return FALSE;
03673         }
0367                                  iter->
03388 dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
03389                                     dbus_int32_t   **value,
03390                                     int             *len)
03391 {
03392   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393                                                   (void **) value, len);
03394 }
03395 
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
03408                                      dbus_uint32_t  **value,
03409                                      int             *len)
03410 {
03411   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412                                                   (void **) value, len);
03413 }
03414 
03415 #ifdef DBUS_HAVE_INT64
03416 
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array  (DBusMessageIter *iter,
03431                                     dbus_int64_t   **value,
03432                                     int             *len)
03433 {
03434   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435                                                   (void **) value, len);
03436 }
03437 
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array  (DBusMessageIter *iter,
03452                                      dbus_uint64_t  **value,
03453                                      int             *len)
03454 {
03455   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456                                                   (void **) value, len);
03457 }
03458 
03459 #endif /* DBUS_HAVE_INT64 */
03460 
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array  (DBusMessageIter *iter,
03473                                      double         **value,
03474                                      int             *len)
03475 {
03476   return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477                                                   (void **) value, len);
03478 }
03479 
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497                                     char          ***value,
03498                                     int             *len)
03499 {
03500   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501   int type, pos;
03502 
03503   _dbus_return_val_if_fail (dbus_message_iter_check (real),