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