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