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 NULL;
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 DBusTypeReader restored;
00987
00988 if (!(* node->klass->read_value) (node, reader, seed))
00989 return FALSE;
00990
00991 return TRUE;
00992 }
00993
00994
00995
00996
00997
00998 static dbus_bool_t
00999 node_set_value (TestTypeNode *node,
01000 DBusTypeReader *reader,
01001 DBusTypeReader *realign_root,
01002 int seed)
01003 {
01004 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
01005 return FALSE;
01006
01007 return TRUE;
01008 }
01009
01010 static dbus_bool_t
01011 node_build_signature (TestTypeNode *node,
01012 DBusString *str)
01013 {
01014 if (node->klass->build_signature)
01015 return (* node->klass->build_signature) (node, str);
01016 else
01017 return _dbus_string_append_byte (str, node->klass->typecode);
01018 }
01019
01020 static dbus_bool_t
01021 node_append_child (TestTypeNode *node,
01022 TestTypeNode *child)
01023 {
01024 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01025
01026 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
01027
01028 if (!_dbus_list_append (&container->children, child))
01029 _dbus_assert_not_reached ("no memory");
01030
01031 return TRUE;
01032 }
01033
01034 static dbus_bool_t
01035 node_write_multi (TestTypeNode *node,
01036 DataBlock *block,
01037 DBusTypeWriter *writer,
01038 int seed,
01039 int n_copies)
01040 {
01041 dbus_bool_t retval;
01042
01043 _dbus_assert (node->klass->write_multi != NULL);
01044 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
01045
01046 #if 0
01047
01048 data_block_verify (block);
01049 #endif
01050
01051 return retval;
01052 }
01053
01054 static dbus_bool_t
01055 node_read_multi (TestTypeNode *node,
01056 DBusTypeReader *reader,
01057 int seed,
01058 int n_copies)
01059 {
01060 _dbus_assert (node->klass->read_multi != NULL);
01061
01062 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
01063 return FALSE;
01064
01065 return TRUE;
01066 }
01067
01068 static int n_iterations_completed_total = 0;
01069 static int n_iterations_completed_this_test = 0;
01070 static int n_iterations_expected_this_test = 0;
01071
01072 typedef struct
01073 {
01074 const DBusString *signature;
01075 DataBlock *block;
01076 int type_offset;
01077 TestTypeNode **nodes;
01078 int n_nodes;
01079 } NodeIterationData;
01080
01081 static dbus_bool_t
01082 run_test_copy (NodeIterationData *nid)
01083 {
01084 DataBlock *src;
01085 DataBlock dest;
01086 dbus_bool_t retval;
01087 DBusTypeReader reader;
01088 DBusTypeWriter writer;
01089
01090 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01091
01092 src = nid->block;
01093
01094 retval = FALSE;
01095
01096 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
01097 return FALSE;
01098
01099 data_block_init_reader_writer (src, &reader, NULL);
01100 data_block_init_reader_writer (&dest, NULL, &writer);
01101
01102
01103
01104
01105 if (!_dbus_string_insert_byte (&dest.signature,
01106 dest.initial_offset, '\0'))
01107 goto out;
01108
01109 if (!_dbus_type_writer_write_reader (&writer, &reader))
01110 goto out;
01111
01112
01113 if (!_dbus_string_equal (&src->signature, &dest.signature))
01114 {
01115 _dbus_verbose ("SOURCE\n");
01116 _dbus_verbose_bytes_of_string (&src->signature, 0,
01117 _dbus_string_get_length (&src->signature));
01118 _dbus_verbose ("DEST\n");
01119 _dbus_verbose_bytes_of_string (&dest.signature, 0,
01120 _dbus_string_get_length (&dest.signature));
01121 _dbus_assert_not_reached ("signatures did not match");
01122 }
01123
01124 if (!_dbus_string_equal (&src->body, &dest.body))
01125 {
01126 _dbus_verbose ("SOURCE\n");
01127 _dbus_verbose_bytes_of_string (&src->body, 0,
01128 _dbus_string_get_length (&src->body));
01129 _dbus_verbose ("DEST\n");
01130 _dbus_verbose_bytes_of_string (&dest.body, 0,
01131 _dbus_string_get_length (&dest.body));
01132 _dbus_assert_not_reached ("bodies did not match");
01133 }
01134
01135 retval = TRUE;
01136
01137 out:
01138
01139 data_block_free (&dest);
01140
01141 return retval;
01142 }
01143
01144 static dbus_bool_t
01145 run_test_values_only_write (NodeIterationData *nid)
01146 {
01147 DBusTypeReader reader;
01148 DBusTypeWriter writer;
01149 int i;
01150 dbus_bool_t retval;
01151 int sig_len;
01152
01153 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01154
01155 retval = FALSE;
01156
01157 data_block_reset (nid->block);
01158
01159 sig_len = _dbus_string_get_length (nid->signature);
01160
01161 _dbus_type_writer_init_values_only (&writer,
01162 nid->block->byte_order,
01163 nid->signature, 0,
01164 &nid->block->body,
01165 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
01166 _dbus_type_reader_init (&reader,
01167 nid->block->byte_order,
01168 nid->signature, 0,
01169 &nid->block->body,
01170 nid->block->initial_offset);
01171
01172 i = 0;
01173 while (i < nid->n_nodes)
01174 {
01175 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
01176 goto out;
01177
01178 ++i;
01179 }
01180
01181
01182 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
01183
01184
01185 i = 0;
01186 while (i < nid->n_nodes)
01187 {
01188 if (!node_read_value (nid->nodes[i], &reader, i))
01189 goto out;
01190
01191 if (i + 1 == nid->n_nodes)
01192 NEXT_EXPECTING_FALSE (&reader);
01193 else
01194 NEXT_EXPECTING_TRUE (&reader);
01195
01196 ++i;
01197 }
01198
01199 retval = TRUE;
01200
01201 out:
01202 data_block_reset (nid->block);
01203 return retval;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212 #define SET_SEED 1
01213 static dbus_bool_t
01214 run_test_set_values (NodeIterationData *nid)
01215 {
01216 DBusTypeReader reader;
01217 DBusTypeReader realign_root;
01218 dbus_bool_t retval;
01219 int i;
01220
01221 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01222
01223 retval = FALSE;
01224
01225 data_block_init_reader_writer (nid->block,
01226 &reader, NULL);
01227
01228 realign_root = reader;
01229
01230 i = 0;
01231 while (i < nid->n_nodes)
01232 {
01233 if (!node_set_value (nid->nodes[i],
01234 &reader, &realign_root,
01235 i + SET_SEED))
01236 goto out;
01237
01238 if (i + 1 == nid->n_nodes)
01239 NEXT_EXPECTING_FALSE (&reader);
01240 else
01241 NEXT_EXPECTING_TRUE (&reader);
01242
01243 ++i;
01244 }
01245
01246
01247
01248 reader = realign_root;
01249
01250 i = 0;
01251 while (i < nid->n_nodes)
01252 {
01253 if (!node_read_value (nid->nodes[i], &reader,
01254 i + SET_SEED))
01255 goto out;
01256
01257 if (i + 1 == nid->n_nodes)
01258 NEXT_EXPECTING_FALSE (&reader);
01259 else
01260 NEXT_EXPECTING_TRUE (&reader);
01261
01262 ++i;
01263 }
01264
01265 retval = TRUE;
01266
01267 out:
01268 return retval;
01269 }
01270
01271 static dbus_bool_t
01272 run_test_delete_values (NodeIterationData *nid)
01273 {
01274 DBusTypeReader reader;
01275 dbus_bool_t retval;
01276 int t;
01277
01278 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
01279
01280 retval = FALSE;
01281
01282 data_block_init_reader_writer (nid->block,
01283 &reader, NULL);
01284
01285 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
01286 {
01287
01288
01289
01290
01291 if (t == DBUS_TYPE_ARRAY)
01292 {
01293 DBusTypeReader array;
01294 int n_elements;
01295 int elem_type;
01296
01297 _dbus_type_reader_recurse (&reader, &array);
01298 n_elements = 0;
01299 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
01300 {
01301 n_elements += 1;
01302 _dbus_type_reader_next (&array);
01303 }
01304
01305
01306 _dbus_type_reader_recurse (&reader, &array);
01307 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
01308 reader.value_pos, array.value_pos, array.u.array.start_pos);
01309 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
01310 {
01311
01312 static int cycle = 0;
01313 int elem;
01314
01315 _dbus_assert (n_elements > 0);
01316
01317 elem = cycle;
01318 if (elem == 3 || elem >= n_elements)
01319 elem = n_elements - 1;
01320
01321 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
01322 elem, n_elements, _dbus_type_to_string (elem_type),
01323 cycle, reader.value_pos, array.value_pos);
01324 while (elem > 0)
01325 {
01326 if (!_dbus_type_reader_next (&array))
01327 _dbus_assert_not_reached ("should have had another element\n");
01328 --elem;
01329 }
01330
01331 if (!_dbus_type_reader_delete (&array, &reader))
01332 goto out;
01333
01334 n_elements -= 1;
01335
01336
01337 _dbus_type_reader_recurse (&reader, &array);
01338
01339 if (cycle > 2)
01340 cycle = 0;
01341 else
01342 cycle += 1;
01343 }
01344 }
01345 _dbus_type_reader_next (&reader);
01346 }
01347
01348
01349 data_block_init_reader_writer (nid->block,
01350 &reader, NULL);
01351
01352 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
01353 {
01354 _dbus_type_reader_next (&reader);
01355 }
01356
01357 retval = TRUE;
01358
01359 out:
01360 return retval;
01361 }
01362
01363 static dbus_bool_t
01364 run_test_nodes_iteration (void *data)
01365 {
01366 NodeIterationData *nid = data;
01367 DBusTypeReader reader;
01368 DBusTypeWriter writer;
01369 int i;
01370 dbus_bool_t retval;
01371
01372
01373
01374
01375
01376
01377
01378 retval = FALSE;
01379
01380 data_block_init_reader_writer (nid->block,
01381 &reader, &writer);
01382
01383
01384
01385
01386 if (!_dbus_string_insert_byte (&nid->block->signature,
01387 nid->type_offset, '\0'))
01388 goto out;
01389
01390 i = 0;
01391 while (i < nid->n_nodes)
01392 {
01393 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
01394 goto out;
01395
01396 ++i;
01397 }
01398
01399 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
01400 &nid->block->signature, nid->type_offset))
01401 {
01402 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
01403 _dbus_string_get_const_data (nid->signature),
01404 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
01405 nid->type_offset);
01406 _dbus_assert_not_reached ("wrong signature");
01407 }
01408
01409 i = 0;
01410 while (i < nid->n_nodes)
01411 {
01412 if (!node_read_value (nid->nodes[i], &reader, i))
01413 goto out;
01414
01415 if (i + 1 == nid->n_nodes)
01416 NEXT_EXPECTING_FALSE (&reader);
01417 else
01418 NEXT_EXPECTING_TRUE (&reader);
01419
01420 ++i;
01421 }
01422
01423 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
01424 {
01425
01426
01427
01428
01429
01430
01431
01432 if (!run_test_set_values (nid))
01433 goto out;
01434
01435 if (!run_test_delete_values (nid))
01436 goto out;
01437
01438 if (!run_test_copy (nid))
01439 goto out;
01440
01441 if (!run_test_values_only_write (nid))
01442 goto out;
01443 }
01444
01445
01446
01447
01448
01449 retval = TRUE;
01450
01451 out:
01452
01453 data_block_reset (nid->block);
01454
01455 return retval;
01456 }
01457
01458 static void
01459 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
01460 int n_nodes,
01461 const DBusString *signature,
01462 int byte_order,
01463 int initial_offset)
01464 {
01465 DataBlock block;
01466 NodeIterationData nid;
01467
01468 if (!data_block_init (&block, byte_order, initial_offset))
01469 _dbus_assert_not_reached ("no memory");
01470
01471 nid.signature = signature;
01472 nid.block = █
01473 nid.type_offset = initial_offset;
01474 nid.nodes = nodes;
01475 nid.n_nodes = n_nodes;
01476
01477 if (TEST_OOM_HANDLING &&
01478 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
01479 {
01480 _dbus_test_oom_handling ("running test node",
01481 run_test_nodes_iteration,
01482 &nid);
01483 }
01484 else
01485 {
01486 if (!run_test_nodes_iteration (&nid))
01487 _dbus_assert_not_reached ("no memory");
01488 }
01489
01490 data_block_free (&block);
01491 }
01492
01493 static void
01494 run_test_nodes (TestTypeNode **nodes,
01495 int n_nodes)
01496 {
01497 int i;
01498 DBusString signature;
01499
01500 if (!_dbus_string_init (&signature))
01501 _dbus_assert_not_reached ("no memory");
01502
01503 i = 0;
01504 while (i < n_nodes)
01505 {
01506 if (! node_build_signature (nodes[i], &signature))
01507 _dbus_assert_not_reached ("no memory");
01508
01509 ++i;
01510 }
01511
01512 _dbus_verbose (">>> test nodes with signature '%s'\n",
01513 _dbus_string_get_const_data (&signature));
01514
01515 i = 0;
01516 while (i <= MAX_INITIAL_OFFSET)
01517 {
01518 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
01519 DBUS_LITTLE_ENDIAN, i);
01520 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
01521 DBUS_BIG_ENDIAN, i);
01522
01523 ++i;
01524 }
01525
01526 n_iterations_completed_this_test += 1;
01527 n_iterations_completed_total += 1;
01528
01529 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
01530 {
01531 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
01532 n_iterations_completed_this_test,
01533 n_iterations_completed_total);
01534 }
01535
01536 else if ((n_iterations_completed_this_test %
01537 (int)(n_iterations_expected_this_test / 10.0)) == 1)
01538 {
01539 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
01540 }
01541
01542 _dbus_string_free (&signature);
01543 }
01544
01545 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
01546
01547 static TestTypeNode*
01548 value_generator (int *ip)
01549 {
01550 int i = *ip;
01551 const TestTypeNodeClass *child_klass;
01552 const TestTypeNodeClass *container_klass;
01553 TestTypeNode *child;
01554 TestTypeNode *node;
01555
01556 _dbus_assert (i <= N_VALUES);
01557
01558 if (i == N_VALUES)
01559 {
01560 return NULL;
01561 }
01562 else if (i < N_BASICS)
01563 {
01564 node = node_new (basic_nodes[i]);
01565 }
01566 else
01567 {
01568
01569
01570
01571
01572
01573
01574
01575
01576 i -= N_BASICS;
01577
01578 container_klass = container_nodes[i / N_BASICS];
01579 child_klass = basic_nodes[i % N_BASICS];
01580
01581 node = node_new (container_klass);
01582 child = node_new (child_klass);
01583
01584 node_append_child (node, child);
01585 }
01586
01587 *ip += 1;
01588
01589 return node;
01590 }
01591
01592 static void
01593 build_body (TestTypeNode **nodes,
01594 int n_nodes,
01595 int byte_order,
01596 DBusString *signature,
01597 DBusString *body)
01598 {
01599 int i;
01600 DataBlock block;
01601 DBusTypeReader reader;
01602 DBusTypeWriter writer;
01603
01604 i = 0;
01605 while (i < n_nodes)
01606 {
01607 if (! node_build_signature (nodes[i], signature))
01608 _dbus_assert_not_reached ("no memory");
01609
01610 ++i;
01611 }
01612
01613 if (!data_block_init (&block, byte_order, 0))
01614 _dbus_assert_not_reached ("no memory");
01615
01616 data_block_init_reader_writer (&block,
01617 &reader, &writer);
01618
01619
01620
01621
01622 if (!_dbus_string_insert_byte (&block.signature,
01623 0, '\0'))
01624 _dbus_assert_not_reached ("no memory");
01625
01626 i = 0;
01627 while (i < n_nodes)
01628 {
01629 if (!node_write_value (nodes[i], &block, &writer, i))
01630 _dbus_assert_not_reached ("no memory");
01631
01632 ++i;
01633 }
01634
01635 if (!_dbus_string_copy_len (&block.body, 0,
01636 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
01637 body, 0))
01638 _dbus_assert_not_reached ("oom");
01639
01640 data_block_free (&block);
01641 }
01642
01643 dbus_bool_t
01644 dbus_internal_do_not_use_generate_bodies (int sequence,
01645 int byte_order,
01646 DBusString *signature,
01647 DBusString *body)
01648 {
01649 TestTypeNode *nodes[1];
01650 int i;
01651 int n_nodes;
01652
01653 nodes[0] = value_generator (&sequence);
01654
01655 if (nodes[0] == NULL)
01656 return FALSE;
01657
01658 n_nodes = 1;
01659
01660 build_body (nodes, n_nodes, byte_order, signature, body);
01661
01662
01663 i = 0;
01664 while (i < n_nodes)
01665 {
01666 node_destroy (nodes[i]);
01667 ++i;
01668 }
01669
01670 return TRUE;
01671 }
01672
01673 static void
01674 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
01675 int n_nested)
01676 {
01677 TestTypeNode *root;
01678 TestTypeNode *container;
01679 TestTypeNode *child;
01680 int i;
01681
01682 root = node_new (container_klass);
01683 container = root;
01684 for (i = 1; i < n_nested; i++)
01685 {
01686 child = node_new (container_klass);
01687 node_append_child (container, child);
01688 container = child;
01689 }
01690
01691
01692
01693 i = 0;
01694 while ((child = value_generator (&i)))
01695 {
01696 node_append_child (container, child);
01697
01698 run_test_nodes (&root, 1);
01699
01700 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
01701 node_destroy (child);
01702 }
01703
01704 node_destroy (root);
01705 }
01706
01707 static void
01708 start_next_test (const char *format,
01709 int expected)
01710 {
01711 n_iterations_completed_this_test = 0;
01712 n_iterations_expected_this_test = expected;
01713
01714 fprintf (stderr, ">>> >>> ");
01715 fprintf (stderr, format,
01716 n_iterations_expected_this_test);
01717 }
01718
01719 static void
01720 make_and_run_test_nodes (void)
01721 {
01722 int i, j, k, m;
01723
01724
01725
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 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
01757 {
01758 TestTypeNode *node;
01759 i = 0;
01760 while ((node = value_generator (&i)))
01761 {
01762 run_test_nodes (&node, 1);
01763
01764 node_destroy (node);
01765 }
01766 }
01767
01768 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
01769 arrays_write_fixed_in_blocks = TRUE;
01770 {
01771 TestTypeNode *node;
01772 i = 0;
01773 while ((node = value_generator (&i)))
01774 {
01775 run_test_nodes (&node, 1);
01776
01777 node_destroy (node);
01778 }
01779 }
01780 arrays_write_fixed_in_blocks = FALSE;
01781
01782 start_next_test ("All values in one big toplevel %d iteration\n", 1);
01783 {
01784 TestTypeNode *nodes[N_VALUES];
01785
01786 i = 0;
01787 while ((nodes[i] = value_generator (&i)))
01788 ;
01789
01790 run_test_nodes (nodes, N_VALUES);
01791
01792 for (i = 0; i < N_VALUES; i++)
01793 node_destroy (nodes[i]);
01794 }
01795
01796 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
01797 N_VALUES * N_VALUES);
01798 {
01799 TestTypeNode *nodes[2];
01800
01801 i = 0;
01802 while ((nodes[0] = value_generator (&i)))
01803 {
01804 j = 0;
01805 while ((nodes[1] = value_generator (&j)))
01806 {
01807 run_test_nodes (nodes, 2);
01808
01809 node_destroy (nodes[1]);
01810 }
01811
01812 node_destroy (nodes[0]);
01813 }
01814 }
01815
01816 start_next_test ("Each container containing each value %d iterations\n",
01817 N_CONTAINERS * N_VALUES);
01818 for (i = 0; i < N_CONTAINERS; i++)
01819 {
01820 const TestTypeNodeClass *container_klass = container_nodes[i];
01821
01822 make_and_run_values_inside_container (container_klass, 1);
01823 }
01824
01825 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
01826 N_CONTAINERS * N_VALUES);
01827 arrays_write_fixed_in_blocks = TRUE;
01828 for (i = 0; i < N_CONTAINERS; i++)
01829 {
01830 const TestTypeNodeClass *container_klass = container_nodes[i];
01831
01832 make_and_run_values_inside_container (container_klass, 1);
01833 }
01834 arrays_write_fixed_in_blocks = FALSE;
01835
01836 start_next_test ("Each container of same container of each value %d iterations\n",
01837 N_CONTAINERS * N_VALUES);
01838 for (i = 0; i < N_CONTAINERS; i++)
01839 {
01840 const TestTypeNodeClass *container_klass = container_nodes[i];
01841
01842 make_and_run_values_inside_container (container_klass, 2);
01843 }
01844
01845 start_next_test ("Each container of same container of same container of each value %d iterations\n",
01846 N_CONTAINERS * N_VALUES);
01847 for (i = 0; i < N_CONTAINERS; i++)
01848 {
01849 const TestTypeNodeClass *container_klass = container_nodes[i];
01850
01851 make_and_run_values_inside_container (container_klass, 3);
01852 }
01853
01854 start_next_test ("Each value,value pair inside a struct %d iterations\n",
01855 N_VALUES * N_VALUES);
01856 {
01857 TestTypeNode *val1, *val2;
01858 TestTypeNode *node;
01859
01860 node = node_new (&struct_1_class);
01861
01862 i = 0;
01863 while ((val1 = value_generator (&i)))
01864 {
01865 j = 0;
01866 while ((val2 = value_generator (&j)))
01867 {
01868 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01869
01870 node_append_child (node, val1);
01871 node_append_child (node, val2);
01872
01873 run_test_nodes (&node, 1);
01874
01875 _dbus_list_clear (&container->children);
01876 node_destroy (val2);
01877 }
01878 node_destroy (val1);
01879 }
01880 node_destroy (node);
01881 }
01882
01883 start_next_test ("All values in one big struct %d iteration\n",
01884 1);
01885 {
01886 TestTypeNode *node;
01887 TestTypeNode *child;
01888
01889 node = node_new (&struct_1_class);
01890
01891 i = 0;
01892 while ((child = value_generator (&i)))
01893 node_append_child (node, child);
01894
01895 run_test_nodes (&node, 1);
01896
01897 node_destroy (node);
01898 }
01899
01900 start_next_test ("Each value in a large array %d iterations\n",
01901 N_VALUES);
01902 {
01903 TestTypeNode *val;
01904 TestTypeNode *node;
01905
01906 node = node_new (&array_9_class);
01907
01908 i = 0;
01909 while ((val = value_generator (&i)))
01910 {
01911 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
01912
01913 node_append_child (node, val);
01914
01915 run_test_nodes (&node, 1);
01916
01917 _dbus_list_clear (&container->children);
01918 node_destroy (val);
01919 }
01920
01921 node_destroy (node);
01922 }
01923
01924 start_next_test ("Each container of each container of each value %d iterations\n",
01925 N_CONTAINERS * N_CONTAINERS * N_VALUES);
01926 for (i = 0; i < N_CONTAINERS; i++)
01927 {
01928 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
01929 TestTypeNode *outer_container = node_new (outer_container_klass);
01930
01931 for (j = 0; j < N_CONTAINERS; j++)
01932 {
01933 TestTypeNode *child;
01934 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
01935 TestTypeNode *inner_container = node_new (inner_container_klass);
01936
01937 node_append_child (outer_container, inner_container);
01938
01939 m = 0;
01940 while ((child = value_generator (&m)))
01941 {
01942 node_append_child (inner_container, child);
01943
01944 run_test_nodes (&outer_container, 1);
01945
01946 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
01947 node_destroy (child);
01948 }
01949 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
01950 node_destroy (inner_container);
01951 }
01952 node_destroy (outer_container);
01953 }
01954
01955 start_next_test ("Each container of each container of each container of each value %d iterations\n",
01956 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
01957 for (i = 0; i < N_CONTAINERS; i++)
01958 {
01959 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
01960 TestTypeNode *outer_container = node_new (outer_container_klass);
01961
01962 for (j = 0; j < N_CONTAINERS; j++)
01963 {
01964 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
01965 TestTypeNode *inner_container = node_new (inner_container_klass);
01966
01967 node_append_child (outer_container, inner_container);
01968
01969 for (k = 0; k < N_CONTAINERS; k++)
01970 {
01971 TestTypeNode *child;
01972 const TestTypeNodeClass *center_container_klass = container_nodes[k];
01973 TestTypeNode *center_container = node_new (center_container_klass);
01974
01975 node_append_child (inner_container, center_container);
01976
01977 m = 0;
01978 while ((child = value_generator (&m)))
01979 {
01980 node_append_child (center_container, child);
01981
01982 run_test_nodes (&outer_container, 1);
01983
01984 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
01985 node_destroy (child);
01986 }
01987 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
01988 node_destroy (center_container);
01989 }
01990 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
01991 node_destroy (inner_container);
01992 }
01993 node_destroy (outer_container);
01994 }
01995
01996 #if 0
01997
01998 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
01999 N_VALUES * N_VALUES * N_VALUES);
02000 {
02001 TestTypeNode *nodes[3];
02002
02003 i = 0;
02004 while ((nodes[0] = value_generator (&i)))
02005 {
02006 j = 0;
02007 while ((nodes[1] = value_generator (&j)))
02008 {
02009 k = 0;
02010 while ((nodes[2] = value_generator (&k)))
02011 {
02012 run_test_nodes (nodes, 3);
02013
02014 node_destroy (nodes[2]);
02015 }
02016 node_destroy (nodes[1]);
02017 }
02018 node_destroy (nodes[0]);
02019 }
02020 }
02021 #endif
02022
02023 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
02024 n_iterations_completed_total);
02025 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
02026 MAX_INITIAL_OFFSET);
02027 fprintf (stderr, "out of memory handling %s tested\n",
02028 TEST_OOM_HANDLING ? "was" : "was not");
02029 }
02030
02031 dbus_bool_t
02032 _dbus_marshal_recursive_test (void)
02033 {
02034 make_and_run_test_nodes ();
02035
02036 return TRUE;
02037 }
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047 #define MAX_MULTI_COUNT 5
02048
02049 #define SAMPLE_INT16 1234
02050 #define SAMPLE_INT16_ALTERNATE 6785
02051 static dbus_int16_t
02052 int16_from_seed (int seed)
02053 {
02054
02055
02056
02057
02058 dbus_int16_t v;
02059
02060 v = 42;
02061 switch (seed % 5)
02062 {
02063 case 0:
02064 v = SAMPLE_INT16;
02065 break;
02066 case 1:
02067 v = SAMPLE_INT16_ALTERNATE;
02068 break;
02069 case 2:
02070 v = -1;
02071 break;
02072 case 3:
02073 v = _DBUS_INT16_MAX;
02074 break;
02075 case 4:
02076 v = 1;
02077 break;
02078 }
02079
02080 if (seed > 1)
02081 v *= seed;
02082
02083 return v;
02084 }
02085
02086 static dbus_bool_t
02087 int16_write_value (TestTypeNode *node,
02088 DataBlock *block,
02089 DBusTypeWriter *writer,
02090 int seed)
02091 {
02092
02093 dbus_int16_t v;
02094
02095 v = int16_from_seed (seed);
02096
02097 return _dbus_type_writer_write_basic (writer,
02098 node->klass->typecode,
02099 &v);
02100 }
02101
02102 static dbus_bool_t
02103 int16_read_value (TestTypeNode *node,
02104 DBusTypeReader *reader,
02105 int seed)
02106 {
02107
02108 dbus_int16_t v;
02109
02110 check_expected_type (reader, node->klass->typecode);
02111
02112 _dbus_type_reader_read_basic (reader,
02113 (dbus_int16_t*) &v);
02114
02115 _dbus_assert (v == int16_from_seed (seed));
02116
02117 return TRUE;
02118 }
02119
02120 static dbus_bool_t
02121 int16_set_value (TestTypeNode *node,
02122 DBusTypeReader *reader,
02123 DBusTypeReader *realign_root,
02124 int seed)
02125 {
02126
02127 dbus_int16_t v;
02128
02129 v = int16_from_seed (seed);
02130
02131 return _dbus_type_reader_set_basic (reader,
02132 &v,
02133 realign_root);
02134 }
02135
02136 static dbus_bool_t
02137 int16_write_multi (TestTypeNode *node,
02138 DataBlock *block,
02139 DBusTypeWriter *writer,
02140 int seed,
02141 int count)
02142 {
02143
02144 dbus_int16_t values[MAX_MULTI_COUNT];
02145 dbus_int16_t *v_ARRAY_INT16 = values;
02146 int i;
02147
02148 for (i = 0; i < count; ++i)
02149 values[i] = int16_from_seed (seed + i);
02150
02151 return _dbus_type_writer_write_fixed_multi (writer,
02152 node->klass->typecode,
02153 &v_ARRAY_INT16, count);
02154 }
02155
02156 static dbus_bool_t
02157 int16_read_multi (TestTypeNode *node,
02158 DBusTypeReader *reader,
02159 int seed,
02160 int count)
02161 {
02162
02163 dbus_int16_t *values;
02164 int n_elements;
02165 int i;
02166
02167 check_expected_type (reader, node->klass->typecode);
02168
02169 _dbus_type_reader_read_fixed_multi (reader,
02170 &values,
02171 &n_elements);
02172
02173 if (n_elements != count)
02174 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
02175 _dbus_assert (n_elements == count);
02176
02177 for (i = 0; i < count; i++)
02178 _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
02179 (const unsigned char*)values + (i * 2))) ==
02180 int16_from_seed (seed + i));
02181
02182 return TRUE;
02183 }
02184
02185
02186 #define SAMPLE_INT32 12345678
02187 #define SAMPLE_INT32_ALTERNATE 53781429
02188 static dbus_int32_t
02189 int32_from_seed (int seed)
02190 {
02191
02192
02193
02194
02195 dbus_int32_t v;
02196
02197 v = 42;
02198 switch (seed % 5)
02199 {
02200 case 0:
02201 v = SAMPLE_INT32;
02202 break;
02203 case 1:
02204 v = SAMPLE_INT32_ALTERNATE;
02205 break;
02206 case 2:
02207 v = -1;
02208 break;
02209 case 3:
02210 v = _DBUS_INT_MAX;
02211 break;
02212 case 4:
02213 v = 1;
02214 break;
02215 }
02216
02217 if (seed > 1)
02218 v *= seed;
02219
02220 return v;
02221 }
02222
02223 static dbus_bool_t
02224 int32_write_value (TestTypeNode *node,
02225 DataBlock *block,
02226 DBusTypeWriter *writer,
02227 int seed)
02228 {
02229
02230 dbus_int32_t v;
02231
02232 v = int32_from_seed (seed);
02233
02234 return _dbus_type_writer_write_basic (writer,
02235 node->klass->typecode,
02236 &v);
02237 }
02238
02239 static dbus_bool_t
02240 int32_read_value (TestTypeNode *node,
02241 DBusTypeReader *reader,
02242 int seed)
02243 {
02244
02245 dbus_int32_t v;
02246
02247 check_expected_type (reader, node->klass->typecode);
02248
02249 _dbus_type_reader_read_basic (reader,
02250 (dbus_int32_t*) &v);
02251
02252 _dbus_assert (v == int32_from_seed (seed));
02253
02254 return TRUE;
02255 }
02256
02257 static dbus_bool_t
02258 int32_set_value (TestTypeNode *node,
02259 DBusTypeReader *reader,
02260 DBusTypeReader *realign_root,
02261 int seed)
02262 {
02263
02264 dbus_int32_t v;
02265
02266 v = int32_from_seed (seed);
02267
02268 return _dbus_type_reader_set_basic (reader,
02269 &v,
02270 realign_root);
02271 }
02272
02273 static dbus_bool_t
02274 int32_write_multi (TestTypeNode *node,
02275 DataBlock *block,
02276 DBusTypeWriter *writer,
02277 int seed,
02278 int count)
02279 {
02280
02281 dbus_int32_t values[MAX_MULTI_COUNT];
02282 dbus_int32_t *v_ARRAY_INT32 = values;
02283 int i;
02284
02285 for (i = 0; i < count; ++i)
02286 values[i] = int32_from_seed (seed + i);
02287
02288 return _dbus_type_writer_write_fixed_multi (writer,
02289 node->klass->typecode,
02290 &v_ARRAY_INT32, count);
02291 }
02292
02293 static dbus_bool_t
02294 int32_read_multi (TestTypeNode *node,
02295 DBusTypeReader *reader,
02296 int seed,
02297 int count)
02298 {
02299
02300 dbus_int32_t *values;
02301 int n_elements;
02302 int i;
02303
02304 check_expected_type (reader, node->klass->typecode);
02305
02306 _dbus_type_reader_read_fixed_multi (reader,
02307 &values,
02308 &n_elements);
02309
02310 if (n_elements != count)
02311 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
02312 _dbus_assert (n_elements == count);
02313
02314 for (i = 0; i < count; i++)
02315 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
02316 (const unsigned char*)values + (i * 4))) ==
02317 int32_from_seed (seed + i));
02318
02319 return TRUE;
02320 }
02321
02322 #ifdef DBUS_HAVE_INT64
02323 static dbus_int64_t
02324 int64_from_seed (int seed)
02325 {
02326 dbus_int32_t v32;
02327 dbus_int64_t v;
02328
02329 v32 = int32_from_seed (seed);
02330
02331 v = - (dbus_int32_t) ~ v32;
02332 v |= (((dbus_int64_t)v32) << 32);
02333
02334 return v;
02335 }
02336 #endif
02337
02338 static dbus_bool_t
02339 int64_write_value (TestTypeNode *node,
02340 DataBlock *block,
02341 DBusTypeWriter *writer,
02342 int seed)
02343 {
02344 #ifdef DBUS_HAVE_INT64
02345
02346 dbus_int64_t v;
02347
02348 v = int64_from_seed (seed);
02349
02350 return _dbus_type_writer_write_basic (writer,
02351 node->klass->typecode,
02352 &v);
02353 #else
02354 return TRUE;
02355 #endif
02356 }
02357
02358 static dbus_bool_t
02359 int64_read_value (TestTypeNode *node,
02360 DBusTypeReader *reader,
02361 int seed)
02362 {
02363 #ifdef DBUS_HAVE_INT64
02364
02365 dbus_int64_t v;
02366
02367 check_expected_type (reader, node->klass->typecode);
02368
02369 _dbus_type_reader_read_basic (reader,
02370 (dbus_int64_t*) &v);
02371
02372 _dbus_assert (v == int64_from_seed (seed));
02373
02374 return TRUE;
02375 #else
02376 return TRUE;
02377 #endif
02378 }
02379
02380 static dbus_bool_t
02381 int64_set_value (TestTypeNode *node,
02382 DBusTypeReader *reader,
02383 DBusTypeReader *realign_root,
02384 int seed)
02385 {
02386 #ifdef DBUS_HAVE_INT64
02387
02388 dbus_int64_t v;
02389
02390 v = int64_from_seed (seed);
02391
02392 return _dbus_type_reader_set_basic (reader,
02393 &v,
02394 realign_root);
02395 #else
02396 return TRUE;
02397 #endif
02398 }
02399
02400 #define MAX_SAMPLE_STRING_LEN 10
02401 static void
02402 string_from_seed (char *buf,
02403 int len,
02404 int seed)
02405 {
02406 int i;
02407 unsigned char v;
02408
02409 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
02410
02411
02412
02413
02414 switch (seed % 3)
02415 {
02416 case 1:
02417 len += 2;
02418 break;
02419 case 2:
02420 len -= 2;
02421 break;
02422 }
02423 if (len < 0)
02424 len = 0;
02425
02426 v = (unsigned char) ('A' + seed);
02427
02428 i = 0;
02429 while (i < len)
02430 {
02431 if (v < 'A' || v > 'z')
02432 v = 'A';
02433
02434 buf[i] = v;
02435
02436 v += 1;
02437 ++i;
02438 }
02439
02440 buf[i] = '\0';
02441 }
02442
02443 static dbus_bool_t
02444 string_write_value (TestTypeNode *node,
02445 DataBlock *block,
02446 DBusTypeWriter *writer,
02447 int seed)
02448 {
02449 char buf[MAX_SAMPLE_STRING_LEN + 1]="";
02450 const char *v_string = buf;
02451
02452
02453 string_from_seed (buf, node->klass->subclass_detail,
02454 seed);
02455
02456 return _dbus_type_writer_write_basic (writer,
02457 node->klass->typecode,
02458 &v_string);
02459 }
02460
02461 static dbus_bool_t
02462 string_read_value (TestTypeNode *node,
02463 DBusTypeReader *reader,
02464 int seed)
02465 {
02466 const char *v;
02467 char buf[MAX_SAMPLE_STRING_LEN + 1];
02468 v = buf;
02469
02470 check_expected_type (reader, node->klass->typecode);
02471
02472 _dbus_type_reader_read_basic (reader,
02473 (const char **) &v);
02474
02475 string_from_seed (buf, node->klass->subclass_detail,
02476 seed);
02477
02478 if (strcmp (buf, v) != 0)
02479 {
02480 _dbus_warn ("read string '%s' expected '%s'\n",
02481 v, buf);
02482 _dbus_assert_not_reached ("test failed");
02483 }
02484
02485 return TRUE;
02486 }
02487
02488 static dbus_bool_t
02489 string_set_value (TestTypeNode *node,
02490 DBusTypeReader *reader,
02491 DBusTypeReader *realign_root,
02492 int seed)
02493 {
02494 char buf[MAX_SAMPLE_STRING_LEN + 1];
02495 const char *v_string = buf;
02496
02497 string_from_seed (buf, node->klass->subclass_detail,
02498 seed);
02499
02500 #if RECURSIVE_MARSHAL_WRITE_TRACE
02501 {
02502 const char *old;
02503 _dbus_type_reader_read_basic (reader, &old);
02504 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
02505 v_string, strlen (v_string), old, strlen (old));
02506 }
02507 #endif
02508
02509 return _dbus_type_reader_set_basic (reader,
02510 &v_string,
02511 realign_root);
02512 }
02513
02514 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
02515
02516 static dbus_bool_t
02517 bool_write_value (TestTypeNode *node,
02518 DataBlock *block,
02519 DBusTypeWriter *writer,
02520 int seed)
02521 {
02522 dbus_bool_t v;
02523
02524 v = BOOL_FROM_SEED (seed);
02525
02526 return _dbus_type_writer_write_basic (writer,
02527 node->klass->typecode,
02528 &v);
02529 }
02530
02531 static dbus_bool_t
02532 bool_read_value (TestTypeNode *node,
02533 DBusTypeReader *reader,
02534 int seed)
02535 {
02536 dbus_bool_t v;
02537
02538 check_expected_type (reader, node->klass->typecode);
02539
02540 _dbus_type_reader_read_basic (reader,
02541 (unsigned char*) &v);
02542
02543 _dbus_assert (v == BOOL_FROM_SEED (seed));
02544
02545 return TRUE;
02546 }
02547
02548 static dbus_bool_t
02549 bool_set_value (TestTypeNode *node,
02550 DBusTypeReader *reader,
02551 DBusTypeReader *realign_root,
02552 int seed)
02553 {
02554 dbus_bool_t v;
02555
02556 v = BOOL_FROM_SEED (seed);
02557
02558 return _dbus_type_reader_set_basic (reader,
02559 &v,
02560 realign_root);
02561 }
02562
02563 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
02564
02565 static dbus_bool_t
02566 byte_write_value (TestTypeNode *node,
02567 DataBlock *block,
02568 DBusTypeWriter *writer,
02569 int seed)
02570 {
02571 unsigned char v;
02572
02573 v = BYTE_FROM_SEED (seed);
02574
02575 return _dbus_type_writer_write_basic (writer,
02576 node->klass->typecode,
02577 &v);
02578 }
02579
02580 static dbus_bool_t
02581 byte_read_value (TestTypeNode *node,
02582 DBusTypeReader *reader,
02583 int seed)
02584 {
02585 unsigned char v;
02586
02587 check_expected_type (reader, node->klass->typecode);
02588
02589 _dbus_type_reader_read_basic (reader,
02590 (unsigned char*) &v);
02591
02592 _dbus_assert (v == BYTE_FROM_SEED (seed));
02593
02594 return TRUE;
02595 }
02596
02597
02598 static dbus_bool_t
02599 byte_set_value (TestTypeNode *node,
02600 DBusTypeReader *reader,
02601 DBusTypeReader *realign_root,
02602 int seed)
02603 {
02604 unsigned char v;
02605
02606 v = BYTE_FROM_SEED (seed);
02607
02608 return _dbus_type_reader_set_basic (reader,
02609 &v,
02610 realign_root);
02611 }
02612
02613 static double
02614 double_from_seed (int seed)
02615 {
02616 return SAMPLE_INT32 * (double) seed + 0.3;
02617 }
02618
02619 static dbus_bool_t
02620 double_write_value (TestTypeNode *node,
02621 DataBlock *block,
02622 DBusTypeWriter *writer,
02623 int seed)
02624 {
02625 double v;
02626
02627 v = double_from_seed (seed);
02628
02629 return _dbus_type_writer_write_basic (writer,
02630 node->klass->typecode,
02631 &v);
02632 }
02633
02634 static dbus_bool_t
02635 double_read_value (TestTypeNode *node,
02636 DBusTypeReader *reader,
02637 int seed)
02638 {
02639 double v;
02640 double expected;
02641
02642 check_expected_type (reader, node->klass->typecode);
02643
02644 _dbus_type_reader_read_basic (reader,
02645 (double*) &v);
02646
02647 expected = double_from_seed (seed);
02648
02649 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
02650 {
02651 #ifdef DBUS_HAVE_INT64
02652 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
02653 expected, v,
02654 *(dbus_uint64_t*)(char*)&expected,
02655 *(dbus_uint64_t*)(char*)&v);
02656 #endif
02657 _dbus_assert_not_reached ("test failed");
02658 }
02659
02660 return TRUE;
02661 }
02662
02663 static dbus_bool_t
02664 double_set_value (TestTypeNode *node,
02665 DBusTypeReader *reader,
02666 DBusTypeReader *realign_root,
02667 int seed)
02668 {
02669 double v;
02670
02671 v = double_from_seed (seed);
02672
02673 return _dbus_type_reader_set_basic (reader,
02674 &v,
02675 realign_root);
02676 }
02677
02678 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
02679 static void
02680 object_path_from_seed (char *buf,
02681 int seed)
02682 {
02683 int i;
02684 unsigned char v;
02685 int len;
02686
02687 len = seed % 9;
02688 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
02689
02690 v = (unsigned char) ('A' + seed);
02691
02692 if (len < 2)
02693 {
02694 buf[0] = '/';
02695 i = 1;
02696 }
02697 else
02698 {
02699 i = 0;
02700 while (i + 1 < len)
02701 {
02702 if (v < 'A' || v > 'z')
02703 v = 'A';
02704
02705 buf[i] = '/';
02706 ++i;
02707 buf[i] = v;
02708 ++i;
02709
02710 v += 1;
02711 }
02712 }
02713
02714 buf[i] = '\0';
02715 }
02716
02717 static dbus_bool_t
02718 object_path_write_value (TestTypeNode *node,
02719 DataBlock *block,
02720 DBusTypeWriter *writer,
02721 int seed)
02722 {
02723 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02724 const char *v_string = buf;
02725
02726 object_path_from_seed (buf, seed);
02727
02728 return _dbus_type_writer_write_basic (writer,
02729 node->klass->typecode,
02730 &v_string);
02731 }
02732
02733 static dbus_bool_t
02734 object_path_read_value (TestTypeNode *node,
02735 DBusTypeReader *reader,
02736 int seed)
02737 {
02738 const char *v;
02739 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02740
02741 check_expected_type (reader, node->klass->typecode);
02742
02743 _dbus_type_reader_read_basic (reader,
02744 (const char **) &v);
02745
02746 object_path_from_seed (buf, seed);
02747
02748 if (strcmp (buf, v) != 0)
02749 {
02750 _dbus_warn ("read object path '%s' expected '%s'\n",
02751 v, buf);
02752 _dbus_assert_not_reached ("test failed");
02753 }
02754
02755 return TRUE;
02756 }
02757
02758 static dbus_bool_t
02759 object_path_set_value (TestTypeNode *node,
02760 DBusTypeReader *reader,
02761 DBusTypeReader *realign_root,
02762 int seed)
02763 {
02764 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
02765 const char *v_string = buf;
02766
02767 object_path_from_seed (buf, seed);
02768
02769 return _dbus_type_reader_set_basic (reader,
02770 &v_string,
02771 realign_root);
02772 }
02773
02774 #define MAX_SAMPLE_SIGNATURE_LEN 10
02775 static void
02776 signature_from_seed (char *buf,
02777 int seed)
02778 {
02779
02780 const char *sample_signatures[] = {
02781 "asax"
02782 "",
02783 "asau(xxxx)",
02784 "x",
02785 "ai",
02786 "a(ii)"
02787 };
02788
02789 strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
02790 }
02791
02792 static dbus_bool_t
02793 signature_write_value (TestTypeNode *node,
02794 DataBlock *block,
02795 DBusTypeWriter *writer,
02796 int seed)
02797 {
02798 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02799 const char *v_string = buf;
02800
02801 signature_from_seed (buf, seed);
02802
02803 return _dbus_type_writer_write_basic (writer,
02804 node->klass->typecode,
02805 &v_string);
02806 }
02807
02808 static dbus_bool_t
02809 signature_read_value (TestTypeNode *node,
02810 DBusTypeReader *reader,
02811 int seed)
02812 {
02813 const char *v;
02814 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02815
02816 check_expected_type (reader, node->klass->typecode);
02817
02818 _dbus_type_reader_read_basic (reader,
02819 (const char **) &v);
02820
02821 signature_from_seed (buf, seed);
02822
02823 if (strcmp (buf, v) != 0)
02824 {
02825 _dbus_warn ("read signature value '%s' expected '%s'\n",
02826 v, buf);
02827 _dbus_assert_not_reached ("test failed");
02828 }
02829
02830 return TRUE;
02831 }
02832
02833
02834 static dbus_bool_t
02835 signature_set_value (TestTypeNode *node,
02836 DBusTypeReader *reader,
02837 DBusTypeReader *realign_root,
02838 int seed)
02839 {
02840 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
02841 const char *v_string = buf;
02842
02843 signature_from_seed (buf, seed);
02844
02845 return _dbus_type_reader_set_basic (reader,
02846 &v_string,
02847 realign_root);
02848 }
02849
02850 static dbus_bool_t
02851 struct_write_value (TestTypeNode *node,
02852 DataBlock *block,
02853 DBusTypeWriter *writer,
02854 int seed)
02855 {
02856 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02857 DataBlockState saved;
02858 DBusTypeWriter sub;
02859 int i;
02860 int n_copies;
02861
02862 n_copies = node->klass->subclass_detail;
02863
02864 _dbus_assert (container->children != NULL);
02865
02866 data_block_save (block, &saved);
02867
02868 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
02869 NULL, 0,
02870 &sub))
02871 return FALSE;
02872
02873 i = 0;
02874 while (i < n_copies)
02875 {
02876 DBusList *link;
02877
02878 link = _dbus_list_get_first_link (&container->children);
02879 while (link != NULL)
02880 {
02881 TestTypeNode *child = link->data;
02882 DBusList *next = _dbus_list_get_next_link (&container->children, link);
02883
02884 if (!node_write_value (child, block, &sub, seed + i))
02885 {
02886 data_block_restore (block, &saved);
02887 return FALSE;
02888 }
02889
02890 link = next;
02891 }
02892
02893 ++i;
02894 }
02895
02896 if (!_dbus_type_writer_unrecurse (writer, &sub))
02897 {
02898 data_block_restore (block, &saved);
02899 return FALSE;
02900 }
02901
02902 return TRUE;
02903 }
02904
02905 static dbus_bool_t
02906 struct_read_or_set_value (TestTypeNode *node,
02907 DBusTypeReader *reader,
02908 DBusTypeReader *realign_root,
02909 int seed)
02910 {
02911 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02912 DBusTypeReader sub;
02913 int i;
02914 int n_copies;
02915
02916 n_copies = node->klass->subclass_detail;
02917
02918 check_expected_type (reader, DBUS_TYPE_STRUCT);
02919
02920 _dbus_type_reader_recurse (reader, &sub);
02921
02922 i = 0;
02923 while (i < n_copies)
02924 {
02925 DBusList *link;
02926
02927 link = _dbus_list_get_first_link (&container->children);
02928 while (link != NULL)
02929 {
02930 TestTypeNode *child = link->data;
02931 DBusList *next = _dbus_list_get_next_link (&container->children, link);
02932
02933 if (realign_root == NULL)
02934 {
02935 if (!node_read_value (child, &sub, seed + i))
02936 return FALSE;
02937 }
02938 else
02939 {
02940 if (!node_set_value (child, &sub, realign_root, seed + i))
02941 return FALSE;
02942 }
02943
02944 if (i == (n_copies - 1) && next == NULL)
02945 NEXT_EXPECTING_FALSE (&sub);
02946 else
02947 NEXT_EXPECTING_TRUE (&sub);
02948
02949 link = next;
02950 }
02951
02952 ++i;
02953 }
02954
02955 return TRUE;
02956 }
02957
02958 static dbus_bool_t
02959 struct_read_value (TestTypeNode *node,
02960 DBusTypeReader *reader,
02961 int seed)
02962 {
02963 return struct_read_or_set_value (node, reader, NULL, seed);
02964 }
02965
02966 static dbus_bool_t
02967 struct_set_value (TestTypeNode *node,
02968 DBusTypeReader *reader,
02969 DBusTypeReader *realign_root,
02970 int seed)
02971 {
02972 return struct_read_or_set_value (node, reader, realign_root, seed);
02973 }
02974
02975 static dbus_bool_t
02976 struct_build_signature (TestTypeNode *node,
02977 DBusString *str)
02978 {
02979 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
02980 int i;
02981 int orig_len;
02982 int n_copies;
02983
02984 n_copies = node->klass->subclass_detail;
02985
02986 orig_len = _dbus_string_get_length (str);
02987
02988 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
02989 goto oom;
02990
02991 i = 0;
02992 while (i < n_copies)
02993 {
02994 DBusList *link;
02995
02996 link = _dbus_list_get_first_link (&container->children);
02997 while (link != NULL)
02998 {
02999 TestTypeNode *child = link->data;
03000 DBusList *next = _dbus_list_get_next_link (&container->children, link);
03001
03002 if (!node_build_signature (child, str))
03003 goto oom;
03004
03005 link = next;
03006 }
03007
03008 ++i;
03009 }
03010
03011 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
03012 goto oom;
03013
03014 return TRUE;
03015
03016 oom:
03017 _dbus_string_set_length (str, orig_len);
03018 return FALSE;
03019 }
03020
03021 static dbus_bool_t
03022 array_write_value (TestTypeNode *node,
03023 DataBlock *block,
03024 DBusTypeWriter *writer,
03025 int seed)
03026 {
03027 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03028 DataBlockState saved;
03029 DBusTypeWriter sub;
03030 DBusString element_signature;
03031 int i;
03032 int n_copies;
03033 int element_type;
03034 TestTypeNode *child;
03035
03036 n_copies = node->klass->subclass_detail;
03037
03038 _dbus_assert (container->children != NULL);
03039
03040 data_block_save (block, &saved);
03041
03042 if (!_dbus_string_init (&element_signature))
03043 return FALSE;
03044
03045 child = _dbus_list_get_first (&container->children);
03046
03047 if (!node_build_signature (child,
03048 &element_signature))
03049 goto oom;
03050
03051 element_type = _dbus_first_type_in_signature (&element_signature, 0);
03052
03053 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
03054 &element_signature, 0,
03055 &sub))
03056 goto oom;
03057
03058 if (arrays_write_fixed_in_blocks &&
03059 dbus_type_is_fixed (element_type) &&
03060 child->klass->write_multi)
03061 {
03062 if (!node_write_multi (child, block, &sub, seed, n_copies))
03063 goto oom;
03064 }
03065 else
03066 {
03067 i = 0;
03068 while (i < n_copies)
03069 {
03070 DBusList *link;
03071
03072 link = _dbus_list_get_first_link (&container->children);
03073 while (link != NULL)
03074 {
03075 TestTypeNode *child = link->data;
03076 DBusList *next = _dbus_list_get_next_link (&container->children, link);
03077
03078 if (!node_write_value (child, block, &sub, seed + i))
03079 goto oom;
03080
03081 link = next;
03082 }
03083
03084 ++i;
03085 }
03086 }
03087
03088 if (!_dbus_type_writer_unrecurse (writer, &sub))
03089 goto oom;
03090
03091 _dbus_string_free (&element_signature);
03092 return TRUE;
03093
03094 oom:
03095 data_block_restore (block, &saved);
03096 _dbus_string_free (&element_signature);
03097 return FALSE;
03098 }
03099
03100 static dbus_bool_t
03101 array_read_or_set_value (TestTypeNode *node,
03102 DBusTypeReader *reader,
03103 DBusTypeReader *realign_root,
03104 int seed)
03105 {
03106 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03107 DBusTypeReader sub;
03108 int i;
03109 int n_copies;
03110 TestTypeNode *child;
03111
03112 n_copies = node->klass->subclass_detail;
03113
03114 check_expected_type (reader, DBUS_TYPE_ARRAY);
03115
03116 child = _dbus_list_get_first (&container->children);
03117
03118 if (n_copies > 0)
03119 {
03120 _dbus_type_reader_recurse (reader, &sub);
03121
03122 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
03123 dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
03124 child->klass->read_multi)
03125 {
03126 if (!node_read_multi (child, &sub, seed, n_copies))
03127 return FALSE;
03128 }
03129 else
03130 {
03131 i = 0;
03132 while (i < n_copies)
03133 {
03134 DBusList *link;
03135
03136 link = _dbus_list_get_first_link (&container->children);
03137 while (link != NULL)
03138 {
03139 TestTypeNode *child = link->data;
03140 DBusList *next = _dbus_list_get_next_link (&container->children, link);
03141
03142 _dbus_assert (child->klass->typecode ==
03143 _dbus_type_reader_get_element_type (reader));
03144
03145 if (realign_root == NULL)
03146 {
03147 if (!node_read_value (child, &sub, seed + i))
03148 return FALSE;
03149 }
03150 else
03151 {
03152 if (!node_set_value (child, &sub, realign_root, seed + i))
03153 return FALSE;
03154 }
03155
03156 if (i == (n_copies - 1) && next == NULL)
03157 NEXT_EXPECTING_FALSE (&sub);
03158 else
03159 NEXT_EXPECTING_TRUE (&sub);
03160
03161 link = next;
03162 }
03163
03164 ++i;
03165 }
03166 }
03167 }
03168
03169 return TRUE;
03170 }
03171
03172 static dbus_bool_t
03173 array_read_value (TestTypeNode *node,
03174 DBusTypeReader *reader,
03175 int seed)
03176 {
03177 return array_read_or_set_value (node, reader, NULL, seed);
03178 }
03179
03180 static dbus_bool_t
03181 array_set_value (TestTypeNode *node,
03182 DBusTypeReader *reader,
03183 DBusTypeReader *realign_root,
03184 int seed)
03185 {
03186 return array_read_or_set_value (node, reader, realign_root, seed);
03187 }
03188
03189 static dbus_bool_t
03190 array_build_signature (TestTypeNode *node,
03191 DBusString *str)
03192 {
03193 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03194 int orig_len;
03195
03196 orig_len = _dbus_string_get_length (str);
03197
03198 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
03199 goto oom;
03200
03201 if (!node_build_signature (_dbus_list_get_first (&container->children),
03202 str))
03203 goto oom;
03204
03205 return TRUE;
03206
03207 oom:
03208 _dbus_string_set_length (str, orig_len);
03209 return FALSE;
03210 }
03211
03212
03213 #define VARIANT_SEED 10
03214
03215 static dbus_bool_t
03216 variant_write_value (TestTypeNode *node,
03217 DataBlock *block,
03218 DBusTypeWriter *writer,
03219 int seed)
03220 {
03221 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03222 DataBlockState saved;
03223 DBusTypeWriter sub;
03224 DBusString content_signature;
03225 TestTypeNode *child;
03226
03227 _dbus_assert (container->children != NULL);
03228 _dbus_assert (_dbus_list_length_is_one (&container->children));
03229
03230 child = _dbus_list_get_first (&container->children);
03231
03232 data_block_save (block, &saved);
03233
03234 if (!_dbus_string_init (&content_signature))
03235 return FALSE;
03236
03237 if (!node_build_signature (child,
03238 &content_signature))
03239 goto oom;
03240
03241 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
03242 &content_signature, 0,
03243 &sub))
03244 goto oom;
03245
03246 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
03247 goto oom;
03248
03249 if (!_dbus_type_writer_unrecurse (writer, &sub))
03250 goto oom;
03251
03252 _dbus_string_free (&content_signature);
03253 return TRUE;
03254
03255 oom:
03256 data_block_restore (block, &saved);
03257 _dbus_string_free (&content_signature);
03258 return FALSE;
03259 }
03260
03261 static dbus_bool_t
03262 variant_read_or_set_value (TestTypeNode *node,
03263 DBusTypeReader *reader,
03264 DBusTypeReader *realign_root,
03265 int seed)
03266 {
03267 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03268 DBusTypeReader sub;
03269 TestTypeNode *child;
03270
03271 _dbus_assert (container->children != NULL);
03272 _dbus_assert (_dbus_list_length_is_one (&container->children));
03273
03274 child = _dbus_list_get_first (&container->children);
03275
03276 check_expected_type (reader, DBUS_TYPE_VARIANT);
03277
03278 _dbus_type_reader_recurse (reader, &sub);
03279
03280 if (realign_root == NULL)
03281 {
03282 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
03283 return FALSE;
03284 }
03285 else
03286 {
03287 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
03288 return FALSE;
03289 }
03290
03291 NEXT_EXPECTING_FALSE (&sub);
03292
03293 return TRUE;
03294 }
03295
03296 static dbus_bool_t
03297 variant_read_value (TestTypeNode *node,
03298 DBusTypeReader *reader,
03299 int seed)
03300 {
03301 return variant_read_or_set_value (node, reader, NULL, seed);
03302 }
03303
03304 static dbus_bool_t
03305 variant_set_value (TestTypeNode *node,
03306 DBusTypeReader *reader,
03307 DBusTypeReader *realign_root,
03308 int seed)
03309 {
03310 return variant_read_or_set_value (node, reader, realign_root, seed);
03311 }
03312
03313 static dbus_bool_t
03314 dict_write_value (TestTypeNode *node,
03315 DataBlock *block,
03316 DBusTypeWriter *writer,
03317 int seed)
03318 {
03319 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03320 DataBlockState saved;
03321 DBusTypeWriter sub;
03322 DBusString entry_value_signature;
03323 DBusString dict_entry_signature;
03324 int i;
03325 int n_entries;
03326 int entry_value_type;
03327 TestTypeNode *child;
03328
03329 n_entries = node->klass->subclass_detail;
03330
03331 _dbus_assert (container->children != NULL);
03332
03333 data_block_save (block, &saved);
03334
03335 if (!_dbus_string_init (&entry_value_signature))
03336 return FALSE;
03337
03338 if (!_dbus_string_init (&dict_entry_signature))
03339 {
03340 _dbus_string_free (&entry_value_signature);
03341 return FALSE;
03342 }
03343
03344 child = _dbus_list_get_first (&container->children);
03345
03346 if (!node_build_signature (child,
03347 &entry_value_signature))
03348 goto oom;
03349
03350 if (!_dbus_string_append (&dict_entry_signature,
03351 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
03352 DBUS_TYPE_INT32_AS_STRING))
03353 goto oom;
03354
03355 if (!_dbus_string_copy (&entry_value_signature, 0,
03356 &dict_entry_signature,
03357 _dbus_string_get_length (&dict_entry_signature)))
03358 goto oom;
03359
03360 if (!_dbus_string_append_byte (&dict_entry_signature,
03361 DBUS_DICT_ENTRY_END_CHAR))
03362 goto oom;
03363
03364 entry_value_type = _dbus_first_type_in_signature (&entry_value_signature, 0);
03365
03366 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
03367 &dict_entry_signature, 0,
03368 &sub))
03369 goto oom;
03370
03371 i = 0;
03372 while (i < n_entries)
03373 {
03374 DBusTypeWriter entry_sub;
03375 dbus_int32_t key;
03376
03377 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
03378 NULL, 0,
03379 &entry_sub))
03380 goto oom;
03381
03382 key = int32_from_seed (seed + i);
03383
03384 if (!_dbus_type_writer_write_basic (&entry_sub,
03385 DBUS_TYPE_INT32,
03386 &key))
03387 goto oom;
03388
03389 if (!node_write_value (child, block, &entry_sub, seed + i))
03390 goto oom;
03391
03392 if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
03393 goto oom;
03394
03395 ++i;
03396 }
03397
03398 if (!_dbus_type_writer_unrecurse (writer, &sub))
03399 goto oom;
03400
03401 _dbus_string_free (&entry_value_signature);
03402 _dbus_string_free (&dict_entry_signature);
03403 return TRUE;
03404
03405 oom:
03406 data_block_restore (block, &saved);
03407 _dbus_string_free (&entry_value_signature);
03408 _dbus_string_free (&dict_entry_signature);
03409 return FALSE;
03410 }
03411
03412 static dbus_bool_t
03413 dict_read_or_set_value (TestTypeNode *node,
03414 DBusTypeReader *reader,
03415 DBusTypeReader *realign_root,
03416 int seed)
03417 {
03418 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03419 DBusTypeReader sub;
03420 int i;
03421 int n_entries;
03422 TestTypeNode *child;
03423
03424 n_entries = node->klass->subclass_detail;
03425
03426 check_expected_type (reader, DBUS_TYPE_ARRAY);
03427
03428 child = _dbus_list_get_first (&container->children);
03429
03430 if (n_entries > 0)
03431 {
03432 _dbus_type_reader_recurse (reader, &sub);
03433
03434 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
03435
03436 i = 0;
03437 while (i < n_entries)
03438 {
03439 DBusTypeReader entry_sub;
03440
03441 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
03442
03443 _dbus_type_reader_recurse (&sub, &entry_sub);
03444
03445 if (realign_root == NULL)
03446 {
03447 dbus_int32_t v;
03448
03449 check_expected_type (&entry_sub, DBUS_TYPE_INT32);
03450
03451 _dbus_type_reader_read_basic (&entry_sub,
03452 (dbus_int32_t*) &v);
03453
03454 _dbus_assert (v == int32_from_seed (seed + i));
03455
03456 NEXT_EXPECTING_TRUE (&entry_sub);
03457
03458 if (!node_read_value (child, &entry_sub, seed + i))
03459 return FALSE;
03460
03461 NEXT_EXPECTING_FALSE (&entry_sub);
03462 }
03463 else
03464 {
03465 dbus_int32_t v;
03466
03467 v = int32_from_seed (seed + i);
03468
03469 if (!_dbus_type_reader_set_basic (&entry_sub,
03470 &v,
03471 realign_root))
03472 return FALSE;
03473
03474 NEXT_EXPECTING_TRUE (&entry_sub);
03475
03476 if (!node_set_value (child, &entry_sub, realign_root, seed + i))
03477 return FALSE;
03478
03479 NEXT_EXPECTING_FALSE (&entry_sub);
03480 }
03481
03482 if (i == (n_entries - 1))
03483 NEXT_EXPECTING_FALSE (&sub);
03484 else
03485 NEXT_EXPECTING_TRUE (&sub);
03486
03487 ++i;
03488 }
03489 }
03490
03491 return TRUE;
03492 }
03493
03494 static dbus_bool_t
03495 dict_read_value (TestTypeNode *node,
03496 DBusTypeReader *reader,
03497 int seed)
03498 {
03499 return dict_read_or_set_value (node, reader, NULL, seed);
03500 }
03501
03502 static dbus_bool_t
03503 dict_set_value (TestTypeNode *node,
03504 DBusTypeReader *reader,
03505 DBusTypeReader *realign_root,
03506 int seed)
03507 {
03508 return dict_read_or_set_value (node, reader, realign_root, seed);
03509 }
03510
03511 static dbus_bool_t
03512 dict_build_signature (TestTypeNode *node,
03513 DBusString *str)
03514 {
03515 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03516 int orig_len;
03517
03518 orig_len = _dbus_string_get_length (str);
03519
03520 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
03521 goto oom;
03522
03523 if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
03524 goto oom;
03525
03526 if (!node_build_signature (_dbus_list_get_first (&container->children),
03527 str))
03528 goto oom;
03529
03530 if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
03531 goto oom;
03532
03533 return TRUE;
03534
03535 oom:
03536 _dbus_string_set_length (str, orig_len);
03537 return FALSE;
03538 }
03539
03540 static void
03541 container_destroy (TestTypeNode *node)
03542 {
03543 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
03544 DBusList *link;
03545
03546 link = _dbus_list_get_first_link (&container->children);
03547 while (link != NULL)
03548 {
03549 TestTypeNode *child = link->data;
03550 DBusList *next = _dbus_list_get_next_link (&container->children, link);
03551
03552 node_destroy (child);
03553
03554 _dbus_list_free_link (link);
03555
03556 link = next;
03557 }
03558 }
03559
03560 #endif