00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include <config.h>
00025 
00026 #ifdef DBUS_BUILD_TESTS
00027 
00028 #include "dbus-marshal-recursive.h"
00029 #include "dbus-marshal-basic.h"
00030 #include "dbus-signature.h"
00031 #include "dbus-internals.h"
00032 #include <string.h>
00033 
00034 static void
00035 basic_value_zero (DBusBasicValue *value)
00036 {
00037 
00038 #ifdef DBUS_HAVE_INT64
00039   value->u64 = 0;
00040 #else
00041   value->u64.first32 = 0;
00042   value->u64.second32 = 0;
00043 #endif
00044 }
00045 
00046 static dbus_bool_t
00047 basic_value_equal (int             type,
00048                    DBusBasicValue *lhs,
00049                    DBusBasicValue *rhs)
00050 {
00051   if (type == DBUS_TYPE_STRING ||
00052       type == DBUS_TYPE_SIGNATURE ||
00053       type == DBUS_TYPE_OBJECT_PATH)
00054     {
00055       return strcmp (lhs->str, rhs->str) == 0;
00056     }
00057   else
00058     {
00059 #ifdef DBUS_HAVE_INT64
00060       return lhs->u64 == rhs->u64;
00061 #else
00062       return lhs->u64.first32 == rhs->u64.first32 &&
00063         lhs->u64.second32 == rhs->u64.second32;
00064 #endif
00065     }
00066 }
00067 
00068 static dbus_bool_t
00069 equal_values_helper (DBusTypeReader *lhs,
00070                      DBusTypeReader *rhs)
00071 {
00072   int lhs_type;
00073   int rhs_type;
00074 
00075   lhs_type = _dbus_type_reader_get_current_type (lhs);
00076   rhs_type = _dbus_type_reader_get_current_type (rhs);
00077 
00078   if (lhs_type != rhs_type)
00079     return FALSE;
00080 
00081   if (lhs_type == DBUS_TYPE_INVALID)
00082     return TRUE;
00083 
00084   if (dbus_type_is_basic (lhs_type))
00085     {
00086       DBusBasicValue lhs_value;
00087       DBusBasicValue rhs_value;
00088 
00089       basic_value_zero (&lhs_value);
00090       basic_value_zero (&rhs_value);
00091       
00092       _dbus_type_reader_read_basic (lhs, &lhs_value);
00093       _dbus_type_reader_read_basic (rhs, &rhs_value);
00094 
00095       return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
00096     }
00097   else
00098     {
00099       DBusTypeReader lhs_sub;
00100       DBusTypeReader rhs_sub;
00101 
00102       _dbus_type_reader_recurse (lhs, &lhs_sub);
00103       _dbus_type_reader_recurse (rhs, &rhs_sub);
00104 
00105       return equal_values_helper (&lhs_sub, &rhs_sub);
00106     }
00107 }
00108 
00116 dbus_bool_t
00117 _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
00118                                 const DBusTypeReader *rhs)
00119 {
00120   DBusTypeReader copy_lhs = *lhs;
00121   DBusTypeReader copy_rhs = *rhs;
00122 
00123   return equal_values_helper (©_lhs, ©_rhs);
00124 }
00125 
00126 
00127 
00128 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00129 
00130 #include "dbus-test.h"
00131 #include "dbus-list.h"
00132 #include <stdio.h>
00133 #include <stdlib.h>
00134 
00135 
00136 #define TEST_OOM_HANDLING 0
00137 
00138 
00139 
00140 #define MAX_INITIAL_OFFSET 9
00141 
00142 
00143 
00144 
00145 
00146 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
00147 
00148 typedef struct
00149 {
00150   int byte_order;
00151   int initial_offset;
00152   DBusString signature;
00153   DBusString body;
00154 } DataBlock;
00155 
00156 typedef struct
00157 {
00158   int saved_sig_len;
00159   int saved_body_len;
00160 } DataBlockState;
00161 
00162 #define N_FENCE_BYTES 5
00163 #define FENCE_BYTES_STR "abcde"
00164 #define INITIAL_PADDING_BYTE '\0'
00165 
00166 static dbus_bool_t
00167 data_block_init (DataBlock *block,
00168                  int        byte_order,
00169                  int        initial_offset)
00170 {
00171   if (!_dbus_string_init (&block->signature))
00172     return FALSE;
00173 
00174   if (!_dbus_string_init (&block->body))
00175     {
00176       _dbus_string_free (&block->signature);
00177       return FALSE;
00178     }
00179 
00180   if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
00181                                   INITIAL_PADDING_BYTE) ||
00182       !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
00183                                   INITIAL_PADDING_BYTE) ||
00184       !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
00185       !_dbus_string_append (&block->body, FENCE_BYTES_STR))
00186     {
00187       _dbus_string_free (&block->signature);
00188       _dbus_string_free (&block->body);
00189       return FALSE;
00190     }
00191 
00192   block->byte_order = byte_order;
00193   block->initial_offset = initial_offset;
00194 
00195   return TRUE;
00196 }
00197 
00198 static void
00199 data_block_save (DataBlock      *block,
00200                  DataBlockState *state)
00201 {
00202   state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
00203   state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
00204 }
00205 
00206 static void
00207 data_block_restore (DataBlock      *block,
00208                     DataBlockState *state)
00209 {
00210   _dbus_string_delete (&block->signature,
00211                        state->saved_sig_len,
00212                        _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
00213   _dbus_string_delete (&block->body,
00214                        state->saved_body_len,
00215                        _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
00216 }
00217 
00218 static void
00219 data_block_verify (DataBlock *block)
00220 {
00221   if (!_dbus_string_ends_with_c_str (&block->signature,
00222                                      FENCE_BYTES_STR))
00223     {
00224       int offset;
00225 
00226       offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
00227       if (offset < 0)
00228         offset = 0;
00229 
00230       _dbus_verbose_bytes_of_string (&block->signature,
00231                                      offset,
00232                                      _dbus_string_get_length (&block->signature) - offset);
00233       _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
00234     }
00235   if (!_dbus_string_ends_with_c_str (&block->body,
00236                                      FENCE_BYTES_STR))
00237     {
00238       int offset;
00239 
00240       offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
00241       if (offset < 0)
00242         offset = 0;
00243 
00244       _dbus_verbose_bytes_of_string (&block->body,
00245                                      offset,
00246                                      _dbus_string_get_length (&block->body) - offset);
00247       _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
00248     }
00249 
00250   _dbus_assert (_dbus_string_validate_nul (&block->signature,
00251                                            0, block->initial_offset));
00252   _dbus_assert (_dbus_string_validate_nul (&block->body,
00253                                            0, block->initial_offset));
00254 }
00255 
00256 static void
00257 data_block_free (DataBlock *block)
00258 {
00259   data_block_verify (block);
00260 
00261   _dbus_string_free (&block->signature);
00262   _dbus_string_free (&block->body);
00263 }
00264 
00265 static void
00266 data_block_reset (DataBlock *block)
00267 {
00268   data_block_verify (block);
00269 
00270   _dbus_string_delete (&block->signature,
00271                        block->initial_offset,
00272                        _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
00273   _dbus_string_delete (&block->body,
00274                        block->initial_offset,
00275                        _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
00276 
00277   data_block_verify (block);
00278 }
00279 
00280 static void
00281 data_block_init_reader_writer (DataBlock      *block,
00282                                DBusTypeReader *reader,
00283                                DBusTypeWriter *writer)
00284 {
00285   if (reader)
00286     _dbus_type_reader_init (reader,
00287                             block->byte_order,
00288                             &block->signature,
00289                             block->initial_offset,
00290                             &block->body,
00291                             block->initial_offset);
00292 
00293   if (writer)
00294     _dbus_type_writer_init (writer,
00295                             block->byte_order,
00296                             &block->signature,
00297                             _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
00298                             &block->body,
00299                             _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
00300 }
00301 
00302 static void
00303 real_check_expected_type (DBusTypeReader *reader,
00304                           int             expected,
00305                           const char     *funcname,
00306                           int             line)
00307 {
00308   int t;
00309 
00310   t = _dbus_type_reader_get_current_type (reader);
00311 
00312   if (t != expected)
00313     {
00314       _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
00315                   _dbus_type_to_string (t),
00316                   _dbus_type_to_string (expected),
00317                   funcname, line);
00318 
00319       _dbus_assert_not_reached ("read wrong type");
00320     }
00321 }
00322 
00323 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
00324 
00325 #define NEXT_EXPECTING_TRUE(reader)  do { if (!_dbus_type_reader_next (reader))         \
00326  {                                                                                      \
00327     _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n",        \
00328                               _DBUS_FUNCTION_NAME, __LINE__);                           \
00329     _dbus_assert_not_reached ("test failed");                                           \
00330  }                                                                                      \
00331 } while (0)
00332 
00333 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader))          \
00334  {                                                                                      \
00335     _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n",       \
00336                               _DBUS_FUNCTION_NAME, __LINE__);                           \
00337     _dbus_assert_not_reached ("test failed");                                           \
00338  }                                                                                      \
00339  check_expected_type (reader, DBUS_TYPE_INVALID);                                       \
00340 } while (0)
00341 
00342 typedef struct TestTypeNode               TestTypeNode;
00343 typedef struct TestTypeNodeClass          TestTypeNodeClass;
00344 typedef struct TestTypeNodeContainer      TestTypeNodeContainer;
00345 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
00346 
00347 struct TestTypeNode
00348 {
00349   const TestTypeNodeClass *klass;
00350 };
00351 
00352 struct TestTypeNodeContainer
00353 {
00354   TestTypeNode base;
00355   DBusList    *children;
00356 };
00357 
00358 struct TestTypeNodeClass
00359 {
00360   int typecode;
00361 
00362   int instance_size;
00363 
00364   int subclass_detail; 
00365 
00366   dbus_bool_t   (* construct)     (TestTypeNode   *node);
00367   void          (* destroy)       (TestTypeNode   *node);
00368 
00369   dbus_bool_t (* write_value)     (TestTypeNode   *node,
00370                                    DataBlock      *block,
00371                                    DBusTypeWriter *writer,
00372                                    int             seed);
00373   dbus_bool_t (* read_value)      (TestTypeNode   *node,
00374                                    DBusTypeReader *reader,
00375                                    int             seed);
00376   dbus_bool_t (* set_value)       (TestTypeNode   *node,
00377                                    DBusTypeReader *reader,
00378                                    DBusTypeReader *realign_root,
00379                                    int             seed);
00380   dbus_bool_t (* build_signature) (TestTypeNode   *node,
00381                                    DBusString     *str);
00382   dbus_bool_t (* write_multi)     (TestTypeNode   *node,
00383                                    DataBlock      *block,
00384                                    DBusTypeWriter *writer,
00385                                    int             seed,
00386                                    int             count);
00387   dbus_bool_t (* read_multi)      (TestTypeNode   *node,
00388                                    DBusTypeReader *reader,
00389                                    int             seed,
00390                                    int             count);
00391 };
00392 
00393 struct TestTypeNodeContainerClass
00394 {
00395   TestTypeNodeClass base;
00396 };
00397 
00398 
00399 
00400 
00401 
00402 
00403 static dbus_bool_t int16_write_value       (TestTypeNode   *node,
00404                                             DataBlock      *block,
00405                                             DBusTypeWriter *writer,
00406                                             int             seed);
00407 static dbus_bool_t int16_read_value        (TestTypeNode   *node,
00408                                             DBusTypeReader *reader,
00409                                             int             seed);
00410 static dbus_bool_t int16_set_value         (TestTypeNode   *node,
00411                                             DBusTypeReader *reader,
00412                                             DBusTypeReader *realign_root,
00413                                             int             seed);
00414 static dbus_bool_t int16_write_multi       (TestTypeNode   *node,
00415                                             DataBlock      *block,
00416                                             DBusTypeWriter *writer,
00417                                             int             seed,
00418                                             int             count);
00419 static dbus_bool_t int16_read_multi        (TestTypeNode   *node,
00420                                             DBusTypeReader *reader,
00421                                             int             seed,
00422                                             int             count);
00423 static dbus_bool_t int32_write_value       (TestTypeNode   *node,
00424                                             DataBlock      *block,
00425                                             DBusTypeWriter *writer,
00426                                             int             seed);
00427 static dbus_bool_t int32_read_value        (TestTypeNode   *node,
00428                                             DBusTypeReader *reader,
00429                                             int             seed);
00430 static dbus_bool_t int32_set_value         (TestTypeNode   *node,
00431                                             DBusTypeReader *reader,
00432                                             DBusTypeReader *realign_root,
00433                                             int             seed);
00434 static dbus_bool_t int32_write_multi       (TestTypeNode   *node,
00435                                             DataBlock      *block,
00436                                             DBusTypeWriter *writer,
00437                                             int             seed,
00438                                             int             count);
00439 static dbus_bool_t int32_read_multi        (TestTypeNode   *node,
00440                                             DBusTypeReader *reader,
00441                                             int             seed,
00442                                             int             count);
00443 static dbus_bool_t int64_write_value       (TestTypeNode   *node,
00444                                             DataBlock      *block,
00445                                             DBusTypeWriter *writer,
00446                                             int             seed);
00447 static dbus_bool_t int64_read_value        (TestTypeNode   *node,
00448                                             DBusTypeReader *reader,
00449                                             int             seed);
00450 static dbus_bool_t int64_set_value         (TestTypeNode   *node,
00451                                             DBusTypeReader *reader,
00452                                             DBusTypeReader *realign_root,
00453                                             int             seed);
00454 static dbus_bool_t string_write_value      (TestTypeNode   *node,
00455                                             DataBlock      *block,
00456                                             DBusTypeWriter *writer,
00457                                             int             seed);
00458 static dbus_bool_t string_read_value       (TestTypeNode   *node,
00459                                             DBusTypeReader *reader,
00460                                             int             seed);
00461 static dbus_bool_t string_set_value        (TestTypeNode   *node,
00462                                             DBusTypeReader *reader,
00463                                             DBusTypeReader *realign_root,
00464                                             int             seed);
00465 static dbus_bool_t bool_write_value        (TestTypeNode   *node,
00466                                             DataBlock      *block,
00467                                             DBusTypeWriter *writer,
00468                                             int             seed);
00469 static dbus_bool_t bool_read_value         (TestTypeNode   *node,
00470                                             DBusTypeReader *reader,
00471                                             int             seed);
00472 static dbus_bool_t bool_set_value          (TestTypeNode   *node,
00473                                             DBusTypeReader *reader,
00474                                             DBusTypeReader *realign_root,
00475                                             int             seed);
00476 static dbus_bool_t byte_write_value        (TestTypeNode   *node,
00477                                             DataBlock      *block,
00478                                             DBusTypeWriter *writer,
00479                                             int             seed);
00480 static dbus_bool_t byte_read_value         (TestTypeNode   *node,
00481                                             DBusTypeReader *reader,
00482                                             int             seed);
00483 static dbus_bool_t byte_set_value          (TestTypeNode   *node,
00484                                             DBusTypeReader *reader,
00485                                             DBusTypeReader *realign_root,
00486                                             int             seed);
00487 static dbus_bool_t double_write_value      (TestTypeNode   *node,
00488                                             DataBlock      *block,
00489                                             DBusTypeWriter *writer,
00490                                             int             seed);
00491 static dbus_bool_t double_read_value       (TestTypeNode   *node,
00492                                             DBusTypeReader *reader,
00493                                             int             seed);
00494 static dbus_bool_t double_set_value        (TestTypeNode   *node,
00495                                             DBusTypeReader *reader,
00496                                             DBusTypeReader *realign_root,
00497                                             int             seed);
00498 static dbus_bool_t object_path_write_value (TestTypeNode   *node,
00499                                             DataBlock      *block,
00500                                             DBusTypeWriter *writer,
00501                                             int             seed);
00502 static dbus_bool_t object_path_read_value  (TestTypeNode   *node,
00503                                             DBusTypeReader *reader,
00504                                             int             seed);
00505 static dbus_bool_t object_path_set_value   (TestTypeNode   *node,
00506                                             DBusTypeReader *reader,
00507                                             DBusTypeReader *realign_root,
00508                                             int             seed);
00509 static dbus_bool_t signature_write_value   (TestTypeNode   *node,
00510                                             DataBlock      *block,
00511                                             DBusTypeWriter *writer,
00512                                             int             seed);
00513 static dbus_bool_t signature_read_value    (TestTypeNode   *node,
00514                                             DBusTypeReader *reader,
00515                                             int             seed);
00516 static dbus_bool_t signature_set_value     (TestTypeNode   *node,
00517                                             DBusTypeReader *reader,
00518                                             DBusTypeReader *realign_root,
00519                                             int             seed);
00520 static dbus_bool_t struct_write_value      (TestTypeNode   *node,
00521                                             DataBlock      *block,
00522                                             DBusTypeWriter *writer,
00523                                             int             seed);
00524 static dbus_bool_t struct_read_value       (TestTypeNode   *node,
00525                                             DBusTypeReader *reader,
00526                                             int             seed);
00527 static dbus_bool_t struct_set_value        (TestTypeNode   *node,
00528                                             DBusTypeReader *reader,
00529                                             DBusTypeReader *realign_root,
00530                                             int             seed);
00531 static dbus_bool_t struct_build_signature  (TestTypeNode   *node,
00532                                             DBusString     *str);
00533 static dbus_bool_t dict_write_value        (TestTypeNode   *node,
00534                                             DataBlock      *block,
00535                                             DBusTypeWriter *writer,
00536                                             int             seed);
00537 static dbus_bool_t dict_read_value         (TestTypeNode   *node,
00538                                             DBusTypeReader *reader,
00539                                             int             seed);
00540 static dbus_bool_t dict_set_value          (TestTypeNode   *node,
00541                                             DBusTypeReader *reader,
00542                                             DBusTypeReader *realign_root,
00543                                             int             seed);
00544 static dbus_bool_t dict_build_signature    (TestTypeNode   *node,
00545                                             DBusString     *str);
00546 static dbus_bool_t array_write_value       (TestTypeNode   *node,
00547                                             DataBlock      *block,
00548                                             DBusTypeWriter *writer,
00549                                             int             seed);
00550 static dbus_bool_t array_read_value        (TestTypeNode   *node,
00551                                             DBusTypeReader *reader,
00552                                             int             seed);
00553 static dbus_bool_t array_set_value         (TestTypeNode   *node,
00554                                             DBusTypeReader *reader,
00555                                             DBusTypeReader *realign_root,
00556                                             int             seed);
00557 static dbus_bool_t array_build_signature   (TestTypeNode   *node,
00558                                             DBusString     *str);
00559 static dbus_bool_t variant_write_value     (TestTypeNode   *node,
00560                                             DataBlock      *block,
00561                                             DBusTypeWriter *writer,
00562                                             int             seed);
00563 static dbus_bool_t variant_read_value      (TestTypeNode   *node,
00564                                             DBusTypeReader *reader,
00565                                             int             seed);
00566 static dbus_bool_t variant_set_value       (TestTypeNode   *node,
00567                                             DBusTypeReader *reader,
00568                                             DBusTypeReader *realign_root,
00569                                             int             seed);
00570 static void        container_destroy       (TestTypeNode   *node);
00571 
00572 
00573 
00574 static const TestTypeNodeClass int16_class = {
00575   DBUS_TYPE_INT16,
00576   sizeof (TestTypeNode),
00577   0,
00578   NULL,
00579   NULL,
00580   int16_write_value,
00581   int16_read_value,
00582   int16_set_value,
00583   NULL,
00584   int16_write_multi,
00585   int16_read_multi
00586 };
00587 
00588 static const TestTypeNodeClass uint16_class = {
00589   DBUS_TYPE_UINT16,
00590   sizeof (TestTypeNode),
00591   0,
00592   NULL,
00593   NULL,
00594   int16_write_value, 
00595   int16_read_value,  
00596   int16_set_value,   
00597   NULL,
00598   int16_write_multi, 
00599   int16_read_multi   
00600 };
00601 
00602 static const TestTypeNodeClass int32_class = {
00603   DBUS_TYPE_INT32,
00604   sizeof (TestTypeNode),
00605   0,
00606   NULL,
00607   NULL,
00608   int32_write_value,
00609   int32_read_value,
00610   int32_set_value,
00611   NULL,
00612   int32_write_multi,
00613   int32_read_multi
00614 };
00615 
00616 static const TestTypeNodeClass uint32_class = {
00617   DBUS_TYPE_UINT32,
00618   sizeof (TestTypeNode),
00619   0,
00620   NULL,
00621   NULL,
00622   int32_write_value, 
00623   int32_read_value,  
00624   int32_set_value,   
00625   NULL,
00626   int32_write_multi, 
00627   int32_read_multi   
00628 };
00629 
00630 static const TestTypeNodeClass int64_class = {
00631   DBUS_TYPE_INT64,
00632   sizeof (TestTypeNode),
00633   0,
00634   NULL,
00635   NULL,
00636   int64_write_value,
00637   int64_read_value,
00638   int64_set_value,
00639   NULL,
00640   NULL, 
00641   NULL  
00642 };
00643 
00644 static const TestTypeNodeClass uint64_class = {
00645   DBUS_TYPE_UINT64,
00646   sizeof (TestTypeNode),
00647   0,
00648   NULL,
00649   NULL,
00650   int64_write_value, 
00651   int64_read_value,  
00652   int64_set_value,   
00653   NULL,
00654   NULL, 
00655   NULL  
00656 };
00657 
00658 static const TestTypeNodeClass string_0_class = {
00659   DBUS_TYPE_STRING,
00660   sizeof (TestTypeNode),
00661   0, 
00662   NULL,
00663   NULL,
00664   string_write_value,
00665   string_read_value,
00666   string_set_value,
00667   NULL,
00668   NULL,
00669   NULL
00670 };
00671 
00672 static const TestTypeNodeClass string_1_class = {
00673   DBUS_TYPE_STRING,
00674   sizeof (TestTypeNode),
00675   1, 
00676   NULL,
00677   NULL,
00678   string_write_value,
00679   string_read_value,
00680   string_set_value,
00681   NULL,
00682   NULL,
00683   NULL
00684 };
00685 
00686 
00687 static const TestTypeNodeClass string_3_class = {
00688   DBUS_TYPE_STRING,
00689   sizeof (TestTypeNode),
00690   3, 
00691   NULL,
00692   NULL,
00693   string_write_value,
00694   string_read_value,
00695   string_set_value,
00696   NULL,
00697   NULL,
00698   NULL
00699 };
00700 
00701 
00702 static const TestTypeNodeClass string_8_class = {
00703   DBUS_TYPE_STRING,
00704   sizeof (TestTypeNode),
00705   8, 
00706   NULL,
00707   NULL,
00708   string_write_value,
00709   string_read_value,
00710   string_set_value,
00711   NULL,
00712   NULL,
00713   NULL
00714 };
00715 
00716 static const TestTypeNodeClass bool_class = {
00717   DBUS_TYPE_BOOLEAN,
00718   sizeof (TestTypeNode),
00719   0,
00720   NULL,
00721   NULL,
00722   bool_write_value,
00723   bool_read_value,
00724   bool_set_value,
00725   NULL,
00726   NULL, 
00727   NULL  
00728 };
00729 
00730 static const TestTypeNodeClass byte_class = {
00731   DBUS_TYPE_BYTE,
00732   sizeof (TestTypeNode),
00733   0,
00734   NULL,
00735   NULL,
00736   byte_write_value,
00737   byte_read_value,
00738   byte_set_value,
00739   NULL,
00740   NULL, 
00741   NULL  
00742 };
00743 
00744 static const TestTypeNodeClass double_class = {
00745   DBUS_TYPE_DOUBLE,
00746   sizeof (TestTypeNode),
00747   0,
00748   NULL,
00749   NULL,
00750   double_write_value,
00751   double_read_value,
00752   double_set_value,
00753   NULL,
00754   NULL, 
00755   NULL  
00756 };
00757 
00758 static const TestTypeNodeClass object_path_class = {
00759   DBUS_TYPE_OBJECT_PATH,
00760   sizeof (TestTypeNode),
00761   0,
00762   NULL,
00763   NULL,
00764   object_path_write_value,
00765   object_path_read_value,
00766   object_path_set_value,
00767   NULL,
00768   NULL,
00769   NULL
00770 };
00771 
00772 static const TestTypeNodeClass signature_class = {
00773   DBUS_TYPE_SIGNATURE,
00774   sizeof (TestTypeNode),
00775   0,
00776   NULL,
00777   NULL,
00778   signature_write_value,
00779   signature_read_value,
00780   signature_set_value,
00781   NULL,
00782   NULL,
00783   NULL
00784 };
00785 
00786 static const TestTypeNodeClass struct_1_class = {
00787   DBUS_TYPE_STRUCT,
00788   sizeof (TestTypeNodeContainer),
00789   1, 
00790   NULL,
00791   container_destroy,
00792   struct_write_value,
00793   struct_read_value,
00794   struct_set_value,
00795   struct_build_signature,
00796   NULL,
00797   NULL
00798 };
00799 
00800 static const TestTypeNodeClass struct_2_class = {
00801   DBUS_TYPE_STRUCT,
00802   sizeof (TestTypeNodeContainer),
00803   2, 
00804   NULL,
00805   container_destroy,
00806   struct_write_value,
00807   struct_read_value,
00808   struct_set_value,
00809   struct_build_signature,
00810   NULL,
00811   NULL
00812 };
00813 
00814 static const TestTypeNodeClass dict_1_class = {
00815   DBUS_TYPE_ARRAY, 
00816   sizeof (TestTypeNodeContainer),
00817   1, 
00818   NULL,
00819   container_destroy,
00820   dict_write_value,
00821   dict_read_value,
00822   dict_set_value,
00823   dict_build_signature,
00824   NULL,
00825   NULL
00826 };
00827 
00828 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
00829 
00830 static const TestTypeNodeClass array_0_class = {
00831   DBUS_TYPE_ARRAY,
00832   sizeof (TestTypeNodeContainer),
00833   0, 
00834   NULL,
00835   container_destroy,
00836   array_write_value,
00837   array_read_value,
00838   array_set_value,
00839   array_build_signature,
00840   NULL,
00841   NULL
00842 };
00843 
00844 static const TestTypeNodeClass array_1_class = {
00845   DBUS_TYPE_ARRAY,
00846   sizeof (TestTypeNodeContainer),
00847   1, 
00848   NULL,
00849   container_destroy,
00850   array_write_value,
00851   array_read_value,
00852   array_set_value,
00853   array_build_signature,
00854   NULL,
00855   NULL
00856 };
00857 
00858 static const TestTypeNodeClass array_2_class = {
00859   DBUS_TYPE_ARRAY,
00860   sizeof (TestTypeNodeContainer),
00861   2, 
00862   NULL,
00863   container_destroy,
00864   array_write_value,
00865   array_read_value,
00866   array_set_value,
00867   array_build_signature,
00868   NULL,
00869   NULL
00870 };
00871 
00872 static const TestTypeNodeClass array_9_class = {
00873   DBUS_TYPE_ARRAY,
00874   sizeof (TestTypeNodeContainer),
00875   9, 
00876   NULL,
00877   container_destroy,
00878   array_write_value,
00879   array_read_value,
00880   array_set_value,
00881   array_build_signature,
00882   NULL,
00883   NULL
00884 };
00885 
00886 static const TestTypeNodeClass variant_class = {
00887   DBUS_TYPE_VARIANT,
00888   sizeof (TestTypeNodeContainer),
00889   0,
00890   NULL,
00891   container_destroy,
00892   variant_write_value,
00893   variant_read_value,
00894   variant_set_value,
00895   NULL,
00896   NULL,
00897   NULL
00898 };
00899 
00900 static const TestTypeNodeClass* const
00901 basic_nodes[] = {
00902   &int16_class,
00903   &uint16_class,
00904   &int32_class,
00905   &uint32_class,
00906   &int64_class,
00907   &uint64_class,
00908   &bool_class,
00909   &byte_class,
00910   &double_class,
00911   &string_0_class,
00912   &string_1_class,
00913   &string_3_class,
00914   &string_8_class,
00915   &object_path_class,
00916   &signature_class
00917 };
00918 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
00919 
00920 static const TestTypeNodeClass* const
00921 container_nodes[] = {
00922   &struct_1_class,
00923   &array_1_class,
00924   &struct_2_class,
00925   &array_0_class,
00926   &array_2_class,
00927   &variant_class,
00928   &dict_1_class 
00929   
00930 
00931 
00932 };
00933 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
00934 
00935 static TestTypeNode*
00936 node_new (const TestTypeNodeClass *klass)
00937 {
00938   TestTypeNode *node;
00939 
00940   node = dbus_malloc0 (klass->instance_size);
00941   if (node == NULL)
00942     return NULL;
00943 
00944   node->klass = klass;
00945 
00946   if (klass->construct)
00947     {
00948       if (!(* klass->construct) (node))
00949         {
00950           dbus_free (node);
00951           return NULL;
00952         }
00953     }
00954 
00955   return node;
00956 }
00957 
00958 static void
00959 node_destroy (TestTypeNode *node)
00960 {
00961   if (node->klass->destroy)
00962     (* node->klass->destroy) (node);
00963   dbus_free (node);
00964 }
00965 
00966 static dbus_bool_t
00967 node_write_value (TestTypeNode   *node,
00968                   DataBlock      *block,
00969                   DBusTypeWriter *writer,
00970                   int             seed)
00971 {
00972   dbus_bool_t retval;
00973 
00974   retval = (* node->klass->write_value) (node, block, writer, seed);
00975 
00976 #if 0
00977   
00978   data_block_verify (block);
00979 #endif
00980 
00981   return retval;
00982 }
00983 
00984 static dbus_bool_t
00985 node_read_value (TestTypeNode   *node,
00986                  DBusTypeReader *reader,
00987                  int             seed)
00988 {
00989   DBusTypeReader restored;
00990 
00991   if (!(* node->klass->read_value) (node, reader, seed))
00992     return FALSE;
00993 
00994   return TRUE;
00995 }
00996 
00997 
00998 
00999 
01000 
01001 static dbus_bool_t
01002 node_set_value (TestTypeNode   *node,
01003                 DBusTypeReader *reader,
01004                 DBusTypeReader *realign_root,
01005                 int             seed)
01006 {
01007   if (!(* node->klass->set_value) (node, reader, realign_root, seed))
01008     return FALSE;
01009 
01010   return TRUE;
01011 }
01012 
01013 static dbus_bool_t
01014 node_build_signature (TestTypeNode *node,
01015                       DBusString   *str)
01016 {
01017   if (node->klass->build_signature)
01018     return (* node->klass->build_signature) (node, str);
01019   else
01020     return _dbus_string_append_byte (str, node->klass->typecode);
01021 }
01022 
01023 static dbus_bool_t
01024 node_append_child (TestTypeNode *node,
01025                    TestTypeNode *child)
01026 {
01027   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01028 
01029   _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
01030 
01031   if (!_dbus_list_append (&container->children, child))
01032     _dbus_assert_not_reached ("no memory"); 
01033 
01034   return TRUE;
01035 }
01036 
01037 static dbus_bool_t
01038 node_write_multi (TestTypeNode   *node,
01039                   DataBlock      *block,
01040                   DBusTypeWriter *writer,
01041                   int             seed,
01042                   int             n_copies)
01043 {
01044   dbus_bool_t retval;
01045 
01046   _dbus_assert (node->klass->write_multi != NULL);
01047   retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
01048 
01049 #if 0
01050   
01051   data_block_verify (block);
01052 #endif
01053 
01054   return retval;
01055 }
01056 
01057 static dbus_bool_t
01058 node_read_multi (TestTypeNode   *node,
01059                  DBusTypeReader *reader,
01060                  int             seed,
01061                  int             n_copies)
01062 {
01063   _dbus_assert (node->klass->read_multi != NULL);
01064 
01065   if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
01066     return FALSE;
01067 
01068   return TRUE;
01069 }
01070 
01071 static int n_iterations_completed_total = 0;
01072 static int n_iterations_completed_this_test = 0;
01073 static int n_iterations_expected_this_test = 0;
01074 
01075 typedef struct
01076 {
01077   const DBusString   *signature;
01078   DataBlock          *block;
01079   int                 type_offset;
01080   TestTypeNode      **nodes;
01081   int                 n_nodes;
01082 } NodeIterationData;
01083 
01084 static dbus_bool_t
01085 run_test_copy (NodeIterationData *nid)
01086 {
01087   DataBlock *src;
01088   DataBlock dest;
01089   dbus_bool_t retval;
01090   DBusTypeReader reader;
01091   DBusTypeWriter writer;
01092 
01093   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01094 
01095   src = nid->block;
01096 
01097   retval = FALSE;
01098 
01099   if (!data_block_init (&dest, src->byte_order, src->initial_offset))
01100     return FALSE;
01101 
01102   data_block_init_reader_writer (src, &reader, NULL);
01103   data_block_init_reader_writer (&dest, NULL, &writer);
01104 
01105   
01106 
01107 
01108   if (!_dbus_string_insert_byte (&dest.signature,
01109                                  dest.initial_offset, '\0'))
01110     goto out;
01111 
01112   if (!_dbus_type_writer_write_reader (&writer, &reader))
01113     goto out;
01114 
01115   
01116   if (!_dbus_string_equal (&src->signature, &dest.signature))
01117     {
01118       _dbus_verbose ("SOURCE\n");
01119       _dbus_verbose_bytes_of_string (&src->signature, 0,
01120                                      _dbus_string_get_length (&src->signature));
01121       _dbus_verbose ("DEST\n");
01122       _dbus_verbose_bytes_of_string (&dest.signature, 0,
01123                                      _dbus_string_get_length (&dest.signature));
01124       _dbus_assert_not_reached ("signatures did not match");
01125     }
01126 
01127   if (!_dbus_string_equal (&src->body, &dest.body))
01128     {
01129       _dbus_verbose ("SOURCE\n");
01130       _dbus_verbose_bytes_of_string (&src->body, 0,
01131                                      _dbus_string_get_length (&src->body));
01132       _dbus_verbose ("DEST\n");
01133       _dbus_verbose_bytes_of_string (&dest.body, 0,
01134                                      _dbus_string_get_length (&dest.body));
01135       _dbus_assert_not_reached ("bodies did not match");
01136     }
01137 
01138   retval = TRUE;
01139 
01140  out:
01141 
01142   data_block_free (&dest);
01143 
01144   return retval;
01145 }
01146 
01147 static dbus_bool_t
01148 run_test_values_only_write (NodeIterationData *nid)
01149 {
01150   DBusTypeReader reader;
01151   DBusTypeWriter writer;
01152   int i;
01153   dbus_bool_t retval;
01154   int sig_len;
01155 
01156   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01157 
01158   retval = FALSE;
01159 
01160   data_block_reset (nid->block);
01161 
01162   sig_len = _dbus_string_get_length (nid->signature);
01163 
01164   _dbus_type_writer_init_values_only (&writer,
01165                                       nid->block->byte_order,
01166                                       nid->signature, 0,
01167                                       &nid->block->body,
01168                                       _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
01169   _dbus_type_reader_init (&reader,
01170                           nid->block->byte_order,
01171                           nid->signature, 0,
01172                           &nid->block->body,
01173                           nid->block->initial_offset);
01174 
01175   i = 0;
01176   while (i < nid->n_nodes)
01177     {
01178       if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
01179         goto out;
01180 
01181       ++i;
01182     }
01183 
01184   
01185   _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
01186 
01187   
01188   i = 0;
01189   while (i < nid->n_nodes)
01190     {
01191       if (!node_read_value (nid->nodes[i], &reader, i))
01192         goto out;
01193 
01194       if (i + 1 == nid->n_nodes)
01195         NEXT_EXPECTING_FALSE (&reader);
01196       else
01197         NEXT_EXPECTING_TRUE (&reader);
01198 
01199       ++i;
01200     }
01201 
01202   retval = TRUE;
01203 
01204  out:
01205   data_block_reset (nid->block);
01206   return retval;
01207 }
01208 
01209 
01210 
01211 
01212 
01213 
01214 
01215 #define SET_SEED 1
01216 static dbus_bool_t
01217 run_test_set_values (NodeIterationData *nid)
01218 {
01219   DBusTypeReader reader;
01220   DBusTypeReader realign_root;
01221   dbus_bool_t retval;
01222   int i;
01223 
01224   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01225 
01226   retval = FALSE;
01227 
01228   data_block_init_reader_writer (nid->block,
01229                                  &reader, NULL);
01230 
01231   realign_root = reader;
01232 
01233   i = 0;
01234   while (i < nid->n_nodes)
01235     {
01236       if (!node_set_value (nid->nodes[i],
01237                            &reader, &realign_root,
01238                            i + SET_SEED))
01239         goto out;
01240 
01241       if (i + 1 == nid->n_nodes)
01242         NEXT_EXPECTING_FALSE (&reader);
01243       else
01244         NEXT_EXPECTING_TRUE (&reader);
01245 
01246       ++i;
01247     }
01248 
01249   
01250 
01251   reader = realign_root;
01252 
01253   i = 0;
01254   while (i < nid->n_nodes)
01255     {
01256       if (!node_read_value (nid->nodes[i], &reader,
01257                             i + SET_SEED))
01258         goto out;
01259 
01260       if (i + 1 == nid->n_nodes)
01261         NEXT_EXPECTING_FALSE (&reader);
01262       else
01263         NEXT_EXPECTING_TRUE (&reader);
01264 
01265       ++i;
01266     }
01267 
01268   retval = TRUE;
01269 
01270  out:
01271   return retval;
01272 }
01273 
01274 static dbus_bool_t
01275 run_test_delete_values (NodeIterationData *nid)
01276 {
01277   DBusTypeReader reader;
01278   dbus_bool_t retval;
01279   int t;
01280 
01281   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01282 
01283   retval = FALSE;
01284 
01285   data_block_init_reader_writer (nid->block,
01286                                  &reader, NULL);
01287 
01288   while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
01289     {
01290       
01291 
01292 
01293 
01294       if (t == DBUS_TYPE_ARRAY)
01295         {
01296           DBusTypeReader array;
01297           int n_elements;
01298           int elem_type;
01299 
01300           _dbus_type_reader_recurse (&reader, &array);
01301           n_elements = 0;
01302           while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
01303             {
01304               n_elements += 1;
01305               _dbus_type_reader_next (&array);
01306             }
01307 
01308           
01309           _dbus_type_reader_recurse (&reader, &array);
01310           _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
01311                          reader.value_pos, array.value_pos, array.u.array.start_pos);
01312           while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
01313             {
01314               
01315               static int cycle = 0;
01316               int elem;
01317 
01318               _dbus_assert (n_elements > 0);
01319 
01320               elem = cycle;
01321               if (elem == 3 || elem >= n_elements) 
01322                 elem = n_elements - 1;
01323 
01324               _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
01325                              elem, n_elements, _dbus_type_to_string (elem_type),
01326                              cycle, reader.value_pos, array.value_pos);
01327               while (elem > 0)
01328                 {
01329                   if (!_dbus_type_reader_next (&array))
01330                     _dbus_assert_not_reached ("should have had another element\n");
01331                   --elem;
01332                 }
01333 
01334               if (!_dbus_type_reader_delete (&array, &reader))
01335                 goto out;
01336 
01337               n_elements -= 1;
01338 
01339               
01340               _dbus_type_reader_recurse (&reader, &array);
01341 
01342               if (cycle > 2)
01343                 cycle = 0;
01344               else
01345                 cycle += 1;
01346             }
01347         }
01348       _dbus_type_reader_next (&reader);
01349     }
01350 
01351   
01352   data_block_init_reader_writer (nid->block,
01353                                  &reader, NULL);
01354 
01355   while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
01356     {
01357       _dbus_type_reader_next (&reader);
01358     }
01359 
01360   retval = TRUE;
01361 
01362  out:
01363   return retval;
01364 }
01365 
01366 static dbus_bool_t
01367 run_test_nodes_iteration (void *data)
01368 {
01369   NodeIterationData *nid = data;
01370   DBusTypeReader reader;
01371   DBusTypeWriter writer;
01372   int i;
01373   dbus_bool_t retval;
01374 
01375   
01376 
01377 
01378 
01379 
01380 
01381   retval = FALSE;
01382 
01383   data_block_init_reader_writer (nid->block,
01384                                  &reader, &writer);
01385 
01386   
01387 
01388 
01389   if (!_dbus_string_insert_byte (&nid->block->signature,
01390                                  nid->type_offset, '\0'))
01391     goto out;
01392 
01393   i = 0;
01394   while (i < nid->n_nodes)
01395     {
01396       if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
01397         goto out;
01398 
01399       ++i;
01400     }
01401 
01402   if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
01403                                      &nid->block->signature, nid->type_offset))
01404     {
01405       _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
01406                   _dbus_string_get_const_data (nid->signature),
01407                   _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
01408                   nid->type_offset);
01409       _dbus_assert_not_reached ("wrong signature");
01410     }
01411 
01412   i = 0;
01413   while (i < nid->n_nodes)
01414     {
01415       if (!node_read_value (nid->nodes[i], &reader, i))
01416         goto out;
01417 
01418       if (i + 1 == nid->n_nodes)
01419         NEXT_EXPECTING_FALSE (&reader);
01420       else
01421         NEXT_EXPECTING_TRUE (&reader);
01422 
01423       ++i;
01424     }
01425 
01426   if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
01427     {
01428       
01429 
01430 
01431 
01432 
01433 
01434 
01435       if (!run_test_set_values (nid))
01436         goto out;
01437 
01438       if (!run_test_delete_values (nid))
01439         goto out;
01440 
01441       if (!run_test_copy (nid))
01442         goto out;
01443 
01444       if (!run_test_values_only_write (nid))
01445         goto out;
01446     }
01447 
01448   
01449 
01450 
01451 
01452   retval = TRUE;
01453 
01454  out:
01455 
01456   data_block_reset (nid->block);
01457 
01458   return retval;
01459 }
01460 
01461 static void
01462 run_test_nodes_in_one_configuration (TestTypeNode    **nodes,
01463                                      int               n_nodes,
01464                                      const DBusString *signature,
01465                                      int               byte_order,
01466                                      int               initial_offset)
01467 {
01468   DataBlock block;
01469   NodeIterationData nid;
01470 
01471   if (!data_block_init (&block, byte_order, initial_offset))
01472     _dbus_assert_not_reached ("no memory");
01473 
01474   nid.signature = signature;
01475   nid.block = █
01476   nid.type_offset = initial_offset;
01477   nid.nodes = nodes;
01478   nid.n_nodes = n_nodes;
01479 
01480   if (TEST_OOM_HANDLING &&
01481       n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
01482     {
01483       _dbus_test_oom_handling ("running test node",
01484                                run_test_nodes_iteration,
01485                                &nid);
01486     }
01487   else
01488     {
01489       if (!run_test_nodes_iteration (&nid))
01490         _dbus_assert_not_reached ("no memory");
01491     }
01492 
01493   data_block_free (&block);
01494 }
01495 
01496 static void
01497 run_test_nodes (TestTypeNode **nodes,
01498                 int            n_nodes)
01499 {
01500   int i;
01501   DBusString signature;
01502 
01503   if (!_dbus_string_init (&signature))
01504     _dbus_assert_not_reached ("no memory");
01505 
01506   i = 0;
01507   while (i < n_nodes)
01508     {
01509       if (! node_build_signature (nodes[i], &signature))
01510         _dbus_assert_not_reached ("no memory");
01511 
01512       ++i;
01513     }
01514 
01515   _dbus_verbose (">>> test nodes with signature '%s'\n",
01516                  _dbus_string_get_const_data (&signature));
01517 
01518   i = 0;
01519   while (i <= MAX_INITIAL_OFFSET)
01520     {
01521       run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
01522                                            DBUS_LITTLE_ENDIAN, i);
01523       run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
01524                                            DBUS_BIG_ENDIAN, i);
01525 
01526       ++i;
01527     }
01528 
01529   n_iterations_completed_this_test += 1;
01530   n_iterations_completed_total += 1;
01531 
01532   if (n_iterations_completed_this_test == n_iterations_expected_this_test)
01533     {
01534       fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
01535                n_iterations_completed_this_test,
01536                n_iterations_completed_total);
01537     }
01538   
01539   else if ((n_iterations_completed_this_test %
01540             (int)(n_iterations_expected_this_test / 10.0)) == 1)
01541     {
01542       fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
01543     }
01544 
01545   _dbus_string_free (&signature);
01546 }
01547 
01548 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
01549 
01550 static TestTypeNode*
01551 value_generator (int *ip)
01552 {
01553   int i = *ip;
01554   const TestTypeNodeClass *child_klass;
01555   const TestTypeNodeClass *container_klass;
01556   TestTypeNode *child;
01557   TestTypeNode *node;
01558 
01559   _dbus_assert (i <= N_VALUES);
01560 
01561   if (i == N_VALUES)
01562     {
01563       return NULL;
01564     }
01565   else if (i < N_BASICS)
01566     {
01567       node = node_new (basic_nodes[i]);
01568     }
01569   else
01570     {
01571       
01572 
01573 
01574 
01575 
01576 
01577 
01578 
01579       i -= N_BASICS;
01580 
01581       container_klass = container_nodes[i / N_BASICS];
01582       child_klass = basic_nodes[i % N_BASICS];
01583 
01584       node = node_new (container_klass);
01585       child = node_new (child_klass);
01586 
01587       node_append_child (node, child);
01588     }
01589 
01590   *ip += 1; 
01591 
01592   return node;
01593 }
01594 
01595 static void
01596 build_body (TestTypeNode **nodes,
01597             int            n_nodes,
01598             int            byte_order,
01599             DBusString    *signature,
01600             DBusString    *body)
01601 {
01602   int i;
01603   DataBlock block;
01604   DBusTypeReader reader;
01605   DBusTypeWriter writer;
01606 
01607   i = 0;
01608   while (i < n_nodes)
01609     {
01610       if (! node_build_signature (nodes[i], signature))
01611         _dbus_assert_not_reached ("no memory");
01612       
01613       ++i;
01614     }
01615 
01616   if (!data_block_init (&block, byte_order, 0))
01617     _dbus_assert_not_reached ("no memory");
01618   
01619   data_block_init_reader_writer (&block,
01620                                  &reader, &writer);
01621   
01622   
01623 
01624 
01625   if (!_dbus_string_insert_byte (&block.signature,
01626                                  0, '\0'))
01627     _dbus_assert_not_reached ("no memory");
01628 
01629   i = 0;
01630   while (i < n_nodes)
01631     {
01632       if (!node_write_value (nodes[i], &block, &writer, i))
01633         _dbus_assert_not_reached ("no memory");
01634 
01635       ++i;
01636     }
01637 
01638   if (!_dbus_string_copy_len (&block.body, 0,
01639                               _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
01640                               body, 0))
01641     _dbus_assert_not_reached ("oom");
01642 
01643   data_block_free (&block);  
01644 }
01645 
01646 dbus_bool_t
01647 dbus_internal_do_not_use_generate_bodies (int           sequence,
01648                                           int           byte_order,
01649                                           DBusString   *signature,
01650                                           DBusString   *body)
01651 {
01652   TestTypeNode *nodes[1];
01653   int i;
01654   int n_nodes;
01655 
01656   nodes[0] = value_generator (&sequence);
01657 
01658   if (nodes[0] == NULL)
01659     return FALSE;
01660 
01661   n_nodes = 1;
01662   
01663   build_body (nodes, n_nodes, byte_order, signature, body);
01664 
01665 
01666   i = 0;
01667   while (i < n_nodes)
01668     {
01669       node_destroy (nodes[i]);
01670       ++i;
01671     }
01672   
01673   return TRUE;
01674 }
01675 
01676 static void
01677 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
01678                                       int                      n_nested)
01679 {
01680   TestTypeNode *root;
01681   TestTypeNode *container;
01682   TestTypeNode *child;
01683   int i;
01684 
01685   root = node_new (container_klass);
01686   container = root;
01687   for (i = 1; i < n_nested; i++)
01688     {
01689       child = node_new (container_klass);
01690       node_append_child (container, child);
01691       container = child;
01692     }
01693 
01694   
01695 
01696   i = 0;
01697   while ((child = value_generator (&i)))
01698     {
01699       node_append_child (container, child);
01700 
01701       run_test_nodes (&root, 1);
01702 
01703       _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
01704       node_destroy (child);
01705     }
01706 
01707   node_destroy (root);
01708 }
01709 
01710 static void
01711 start_next_test (const char *format,
01712                  int         expected)
01713 {
01714   n_iterations_completed_this_test = 0;
01715   n_iterations_expected_this_test = expected;
01716 
01717   fprintf (stderr, ">>> >>> ");
01718   fprintf (stderr, format,
01719            n_iterations_expected_this_test);
01720 }
01721 
01722 static void
01723 make_and_run_test_nodes (void)
01724 {
01725   int i, j, k, m;
01726 
01727   
01728 
01729 
01730 
01731 
01732 
01733 
01734   
01735 
01736 
01737 
01738 
01739 
01740 
01741 
01742   
01743 
01744 
01745 
01746 
01747 
01748   
01749 
01750 
01751 
01752 
01753   
01754 
01755 
01756 
01757   
01758 
01759   start_next_test ("Each value by itself %d iterations\n", N_VALUES);
01760   {
01761     TestTypeNode *node;
01762     i = 0;
01763     while ((node = value_generator (&i)))
01764       {
01765         run_test_nodes (&node, 1);
01766 
01767         node_destroy (node);
01768       }
01769   }
01770 
01771   start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
01772   arrays_write_fixed_in_blocks = TRUE;
01773   {
01774     TestTypeNode *node;
01775     i = 0;
01776     while ((node = value_generator (&i)))
01777       {
01778         run_test_nodes (&node, 1);
01779 
01780         node_destroy (node);
01781       }
01782   }
01783   arrays_write_fixed_in_blocks = FALSE;
01784 
01785   start_next_test ("All values in one big toplevel %d iteration\n", 1);
01786   {
01787     TestTypeNode *nodes[N_VALUES];
01788 
01789     i = 0;
01790     while ((nodes[i] = value_generator (&i)))
01791       ;
01792 
01793     run_test_nodes (nodes, N_VALUES);
01794 
01795     for (i = 0; i < N_VALUES; i++)
01796       node_destroy (nodes[i]);
01797   }
01798 
01799   start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
01800                    N_VALUES * N_VALUES);
01801   {
01802     TestTypeNode *nodes[2];
01803 
01804     i = 0;
01805     while ((nodes[0] = value_generator (&i)))
01806       {
01807         j = 0;
01808         while ((nodes[1] = value_generator (&j)))
01809           {
01810             run_test_nodes (nodes, 2);
01811 
01812             node_destroy (nodes[1]);
01813           }
01814 
01815         node_destroy (nodes[0]);
01816       }
01817   }
01818 
01819   start_next_test ("Each container containing each value %d iterations\n",
01820                    N_CONTAINERS * N_VALUES);
01821   for (i = 0; i < N_CONTAINERS; i++)
01822     {
01823       const TestTypeNodeClass *container_klass = container_nodes[i];
01824 
01825       make_and_run_values_inside_container (container_klass, 1);
01826     }
01827 
01828   start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
01829                    N_CONTAINERS * N_VALUES);
01830   arrays_write_fixed_in_blocks = TRUE;
01831   for (i = 0; i < N_CONTAINERS; i++)
01832     {
01833       const TestTypeNodeClass *container_klass = container_nodes[i];
01834 
01835       make_and_run_values_inside_container (container_klass, 1);
01836     }
01837   arrays_write_fixed_in_blocks = FALSE;
01838 
01839   start_next_test ("Each container of same container of each value %d iterations\n",
01840                    N_CONTAINERS * N_VALUES);
01841   for (i = 0; i < N_CONTAINERS; i++)
01842     {
01843       const TestTypeNodeClass *container_klass = container_nodes[i];
01844 
01845       make_and_run_values_inside_container (container_klass, 2);
01846     }
01847 
01848   start_next_test ("Each container of same container of same container of each value %d iterations\n",
01849                    N_CONTAINERS * N_VALUES);
01850   for (i = 0; i < N_CONTAINERS; i++)
01851     {
01852       const TestTypeNodeClass *container_klass = container_nodes[i];
01853 
01854       make_and_run_values_inside_container (container_klass, 3);
01855     }
01856 
01857   start_next_test ("Each value,value pair inside a struct %d iterations\n",
01858                    N_VALUES * N_VALUES);
01859   {
01860     TestTypeNode *val1, *val2;
01861     TestTypeNode *node;
01862 
01863     node = node_new (&struct_1_class);
01864 
01865     i = 0;
01866     while ((val1 = value_generator (&i)))
01867       {
01868         j = 0;
01869         while ((val2 = value_generator (&j)))
01870           {
01871             TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01872 
01873             node_append_child (node, val1);
01874             node_append_child (node, val2);
01875 
01876             run_test_nodes (&node, 1);
01877 
01878             _dbus_list_clear (&container->children);
01879             node_destroy (val2);
01880           }
01881         node_destroy (val1);
01882       }
01883     node_destroy (node);
01884   }
01885 
01886   start_next_test ("All values in one big struct %d iteration\n",
01887                    1);
01888   {
01889     TestTypeNode *node;
01890     TestTypeNode *child;
01891 
01892     node = node_new (&struct_1_class);
01893 
01894     i = 0;
01895     while ((child = value_generator (&i)))
01896       node_append_child (node, child);
01897 
01898     run_test_nodes (&node, 1);
01899 
01900     node_destroy (node);
01901   }
01902 
01903   start_next_test ("Each value in a large array %d iterations\n",
01904                    N_VALUES);
01905   {
01906     TestTypeNode *val;
01907     TestTypeNode *node;
01908 
01909     node = node_new (&array_9_class);
01910 
01911     i = 0;
01912     while ((val = value_generator (&i)))
01913       {
01914         TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01915 
01916         node_append_child (node, val);
01917 
01918         run_test_nodes (&node, 1);
01919 
01920         _dbus_list_clear (&container->children);
01921         node_destroy (val);
01922       }
01923 
01924     node_destroy (node);
01925   }
01926 
01927   start_next_test ("Each container of each container of each value %d iterations\n",
01928                    N_CONTAINERS * N_CONTAINERS * N_VALUES);
01929   for (i = 0; i < N_CONTAINERS; i++)
01930     {
01931       const TestTypeNodeClass *outer_container_klass = container_nodes[i];
01932       TestTypeNode *outer_container = node_new (outer_container_klass);
01933 
01934       for (j = 0; j < N_CONTAINERS; j++)
01935         {
01936           TestTypeNode *child;
01937           const TestTypeNodeClass *inner_container_klass = container_nodes[j];
01938           TestTypeNode *inner_container = node_new (inner_container_klass);
01939 
01940           node_append_child (outer_container, inner_container);
01941 
01942           m = 0;
01943           while ((child = value_generator (&m)))
01944             {
01945               node_append_child (inner_container, child);
01946 
01947               run_test_nodes (&outer_container, 1);
01948 
01949               _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
01950               node_destroy (child);
01951             }
01952           _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
01953           node_destroy (inner_container);
01954         }
01955       node_destroy (outer_container);
01956     }
01957 
01958   start_next_test ("Each container of each container of each container of each value %d iterations\n",
01959                    N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
01960   for (i = 0; i < N_CONTAINERS; i++)
01961     {
01962       const TestTypeNodeClass *outer_container_klass = container_nodes[i];
01963       TestTypeNode *outer_container = node_new (outer_container_klass);
01964 
01965       for (j = 0; j < N_CONTAINERS; j++)
01966         {
01967           const TestTypeNodeClass *inner_container_klass = container_nodes[j];
01968           TestTypeNode *inner_container = node_new (inner_container_klass);
01969 
01970           node_append_child (outer_container, inner_container);
01971 
01972           for (k = 0; k < N_CONTAINERS; k++)
01973             {
01974               TestTypeNode *child;
01975               const TestTypeNodeClass *center_container_klass = container_nodes[k];
01976               TestTypeNode *center_container = node_new (center_container_klass);
01977 
01978               node_append_child (inner_container, center_container);
01979 
01980               m = 0;
01981               while ((child = value_generator (&m)))
01982                 {
01983                   node_append_child (center_container, child);
01984 
01985                   run_test_nodes (&outer_container, 1);
01986 
01987                   _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
01988                   node_destroy (child);
01989                 }
01990               _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
01991               node_destroy (center_container);
01992             }
01993           _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
01994           node_destroy (inner_container);
01995         }
01996       node_destroy (outer_container);
01997     }
01998 
01999 #if 0
02000   
02001   start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
02002                    N_VALUES * N_VALUES * N_VALUES);
02003   {
02004     TestTypeNode *nodes[3];
02005 
02006     i = 0;
02007     while ((nodes[0] = value_generator (&i)))
02008       {
02009         j = 0;
02010         while ((nodes[1] = value_generator (&j)))
02011           {
02012             k = 0;
02013             while ((nodes[2] = value_generator (&k)))
02014               {
02015                 run_test_nodes (nodes, 3);
02016 
02017                 node_destroy (nodes[2]);
02018               }
02019             node_destroy (nodes[1]);
02020           }
02021         node_destroy (nodes[0]);
02022       }
02023   }
02024 #endif 
02025 
02026   fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
02027            n_iterations_completed_total);
02028   fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
02029            MAX_INITIAL_OFFSET);
02030   fprintf (stderr, "out of memory handling %s tested\n",
02031            TEST_OOM_HANDLING ? "was" : "was not");
02032 }
02033 
02034 dbus_bool_t
02035 _dbus_marshal_recursive_test (void)
02036 {
02037   make_and_run_test_nodes ();
02038 
02039   return TRUE;
02040 }
02041 
02042 
02043 
02044 
02045 
02046 
02047 
02048 
02049 
02050 #define MAX_MULTI_COUNT 5
02051 
02052 #define SAMPLE_INT16           1234
02053 #define SAMPLE_INT16_ALTERNATE 6785
02054 static dbus_int16_t
02055 int16_from_seed (int seed)
02056 {
02057   
02058 
02059 
02060 
02061   dbus_int16_t v;
02062 
02063   v = 42; 
02064   switch (seed % 5)
02065     {
02066     case 0:
02067       v = SAMPLE_INT16;
02068       break;
02069     case 1:
02070       v = SAMPLE_INT16_ALTERNATE;
02071       break;
02072     case 2:
02073       v = -1;
02074       break;
02075     case 3:
02076       v = _DBUS_INT16_MAX;
02077       break;
02078     case 4:
02079       v = 1;
02080       break;
02081     }
02082 
02083   if (seed > 1)
02084     v *= seed; 
02085 
02086   return v;
02087 }
02088 
02089 static dbus_bool_t
02090 int16_write_value (TestTypeNode   *node,
02091                    DataBlock      *block,
02092                    DBusTypeWriter *writer,
02093                    int             seed)
02094 {
02095   
02096   dbus_int16_t v;
02097 
02098   v = int16_from_seed (seed);
02099 
02100   return _dbus_type_writer_write_basic (writer,
02101                                         node->klass->typecode,
02102                                         &v);
02103 }
02104 
02105 static dbus_bool_t
02106 int16_read_value (TestTypeNode   *node,
02107                   DBusTypeReader *reader,
02108                   int             seed)
02109 {
02110   
02111   dbus_int16_t v;
02112 
02113   check_expected_type (reader, node->klass->typecode);
02114 
02115   _dbus_type_reader_read_basic (reader,
02116                                 (dbus_int16_t*) &v);
02117 
02118   _dbus_assert (v == int16_from_seed (seed));
02119 
02120   return TRUE;
02121 }
02122 
02123 static dbus_bool_t
02124 int16_set_value (TestTypeNode   *node,
02125                  DBusTypeReader *reader,
02126                  DBusTypeReader *realign_root,
02127                  int             seed)
02128 {
02129   
02130   dbus_int16_t v;
02131 
02132   v = int16_from_seed (seed);
02133 
02134   return _dbus_type_reader_set_basic (reader,
02135                                       &v,
02136                                       realign_root);
02137 }
02138 
02139 static dbus_bool_t
02140 int16_write_multi (TestTypeNode   *node,
02141                    DataBlock      *block,
02142                    DBusTypeWriter *writer,
02143                    int             seed,
02144                    int             count)
02145 {
02146   
02147   dbus_int16_t values[MAX_MULTI_COUNT];
02148   dbus_int16_t *v_ARRAY_INT16 = values;
02149   int i;
02150 
02151   for (i = 0; i < count; ++i)
02152     values[i] = int16_from_seed (seed + i);
02153 
02154   return _dbus_type_writer_write_fixed_multi (writer,
02155                                               node->klass->typecode,
02156                                               &v_ARRAY_INT16, count);
02157 }
02158 
02159 static dbus_bool_t
02160 int16_read_multi (TestTypeNode   *node,
02161                   DBusTypeReader *reader,
02162                   int             seed,
02163                   int             count)
02164 {
02165   
02166   dbus_int16_t *values;
02167   int n_elements;
02168   int i;
02169 
02170   check_expected_type (reader, node->klass->typecode);
02171 
02172   _dbus_type_reader_read_fixed_multi (reader,
02173                                       &values,
02174                                       &n_elements);
02175 
02176   if (n_elements != count)
02177     _dbus_warn ("got %d elements expected %d\n", n_elements, count);
02178   _dbus_assert (n_elements == count);
02179 
02180   for (i = 0; i < count; i++)
02181     _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
02182                                                       (const unsigned char*)values + (i * 2))) ==
02183                   int16_from_seed (seed + i));
02184 
02185   return TRUE;
02186 }
02187 
02188 
02189 #define SAMPLE_INT32           12345678
02190 #define SAMPLE_INT32_ALTERNATE 53781429
02191 static dbus_int32_t
02192 int32_from_seed (int seed)
02193 {
02194   
02195 
02196 
02197 
02198   dbus_int32_t v;
02199 
02200   v = 42; 
02201   switch (seed % 5)
02202     {
02203     case 0:
02204       v = SAMPLE_INT32;
02205       break;
02206     case 1:
02207       v = SAMPLE_INT32_ALTERNATE;
02208       break;
02209     case 2:
02210       v = -1;
02211       break;
02212     case 3:
02213       v = _DBUS_INT_MAX;
02214       break;
02215     case 4:
02216       v = 1;
02217       break;
02218     }
02219 
02220   if (seed > 1)
02221     v *= seed; 
02222 
02223   return v;
02224 }
02225 
02226 static dbus_bool_t
02227 int32_write_value (TestTypeNode   *node,
02228                    DataBlock      *block,
02229                    DBusTypeWriter *writer,
02230                    int             seed)
02231 {
02232   
02233   dbus_int32_t v;
02234 
02235   v = int32_from_seed (seed);
02236 
02237   return _dbus_type_writer_write_basic (writer,
02238                                         node->klass->typecode,
02239                                         &v);
02240 }
02241 
02242 static dbus_bool_t
02243 int32_read_value (TestTypeNode   *node,
02244                   DBusTypeReader *reader,
02245                   int             seed)
02246 {
02247   
02248   dbus_int32_t v;
02249 
02250   check_expected_type (reader, node->klass->typecode);
02251 
02252   _dbus_type_reader_read_basic (reader,
02253                                 (dbus_int32_t*) &v);
02254 
02255   _dbus_assert (v == int32_from_seed (seed));
02256 
02257   return TRUE;
02258 }
02259 
02260 static dbus_bool_t
02261 int32_set_value (TestTypeNode   *node,
02262                  DBusTypeReader *reader,
02263                  DBusTypeReader *realign_root,
02264                  int             seed)
02265 {
02266   
02267   dbus_int32_t v;
02268 
02269   v = int32_from_seed (seed);
02270 
02271   return _dbus_type_reader_set_basic (reader,
02272                                       &v,
02273                                       realign_root);
02274 }
02275 
02276 static dbus_bool_t
02277 int32_write_multi (TestTypeNode   *node,
02278                    DataBlock      *block,
02279                    DBusTypeWriter *writer,
02280                    int             seed,
02281                    int             count)
02282 {
02283   
02284   dbus_int32_t values[MAX_MULTI_COUNT];
02285   dbus_int32_t *v_ARRAY_INT32 = values;
02286   int i;
02287 
02288   for (i = 0; i < count; ++i)
02289     values[i] = int32_from_seed (seed + i);
02290 
02291   return _dbus_type_writer_write_fixed_multi (writer,
02292                                               node->klass->typecode,
02293                                               &v_ARRAY_INT32, count);
02294 }
02295 
02296 static dbus_bool_t
02297 int32_read_multi (TestTypeNode   *node,
02298                   DBusTypeReader *reader,
02299                   int             seed,
02300                   int             count)
02301 {
02302   
02303   dbus_int32_t *values;
02304   int n_elements;
02305   int i;
02306 
02307   check_expected_type (reader, node->klass->typecode);
02308 
02309   _dbus_type_reader_read_fixed_multi (reader,
02310                                       &values,
02311                                       &n_elements);
02312 
02313   if (n_elements != count)
02314     _dbus_warn ("got %d elements expected %d\n", n_elements, count);
02315   _dbus_assert (n_elements == count);
02316 
02317   for (i = 0; i < count; i++)
02318     _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
02319                                              (const unsigned char*)values + (i * 4))) ==
02320                   int32_from_seed (seed + i));
02321 
02322   return TRUE;
02323 }
02324 
02325 #ifdef DBUS_HAVE_INT64
02326 static dbus_int64_t
02327 int64_from_seed (int seed)
02328 {
02329   dbus_int32_t v32;
02330   dbus_int64_t v;
02331 
02332   v32 = int32_from_seed (seed);
02333 
02334   v = - (dbus_int32_t) ~ v32;
02335   v |= (((dbus_int64_t)v32) << 32);
02336 
02337   return v;
02338 }
02339 #endif
02340 
02341 static dbus_bool_t
02342 int64_write_value (TestTypeNode   *node,
02343                    DataBlock      *block,
02344                    DBusTypeWriter *writer,
02345                    int             seed)
02346 {
02347 #ifdef DBUS_HAVE_INT64
02348   
02349   dbus_int64_t v;
02350 
02351   v = int64_from_seed (seed);
02352 
02353   return _dbus_type_writer_write_basic (writer,
02354                                         node->klass->typecode,
02355                                         &v);
02356 #else
02357   return TRUE;
02358 #endif
02359 }
02360 
02361 static dbus_bool_t
02362 int64_read_value (TestTypeNode   *node,
02363                   DBusTypeReader *reader,
02364                   int             seed)
02365 {
02366 #ifdef DBUS_HAVE_INT64
02367   
02368   dbus_int64_t v;
02369 
02370   check_expected_type (reader, node->klass->typecode);
02371 
02372   _dbus_type_reader_read_basic (reader,
02373                                 (dbus_int64_t*) &v);
02374 
02375   _dbus_assert (v == int64_from_seed (seed));
02376 
02377   return TRUE;
02378 #else
02379   return TRUE;
02380 #endif
02381 }
02382 
02383 static dbus_bool_t
02384 int64_set_value (TestTypeNode   *node,
02385                  DBusTypeReader *reader,
02386                  DBusTypeReader *realign_root,
02387                  int             seed)
02388 {
02389 #ifdef DBUS_HAVE_INT64
02390   
02391   dbus_int64_t v;
02392 
02393   v = int64_from_seed (seed);
02394 
02395   return _dbus_type_reader_set_basic (reader,
02396                                       &v,
02397                                       realign_root);
02398 #else
02399   return TRUE;
02400 #endif
02401 }
02402 
02403 #define MAX_SAMPLE_STRING_LEN 10
02404 static void
02405 string_from_seed (char *buf,
02406                   int   len,
02407                   int   seed)
02408 {
02409   int i;
02410   unsigned char v;
02411 
02412   _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
02413 
02414   
02415 
02416 
02417   switch (seed % 3)
02418     {
02419     case 1:
02420       len += 2;
02421       break;
02422     case 2:
02423       len -= 2;
02424       break;
02425     }
02426   if (len < 0)
02427     len = 0;
02428 
02429   v = (unsigned char) ('A' + seed);
02430 
02431   i = 0;
02432   while (i < len)
02433     {
02434       if (v < 'A' || v > 'z')
02435         v = 'A';
02436 
02437       buf[i] = v;
02438 
02439       v += 1;
02440       ++i;
02441     }
02442 
02443   buf[i] = '\0';
02444 }
02445 
02446 static dbus_bool_t
02447 string_write_value (TestTypeNode   *node,
02448                     DataBlock      *block,
02449                     DBusTypeWriter *writer,
02450                     int             seed)
02451 {
02452   char buf[MAX_SAMPLE_STRING_LEN + 1]="";
02453   const char *v_string = buf;
02454 
02455 
02456   string_from_seed (buf, node->klass->subclass_detail,
02457                     seed);
02458 
02459   return _dbus_type_writer_write_basic (writer,
02460                                         node->klass->typecode,
02461                                         &v_string);
02462 }
02463 
02464 static dbus_bool_t
02465 string_read_value (TestTypeNode   *node,
02466                    DBusTypeReader *reader,
02467                    int             seed)
02468 {
02469   const char *v;
02470   char buf[MAX_SAMPLE_STRING_LEN + 1];
02471   v = buf;
02472 
02473   check_expected_type (reader, node->klass->typecode);
02474 
02475   _dbus_type_reader_read_basic (reader,
02476                                 (const char **) &v);
02477 
02478   string_from_seed (buf, node->klass->subclass_detail,
02479                     seed);
02480 
02481   if (strcmp (buf, v) != 0)
02482     {
02483       _dbus_warn ("read string '%s' expected '%s'\n",
02484                   v, buf);
02485       _dbus_assert_not_reached ("test failed");
02486     }
02487 
02488   return TRUE;
02489 }
02490 
02491 static dbus_bool_t
02492 string_set_value (TestTypeNode   *node,
02493                   DBusTypeReader *reader,
02494                   DBusTypeReader *realign_root,
02495                   int             seed)
02496 {
02497   char buf[MAX_SAMPLE_STRING_LEN + 1];
02498   const char *v_string = buf;
02499 
02500   string_from_seed (buf, node->klass->subclass_detail,
02501                     seed);
02502 
02503 #if RECURSIVE_MARSHAL_WRITE_TRACE
02504  {
02505    const char *old;
02506    _dbus_type_reader_read_basic (reader, &old);
02507    _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
02508                   v_string, strlen (v_string), old, strlen (old));
02509  }
02510 #endif
02511 
02512   return _dbus_type_reader_set_basic (reader,
02513                                       &v_string,
02514                                       realign_root);
02515 }
02516 
02517 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
02518 
02519 static dbus_bool_t
02520 bool_write_value (TestTypeNode   *node,
02521                   DataBlock      *block,
02522                   DBusTypeWriter *writer,
02523                   int             seed)
02524 {
02525   dbus_bool_t v;
02526 
02527   v = BOOL_FROM_SEED (seed);
02528 
02529   return _dbus_type_writer_write_basic (writer,
02530                                         node->klass->typecode,
02531                                         &v);
02532 }
02533 
02534 static dbus_bool_t
02535 bool_read_value (TestTypeNode   *node,
02536                  DBusTypeReader *reader,
02537                  int             seed)
02538 {
02539   dbus_bool_t v;
02540 
02541   check_expected_type (reader, node->klass->typecode);
02542 
02543   _dbus_type_reader_read_basic (reader,
02544                                 (unsigned char*) &v);
02545 
02546   _dbus_assert (v == BOOL_FROM_SEED (seed));
02547 
02548   return TRUE;
02549 }
02550 
02551 static dbus_bool_t
02552 bool_set_value (TestTypeNode   *node,
02553                 DBusTypeReader *reader,
02554                 DBusTypeReader *realign_root,
02555                 int             seed)
02556 {
02557   dbus_bool_t v;
02558 
02559   v = BOOL_FROM_SEED (seed);
02560 
02561   return _dbus_type_reader_set_basic (reader,
02562                                       &v,
02563                                       realign_root);
02564 }
02565 
02566 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
02567 
02568 static dbus_bool_t
02569 byte_write_value (TestTypeNode   *node,
02570                   DataBlock      *block,
02571                   DBusTypeWriter *writer,
02572                   int             seed)
02573 {
02574   unsigned char v;
02575 
02576   v = BYTE_FROM_SEED (seed);
02577 
02578   return _dbus_type_writer_write_basic (writer,
02579                                         node->klass->typecode,
02580                                         &v);
02581 }
02582 
02583 static dbus_bool_t
02584 byte_read_value (TestTypeNode   *node,
02585                  DBusTypeReader *reader,
02586                  int             seed)
02587 {
02588   unsigned char v;
02589 
02590   check_expected_type (reader, node->klass->typecode);
02591 
02592   _dbus_type_reader_read_basic (reader,
02593                                 (unsigned char*) &v);
02594 
02595   _dbus_assert (v == BYTE_FROM_SEED (seed));
02596 
02597   return TRUE;
02598 }
02599 
02600 
02601 static dbus_bool_t
02602 byte_set_value (TestTypeNode   *node,
02603                 DBusTypeReader *reader,
02604                 DBusTypeReader *realign_root,
02605                 int             seed)
02606 {
02607   unsigned char v;
02608 
02609   v = BYTE_FROM_SEED (seed);
02610 
02611   return _dbus_type_reader_set_basic (reader,
02612                                       &v,
02613                                       realign_root);
02614 }
02615 
02616 static double
02617 double_from_seed (int seed)
02618 {
02619   return SAMPLE_INT32 * (double) seed + 0.3;
02620 }
02621 
02622 static dbus_bool_t
02623 double_write_value (TestTypeNode   *node,
02624                     DataBlock      *block,
02625                     DBusTypeWriter *writer,
02626                     int             seed)
02627 {
02628   double v;
02629 
02630   v = double_from_seed (seed);
02631 
02632   return _dbus_type_writer_write_basic (writer,
02633                                         node->klass->typecode,
02634                                         &v);
02635 }
02636 
02637 static dbus_bool_t
02638 double_read_value (TestTypeNode   *node,
02639                    DBusTypeReader *reader,
02640                    int             seed)
02641 {
02642   double v;
02643   double expected;
02644 
02645   check_expected_type (reader, node->klass->typecode);
02646 
02647   _dbus_type_reader_read_basic (reader,
02648                                 (double*) &v);
02649 
02650   expected = double_from_seed (seed);
02651 
02652   if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
02653     {
02654 #ifdef DBUS_HAVE_INT64
02655       _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
02656                   expected, v,
02657                   *(dbus_uint64_t*)(char*)&expected,
02658                   *(dbus_uint64_t*)(char*)&v);
02659 #endif
02660       _dbus_assert_not_reached ("test failed");
02661     }
02662 
02663   return TRUE;
02664 }
02665 
02666 static dbus_bool_t
02667 double_set_value (TestTypeNode   *node,
02668                 DBusTypeReader *reader,
02669                 DBusTypeReader *realign_root,
02670                 int             seed)
02671 {
02672   double v;
02673 
02674   v = double_from_seed (seed);
02675 
02676   return _dbus_type_reader_set_basic (reader,
02677                                       &v,
02678                                       realign_root);
02679 }
02680 
02681 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
02682 static void
02683 object_path_from_seed (char *buf,
02684                        int   seed)
02685 {
02686   int i;
02687   unsigned char v;
02688   int len;
02689 
02690   len = seed % 9;
02691   _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
02692 
02693   v = (unsigned char) ('A' + seed);
02694 
02695   if (len < 2)
02696     {
02697       buf[0] = '/';
02698       i = 1;
02699     }
02700   else
02701     {
02702       i = 0;
02703       while (i + 1 < len)
02704         {
02705           if (v < 'A' || v > 'z')
02706             v = 'A';
02707 
02708           buf[i] = '/';
02709           ++i;
02710           buf[i] = v;
02711           ++i;
02712           
02713           v += 1;
02714         }
02715     }
02716 
02717   buf[i] = '\0';
02718 }
02719 
02720 static dbus_bool_t
02721 object_path_write_value (TestTypeNode   *node,
02722                          DataBlock      *block,
02723                          DBusTypeWriter *writer,
02724                          int             seed)
02725 {
02726   char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02727   const char *v_string = buf;
02728 
02729   object_path_from_seed (buf, seed);
02730 
02731   return _dbus_type_writer_write_basic (writer,
02732                                         node->klass->typecode,
02733                                         &v_string);
02734 }
02735 
02736 static dbus_bool_t
02737 object_path_read_value (TestTypeNode   *node,
02738                         DBusTypeReader *reader,
02739                         int             seed)
02740 {
02741   const char *v;
02742   char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02743 
02744   check_expected_type (reader, node->klass->typecode);
02745 
02746   _dbus_type_reader_read_basic (reader,
02747                                 (const char **) &v);
02748 
02749   object_path_from_seed (buf, seed);
02750 
02751   if (strcmp (buf, v) != 0)
02752     {
02753       _dbus_warn ("read object path '%s' expected '%s'\n",
02754                   v, buf);
02755       _dbus_assert_not_reached ("test failed");
02756     }
02757 
02758   return TRUE;
02759 }
02760 
02761 static dbus_bool_t
02762 object_path_set_value (TestTypeNode   *node,
02763                        DBusTypeReader *reader,
02764                        DBusTypeReader *realign_root,
02765                        int             seed)
02766 {
02767   char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02768   const char *v_string = buf;
02769 
02770   object_path_from_seed (buf, seed);
02771 
02772   return _dbus_type_reader_set_basic (reader,
02773                                       &v_string,
02774                                       realign_root);
02775 }
02776 
02777 #define MAX_SAMPLE_SIGNATURE_LEN 10
02778 static void
02779 signature_from_seed (char *buf,
02780                      int   seed)
02781 {
02782   
02783   const char *sample_signatures[] = {
02784     "asax"
02785     "",
02786     "asau(xxxx)",
02787     "x",
02788     "ai",
02789     "a(ii)"
02790   };
02791 
02792   strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
02793 }
02794 
02795 static dbus_bool_t
02796 signature_write_value (TestTypeNode   *node,
02797                        DataBlock      *block,
02798                        DBusTypeWriter *writer,
02799                        int             seed)
02800 {
02801   char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02802   const char *v_string = buf;
02803 
02804   signature_from_seed (buf, seed);
02805 
02806   return _dbus_type_writer_write_basic (writer,
02807                                         node->klass->typecode,
02808                                         &v_string);
02809 }
02810 
02811 static dbus_bool_t
02812 signature_read_value (TestTypeNode   *node,
02813                       DBusTypeReader *reader,
02814                       int             seed)
02815 {
02816   const char *v;
02817   char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02818 
02819   check_expected_type (reader, node->klass->typecode);
02820 
02821   _dbus_type_reader_read_basic (reader,
02822                                 (const char **) &v);
02823 
02824   signature_from_seed (buf, seed);
02825 
02826   if (strcmp (buf, v) != 0)
02827     {
02828       _dbus_warn ("read signature value '%s' expected '%s'\n",
02829                   v, buf);
02830       _dbus_assert_not_reached ("test failed");
02831     }
02832 
02833   return TRUE;
02834 }
02835 
02836 
02837 static dbus_bool_t
02838 signature_set_value (TestTypeNode   *node,
02839                      DBusTypeReader *reader,
02840                      DBusTypeReader *realign_root,
02841                      int             seed)
02842 {
02843   char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02844   const char *v_string = buf;
02845 
02846   signature_from_seed (buf, seed);
02847 
02848   return _dbus_type_reader_set_basic (reader,
02849                                       &v_string,
02850                                       realign_root);
02851 }
02852 
02853 static dbus_bool_t
02854 struct_write_value (TestTypeNode   *node,
02855                     DataBlock      *block,
02856                     DBusTypeWriter *writer,
02857                     int             seed)
02858 {
02859   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02860   DataBlockState saved;
02861   DBusTypeWriter sub;
02862   int i;
02863   int n_copies;
02864 
02865   n_copies = node->klass->subclass_detail;
02866 
02867   _dbus_assert (container->children != NULL);
02868 
02869   data_block_save (block, &saved);
02870 
02871   if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
02872                                   NULL, 0,
02873                                   &sub))
02874     return FALSE;
02875 
02876   i = 0;
02877   while (i < n_copies)
02878     {
02879       DBusList *link;
02880 
02881       link = _dbus_list_get_first_link (&container->children);
02882       while (link != NULL)
02883         {
02884           TestTypeNode *child = link->data;
02885           DBusList *next = _dbus_list_get_next_link (&container->children, link);
02886 
02887           if (!node_write_value (child, block, &sub, seed + i))
02888             {
02889               data_block_restore (block, &saved);
02890               return FALSE;
02891             }
02892 
02893           link = next;
02894         }
02895 
02896       ++i;
02897     }
02898 
02899   if (!_dbus_type_writer_unrecurse (writer, &sub))
02900     {
02901       data_block_restore (block, &saved);
02902       return FALSE;
02903     }
02904 
02905   return TRUE;
02906 }
02907 
02908 static dbus_bool_t
02909 struct_read_or_set_value (TestTypeNode   *node,
02910                           DBusTypeReader *reader,
02911                           DBusTypeReader *realign_root,
02912                           int             seed)
02913 {
02914   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02915   DBusTypeReader sub;
02916   int i;
02917   int n_copies;
02918 
02919   n_copies = node->klass->subclass_detail;
02920 
02921   check_expected_type (reader, DBUS_TYPE_STRUCT);
02922 
02923   _dbus_type_reader_recurse (reader, &sub);
02924 
02925   i = 0;
02926   while (i < n_copies)
02927     {
02928       DBusList *link;
02929 
02930       link = _dbus_list_get_first_link (&container->children);
02931       while (link != NULL)
02932         {
02933           TestTypeNode *child = link->data;
02934           DBusList *next = _dbus_list_get_next_link (&container->children, link);
02935 
02936           if (realign_root == NULL)
02937             {
02938               if (!node_read_value (child, &sub, seed + i))
02939                 return FALSE;
02940             }
02941           else
02942             {
02943               if (!node_set_value (child, &sub, realign_root, seed + i))
02944                 return FALSE;
02945             }
02946 
02947           if (i == (n_copies - 1) && next == NULL)
02948             NEXT_EXPECTING_FALSE (&sub);
02949           else
02950             NEXT_EXPECTING_TRUE (&sub);
02951 
02952           link = next;
02953         }
02954 
02955       ++i;
02956     }
02957 
02958   return TRUE;
02959 }
02960 
02961 static dbus_bool_t
02962 struct_read_value (TestTypeNode   *node,
02963                    DBusTypeReader *reader,
02964                    int             seed)
02965 {
02966   return struct_read_or_set_value (node, reader, NULL, seed);
02967 }
02968 
02969 static dbus_bool_t
02970 struct_set_value (TestTypeNode   *node,
02971                   DBusTypeReader *reader,
02972                   DBusTypeReader *realign_root,
02973                   int             seed)
02974 {
02975   return struct_read_or_set_value (node, reader, realign_root, seed);
02976 }
02977 
02978 static dbus_bool_t
02979 struct_build_signature (TestTypeNode   *node,
02980                         DBusString     *str)
02981 {
02982   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02983   int i;
02984   int orig_len;
02985   int n_copies;
02986 
02987   n_copies = node->klass->subclass_detail;
02988 
02989   orig_len = _dbus_string_get_length (str);
02990 
02991   if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
02992     goto oom;
02993 
02994   i = 0;
02995   while (i < n_copies)
02996     {
02997       DBusList *link;
02998 
02999       link = _dbus_list_get_first_link (&container->children);
03000       while (link != NULL)
03001         {
03002           TestTypeNode *child = link->data;
03003           DBusList *next = _dbus_list_get_next_link (&container->children, link);
03004 
03005           if (!node_build_signature (child, str))
03006             goto oom;
03007 
03008           link = next;
03009         }
03010 
03011       ++i;
03012     }
03013 
03014   if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
03015     goto oom;
03016 
03017   return TRUE;
03018 
03019  oom:
03020   _dbus_string_set_length (str, orig_len);
03021   return FALSE;
03022 }
03023 
03024 static dbus_bool_t
03025 array_write_value (TestTypeNode   *node,
03026                    DataBlock      *block,
03027                    DBusTypeWriter *writer,
03028                    int             seed)
03029 {
03030   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03031   DataBlockState saved;
03032   DBusTypeWriter sub;
03033   DBusString element_signature;
03034   int i;
03035   int n_copies;
03036   int element_type;
03037   TestTypeNode *child;
03038 
03039   n_copies = node->klass->subclass_detail;
03040 
03041   _dbus_assert (container->children != NULL);
03042 
03043   data_block_save (block, &saved);
03044 
03045   if (!_dbus_string_init (&element_signature))
03046     return FALSE;
03047 
03048   child = _dbus_list_get_first (&container->children);
03049 
03050   if (!node_build_signature (child,
03051                              &element_signature))
03052     goto oom;
03053 
03054   element_type = _dbus_first_type_in_signature (&element_signature, 0);
03055 
03056   if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
03057                                   &element_signature, 0,
03058                                   &sub))
03059     goto oom;
03060 
03061   if (arrays_write_fixed_in_blocks &&
03062       dbus_type_is_fixed (element_type) &&
03063       child->klass->write_multi)
03064     {
03065       if (!node_write_multi (child, block, &sub, seed, n_copies))
03066         goto oom;
03067     }
03068   else
03069     {
03070       i = 0;
03071       while (i < n_copies)
03072         {
03073           DBusList *link;
03074 
03075           link = _dbus_list_get_first_link (&container->children);
03076           while (link != NULL)
03077             {
03078               TestTypeNode *child = link->data;
03079               DBusList *next = _dbus_list_get_next_link (&container->children, link);
03080 
03081               if (!node_write_value (child, block, &sub, seed + i))
03082                 goto oom;
03083 
03084               link = next;
03085             }
03086 
03087           ++i;
03088         }
03089     }
03090 
03091   if (!_dbus_type_writer_unrecurse (writer, &sub))
03092     goto oom;
03093 
03094   _dbus_string_free (&element_signature);
03095   return TRUE;
03096 
03097  oom:
03098   data_block_restore (block, &saved);
03099   _dbus_string_free (&element_signature);
03100   return FALSE;
03101 }
03102 
03103 static dbus_bool_t
03104 array_read_or_set_value (TestTypeNode   *node,
03105                          DBusTypeReader *reader,
03106                          DBusTypeReader *realign_root,
03107                          int             seed)
03108 {
03109   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03110   DBusTypeReader sub;
03111   int i;
03112   int n_copies;
03113   TestTypeNode *child;
03114 
03115   n_copies = node->klass->subclass_detail;
03116 
03117   check_expected_type (reader, DBUS_TYPE_ARRAY);
03118 
03119   child = _dbus_list_get_first (&container->children);
03120 
03121   if (n_copies > 0)
03122     {
03123       _dbus_type_reader_recurse (reader, &sub);
03124 
03125       if (realign_root == NULL && arrays_write_fixed_in_blocks &&
03126           dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
03127           child->klass->read_multi)
03128         {
03129           if (!node_read_multi (child, &sub, seed, n_copies))
03130             return FALSE;
03131         }
03132       else
03133         {
03134           i = 0;
03135           while (i < n_copies)
03136             {
03137               DBusList *link;
03138 
03139               link = _dbus_list_get_first_link (&container->children);
03140               while (link != NULL)
03141                 {
03142                   TestTypeNode *child = link->data;
03143                   DBusList *next = _dbus_list_get_next_link (&container->children, link);
03144 
03145                   _dbus_assert (child->klass->typecode ==
03146                                 _dbus_type_reader_get_element_type (reader));
03147 
03148                   if (realign_root == NULL)
03149                     {
03150                       if (!node_read_value (child, &sub, seed + i))
03151                         return FALSE;
03152                     }
03153                   else
03154                     {
03155                       if (!node_set_value (child, &sub, realign_root, seed + i))
03156                         return FALSE;
03157                     }
03158 
03159                   if (i == (n_copies - 1) && next == NULL)
03160                     NEXT_EXPECTING_FALSE (&sub);
03161                   else
03162                     NEXT_EXPECTING_TRUE (&sub);
03163 
03164                   link = next;
03165                 }
03166 
03167               ++i;
03168             }
03169         }
03170     }
03171 
03172   return TRUE;
03173 }
03174 
03175 static dbus_bool_t
03176 array_read_value (TestTypeNode   *node,
03177                   DBusTypeReader *reader,
03178                   int             seed)
03179 {
03180   return array_read_or_set_value (node, reader, NULL, seed);
03181 }
03182 
03183 static dbus_bool_t
03184 array_set_value (TestTypeNode   *node,
03185                  DBusTypeReader *reader,
03186                  DBusTypeReader *realign_root,
03187                  int             seed)
03188 {
03189   return array_read_or_set_value (node, reader, realign_root, seed);
03190 }
03191 
03192 static dbus_bool_t
03193 array_build_signature (TestTypeNode   *node,
03194                        DBusString     *str)
03195 {
03196   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03197   int orig_len;
03198 
03199   orig_len = _dbus_string_get_length (str);
03200 
03201   if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
03202     goto oom;
03203 
03204   if (!node_build_signature (_dbus_list_get_first (&container->children),
03205                              str))
03206     goto oom;
03207 
03208   return TRUE;
03209 
03210  oom:
03211   _dbus_string_set_length (str, orig_len);
03212   return FALSE;
03213 }
03214 
03215  
03216 #define VARIANT_SEED 10
03217 
03218 static dbus_bool_t
03219 variant_write_value (TestTypeNode   *node,
03220                      DataBlock      *block,
03221                      DBusTypeWriter *writer,
03222                      int             seed)
03223 {
03224   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03225   DataBlockState saved;
03226   DBusTypeWriter sub;
03227   DBusString content_signature;
03228   TestTypeNode *child;
03229 
03230   _dbus_assert (container->children != NULL);
03231   _dbus_assert (_dbus_list_length_is_one (&container->children));
03232 
03233   child = _dbus_list_get_first (&container->children);
03234 
03235   data_block_save (block, &saved);
03236 
03237   if (!_dbus_string_init (&content_signature))
03238     return FALSE;
03239 
03240   if (!node_build_signature (child,
03241                              &content_signature))
03242     goto oom;
03243 
03244   if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
03245                                   &content_signature, 0,
03246                                   &sub))
03247     goto oom;
03248 
03249   if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
03250     goto oom;
03251 
03252   if (!_dbus_type_writer_unrecurse (writer, &sub))
03253     goto oom;
03254 
03255   _dbus_string_free (&content_signature);
03256   return TRUE;
03257 
03258  oom:
03259   data_block_restore (block, &saved);
03260   _dbus_string_free (&content_signature);
03261   return FALSE;
03262 }
03263 
03264 static dbus_bool_t
03265 variant_read_or_set_value (TestTypeNode   *node,
03266                            DBusTypeReader *reader,
03267                            DBusTypeReader *realign_root,
03268                            int             seed)
03269 {
03270   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03271   DBusTypeReader sub;
03272   TestTypeNode *child;
03273 
03274   _dbus_assert (container->children != NULL);
03275   _dbus_assert (_dbus_list_length_is_one (&container->children));
03276 
03277   child = _dbus_list_get_first (&container->children);
03278 
03279   check_expected_type (reader, DBUS_TYPE_VARIANT);
03280 
03281   _dbus_type_reader_recurse (reader, &sub);
03282 
03283   if (realign_root == NULL)
03284     {
03285       if (!node_read_value (child, &sub, seed + VARIANT_SEED))
03286         return FALSE;
03287     }
03288   else
03289     {
03290       if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
03291         return FALSE;
03292     }
03293 
03294   NEXT_EXPECTING_FALSE (&sub);
03295 
03296   return TRUE;
03297 }
03298 
03299 static dbus_bool_t
03300 variant_read_value (TestTypeNode   *node,
03301                     DBusTypeReader *reader,
03302                     int             seed)
03303 {
03304   return variant_read_or_set_value (node, reader, NULL, seed);
03305 }
03306 
03307 static dbus_bool_t
03308 variant_set_value (TestTypeNode   *node,
03309                    DBusTypeReader *reader,
03310                    DBusTypeReader *realign_root,
03311                    int             seed)
03312 {
03313   return variant_read_or_set_value (node, reader, realign_root, seed);
03314 }
03315 
03316 static dbus_bool_t
03317 dict_write_value (TestTypeNode   *node,
03318                   DataBlock      *block,
03319                   DBusTypeWriter *writer,
03320                   int             seed)
03321 {
03322   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03323   DataBlockState saved;
03324   DBusTypeWriter sub;
03325   DBusString entry_value_signature;
03326   DBusString dict_entry_signature;
03327   int i;
03328   int n_entries;
03329   int entry_value_type;
03330   TestTypeNode *child;
03331 
03332   n_entries = node->klass->subclass_detail;
03333 
03334   _dbus_assert (container->children != NULL);
03335 
03336   data_block_save (block, &saved);
03337 
03338   if (!_dbus_string_init (&entry_value_signature))
03339     return FALSE;
03340 
03341   if (!_dbus_string_init (&dict_entry_signature))
03342     {
03343       _dbus_string_free (&entry_value_signature);
03344       return FALSE;
03345     }
03346   
03347   child = _dbus_list_get_first (&container->children);
03348 
03349   if (!node_build_signature (child,
03350                              &entry_value_signature))
03351     goto oom;
03352 
03353   if (!_dbus_string_append (&dict_entry_signature,
03354                             DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
03355                             DBUS_TYPE_INT32_AS_STRING))
03356     goto oom;
03357 
03358   if (!_dbus_string_copy (&entry_value_signature, 0,
03359                           &dict_entry_signature,
03360                           _dbus_string_get_length (&dict_entry_signature)))
03361     goto oom;
03362 
03363   if (!_dbus_string_append_byte (&dict_entry_signature,
03364                                  DBUS_DICT_ENTRY_END_CHAR))
03365     goto oom;
03366   
03367   entry_value_type = _dbus_first_type_in_signature (&entry_value_signature, 0);
03368   
03369   if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
03370                                   &dict_entry_signature, 0,
03371                                   &sub))
03372     goto oom;
03373 
03374   i = 0;
03375   while (i < n_entries)
03376     {
03377       DBusTypeWriter entry_sub;
03378       dbus_int32_t key;
03379 
03380       if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
03381                                       NULL, 0,
03382                                       &entry_sub))
03383         goto oom;
03384 
03385       key = int32_from_seed (seed + i);
03386 
03387       if (!_dbus_type_writer_write_basic (&entry_sub,
03388                                           DBUS_TYPE_INT32,
03389                                           &key))
03390         goto oom;
03391       
03392       if (!node_write_value (child, block, &entry_sub, seed + i))
03393         goto oom;
03394 
03395       if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
03396         goto oom;
03397       
03398       ++i;
03399     }
03400 
03401   if (!_dbus_type_writer_unrecurse (writer, &sub))
03402     goto oom;
03403   
03404   _dbus_string_free (&entry_value_signature);
03405   _dbus_string_free (&dict_entry_signature);
03406   return TRUE;
03407 
03408  oom:
03409   data_block_restore (block, &saved);
03410   _dbus_string_free (&entry_value_signature);
03411   _dbus_string_free (&dict_entry_signature);
03412   return FALSE;
03413 }
03414 
03415 static dbus_bool_t
03416 dict_read_or_set_value (TestTypeNode   *node,
03417                         DBusTypeReader *reader,
03418                         DBusTypeReader *realign_root,
03419                         int             seed)
03420 {
03421   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03422   DBusTypeReader sub;
03423   int i;
03424   int n_entries;
03425   TestTypeNode *child;
03426 
03427   n_entries = node->klass->subclass_detail;
03428 
03429   check_expected_type (reader, DBUS_TYPE_ARRAY);
03430 
03431   child = _dbus_list_get_first (&container->children);
03432 
03433   if (n_entries > 0)
03434     {
03435       _dbus_type_reader_recurse (reader, &sub);
03436 
03437       check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
03438       
03439       i = 0;
03440       while (i < n_entries)
03441         {
03442           DBusTypeReader entry_sub;
03443 
03444           check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
03445           
03446           _dbus_type_reader_recurse (&sub, &entry_sub);
03447           
03448           if (realign_root == NULL)
03449             {
03450               dbus_int32_t v;
03451               
03452               check_expected_type (&entry_sub, DBUS_TYPE_INT32);
03453 
03454               _dbus_type_reader_read_basic (&entry_sub,
03455                                             (dbus_int32_t*) &v);
03456 
03457               _dbus_assert (v == int32_from_seed (seed + i));
03458 
03459               NEXT_EXPECTING_TRUE (&entry_sub);
03460               
03461               if (!node_read_value (child, &entry_sub, seed + i))
03462                 return FALSE;
03463 
03464               NEXT_EXPECTING_FALSE (&entry_sub);
03465             }
03466           else
03467             {
03468               dbus_int32_t v;
03469               
03470               v = int32_from_seed (seed + i);
03471               
03472               if (!_dbus_type_reader_set_basic (&entry_sub,
03473                                                 &v,
03474                                                 realign_root))
03475                 return FALSE;
03476 
03477               NEXT_EXPECTING_TRUE (&entry_sub);
03478               
03479               if (!node_set_value (child, &entry_sub, realign_root, seed + i))
03480                 return FALSE;
03481 
03482               NEXT_EXPECTING_FALSE (&entry_sub);
03483             }
03484           
03485           if (i == (n_entries - 1))
03486             NEXT_EXPECTING_FALSE (&sub);
03487           else
03488             NEXT_EXPECTING_TRUE (&sub);
03489 
03490           ++i;
03491         }
03492     }
03493 
03494   return TRUE;
03495 }
03496 
03497 static dbus_bool_t
03498 dict_read_value (TestTypeNode   *node,
03499                  DBusTypeReader *reader,
03500                  int             seed)
03501 {
03502   return dict_read_or_set_value (node, reader, NULL, seed);
03503 }
03504 
03505 static dbus_bool_t
03506 dict_set_value (TestTypeNode   *node,
03507                 DBusTypeReader *reader,
03508                 DBusTypeReader *realign_root,
03509                 int             seed)
03510 {
03511   return dict_read_or_set_value (node, reader, realign_root, seed);
03512 }
03513 
03514 static dbus_bool_t
03515 dict_build_signature (TestTypeNode   *node,
03516                       DBusString     *str)
03517 {
03518   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03519   int orig_len;
03520 
03521   orig_len = _dbus_string_get_length (str);
03522 
03523   if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
03524     goto oom;
03525 
03526   if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
03527     goto oom;
03528   
03529   if (!node_build_signature (_dbus_list_get_first (&container->children),
03530                              str))
03531     goto oom;
03532 
03533   if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
03534     goto oom;
03535 
03536   return TRUE;
03537 
03538  oom:
03539   _dbus_string_set_length (str, orig_len);
03540   return FALSE;
03541 }
03542 
03543 static void
03544 container_destroy (TestTypeNode *node)
03545 {
03546   TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03547   DBusList *link;
03548 
03549   link = _dbus_list_get_first_link (&container->children);
03550   while (link != NULL)
03551     {
03552       TestTypeNode *child = link->data;
03553       DBusList *next = _dbus_list_get_next_link (&container->children, link);
03554 
03555       node_destroy (child);
03556 
03557       _dbus_list_free_link (link);
03558 
03559       link = next;
03560     }
03561 }
03562 
03563 #endif 
03564 
03565 #endif