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