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
24 #include "dbus-marshal-recursive.h"
25 #include "dbus-marshal-basic.h"
26 #include "dbus-internals.h"
28 #ifdef DBUS_BUILD_TESTS
29 #include "dbus-test.h"
30 #include "dbus-list.h"
34 /* Whether to do the OOM stuff (only with other expensive tests) */
35 #define TEST_OOM_HANDLING 0
36 /* We do start offset 0 through 9, to get various alignment cases. Still this
37 * obviously makes the test suite run 10x as slow.
39 #define MAX_INITIAL_OFFSET 9
41 /* Largest iteration count to test copying, realignment,
42 * etc. with. i.e. we only test this stuff with some of the smaller
45 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
61 #define N_FENCE_BYTES 5
62 #define FENCE_BYTES_STR "abcde"
63 #define INITIAL_PADDING_BYTE '\0'
66 data_block_init (DataBlock *block,
70 if (!_dbus_string_init (&block->signature))
73 if (!_dbus_string_init (&block->body))
75 _dbus_string_free (&block->signature);
79 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
80 INITIAL_PADDING_BYTE) ||
81 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
82 INITIAL_PADDING_BYTE) ||
83 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
84 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
86 _dbus_string_free (&block->signature);
87 _dbus_string_free (&block->body);
91 block->byte_order = byte_order;
92 block->initial_offset = initial_offset;
98 data_block_save (DataBlock *block,
99 DataBlockState *state)
101 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
102 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
106 data_block_restore (DataBlock *block,
107 DataBlockState *state)
109 _dbus_string_delete (&block->signature,
110 state->saved_sig_len,
111 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
112 _dbus_string_delete (&block->body,
113 state->saved_body_len,
114 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
118 data_block_verify (DataBlock *block)
120 if (!_dbus_string_ends_with_c_str (&block->signature,
125 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
129 _dbus_verbose_bytes_of_string (&block->signature,
131 _dbus_string_get_length (&block->signature) - offset);
132 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
134 if (!_dbus_string_ends_with_c_str (&block->body,
139 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
143 _dbus_verbose_bytes_of_string (&block->body,
145 _dbus_string_get_length (&block->body) - offset);
146 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
149 _dbus_assert (_dbus_string_validate_nul (&block->signature,
150 0, block->initial_offset));
151 _dbus_assert (_dbus_string_validate_nul (&block->body,
152 0, block->initial_offset));
156 data_block_free (DataBlock *block)
158 data_block_verify (block);
160 _dbus_string_free (&block->signature);
161 _dbus_string_free (&block->body);
165 data_block_reset (DataBlock *block)
167 data_block_verify (block);
169 _dbus_string_delete (&block->signature,
170 block->initial_offset,
171 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
172 _dbus_string_delete (&block->body,
173 block->initial_offset,
174 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
176 data_block_verify (block);
180 data_block_init_reader_writer (DataBlock *block,
181 DBusTypeReader *reader,
182 DBusTypeWriter *writer)
185 _dbus_type_reader_init (reader,
188 block->initial_offset,
190 block->initial_offset);
193 _dbus_type_writer_init (writer,
196 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
198 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
202 real_check_expected_type (DBusTypeReader *reader,
204 const char *funcname,
209 t = _dbus_type_reader_get_current_type (reader);
213 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
214 _dbus_type_to_string (t),
215 _dbus_type_to_string (expected),
218 _dbus_assert_not_reached ("read wrong type");
222 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
224 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
226 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
227 _DBUS_FUNCTION_NAME, __LINE__); \
228 _dbus_assert_not_reached ("test failed"); \
232 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
234 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
235 _DBUS_FUNCTION_NAME, __LINE__); \
236 _dbus_assert_not_reached ("test failed"); \
238 check_expected_type (reader, DBUS_TYPE_INVALID); \
241 typedef struct TestTypeNode TestTypeNode;
242 typedef struct TestTypeNodeClass TestTypeNodeClass;
243 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
244 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
248 const TestTypeNodeClass *klass;
251 struct TestTypeNodeContainer
257 struct TestTypeNodeClass
263 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
265 dbus_bool_t (* construct) (TestTypeNode *node);
266 void (* destroy) (TestTypeNode *node);
268 dbus_bool_t (* write_value) (TestTypeNode *node,
270 DBusTypeWriter *writer,
272 dbus_bool_t (* read_value) (TestTypeNode *node,
273 DBusTypeReader *reader,
275 dbus_bool_t (* set_value) (TestTypeNode *node,
276 DBusTypeReader *reader,
277 DBusTypeReader *realign_root,
279 dbus_bool_t (* build_signature) (TestTypeNode *node,
281 dbus_bool_t (* write_multi) (TestTypeNode *node,
283 DBusTypeWriter *writer,
286 dbus_bool_t (* read_multi) (TestTypeNode *node,
287 DBusTypeReader *reader,
292 struct TestTypeNodeContainerClass
294 TestTypeNodeClass base;
297 /* FIXME this could be chilled out substantially by unifying
298 * the basic types into basic_write_value/basic_read_value
299 * and by merging read_value and set_value into one function
300 * taking a flag argument.
302 static dbus_bool_t int32_write_value (TestTypeNode *node,
304 DBusTypeWriter *writer,
306 static dbus_bool_t int32_read_value (TestTypeNode *node,
307 DBusTypeReader *reader,
309 static dbus_bool_t int32_set_value (TestTypeNode *node,
310 DBusTypeReader *reader,
311 DBusTypeReader *realign_root,
313 static dbus_bool_t int32_write_multi (TestTypeNode *node,
315 DBusTypeWriter *writer,
318 static dbus_bool_t int32_read_multi (TestTypeNode *node,
319 DBusTypeReader *reader,
322 static dbus_bool_t int64_write_value (TestTypeNode *node,
324 DBusTypeWriter *writer,
326 static dbus_bool_t int64_read_value (TestTypeNode *node,
327 DBusTypeReader *reader,
329 static dbus_bool_t int64_set_value (TestTypeNode *node,
330 DBusTypeReader *reader,
331 DBusTypeReader *realign_root,
333 static dbus_bool_t string_write_value (TestTypeNode *node,
335 DBusTypeWriter *writer,
337 static dbus_bool_t string_read_value (TestTypeNode *node,
338 DBusTypeReader *reader,
340 static dbus_bool_t string_set_value (TestTypeNode *node,
341 DBusTypeReader *reader,
342 DBusTypeReader *realign_root,
344 static dbus_bool_t bool_write_value (TestTypeNode *node,
346 DBusTypeWriter *writer,
348 static dbus_bool_t bool_read_value (TestTypeNode *node,
349 DBusTypeReader *reader,
351 static dbus_bool_t bool_set_value (TestTypeNode *node,
352 DBusTypeReader *reader,
353 DBusTypeReader *realign_root,
355 static dbus_bool_t byte_write_value (TestTypeNode *node,
357 DBusTypeWriter *writer,
359 static dbus_bool_t byte_read_value (TestTypeNode *node,
360 DBusTypeReader *reader,
362 static dbus_bool_t byte_set_value (TestTypeNode *node,
363 DBusTypeReader *reader,
364 DBusTypeReader *realign_root,
366 static dbus_bool_t double_write_value (TestTypeNode *node,
368 DBusTypeWriter *writer,
370 static dbus_bool_t double_read_value (TestTypeNode *node,
371 DBusTypeReader *reader,
373 static dbus_bool_t double_set_value (TestTypeNode *node,
374 DBusTypeReader *reader,
375 DBusTypeReader *realign_root,
377 static dbus_bool_t object_path_write_value (TestTypeNode *node,
379 DBusTypeWriter *writer,
381 static dbus_bool_t object_path_read_value (TestTypeNode *node,
382 DBusTypeReader *reader,
384 static dbus_bool_t object_path_set_value (TestTypeNode *node,
385 DBusTypeReader *reader,
386 DBusTypeReader *realign_root,
388 static dbus_bool_t signature_write_value (TestTypeNode *node,
390 DBusTypeWriter *writer,
392 static dbus_bool_t signature_read_value (TestTypeNode *node,
393 DBusTypeReader *reader,
395 static dbus_bool_t signature_set_value (TestTypeNode *node,
396 DBusTypeReader *reader,
397 DBusTypeReader *realign_root,
399 static dbus_bool_t struct_write_value (TestTypeNode *node,
401 DBusTypeWriter *writer,
403 static dbus_bool_t struct_read_value (TestTypeNode *node,
404 DBusTypeReader *reader,
406 static dbus_bool_t struct_set_value (TestTypeNode *node,
407 DBusTypeReader *reader,
408 DBusTypeReader *realign_root,
410 static dbus_bool_t struct_build_signature (TestTypeNode *node,
412 static dbus_bool_t array_write_value (TestTypeNode *node,
414 DBusTypeWriter *writer,
416 static dbus_bool_t array_read_value (TestTypeNode *node,
417 DBusTypeReader *reader,
419 static dbus_bool_t array_set_value (TestTypeNode *node,
420 DBusTypeReader *reader,
421 DBusTypeReader *realign_root,
423 static dbus_bool_t array_build_signature (TestTypeNode *node,
425 static dbus_bool_t variant_write_value (TestTypeNode *node,
427 DBusTypeWriter *writer,
429 static dbus_bool_t variant_read_value (TestTypeNode *node,
430 DBusTypeReader *reader,
432 static dbus_bool_t variant_set_value (TestTypeNode *node,
433 DBusTypeReader *reader,
434 DBusTypeReader *realign_root,
436 static void container_destroy (TestTypeNode *node);
439 static const TestTypeNodeClass int32_class = {
441 sizeof (TestTypeNode),
453 static const TestTypeNodeClass uint32_class = {
455 sizeof (TestTypeNode),
459 int32_write_value, /* recycle from int32 */
460 int32_read_value, /* recycle from int32 */
461 int32_set_value, /* recycle from int32 */
463 int32_write_multi, /* recycle from int32 */
464 int32_read_multi /* recycle from int32 */
467 static const TestTypeNodeClass int64_class = {
469 sizeof (TestTypeNode),
481 static const TestTypeNodeClass uint64_class = {
483 sizeof (TestTypeNode),
487 int64_write_value, /* recycle from int64 */
488 int64_read_value, /* recycle from int64 */
489 int64_set_value, /* recycle from int64 */
495 static const TestTypeNodeClass string_0_class = {
497 sizeof (TestTypeNode),
498 0, /* string length */
509 static const TestTypeNodeClass string_1_class = {
511 sizeof (TestTypeNode),
512 1, /* string length */
523 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
524 static const TestTypeNodeClass string_3_class = {
526 sizeof (TestTypeNode),
527 3, /* string length */
538 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
539 static const TestTypeNodeClass string_8_class = {
541 sizeof (TestTypeNode),
542 8, /* string length */
553 static const TestTypeNodeClass bool_class = {
555 sizeof (TestTypeNode),
567 static const TestTypeNodeClass byte_class = {
569 sizeof (TestTypeNode),
581 static const TestTypeNodeClass double_class = {
583 sizeof (TestTypeNode),
595 static const TestTypeNodeClass object_path_class = {
596 DBUS_TYPE_OBJECT_PATH,
597 sizeof (TestTypeNode),
601 object_path_write_value,
602 object_path_read_value,
603 object_path_set_value,
609 static const TestTypeNodeClass signature_class = {
611 sizeof (TestTypeNode),
615 signature_write_value,
616 signature_read_value,
623 static const TestTypeNodeClass struct_1_class = {
625 sizeof (TestTypeNodeContainer),
626 1, /* number of times children appear as fields */
632 struct_build_signature,
637 static const TestTypeNodeClass struct_2_class = {
639 sizeof (TestTypeNodeContainer),
640 2, /* number of times children appear as fields */
646 struct_build_signature,
651 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
653 static const TestTypeNodeClass array_0_class = {
655 sizeof (TestTypeNodeContainer),
656 0, /* number of array elements */
662 array_build_signature,
667 static const TestTypeNodeClass array_1_class = {
669 sizeof (TestTypeNodeContainer),
670 1, /* number of array elements */
676 array_build_signature,
681 static const TestTypeNodeClass array_2_class = {
683 sizeof (TestTypeNodeContainer),
684 2, /* number of array elements */
690 array_build_signature,
695 static const TestTypeNodeClass array_9_class = {
697 sizeof (TestTypeNodeContainer),
698 9, /* number of array elements */
704 array_build_signature,
709 static const TestTypeNodeClass variant_class = {
711 sizeof (TestTypeNodeContainer),
723 static const TestTypeNodeClass* const
739 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
741 static const TestTypeNodeClass* const
742 container_nodes[] = {
749 /* array_9_class is omitted on purpose, it's too slow;
750 * we only use it in one hardcoded test below
753 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
756 node_new (const TestTypeNodeClass *klass)
760 node = dbus_malloc0 (klass->instance_size);
766 if (klass->construct)
768 if (!(* klass->construct) (node))
779 node_destroy (TestTypeNode *node)
781 if (node->klass->destroy)
782 (* node->klass->destroy) (node);
787 node_write_value (TestTypeNode *node,
789 DBusTypeWriter *writer,
794 retval = (* node->klass->write_value) (node, block, writer, seed);
797 /* Handy to see where things break, but too expensive to do all the time */
798 data_block_verify (block);
805 node_read_value (TestTypeNode *node,
806 DBusTypeReader *reader,
810 DBusTypeReader restored;
812 _dbus_type_reader_save_mark (reader, &mark);
814 if (!(* node->klass->read_value) (node, reader, seed))
817 _dbus_type_reader_init_from_mark (&restored,
823 if (!(* node->klass->read_value) (node, &restored, seed))
829 /* Warning: if this one fails due to OOM, it has side effects (can
830 * modify only some of the sub-values). OK in a test suite, but we
831 * never do this in real code.
834 node_set_value (TestTypeNode *node,
835 DBusTypeReader *reader,
836 DBusTypeReader *realign_root,
839 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
846 node_build_signature (TestTypeNode *node,
849 if (node->klass->build_signature)
850 return (* node->klass->build_signature) (node, str);
852 return _dbus_string_append_byte (str, node->klass->typecode);
856 node_append_child (TestTypeNode *node,
859 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
861 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
863 if (!_dbus_list_append (&container->children, child))
864 _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 */
870 node_write_multi (TestTypeNode *node,
872 DBusTypeWriter *writer,
878 _dbus_assert (node->klass->write_multi != NULL);
879 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
882 /* Handy to see where things break, but too expensive to do all the time */
883 data_block_verify (block);
890 node_read_multi (TestTypeNode *node,
891 DBusTypeReader *reader,
895 _dbus_assert (node->klass->read_multi != NULL);
897 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
903 static int n_iterations_completed_total = 0;
904 static int n_iterations_completed_this_test = 0;
905 static int n_iterations_expected_this_test = 0;
909 const DBusString *signature;
912 TestTypeNode **nodes;
917 run_test_copy (NodeIterationData *nid)
922 DBusTypeReader reader;
923 DBusTypeWriter writer;
925 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
931 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
934 data_block_init_reader_writer (src, &reader, NULL);
935 data_block_init_reader_writer (&dest, NULL, &writer);
937 /* DBusTypeWriter assumes it's writing into an existing signature,
938 * so doesn't add nul on its own. We have to do that.
940 if (!_dbus_string_insert_byte (&dest.signature,
941 dest.initial_offset, '\0'))
944 if (!_dbus_type_writer_write_reader (&writer, &reader))
947 /* Data blocks should now be identical */
948 if (!_dbus_string_equal (&src->signature, &dest.signature))
950 _dbus_verbose ("SOURCE\n");
951 _dbus_verbose_bytes_of_string (&src->signature, 0,
952 _dbus_string_get_length (&src->signature));
953 _dbus_verbose ("DEST\n");
954 _dbus_verbose_bytes_of_string (&dest.signature, 0,
955 _dbus_string_get_length (&dest.signature));
956 _dbus_assert_not_reached ("signatures did not match");
959 if (!_dbus_string_equal (&src->body, &dest.body))
961 _dbus_verbose ("SOURCE\n");
962 _dbus_verbose_bytes_of_string (&src->body, 0,
963 _dbus_string_get_length (&src->body));
964 _dbus_verbose ("DEST\n");
965 _dbus_verbose_bytes_of_string (&dest.body, 0,
966 _dbus_string_get_length (&dest.body));
967 _dbus_assert_not_reached ("bodies did not match");
974 data_block_free (&dest);
980 run_test_values_only_write (NodeIterationData *nid)
982 DBusTypeReader reader;
983 DBusTypeWriter writer;
988 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
992 data_block_reset (nid->block);
994 sig_len = _dbus_string_get_length (nid->signature);
996 _dbus_type_writer_init_values_only (&writer,
997 nid->block->byte_order,
1000 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1001 _dbus_type_reader_init (&reader,
1002 nid->block->byte_order,
1005 nid->block->initial_offset);
1008 while (i < nid->n_nodes)
1010 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1016 /* if we wrote any typecodes then this would fail */
1017 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1019 /* But be sure we wrote out the values correctly */
1021 while (i < nid->n_nodes)
1023 if (!node_read_value (nid->nodes[i], &reader, i))
1026 if (i + 1 == nid->n_nodes)
1027 NEXT_EXPECTING_FALSE (&reader);
1029 NEXT_EXPECTING_TRUE (&reader);
1037 data_block_reset (nid->block);
1041 /* offset the seed for setting, so we set different numbers than
1042 * we originally wrote. Don't offset by a huge number since in
1043 * some cases it's value = possibilities[seed % n_possibilities]
1044 * and we don't want to wrap around. bool_from_seed
1045 * is just seed % 2 even.
1049 run_test_set_values (NodeIterationData *nid)
1051 DBusTypeReader reader;
1052 DBusTypeReader realign_root;
1056 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1060 data_block_init_reader_writer (nid->block,
1063 realign_root = reader;
1066 while (i < nid->n_nodes)
1068 if (!node_set_value (nid->nodes[i],
1069 &reader, &realign_root,
1073 if (i + 1 == nid->n_nodes)
1074 NEXT_EXPECTING_FALSE (&reader);
1076 NEXT_EXPECTING_TRUE (&reader);
1081 /* Check that the new values were set */
1083 reader = realign_root;
1086 while (i < nid->n_nodes)
1088 if (!node_read_value (nid->nodes[i], &reader,
1092 if (i + 1 == nid->n_nodes)
1093 NEXT_EXPECTING_FALSE (&reader);
1095 NEXT_EXPECTING_TRUE (&reader);
1107 run_test_delete_values (NodeIterationData *nid)
1109 DBusTypeReader reader;
1113 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1117 data_block_init_reader_writer (nid->block,
1120 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1122 /* Right now, deleting only works on array elements. We delete
1123 * all array elements, and then verify that there aren't any
1126 if (t == DBUS_TYPE_ARRAY)
1128 DBusTypeReader array;
1132 _dbus_type_reader_recurse (&reader, &array);
1134 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1137 _dbus_type_reader_next (&array);
1140 /* reset to start of array */
1141 _dbus_type_reader_recurse (&reader, &array);
1142 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1143 reader.value_pos, array.value_pos, array.u.array.start_pos);
1144 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1146 /* We don't want to always delete from the same part of the array. */
1147 static int cycle = 0;
1150 _dbus_assert (n_elements > 0);
1153 if (elem == 3 || elem >= n_elements) /* end of array */
1154 elem = n_elements - 1;
1156 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1157 elem, n_elements, _dbus_type_to_string (elem_type),
1158 cycle, reader.value_pos, array.value_pos);
1161 if (!_dbus_type_reader_next (&array))
1162 _dbus_assert_not_reached ("should have had another element\n");
1166 if (!_dbus_type_reader_delete (&array, &reader))
1172 _dbus_type_reader_recurse (&reader, &array);
1180 _dbus_type_reader_next (&reader);
1183 /* Check that there are no array elements left */
1184 data_block_init_reader_writer (nid->block,
1187 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1189 _dbus_type_reader_next (&reader);
1199 run_test_nodes_iteration (void *data)
1201 NodeIterationData *nid = data;
1202 DBusTypeReader reader;
1203 DBusTypeWriter writer;
1208 * 1. write the value
1209 * 2. strcmp-compare with the signature we built
1211 * 4. type-iterate the signature and the value and see if they are the same type-wise
1215 data_block_init_reader_writer (nid->block,
1218 /* DBusTypeWriter assumes it's writing into an existing signature,
1219 * so doesn't add nul on its own. We have to do that.
1221 if (!_dbus_string_insert_byte (&nid->block->signature,
1222 nid->type_offset, '\0'))
1226 while (i < nid->n_nodes)
1228 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1234 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1235 &nid->block->signature, nid->type_offset))
1237 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1238 _dbus_string_get_const_data (nid->signature),
1239 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1241 _dbus_assert_not_reached ("wrong signature");
1245 while (i < nid->n_nodes)
1247 if (!node_read_value (nid->nodes[i], &reader, i))
1250 if (i + 1 == nid->n_nodes)
1251 NEXT_EXPECTING_FALSE (&reader);
1253 NEXT_EXPECTING_TRUE (&reader);
1258 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1260 /* this set values test uses code from copy and
1261 * values_only_write so would ideally be last so you get a
1262 * simpler test case for problems with copying or values_only
1263 * writing; but it also needs an already-written DataBlock so it
1264 * has to go first. Comment it out if it breaks, and see if the
1265 * later tests also break - debug them first if so.
1267 if (!run_test_set_values (nid))
1270 if (!run_test_delete_values (nid))
1273 if (!run_test_copy (nid))
1276 if (!run_test_values_only_write (nid))
1280 /* FIXME type-iterate both signature and value and compare the resulting
1281 * tree to the node tree perhaps
1288 data_block_reset (nid->block);
1294 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1296 const DBusString *signature,
1301 NodeIterationData nid;
1303 if (!data_block_init (&block, byte_order, initial_offset))
1304 _dbus_assert_not_reached ("no memory");
1306 nid.signature = signature;
1308 nid.type_offset = initial_offset;
1310 nid.n_nodes = n_nodes;
1312 if (TEST_OOM_HANDLING &&
1313 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1315 _dbus_test_oom_handling ("running test node",
1316 run_test_nodes_iteration,
1321 if (!run_test_nodes_iteration (&nid))
1322 _dbus_assert_not_reached ("no memory");
1325 data_block_free (&block);
1329 run_test_nodes (TestTypeNode **nodes,
1333 DBusString signature;
1335 if (!_dbus_string_init (&signature))
1336 _dbus_assert_not_reached ("no memory");
1341 if (! node_build_signature (nodes[i], &signature))
1342 _dbus_assert_not_reached ("no memory");
1347 _dbus_verbose (">>> test nodes with signature '%s'\n",
1348 _dbus_string_get_const_data (&signature));
1351 while (i <= MAX_INITIAL_OFFSET)
1353 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1354 DBUS_LITTLE_ENDIAN, i);
1355 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1356 DBUS_BIG_ENDIAN, i);
1361 n_iterations_completed_this_test += 1;
1362 n_iterations_completed_total += 1;
1364 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1366 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1367 n_iterations_completed_this_test,
1368 n_iterations_completed_total);
1370 /* this happens to turn out well with mod == 1 */
1371 else if ((n_iterations_completed_this_test %
1372 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1374 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1377 _dbus_string_free (&signature);
1380 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1382 static TestTypeNode*
1383 value_generator (int *ip)
1386 const TestTypeNodeClass *child_klass;
1387 const TestTypeNodeClass *container_klass;
1388 TestTypeNode *child;
1391 _dbus_assert (i <= N_VALUES);
1397 else if (i < N_BASICS)
1399 node = node_new (basic_nodes[i]);
1403 /* imagine an array:
1404 * container 0 of basic 0
1405 * container 0 of basic 1
1406 * container 0 of basic 2
1407 * container 1 of basic 0
1408 * container 1 of basic 1
1409 * container 1 of basic 2
1413 container_klass = container_nodes[i / N_BASICS];
1414 child_klass = basic_nodes[i % N_BASICS];
1416 node = node_new (container_klass);
1417 child = node_new (child_klass);
1419 node_append_child (node, child);
1422 *ip += 1; /* increment the generator */
1428 build_body (TestTypeNode **nodes,
1431 DBusString *signature,
1436 DBusTypeReader reader;
1437 DBusTypeWriter writer;
1442 if (! node_build_signature (nodes[i], signature))
1443 _dbus_assert_not_reached ("no memory");
1448 if (!data_block_init (&block, byte_order, 0))
1449 _dbus_assert_not_reached ("no memory");
1451 data_block_init_reader_writer (&block,
1454 /* DBusTypeWriter assumes it's writing into an existing signature,
1455 * so doesn't add nul on its own. We have to do that.
1457 if (!_dbus_string_insert_byte (&block.signature,
1459 _dbus_assert_not_reached ("no memory");
1464 if (!node_write_value (nodes[i], &block, &writer, i))
1465 _dbus_assert_not_reached ("no memory");
1470 if (!_dbus_string_copy_len (&block.body, 0,
1471 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1473 _dbus_assert_not_reached ("oom");
1475 data_block_free (&block);
1479 dbus_internal_do_not_use_generate_bodies (int sequence,
1481 DBusString *signature,
1484 TestTypeNode *nodes[1];
1488 nodes[0] = value_generator (&sequence);
1490 if (nodes[0] == NULL)
1495 build_body (nodes, n_nodes, byte_order, signature, body);
1501 node_destroy (nodes[i]);
1509 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1513 TestTypeNode *container;
1514 TestTypeNode *child;
1517 root = node_new (container_klass);
1519 for (i = 1; i < n_nested; i++)
1521 child = node_new (container_klass);
1522 node_append_child (container, child);
1526 /* container should now be the most-nested container */
1529 while ((child = value_generator (&i)))
1531 node_append_child (container, child);
1533 run_test_nodes (&root, 1);
1535 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1536 node_destroy (child);
1539 node_destroy (root);
1543 start_next_test (const char *format,
1546 n_iterations_completed_this_test = 0;
1547 n_iterations_expected_this_test = expected;
1549 fprintf (stderr, ">>> >>> ");
1550 fprintf (stderr, format,
1551 n_iterations_expected_this_test);
1555 make_and_run_test_nodes (void)
1559 /* We try to do this in order of "complicatedness" so that test
1560 * failures tend to show up in the simplest test case that
1561 * demonstrates the failure. There are also some tests that run
1562 * more than once for this reason, first while going through simple
1563 * cases, second while going through a broader range of complex
1566 /* Each basic node. The basic nodes should include:
1568 * - each fixed-size type (in such a way that it has different values each time,
1569 * so we can tell if we mix two of them up)
1570 * - strings of various lengths
1574 /* Each container node. The container nodes should include:
1576 * struct with 1 and 2 copies of the contained item
1577 * array with 0, 1, 2 copies of the contained item
1580 /* Let a "value" be a basic node, or a container containing a single basic node.
1581 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1582 * When iterating through all values to make combinations, do the basic types
1583 * first and the containers second.
1585 /* Each item is shown with its number of iterations to complete so
1586 * we can keep a handle on this unit test
1589 /* FIXME test just an empty body, no types at all */
1591 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1595 while ((node = value_generator (&i)))
1597 run_test_nodes (&node, 1);
1599 node_destroy (node);
1603 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1604 arrays_write_fixed_in_blocks = TRUE;
1608 while ((node = value_generator (&i)))
1610 run_test_nodes (&node, 1);
1612 node_destroy (node);
1615 arrays_write_fixed_in_blocks = FALSE;
1617 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1619 TestTypeNode *nodes[N_VALUES];
1622 while ((nodes[i] = value_generator (&i)))
1625 run_test_nodes (nodes, N_VALUES);
1627 for (i = 0; i < N_VALUES; i++)
1628 node_destroy (nodes[i]);
1631 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1632 N_VALUES * N_VALUES);
1634 TestTypeNode *nodes[2];
1637 while ((nodes[0] = value_generator (&i)))
1640 while ((nodes[1] = value_generator (&j)))
1642 run_test_nodes (nodes, 2);
1644 node_destroy (nodes[1]);
1647 node_destroy (nodes[0]);
1651 start_next_test ("Each container containing each value %d iterations\n",
1652 N_CONTAINERS * N_VALUES);
1653 for (i = 0; i < N_CONTAINERS; i++)
1655 const TestTypeNodeClass *container_klass = container_nodes[i];
1657 make_and_run_values_inside_container (container_klass, 1);
1660 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1661 N_CONTAINERS * N_VALUES);
1662 arrays_write_fixed_in_blocks = TRUE;
1663 for (i = 0; i < N_CONTAINERS; i++)
1665 const TestTypeNodeClass *container_klass = container_nodes[i];
1667 make_and_run_values_inside_container (container_klass, 1);
1669 arrays_write_fixed_in_blocks = FALSE;
1671 start_next_test ("Each container of same container of each value %d iterations\n",
1672 N_CONTAINERS * N_VALUES);
1673 for (i = 0; i < N_CONTAINERS; i++)
1675 const TestTypeNodeClass *container_klass = container_nodes[i];
1677 make_and_run_values_inside_container (container_klass, 2);
1680 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1681 N_CONTAINERS * N_VALUES);
1682 for (i = 0; i < N_CONTAINERS; i++)
1684 const TestTypeNodeClass *container_klass = container_nodes[i];
1686 make_and_run_values_inside_container (container_klass, 3);
1689 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1690 N_VALUES * N_VALUES);
1692 TestTypeNode *val1, *val2;
1695 node = node_new (&struct_1_class);
1698 while ((val1 = value_generator (&i)))
1701 while ((val2 = value_generator (&j)))
1703 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1705 node_append_child (node, val1);
1706 node_append_child (node, val2);
1708 run_test_nodes (&node, 1);
1710 _dbus_list_clear (&container->children);
1711 node_destroy (val2);
1713 node_destroy (val1);
1715 node_destroy (node);
1718 start_next_test ("All values in one big struct %d iteration\n",
1722 TestTypeNode *child;
1724 node = node_new (&struct_1_class);
1727 while ((child = value_generator (&i)))
1728 node_append_child (node, child);
1730 run_test_nodes (&node, 1);
1732 node_destroy (node);
1735 start_next_test ("Each value in a large array %d iterations\n",
1741 node = node_new (&array_9_class);
1744 while ((val = value_generator (&i)))
1746 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1748 node_append_child (node, val);
1750 run_test_nodes (&node, 1);
1752 _dbus_list_clear (&container->children);
1756 node_destroy (node);
1759 start_next_test ("Each container of each container of each value %d iterations\n",
1760 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1761 for (i = 0; i < N_CONTAINERS; i++)
1763 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1764 TestTypeNode *outer_container = node_new (outer_container_klass);
1766 for (j = 0; j < N_CONTAINERS; j++)
1768 TestTypeNode *child;
1769 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1770 TestTypeNode *inner_container = node_new (inner_container_klass);
1772 node_append_child (outer_container, inner_container);
1775 while ((child = value_generator (&m)))
1777 node_append_child (inner_container, child);
1779 run_test_nodes (&outer_container, 1);
1781 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1782 node_destroy (child);
1784 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1785 node_destroy (inner_container);
1787 node_destroy (outer_container);
1790 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1791 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1792 for (i = 0; i < N_CONTAINERS; i++)
1794 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1795 TestTypeNode *outer_container = node_new (outer_container_klass);
1797 for (j = 0; j < N_CONTAINERS; j++)
1799 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1800 TestTypeNode *inner_container = node_new (inner_container_klass);
1802 node_append_child (outer_container, inner_container);
1804 for (k = 0; k < N_CONTAINERS; k++)
1806 TestTypeNode *child;
1807 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1808 TestTypeNode *center_container = node_new (center_container_klass);
1810 node_append_child (inner_container, center_container);
1813 while ((child = value_generator (&m)))
1815 node_append_child (center_container, child);
1817 run_test_nodes (&outer_container, 1);
1819 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1820 node_destroy (child);
1822 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1823 node_destroy (center_container);
1825 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1826 node_destroy (inner_container);
1828 node_destroy (outer_container);
1832 /* This one takes a really long time, so comment it out for now */
1833 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
1834 N_VALUES * N_VALUES * N_VALUES);
1836 TestTypeNode *nodes[3];
1839 while ((nodes[0] = value_generator (&i)))
1842 while ((nodes[1] = value_generator (&j)))
1845 while ((nodes[2] = value_generator (&k)))
1847 run_test_nodes (nodes, 3);
1849 node_destroy (nodes[2]);
1851 node_destroy (nodes[1]);
1853 node_destroy (nodes[0]);
1856 #endif /* #if 0 expensive test */
1858 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
1859 n_iterations_completed_total);
1860 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
1861 MAX_INITIAL_OFFSET);
1862 fprintf (stderr, "out of memory handling %s tested\n",
1863 TEST_OOM_HANDLING ? "was" : "was not");
1867 _dbus_marshal_recursive_test (void)
1869 make_and_run_test_nodes ();
1877 * Implementations of each type node class
1882 #define MAX_MULTI_COUNT 5
1885 #define SAMPLE_INT32 12345678
1886 #define SAMPLE_INT32_ALTERNATE 53781429
1888 int32_from_seed (int seed)
1890 /* Generate an integer value that's predictable from seed. We could
1891 * just use seed itself, but that would only ever touch one byte of
1892 * the int so would miss some kinds of bug.
1896 v = 42; /* just to quiet compiler afaik */
1903 v = SAMPLE_INT32_ALTERNATE;
1917 v *= seed; /* wraps around eventually, which is fine */
1923 int32_write_value (TestTypeNode *node,
1925 DBusTypeWriter *writer,
1928 /* also used for uint32 */
1931 v = int32_from_seed (seed);
1933 return _dbus_type_writer_write_basic (writer,
1934 node->klass->typecode,
1939 int32_read_value (TestTypeNode *node,
1940 DBusTypeReader *reader,
1943 /* also used for uint32 */
1946 check_expected_type (reader, node->klass->typecode);
1948 _dbus_type_reader_read_basic (reader,
1949 (dbus_int32_t*) &v);
1951 _dbus_assert (v == int32_from_seed (seed));
1957 int32_set_value (TestTypeNode *node,
1958 DBusTypeReader *reader,
1959 DBusTypeReader *realign_root,
1962 /* also used for uint32 */
1965 v = int32_from_seed (seed);
1967 return _dbus_type_reader_set_basic (reader,
1973 int32_write_multi (TestTypeNode *node,
1975 DBusTypeWriter *writer,
1979 /* also used for uint32 */
1980 dbus_int32_t values[MAX_MULTI_COUNT];
1981 dbus_int32_t *v_ARRAY_INT32 = values;
1984 for (i = 0; i < count; ++i)
1985 values[i] = int32_from_seed (seed + i);
1987 return _dbus_type_writer_write_fixed_multi (writer,
1988 node->klass->typecode,
1989 &v_ARRAY_INT32, count);
1993 int32_read_multi (TestTypeNode *node,
1994 DBusTypeReader *reader,
1998 /* also used for uint32 */
1999 dbus_int32_t *values;
2003 check_expected_type (reader, node->klass->typecode);
2005 _dbus_type_reader_read_fixed_multi (reader,
2009 if (n_elements != count)
2010 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2011 _dbus_assert (n_elements == count);
2013 for (i = 0; i < count; i++)
2014 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2015 (const unsigned char*)values + (i * 4))) ==
2016 int32_from_seed (seed + i));
2021 #ifdef DBUS_HAVE_INT64
2023 int64_from_seed (int seed)
2028 v32 = int32_from_seed (seed);
2030 v = - (dbus_int32_t) ~ v32;
2031 v |= (((dbus_int64_t)v32) << 32);
2038 int64_write_value (TestTypeNode *node,
2040 DBusTypeWriter *writer,
2043 #ifdef DBUS_HAVE_INT64
2044 /* also used for uint64 */
2047 v = int64_from_seed (seed);
2049 return _dbus_type_writer_write_basic (writer,
2050 node->klass->typecode,
2058 int64_read_value (TestTypeNode *node,
2059 DBusTypeReader *reader,
2062 #ifdef DBUS_HAVE_INT64
2063 /* also used for uint64 */
2066 check_expected_type (reader, node->klass->typecode);
2068 _dbus_type_reader_read_basic (reader,
2069 (dbus_int64_t*) &v);
2071 _dbus_assert (v == int64_from_seed (seed));
2080 int64_set_value (TestTypeNode *node,
2081 DBusTypeReader *reader,
2082 DBusTypeReader *realign_root,
2085 #ifdef DBUS_HAVE_INT64
2086 /* also used for uint64 */
2089 v = int64_from_seed (seed);
2091 return _dbus_type_reader_set_basic (reader,
2099 #define MAX_SAMPLE_STRING_LEN 10
2101 string_from_seed (char *buf,
2108 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2110 /* vary the length slightly, though we also have multiple string
2111 * value types for this, varying it here tests the set_value code
2125 v = (unsigned char) ('A' + seed);
2130 if (v < 'A' || v > 'z')
2143 string_write_value (TestTypeNode *node,
2145 DBusTypeWriter *writer,
2148 char buf[MAX_SAMPLE_STRING_LEN];
2149 const char *v_string = buf;
2151 string_from_seed (buf, node->klass->subclass_detail,
2154 return _dbus_type_writer_write_basic (writer,
2155 node->klass->typecode,
2160 string_read_value (TestTypeNode *node,
2161 DBusTypeReader *reader,
2165 char buf[MAX_SAMPLE_STRING_LEN];
2167 check_expected_type (reader, node->klass->typecode);
2169 _dbus_type_reader_read_basic (reader,
2170 (const char **) &v);
2172 string_from_seed (buf, node->klass->subclass_detail,
2175 if (strcmp (buf, v) != 0)
2177 _dbus_warn ("read string '%s' expected '%s'\n",
2179 _dbus_assert_not_reached ("test failed");
2186 string_set_value (TestTypeNode *node,
2187 DBusTypeReader *reader,
2188 DBusTypeReader *realign_root,
2191 char buf[MAX_SAMPLE_STRING_LEN];
2192 const char *v_string = buf;
2194 string_from_seed (buf, node->klass->subclass_detail,
2197 #if RECURSIVE_MARSHAL_WRITE_TRACE
2200 _dbus_type_reader_read_basic (reader, &old);
2201 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2202 v_string, strlen (v_string), old, strlen (old));
2206 return _dbus_type_reader_set_basic (reader,
2211 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2214 bool_write_value (TestTypeNode *node,
2216 DBusTypeWriter *writer,
2221 v = BOOL_FROM_SEED (seed);
2223 return _dbus_type_writer_write_basic (writer,
2224 node->klass->typecode,
2229 bool_read_value (TestTypeNode *node,
2230 DBusTypeReader *reader,
2235 check_expected_type (reader, node->klass->typecode);
2237 _dbus_type_reader_read_basic (reader,
2238 (unsigned char*) &v);
2240 _dbus_assert (v == BOOL_FROM_SEED (seed));
2246 bool_set_value (TestTypeNode *node,
2247 DBusTypeReader *reader,
2248 DBusTypeReader *realign_root,
2253 v = BOOL_FROM_SEED (seed);
2255 return _dbus_type_reader_set_basic (reader,
2260 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2263 byte_write_value (TestTypeNode *node,
2265 DBusTypeWriter *writer,
2270 v = BYTE_FROM_SEED (seed);
2272 return _dbus_type_writer_write_basic (writer,
2273 node->klass->typecode,
2278 byte_read_value (TestTypeNode *node,
2279 DBusTypeReader *reader,
2284 check_expected_type (reader, node->klass->typecode);
2286 _dbus_type_reader_read_basic (reader,
2287 (unsigned char*) &v);
2289 _dbus_assert (v == BYTE_FROM_SEED (seed));
2296 byte_set_value (TestTypeNode *node,
2297 DBusTypeReader *reader,
2298 DBusTypeReader *realign_root,
2303 v = BYTE_FROM_SEED (seed);
2305 return _dbus_type_reader_set_basic (reader,
2311 double_from_seed (int seed)
2313 return SAMPLE_INT32 * (double) seed + 0.3;
2317 double_write_value (TestTypeNode *node,
2319 DBusTypeWriter *writer,
2324 v = double_from_seed (seed);
2326 return _dbus_type_writer_write_basic (writer,
2327 node->klass->typecode,
2332 double_read_value (TestTypeNode *node,
2333 DBusTypeReader *reader,
2339 check_expected_type (reader, node->klass->typecode);
2341 _dbus_type_reader_read_basic (reader,
2344 expected = double_from_seed (seed);
2346 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2348 #ifdef DBUS_HAVE_INT64
2349 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2351 *(dbus_uint64_t*)(char*)&expected,
2352 *(dbus_uint64_t*)(char*)&v);
2354 _dbus_assert_not_reached ("test failed");
2361 double_set_value (TestTypeNode *node,
2362 DBusTypeReader *reader,
2363 DBusTypeReader *realign_root,
2368 v = double_from_seed (seed);
2370 return _dbus_type_reader_set_basic (reader,
2375 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2377 object_path_from_seed (char *buf,
2385 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2387 v = (unsigned char) ('A' + seed);
2399 if (v < 'A' || v > 'z')
2415 object_path_write_value (TestTypeNode *node,
2417 DBusTypeWriter *writer,
2420 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2421 const char *v_string = buf;
2423 object_path_from_seed (buf, seed);
2425 return _dbus_type_writer_write_basic (writer,
2426 node->klass->typecode,
2431 object_path_read_value (TestTypeNode *node,
2432 DBusTypeReader *reader,
2436 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2438 check_expected_type (reader, node->klass->typecode);
2440 _dbus_type_reader_read_basic (reader,
2441 (const char **) &v);
2443 object_path_from_seed (buf, seed);
2445 if (strcmp (buf, v) != 0)
2447 _dbus_warn ("read object path '%s' expected '%s'\n",
2449 _dbus_assert_not_reached ("test failed");
2456 object_path_set_value (TestTypeNode *node,
2457 DBusTypeReader *reader,
2458 DBusTypeReader *realign_root,
2461 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2462 const char *v_string = buf;
2464 object_path_from_seed (buf, seed);
2466 return _dbus_type_reader_set_basic (reader,
2471 #define MAX_SAMPLE_SIGNATURE_LEN 10
2473 signature_from_seed (char *buf,
2478 /* try to avoid ascending, descending, or alternating length to help find bugs */
2479 const char *sample_signatures[] = {
2488 s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)];
2490 for (i = 0; s[i]; i++)
2498 signature_write_value (TestTypeNode *node,
2500 DBusTypeWriter *writer,
2503 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2504 const char *v_string = buf;
2506 signature_from_seed (buf, seed);
2508 return _dbus_type_writer_write_basic (writer,
2509 node->klass->typecode,
2514 signature_read_value (TestTypeNode *node,
2515 DBusTypeReader *reader,
2519 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2521 check_expected_type (reader, node->klass->typecode);
2523 _dbus_type_reader_read_basic (reader,
2524 (const char **) &v);
2526 signature_from_seed (buf, seed);
2528 if (strcmp (buf, v) != 0)
2530 _dbus_warn ("read signature value '%s' expected '%s'\n",
2532 _dbus_assert_not_reached ("test failed");
2540 signature_set_value (TestTypeNode *node,
2541 DBusTypeReader *reader,
2542 DBusTypeReader *realign_root,
2545 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2546 const char *v_string = buf;
2548 signature_from_seed (buf, seed);
2550 return _dbus_type_reader_set_basic (reader,
2556 struct_write_value (TestTypeNode *node,
2558 DBusTypeWriter *writer,
2561 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2562 DataBlockState saved;
2567 n_copies = node->klass->subclass_detail;
2569 _dbus_assert (container->children != NULL);
2571 data_block_save (block, &saved);
2573 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2579 while (i < n_copies)
2583 link = _dbus_list_get_first_link (&container->children);
2584 while (link != NULL)
2586 TestTypeNode *child = link->data;
2587 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2589 if (!node_write_value (child, block, &sub, seed + i))
2591 data_block_restore (block, &saved);
2601 if (!_dbus_type_writer_unrecurse (writer, &sub))
2603 data_block_restore (block, &saved);
2611 struct_read_or_set_value (TestTypeNode *node,
2612 DBusTypeReader *reader,
2613 DBusTypeReader *realign_root,
2616 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2621 n_copies = node->klass->subclass_detail;
2623 check_expected_type (reader, DBUS_TYPE_STRUCT);
2625 _dbus_type_reader_recurse (reader, &sub);
2628 while (i < n_copies)
2632 link = _dbus_list_get_first_link (&container->children);
2633 while (link != NULL)
2635 TestTypeNode *child = link->data;
2636 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2638 if (realign_root == NULL)
2640 if (!node_read_value (child, &sub, seed + i))
2645 if (!node_set_value (child, &sub, realign_root, seed + i))
2649 if (i == (n_copies - 1) && next == NULL)
2650 NEXT_EXPECTING_FALSE (&sub);
2652 NEXT_EXPECTING_TRUE (&sub);
2664 struct_read_value (TestTypeNode *node,
2665 DBusTypeReader *reader,
2668 return struct_read_or_set_value (node, reader, NULL, seed);
2672 struct_set_value (TestTypeNode *node,
2673 DBusTypeReader *reader,
2674 DBusTypeReader *realign_root,
2677 return struct_read_or_set_value (node, reader, realign_root, seed);
2681 struct_build_signature (TestTypeNode *node,
2684 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2689 n_copies = node->klass->subclass_detail;
2691 orig_len = _dbus_string_get_length (str);
2693 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2697 while (i < n_copies)
2701 link = _dbus_list_get_first_link (&container->children);
2702 while (link != NULL)
2704 TestTypeNode *child = link->data;
2705 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2707 if (!node_build_signature (child, str))
2716 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
2722 _dbus_string_set_length (str, orig_len);
2727 array_write_value (TestTypeNode *node,
2729 DBusTypeWriter *writer,
2732 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2733 DataBlockState saved;
2735 DBusString element_signature;
2739 TestTypeNode *child;
2741 n_copies = node->klass->subclass_detail;
2743 _dbus_assert (container->children != NULL);
2745 data_block_save (block, &saved);
2747 if (!_dbus_string_init (&element_signature))
2750 child = _dbus_list_get_first (&container->children);
2752 if (!node_build_signature (child,
2753 &element_signature))
2756 element_type = _dbus_first_type_in_signature (&element_signature, 0);
2758 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
2759 &element_signature, 0,
2763 if (arrays_write_fixed_in_blocks &&
2764 _dbus_type_is_fixed (element_type) &&
2765 child->klass->write_multi)
2767 if (!node_write_multi (child, block, &sub, seed, n_copies))
2773 while (i < n_copies)
2777 link = _dbus_list_get_first_link (&container->children);
2778 while (link != NULL)
2780 TestTypeNode *child = link->data;
2781 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2783 if (!node_write_value (child, block, &sub, seed + i))
2793 if (!_dbus_type_writer_unrecurse (writer, &sub))
2796 _dbus_string_free (&element_signature);
2800 data_block_restore (block, &saved);
2801 _dbus_string_free (&element_signature);
2806 array_read_or_set_value (TestTypeNode *node,
2807 DBusTypeReader *reader,
2808 DBusTypeReader *realign_root,
2811 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2815 TestTypeNode *child;
2817 n_copies = node->klass->subclass_detail;
2819 check_expected_type (reader, DBUS_TYPE_ARRAY);
2821 child = _dbus_list_get_first (&container->children);
2825 _dbus_type_reader_recurse (reader, &sub);
2827 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
2828 _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
2829 child->klass->read_multi)
2831 if (!node_read_multi (child, &sub, seed, n_copies))
2837 while (i < n_copies)
2841 link = _dbus_list_get_first_link (&container->children);
2842 while (link != NULL)
2844 TestTypeNode *child = link->data;
2845 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2847 _dbus_assert (child->klass->typecode ==
2848 _dbus_type_reader_get_element_type (reader));
2850 if (realign_root == NULL)
2852 if (!node_read_value (child, &sub, seed + i))
2857 if (!node_set_value (child, &sub, realign_root, seed + i))
2861 if (i == (n_copies - 1) && next == NULL)
2862 NEXT_EXPECTING_FALSE (&sub);
2864 NEXT_EXPECTING_TRUE (&sub);
2878 array_read_value (TestTypeNode *node,
2879 DBusTypeReader *reader,
2882 return array_read_or_set_value (node, reader, NULL, seed);
2886 array_set_value (TestTypeNode *node,
2887 DBusTypeReader *reader,
2888 DBusTypeReader *realign_root,
2891 return array_read_or_set_value (node, reader, realign_root, seed);
2895 array_build_signature (TestTypeNode *node,
2898 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2901 orig_len = _dbus_string_get_length (str);
2903 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
2906 if (!node_build_signature (_dbus_list_get_first (&container->children),
2913 _dbus_string_set_length (str, orig_len);
2917 /* 10 is random just to add another seed that we use in the suite */
2918 #define VARIANT_SEED 10
2921 variant_write_value (TestTypeNode *node,
2923 DBusTypeWriter *writer,
2926 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2927 DataBlockState saved;
2929 DBusString content_signature;
2930 TestTypeNode *child;
2932 _dbus_assert (container->children != NULL);
2933 _dbus_assert (_dbus_list_length_is_one (&container->children));
2935 child = _dbus_list_get_first (&container->children);
2937 data_block_save (block, &saved);
2939 if (!_dbus_string_init (&content_signature))
2942 if (!node_build_signature (child,
2943 &content_signature))
2946 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
2947 &content_signature, 0,
2951 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
2954 if (!_dbus_type_writer_unrecurse (writer, &sub))
2957 _dbus_string_free (&content_signature);
2961 data_block_restore (block, &saved);
2962 _dbus_string_free (&content_signature);
2967 variant_read_or_set_value (TestTypeNode *node,
2968 DBusTypeReader *reader,
2969 DBusTypeReader *realign_root,
2972 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2974 TestTypeNode *child;
2976 _dbus_assert (container->children != NULL);
2977 _dbus_assert (_dbus_list_length_is_one (&container->children));
2979 child = _dbus_list_get_first (&container->children);
2981 check_expected_type (reader, DBUS_TYPE_VARIANT);
2983 _dbus_type_reader_recurse (reader, &sub);
2985 if (realign_root == NULL)
2987 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
2992 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
2996 NEXT_EXPECTING_FALSE (&sub);
3002 variant_read_value (TestTypeNode *node,
3003 DBusTypeReader *reader,
3006 return variant_read_or_set_value (node, reader, NULL, seed);
3010 variant_set_value (TestTypeNode *node,
3011 DBusTypeReader *reader,
3012 DBusTypeReader *realign_root,
3015 return variant_read_or_set_value (node, reader, realign_root, seed);
3019 container_destroy (TestTypeNode *node)
3021 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3024 link = _dbus_list_get_first_link (&container->children);
3025 while (link != NULL)
3027 TestTypeNode *child = link->data;
3028 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3030 node_destroy (child);
3032 _dbus_list_free_link (link);
3038 #endif /* DBUS_BUILD_TESTS */