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

dbus-marshal.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-marshal.c  Marshalling routines
00003  *
00004  * Copyright (C) 2002 CodeFactory AB
00005  * Copyright (C) 2003 Red Hat, Inc.
00006  *
00007  * Licensed under the Academic Free License version 1.2
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-marshal.h"
00026 #include "dbus-internals.h"
00027 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00028 #include "dbus-string-private.h"
00029 
00030 #include <string.h>
00031 
00043 static dbus_uint32_t
00044 unpack_4_octets (int                  byte_order,
00045                  const unsigned char *data)
00046 {
00047   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00048   
00049   if (byte_order == DBUS_LITTLE_ENDIAN)
00050     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
00051   else
00052     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
00053 }
00054 
00055 #ifndef DBUS_HAVE_INT64
00056 /* from ORBit */
00057 static void
00058 swap_bytes (unsigned char *data,
00059             unsigned int   len)
00060 {
00061   unsigned char *p1 = data;
00062   unsigned char *p2 = data + len - 1;
00063 
00064   while (p1 < p2)
00065     {
00066       unsigned char tmp = *p1;
00067       *p1 = *p2;
00068       *p2 = tmp;
00069 
00070       --p2;
00071       ++p1;
00072     }
00073 }
00074 #endif /* !DBUS_HAVE_INT64 */
00075 
00080 typedef union
00081 {
00082 #ifdef DBUS_HAVE_INT64
00083   dbus_int64_t  s; 
00084   dbus_uint64_t u; 
00085 #endif
00086   double d;        
00087 } DBusOctets8;
00088 
00089 static DBusOctets8
00090 unpack_8_octets (int                  byte_order,
00091                  const unsigned char *data)
00092 {
00093   DBusOctets8 r;
00094   
00095   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00096   _dbus_assert (sizeof (r) == 8);
00097   
00098 #ifdef DBUS_HAVE_INT64
00099   if (byte_order == DBUS_LITTLE_ENDIAN)
00100     r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
00101   else
00102     r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
00103 #else
00104   r.d = *(double*)data;
00105   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00106     swap_bytes ((unsigned char*) &r, sizeof (r));
00107 #endif
00108   
00109   return r;
00110 }
00111 
00119 dbus_uint32_t
00120 _dbus_unpack_uint32 (int                  byte_order,
00121                      const unsigned char *data)
00122 {
00123   return unpack_4_octets (byte_order, data);
00124 }  
00125 
00133 dbus_int32_t
00134 _dbus_unpack_int32 (int                  byte_order,
00135                     const unsigned char *data)
00136 {
00137   return (dbus_int32_t) unpack_4_octets (byte_order, data);
00138 }
00139 
00140 #ifdef DBUS_HAVE_INT64
00141 
00148 dbus_uint64_t
00149 _dbus_unpack_uint64 (int                  byte_order,
00150                      const unsigned char *data)
00151 {
00152   DBusOctets8 r;
00153   
00154   r = unpack_8_octets (byte_order, data);
00155 
00156   return r.u;
00157 }  
00158 
00166 dbus_int64_t
00167 _dbus_unpack_int64 (int                  byte_order,
00168                     const unsigned char *data)
00169 {
00170   DBusOctets8 r;
00171   
00172   r = unpack_8_octets (byte_order, data);
00173 
00174   return r.s;
00175 }
00176 
00177 #endif /* DBUS_HAVE_INT64 */
00178 
00179 static void
00180 pack_4_octets (dbus_uint32_t   value,
00181                int             byte_order,
00182                unsigned char  *data)
00183 {
00184   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00185   
00186   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
00187     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
00188   else
00189     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
00190 }
00191 
00192 static void
00193 pack_8_octets (DBusOctets8     value,
00194                int             byte_order,
00195                unsigned char  *data)
00196 {
00197   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00198 
00199 #ifdef DBUS_HAVE_INT64
00200   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
00201     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u); 
00202   else
00203     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
00204 #else
00205   memcpy (data, &value, 8);
00206   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00207     swap_bytes ((unsigned char *)data, 8);
00208 #endif
00209 }
00210 
00218 void
00219 _dbus_pack_uint32 (dbus_uint32_t   value,
00220                    int             byte_order,
00221                    unsigned char  *data)
00222 {
00223   pack_4_octets (value, byte_order, data);
00224 }
00225 
00233 void
00234 _dbus_pack_int32 (dbus_int32_t   value,
00235                   int            byte_order,
00236                   unsigned char *data)
00237 {
00238   pack_4_octets ((dbus_uint32_t) value, byte_order, data);
00239 }
00240 
00241 #ifdef DBUS_HAVE_INT64
00242 
00249 void
00250 _dbus_pack_uint64 (dbus_uint64_t   value,
00251                    int             byte_order,
00252                    unsigned char  *data)
00253 {
00254   DBusOctets8 r;
00255   r.u = value;
00256   pack_8_octets (r, byte_order, data);
00257 }
00258 
00266 void
00267 _dbus_pack_int64 (dbus_int64_t   value,
00268                   int            byte_order,
00269                   unsigned char *data)
00270 {
00271   DBusOctets8 r;
00272   r.s = value;
00273   pack_8_octets (r, byte_order, data);
00274 }
00275 #endif /* DBUS_HAVE_INT64 */
00276 
00277 static void
00278 set_4_octets (DBusString          *str,
00279               int                  byte_order,
00280               int                  offset,
00281               dbus_uint32_t        value)
00282 {
00283   char *data;
00284   
00285   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00286                 byte_order == DBUS_BIG_ENDIAN);
00287   
00288   data = _dbus_string_get_data_len (str, offset, 4);
00289 
00290   _dbus_pack_uint32 (value, byte_order, data);
00291 }
00292 
00293 static void
00294 set_8_octets (DBusString          *str,
00295               int                  byte_order,
00296               int                  offset,
00297               DBusOctets8          value)
00298 {
00299   char *data;
00300   
00301   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00302                 byte_order == DBUS_BIG_ENDIAN);
00303   
00304   data = _dbus_string_get_data_len (str, offset, 8);
00305 
00306   pack_8_octets (value, byte_order, data);
00307 }
00308 
00319 void
00320 _dbus_marshal_set_int32 (DBusString          *str,
00321                          int                  byte_order,
00322                          int                  offset,
00323                          dbus_int32_t         value)
00324 {
00325   set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
00326 }
00327 
00338 void
00339 _dbus_marshal_set_uint32 (DBusString          *str,
00340                           int                  byte_order,
00341                           int                  offset,
00342                           dbus_uint32_t        value)
00343 {
00344   set_4_octets (str, byte_order, offset, value);
00345 }
00346 
00347 #ifdef DBUS_HAVE_INT64
00348 
00359 void
00360 _dbus_marshal_set_int64 (DBusString          *str,
00361                          int                  byte_order,
00362                          int                  offset,
00363                          dbus_int64_t         value)
00364 {
00365   DBusOctets8 r;
00366   r.s = value;
00367   set_8_octets (str, byte_order, offset, r);
00368 }
00369 
00380 void
00381 _dbus_marshal_set_uint64 (DBusString          *str,
00382                           int                  byte_order,
00383                           int                  offset,
00384                           dbus_uint64_t        value)
00385 {
00386   DBusOctets8 r;
00387   r.u = value;
00388   set_8_octets (str, byte_order, offset, r);
00389 }
00390 #endif /* DBUS_HAVE_INT64 */
00391 
00410 dbus_bool_t
00411 _dbus_marshal_set_string (DBusString          *str,
00412                           int                  byte_order,
00413                           int                  offset,
00414                           const DBusString    *value,
00415                           int                  len)
00416 {
00417   int old_len;
00418   
00419   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00420                 byte_order == DBUS_BIG_ENDIAN);
00421   
00422   old_len = _dbus_demarshal_uint32 (str, byte_order,
00423                                     offset, NULL);
00424 
00425   if (!_dbus_string_replace_len (value, 0, len,
00426                                  str, offset + 4, old_len))
00427     return FALSE;
00428 
00429   _dbus_marshal_set_uint32 (str, byte_order,
00430                             offset, len);
00431 
00432   return TRUE;
00433 }
00434 
00448 void
00449 _dbus_marshal_set_object_path (DBusString         *str,
00450                                int                 byte_order,
00451                                int                 offset,
00452                                const char        **path,
00453                                int                 path_len)
00454 {
00455 
00456   /* FIXME */
00457 }
00458 
00459 static dbus_bool_t
00460 marshal_4_octets (DBusString   *str,
00461                   int           byte_order,
00462                   dbus_uint32_t value)
00463 {
00464   _dbus_assert (sizeof (value) == 4);
00465   
00466   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00467     value = DBUS_UINT32_SWAP_LE_BE (value);
00468 
00469   return _dbus_string_append_4_aligned (str,
00470                                         (const unsigned char *)&value);
00471 }
00472 
00473 static dbus_bool_t
00474 marshal_8_octets (DBusString *str,
00475                   int         byte_order,
00476                   DBusOctets8 value)
00477 {
00478   _dbus_assert (sizeof (value) == 8);
00479   
00480   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00481     pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
00482 
00483   return _dbus_string_append_8_aligned (str,
00484                                         (const unsigned char *)&value);
00485 }
00486 
00495 dbus_bool_t
00496 _dbus_marshal_double (DBusString *str,
00497                       int         byte_order,
00498                       double      value)
00499 {
00500   DBusOctets8 r;
00501   r.d = value;
00502   return marshal_8_octets (str, byte_order, r);
00503 }
00504 
00513 dbus_bool_t
00514 _dbus_marshal_int32  (DBusString   *str,
00515                       int           byte_order,
00516                       dbus_int32_t  value)
00517 {
00518   return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
00519 }
00520 
00529 dbus_bool_t
00530 _dbus_marshal_uint32 (DBusString    *str,
00531                       int            byte_order,
00532                       dbus_uint32_t  value)
00533 {
00534   return marshal_4_octets (str, byte_order, value);
00535 }
00536 
00537 
00538 #ifdef DBUS_HAVE_INT64
00539 
00547 dbus_bool_t
00548 _dbus_marshal_int64  (DBusString   *str,
00549                       int           byte_order,
00550                       dbus_int64_t  value)
00551 {
00552   DBusOctets8 r;
00553   r.s = value;
00554   return marshal_8_octets (str, byte_order, r);
00555 }
00556 
00565 dbus_bool_t
00566 _dbus_marshal_uint64 (DBusString    *str,
00567                       int            byte_order,
00568                       dbus_uint64_t  value)
00569 {
00570   DBusOctets8 r;
00571   r.u = value;
00572   return marshal_8_octets (str, byte_order, r);
00573 }
00574 
00575 #endif /* DBUS_HAVE_INT64 */
00576 
00588 dbus_bool_t
00589 _dbus_marshal_string (DBusString    *str,
00590                       int            byte_order,
00591                       const char    *value)
00592 {
00593   int len, old_string_len;
00594 
00595   old_string_len = _dbus_string_get_length (str);
00596   
00597   len = strlen (value);
00598 
00599   if (!_dbus_marshal_uint32 (str, byte_order, len))
00600     {
00601       /* Restore the previous length */
00602       _dbus_string_set_length (str, old_string_len);
00603 
00604       return FALSE;
00605     }
00606 
00607   return _dbus_string_append_len (str, value, len + 1);
00608 }
00609 
00619 dbus_bool_t
00620 _dbus_marshal_byte_array (DBusString          *str,
00621                           int                  byte_order,
00622                           const unsigned char *value,
00623                           int                  len)
00624 {
00625   int old_string_len;
00626 
00627   old_string_len = _dbus_string_get_length (str);
00628   
00629   if (!_dbus_marshal_uint32 (str, byte_order, len))
00630     {
00631       /* Restore the previous length */
00632       _dbus_string_set_length (str, old_string_len);
00633 
00634       return FALSE;
00635     }
00636 
00637   if (len == 0)
00638     return TRUE;
00639   else
00640     return _dbus_string_append_len (str, value, len);
00641 }
00642 
00643 static dbus_bool_t
00644 marshal_4_octets_array (DBusString          *str,
00645                         int                  byte_order,
00646                         const dbus_uint32_t *value,
00647                         int                  len)
00648 {
00649   int old_string_len;
00650   int array_start;
00651 
00652   old_string_len = _dbus_string_get_length (str);
00653 
00654   if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
00655     goto error;
00656 
00657   array_start = _dbus_string_get_length (str);
00658   
00659   if (!_dbus_string_append_len (str, (const unsigned char*) value,
00660                                 len * 4))
00661     goto error;
00662   
00663   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00664     {
00665       const unsigned char *d;
00666       const unsigned char *end;
00667       
00668       d = _dbus_string_get_data (str) + array_start;
00669       end = d + len * 4;
00670       while (d != end)
00671         {
00672           *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
00673           d += 4;
00674         }
00675     }
00676 
00677   return TRUE;
00678   
00679  error:
00680   /* Restore previous length */
00681   _dbus_string_set_length (str, old_string_len);
00682   
00683   return FALSE;  
00684 }
00685 
00686 static dbus_bool_t
00687 marshal_8_octets_array (DBusString          *str,
00688                         int                  byte_order,
00689                         const DBusOctets8   *value,
00690                         int                  len)
00691 {
00692   int old_string_len;
00693   int array_start;
00694 
00695   old_string_len = _dbus_string_get_length (str);
00696 
00697   if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
00698     goto error;
00699 
00700   array_start = _dbus_string_get_length (str);
00701   
00702   if (!_dbus_string_append_len (str, (const unsigned char*) value,
00703                                 len * 8))
00704     goto error;
00705   
00706   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00707     {
00708       const unsigned char *d;
00709       const unsigned char *end;
00710       
00711       d = _dbus_string_get_data (str) + array_start;
00712       end = d + len * 8;
00713       while (d != end)
00714         {
00715 #ifdef DBUS_HAVE_INT64
00716           *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
00717 #else
00718           swap_bytes ((unsigned char*) d, 8);
00719 #endif
00720           d += 8;
00721         }
00722     }
00723 
00724   return TRUE;
00725   
00726  error:
00727   /* Restore previous length */
00728   _dbus_string_set_length (str, old_string_len);
00729   
00730   return FALSE;  
00731 }
00732 
00742 dbus_bool_t
00743 _dbus_marshal_int32_array (DBusString         *str,
00744                            int                 byte_order,
00745                            const dbus_int32_t *value,
00746                            int                 len)
00747 {
00748   return marshal_4_octets_array (str, byte_order,
00749                                  (const dbus_uint32_t*) value,
00750                                  len);
00751 }
00752 
00762 dbus_bool_t
00763 _dbus_marshal_uint32_array (DBusString          *str,
00764                             int                  byte_order,
00765                             const dbus_uint32_t  *value,
00766                             int                  len)
00767 {
00768   return marshal_4_octets_array (str, byte_order,
00769                                  value,
00770                                  len);
00771 }
00772 
00773 #ifdef DBUS_HAVE_INT64
00774 
00784 dbus_bool_t
00785 _dbus_marshal_int64_array (DBusString         *str,
00786                            int                 byte_order,
00787                            const dbus_int64_t *value,
00788                            int                 len)
00789 {
00790   return marshal_8_octets_array (str, byte_order,
00791                                  (const DBusOctets8*) value,
00792                                  len);
00793 }
00794 
00804 dbus_bool_t
00805 _dbus_marshal_uint64_array (DBusString          *str,
00806                             int                  byte_order,
00807                             const dbus_uint64_t  *value,
00808                             int                  len)
00809 {
00810   return marshal_8_octets_array (str, byte_order,
00811                                  (const DBusOctets8*) value,
00812                                  len);
00813 }
00814 
00815 #endif /* DBUS_HAVE_INT64 */
00816 
00826 dbus_bool_t
00827 _dbus_marshal_double_array (DBusString          *str,
00828                             int                  byte_order,
00829                             const double        *value,
00830                             int                  len)
00831 {
00832   return marshal_8_octets_array (str, byte_order,
00833                                  (const DBusOctets8*) value,
00834                                  len);
00835 }
00836 
00846 dbus_bool_t
00847 _dbus_marshal_string_array (DBusString  *str,
00848                             int          byte_order,
00849                             const char **value,
00850                             int          len)
00851 {
00852   int i, old_string_len, array_start;
00853 
00854   old_string_len = _dbus_string_get_length (str);
00855 
00856   /* Set the length to 0 temporarily */
00857   if (!_dbus_marshal_uint32 (str, byte_order, 0))
00858     goto error;
00859 
00860   array_start = _dbus_string_get_length (str);
00861   
00862   for (i = 0; i < len; i++)
00863     if (!_dbus_marshal_string (str, byte_order, value[i]))
00864       goto error;
00865 
00866   /* Write the length now that we know it */
00867   _dbus_marshal_set_uint32 (str, byte_order,
00868                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00869                             _dbus_string_get_length (str) - array_start);
00870   
00871   return TRUE;
00872   
00873  error:
00874   /* Restore previous length */
00875   _dbus_string_set_length (str, old_string_len);
00876   
00877   return FALSE;      
00878 }
00879 
00889 dbus_bool_t
00890 _dbus_marshal_object_path (DBusString            *str,
00891                            int                    byte_order,
00892                            const char           **path,
00893                            int                    path_len)
00894 {
00895   int array_start, old_string_len;
00896   int i;
00897   
00898   old_string_len = _dbus_string_get_length (str);
00899   
00900   /* Set the length to 0 temporarily */
00901   if (!_dbus_marshal_uint32 (str, byte_order, 0))
00902     goto nomem;
00903 
00904   array_start = _dbus_string_get_length (str);
00905   
00906   i = 0;
00907   while (i < path_len)
00908     {
00909       if (!_dbus_string_append_byte (str, '/'))
00910         goto nomem;
00911       
00912       if (!_dbus_string_append (str, path[0]))
00913         goto nomem;
00914 
00915       ++i;
00916     }
00917 
00918   /* Write the length now that we know it */
00919   _dbus_marshal_set_uint32 (str, byte_order,
00920                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00921                             _dbus_string_get_length (str) - array_start);  
00922 
00923   return TRUE;
00924 
00925  nomem:
00926   /* Restore the previous length */
00927   _dbus_string_set_length (str, old_string_len);
00928   
00929   return FALSE;
00930 }
00931 
00932 static dbus_uint32_t
00933 demarshal_4_octets (const DBusString *str,
00934                     int               byte_order,
00935                     int               pos,
00936                     int              *new_pos)
00937 {
00938   const DBusRealString *real = (const DBusRealString*) str;
00939   
00940   pos = _DBUS_ALIGN_VALUE (pos, 4);
00941   
00942   if (new_pos)
00943     *new_pos = pos + 4;
00944 
00945   return unpack_4_octets (byte_order, real->str + pos);
00946 }
00947 
00948 static DBusOctets8
00949 demarshal_8_octets (const DBusString *str,
00950                     int               byte_order,
00951                     int               pos,
00952                     int              *new_pos)
00953 {
00954   const DBusRealString *real = (const DBusRealString*) str;
00955   
00956   pos = _DBUS_ALIGN_VALUE (pos, 8);
00957   
00958   if (new_pos)
00959     *new_pos = pos + 8;
00960 
00961   return unpack_8_octets (byte_order, real->str + pos);
00962 }
00963 
00973 double
00974 _dbus_demarshal_double (const DBusString  *str,
00975                         int                byte_order,
00976                         int                pos,
00977                         int               *new_pos)
00978 {
00979   DBusOctets8 r;
00980 
00981   r = demarshal_8_octets (str, byte_order, pos, new_pos);
00982 
00983   return r.d;
00984 }
00985 
00995 dbus_int32_t
00996 _dbus_demarshal_int32  (const DBusString *str,
00997                         int               byte_order,
00998                         int               pos,
00999                         int              *new_pos)
01000 {
01001   return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
01002 }
01003 
01013 dbus_uint32_t
01014 _dbus_demarshal_uint32  (const DBusString *str,
01015                          int         byte_order,
01016                          int         pos,
01017                          int        *new_pos)
01018 {
01019   return demarshal_4_octets (str, byte_order, pos, new_pos);
01020 }
01021 
01022 #ifdef DBUS_HAVE_INT64
01023 
01033 dbus_int64_t
01034 _dbus_demarshal_int64  (const DBusString *str,
01035                         int               byte_order,
01036                         int               pos,
01037                         int              *new_pos)
01038 {
01039   DBusOctets8 r;
01040 
01041   r = demarshal_8_octets (str, byte_order, pos, new_pos);
01042 
01043   return r.s;
01044 }
01045 
01055 dbus_uint64_t
01056 _dbus_demarshal_uint64  (const DBusString *str,
01057                          int         byte_order,
01058                          int         pos,
01059                          int        *new_pos)
01060 {
01061   DBusOctets8 r;
01062 
01063   r = demarshal_8_octets (str, byte_order, pos, new_pos);
01064 
01065   return r.u;
01066 }
01067 
01068 #endif /* DBUS_HAVE_INT64 */
01069 
01086 char *
01087 _dbus_demarshal_string (const DBusString *str,
01088                         int               byte_order,
01089                         int               pos,
01090                         int              *new_pos)
01091 {
01092   int len;
01093   char *retval;
01094   const char *data;
01095   
01096   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01097 
01098   retval = dbus_malloc (len + 1);
01099 
01100   if (!retval)
01101     return NULL;
01102 
01103   data = _dbus_string_get_const_data_len (str, pos, len + 1);
01104 
01105   if (!data)
01106     return NULL;
01107 
01108   memcpy (retval, data, len + 1);
01109 
01110   if (new_pos)
01111     *new_pos = pos + len + 1;
01112   
01113   return retval;
01114 }
01115 
01131 dbus_bool_t
01132 _dbus_demarshal_byte_array (const DBusString  *str,
01133                             int                byte_order,
01134                             int                pos,
01135                             int               *new_pos,
01136                             unsigned char    **array,
01137                             int               *array_len)
01138 {
01139   int len;
01140   unsigned char *retval;
01141   const char *data;
01142 
01143   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01144 
01145   if (len == 0)
01146     {
01147       *array_len = len;
01148       *array = NULL;
01149 
01150       if (new_pos)
01151         *new_pos = pos;
01152       
01153       return TRUE;
01154     }
01155   
01156   retval = dbus_malloc (len);
01157 
01158   if (!retval)
01159     return FALSE;
01160 
01161   data = _dbus_string_get_const_data_len (str, pos, len);
01162 
01163   if (!data)
01164     {
01165       dbus_free (retval);
01166       return FALSE;
01167     }
01168 
01169   memcpy (retval, data, len);
01170 
01171   if (new_pos)
01172     *new_pos = pos + len;
01173 
01174   *array = retval;
01175   *array_len = len;
01176   
01177   return TRUE;
01178 }
01179 
01180 static dbus_bool_t
01181 demarshal_4_octets_array (const DBusString  *str,
01182                           int                byte_order,
01183                           int                pos,
01184                           int               *new_pos,
01185                           dbus_uint32_t    **array,
01186                           int               *array_len)
01187 {
01188   int len, i;
01189   dbus_uint32_t *retval;
01190   int byte_len;
01191   
01192   byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01193   len = byte_len / 4;
01194 
01195   if (len == 0)
01196     {
01197       *array_len = 0;
01198       *array = NULL;
01199 
01200       if (new_pos)
01201         *new_pos = pos;
01202       
01203       return TRUE;
01204     }
01205 
01206   if (!_dbus_string_copy_data_len (str, (char**) &retval,
01207                                    pos, byte_len))
01208     return FALSE;
01209   
01210   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01211     {
01212       for (i = 0; i < len; i++)
01213         retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
01214     }
01215 
01216   if (new_pos)
01217     *new_pos = pos + byte_len;
01218 
01219   *array_len = len;
01220   *array = retval;
01221   
01222   return TRUE;  
01223 }
01224 
01225 static dbus_bool_t
01226 demarshal_8_octets_array (const DBusString  *str,
01227                           int                byte_order,
01228                           int                pos,
01229                           int               *new_pos,
01230                           DBusOctets8      **array,
01231                           int               *array_len)
01232 {
01233   int len, i;
01234   DBusOctets8 *retval;
01235   int byte_len;
01236   
01237   byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01238   len = byte_len / 8;
01239 
01240   if (len == 0)
01241     {
01242       *array_len = 0;
01243       *array = NULL;
01244 
01245       if (new_pos)
01246         *new_pos = pos;
01247       
01248       return TRUE;
01249     }
01250 
01251   if (!_dbus_string_copy_data_len (str, (char**) &retval,
01252                                    pos, byte_len))
01253     return FALSE;
01254   
01255   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01256     {
01257       for (i = 0; i < len; i++)
01258         {
01259 #ifdef DBUS_HAVE_INT64
01260           retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
01261 #else
01262           swap_bytes ((unsigned char *) &retval[i], 8);
01263 #endif
01264         }
01265     }
01266 
01267   if (new_pos)
01268     *new_pos = pos + byte_len;
01269 
01270   *array_len = len;
01271   *array = retval;
01272   
01273   return TRUE;  
01274 }
01275 
01287 dbus_bool_t
01288 _dbus_demarshal_int32_array (const DBusString  *str,
01289                              int                byte_order,
01290                              int                pos,
01291                              int               *new_pos,
01292                              dbus_int32_t     **array,
01293                              int               *array_len)
01294 {
01295   return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01296                                    (dbus_uint32_t**) array, array_len);
01297 }
01298 
01310 dbus_bool_t
01311 _dbus_demarshal_uint32_array (const DBusString  *str,
01312                               int                byte_order,
01313                               int                pos,
01314                               int               *new_pos,
01315                               dbus_uint32_t    **array,
01316                               int               *array_len)
01317 {
01318   return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01319                                    array, array_len);
01320 }
01321 
01322 #ifdef DBUS_HAVE_INT64
01323 
01335 dbus_bool_t
01336 _dbus_demarshal_int64_array (const DBusString  *str,
01337                              int                byte_order,
01338                              int                pos,
01339                              int               *new_pos,
01340                              dbus_int64_t     **array,
01341                              int               *array_len)
01342 {
01343   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01344                                    (DBusOctets8**) array, array_len);
01345 }
01346 
01358 dbus_bool_t
01359 _dbus_demarshal_uint64_array (const DBusString  *str,
01360                               int                byte_order,
01361                               int                pos,
01362                               int               *new_pos,
01363                               dbus_uint64_t    **array,
01364                               int               *array_len)
01365 {
01366   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01367                                    (DBusOctets8**) array, array_len);
01368 }
01369 
01370 #endif /* DBUS_HAVE_INT64 */
01371 
01383 dbus_bool_t
01384 _dbus_demarshal_double_array (const DBusString  *str,
01385                               int                byte_order,
01386                               int                pos,
01387                               int               *new_pos,
01388                               double           **array,
01389                               int               *array_len)
01390 {
01391   return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01392                                    (DBusOctets8**) array, array_len);
01393 }
01394 
01406 dbus_bool_t
01407 _dbus_demarshal_string_array (const DBusString   *str,
01408                               int                 byte_order,
01409                               int                 pos,
01410                               int                *new_pos,
01411                               char             ***array,
01412                               int                *array_len)
01413 {
01414   int bytes_len, i;
01415   int len, allocated;
01416   int end_pos;
01417   char **retval;
01418   
01419   bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01420   
01421   if (bytes_len == 0)
01422     {
01423       *array_len = 0;
01424       *array = NULL;
01425 
01426       if (new_pos)
01427         *new_pos = pos;
01428       
01429       return TRUE;
01430     }
01431 
01432   len = 0;
01433   allocated = 4;
01434   end_pos = pos + bytes_len;
01435   
01436   retval = dbus_new (char *, allocated);
01437 
01438   if (!retval)
01439     return FALSE;
01440 
01441   while (pos < end_pos)
01442     {
01443       retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
01444       
01445       if (retval[len] == NULL)
01446         goto error;
01447       
01448       len += 1;
01449 
01450       if (len >= allocated - 1) /* -1 for NULL termination */
01451         {
01452           char **newp;
01453           newp = dbus_realloc (retval,
01454                                sizeof (char*) * allocated * 2);
01455           if (newp == NULL)
01456             goto error;
01457 
01458           allocated *= 2;
01459           retval = newp;
01460         }
01461     }
01462       
01463   retval[len] = NULL;
01464 
01465   if (new_pos)
01466     *new_pos = pos;
01467   
01468   *array = retval;
01469   *array_len = len;
01470   
01471   return TRUE;
01472 
01473  error:
01474   for (i = 0; i < len; i++)
01475     dbus_free (retval[i]);
01476   dbus_free (retval);
01477 
01478   return FALSE;
01479 }
01480 
01482 #define VERBOSE_DECOMPOSE 0
01483 
01495 dbus_bool_t
01496 _dbus_demarshal_object_path (const DBusString *str,
01497                              int               byte_order,
01498                              int               pos,
01499                              int              *new_pos,
01500                              char           ***path,
01501                              int              *path_len)
01502 {
01503   int len;
01504   char **retval;
01505   const char *data;
01506   int n_components;
01507   int i, j, comp;
01508   
01509   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01510   data = _dbus_string_get_const_data_len (str, pos, len + 1);
01511   _dbus_assert (data != NULL);
01512 
01513 #if VERBOSE_DECOMPOSE
01514   _dbus_verbose ("Decomposing path \"%s\"\n",
01515                  data);
01516 #endif
01517   
01518   n_components = 0;
01519   i = 0;
01520   while (i < len)
01521     {
01522       if (data[i] == '/')
01523         n_components += 1;
01524       ++i;
01525     }
01526   
01527   retval = dbus_new0 (char*, n_components + 1);
01528 
01529   if (retval == NULL)
01530     return FALSE;
01531 
01532   comp = 0;
01533   i = 0;
01534   while (i < len)
01535     {
01536       if (data[i] == '/')
01537         ++i;
01538       j = i;
01539 
01540       while (j < len && data[j] != '/')
01541         ++j;
01542 
01543       /* Now [i, j) is the path component */
01544       _dbus_assert (i < j);
01545       _dbus_assert (data[i] != '/');
01546       _dbus_assert (j == len || data[j] == '/');
01547 
01548 #if VERBOSE_DECOMPOSE
01549       _dbus_verbose ("  (component in [%d,%d))\n",
01550                      i, j);
01551 #endif
01552       
01553       retval[comp] = _dbus_memdup (&data[i], j - i + 1);
01554       if (retval[comp] == NULL)
01555         {
01556           dbus_free_string_array (retval);
01557           return FALSE;
01558         }
01559       retval[comp][j-i] = '\0';
01560 #if VERBOSE_DECOMPOSE
01561       _dbus_verbose ("  (component %d = \"%s\")\n",
01562                      comp, retval[comp]);
01563 #endif
01564 
01565       ++comp;
01566       i = j;
01567     }
01568   _dbus_assert (i == len);
01569   
01570   *path = retval;
01571   if (path_len)
01572     *path_len = n_components;
01573   
01574   if (new_pos)
01575     *new_pos = pos + len + 1;
01576   
01577   return TRUE;
01578 }
01579 
01593 dbus_bool_t
01594 _dbus_marshal_get_arg_end_pos (const DBusString *str,
01595                                int               byte_order,
01596                                int               type,
01597                                int               pos,
01598                                int              *end_pos)
01599 {
01600   if (pos >= _dbus_string_get_length (str))
01601     return FALSE;
01602 
01603   switch (type)
01604     {
01605     case DBUS_TYPE_INVALID:
01606       return FALSE;
01607       break;
01608 
01609     case DBUS_TYPE_NIL:
01610       *end_pos = pos;
01611       break;
01612 
01613     case DBUS_TYPE_BYTE:
01614       *end_pos = pos + 1;
01615       break;
01616       
01617     case DBUS_TYPE_BOOLEAN:
01618       *end_pos = pos + 1;
01619       break;
01620 
01621     case DBUS_TYPE_INT32:
01622     case DBUS_TYPE_UINT32:
01623       *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
01624       break;
01625 
01626     case DBUS_TYPE_INT64:
01627     case DBUS_TYPE_UINT64:
01628     case DBUS_TYPE_DOUBLE:
01629       
01630       *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
01631       break;
01632 
01633     case DBUS_TYPE_OBJECT_PATH:
01634     case DBUS_TYPE_STRING:
01635       {
01636         int len;
01637         
01638         /* Demarshal the length */
01639         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01640 
01641         *end_pos = pos + len + 1;
01642       }
01643       break;
01644 
01645     case DBUS_TYPE_CUSTOM:
01646       {
01647         int len;
01648         
01649         /* Demarshal the string length */
01650         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01651 
01652         *end_pos = pos + len + 1;
01653         
01654         /* Demarshal the data length */
01655         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01656 
01657         *end_pos = pos + len;
01658       }
01659       break;
01660       
01661     case DBUS_TYPE_ARRAY:
01662       {
01663         int len;
01664 
01665         /* Demarshal the length  */
01666         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01667         
01668         *end_pos = pos + len;
01669       }
01670       break;
01671 
01672     case DBUS_TYPE_DICT:
01673       {
01674         int len;
01675 
01676         /* Demarshal the length */
01677         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01678         
01679         *end_pos = pos + len;
01680       }
01681       break;
01682       
01683     default:
01684       _dbus_warn ("Unknown message arg type %d\n", type);
01685       _dbus_assert_not_reached ("Unknown message argument type\n");
01686       return FALSE;
01687     }
01688 
01689   if (*end_pos > _dbus_string_get_length (str))
01690     return FALSE;
01691   
01692   return TRUE;
01693 }
01694 
01708 static int
01709 demarshal_and_validate_len (const DBusString *str,
01710                             int               byte_order,
01711                             int               pos,
01712                             int              *new_pos)
01713 {
01714   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
01715   unsigned int len;
01716 
01717   _dbus_assert (new_pos != NULL);
01718   
01719   if ((align_4 + 4) > _dbus_string_get_length (str))
01720     {
01721       _dbus_verbose ("not enough room in message for array length\n");
01722       return -1;
01723     }
01724   
01725   if (!_dbus_string_validate_nul (str, pos,
01726                                   align_4 - pos))
01727     {
01728       _dbus_verbose ("array length alignment padding not initialized to nul\n");
01729       return -1;
01730     }
01731 
01732   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
01733 
01734   /* note that the len is the number of bytes, so we need it to be
01735    * at least SIZE_T_MAX, but make it smaller just to keep things
01736    * sane.  We end up using ints for most sizes to avoid unsigned mess
01737    * so limit to maximum 32-bit signed int divided by at least 8, more
01738    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
01739    */  
01740 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
01741   if (len > MAX_ARRAY_LENGTH)
01742     {
01743       _dbus_verbose ("array length %u exceeds maximum of %u\n",
01744                      len, MAX_ARRAY_LENGTH);
01745       return -1;
01746     }
01747   else
01748     return (int) len;
01749 }
01750 
01751 static dbus_bool_t
01752 validate_string (const DBusString *str,
01753                  int               pos,
01754                  int               len_without_nul,
01755                  int              *end_pos)
01756 {
01757   *end_pos = pos + len_without_nul + 1;
01758   
01759   if (*end_pos > _dbus_string_get_length (str))
01760     {
01761       _dbus_verbose ("string length outside length of the message\n");
01762       return FALSE;
01763     }
01764   
01765   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
01766     {
01767       _dbus_verbose ("string arg not nul-terminated\n");
01768       return FALSE;
01769     }
01770   
01771   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
01772     {
01773       _dbus_verbose ("string is not valid UTF-8\n");
01774       return FALSE;
01775     }
01776 
01777   return TRUE;
01778 }   
01779 
01791 dbus_bool_t
01792 _dbus_marshal_validate_type   (const DBusString *str,
01793                                int               pos,
01794                                int              *type,
01795                                int              *end_pos)
01796 {
01797   const char *data;
01798   
01799   if (pos >= _dbus_string_get_length (str))
01800     return FALSE;
01801 
01802   data = _dbus_string_get_const_data_len (str, pos, 1);
01803 
01804   if (_dbus_type_is_valid (*data))
01805     {
01806       *type = *data;
01807       if (end_pos != NULL)
01808         *end_pos = pos + 1;
01809       return TRUE;
01810     }
01811 
01812   _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
01813   
01814   return FALSE;
01815 }
01816 
01817 /* Faster validator for array data that doesn't call
01818  * validate_arg for each value
01819  */
01820 static dbus_bool_t
01821 validate_array_data (const DBusString *str,
01822                      int               byte_order,
01823                      int               depth,
01824                      int               type,
01825                      int               array_type_pos,
01826                      int               pos,
01827                      int              *new_pos,
01828                      int               end)
01829 {
01830   switch (type)
01831     {
01832     case DBUS_TYPE_INVALID:
01833       return FALSE;
01834       break;
01835 
01836     case DBUS_TYPE_NIL:
01837       break;
01838 
01839     case DBUS_TYPE_OBJECT_PATH:
01840     case DBUS_TYPE_STRING:
01841     case DBUS_TYPE_CUSTOM:
01842     case DBUS_TYPE_ARRAY:
01843     case DBUS_TYPE_DICT:
01844       /* This clean recursion to validate_arg is what we
01845        * are doing logically for all types, but we don't
01846        * really want to call validate_arg for every byte
01847        * in a byte array, so the primitive types are
01848        * special-cased.
01849        */
01850       while (pos < end)
01851         {
01852           if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01853                                            type, array_type_pos, pos, &pos))
01854             return FALSE;
01855         }
01856       break;
01857       
01858     case DBUS_TYPE_BYTE:
01859       pos = end;
01860       break;
01861       
01862     case DBUS_TYPE_BOOLEAN:
01863       while (pos < end)
01864         {
01865           unsigned char c;
01866           
01867           c = _dbus_string_get_byte (str, pos);
01868           
01869           if (!(c == 0 || c == 1))
01870             {
01871               _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
01872               return FALSE;
01873             }
01874           
01875           ++pos;
01876         }
01877       break;
01878       
01879     case DBUS_TYPE_INT32:
01880     case DBUS_TYPE_UINT32:
01881       /* Call validate arg one time to check alignment padding
01882        * at start of array
01883        */
01884       if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01885                                        type, array_type_pos, pos, &pos))
01886         return FALSE;
01887       pos = _DBUS_ALIGN_VALUE (end, 4);
01888       break;
01889 
01890     case DBUS_TYPE_INT64:
01891     case DBUS_TYPE_UINT64:
01892     case DBUS_TYPE_DOUBLE:
01893       /* Call validate arg one time to check alignment padding
01894        * at start of array
01895        */
01896       if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01897                                        type, array_type_pos, pos, &pos))
01898         return FALSE;
01899       pos = _DBUS_ALIGN_VALUE (end, 8);
01900       break;
01901       
01902     default:
01903       _dbus_verbose ("Unknown message arg type %d\n", type);
01904       return FALSE;
01905     }
01906 
01907   *new_pos = pos;
01908 
01909   return TRUE;
01910 }
01911 
01932 dbus_bool_t
01933 _dbus_marshal_validate_arg (const DBusString *str,
01934                             int               byte_order,
01935                             int               depth,
01936                             int               type,
01937                             int               array_type_pos,
01938                             int               pos,
01939                             int              *end_pos)
01940 {
01941   if (pos > _dbus_string_get_length (str))
01942     {
01943       _dbus_verbose ("Validation went off the end of the message\n");
01944       return FALSE;
01945     }
01946 
01947 #define MAX_VALIDATION_DEPTH 32
01948   
01949   if (depth > MAX_VALIDATION_DEPTH)
01950     {
01951       _dbus_verbose ("Maximum recursion depth reached validating message\n");
01952       return FALSE;
01953     }
01954   
01955   switch (type)
01956     {
01957     case DBUS_TYPE_INVALID:
01958       return FALSE;
01959       break;
01960 
01961     case DBUS_TYPE_NIL:
01962       *end_pos = pos;
01963       break;
01964 
01965     case DBUS_TYPE_BYTE:
01966       if (1 > _dbus_string_get_length (str) - pos)
01967         {
01968           _dbus_verbose ("no room for byte value\n");
01969           return FALSE;
01970         }
01971         
01972       *end_pos = pos + 1;
01973       break;
01974       
01975     case DBUS_TYPE_BOOLEAN:
01976       {
01977         unsigned char c;
01978 
01979         if (1 > _dbus_string_get_length (str) - pos)
01980           {
01981             _dbus_verbose ("no room for boolean value\n");
01982             return FALSE;
01983           }
01984         
01985         c = _dbus_string_get_byte (str, pos);
01986 
01987         if (!(c == 0 || c == 1))
01988           {
01989             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
01990             return FALSE;
01991           }
01992         
01993         *end_pos = pos + 1;
01994       }
01995       break;
01996       
01997     case DBUS_TYPE_INT32:
01998     case DBUS_TYPE_UINT32:
01999       {
02000         int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
02001         
02002         if (!_dbus_string_validate_nul (str, pos,
02003                                         align_4 - pos))
02004           {
02005             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
02006             return FALSE;
02007           }
02008 
02009         *end_pos = align_4 + 4;
02010       }
02011       break;
02012 
02013     case DBUS_TYPE_INT64:
02014     case DBUS_TYPE_UINT64:      
02015     case DBUS_TYPE_DOUBLE:
02016       {
02017         int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
02018 
02019         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
02020         
02021         if (!_dbus_string_validate_nul (str, pos,
02022                                         align_8 - pos))
02023           {
02024             _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
02025             return FALSE;
02026           }
02027 
02028         *end_pos = align_8 + 8;
02029       }
02030       break;
02031 
02032     case DBUS_TYPE_OBJECT_PATH:
02033     case DBUS_TYPE_STRING:
02034       {
02035         int len;
02036 
02037         /* Demarshal the length, which does NOT include
02038          * nul termination
02039          */
02040         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02041         if (len < 0)
02042           return FALSE;
02043 
02044         if (!validate_string (str, pos, len, end_pos))
02045           return FALSE;
02046 
02047         if (type == DBUS_TYPE_OBJECT_PATH)
02048           {
02049             if (!_dbus_string_validate_path (str, pos, len))
02050               return FALSE;
02051           }
02052       }
02053       break;
02054 
02055     case DBUS_TYPE_CUSTOM:
02056       {
02057         int len;
02058 
02059         /* Demarshal the string length, which does NOT include
02060          * nul termination
02061          */
02062         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02063         if (len < 0)
02064           return FALSE;
02065 
02066         if (!validate_string (str, pos, len, &pos))
02067           return FALSE;
02068 
02069         /* Validate data */
02070         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02071         if (len < 0)
02072           return FALSE;
02073 
02074         *end_pos = pos + len;
02075       }
02076       break;
02077       
02078     case DBUS_TYPE_ARRAY:
02079       {
02080         int len;
02081         int end;
02082         int array_type;
02083 
02084         if (array_type_pos == -1)
02085           {
02086             array_type_pos = pos;
02087 
02088             do
02089               {
02090                 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
02091                   {
02092                     _dbus_verbose ("invalid array type\n");
02093                     return FALSE;
02094                   }
02095                 
02096                 /* NIL values take up no space, so you couldn't iterate over an array of them.
02097                  * array of nil seems useless anyway; the useful thing might be array of
02098                  * (nil OR string) but we have no framework for that.
02099                  */
02100                 if (array_type == DBUS_TYPE_NIL)
02101                   {
02102                     _dbus_verbose ("array of NIL is not allowed\n");
02103                     return FALSE;
02104                   }
02105               }
02106             while (array_type == DBUS_TYPE_ARRAY);
02107           }
02108         else
02109           array_type_pos++;
02110 
02111         if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
02112           {
02113             _dbus_verbose ("invalid array type\n");
02114             return FALSE;
02115           }
02116         
02117         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02118         if (len < 0)
02119           return FALSE;
02120 
02121         if (len > _dbus_string_get_length (str) - pos)
02122           {
02123             _dbus_verbose ("array length outside length of the message\n");
02124             return FALSE;
02125           }
02126         
02127         end = pos + len;
02128 
02129         if (!validate_array_data (str, byte_order, depth + 1,
02130                                   array_type, array_type_pos,
02131                                   pos, &pos, end))
02132           return FALSE;
02133 
02134         if (pos < end)
02135           {
02136             /* This should not be able to happen, as long as validate_arg moves forward;
02137              * but the check is here just to be paranoid.
02138              */
02139             _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
02140                            len, end - pos);
02141             return FALSE;
02142           }
02143         
02144         if (pos > end)
02145           {
02146             _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
02147             return FALSE;
02148           }
02149 
02150         *end_pos = pos;
02151       }
02152       break;
02153 
02154     case DBUS_TYPE_DICT:
02155       {
02156         int dict_type;
02157         int len;
02158         int end;
02159         
02160         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02161         if (len < 0)
02162           return FALSE;
02163 
02164         if (len > _dbus_string_get_length (str) - pos)
02165           {
02166             _dbus_verbose ("dict length outside length of the message\n");
02167             return FALSE;
02168           }
02169         
02170         end = pos + len;
02171         
02172         while (pos < end)
02173           {
02174             /* Validate name */
02175             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02176                                              DBUS_TYPE_STRING, -1, pos, &pos))
02177               return FALSE;
02178             
02179             if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
02180               {
02181                 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
02182                 return FALSE;
02183               }
02184             
02185             /* Validate element */
02186             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02187                                              dict_type, -1, pos, &pos))
02188               return FALSE;
02189           }
02190         
02191         if (pos > end)
02192           {
02193             _dbus_verbose ("dict contents exceed stated dict length\n");
02194             return FALSE;
02195           }
02196         
02197         *end_pos = pos;
02198       }
02199       break;
02200       
02201     default:
02202       _dbus_verbose ("Unknown message arg type %d\n", type);
02203       return FALSE;
02204     }
02205 
02206   if (*end_pos > _dbus_string_get_length (str))
02207     return FALSE;
02208   
02209   return TRUE;
02210 }
02211 
02217 dbus_bool_t
02218 _dbus_type_is_valid (int typecode)
02219 {
02220   switch (typecode)
02221     {
02222     case DBUS_TYPE_NIL:
02223     case DBUS_TYPE_BYTE:
02224     case DBUS_TYPE_BOOLEAN:
02225     case DBUS_TYPE_INT32:
02226     case DBUS_TYPE_UINT32:
02227     case DBUS_TYPE_INT64:
02228     case DBUS_TYPE_UINT64:
02229     case DBUS_TYPE_DOUBLE:
02230     case DBUS_TYPE_STRING:
02231     case DBUS_TYPE_CUSTOM:
02232     case DBUS_TYPE_ARRAY:
02233     case DBUS_TYPE_DICT:
02234     case DBUS_TYPE_OBJECT_PATH:
02235       return TRUE;
02236       
02237     default:
02238       return FALSE;
02239     }
02240 }
02241 
02250 void
02251 _dbus_verbose_bytes (const unsigned char *data,
02252                      int                  len)
02253 {
02254   int i;
02255   const unsigned char *aligned;
02256 
02257   _dbus_assert (len >= 0);
02258   
02259   /* Print blanks on first row if appropriate */
02260   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
02261   if (aligned > data)
02262     aligned -= 4;
02263   _dbus_assert (aligned <= data);
02264 
02265   if (aligned != data)
02266     {
02267       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
02268       while (aligned != data)
02269         {
02270           _dbus_verbose ("    ");
02271           ++aligned;
02272         }
02273     }
02274 
02275   /* now print the bytes */
02276   i = 0;
02277   while (i < len)
02278     {
02279       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02280         {
02281           _dbus_verbose ("%4d\t%p: ",
02282                    i, &data[i]);
02283         }
02284       
02285       if (data[i] >= 32 &&
02286           data[i] <= 126)
02287         _dbus_verbose (" '%c' ", data[i]);
02288       else
02289         _dbus_verbose ("0x%s%x ",
02290                  data[i] <= 0xf ? "0" : "", data[i]);
02291 
02292       ++i;
02293 
02294       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02295         {
02296           if (i > 3)
02297             _dbus_verbose ("BE: %d LE: %d",
02298                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
02299                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
02300 
02301           if (i > 7 && 
02302               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
02303             {
02304               _dbus_verbose (" dbl: %g",
02305                              *(double*)&data[i-8]);
02306             }
02307           
02308           _dbus_verbose ("\n");
02309         }
02310     }
02311 
02312   _dbus_verbose ("\n");
02313 }
02314 
02322 void
02323 _dbus_verbose_bytes_of_string (const DBusString    *str,
02324                                int                  start,
02325                                int                  len)
02326 {
02327   const char *d;
02328   int real_len;
02329 
02330   real_len = _dbus_string_get_length (str);
02331 
02332   _dbus_assert (start >= 0);
02333   
02334   if (start > real_len)
02335     {
02336       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
02337                      start, len, real_len);
02338       return;
02339     }
02340 
02341   if ((start + len) > real_len)
02342     {
02343       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
02344                      start, len, real_len);
02345       len = real_len - start;
02346     }
02347   
02348   d = _dbus_string_get_const_data_len (str, start, len);
02349 
02350   _dbus_verbose_bytes (d, len);
02351 }
02352 
02355 #ifdef DBUS_BUILD_TESTS
02356 #include "dbus-test.h"
02357 #include <stdio.h>
02358 
02359 dbus_bool_t
02360 _dbus_marshal_test (void)
02361 {
02362   DBusString str;
02363   char *tmp1, *tmp2;
02364   int pos = 0, len;
02365   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
02366 #ifdef DBUS_HAVE_INT64
02367   dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
02368 #endif
02369   char *s;
02370   DBusString t;
02371   
02372   if (!_dbus_string_init (&str))
02373     _dbus_assert_not_reached ("failed to init string");
02374 
02375   /* Marshal doubles */
02376   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
02377     _dbus_assert_not_reached ("could not marshal double value");
02378   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
02379     _dbus_assert_not_reached ("demarshal failed");
02380 
02381   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
02382     _dbus_assert_not_reached ("could not marshal double value");
02383   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
02384     _dbus_assert_not_reached ("demarshal failed");
02385   
02386   /* Marshal signed integers */
02387   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
02388     _dbus_assert_not_reached ("could not marshal signed integer value");
02389   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
02390     _dbus_assert_not_reached ("demarshal failed");
02391 
02392   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
02393     _dbus_assert_not_reached ("could not marshal signed integer value");
02394   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
02395     _dbus_assert_not_reached ("demarshal failed");
02396   
02397   /* Marshal unsigned integers */
02398   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
02399     _dbus_assert_not_reached ("could not marshal signed integer value");
02400   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
02401     _dbus_assert_not_reached ("demarshal failed");
02402   
02403   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
02404     _dbus_assert_not_reached ("could not marshal signed integer value");
02405   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
02406     _dbus_assert_not_reached ("demarshal failed");
02407 
02408 #ifdef DBUS_HAVE_INT64
02409   /* Marshal signed integers */
02410   if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02411     _dbus_assert_not_reached ("could not marshal signed integer value");
02412   if (!_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
02413     _dbus_assert_not_reached ("demarshal failed");
02414 
02415   if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02416     _dbus_assert_not_reached ("could not marshal signed integer value");
02417   if (!_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
02418     _dbus_assert_not_reached ("demarshal failed");
02419   
02420   /* Marshal unsigned integers */
02421   if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02422     _dbus_assert_not_reached ("could not marshal signed integer value");
02423   if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02424     _dbus_assert_not_reached ("demarshal failed");
02425   
02426   if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02427     _dbus_assert_not_reached ("could not marshal signed integer value");
02428   if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02429     _dbus_assert_not_reached ("demarshal failed");
02430 #endif /* DBUS_HAVE_INT64 */
02431   
02432   /* Marshal strings */
02433   tmp1 = "This is the dbus test string";
02434   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
02435     _dbus_assert_not_reached ("could not marshal string");
02436   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
02437   if (!strcmp (tmp1, tmp2) == 0)
02438     _dbus_assert_not_reached ("demarshal failed");
02439   dbus_free (tmp2);
02440 
02441   tmp1 = "This is the dbus test string";
02442   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
02443     _dbus_assert_not_reached ("could not marshal string");
02444   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
02445   if (!strcmp (tmp1, tmp2) == 0)
02446     _dbus_assert_not_reached ("demarshal failed");
02447   dbus_free (tmp2);
02448 
02449   /* Marshal signed integer arrays */
02450   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
02451     _dbus_assert_not_reached ("could not marshal integer array");
02452   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
02453     _dbus_assert_not_reached ("could not demarshal integer array");
02454 
02455   if (len != 3)
02456     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02457   dbus_free (array2);
02458 
02459 #ifdef DBUS_HAVE_INT64
02460   /* Marshal 64-bit signed integer arrays */
02461   if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
02462     _dbus_assert_not_reached ("could not marshal integer array");
02463   if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
02464     _dbus_assert_not_reached ("could not demarshal integer array");
02465 
02466   if (len != 3)
02467     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02468   dbus_free (array4);
02469 
02470   /* set/pack 64-bit integers */
02471   _dbus_string_set_length (&str, 8);
02472 
02473   /* signed little */
02474   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
02475                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02476   
02477   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02478                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02479                                     _dbus_string_get_const_data (&str)));
02480 
02481   /* signed big */
02482   _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
02483                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02484 
02485   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02486                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02487                                     _dbus_string_get_const_data (&str)));
02488 
02489   /* signed little pack */
02490   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02491                     DBUS_LITTLE_ENDIAN,
02492                     _dbus_string_get_data (&str));
02493   
02494   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02495                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02496                                     _dbus_string_get_const_data (&str)));
02497 
02498   /* signed big pack */
02499   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02500                     DBUS_BIG_ENDIAN,
02501                     _dbus_string_get_data (&str));
02502 
02503   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02504                 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02505                                     _dbus_string_get_const_data (&str)));
02506 
02507   /* unsigned little */
02508   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
02509                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02510   
02511   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02512                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02513                                      _dbus_string_get_const_data (&str)));
02514 
02515   /* unsigned big */
02516   _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
02517                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02518 
02519   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02520                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02521                                      _dbus_string_get_const_data (&str)));
02522 
02523   /* unsigned little pack */
02524   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02525                      DBUS_LITTLE_ENDIAN,
02526                      _dbus_string_get_data (&str));
02527   
02528   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02529                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02530                                      _dbus_string_get_const_data (&str)));
02531 
02532   /* unsigned big pack */
02533   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02534                      DBUS_BIG_ENDIAN,
02535                      _dbus_string_get_data (&str));
02536 
02537   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02538                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02539                                      _dbus_string_get_const_data (&str)));
02540   
02541 #endif
02542 
02543   /* set/pack 32-bit integers */
02544   _dbus_string_set_length (&str, 4);
02545 
02546   /* signed little */
02547   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
02548                            0, -0x123456);
02549   
02550   _dbus_assert (-0x123456 ==
02551                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02552                                     _dbus_string_get_const_data (&str)));
02553 
02554   /* signed big */
02555   _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
02556                            0, -0x123456);
02557 
02558   _dbus_assert (-0x123456 ==
02559                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02560                                     _dbus_string_get_const_data (&str)));
02561 
02562   /* signed little pack */
02563   _dbus_pack_int32 (-0x123456,
02564                     DBUS_LITTLE_ENDIAN,
02565                     _dbus_string_get_data (&str));
02566   
02567   _dbus_assert (-0x123456 ==
02568                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02569                                     _dbus_string_get_const_data (&str)));
02570 
02571   /* signed big pack */
02572   _dbus_pack_int32 (-0x123456,
02573                     DBUS_BIG_ENDIAN,
02574                     _dbus_string_get_data (&str));
02575 
02576   _dbus_assert (-0x123456 ==
02577                 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02578                                     _dbus_string_get_const_data (&str)));
02579 
02580   /* unsigned little */
02581   _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
02582                             0, 0x123456);
02583   
02584   _dbus_assert (0x123456 ==
02585                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02586                                      _dbus_string_get_const_data (&str)));
02587 
02588   /* unsigned big */
02589   _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
02590                             0, 0x123456);
02591 
02592   _dbus_assert (0x123456 ==
02593                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02594                                      _dbus_string_get_const_data (&str)));
02595 
02596   /* unsigned little pack */
02597   _dbus_pack_uint32 (0x123456,
02598                      DBUS_LITTLE_ENDIAN,
02599                      _dbus_string_get_data (&str));
02600   
02601   _dbus_assert (0x123456 ==
02602                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02603                                      _dbus_string_get_const_data (&str)));
02604 
02605   /* unsigned big pack */
02606   _dbus_pack_uint32 (0x123456,
02607                      DBUS_BIG_ENDIAN,
02608                      _dbus_string_get_data (&str));
02609 
02610   _dbus_assert (0x123456 ==
02611                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02612                                      _dbus_string_get_const_data (&str)));
02613 
02614 
02615   /* Strings */
02616   
02617   _dbus_string_set_length (&str, 0);
02618 
02619   _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
02620                         "Hello world");
02621   
02622   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02623   _dbus_assert (strcmp (s, "Hello world") == 0);
02624   dbus_free (s);
02625 
02626   _dbus_string_init_const (&t, "Hello world foo");
02627   
02628   _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02629                             &t, _dbus_string_get_length (&t));
02630   
02631   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02632   _dbus_assert (strcmp (s, "Hello world foo") == 0);
02633   dbus_free (s);
02634 
02635   _dbus_string_init_const (&t, "Hello");
02636   
02637   _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02638                             &t, _dbus_string_get_length (&t));
02639   
02640   s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02641   _dbus_assert (strcmp (s, "Hello") == 0);
02642   dbus_free (s);
02643 
02644   /* Strings (big endian) */
02645   
02646   _dbus_string_set_length (&str, 0);
02647 
02648   _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
02649                         "Hello world");
02650   
02651   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02652   _dbus_assert (strcmp (s, "Hello world") == 0);
02653   dbus_free (s);
02654 
02655   _dbus_string_init_const (&t, "Hello world foo");
02656   
02657   _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02658                             &t, _dbus_string_get_length (&t));
02659   
02660   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02661   _dbus_assert (strcmp (s, "Hello world foo") == 0);
02662   dbus_free (s);
02663 
02664   _dbus_string_init_const (&t, "Hello");
02665   
02666   _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02667                             &t, _dbus_string_get_length (&t));
02668   
02669   s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02670   _dbus_assert (strcmp (s, "Hello") == 0);
02671   dbus_free (s);
02672   
02673   _dbus_string_free (&str);
02674       
02675   return TRUE;
02676 }
02677 
02678 #endif /* DBUS_BUILD_TESTS */

Generated on Tue Feb 10 18:14:04 2004 for D-BUS by doxygen 1.3.5