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