1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-recursive-util.c Would be in dbus-marshal-recursive.c, but only used in bus/tests
4 * Copyright (C) 2004, 2005 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #ifdef DBUS_BUILD_TESTS
28 #include "dbus-marshal-recursive.h"
29 #include "dbus-marshal-basic.h"
30 #include "dbus-internals.h"
34 basic_value_zero (DBusBasicValue *value)
37 #ifdef DBUS_HAVE_INT64
40 value->u64.first32 = 0;
41 value->u64.second32 = 0;
46 basic_value_equal (int type,
50 if (type == DBUS_TYPE_STRING ||
51 type == DBUS_TYPE_SIGNATURE ||
52 type == DBUS_TYPE_OBJECT_PATH)
54 return strcmp (lhs->str, rhs->str) == 0;
58 #ifdef DBUS_HAVE_INT64
59 return lhs->u64 == rhs->u64;
61 return lhs->u64.first32 == rhs->u64.first32 &&
62 lhs->u64.second32 == rhs->u64.second32;
68 equal_values_helper (DBusTypeReader *lhs,
74 lhs_type = _dbus_type_reader_get_current_type (lhs);
75 rhs_type = _dbus_type_reader_get_current_type (rhs);
77 if (lhs_type != rhs_type)
80 if (lhs_type == DBUS_TYPE_INVALID)
83 if (_dbus_type_is_basic (lhs_type))
85 DBusBasicValue lhs_value;
86 DBusBasicValue rhs_value;
88 basic_value_zero (&lhs_value);
89 basic_value_zero (&rhs_value);
91 _dbus_type_reader_read_basic (lhs, &lhs_value);
92 _dbus_type_reader_read_basic (rhs, &rhs_value);
94 return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
98 DBusTypeReader lhs_sub;
99 DBusTypeReader rhs_sub;
101 _dbus_type_reader_recurse (lhs, &lhs_sub);
102 _dbus_type_reader_recurse (rhs, &rhs_sub);
104 return equal_values_helper (&lhs_sub, &rhs_sub);
109 * See whether the two readers point to identical data blocks.
111 * @param lhs reader 1
112 * @param rhs reader 2
113 * @returns #TRUE if the data blocks have the same values
116 _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
117 const DBusTypeReader *rhs)
119 DBusTypeReader copy_lhs = *lhs;
120 DBusTypeReader copy_rhs = *rhs;
122 return equal_values_helper (©_lhs, ©_rhs);
126 #include "dbus-test.h"
127 #include "dbus-list.h"
131 /* Whether to do the OOM stuff (only with other expensive tests) */
132 #define TEST_OOM_HANDLING 0
133 /* We do start offset 0 through 9, to get various alignment cases. Still this
134 * obviously makes the test suite run 10x as slow.
136 #define MAX_INITIAL_OFFSET 9
138 /* Largest iteration count to test copying, realignment,
139 * etc. with. i.e. we only test this stuff with some of the smaller
142 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
148 DBusString signature;
158 #define N_FENCE_BYTES 5
159 #define FENCE_BYTES_STR "abcde"
160 #define INITIAL_PADDING_BYTE '\0'
163 data_block_init (DataBlock *block,
167 if (!_dbus_string_init (&block->signature))
170 if (!_dbus_string_init (&block->body))
172 _dbus_string_free (&block->signature);
176 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
177 INITIAL_PADDING_BYTE) ||
178 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
179 INITIAL_PADDING_BYTE) ||
180 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
181 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
183 _dbus_string_free (&block->signature);
184 _dbus_string_free (&block->body);
188 block->byte_order = byte_order;
189 block->initial_offset = initial_offset;
195 data_block_save (DataBlock *block,
196 DataBlockState *state)
198 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
199 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
203 data_block_restore (DataBlock *block,
204 DataBlockState *state)
206 _dbus_string_delete (&block->signature,
207 state->saved_sig_len,
208 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
209 _dbus_string_delete (&block->body,
210 state->saved_body_len,
211 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
215 data_block_verify (DataBlock *block)
217 if (!_dbus_string_ends_with_c_str (&block->signature,
222 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
226 _dbus_verbose_bytes_of_string (&block->signature,
228 _dbus_string_get_length (&block->signature) - offset);
229 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
231 if (!_dbus_string_ends_with_c_str (&block->body,
236 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
240 _dbus_verbose_bytes_of_string (&block->body,
242 _dbus_string_get_length (&block->body) - offset);
243 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
246 _dbus_assert (_dbus_string_validate_nul (&block->signature,
247 0, block->initial_offset));
248 _dbus_assert (_dbus_string_validate_nul (&block->body,
249 0, block->initial_offset));
253 data_block_free (DataBlock *block)
255 data_block_verify (block);
257 _dbus_string_free (&block->signature);
258 _dbus_string_free (&block->body);
262 data_block_reset (DataBlock *block)
264 data_block_verify (block);
266 _dbus_string_delete (&block->signature,
267 block->initial_offset,
268 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
269 _dbus_string_delete (&block->body,
270 block->initial_offset,
271 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
273 data_block_verify (block);
277 data_block_init_reader_writer (DataBlock *block,
278 DBusTypeReader *reader,
279 DBusTypeWriter *writer)
282 _dbus_type_reader_init (reader,
285 block->initial_offset,
287 block->initial_offset);
290 _dbus_type_writer_init (writer,
293 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
295 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
299 real_check_expected_type (DBusTypeReader *reader,
301 const char *funcname,
306 t = _dbus_type_reader_get_current_type (reader);
310 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
311 _dbus_type_to_string (t),
312 _dbus_type_to_string (expected),
315 _dbus_assert_not_reached ("read wrong type");
319 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
321 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
323 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
324 _DBUS_FUNCTION_NAME, __LINE__); \
325 _dbus_assert_not_reached ("test failed"); \
329 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
331 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
332 _DBUS_FUNCTION_NAME, __LINE__); \
333 _dbus_assert_not_reached ("test failed"); \
335 check_expected_type (reader, DBUS_TYPE_INVALID); \
338 typedef struct TestTypeNode TestTypeNode;
339 typedef struct TestTypeNodeClass TestTypeNodeClass;
340 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
341 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
345 const TestTypeNodeClass *klass;
348 struct TestTypeNodeContainer
354 struct TestTypeNodeClass
360 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
362 dbus_bool_t (* construct) (TestTypeNode *node);
363 void (* destroy) (TestTypeNode *node);
365 dbus_bool_t (* write_value) (TestTypeNode *node,
367 DBusTypeWriter *writer,
369 dbus_bool_t (* read_value) (TestTypeNode *node,
370 DBusTypeReader *reader,
372 dbus_bool_t (* set_value) (TestTypeNode *node,
373 DBusTypeReader *reader,
374 DBusTypeReader *realign_root,
376 dbus_bool_t (* build_signature) (TestTypeNode *node,
378 dbus_bool_t (* write_multi) (TestTypeNode *node,
380 DBusTypeWriter *writer,
383 dbus_bool_t (* read_multi) (TestTypeNode *node,
384 DBusTypeReader *reader,
389 struct TestTypeNodeContainerClass
391 TestTypeNodeClass base;
394 /* FIXME this could be chilled out substantially by unifying
395 * the basic types into basic_write_value/basic_read_value
396 * and by merging read_value and set_value into one function
397 * taking a flag argument.
399 static dbus_bool_t int32_write_value (TestTypeNode *node,
401 DBusTypeWriter *writer,
403 static dbus_bool_t int32_read_value (TestTypeNode *node,
404 DBusTypeReader *reader,
406 static dbus_bool_t int32_set_value (TestTypeNode *node,
407 DBusTypeReader *reader,
408 DBusTypeReader *realign_root,
410 static dbus_bool_t int32_write_multi (TestTypeNode *node,
412 DBusTypeWriter *writer,
415 static dbus_bool_t int32_read_multi (TestTypeNode *node,
416 DBusTypeReader *reader,
419 static dbus_bool_t int64_write_value (TestTypeNode *node,
421 DBusTypeWriter *writer,
423 static dbus_bool_t int64_read_value (TestTypeNode *node,
424 DBusTypeReader *reader,
426 static dbus_bool_t int64_set_value (TestTypeNode *node,
427 DBusTypeReader *reader,
428 DBusTypeReader *realign_root,
430 static dbus_bool_t string_write_value (TestTypeNode *node,
432 DBusTypeWriter *writer,
434 static dbus_bool_t string_read_value (TestTypeNode *node,
435 DBusTypeReader *reader,
437 static dbus_bool_t string_set_value (TestTypeNode *node,
438 DBusTypeReader *reader,
439 DBusTypeReader *realign_root,
441 static dbus_bool_t bool_write_value (TestTypeNode *node,
443 DBusTypeWriter *writer,
445 static dbus_bool_t bool_read_value (TestTypeNode *node,
446 DBusTypeReader *reader,
448 static dbus_bool_t bool_set_value (TestTypeNode *node,
449 DBusTypeReader *reader,
450 DBusTypeReader *realign_root,
452 static dbus_bool_t byte_write_value (TestTypeNode *node,
454 DBusTypeWriter *writer,
456 static dbus_bool_t byte_read_value (TestTypeNode *node,
457 DBusTypeReader *reader,
459 static dbus_bool_t byte_set_value (TestTypeNode *node,
460 DBusTypeReader *reader,
461 DBusTypeReader *realign_root,
463 static dbus_bool_t double_write_value (TestTypeNode *node,
465 DBusTypeWriter *writer,
467 static dbus_bool_t double_read_value (TestTypeNode *node,
468 DBusTypeReader *reader,
470 static dbus_bool_t double_set_value (TestTypeNode *node,
471 DBusTypeReader *reader,
472 DBusTypeReader *realign_root,
474 static dbus_bool_t object_path_write_value (TestTypeNode *node,
476 DBusTypeWriter *writer,
478 static dbus_bool_t object_path_read_value (TestTypeNode *node,
479 DBusTypeReader *reader,
481 static dbus_bool_t object_path_set_value (TestTypeNode *node,
482 DBusTypeReader *reader,
483 DBusTypeReader *realign_root,
485 static dbus_bool_t signature_write_value (TestTypeNode *node,
487 DBusTypeWriter *writer,
489 static dbus_bool_t signature_read_value (TestTypeNode *node,
490 DBusTypeReader *reader,
492 static dbus_bool_t signature_set_value (TestTypeNode *node,
493 DBusTypeReader *reader,
494 DBusTypeReader *realign_root,
496 static dbus_bool_t struct_write_value (TestTypeNode *node,
498 DBusTypeWriter *writer,
500 static dbus_bool_t struct_read_value (TestTypeNode *node,
501 DBusTypeReader *reader,
503 static dbus_bool_t struct_set_value (TestTypeNode *node,
504 DBusTypeReader *reader,
505 DBusTypeReader *realign_root,
507 static dbus_bool_t struct_build_signature (TestTypeNode *node,
509 static dbus_bool_t array_write_value (TestTypeNode *node,
511 DBusTypeWriter *writer,
513 static dbus_bool_t array_read_value (TestTypeNode *node,
514 DBusTypeReader *reader,
516 static dbus_bool_t array_set_value (TestTypeNode *node,
517 DBusTypeReader *reader,
518 DBusTypeReader *realign_root,
520 static dbus_bool_t array_build_signature (TestTypeNode *node,
522 static dbus_bool_t variant_write_value (TestTypeNode *node,
524 DBusTypeWriter *writer,
526 static dbus_bool_t variant_read_value (TestTypeNode *node,
527 DBusTypeReader *reader,
529 static dbus_bool_t variant_set_value (TestTypeNode *node,
530 DBusTypeReader *reader,
531 DBusTypeReader *realign_root,
533 static void container_destroy (TestTypeNode *node);
536 static const TestTypeNodeClass int32_class = {
538 sizeof (TestTypeNode),
550 static const TestTypeNodeClass uint32_class = {
552 sizeof (TestTypeNode),
556 int32_write_value, /* recycle from int32 */
557 int32_read_value, /* recycle from int32 */
558 int32_set_value, /* recycle from int32 */
560 int32_write_multi, /* recycle from int32 */
561 int32_read_multi /* recycle from int32 */
564 static const TestTypeNodeClass int64_class = {
566 sizeof (TestTypeNode),
578 static const TestTypeNodeClass uint64_class = {
580 sizeof (TestTypeNode),
584 int64_write_value, /* recycle from int64 */
585 int64_read_value, /* recycle from int64 */
586 int64_set_value, /* recycle from int64 */
592 static const TestTypeNodeClass string_0_class = {
594 sizeof (TestTypeNode),
595 0, /* string length */
606 static const TestTypeNodeClass string_1_class = {
608 sizeof (TestTypeNode),
609 1, /* string length */
620 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
621 static const TestTypeNodeClass string_3_class = {
623 sizeof (TestTypeNode),
624 3, /* string length */
635 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
636 static const TestTypeNodeClass string_8_class = {
638 sizeof (TestTypeNode),
639 8, /* string length */
650 static const TestTypeNodeClass bool_class = {
652 sizeof (TestTypeNode),
664 static const TestTypeNodeClass byte_class = {
666 sizeof (TestTypeNode),
678 static const TestTypeNodeClass double_class = {
680 sizeof (TestTypeNode),
692 static const TestTypeNodeClass object_path_class = {
693 DBUS_TYPE_OBJECT_PATH,
694 sizeof (TestTypeNode),
698 object_path_write_value,
699 object_path_read_value,
700 object_path_set_value,
706 static const TestTypeNodeClass signature_class = {
708 sizeof (TestTypeNode),
712 signature_write_value,
713 signature_read_value,
720 static const TestTypeNodeClass struct_1_class = {
722 sizeof (TestTypeNodeContainer),
723 1, /* number of times children appear as fields */
729 struct_build_signature,
734 static const TestTypeNodeClass struct_2_class = {
736 sizeof (TestTypeNodeContainer),
737 2, /* number of times children appear as fields */
743 struct_build_signature,
748 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
750 static const TestTypeNodeClass array_0_class = {
752 sizeof (TestTypeNodeContainer),
753 0, /* number of array elements */
759 array_build_signature,
764 static const TestTypeNodeClass array_1_class = {
766 sizeof (TestTypeNodeContainer),
767 1, /* number of array elements */
773 array_build_signature,
778 static const TestTypeNodeClass array_2_class = {
780 sizeof (TestTypeNodeContainer),
781 2, /* number of array elements */
787 array_build_signature,
792 static const TestTypeNodeClass array_9_class = {
794 sizeof (TestTypeNodeContainer),
795 9, /* number of array elements */
801 array_build_signature,
806 static const TestTypeNodeClass variant_class = {
808 sizeof (TestTypeNodeContainer),
820 static const TestTypeNodeClass* const
836 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
838 static const TestTypeNodeClass* const
839 container_nodes[] = {
846 /* array_9_class is omitted on purpose, it's too slow;
847 * we only use it in one hardcoded test below
850 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
853 node_new (const TestTypeNodeClass *klass)
857 node = dbus_malloc0 (klass->instance_size);
863 if (klass->construct)
865 if (!(* klass->construct) (node))
876 node_destroy (TestTypeNode *node)
878 if (node->klass->destroy)
879 (* node->klass->destroy) (node);
884 node_write_value (TestTypeNode *node,
886 DBusTypeWriter *writer,
891 retval = (* node->klass->write_value) (node, block, writer, seed);
894 /* Handy to see where things break, but too expensive to do all the time */
895 data_block_verify (block);
902 node_read_value (TestTypeNode *node,
903 DBusTypeReader *reader,
907 DBusTypeReader restored;
909 _dbus_type_reader_save_mark (reader, &mark);
911 if (!(* node->klass->read_value) (node, reader, seed))
914 _dbus_type_reader_init_from_mark (&restored,
920 if (!(* node->klass->read_value) (node, &restored, seed))
926 /* Warning: if this one fails due to OOM, it has side effects (can
927 * modify only some of the sub-values). OK in a test suite, but we
928 * never do this in real code.
931 node_set_value (TestTypeNode *node,
932 DBusTypeReader *reader,
933 DBusTypeReader *realign_root,
936 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
943 node_build_signature (TestTypeNode *node,
946 if (node->klass->build_signature)
947 return (* node->klass->build_signature) (node, str);
949 return _dbus_string_append_byte (str, node->klass->typecode);
953 node_append_child (TestTypeNode *node,
956 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
958 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
960 if (!_dbus_list_append (&container->children, child))
961 _dbus_assert_not_reached ("no memory"); /* we never check the return value on node_append_child anyhow - it's run from outside the malloc-failure test code */
967 node_write_multi (TestTypeNode *node,
969 DBusTypeWriter *writer,
975 _dbus_assert (node->klass->write_multi != NULL);
976 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
979 /* Handy to see where things break, but too expensive to do all the time */
980 data_block_verify (block);
987 node_read_multi (TestTypeNode *node,
988 DBusTypeReader *reader,
992 _dbus_assert (node->klass->read_multi != NULL);
994 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1000 static int n_iterations_completed_total = 0;
1001 static int n_iterations_completed_this_test = 0;
1002 static int n_iterations_expected_this_test = 0;
1006 const DBusString *signature;
1009 TestTypeNode **nodes;
1011 } NodeIterationData;
1014 run_test_copy (NodeIterationData *nid)
1019 DBusTypeReader reader;
1020 DBusTypeWriter writer;
1022 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1028 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1031 data_block_init_reader_writer (src, &reader, NULL);
1032 data_block_init_reader_writer (&dest, NULL, &writer);
1034 /* DBusTypeWriter assumes it's writing into an existing signature,
1035 * so doesn't add nul on its own. We have to do that.
1037 if (!_dbus_string_insert_byte (&dest.signature,
1038 dest.initial_offset, '\0'))
1041 if (!_dbus_type_writer_write_reader (&writer, &reader))
1044 /* Data blocks should now be identical */
1045 if (!_dbus_string_equal (&src->signature, &dest.signature))
1047 _dbus_verbose ("SOURCE\n");
1048 _dbus_verbose_bytes_of_string (&src->signature, 0,
1049 _dbus_string_get_length (&src->signature));
1050 _dbus_verbose ("DEST\n");
1051 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1052 _dbus_string_get_length (&dest.signature));
1053 _dbus_assert_not_reached ("signatures did not match");
1056 if (!_dbus_string_equal (&src->body, &dest.body))
1058 _dbus_verbose ("SOURCE\n");
1059 _dbus_verbose_bytes_of_string (&src->body, 0,
1060 _dbus_string_get_length (&src->body));
1061 _dbus_verbose ("DEST\n");
1062 _dbus_verbose_bytes_of_string (&dest.body, 0,
1063 _dbus_string_get_length (&dest.body));
1064 _dbus_assert_not_reached ("bodies did not match");
1071 data_block_free (&dest);
1077 run_test_values_only_write (NodeIterationData *nid)
1079 DBusTypeReader reader;
1080 DBusTypeWriter writer;
1085 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1089 data_block_reset (nid->block);
1091 sig_len = _dbus_string_get_length (nid->signature);
1093 _dbus_type_writer_init_values_only (&writer,
1094 nid->block->byte_order,
1097 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1098 _dbus_type_reader_init (&reader,
1099 nid->block->byte_order,
1102 nid->block->initial_offset);
1105 while (i < nid->n_nodes)
1107 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1113 /* if we wrote any typecodes then this would fail */
1114 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1116 /* But be sure we wrote out the values correctly */
1118 while (i < nid->n_nodes)
1120 if (!node_read_value (nid->nodes[i], &reader, i))
1123 if (i + 1 == nid->n_nodes)
1124 NEXT_EXPECTING_FALSE (&reader);
1126 NEXT_EXPECTING_TRUE (&reader);
1134 data_block_reset (nid->block);
1138 /* offset the seed for setting, so we set different numbers than
1139 * we originally wrote. Don't offset by a huge number since in
1140 * some cases it's value = possibilities[seed % n_possibilities]
1141 * and we don't want to wrap around. bool_from_seed
1142 * is just seed % 2 even.
1146 run_test_set_values (NodeIterationData *nid)
1148 DBusTypeReader reader;
1149 DBusTypeReader realign_root;
1153 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1157 data_block_init_reader_writer (nid->block,
1160 realign_root = reader;
1163 while (i < nid->n_nodes)
1165 if (!node_set_value (nid->nodes[i],
1166 &reader, &realign_root,
1170 if (i + 1 == nid->n_nodes)
1171 NEXT_EXPECTING_FALSE (&reader);
1173 NEXT_EXPECTING_TRUE (&reader);
1178 /* Check that the new values were set */
1180 reader = realign_root;
1183 while (i < nid->n_nodes)
1185 if (!node_read_value (nid->nodes[i], &reader,
1189 if (i + 1 == nid->n_nodes)
1190 NEXT_EXPECTING_FALSE (&reader);
1192 NEXT_EXPECTING_TRUE (&reader);
1204 run_test_delete_values (NodeIterationData *nid)
1206 DBusTypeReader reader;
1210 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1214 data_block_init_reader_writer (nid->block,
1217 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1219 /* Right now, deleting only works on array elements. We delete
1220 * all array elements, and then verify that there aren't any
1223 if (t == DBUS_TYPE_ARRAY)
1225 DBusTypeReader array;
1229 _dbus_type_reader_recurse (&reader, &array);
1231 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1234 _dbus_type_reader_next (&array);
1237 /* reset to start of array */
1238 _dbus_type_reader_recurse (&reader, &array);
1239 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1240 reader.value_pos, array.value_pos, array.u.array.start_pos);
1241 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1243 /* We don't want to always delete from the same part of the array. */
1244 static int cycle = 0;
1247 _dbus_assert (n_elements > 0);
1250 if (elem == 3 || elem >= n_elements) /* end of array */
1251 elem = n_elements - 1;
1253 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1254 elem, n_elements, _dbus_type_to_string (elem_type),
1255 cycle, reader.value_pos, array.value_pos);
1258 if (!_dbus_type_reader_next (&array))
1259 _dbus_assert_not_reached ("should have had another element\n");
1263 if (!_dbus_type_reader_delete (&array, &reader))
1269 _dbus_type_reader_recurse (&reader, &array);
1277 _dbus_type_reader_next (&reader);
1280 /* Check that there are no array elements left */
1281 data_block_init_reader_writer (nid->block,
1284 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1286 _dbus_type_reader_next (&reader);
1296 run_test_nodes_iteration (void *data)
1298 NodeIterationData *nid = data;
1299 DBusTypeReader reader;
1300 DBusTypeWriter writer;
1305 * 1. write the value
1306 * 2. strcmp-compare with the signature we built
1308 * 4. type-iterate the signature and the value and see if they are the same type-wise
1312 data_block_init_reader_writer (nid->block,
1315 /* DBusTypeWriter assumes it's writing into an existing signature,
1316 * so doesn't add nul on its own. We have to do that.
1318 if (!_dbus_string_insert_byte (&nid->block->signature,
1319 nid->type_offset, '\0'))
1323 while (i < nid->n_nodes)
1325 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1331 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1332 &nid->block->signature, nid->type_offset))
1334 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1335 _dbus_string_get_const_data (nid->signature),
1336 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1338 _dbus_assert_not_reached ("wrong signature");
1342 while (i < nid->n_nodes)
1344 if (!node_read_value (nid->nodes[i], &reader, i))
1347 if (i + 1 == nid->n_nodes)
1348 NEXT_EXPECTING_FALSE (&reader);
1350 NEXT_EXPECTING_TRUE (&reader);
1355 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1357 /* this set values test uses code from copy and
1358 * values_only_write so would ideally be last so you get a
1359 * simpler test case for problems with copying or values_only
1360 * writing; but it also needs an already-written DataBlock so it
1361 * has to go first. Comment it out if it breaks, and see if the
1362 * later tests also break - debug them first if so.
1364 if (!run_test_set_values (nid))
1367 if (!run_test_delete_values (nid))
1370 if (!run_test_copy (nid))
1373 if (!run_test_values_only_write (nid))
1377 /* FIXME type-iterate both signature and value and compare the resulting
1378 * tree to the node tree perhaps
1385 data_block_reset (nid->block);
1391 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1393 const DBusString *signature,
1398 NodeIterationData nid;
1400 if (!data_block_init (&block, byte_order, initial_offset))
1401 _dbus_assert_not_reached ("no memory");
1403 nid.signature = signature;
1405 nid.type_offset = initial_offset;
1407 nid.n_nodes = n_nodes;
1409 if (TEST_OOM_HANDLING &&
1410 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1412 _dbus_test_oom_handling ("running test node",
1413 run_test_nodes_iteration,
1418 if (!run_test_nodes_iteration (&nid))
1419 _dbus_assert_not_reached ("no memory");
1422 data_block_free (&block);
1426 run_test_nodes (TestTypeNode **nodes,
1430 DBusString signature;
1432 if (!_dbus_string_init (&signature))
1433 _dbus_assert_not_reached ("no memory");
1438 if (! node_build_signature (nodes[i], &signature))
1439 _dbus_assert_not_reached ("no memory");
1444 _dbus_verbose (">>> test nodes with signature '%s'\n",
1445 _dbus_string_get_const_data (&signature));
1448 while (i <= MAX_INITIAL_OFFSET)
1450 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1451 DBUS_LITTLE_ENDIAN, i);
1452 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1453 DBUS_BIG_ENDIAN, i);
1458 n_iterations_completed_this_test += 1;
1459 n_iterations_completed_total += 1;
1461 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1463 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1464 n_iterations_completed_this_test,
1465 n_iterations_completed_total);
1467 /* this happens to turn out well with mod == 1 */
1468 else if ((n_iterations_completed_this_test %
1469 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1471 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1474 _dbus_string_free (&signature);
1477 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1479 static TestTypeNode*
1480 value_generator (int *ip)
1483 const TestTypeNodeClass *child_klass;
1484 const TestTypeNodeClass *container_klass;
1485 TestTypeNode *child;
1488 _dbus_assert (i <= N_VALUES);
1494 else if (i < N_BASICS)
1496 node = node_new (basic_nodes[i]);
1500 /* imagine an array:
1501 * container 0 of basic 0
1502 * container 0 of basic 1
1503 * container 0 of basic 2
1504 * container 1 of basic 0
1505 * container 1 of basic 1
1506 * container 1 of basic 2
1510 container_klass = container_nodes[i / N_BASICS];
1511 child_klass = basic_nodes[i % N_BASICS];
1513 node = node_new (container_klass);
1514 child = node_new (child_klass);
1516 node_append_child (node, child);
1519 *ip += 1; /* increment the generator */
1525 build_body (TestTypeNode **nodes,
1528 DBusString *signature,
1533 DBusTypeReader reader;
1534 DBusTypeWriter writer;
1539 if (! node_build_signature (nodes[i], signature))
1540 _dbus_assert_not_reached ("no memory");
1545 if (!data_block_init (&block, byte_order, 0))
1546 _dbus_assert_not_reached ("no memory");
1548 data_block_init_reader_writer (&block,
1551 /* DBusTypeWriter assumes it's writing into an existing signature,
1552 * so doesn't add nul on its own. We have to do that.
1554 if (!_dbus_string_insert_byte (&block.signature,
1556 _dbus_assert_not_reached ("no memory");
1561 if (!node_write_value (nodes[i], &block, &writer, i))
1562 _dbus_assert_not_reached ("no memory");
1567 if (!_dbus_string_copy_len (&block.body, 0,
1568 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1570 _dbus_assert_not_reached ("oom");
1572 data_block_free (&block);
1576 dbus_internal_do_not_use_generate_bodies (int sequence,
1578 DBusString *signature,
1581 TestTypeNode *nodes[1];
1585 nodes[0] = value_generator (&sequence);
1587 if (nodes[0] == NULL)
1592 build_body (nodes, n_nodes, byte_order, signature, body);
1598 node_destroy (nodes[i]);
1606 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1610 TestTypeNode *container;
1611 TestTypeNode *child;
1614 root = node_new (container_klass);
1616 for (i = 1; i < n_nested; i++)
1618 child = node_new (container_klass);
1619 node_append_child (container, child);
1623 /* container should now be the most-nested container */
1626 while ((child = value_generator (&i)))
1628 node_append_child (container, child);
1630 run_test_nodes (&root, 1);
1632 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1633 node_destroy (child);
1636 node_destroy (root);
1640 start_next_test (const char *format,
1643 n_iterations_completed_this_test = 0;
1644 n_iterations_expected_this_test = expected;
1646 fprintf (stderr, ">>> >>> ");
1647 fprintf (stderr, format,
1648 n_iterations_expected_this_test);
1652 make_and_run_test_nodes (void)
1656 /* We try to do this in order of "complicatedness" so that test
1657 * failures tend to show up in the simplest test case that
1658 * demonstrates the failure. There are also some tests that run
1659 * more than once for this reason, first while going through simple
1660 * cases, second while going through a broader range of complex
1663 /* Each basic node. The basic nodes should include:
1665 * - each fixed-size type (in such a way that it has different values each time,
1666 * so we can tell if we mix two of them up)
1667 * - strings of various lengths
1671 /* Each container node. The container nodes should include:
1673 * struct with 1 and 2 copies of the contained item
1674 * array with 0, 1, 2 copies of the contained item
1677 /* Let a "value" be a basic node, or a container containing a single basic node.
1678 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1679 * When iterating through all values to make combinations, do the basic types
1680 * first and the containers second.
1682 /* Each item is shown with its number of iterations to complete so
1683 * we can keep a handle on this unit test
1686 /* FIXME test just an empty body, no types at all */
1688 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1692 while ((node = value_generator (&i)))
1694 run_test_nodes (&node, 1);
1696 node_destroy (node);
1700 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1701 arrays_write_fixed_in_blocks = TRUE;
1705 while ((node = value_generator (&i)))
1707 run_test_nodes (&node, 1);
1709 node_destroy (node);
1712 arrays_write_fixed_in_blocks = FALSE;
1714 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1716 TestTypeNode *nodes[N_VALUES];
1719 while ((nodes[i] = value_generator (&i)))
1722 run_test_nodes (nodes, N_VALUES);
1724 for (i = 0; i < N_VALUES; i++)
1725 node_destroy (nodes[i]);
1728 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1729 N_VALUES * N_VALUES);
1731 TestTypeNode *nodes[2];
1734 while ((nodes[0] = value_generator (&i)))
1737 while ((nodes[1] = value_generator (&j)))
1739 run_test_nodes (nodes, 2);
1741 node_destroy (nodes[1]);
1744 node_destroy (nodes[0]);
1748 start_next_test ("Each container containing each value %d iterations\n",
1749 N_CONTAINERS * N_VALUES);
1750 for (i = 0; i < N_CONTAINERS; i++)
1752 const TestTypeNodeClass *container_klass = container_nodes[i];
1754 make_and_run_values_inside_container (container_klass, 1);
1757 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1758 N_CONTAINERS * N_VALUES);
1759 arrays_write_fixed_in_blocks = TRUE;
1760 for (i = 0; i < N_CONTAINERS; i++)
1762 const TestTypeNodeClass *container_klass = container_nodes[i];
1764 make_and_run_values_inside_container (container_klass, 1);
1766 arrays_write_fixed_in_blocks = FALSE;
1768 start_next_test ("Each container of same container of each value %d iterations\n",
1769 N_CONTAINERS * N_VALUES);
1770 for (i = 0; i < N_CONTAINERS; i++)
1772 const TestTypeNodeClass *container_klass = container_nodes[i];
1774 make_and_run_values_inside_container (container_klass, 2);
1777 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1778 N_CONTAINERS * N_VALUES);
1779 for (i = 0; i < N_CONTAINERS; i++)
1781 const TestTypeNodeClass *container_klass = container_nodes[i];
1783 make_and_run_values_inside_container (container_klass, 3);
1786 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1787 N_VALUES * N_VALUES);
1789 TestTypeNode *val1, *val2;
1792 node = node_new (&struct_1_class);
1795 while ((val1 = value_generator (&i)))
1798 while ((val2 = value_generator (&j)))
1800 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1802 node_append_child (node, val1);
1803 node_append_child (node, val2);
1805 run_test_nodes (&node, 1);
1807 _dbus_list_clear (&container->children);
1808 node_destroy (val2);
1810 node_destroy (val1);
1812 node_destroy (node);
1815 start_next_test ("All values in one big struct %d iteration\n",
1819 TestTypeNode *child;
1821 node = node_new (&struct_1_class);
1824 while ((child = value_generator (&i)))
1825 node_append_child (node, child);
1827 run_test_nodes (&node, 1);
1829 node_destroy (node);
1832 start_next_test ("Each value in a large array %d iterations\n",
1838 node = node_new (&array_9_class);
1841 while ((val = value_generator (&i)))
1843 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1845 node_append_child (node, val);
1847 run_test_nodes (&node, 1);
1849 _dbus_list_clear (&container->children);
1853 node_destroy (node);
1856 start_next_test ("Each container of each container of each value %d iterations\n",
1857 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1858 for (i = 0; i < N_CONTAINERS; i++)
1860 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1861 TestTypeNode *outer_container = node_new (outer_container_klass);
1863 for (j = 0; j < N_CONTAINERS; j++)
1865 TestTypeNode *child;
1866 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1867 TestTypeNode *inner_container = node_new (inner_container_klass);
1869 node_append_child (outer_container, inner_container);
1872 while ((child = value_generator (&m)))
1874 node_append_child (inner_container, child);
1876 run_test_nodes (&outer_container, 1);
1878 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1879 node_destroy (child);
1881 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1882 node_destroy (inner_container);
1884 node_destroy (outer_container);
1887 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1888 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1889 for (i = 0; i < N_CONTAINERS; i++)
1891 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1892 TestTypeNode *outer_container = node_new (outer_container_klass);
1894 for (j = 0; j < N_CONTAINERS; j++)
1896 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1897 TestTypeNode *inner_container = node_new (inner_container_klass);
1899 node_append_child (outer_container, inner_container);
1901 for (k = 0; k < N_CONTAINERS; k++)
1903 TestTypeNode *child;
1904 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1905 TestTypeNode *center_container = node_new (center_container_klass);
1907 node_append_child (inner_container, center_container);
1910 while ((child = value_generator (&m)))
1912 node_append_child (center_container, child);
1914 run_test_nodes (&outer_container, 1);
1916 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1917 node_destroy (child);
1919 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1920 node_destroy (center_container);
1922 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1923 node_destroy (inner_container);
1925 node_destroy (outer_container);
1929 /* This one takes a really long time, so comment it out for now */
1930 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
1931 N_VALUES * N_VALUES * N_VALUES);
1933 TestTypeNode *nodes[3];
1936 while ((nodes[0] = value_generator (&i)))
1939 while ((nodes[1] = value_generator (&j)))
1942 while ((nodes[2] = value_generator (&k)))
1944 run_test_nodes (nodes, 3);
1946 node_destroy (nodes[2]);
1948 node_destroy (nodes[1]);
1950 node_destroy (nodes[0]);
1953 #endif /* #if 0 expensive test */
1955 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
1956 n_iterations_completed_total);
1957 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
1958 MAX_INITIAL_OFFSET);
1959 fprintf (stderr, "out of memory handling %s tested\n",
1960 TEST_OOM_HANDLING ? "was" : "was not");
1964 _dbus_marshal_recursive_test (void)
1966 make_and_run_test_nodes ();
1974 * Implementations of each type node class
1979 #define MAX_MULTI_COUNT 5
1982 #define SAMPLE_INT32 12345678
1983 #define SAMPLE_INT32_ALTERNATE 53781429
1985 int32_from_seed (int seed)
1987 /* Generate an integer value that's predictable from seed. We could
1988 * just use seed itself, but that would only ever touch one byte of
1989 * the int so would miss some kinds of bug.
1993 v = 42; /* just to quiet compiler afaik */
2000 v = SAMPLE_INT32_ALTERNATE;
2014 v *= seed; /* wraps around eventually, which is fine */
2020 int32_write_value (TestTypeNode *node,
2022 DBusTypeWriter *writer,
2025 /* also used for uint32 */
2028 v = int32_from_seed (seed);
2030 return _dbus_type_writer_write_basic (writer,
2031 node->klass->typecode,
2036 int32_read_value (TestTypeNode *node,
2037 DBusTypeReader *reader,
2040 /* also used for uint32 */
2043 check_expected_type (reader, node->klass->typecode);
2045 _dbus_type_reader_read_basic (reader,
2046 (dbus_int32_t*) &v);
2048 _dbus_assert (v == int32_from_seed (seed));
2054 int32_set_value (TestTypeNode *node,
2055 DBusTypeReader *reader,
2056 DBusTypeReader *realign_root,
2059 /* also used for uint32 */
2062 v = int32_from_seed (seed);
2064 return _dbus_type_reader_set_basic (reader,
2070 int32_write_multi (TestTypeNode *node,
2072 DBusTypeWriter *writer,
2076 /* also used for uint32 */
2077 dbus_int32_t values[MAX_MULTI_COUNT];
2078 dbus_int32_t *v_ARRAY_INT32 = values;
2081 for (i = 0; i < count; ++i)
2082 values[i] = int32_from_seed (seed + i);
2084 return _dbus_type_writer_write_fixed_multi (writer,
2085 node->klass->typecode,
2086 &v_ARRAY_INT32, count);
2090 int32_read_multi (TestTypeNode *node,
2091 DBusTypeReader *reader,
2095 /* also used for uint32 */
2096 dbus_int32_t *values;
2100 check_expected_type (reader, node->klass->typecode);
2102 _dbus_type_reader_read_fixed_multi (reader,
2106 if (n_elements != count)
2107 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2108 _dbus_assert (n_elements == count);
2110 for (i = 0; i < count; i++)
2111 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2112 (const unsigned char*)values + (i * 4))) ==
2113 int32_from_seed (seed + i));
2118 #ifdef DBUS_HAVE_INT64
2120 int64_from_seed (int seed)
2125 v32 = int32_from_seed (seed);
2127 v = - (dbus_int32_t) ~ v32;
2128 v |= (((dbus_int64_t)v32) << 32);
2135 int64_write_value (TestTypeNode *node,
2137 DBusTypeWriter *writer,
2140 #ifdef DBUS_HAVE_INT64
2141 /* also used for uint64 */
2144 v = int64_from_seed (seed);
2146 return _dbus_type_writer_write_basic (writer,
2147 node->klass->typecode,
2155 int64_read_value (TestTypeNode *node,
2156 DBusTypeReader *reader,
2159 #ifdef DBUS_HAVE_INT64
2160 /* also used for uint64 */
2163 check_expected_type (reader, node->klass->typecode);
2165 _dbus_type_reader_read_basic (reader,
2166 (dbus_int64_t*) &v);
2168 _dbus_assert (v == int64_from_seed (seed));
2177 int64_set_value (TestTypeNode *node,
2178 DBusTypeReader *reader,
2179 DBusTypeReader *realign_root,
2182 #ifdef DBUS_HAVE_INT64
2183 /* also used for uint64 */
2186 v = int64_from_seed (seed);
2188 return _dbus_type_reader_set_basic (reader,
2196 #define MAX_SAMPLE_STRING_LEN 10
2198 string_from_seed (char *buf,
2205 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2207 /* vary the length slightly, though we also have multiple string
2208 * value types for this, varying it here tests the set_value code
2222 v = (unsigned char) ('A' + seed);
2227 if (v < 'A' || v > 'z')
2240 string_write_value (TestTypeNode *node,
2242 DBusTypeWriter *writer,
2245 char buf[MAX_SAMPLE_STRING_LEN];
2246 const char *v_string = buf;
2248 string_from_seed (buf, node->klass->subclass_detail,
2251 return _dbus_type_writer_write_basic (writer,
2252 node->klass->typecode,
2257 string_read_value (TestTypeNode *node,
2258 DBusTypeReader *reader,
2262 char buf[MAX_SAMPLE_STRING_LEN];
2264 check_expected_type (reader, node->klass->typecode);
2266 _dbus_type_reader_read_basic (reader,
2267 (const char **) &v);
2269 string_from_seed (buf, node->klass->subclass_detail,
2272 if (strcmp (buf, v) != 0)
2274 _dbus_warn ("read string '%s' expected '%s'\n",
2276 _dbus_assert_not_reached ("test failed");
2283 string_set_value (TestTypeNode *node,
2284 DBusTypeReader *reader,
2285 DBusTypeReader *realign_root,
2288 char buf[MAX_SAMPLE_STRING_LEN];
2289 const char *v_string = buf;
2291 string_from_seed (buf, node->klass->subclass_detail,
2294 #if RECURSIVE_MARSHAL_WRITE_TRACE
2297 _dbus_type_reader_read_basic (reader, &old);
2298 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2299 v_string, strlen (v_string), old, strlen (old));
2303 return _dbus_type_reader_set_basic (reader,
2308 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2311 bool_write_value (TestTypeNode *node,
2313 DBusTypeWriter *writer,
2318 v = BOOL_FROM_SEED (seed);
2320 return _dbus_type_writer_write_basic (writer,
2321 node->klass->typecode,
2326 bool_read_value (TestTypeNode *node,
2327 DBusTypeReader *reader,
2332 check_expected_type (reader, node->klass->typecode);
2334 _dbus_type_reader_read_basic (reader,
2335 (unsigned char*) &v);
2337 _dbus_assert (v == BOOL_FROM_SEED (seed));
2343 bool_set_value (TestTypeNode *node,
2344 DBusTypeReader *reader,
2345 DBusTypeReader *realign_root,
2350 v = BOOL_FROM_SEED (seed);
2352 return _dbus_type_reader_set_basic (reader,
2357 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2360 byte_write_value (TestTypeNode *node,
2362 DBusTypeWriter *writer,
2367 v = BYTE_FROM_SEED (seed);
2369 return _dbus_type_writer_write_basic (writer,
2370 node->klass->typecode,
2375 byte_read_value (TestTypeNode *node,
2376 DBusTypeReader *reader,
2381 check_expected_type (reader, node->klass->typecode);
2383 _dbus_type_reader_read_basic (reader,
2384 (unsigned char*) &v);
2386 _dbus_assert (v == BYTE_FROM_SEED (seed));
2393 byte_set_value (TestTypeNode *node,
2394 DBusTypeReader *reader,
2395 DBusTypeReader *realign_root,
2400 v = BYTE_FROM_SEED (seed);
2402 return _dbus_type_reader_set_basic (reader,
2408 double_from_seed (int seed)
2410 return SAMPLE_INT32 * (double) seed + 0.3;
2414 double_write_value (TestTypeNode *node,
2416 DBusTypeWriter *writer,
2421 v = double_from_seed (seed);
2423 return _dbus_type_writer_write_basic (writer,
2424 node->klass->typecode,
2429 double_read_value (TestTypeNode *node,
2430 DBusTypeReader *reader,
2436 check_expected_type (reader, node->klass->typecode);
2438 _dbus_type_reader_read_basic (reader,
2441 expected = double_from_seed (seed);
2443 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2445 #ifdef DBUS_HAVE_INT64
2446 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2448 *(dbus_uint64_t*)(char*)&expected,
2449 *(dbus_uint64_t*)(char*)&v);
2451 _dbus_assert_not_reached ("test failed");
2458 double_set_value (TestTypeNode *node,
2459 DBusTypeReader *reader,
2460 DBusTypeReader *realign_root,
2465 v = double_from_seed (seed);
2467 return _dbus_type_reader_set_basic (reader,
2472 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2474 object_path_from_seed (char *buf,
2482 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2484 v = (unsigned char) ('A' + seed);
2496 if (v < 'A' || v > 'z')
2512 object_path_write_value (TestTypeNode *node,
2514 DBusTypeWriter *writer,
2517 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2518 const char *v_string = buf;
2520 object_path_from_seed (buf, seed);
2522 return _dbus_type_writer_write_basic (writer,
2523 node->klass->typecode,
2528 object_path_read_value (TestTypeNode *node,
2529 DBusTypeReader *reader,
2533 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2535 check_expected_type (reader, node->klass->typecode);
2537 _dbus_type_reader_read_basic (reader,
2538 (const char **) &v);
2540 object_path_from_seed (buf, seed);
2542 if (strcmp (buf, v) != 0)
2544 _dbus_warn ("read object path '%s' expected '%s'\n",
2546 _dbus_assert_not_reached ("test failed");
2553 object_path_set_value (TestTypeNode *node,
2554 DBusTypeReader *reader,
2555 DBusTypeReader *realign_root,
2558 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2559 const char *v_string = buf;
2561 object_path_from_seed (buf, seed);
2563 return _dbus_type_reader_set_basic (reader,
2568 #define MAX_SAMPLE_SIGNATURE_LEN 10
2570 signature_from_seed (char *buf,
2575 /* try to avoid ascending, descending, or alternating length to help find bugs */
2576 const char *sample_signatures[] = {
2585 s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)];
2587 for (i = 0; s[i]; i++)
2595 signature_write_value (TestTypeNode *node,
2597 DBusTypeWriter *writer,
2600 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2601 const char *v_string = buf;
2603 signature_from_seed (buf, seed);
2605 return _dbus_type_writer_write_basic (writer,
2606 node->klass->typecode,
2611 signature_read_value (TestTypeNode *node,
2612 DBusTypeReader *reader,
2616 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2618 check_expected_type (reader, node->klass->typecode);
2620 _dbus_type_reader_read_basic (reader,
2621 (const char **) &v);
2623 signature_from_seed (buf, seed);
2625 if (strcmp (buf, v) != 0)
2627 _dbus_warn ("read signature value '%s' expected '%s'\n",
2629 _dbus_assert_not_reached ("test failed");
2637 signature_set_value (TestTypeNode *node,
2638 DBusTypeReader *reader,
2639 DBusTypeReader *realign_root,
2642 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2643 const char *v_string = buf;
2645 signature_from_seed (buf, seed);
2647 return _dbus_type_reader_set_basic (reader,
2653 struct_write_value (TestTypeNode *node,
2655 DBusTypeWriter *writer,
2658 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2659 DataBlockState saved;
2664 n_copies = node->klass->subclass_detail;
2666 _dbus_assert (container->children != NULL);
2668 data_block_save (block, &saved);
2670 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2676 while (i < n_copies)
2680 link = _dbus_list_get_first_link (&container->children);
2681 while (link != NULL)
2683 TestTypeNode *child = link->data;
2684 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2686 if (!node_write_value (child, block, &sub, seed + i))
2688 data_block_restore (block, &saved);
2698 if (!_dbus_type_writer_unrecurse (writer, &sub))
2700 data_block_restore (block, &saved);
2708 struct_read_or_set_value (TestTypeNode *node,
2709 DBusTypeReader *reader,
2710 DBusTypeReader *realign_root,
2713 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2718 n_copies = node->klass->subclass_detail;
2720 check_expected_type (reader, DBUS_TYPE_STRUCT);
2722 _dbus_type_reader_recurse (reader, &sub);
2725 while (i < n_copies)
2729 link = _dbus_list_get_first_link (&container->children);
2730 while (link != NULL)
2732 TestTypeNode *child = link->data;
2733 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2735 if (realign_root == NULL)
2737 if (!node_read_value (child, &sub, seed + i))
2742 if (!node_set_value (child, &sub, realign_root, seed + i))
2746 if (i == (n_copies - 1) && next == NULL)
2747 NEXT_EXPECTING_FALSE (&sub);
2749 NEXT_EXPECTING_TRUE (&sub);
2761 struct_read_value (TestTypeNode *node,
2762 DBusTypeReader *reader,
2765 return struct_read_or_set_value (node, reader, NULL, seed);
2769 struct_set_value (TestTypeNode *node,
2770 DBusTypeReader *reader,
2771 DBusTypeReader *realign_root,
2774 return struct_read_or_set_value (node, reader, realign_root, seed);
2778 struct_build_signature (TestTypeNode *node,
2781 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2786 n_copies = node->klass->subclass_detail;
2788 orig_len = _dbus_string_get_length (str);
2790 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2794 while (i < n_copies)
2798 link = _dbus_list_get_first_link (&container->children);
2799 while (link != NULL)
2801 TestTypeNode *child = link->data;
2802 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2804 if (!node_build_signature (child, str))
2813 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
2819 _dbus_string_set_length (str, orig_len);
2824 array_write_value (TestTypeNode *node,
2826 DBusTypeWriter *writer,
2829 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2830 DataBlockState saved;
2832 DBusString element_signature;
2836 TestTypeNode *child;
2838 n_copies = node->klass->subclass_detail;
2840 _dbus_assert (container->children != NULL);
2842 data_block_save (block, &saved);
2844 if (!_dbus_string_init (&element_signature))
2847 child = _dbus_list_get_first (&container->children);
2849 if (!node_build_signature (child,
2850 &element_signature))
2853 element_type = _dbus_first_type_in_signature (&element_signature, 0);
2855 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
2856 &element_signature, 0,
2860 if (arrays_write_fixed_in_blocks &&
2861 _dbus_type_is_fixed (element_type) &&
2862 child->klass->write_multi)
2864 if (!node_write_multi (child, block, &sub, seed, n_copies))
2870 while (i < n_copies)
2874 link = _dbus_list_get_first_link (&container->children);
2875 while (link != NULL)
2877 TestTypeNode *child = link->data;
2878 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2880 if (!node_write_value (child, block, &sub, seed + i))
2890 if (!_dbus_type_writer_unrecurse (writer, &sub))
2893 _dbus_string_free (&element_signature);
2897 data_block_restore (block, &saved);
2898 _dbus_string_free (&element_signature);
2903 array_read_or_set_value (TestTypeNode *node,
2904 DBusTypeReader *reader,
2905 DBusTypeReader *realign_root,
2908 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2912 TestTypeNode *child;
2914 n_copies = node->klass->subclass_detail;
2916 check_expected_type (reader, DBUS_TYPE_ARRAY);
2918 child = _dbus_list_get_first (&container->children);
2922 _dbus_type_reader_recurse (reader, &sub);
2924 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
2925 _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
2926 child->klass->read_multi)
2928 if (!node_read_multi (child, &sub, seed, n_copies))
2934 while (i < n_copies)
2938 link = _dbus_list_get_first_link (&container->children);
2939 while (link != NULL)
2941 TestTypeNode *child = link->data;
2942 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2944 _dbus_assert (child->klass->typecode ==
2945 _dbus_type_reader_get_element_type (reader));
2947 if (realign_root == NULL)
2949 if (!node_read_value (child, &sub, seed + i))
2954 if (!node_set_value (child, &sub, realign_root, seed + i))
2958 if (i == (n_copies - 1) && next == NULL)
2959 NEXT_EXPECTING_FALSE (&sub);
2961 NEXT_EXPECTING_TRUE (&sub);
2975 array_read_value (TestTypeNode *node,
2976 DBusTypeReader *reader,
2979 return array_read_or_set_value (node, reader, NULL, seed);
2983 array_set_value (TestTypeNode *node,
2984 DBusTypeReader *reader,
2985 DBusTypeReader *realign_root,
2988 return array_read_or_set_value (node, reader, realign_root, seed);
2992 array_build_signature (TestTypeNode *node,
2995 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2998 orig_len = _dbus_string_get_length (str);
3000 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3003 if (!node_build_signature (_dbus_list_get_first (&container->children),
3010 _dbus_string_set_length (str, orig_len);
3014 /* 10 is random just to add another seed that we use in the suite */
3015 #define VARIANT_SEED 10
3018 variant_write_value (TestTypeNode *node,
3020 DBusTypeWriter *writer,
3023 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3024 DataBlockState saved;
3026 DBusString content_signature;
3027 TestTypeNode *child;
3029 _dbus_assert (container->children != NULL);
3030 _dbus_assert (_dbus_list_length_is_one (&container->children));
3032 child = _dbus_list_get_first (&container->children);
3034 data_block_save (block, &saved);
3036 if (!_dbus_string_init (&content_signature))
3039 if (!node_build_signature (child,
3040 &content_signature))
3043 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3044 &content_signature, 0,
3048 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3051 if (!_dbus_type_writer_unrecurse (writer, &sub))
3054 _dbus_string_free (&content_signature);
3058 data_block_restore (block, &saved);
3059 _dbus_string_free (&content_signature);
3064 variant_read_or_set_value (TestTypeNode *node,
3065 DBusTypeReader *reader,
3066 DBusTypeReader *realign_root,
3069 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3071 TestTypeNode *child;
3073 _dbus_assert (container->children != NULL);
3074 _dbus_assert (_dbus_list_length_is_one (&container->children));
3076 child = _dbus_list_get_first (&container->children);
3078 check_expected_type (reader, DBUS_TYPE_VARIANT);
3080 _dbus_type_reader_recurse (reader, &sub);
3082 if (realign_root == NULL)
3084 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3089 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3093 NEXT_EXPECTING_FALSE (&sub);
3099 variant_read_value (TestTypeNode *node,
3100 DBusTypeReader *reader,
3103 return variant_read_or_set_value (node, reader, NULL, seed);
3107 variant_set_value (TestTypeNode *node,
3108 DBusTypeReader *reader,
3109 DBusTypeReader *realign_root,
3112 return variant_read_or_set_value (node, reader, realign_root, seed);
3116 container_destroy (TestTypeNode *node)
3118 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3121 link = _dbus_list_get_first_link (&container->children);
3122 while (link != NULL)
3124 TestTypeNode *child = link->data;
3125 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3127 node_destroy (child);
3129 _dbus_list_free_link (link);
3135 #endif /* DBUS_BUILD_TESTS */