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 int16_write_value (TestTypeNode *node,
401 DBusTypeWriter *writer,
403 static dbus_bool_t int16_read_value (TestTypeNode *node,
404 DBusTypeReader *reader,
406 static dbus_bool_t int16_set_value (TestTypeNode *node,
407 DBusTypeReader *reader,
408 DBusTypeReader *realign_root,
410 static dbus_bool_t int16_write_multi (TestTypeNode *node,
412 DBusTypeWriter *writer,
415 static dbus_bool_t int16_read_multi (TestTypeNode *node,
416 DBusTypeReader *reader,
419 static dbus_bool_t int32_write_value (TestTypeNode *node,
421 DBusTypeWriter *writer,
423 static dbus_bool_t int32_read_value (TestTypeNode *node,
424 DBusTypeReader *reader,
426 static dbus_bool_t int32_set_value (TestTypeNode *node,
427 DBusTypeReader *reader,
428 DBusTypeReader *realign_root,
430 static dbus_bool_t int32_write_multi (TestTypeNode *node,
432 DBusTypeWriter *writer,
435 static dbus_bool_t int32_read_multi (TestTypeNode *node,
436 DBusTypeReader *reader,
439 static dbus_bool_t int64_write_value (TestTypeNode *node,
441 DBusTypeWriter *writer,
443 static dbus_bool_t int64_read_value (TestTypeNode *node,
444 DBusTypeReader *reader,
446 static dbus_bool_t int64_set_value (TestTypeNode *node,
447 DBusTypeReader *reader,
448 DBusTypeReader *realign_root,
450 static dbus_bool_t string_write_value (TestTypeNode *node,
452 DBusTypeWriter *writer,
454 static dbus_bool_t string_read_value (TestTypeNode *node,
455 DBusTypeReader *reader,
457 static dbus_bool_t string_set_value (TestTypeNode *node,
458 DBusTypeReader *reader,
459 DBusTypeReader *realign_root,
461 static dbus_bool_t bool_write_value (TestTypeNode *node,
463 DBusTypeWriter *writer,
465 static dbus_bool_t bool_read_value (TestTypeNode *node,
466 DBusTypeReader *reader,
468 static dbus_bool_t bool_set_value (TestTypeNode *node,
469 DBusTypeReader *reader,
470 DBusTypeReader *realign_root,
472 static dbus_bool_t byte_write_value (TestTypeNode *node,
474 DBusTypeWriter *writer,
476 static dbus_bool_t byte_read_value (TestTypeNode *node,
477 DBusTypeReader *reader,
479 static dbus_bool_t byte_set_value (TestTypeNode *node,
480 DBusTypeReader *reader,
481 DBusTypeReader *realign_root,
483 static dbus_bool_t double_write_value (TestTypeNode *node,
485 DBusTypeWriter *writer,
487 static dbus_bool_t double_read_value (TestTypeNode *node,
488 DBusTypeReader *reader,
490 static dbus_bool_t double_set_value (TestTypeNode *node,
491 DBusTypeReader *reader,
492 DBusTypeReader *realign_root,
494 static dbus_bool_t object_path_write_value (TestTypeNode *node,
496 DBusTypeWriter *writer,
498 static dbus_bool_t object_path_read_value (TestTypeNode *node,
499 DBusTypeReader *reader,
501 static dbus_bool_t object_path_set_value (TestTypeNode *node,
502 DBusTypeReader *reader,
503 DBusTypeReader *realign_root,
505 static dbus_bool_t signature_write_value (TestTypeNode *node,
507 DBusTypeWriter *writer,
509 static dbus_bool_t signature_read_value (TestTypeNode *node,
510 DBusTypeReader *reader,
512 static dbus_bool_t signature_set_value (TestTypeNode *node,
513 DBusTypeReader *reader,
514 DBusTypeReader *realign_root,
516 static dbus_bool_t struct_write_value (TestTypeNode *node,
518 DBusTypeWriter *writer,
520 static dbus_bool_t struct_read_value (TestTypeNode *node,
521 DBusTypeReader *reader,
523 static dbus_bool_t struct_set_value (TestTypeNode *node,
524 DBusTypeReader *reader,
525 DBusTypeReader *realign_root,
527 static dbus_bool_t struct_build_signature (TestTypeNode *node,
529 static dbus_bool_t array_write_value (TestTypeNode *node,
531 DBusTypeWriter *writer,
533 static dbus_bool_t array_read_value (TestTypeNode *node,
534 DBusTypeReader *reader,
536 static dbus_bool_t array_set_value (TestTypeNode *node,
537 DBusTypeReader *reader,
538 DBusTypeReader *realign_root,
540 static dbus_bool_t array_build_signature (TestTypeNode *node,
542 static dbus_bool_t variant_write_value (TestTypeNode *node,
544 DBusTypeWriter *writer,
546 static dbus_bool_t variant_read_value (TestTypeNode *node,
547 DBusTypeReader *reader,
549 static dbus_bool_t variant_set_value (TestTypeNode *node,
550 DBusTypeReader *reader,
551 DBusTypeReader *realign_root,
553 static void container_destroy (TestTypeNode *node);
556 static const TestTypeNodeClass int16_class = {
558 sizeof (TestTypeNode),
570 static const TestTypeNodeClass uint16_class = {
572 sizeof (TestTypeNode),
576 int16_write_value, /* recycle from int16 */
577 int16_read_value, /* recycle from int16 */
578 int16_set_value, /* recycle from int16 */
580 int16_write_multi, /* recycle from int16 */
581 int16_read_multi /* recycle from int16 */
584 static const TestTypeNodeClass int32_class = {
586 sizeof (TestTypeNode),
598 static const TestTypeNodeClass uint32_class = {
600 sizeof (TestTypeNode),
604 int32_write_value, /* recycle from int32 */
605 int32_read_value, /* recycle from int32 */
606 int32_set_value, /* recycle from int32 */
608 int32_write_multi, /* recycle from int32 */
609 int32_read_multi /* recycle from int32 */
612 static const TestTypeNodeClass int64_class = {
614 sizeof (TestTypeNode),
626 static const TestTypeNodeClass uint64_class = {
628 sizeof (TestTypeNode),
632 int64_write_value, /* recycle from int64 */
633 int64_read_value, /* recycle from int64 */
634 int64_set_value, /* recycle from int64 */
640 static const TestTypeNodeClass string_0_class = {
642 sizeof (TestTypeNode),
643 0, /* string length */
654 static const TestTypeNodeClass string_1_class = {
656 sizeof (TestTypeNode),
657 1, /* string length */
668 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
669 static const TestTypeNodeClass string_3_class = {
671 sizeof (TestTypeNode),
672 3, /* string length */
683 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
684 static const TestTypeNodeClass string_8_class = {
686 sizeof (TestTypeNode),
687 8, /* string length */
698 static const TestTypeNodeClass bool_class = {
700 sizeof (TestTypeNode),
712 static const TestTypeNodeClass byte_class = {
714 sizeof (TestTypeNode),
726 static const TestTypeNodeClass double_class = {
728 sizeof (TestTypeNode),
740 static const TestTypeNodeClass object_path_class = {
741 DBUS_TYPE_OBJECT_PATH,
742 sizeof (TestTypeNode),
746 object_path_write_value,
747 object_path_read_value,
748 object_path_set_value,
754 static const TestTypeNodeClass signature_class = {
756 sizeof (TestTypeNode),
760 signature_write_value,
761 signature_read_value,
768 static const TestTypeNodeClass struct_1_class = {
770 sizeof (TestTypeNodeContainer),
771 1, /* number of times children appear as fields */
777 struct_build_signature,
782 static const TestTypeNodeClass struct_2_class = {
784 sizeof (TestTypeNodeContainer),
785 2, /* number of times children appear as fields */
791 struct_build_signature,
796 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
798 static const TestTypeNodeClass array_0_class = {
800 sizeof (TestTypeNodeContainer),
801 0, /* number of array elements */
807 array_build_signature,
812 static const TestTypeNodeClass array_1_class = {
814 sizeof (TestTypeNodeContainer),
815 1, /* number of array elements */
821 array_build_signature,
826 static const TestTypeNodeClass array_2_class = {
828 sizeof (TestTypeNodeContainer),
829 2, /* number of array elements */
835 array_build_signature,
840 static const TestTypeNodeClass array_9_class = {
842 sizeof (TestTypeNodeContainer),
843 9, /* number of array elements */
849 array_build_signature,
854 static const TestTypeNodeClass variant_class = {
856 sizeof (TestTypeNodeContainer),
868 static const TestTypeNodeClass* const
886 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
888 static const TestTypeNodeClass* const
889 container_nodes[] = {
896 /* array_9_class is omitted on purpose, it's too slow;
897 * we only use it in one hardcoded test below
900 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
903 node_new (const TestTypeNodeClass *klass)
907 node = dbus_malloc0 (klass->instance_size);
913 if (klass->construct)
915 if (!(* klass->construct) (node))
926 node_destroy (TestTypeNode *node)
928 if (node->klass->destroy)
929 (* node->klass->destroy) (node);
934 node_write_value (TestTypeNode *node,
936 DBusTypeWriter *writer,
941 retval = (* node->klass->write_value) (node, block, writer, seed);
944 /* Handy to see where things break, but too expensive to do all the time */
945 data_block_verify (block);
952 node_read_value (TestTypeNode *node,
953 DBusTypeReader *reader,
957 DBusTypeReader restored;
959 _dbus_type_reader_save_mark (reader, &mark);
961 if (!(* node->klass->read_value) (node, reader, seed))
964 _dbus_type_reader_init_from_mark (&restored,
970 if (!(* node->klass->read_value) (node, &restored, seed))
976 /* Warning: if this one fails due to OOM, it has side effects (can
977 * modify only some of the sub-values). OK in a test suite, but we
978 * never do this in real code.
981 node_set_value (TestTypeNode *node,
982 DBusTypeReader *reader,
983 DBusTypeReader *realign_root,
986 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
993 node_build_signature (TestTypeNode *node,
996 if (node->klass->build_signature)
997 return (* node->klass->build_signature) (node, str);
999 return _dbus_string_append_byte (str, node->klass->typecode);
1003 node_append_child (TestTypeNode *node,
1004 TestTypeNode *child)
1006 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1008 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
1010 if (!_dbus_list_append (&container->children, child))
1011 _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 */
1017 node_write_multi (TestTypeNode *node,
1019 DBusTypeWriter *writer,
1025 _dbus_assert (node->klass->write_multi != NULL);
1026 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
1029 /* Handy to see where things break, but too expensive to do all the time */
1030 data_block_verify (block);
1037 node_read_multi (TestTypeNode *node,
1038 DBusTypeReader *reader,
1042 _dbus_assert (node->klass->read_multi != NULL);
1044 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1050 static int n_iterations_completed_total = 0;
1051 static int n_iterations_completed_this_test = 0;
1052 static int n_iterations_expected_this_test = 0;
1056 const DBusString *signature;
1059 TestTypeNode **nodes;
1061 } NodeIterationData;
1064 run_test_copy (NodeIterationData *nid)
1069 DBusTypeReader reader;
1070 DBusTypeWriter writer;
1072 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1078 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1081 data_block_init_reader_writer (src, &reader, NULL);
1082 data_block_init_reader_writer (&dest, NULL, &writer);
1084 /* DBusTypeWriter assumes it's writing into an existing signature,
1085 * so doesn't add nul on its own. We have to do that.
1087 if (!_dbus_string_insert_byte (&dest.signature,
1088 dest.initial_offset, '\0'))
1091 if (!_dbus_type_writer_write_reader (&writer, &reader))
1094 /* Data blocks should now be identical */
1095 if (!_dbus_string_equal (&src->signature, &dest.signature))
1097 _dbus_verbose ("SOURCE\n");
1098 _dbus_verbose_bytes_of_string (&src->signature, 0,
1099 _dbus_string_get_length (&src->signature));
1100 _dbus_verbose ("DEST\n");
1101 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1102 _dbus_string_get_length (&dest.signature));
1103 _dbus_assert_not_reached ("signatures did not match");
1106 if (!_dbus_string_equal (&src->body, &dest.body))
1108 _dbus_verbose ("SOURCE\n");
1109 _dbus_verbose_bytes_of_string (&src->body, 0,
1110 _dbus_string_get_length (&src->body));
1111 _dbus_verbose ("DEST\n");
1112 _dbus_verbose_bytes_of_string (&dest.body, 0,
1113 _dbus_string_get_length (&dest.body));
1114 _dbus_assert_not_reached ("bodies did not match");
1121 data_block_free (&dest);
1127 run_test_values_only_write (NodeIterationData *nid)
1129 DBusTypeReader reader;
1130 DBusTypeWriter writer;
1135 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1139 data_block_reset (nid->block);
1141 sig_len = _dbus_string_get_length (nid->signature);
1143 _dbus_type_writer_init_values_only (&writer,
1144 nid->block->byte_order,
1147 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1148 _dbus_type_reader_init (&reader,
1149 nid->block->byte_order,
1152 nid->block->initial_offset);
1155 while (i < nid->n_nodes)
1157 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1163 /* if we wrote any typecodes then this would fail */
1164 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1166 /* But be sure we wrote out the values correctly */
1168 while (i < nid->n_nodes)
1170 if (!node_read_value (nid->nodes[i], &reader, i))
1173 if (i + 1 == nid->n_nodes)
1174 NEXT_EXPECTING_FALSE (&reader);
1176 NEXT_EXPECTING_TRUE (&reader);
1184 data_block_reset (nid->block);
1188 /* offset the seed for setting, so we set different numbers than
1189 * we originally wrote. Don't offset by a huge number since in
1190 * some cases it's value = possibilities[seed % n_possibilities]
1191 * and we don't want to wrap around. bool_from_seed
1192 * is just seed % 2 even.
1196 run_test_set_values (NodeIterationData *nid)
1198 DBusTypeReader reader;
1199 DBusTypeReader realign_root;
1203 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1207 data_block_init_reader_writer (nid->block,
1210 realign_root = reader;
1213 while (i < nid->n_nodes)
1215 if (!node_set_value (nid->nodes[i],
1216 &reader, &realign_root,
1220 if (i + 1 == nid->n_nodes)
1221 NEXT_EXPECTING_FALSE (&reader);
1223 NEXT_EXPECTING_TRUE (&reader);
1228 /* Check that the new values were set */
1230 reader = realign_root;
1233 while (i < nid->n_nodes)
1235 if (!node_read_value (nid->nodes[i], &reader,
1239 if (i + 1 == nid->n_nodes)
1240 NEXT_EXPECTING_FALSE (&reader);
1242 NEXT_EXPECTING_TRUE (&reader);
1254 run_test_delete_values (NodeIterationData *nid)
1256 DBusTypeReader reader;
1260 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1264 data_block_init_reader_writer (nid->block,
1267 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1269 /* Right now, deleting only works on array elements. We delete
1270 * all array elements, and then verify that there aren't any
1273 if (t == DBUS_TYPE_ARRAY)
1275 DBusTypeReader array;
1279 _dbus_type_reader_recurse (&reader, &array);
1281 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1284 _dbus_type_reader_next (&array);
1287 /* reset to start of array */
1288 _dbus_type_reader_recurse (&reader, &array);
1289 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1290 reader.value_pos, array.value_pos, array.u.array.start_pos);
1291 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1293 /* We don't want to always delete from the same part of the array. */
1294 static int cycle = 0;
1297 _dbus_assert (n_elements > 0);
1300 if (elem == 3 || elem >= n_elements) /* end of array */
1301 elem = n_elements - 1;
1303 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1304 elem, n_elements, _dbus_type_to_string (elem_type),
1305 cycle, reader.value_pos, array.value_pos);
1308 if (!_dbus_type_reader_next (&array))
1309 _dbus_assert_not_reached ("should have had another element\n");
1313 if (!_dbus_type_reader_delete (&array, &reader))
1319 _dbus_type_reader_recurse (&reader, &array);
1327 _dbus_type_reader_next (&reader);
1330 /* Check that there are no array elements left */
1331 data_block_init_reader_writer (nid->block,
1334 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1336 _dbus_type_reader_next (&reader);
1346 run_test_nodes_iteration (void *data)
1348 NodeIterationData *nid = data;
1349 DBusTypeReader reader;
1350 DBusTypeWriter writer;
1355 * 1. write the value
1356 * 2. strcmp-compare with the signature we built
1358 * 4. type-iterate the signature and the value and see if they are the same type-wise
1362 data_block_init_reader_writer (nid->block,
1365 /* DBusTypeWriter assumes it's writing into an existing signature,
1366 * so doesn't add nul on its own. We have to do that.
1368 if (!_dbus_string_insert_byte (&nid->block->signature,
1369 nid->type_offset, '\0'))
1373 while (i < nid->n_nodes)
1375 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1381 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1382 &nid->block->signature, nid->type_offset))
1384 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1385 _dbus_string_get_const_data (nid->signature),
1386 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1388 _dbus_assert_not_reached ("wrong signature");
1392 while (i < nid->n_nodes)
1394 if (!node_read_value (nid->nodes[i], &reader, i))
1397 if (i + 1 == nid->n_nodes)
1398 NEXT_EXPECTING_FALSE (&reader);
1400 NEXT_EXPECTING_TRUE (&reader);
1405 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1407 /* this set values test uses code from copy and
1408 * values_only_write so would ideally be last so you get a
1409 * simpler test case for problems with copying or values_only
1410 * writing; but it also needs an already-written DataBlock so it
1411 * has to go first. Comment it out if it breaks, and see if the
1412 * later tests also break - debug them first if so.
1414 if (!run_test_set_values (nid))
1417 if (!run_test_delete_values (nid))
1420 if (!run_test_copy (nid))
1423 if (!run_test_values_only_write (nid))
1427 /* FIXME type-iterate both signature and value and compare the resulting
1428 * tree to the node tree perhaps
1435 data_block_reset (nid->block);
1441 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1443 const DBusString *signature,
1448 NodeIterationData nid;
1450 if (!data_block_init (&block, byte_order, initial_offset))
1451 _dbus_assert_not_reached ("no memory");
1453 nid.signature = signature;
1455 nid.type_offset = initial_offset;
1457 nid.n_nodes = n_nodes;
1459 if (TEST_OOM_HANDLING &&
1460 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1462 _dbus_test_oom_handling ("running test node",
1463 run_test_nodes_iteration,
1468 if (!run_test_nodes_iteration (&nid))
1469 _dbus_assert_not_reached ("no memory");
1472 data_block_free (&block);
1476 run_test_nodes (TestTypeNode **nodes,
1480 DBusString signature;
1482 if (!_dbus_string_init (&signature))
1483 _dbus_assert_not_reached ("no memory");
1488 if (! node_build_signature (nodes[i], &signature))
1489 _dbus_assert_not_reached ("no memory");
1494 _dbus_verbose (">>> test nodes with signature '%s'\n",
1495 _dbus_string_get_const_data (&signature));
1498 while (i <= MAX_INITIAL_OFFSET)
1500 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1501 DBUS_LITTLE_ENDIAN, i);
1502 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1503 DBUS_BIG_ENDIAN, i);
1508 n_iterations_completed_this_test += 1;
1509 n_iterations_completed_total += 1;
1511 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1513 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1514 n_iterations_completed_this_test,
1515 n_iterations_completed_total);
1517 /* this happens to turn out well with mod == 1 */
1518 else if ((n_iterations_completed_this_test %
1519 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1521 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1524 _dbus_string_free (&signature);
1527 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1529 static TestTypeNode*
1530 value_generator (int *ip)
1533 const TestTypeNodeClass *child_klass;
1534 const TestTypeNodeClass *container_klass;
1535 TestTypeNode *child;
1538 _dbus_assert (i <= N_VALUES);
1544 else if (i < N_BASICS)
1546 node = node_new (basic_nodes[i]);
1550 /* imagine an array:
1551 * container 0 of basic 0
1552 * container 0 of basic 1
1553 * container 0 of basic 2
1554 * container 1 of basic 0
1555 * container 1 of basic 1
1556 * container 1 of basic 2
1560 container_klass = container_nodes[i / N_BASICS];
1561 child_klass = basic_nodes[i % N_BASICS];
1563 node = node_new (container_klass);
1564 child = node_new (child_klass);
1566 node_append_child (node, child);
1569 *ip += 1; /* increment the generator */
1575 build_body (TestTypeNode **nodes,
1578 DBusString *signature,
1583 DBusTypeReader reader;
1584 DBusTypeWriter writer;
1589 if (! node_build_signature (nodes[i], signature))
1590 _dbus_assert_not_reached ("no memory");
1595 if (!data_block_init (&block, byte_order, 0))
1596 _dbus_assert_not_reached ("no memory");
1598 data_block_init_reader_writer (&block,
1601 /* DBusTypeWriter assumes it's writing into an existing signature,
1602 * so doesn't add nul on its own. We have to do that.
1604 if (!_dbus_string_insert_byte (&block.signature,
1606 _dbus_assert_not_reached ("no memory");
1611 if (!node_write_value (nodes[i], &block, &writer, i))
1612 _dbus_assert_not_reached ("no memory");
1617 if (!_dbus_string_copy_len (&block.body, 0,
1618 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1620 _dbus_assert_not_reached ("oom");
1622 data_block_free (&block);
1626 dbus_internal_do_not_use_generate_bodies (int sequence,
1628 DBusString *signature,
1631 TestTypeNode *nodes[1];
1635 nodes[0] = value_generator (&sequence);
1637 if (nodes[0] == NULL)
1642 build_body (nodes, n_nodes, byte_order, signature, body);
1648 node_destroy (nodes[i]);
1656 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1660 TestTypeNode *container;
1661 TestTypeNode *child;
1664 root = node_new (container_klass);
1666 for (i = 1; i < n_nested; i++)
1668 child = node_new (container_klass);
1669 node_append_child (container, child);
1673 /* container should now be the most-nested container */
1676 while ((child = value_generator (&i)))
1678 node_append_child (container, child);
1680 run_test_nodes (&root, 1);
1682 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1683 node_destroy (child);
1686 node_destroy (root);
1690 start_next_test (const char *format,
1693 n_iterations_completed_this_test = 0;
1694 n_iterations_expected_this_test = expected;
1696 fprintf (stderr, ">>> >>> ");
1697 fprintf (stderr, format,
1698 n_iterations_expected_this_test);
1702 make_and_run_test_nodes (void)
1706 /* We try to do this in order of "complicatedness" so that test
1707 * failures tend to show up in the simplest test case that
1708 * demonstrates the failure. There are also some tests that run
1709 * more than once for this reason, first while going through simple
1710 * cases, second while going through a broader range of complex
1713 /* Each basic node. The basic nodes should include:
1715 * - each fixed-size type (in such a way that it has different values each time,
1716 * so we can tell if we mix two of them up)
1717 * - strings of various lengths
1721 /* Each container node. The container nodes should include:
1723 * struct with 1 and 2 copies of the contained item
1724 * array with 0, 1, 2 copies of the contained item
1727 /* Let a "value" be a basic node, or a container containing a single basic node.
1728 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1729 * When iterating through all values to make combinations, do the basic types
1730 * first and the containers second.
1732 /* Each item is shown with its number of iterations to complete so
1733 * we can keep a handle on this unit test
1736 /* FIXME test just an empty body, no types at all */
1738 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1742 while ((node = value_generator (&i)))
1744 run_test_nodes (&node, 1);
1746 node_destroy (node);
1750 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1751 arrays_write_fixed_in_blocks = TRUE;
1755 while ((node = value_generator (&i)))
1757 run_test_nodes (&node, 1);
1759 node_destroy (node);
1762 arrays_write_fixed_in_blocks = FALSE;
1764 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1766 TestTypeNode *nodes[N_VALUES];
1769 while ((nodes[i] = value_generator (&i)))
1772 run_test_nodes (nodes, N_VALUES);
1774 for (i = 0; i < N_VALUES; i++)
1775 node_destroy (nodes[i]);
1778 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1779 N_VALUES * N_VALUES);
1781 TestTypeNode *nodes[2];
1784 while ((nodes[0] = value_generator (&i)))
1787 while ((nodes[1] = value_generator (&j)))
1789 run_test_nodes (nodes, 2);
1791 node_destroy (nodes[1]);
1794 node_destroy (nodes[0]);
1798 start_next_test ("Each container containing each value %d iterations\n",
1799 N_CONTAINERS * N_VALUES);
1800 for (i = 0; i < N_CONTAINERS; i++)
1802 const TestTypeNodeClass *container_klass = container_nodes[i];
1804 make_and_run_values_inside_container (container_klass, 1);
1807 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1808 N_CONTAINERS * N_VALUES);
1809 arrays_write_fixed_in_blocks = TRUE;
1810 for (i = 0; i < N_CONTAINERS; i++)
1812 const TestTypeNodeClass *container_klass = container_nodes[i];
1814 make_and_run_values_inside_container (container_klass, 1);
1816 arrays_write_fixed_in_blocks = FALSE;
1818 start_next_test ("Each container of same container of each value %d iterations\n",
1819 N_CONTAINERS * N_VALUES);
1820 for (i = 0; i < N_CONTAINERS; i++)
1822 const TestTypeNodeClass *container_klass = container_nodes[i];
1824 make_and_run_values_inside_container (container_klass, 2);
1827 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1828 N_CONTAINERS * N_VALUES);
1829 for (i = 0; i < N_CONTAINERS; i++)
1831 const TestTypeNodeClass *container_klass = container_nodes[i];
1833 make_and_run_values_inside_container (container_klass, 3);
1836 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1837 N_VALUES * N_VALUES);
1839 TestTypeNode *val1, *val2;
1842 node = node_new (&struct_1_class);
1845 while ((val1 = value_generator (&i)))
1848 while ((val2 = value_generator (&j)))
1850 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1852 node_append_child (node, val1);
1853 node_append_child (node, val2);
1855 run_test_nodes (&node, 1);
1857 _dbus_list_clear (&container->children);
1858 node_destroy (val2);
1860 node_destroy (val1);
1862 node_destroy (node);
1865 start_next_test ("All values in one big struct %d iteration\n",
1869 TestTypeNode *child;
1871 node = node_new (&struct_1_class);
1874 while ((child = value_generator (&i)))
1875 node_append_child (node, child);
1877 run_test_nodes (&node, 1);
1879 node_destroy (node);
1882 start_next_test ("Each value in a large array %d iterations\n",
1888 node = node_new (&array_9_class);
1891 while ((val = value_generator (&i)))
1893 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1895 node_append_child (node, val);
1897 run_test_nodes (&node, 1);
1899 _dbus_list_clear (&container->children);
1903 node_destroy (node);
1906 start_next_test ("Each container of each container of each value %d iterations\n",
1907 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1908 for (i = 0; i < N_CONTAINERS; i++)
1910 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1911 TestTypeNode *outer_container = node_new (outer_container_klass);
1913 for (j = 0; j < N_CONTAINERS; j++)
1915 TestTypeNode *child;
1916 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1917 TestTypeNode *inner_container = node_new (inner_container_klass);
1919 node_append_child (outer_container, inner_container);
1922 while ((child = value_generator (&m)))
1924 node_append_child (inner_container, child);
1926 run_test_nodes (&outer_container, 1);
1928 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1929 node_destroy (child);
1931 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1932 node_destroy (inner_container);
1934 node_destroy (outer_container);
1937 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1938 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1939 for (i = 0; i < N_CONTAINERS; i++)
1941 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1942 TestTypeNode *outer_container = node_new (outer_container_klass);
1944 for (j = 0; j < N_CONTAINERS; j++)
1946 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1947 TestTypeNode *inner_container = node_new (inner_container_klass);
1949 node_append_child (outer_container, inner_container);
1951 for (k = 0; k < N_CONTAINERS; k++)
1953 TestTypeNode *child;
1954 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1955 TestTypeNode *center_container = node_new (center_container_klass);
1957 node_append_child (inner_container, center_container);
1960 while ((child = value_generator (&m)))
1962 node_append_child (center_container, child);
1964 run_test_nodes (&outer_container, 1);
1966 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1967 node_destroy (child);
1969 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1970 node_destroy (center_container);
1972 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1973 node_destroy (inner_container);
1975 node_destroy (outer_container);
1979 /* This one takes a really long time, so comment it out for now */
1980 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
1981 N_VALUES * N_VALUES * N_VALUES);
1983 TestTypeNode *nodes[3];
1986 while ((nodes[0] = value_generator (&i)))
1989 while ((nodes[1] = value_generator (&j)))
1992 while ((nodes[2] = value_generator (&k)))
1994 run_test_nodes (nodes, 3);
1996 node_destroy (nodes[2]);
1998 node_destroy (nodes[1]);
2000 node_destroy (nodes[0]);
2003 #endif /* #if 0 expensive test */
2005 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
2006 n_iterations_completed_total);
2007 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
2008 MAX_INITIAL_OFFSET);
2009 fprintf (stderr, "out of memory handling %s tested\n",
2010 TEST_OOM_HANDLING ? "was" : "was not");
2014 _dbus_marshal_recursive_test (void)
2016 make_and_run_test_nodes ();
2024 * Implementations of each type node class
2029 #define MAX_MULTI_COUNT 5
2031 #define SAMPLE_INT16 1234
2032 #define SAMPLE_INT16_ALTERNATE 6785
2034 int16_from_seed (int seed)
2036 /* Generate an integer value that's predictable from seed. We could
2037 * just use seed itself, but that would only ever touch one byte of
2038 * the int so would miss some kinds of bug.
2042 v = 42; /* just to quiet compiler afaik */
2049 v = SAMPLE_INT16_ALTERNATE;
2055 v = _DBUS_INT16_MAX;
2063 v *= seed; /* wraps around eventually, which is fine */
2069 int16_write_value (TestTypeNode *node,
2071 DBusTypeWriter *writer,
2074 /* also used for uint16 */
2077 v = int16_from_seed (seed);
2079 return _dbus_type_writer_write_basic (writer,
2080 node->klass->typecode,
2085 int16_read_value (TestTypeNode *node,
2086 DBusTypeReader *reader,
2089 /* also used for uint16 */
2092 check_expected_type (reader, node->klass->typecode);
2094 _dbus_type_reader_read_basic (reader,
2095 (dbus_int16_t*) &v);
2097 _dbus_assert (v == int16_from_seed (seed));
2103 int16_set_value (TestTypeNode *node,
2104 DBusTypeReader *reader,
2105 DBusTypeReader *realign_root,
2108 /* also used for uint16 */
2111 v = int16_from_seed (seed);
2113 return _dbus_type_reader_set_basic (reader,
2119 int16_write_multi (TestTypeNode *node,
2121 DBusTypeWriter *writer,
2125 /* also used for uint16 */
2126 dbus_int16_t values[MAX_MULTI_COUNT];
2127 dbus_int16_t *v_ARRAY_INT16 = values;
2130 for (i = 0; i < count; ++i)
2131 values[i] = int16_from_seed (seed + i);
2133 return _dbus_type_writer_write_fixed_multi (writer,
2134 node->klass->typecode,
2135 &v_ARRAY_INT16, count);
2139 int16_read_multi (TestTypeNode *node,
2140 DBusTypeReader *reader,
2144 /* also used for uint16 */
2145 dbus_int16_t *values;
2149 check_expected_type (reader, node->klass->typecode);
2151 _dbus_type_reader_read_fixed_multi (reader,
2155 if (n_elements != count)
2156 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2157 _dbus_assert (n_elements == count);
2159 for (i = 0; i < count; i++)
2160 _dbus_assert (((int)_dbus_unpack_uint16 (reader->byte_order,
2161 (const unsigned char*)values + (i * 2))) ==
2162 int16_from_seed (seed + i));
2168 #define SAMPLE_INT32 12345678
2169 #define SAMPLE_INT32_ALTERNATE 53781429
2171 int32_from_seed (int seed)
2173 /* Generate an integer value that's predictable from seed. We could
2174 * just use seed itself, but that would only ever touch one byte of
2175 * the int so would miss some kinds of bug.
2179 v = 42; /* just to quiet compiler afaik */
2186 v = SAMPLE_INT32_ALTERNATE;
2200 v *= seed; /* wraps around eventually, which is fine */
2206 int32_write_value (TestTypeNode *node,
2208 DBusTypeWriter *writer,
2211 /* also used for uint32 */
2214 v = int32_from_seed (seed);
2216 return _dbus_type_writer_write_basic (writer,
2217 node->klass->typecode,
2222 int32_read_value (TestTypeNode *node,
2223 DBusTypeReader *reader,
2226 /* also used for uint32 */
2229 check_expected_type (reader, node->klass->typecode);
2231 _dbus_type_reader_read_basic (reader,
2232 (dbus_int32_t*) &v);
2234 _dbus_assert (v == int32_from_seed (seed));
2240 int32_set_value (TestTypeNode *node,
2241 DBusTypeReader *reader,
2242 DBusTypeReader *realign_root,
2245 /* also used for uint32 */
2248 v = int32_from_seed (seed);
2250 return _dbus_type_reader_set_basic (reader,
2256 int32_write_multi (TestTypeNode *node,
2258 DBusTypeWriter *writer,
2262 /* also used for uint32 */
2263 dbus_int32_t values[MAX_MULTI_COUNT];
2264 dbus_int32_t *v_ARRAY_INT32 = values;
2267 for (i = 0; i < count; ++i)
2268 values[i] = int32_from_seed (seed + i);
2270 return _dbus_type_writer_write_fixed_multi (writer,
2271 node->klass->typecode,
2272 &v_ARRAY_INT32, count);
2276 int32_read_multi (TestTypeNode *node,
2277 DBusTypeReader *reader,
2281 /* also used for uint32 */
2282 dbus_int32_t *values;
2286 check_expected_type (reader, node->klass->typecode);
2288 _dbus_type_reader_read_fixed_multi (reader,
2292 if (n_elements != count)
2293 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2294 _dbus_assert (n_elements == count);
2296 for (i = 0; i < count; i++)
2297 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2298 (const unsigned char*)values + (i * 4))) ==
2299 int32_from_seed (seed + i));
2304 #ifdef DBUS_HAVE_INT64
2306 int64_from_seed (int seed)
2311 v32 = int32_from_seed (seed);
2313 v = - (dbus_int32_t) ~ v32;
2314 v |= (((dbus_int64_t)v32) << 32);
2321 int64_write_value (TestTypeNode *node,
2323 DBusTypeWriter *writer,
2326 #ifdef DBUS_HAVE_INT64
2327 /* also used for uint64 */
2330 v = int64_from_seed (seed);
2332 return _dbus_type_writer_write_basic (writer,
2333 node->klass->typecode,
2341 int64_read_value (TestTypeNode *node,
2342 DBusTypeReader *reader,
2345 #ifdef DBUS_HAVE_INT64
2346 /* also used for uint64 */
2349 check_expected_type (reader, node->klass->typecode);
2351 _dbus_type_reader_read_basic (reader,
2352 (dbus_int64_t*) &v);
2354 _dbus_assert (v == int64_from_seed (seed));
2363 int64_set_value (TestTypeNode *node,
2364 DBusTypeReader *reader,
2365 DBusTypeReader *realign_root,
2368 #ifdef DBUS_HAVE_INT64
2369 /* also used for uint64 */
2372 v = int64_from_seed (seed);
2374 return _dbus_type_reader_set_basic (reader,
2382 #define MAX_SAMPLE_STRING_LEN 10
2384 string_from_seed (char *buf,
2391 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2393 /* vary the length slightly, though we also have multiple string
2394 * value types for this, varying it here tests the set_value code
2408 v = (unsigned char) ('A' + seed);
2413 if (v < 'A' || v > 'z')
2426 string_write_value (TestTypeNode *node,
2428 DBusTypeWriter *writer,
2431 char buf[MAX_SAMPLE_STRING_LEN];
2432 const char *v_string = buf;
2434 string_from_seed (buf, node->klass->subclass_detail,
2437 return _dbus_type_writer_write_basic (writer,
2438 node->klass->typecode,
2443 string_read_value (TestTypeNode *node,
2444 DBusTypeReader *reader,
2448 char buf[MAX_SAMPLE_STRING_LEN];
2450 check_expected_type (reader, node->klass->typecode);
2452 _dbus_type_reader_read_basic (reader,
2453 (const char **) &v);
2455 string_from_seed (buf, node->klass->subclass_detail,
2458 if (strcmp (buf, v) != 0)
2460 _dbus_warn ("read string '%s' expected '%s'\n",
2462 _dbus_assert_not_reached ("test failed");
2469 string_set_value (TestTypeNode *node,
2470 DBusTypeReader *reader,
2471 DBusTypeReader *realign_root,
2474 char buf[MAX_SAMPLE_STRING_LEN];
2475 const char *v_string = buf;
2477 string_from_seed (buf, node->klass->subclass_detail,
2480 #if RECURSIVE_MARSHAL_WRITE_TRACE
2483 _dbus_type_reader_read_basic (reader, &old);
2484 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2485 v_string, strlen (v_string), old, strlen (old));
2489 return _dbus_type_reader_set_basic (reader,
2494 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2497 bool_write_value (TestTypeNode *node,
2499 DBusTypeWriter *writer,
2504 v = BOOL_FROM_SEED (seed);
2506 return _dbus_type_writer_write_basic (writer,
2507 node->klass->typecode,
2512 bool_read_value (TestTypeNode *node,
2513 DBusTypeReader *reader,
2518 check_expected_type (reader, node->klass->typecode);
2520 _dbus_type_reader_read_basic (reader,
2521 (unsigned char*) &v);
2523 _dbus_assert (v == BOOL_FROM_SEED (seed));
2529 bool_set_value (TestTypeNode *node,
2530 DBusTypeReader *reader,
2531 DBusTypeReader *realign_root,
2536 v = BOOL_FROM_SEED (seed);
2538 return _dbus_type_reader_set_basic (reader,
2543 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2546 byte_write_value (TestTypeNode *node,
2548 DBusTypeWriter *writer,
2553 v = BYTE_FROM_SEED (seed);
2555 return _dbus_type_writer_write_basic (writer,
2556 node->klass->typecode,
2561 byte_read_value (TestTypeNode *node,
2562 DBusTypeReader *reader,
2567 check_expected_type (reader, node->klass->typecode);
2569 _dbus_type_reader_read_basic (reader,
2570 (unsigned char*) &v);
2572 _dbus_assert (v == BYTE_FROM_SEED (seed));
2579 byte_set_value (TestTypeNode *node,
2580 DBusTypeReader *reader,
2581 DBusTypeReader *realign_root,
2586 v = BYTE_FROM_SEED (seed);
2588 return _dbus_type_reader_set_basic (reader,
2594 double_from_seed (int seed)
2596 return SAMPLE_INT32 * (double) seed + 0.3;
2600 double_write_value (TestTypeNode *node,
2602 DBusTypeWriter *writer,
2607 v = double_from_seed (seed);
2609 return _dbus_type_writer_write_basic (writer,
2610 node->klass->typecode,
2615 double_read_value (TestTypeNode *node,
2616 DBusTypeReader *reader,
2622 check_expected_type (reader, node->klass->typecode);
2624 _dbus_type_reader_read_basic (reader,
2627 expected = double_from_seed (seed);
2629 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2631 #ifdef DBUS_HAVE_INT64
2632 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2634 *(dbus_uint64_t*)(char*)&expected,
2635 *(dbus_uint64_t*)(char*)&v);
2637 _dbus_assert_not_reached ("test failed");
2644 double_set_value (TestTypeNode *node,
2645 DBusTypeReader *reader,
2646 DBusTypeReader *realign_root,
2651 v = double_from_seed (seed);
2653 return _dbus_type_reader_set_basic (reader,
2658 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2660 object_path_from_seed (char *buf,
2668 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2670 v = (unsigned char) ('A' + seed);
2682 if (v < 'A' || v > 'z')
2698 object_path_write_value (TestTypeNode *node,
2700 DBusTypeWriter *writer,
2703 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2704 const char *v_string = buf;
2706 object_path_from_seed (buf, seed);
2708 return _dbus_type_writer_write_basic (writer,
2709 node->klass->typecode,
2714 object_path_read_value (TestTypeNode *node,
2715 DBusTypeReader *reader,
2719 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2721 check_expected_type (reader, node->klass->typecode);
2723 _dbus_type_reader_read_basic (reader,
2724 (const char **) &v);
2726 object_path_from_seed (buf, seed);
2728 if (strcmp (buf, v) != 0)
2730 _dbus_warn ("read object path '%s' expected '%s'\n",
2732 _dbus_assert_not_reached ("test failed");
2739 object_path_set_value (TestTypeNode *node,
2740 DBusTypeReader *reader,
2741 DBusTypeReader *realign_root,
2744 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2745 const char *v_string = buf;
2747 object_path_from_seed (buf, seed);
2749 return _dbus_type_reader_set_basic (reader,
2754 #define MAX_SAMPLE_SIGNATURE_LEN 10
2756 signature_from_seed (char *buf,
2761 /* try to avoid ascending, descending, or alternating length to help find bugs */
2762 const char *sample_signatures[] = {
2771 s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)];
2773 for (i = 0; s[i]; i++)
2781 signature_write_value (TestTypeNode *node,
2783 DBusTypeWriter *writer,
2786 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2787 const char *v_string = buf;
2789 signature_from_seed (buf, seed);
2791 return _dbus_type_writer_write_basic (writer,
2792 node->klass->typecode,
2797 signature_read_value (TestTypeNode *node,
2798 DBusTypeReader *reader,
2802 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2804 check_expected_type (reader, node->klass->typecode);
2806 _dbus_type_reader_read_basic (reader,
2807 (const char **) &v);
2809 signature_from_seed (buf, seed);
2811 if (strcmp (buf, v) != 0)
2813 _dbus_warn ("read signature value '%s' expected '%s'\n",
2815 _dbus_assert_not_reached ("test failed");
2823 signature_set_value (TestTypeNode *node,
2824 DBusTypeReader *reader,
2825 DBusTypeReader *realign_root,
2828 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2829 const char *v_string = buf;
2831 signature_from_seed (buf, seed);
2833 return _dbus_type_reader_set_basic (reader,
2839 struct_write_value (TestTypeNode *node,
2841 DBusTypeWriter *writer,
2844 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2845 DataBlockState saved;
2850 n_copies = node->klass->subclass_detail;
2852 _dbus_assert (container->children != NULL);
2854 data_block_save (block, &saved);
2856 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2862 while (i < n_copies)
2866 link = _dbus_list_get_first_link (&container->children);
2867 while (link != NULL)
2869 TestTypeNode *child = link->data;
2870 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2872 if (!node_write_value (child, block, &sub, seed + i))
2874 data_block_restore (block, &saved);
2884 if (!_dbus_type_writer_unrecurse (writer, &sub))
2886 data_block_restore (block, &saved);
2894 struct_read_or_set_value (TestTypeNode *node,
2895 DBusTypeReader *reader,
2896 DBusTypeReader *realign_root,
2899 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2904 n_copies = node->klass->subclass_detail;
2906 check_expected_type (reader, DBUS_TYPE_STRUCT);
2908 _dbus_type_reader_recurse (reader, &sub);
2911 while (i < n_copies)
2915 link = _dbus_list_get_first_link (&container->children);
2916 while (link != NULL)
2918 TestTypeNode *child = link->data;
2919 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2921 if (realign_root == NULL)
2923 if (!node_read_value (child, &sub, seed + i))
2928 if (!node_set_value (child, &sub, realign_root, seed + i))
2932 if (i == (n_copies - 1) && next == NULL)
2933 NEXT_EXPECTING_FALSE (&sub);
2935 NEXT_EXPECTING_TRUE (&sub);
2947 struct_read_value (TestTypeNode *node,
2948 DBusTypeReader *reader,
2951 return struct_read_or_set_value (node, reader, NULL, seed);
2955 struct_set_value (TestTypeNode *node,
2956 DBusTypeReader *reader,
2957 DBusTypeReader *realign_root,
2960 return struct_read_or_set_value (node, reader, realign_root, seed);
2964 struct_build_signature (TestTypeNode *node,
2967 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2972 n_copies = node->klass->subclass_detail;
2974 orig_len = _dbus_string_get_length (str);
2976 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2980 while (i < n_copies)
2984 link = _dbus_list_get_first_link (&container->children);
2985 while (link != NULL)
2987 TestTypeNode *child = link->data;
2988 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2990 if (!node_build_signature (child, str))
2999 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
3005 _dbus_string_set_length (str, orig_len);
3010 array_write_value (TestTypeNode *node,
3012 DBusTypeWriter *writer,
3015 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3016 DataBlockState saved;
3018 DBusString element_signature;
3022 TestTypeNode *child;
3024 n_copies = node->klass->subclass_detail;
3026 _dbus_assert (container->children != NULL);
3028 data_block_save (block, &saved);
3030 if (!_dbus_string_init (&element_signature))
3033 child = _dbus_list_get_first (&container->children);
3035 if (!node_build_signature (child,
3036 &element_signature))
3039 element_type = _dbus_first_type_in_signature (&element_signature, 0);
3041 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3042 &element_signature, 0,
3046 if (arrays_write_fixed_in_blocks &&
3047 _dbus_type_is_fixed (element_type) &&
3048 child->klass->write_multi)
3050 if (!node_write_multi (child, block, &sub, seed, n_copies))
3056 while (i < n_copies)
3060 link = _dbus_list_get_first_link (&container->children);
3061 while (link != NULL)
3063 TestTypeNode *child = link->data;
3064 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3066 if (!node_write_value (child, block, &sub, seed + i))
3076 if (!_dbus_type_writer_unrecurse (writer, &sub))
3079 _dbus_string_free (&element_signature);
3083 data_block_restore (block, &saved);
3084 _dbus_string_free (&element_signature);
3089 array_read_or_set_value (TestTypeNode *node,
3090 DBusTypeReader *reader,
3091 DBusTypeReader *realign_root,
3094 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3098 TestTypeNode *child;
3100 n_copies = node->klass->subclass_detail;
3102 check_expected_type (reader, DBUS_TYPE_ARRAY);
3104 child = _dbus_list_get_first (&container->children);
3108 _dbus_type_reader_recurse (reader, &sub);
3110 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
3111 _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
3112 child->klass->read_multi)
3114 if (!node_read_multi (child, &sub, seed, n_copies))
3120 while (i < n_copies)
3124 link = _dbus_list_get_first_link (&container->children);
3125 while (link != NULL)
3127 TestTypeNode *child = link->data;
3128 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3130 _dbus_assert (child->klass->typecode ==
3131 _dbus_type_reader_get_element_type (reader));
3133 if (realign_root == NULL)
3135 if (!node_read_value (child, &sub, seed + i))
3140 if (!node_set_value (child, &sub, realign_root, seed + i))
3144 if (i == (n_copies - 1) && next == NULL)
3145 NEXT_EXPECTING_FALSE (&sub);
3147 NEXT_EXPECTING_TRUE (&sub);
3161 array_read_value (TestTypeNode *node,
3162 DBusTypeReader *reader,
3165 return array_read_or_set_value (node, reader, NULL, seed);
3169 array_set_value (TestTypeNode *node,
3170 DBusTypeReader *reader,
3171 DBusTypeReader *realign_root,
3174 return array_read_or_set_value (node, reader, realign_root, seed);
3178 array_build_signature (TestTypeNode *node,
3181 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3184 orig_len = _dbus_string_get_length (str);
3186 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3189 if (!node_build_signature (_dbus_list_get_first (&container->children),
3196 _dbus_string_set_length (str, orig_len);
3200 /* 10 is random just to add another seed that we use in the suite */
3201 #define VARIANT_SEED 10
3204 variant_write_value (TestTypeNode *node,
3206 DBusTypeWriter *writer,
3209 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3210 DataBlockState saved;
3212 DBusString content_signature;
3213 TestTypeNode *child;
3215 _dbus_assert (container->children != NULL);
3216 _dbus_assert (_dbus_list_length_is_one (&container->children));
3218 child = _dbus_list_get_first (&container->children);
3220 data_block_save (block, &saved);
3222 if (!_dbus_string_init (&content_signature))
3225 if (!node_build_signature (child,
3226 &content_signature))
3229 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3230 &content_signature, 0,
3234 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3237 if (!_dbus_type_writer_unrecurse (writer, &sub))
3240 _dbus_string_free (&content_signature);
3244 data_block_restore (block, &saved);
3245 _dbus_string_free (&content_signature);
3250 variant_read_or_set_value (TestTypeNode *node,
3251 DBusTypeReader *reader,
3252 DBusTypeReader *realign_root,
3255 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3257 TestTypeNode *child;
3259 _dbus_assert (container->children != NULL);
3260 _dbus_assert (_dbus_list_length_is_one (&container->children));
3262 child = _dbus_list_get_first (&container->children);
3264 check_expected_type (reader, DBUS_TYPE_VARIANT);
3266 _dbus_type_reader_recurse (reader, &sub);
3268 if (realign_root == NULL)
3270 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3275 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3279 NEXT_EXPECTING_FALSE (&sub);
3285 variant_read_value (TestTypeNode *node,
3286 DBusTypeReader *reader,
3289 return variant_read_or_set_value (node, reader, NULL, seed);
3293 variant_set_value (TestTypeNode *node,
3294 DBusTypeReader *reader,
3295 DBusTypeReader *realign_root,
3298 return variant_read_or_set_value (node, reader, realign_root, seed);
3302 container_destroy (TestTypeNode *node)
3304 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3307 link = _dbus_list_get_first_link (&container->children);
3308 while (link != NULL)
3310 TestTypeNode *child = link->data;
3311 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3313 node_destroy (child);
3315 _dbus_list_free_link (link);
3321 #endif /* DBUS_BUILD_TESTS */