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"
35 first_type_in_signature (const DBusString *str,
40 t = _dbus_string_get_byte (str, pos);
42 if (t == DBUS_STRUCT_BEGIN_CHAR)
43 return DBUS_TYPE_STRUCT;
48 /* Whether to do the OOM stuff (only with other expensive tests) */
49 #define TEST_OOM_HANDLING 0
50 /* We do start offset 0 through 9, to get various alignment cases. Still this
51 * obviously makes the test suite run 10x as slow.
53 #define MAX_INITIAL_OFFSET 9
55 /* Largest iteration count to test copying, realignment,
56 * etc. with. i.e. we only test this stuff with some of the smaller
59 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
75 #define N_FENCE_BYTES 5
76 #define FENCE_BYTES_STR "abcde"
77 #define INITIAL_PADDING_BYTE '\0'
80 data_block_init (DataBlock *block,
84 if (!_dbus_string_init (&block->signature))
87 if (!_dbus_string_init (&block->body))
89 _dbus_string_free (&block->signature);
93 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
94 INITIAL_PADDING_BYTE) ||
95 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
96 INITIAL_PADDING_BYTE) ||
97 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
98 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
100 _dbus_string_free (&block->signature);
101 _dbus_string_free (&block->body);
105 block->byte_order = byte_order;
106 block->initial_offset = initial_offset;
112 data_block_save (DataBlock *block,
113 DataBlockState *state)
115 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
116 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
120 data_block_restore (DataBlock *block,
121 DataBlockState *state)
123 _dbus_string_delete (&block->signature,
124 state->saved_sig_len,
125 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
126 _dbus_string_delete (&block->body,
127 state->saved_body_len,
128 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
132 data_block_verify (DataBlock *block)
134 if (!_dbus_string_ends_with_c_str (&block->signature,
139 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
143 _dbus_verbose_bytes_of_string (&block->signature,
145 _dbus_string_get_length (&block->signature) - offset);
146 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
148 if (!_dbus_string_ends_with_c_str (&block->body,
153 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
157 _dbus_verbose_bytes_of_string (&block->body,
159 _dbus_string_get_length (&block->body) - offset);
160 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
163 _dbus_assert (_dbus_string_validate_nul (&block->signature,
164 0, block->initial_offset));
165 _dbus_assert (_dbus_string_validate_nul (&block->body,
166 0, block->initial_offset));
170 data_block_free (DataBlock *block)
172 data_block_verify (block);
174 _dbus_string_free (&block->signature);
175 _dbus_string_free (&block->body);
179 data_block_reset (DataBlock *block)
181 data_block_verify (block);
183 _dbus_string_delete (&block->signature,
184 block->initial_offset,
185 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
186 _dbus_string_delete (&block->body,
187 block->initial_offset,
188 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
190 data_block_verify (block);
194 data_block_init_reader_writer (DataBlock *block,
195 DBusTypeReader *reader,
196 DBusTypeWriter *writer)
199 _dbus_type_reader_init (reader,
202 block->initial_offset,
204 block->initial_offset);
207 _dbus_type_writer_init (writer,
210 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
212 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
216 real_check_expected_type (DBusTypeReader *reader,
218 const char *funcname,
223 t = _dbus_type_reader_get_current_type (reader);
227 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
228 _dbus_type_to_string (t),
229 _dbus_type_to_string (expected),
232 _dbus_assert_not_reached ("read wrong type");
236 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
238 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
240 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
241 _DBUS_FUNCTION_NAME, __LINE__); \
242 _dbus_assert_not_reached ("test failed"); \
246 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
248 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
249 _DBUS_FUNCTION_NAME, __LINE__); \
250 _dbus_assert_not_reached ("test failed"); \
252 check_expected_type (reader, DBUS_TYPE_INVALID); \
255 typedef struct TestTypeNode TestTypeNode;
256 typedef struct TestTypeNodeClass TestTypeNodeClass;
257 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
258 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
262 const TestTypeNodeClass *klass;
265 struct TestTypeNodeContainer
271 struct TestTypeNodeClass
277 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
279 dbus_bool_t (* construct) (TestTypeNode *node);
280 void (* destroy) (TestTypeNode *node);
282 dbus_bool_t (* write_value) (TestTypeNode *node,
284 DBusTypeWriter *writer,
286 dbus_bool_t (* read_value) (TestTypeNode *node,
287 DBusTypeReader *reader,
289 dbus_bool_t (* set_value) (TestTypeNode *node,
290 DBusTypeReader *reader,
291 DBusTypeReader *realign_root,
293 dbus_bool_t (* build_signature) (TestTypeNode *node,
295 dbus_bool_t (* write_multi) (TestTypeNode *node,
297 DBusTypeWriter *writer,
300 dbus_bool_t (* read_multi) (TestTypeNode *node,
301 DBusTypeReader *reader,
306 struct TestTypeNodeContainerClass
308 TestTypeNodeClass base;
311 /* FIXME this could be chilled out substantially by unifying
312 * the basic types into basic_write_value/basic_read_value
313 * and by merging read_value and set_value into one function
314 * taking a flag argument.
316 static dbus_bool_t int32_write_value (TestTypeNode *node,
318 DBusTypeWriter *writer,
320 static dbus_bool_t int32_read_value (TestTypeNode *node,
321 DBusTypeReader *reader,
323 static dbus_bool_t int32_set_value (TestTypeNode *node,
324 DBusTypeReader *reader,
325 DBusTypeReader *realign_root,
327 static dbus_bool_t int32_write_multi (TestTypeNode *node,
329 DBusTypeWriter *writer,
332 static dbus_bool_t int32_read_multi (TestTypeNode *node,
333 DBusTypeReader *reader,
336 static dbus_bool_t int64_write_value (TestTypeNode *node,
338 DBusTypeWriter *writer,
340 static dbus_bool_t int64_read_value (TestTypeNode *node,
341 DBusTypeReader *reader,
343 static dbus_bool_t int64_set_value (TestTypeNode *node,
344 DBusTypeReader *reader,
345 DBusTypeReader *realign_root,
347 static dbus_bool_t string_write_value (TestTypeNode *node,
349 DBusTypeWriter *writer,
351 static dbus_bool_t string_read_value (TestTypeNode *node,
352 DBusTypeReader *reader,
354 static dbus_bool_t string_set_value (TestTypeNode *node,
355 DBusTypeReader *reader,
356 DBusTypeReader *realign_root,
358 static dbus_bool_t bool_write_value (TestTypeNode *node,
360 DBusTypeWriter *writer,
362 static dbus_bool_t bool_read_value (TestTypeNode *node,
363 DBusTypeReader *reader,
365 static dbus_bool_t bool_set_value (TestTypeNode *node,
366 DBusTypeReader *reader,
367 DBusTypeReader *realign_root,
369 static dbus_bool_t byte_write_value (TestTypeNode *node,
371 DBusTypeWriter *writer,
373 static dbus_bool_t byte_read_value (TestTypeNode *node,
374 DBusTypeReader *reader,
376 static dbus_bool_t byte_set_value (TestTypeNode *node,
377 DBusTypeReader *reader,
378 DBusTypeReader *realign_root,
380 static dbus_bool_t double_write_value (TestTypeNode *node,
382 DBusTypeWriter *writer,
384 static dbus_bool_t double_read_value (TestTypeNode *node,
385 DBusTypeReader *reader,
387 static dbus_bool_t double_set_value (TestTypeNode *node,
388 DBusTypeReader *reader,
389 DBusTypeReader *realign_root,
391 static dbus_bool_t object_path_write_value (TestTypeNode *node,
393 DBusTypeWriter *writer,
395 static dbus_bool_t object_path_read_value (TestTypeNode *node,
396 DBusTypeReader *reader,
398 static dbus_bool_t object_path_set_value (TestTypeNode *node,
399 DBusTypeReader *reader,
400 DBusTypeReader *realign_root,
402 static dbus_bool_t signature_write_value (TestTypeNode *node,
404 DBusTypeWriter *writer,
406 static dbus_bool_t signature_read_value (TestTypeNode *node,
407 DBusTypeReader *reader,
409 static dbus_bool_t signature_set_value (TestTypeNode *node,
410 DBusTypeReader *reader,
411 DBusTypeReader *realign_root,
413 static dbus_bool_t struct_write_value (TestTypeNode *node,
415 DBusTypeWriter *writer,
417 static dbus_bool_t struct_read_value (TestTypeNode *node,
418 DBusTypeReader *reader,
420 static dbus_bool_t struct_set_value (TestTypeNode *node,
421 DBusTypeReader *reader,
422 DBusTypeReader *realign_root,
424 static dbus_bool_t struct_build_signature (TestTypeNode *node,
426 static dbus_bool_t array_write_value (TestTypeNode *node,
428 DBusTypeWriter *writer,
430 static dbus_bool_t array_read_value (TestTypeNode *node,
431 DBusTypeReader *reader,
433 static dbus_bool_t array_set_value (TestTypeNode *node,
434 DBusTypeReader *reader,
435 DBusTypeReader *realign_root,
437 static dbus_bool_t array_build_signature (TestTypeNode *node,
439 static dbus_bool_t variant_write_value (TestTypeNode *node,
441 DBusTypeWriter *writer,
443 static dbus_bool_t variant_read_value (TestTypeNode *node,
444 DBusTypeReader *reader,
446 static dbus_bool_t variant_set_value (TestTypeNode *node,
447 DBusTypeReader *reader,
448 DBusTypeReader *realign_root,
450 static void container_destroy (TestTypeNode *node);
453 static const TestTypeNodeClass int32_class = {
455 sizeof (TestTypeNode),
467 static const TestTypeNodeClass uint32_class = {
469 sizeof (TestTypeNode),
473 int32_write_value, /* recycle from int32 */
474 int32_read_value, /* recycle from int32 */
475 int32_set_value, /* recycle from int32 */
477 int32_write_multi, /* recycle from int32 */
478 int32_read_multi /* recycle from int32 */
481 static const TestTypeNodeClass int64_class = {
483 sizeof (TestTypeNode),
495 static const TestTypeNodeClass uint64_class = {
497 sizeof (TestTypeNode),
501 int64_write_value, /* recycle from int64 */
502 int64_read_value, /* recycle from int64 */
503 int64_set_value, /* recycle from int64 */
509 static const TestTypeNodeClass string_0_class = {
511 sizeof (TestTypeNode),
512 0, /* string length */
523 static const TestTypeNodeClass string_1_class = {
525 sizeof (TestTypeNode),
526 1, /* string length */
537 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
538 static const TestTypeNodeClass string_3_class = {
540 sizeof (TestTypeNode),
541 3, /* string length */
552 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
553 static const TestTypeNodeClass string_8_class = {
555 sizeof (TestTypeNode),
556 8, /* string length */
567 static const TestTypeNodeClass bool_class = {
569 sizeof (TestTypeNode),
581 static const TestTypeNodeClass byte_class = {
583 sizeof (TestTypeNode),
595 static const TestTypeNodeClass double_class = {
597 sizeof (TestTypeNode),
609 static const TestTypeNodeClass object_path_class = {
610 DBUS_TYPE_OBJECT_PATH,
611 sizeof (TestTypeNode),
615 object_path_write_value,
616 object_path_read_value,
617 object_path_set_value,
623 static const TestTypeNodeClass signature_class = {
625 sizeof (TestTypeNode),
629 signature_write_value,
630 signature_read_value,
637 static const TestTypeNodeClass struct_1_class = {
639 sizeof (TestTypeNodeContainer),
640 1, /* number of times children appear as fields */
646 struct_build_signature,
651 static const TestTypeNodeClass struct_2_class = {
653 sizeof (TestTypeNodeContainer),
654 2, /* number of times children appear as fields */
660 struct_build_signature,
665 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
667 static const TestTypeNodeClass array_0_class = {
669 sizeof (TestTypeNodeContainer),
670 0, /* number of array elements */
676 array_build_signature,
681 static const TestTypeNodeClass array_1_class = {
683 sizeof (TestTypeNodeContainer),
684 1, /* number of array elements */
690 array_build_signature,
695 static const TestTypeNodeClass array_2_class = {
697 sizeof (TestTypeNodeContainer),
698 2, /* number of array elements */
704 array_build_signature,
709 static const TestTypeNodeClass array_9_class = {
711 sizeof (TestTypeNodeContainer),
712 9, /* number of array elements */
718 array_build_signature,
723 static const TestTypeNodeClass variant_class = {
725 sizeof (TestTypeNodeContainer),
737 static const TestTypeNodeClass* const
753 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
755 static const TestTypeNodeClass* const
756 container_nodes[] = {
763 /* array_9_class is omitted on purpose, it's too slow;
764 * we only use it in one hardcoded test below
767 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
770 node_new (const TestTypeNodeClass *klass)
774 node = dbus_malloc0 (klass->instance_size);
780 if (klass->construct)
782 if (!(* klass->construct) (node))
793 node_destroy (TestTypeNode *node)
795 if (node->klass->destroy)
796 (* node->klass->destroy) (node);
801 node_write_value (TestTypeNode *node,
803 DBusTypeWriter *writer,
808 retval = (* node->klass->write_value) (node, block, writer, seed);
811 /* Handy to see where things break, but too expensive to do all the time */
812 data_block_verify (block);
819 node_read_value (TestTypeNode *node,
820 DBusTypeReader *reader,
824 DBusTypeReader restored;
826 _dbus_type_reader_save_mark (reader, &mark);
828 if (!(* node->klass->read_value) (node, reader, seed))
831 _dbus_type_reader_init_from_mark (&restored,
837 if (!(* node->klass->read_value) (node, &restored, seed))
843 /* Warning: if this one fails due to OOM, it has side effects (can
844 * modify only some of the sub-values). OK in a test suite, but we
845 * never do this in real code.
848 node_set_value (TestTypeNode *node,
849 DBusTypeReader *reader,
850 DBusTypeReader *realign_root,
853 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
860 node_build_signature (TestTypeNode *node,
863 if (node->klass->build_signature)
864 return (* node->klass->build_signature) (node, str);
866 return _dbus_string_append_byte (str, node->klass->typecode);
870 node_append_child (TestTypeNode *node,
873 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
875 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
877 if (!_dbus_list_append (&container->children, child))
878 _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 */
884 node_write_multi (TestTypeNode *node,
886 DBusTypeWriter *writer,
892 _dbus_assert (node->klass->write_multi != NULL);
893 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
896 /* Handy to see where things break, but too expensive to do all the time */
897 data_block_verify (block);
904 node_read_multi (TestTypeNode *node,
905 DBusTypeReader *reader,
909 _dbus_assert (node->klass->read_multi != NULL);
911 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
917 static int n_iterations_completed_total = 0;
918 static int n_iterations_completed_this_test = 0;
919 static int n_iterations_expected_this_test = 0;
923 const DBusString *signature;
926 TestTypeNode **nodes;
931 run_test_copy (NodeIterationData *nid)
936 DBusTypeReader reader;
937 DBusTypeWriter writer;
939 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
945 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
948 data_block_init_reader_writer (src, &reader, NULL);
949 data_block_init_reader_writer (&dest, NULL, &writer);
951 /* DBusTypeWriter assumes it's writing into an existing signature,
952 * so doesn't add nul on its own. We have to do that.
954 if (!_dbus_string_insert_byte (&dest.signature,
955 dest.initial_offset, '\0'))
958 if (!_dbus_type_writer_write_reader (&writer, &reader))
961 /* Data blocks should now be identical */
962 if (!_dbus_string_equal (&src->signature, &dest.signature))
964 _dbus_verbose ("SOURCE\n");
965 _dbus_verbose_bytes_of_string (&src->signature, 0,
966 _dbus_string_get_length (&src->signature));
967 _dbus_verbose ("DEST\n");
968 _dbus_verbose_bytes_of_string (&dest.signature, 0,
969 _dbus_string_get_length (&dest.signature));
970 _dbus_assert_not_reached ("signatures did not match");
973 if (!_dbus_string_equal (&src->body, &dest.body))
975 _dbus_verbose ("SOURCE\n");
976 _dbus_verbose_bytes_of_string (&src->body, 0,
977 _dbus_string_get_length (&src->body));
978 _dbus_verbose ("DEST\n");
979 _dbus_verbose_bytes_of_string (&dest.body, 0,
980 _dbus_string_get_length (&dest.body));
981 _dbus_assert_not_reached ("bodies did not match");
988 data_block_free (&dest);
994 run_test_values_only_write (NodeIterationData *nid)
996 DBusTypeReader reader;
997 DBusTypeWriter writer;
1002 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1006 data_block_reset (nid->block);
1008 sig_len = _dbus_string_get_length (nid->signature);
1010 _dbus_type_writer_init_values_only (&writer,
1011 nid->block->byte_order,
1014 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1015 _dbus_type_reader_init (&reader,
1016 nid->block->byte_order,
1019 nid->block->initial_offset);
1022 while (i < nid->n_nodes)
1024 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1030 /* if we wrote any typecodes then this would fail */
1031 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1033 /* But be sure we wrote out the values correctly */
1035 while (i < nid->n_nodes)
1037 if (!node_read_value (nid->nodes[i], &reader, i))
1040 if (i + 1 == nid->n_nodes)
1041 NEXT_EXPECTING_FALSE (&reader);
1043 NEXT_EXPECTING_TRUE (&reader);
1051 data_block_reset (nid->block);
1055 /* offset the seed for setting, so we set different numbers than
1056 * we originally wrote. Don't offset by a huge number since in
1057 * some cases it's value = possibilities[seed % n_possibilities]
1058 * and we don't want to wrap around. bool_from_seed
1059 * is just seed % 2 even.
1063 run_test_set_values (NodeIterationData *nid)
1065 DBusTypeReader reader;
1066 DBusTypeReader realign_root;
1070 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1074 data_block_init_reader_writer (nid->block,
1077 realign_root = reader;
1080 while (i < nid->n_nodes)
1082 if (!node_set_value (nid->nodes[i],
1083 &reader, &realign_root,
1087 if (i + 1 == nid->n_nodes)
1088 NEXT_EXPECTING_FALSE (&reader);
1090 NEXT_EXPECTING_TRUE (&reader);
1095 /* Check that the new values were set */
1097 reader = realign_root;
1100 while (i < nid->n_nodes)
1102 if (!node_read_value (nid->nodes[i], &reader,
1106 if (i + 1 == nid->n_nodes)
1107 NEXT_EXPECTING_FALSE (&reader);
1109 NEXT_EXPECTING_TRUE (&reader);
1121 run_test_delete_values (NodeIterationData *nid)
1123 DBusTypeReader reader;
1127 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1131 data_block_init_reader_writer (nid->block,
1134 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1136 /* Right now, deleting only works on array elements. We delete
1137 * all array elements, and then verify that there aren't any
1140 if (t == DBUS_TYPE_ARRAY)
1142 DBusTypeReader array;
1146 _dbus_type_reader_recurse (&reader, &array);
1148 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1151 _dbus_type_reader_next (&array);
1154 /* reset to start of array */
1155 _dbus_type_reader_recurse (&reader, &array);
1156 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1157 reader.value_pos, array.value_pos, array.u.array.start_pos);
1158 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1160 /* We don't want to always delete from the same part of the array. */
1161 static int cycle = 0;
1164 _dbus_assert (n_elements > 0);
1167 if (elem == 3 || elem >= n_elements) /* end of array */
1168 elem = n_elements - 1;
1170 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1171 elem, n_elements, _dbus_type_to_string (elem_type),
1172 cycle, reader.value_pos, array.value_pos);
1175 if (!_dbus_type_reader_next (&array))
1176 _dbus_assert_not_reached ("should have had another element\n");
1180 if (!_dbus_type_reader_delete (&array, &reader))
1186 _dbus_type_reader_recurse (&reader, &array);
1194 _dbus_type_reader_next (&reader);
1197 /* Check that there are no array elements left */
1198 data_block_init_reader_writer (nid->block,
1201 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1203 _dbus_type_reader_next (&reader);
1213 run_test_nodes_iteration (void *data)
1215 NodeIterationData *nid = data;
1216 DBusTypeReader reader;
1217 DBusTypeWriter writer;
1222 * 1. write the value
1223 * 2. strcmp-compare with the signature we built
1225 * 4. type-iterate the signature and the value and see if they are the same type-wise
1229 data_block_init_reader_writer (nid->block,
1232 /* DBusTypeWriter assumes it's writing into an existing signature,
1233 * so doesn't add nul on its own. We have to do that.
1235 if (!_dbus_string_insert_byte (&nid->block->signature,
1236 nid->type_offset, '\0'))
1240 while (i < nid->n_nodes)
1242 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1248 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1249 &nid->block->signature, nid->type_offset))
1251 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1252 _dbus_string_get_const_data (nid->signature),
1253 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1255 _dbus_assert_not_reached ("wrong signature");
1259 while (i < nid->n_nodes)
1261 if (!node_read_value (nid->nodes[i], &reader, i))
1264 if (i + 1 == nid->n_nodes)
1265 NEXT_EXPECTING_FALSE (&reader);
1267 NEXT_EXPECTING_TRUE (&reader);
1272 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1274 /* this set values test uses code from copy and
1275 * values_only_write so would ideally be last so you get a
1276 * simpler test case for problems with copying or values_only
1277 * writing; but it also needs an already-written DataBlock so it
1278 * has to go first. Comment it out if it breaks, and see if the
1279 * later tests also break - debug them first if so.
1281 if (!run_test_set_values (nid))
1284 if (!run_test_delete_values (nid))
1287 if (!run_test_copy (nid))
1290 if (!run_test_values_only_write (nid))
1294 /* FIXME type-iterate both signature and value and compare the resulting
1295 * tree to the node tree perhaps
1302 data_block_reset (nid->block);
1308 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1310 const DBusString *signature,
1315 NodeIterationData nid;
1317 if (!data_block_init (&block, byte_order, initial_offset))
1318 _dbus_assert_not_reached ("no memory");
1320 nid.signature = signature;
1322 nid.type_offset = initial_offset;
1324 nid.n_nodes = n_nodes;
1326 if (TEST_OOM_HANDLING &&
1327 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1329 _dbus_test_oom_handling ("running test node",
1330 run_test_nodes_iteration,
1335 if (!run_test_nodes_iteration (&nid))
1336 _dbus_assert_not_reached ("no memory");
1339 data_block_free (&block);
1343 run_test_nodes (TestTypeNode **nodes,
1347 DBusString signature;
1349 if (!_dbus_string_init (&signature))
1350 _dbus_assert_not_reached ("no memory");
1355 if (! node_build_signature (nodes[i], &signature))
1356 _dbus_assert_not_reached ("no memory");
1361 _dbus_verbose (">>> test nodes with signature '%s'\n",
1362 _dbus_string_get_const_data (&signature));
1365 while (i <= MAX_INITIAL_OFFSET)
1367 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1368 DBUS_LITTLE_ENDIAN, i);
1369 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1370 DBUS_BIG_ENDIAN, i);
1375 n_iterations_completed_this_test += 1;
1376 n_iterations_completed_total += 1;
1378 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1380 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1381 n_iterations_completed_this_test,
1382 n_iterations_completed_total);
1384 /* this happens to turn out well with mod == 1 */
1385 else if ((n_iterations_completed_this_test %
1386 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1388 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1391 _dbus_string_free (&signature);
1394 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1396 static TestTypeNode*
1397 value_generator (int *ip)
1400 const TestTypeNodeClass *child_klass;
1401 const TestTypeNodeClass *container_klass;
1402 TestTypeNode *child;
1405 _dbus_assert (i <= N_VALUES);
1411 else if (i < N_BASICS)
1413 node = node_new (basic_nodes[i]);
1417 /* imagine an array:
1418 * container 0 of basic 0
1419 * container 0 of basic 1
1420 * container 0 of basic 2
1421 * container 1 of basic 0
1422 * container 1 of basic 1
1423 * container 1 of basic 2
1427 container_klass = container_nodes[i / N_BASICS];
1428 child_klass = basic_nodes[i % N_BASICS];
1430 node = node_new (container_klass);
1431 child = node_new (child_klass);
1433 node_append_child (node, child);
1436 *ip += 1; /* increment the generator */
1442 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1446 TestTypeNode *container;
1447 TestTypeNode *child;
1450 root = node_new (container_klass);
1452 for (i = 1; i < n_nested; i++)
1454 child = node_new (container_klass);
1455 node_append_child (container, child);
1459 /* container should now be the most-nested container */
1462 while ((child = value_generator (&i)))
1464 node_append_child (container, child);
1466 run_test_nodes (&root, 1);
1468 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1469 node_destroy (child);
1472 node_destroy (root);
1476 start_next_test (const char *format,
1479 n_iterations_completed_this_test = 0;
1480 n_iterations_expected_this_test = expected;
1482 fprintf (stderr, ">>> >>> ");
1483 fprintf (stderr, format,
1484 n_iterations_expected_this_test);
1488 make_and_run_test_nodes (void)
1492 /* We try to do this in order of "complicatedness" so that test
1493 * failures tend to show up in the simplest test case that
1494 * demonstrates the failure. There are also some tests that run
1495 * more than once for this reason, first while going through simple
1496 * cases, second while going through a broader range of complex
1499 /* Each basic node. The basic nodes should include:
1501 * - each fixed-size type (in such a way that it has different values each time,
1502 * so we can tell if we mix two of them up)
1503 * - strings of various lengths
1507 /* Each container node. The container nodes should include:
1509 * struct with 1 and 2 copies of the contained item
1510 * array with 0, 1, 2 copies of the contained item
1513 /* Let a "value" be a basic node, or a container containing a single basic node.
1514 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1515 * When iterating through all values to make combinations, do the basic types
1516 * first and the containers second.
1518 /* Each item is shown with its number of iterations to complete so
1519 * we can keep a handle on this unit test
1522 /* FIXME test just an empty body, no types at all */
1524 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1528 while ((node = value_generator (&i)))
1530 run_test_nodes (&node, 1);
1532 node_destroy (node);
1536 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1537 arrays_write_fixed_in_blocks = TRUE;
1541 while ((node = value_generator (&i)))
1543 run_test_nodes (&node, 1);
1545 node_destroy (node);
1548 arrays_write_fixed_in_blocks = FALSE;
1550 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1552 TestTypeNode *nodes[N_VALUES];
1555 while ((nodes[i] = value_generator (&i)))
1558 run_test_nodes (nodes, N_VALUES);
1560 for (i = 0; i < N_VALUES; i++)
1561 node_destroy (nodes[i]);
1564 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1565 N_VALUES * N_VALUES);
1567 TestTypeNode *nodes[2];
1570 while ((nodes[0] = value_generator (&i)))
1573 while ((nodes[1] = value_generator (&j)))
1575 run_test_nodes (nodes, 2);
1577 node_destroy (nodes[1]);
1580 node_destroy (nodes[0]);
1584 start_next_test ("Each container containing each value %d iterations\n",
1585 N_CONTAINERS * N_VALUES);
1586 for (i = 0; i < N_CONTAINERS; i++)
1588 const TestTypeNodeClass *container_klass = container_nodes[i];
1590 make_and_run_values_inside_container (container_klass, 1);
1593 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1594 N_CONTAINERS * N_VALUES);
1595 arrays_write_fixed_in_blocks = TRUE;
1596 for (i = 0; i < N_CONTAINERS; i++)
1598 const TestTypeNodeClass *container_klass = container_nodes[i];
1600 make_and_run_values_inside_container (container_klass, 1);
1602 arrays_write_fixed_in_blocks = FALSE;
1604 start_next_test ("Each container of same container of each value %d iterations\n",
1605 N_CONTAINERS * N_VALUES);
1606 for (i = 0; i < N_CONTAINERS; i++)
1608 const TestTypeNodeClass *container_klass = container_nodes[i];
1610 make_and_run_values_inside_container (container_klass, 2);
1613 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1614 N_CONTAINERS * N_VALUES);
1615 for (i = 0; i < N_CONTAINERS; i++)
1617 const TestTypeNodeClass *container_klass = container_nodes[i];
1619 make_and_run_values_inside_container (container_klass, 3);
1622 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1623 N_VALUES * N_VALUES);
1625 TestTypeNode *val1, *val2;
1628 node = node_new (&struct_1_class);
1631 while ((val1 = value_generator (&i)))
1634 while ((val2 = value_generator (&j)))
1636 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1638 node_append_child (node, val1);
1639 node_append_child (node, val2);
1641 run_test_nodes (&node, 1);
1643 _dbus_list_clear (&container->children);
1644 node_destroy (val2);
1646 node_destroy (val1);
1648 node_destroy (node);
1651 start_next_test ("All values in one big struct %d iteration\n",
1655 TestTypeNode *child;
1657 node = node_new (&struct_1_class);
1660 while ((child = value_generator (&i)))
1661 node_append_child (node, child);
1663 run_test_nodes (&node, 1);
1665 node_destroy (node);
1668 start_next_test ("Each value in a large array %d iterations\n",
1674 node = node_new (&array_9_class);
1677 while ((val = value_generator (&i)))
1679 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1681 node_append_child (node, val);
1683 run_test_nodes (&node, 1);
1685 _dbus_list_clear (&container->children);
1689 node_destroy (node);
1692 start_next_test ("Each container of each container of each value %d iterations\n",
1693 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1694 for (i = 0; i < N_CONTAINERS; i++)
1696 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1697 TestTypeNode *outer_container = node_new (outer_container_klass);
1699 for (j = 0; j < N_CONTAINERS; j++)
1701 TestTypeNode *child;
1702 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1703 TestTypeNode *inner_container = node_new (inner_container_klass);
1705 node_append_child (outer_container, inner_container);
1708 while ((child = value_generator (&m)))
1710 node_append_child (inner_container, child);
1712 run_test_nodes (&outer_container, 1);
1714 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1715 node_destroy (child);
1717 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1718 node_destroy (inner_container);
1720 node_destroy (outer_container);
1723 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1724 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1725 for (i = 0; i < N_CONTAINERS; i++)
1727 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1728 TestTypeNode *outer_container = node_new (outer_container_klass);
1730 for (j = 0; j < N_CONTAINERS; j++)
1732 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1733 TestTypeNode *inner_container = node_new (inner_container_klass);
1735 node_append_child (outer_container, inner_container);
1737 for (k = 0; k < N_CONTAINERS; k++)
1739 TestTypeNode *child;
1740 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1741 TestTypeNode *center_container = node_new (center_container_klass);
1743 node_append_child (inner_container, center_container);
1746 while ((child = value_generator (&m)))
1748 node_append_child (center_container, child);
1750 run_test_nodes (&outer_container, 1);
1752 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1753 node_destroy (child);
1755 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1756 node_destroy (center_container);
1758 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1759 node_destroy (inner_container);
1761 node_destroy (outer_container);
1765 /* This one takes a really long time, so comment it out for now */
1766 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
1767 N_VALUES * N_VALUES * N_VALUES);
1769 TestTypeNode *nodes[3];
1772 while ((nodes[0] = value_generator (&i)))
1775 while ((nodes[1] = value_generator (&j)))
1778 while ((nodes[2] = value_generator (&k)))
1780 run_test_nodes (nodes, 3);
1782 node_destroy (nodes[2]);
1784 node_destroy (nodes[1]);
1786 node_destroy (nodes[0]);
1789 #endif /* #if 0 expensive test */
1791 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
1792 n_iterations_completed_total);
1793 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
1794 MAX_INITIAL_OFFSET);
1795 fprintf (stderr, "out of memory handling %s tested\n",
1796 TEST_OOM_HANDLING ? "was" : "was not");
1800 _dbus_marshal_recursive_test (void)
1802 make_and_run_test_nodes ();
1810 * Implementations of each type node class
1815 #define MAX_MULTI_COUNT 5
1818 #define SAMPLE_INT32 12345678
1819 #define SAMPLE_INT32_ALTERNATE 53781429
1821 int32_from_seed (int seed)
1823 /* Generate an integer value that's predictable from seed. We could
1824 * just use seed itself, but that would only ever touch one byte of
1825 * the int so would miss some kinds of bug.
1829 v = 42; /* just to quiet compiler afaik */
1836 v = SAMPLE_INT32_ALTERNATE;
1850 v *= seed; /* wraps around eventually, which is fine */
1856 int32_write_value (TestTypeNode *node,
1858 DBusTypeWriter *writer,
1861 /* also used for uint32 */
1864 v = int32_from_seed (seed);
1866 return _dbus_type_writer_write_basic (writer,
1867 node->klass->typecode,
1872 int32_read_value (TestTypeNode *node,
1873 DBusTypeReader *reader,
1876 /* also used for uint32 */
1879 check_expected_type (reader, node->klass->typecode);
1881 _dbus_type_reader_read_basic (reader,
1882 (dbus_int32_t*) &v);
1884 _dbus_assert (v == int32_from_seed (seed));
1890 int32_set_value (TestTypeNode *node,
1891 DBusTypeReader *reader,
1892 DBusTypeReader *realign_root,
1895 /* also used for uint32 */
1898 v = int32_from_seed (seed);
1900 return _dbus_type_reader_set_basic (reader,
1906 int32_write_multi (TestTypeNode *node,
1908 DBusTypeWriter *writer,
1912 /* also used for uint32 */
1913 dbus_int32_t values[MAX_MULTI_COUNT];
1914 dbus_int32_t *v_ARRAY_INT32 = values;
1917 for (i = 0; i < count; ++i)
1918 values[i] = int32_from_seed (seed + i);
1920 return _dbus_type_writer_write_fixed_multi (writer,
1921 node->klass->typecode,
1922 &v_ARRAY_INT32, count);
1926 int32_read_multi (TestTypeNode *node,
1927 DBusTypeReader *reader,
1931 /* also used for uint32 */
1932 dbus_int32_t *values;
1936 check_expected_type (reader, node->klass->typecode);
1938 _dbus_type_reader_read_fixed_multi (reader,
1942 if (n_elements != count)
1943 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
1944 _dbus_assert (n_elements == count);
1946 for (i = 0; i < count; i++)
1947 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
1948 (const unsigned char*)values + (i * 4))) ==
1949 int32_from_seed (seed + i));
1954 #ifdef DBUS_HAVE_INT64
1956 int64_from_seed (int seed)
1961 v32 = int32_from_seed (seed);
1963 v = - (dbus_int32_t) ~ v32;
1964 v |= (((dbus_int64_t)v32) << 32);
1971 int64_write_value (TestTypeNode *node,
1973 DBusTypeWriter *writer,
1976 #ifdef DBUS_HAVE_INT64
1977 /* also used for uint64 */
1980 v = int64_from_seed (seed);
1982 return _dbus_type_writer_write_basic (writer,
1983 node->klass->typecode,
1991 int64_read_value (TestTypeNode *node,
1992 DBusTypeReader *reader,
1995 #ifdef DBUS_HAVE_INT64
1996 /* also used for uint64 */
1999 check_expected_type (reader, node->klass->typecode);
2001 _dbus_type_reader_read_basic (reader,
2002 (dbus_int64_t*) &v);
2004 _dbus_assert (v == int64_from_seed (seed));
2013 int64_set_value (TestTypeNode *node,
2014 DBusTypeReader *reader,
2015 DBusTypeReader *realign_root,
2018 #ifdef DBUS_HAVE_INT64
2019 /* also used for uint64 */
2022 v = int64_from_seed (seed);
2024 return _dbus_type_reader_set_basic (reader,
2032 #define MAX_SAMPLE_STRING_LEN 10
2034 string_from_seed (char *buf,
2041 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2043 /* vary the length slightly, though we also have multiple string
2044 * value types for this, varying it here tests the set_value code
2058 v = (unsigned char) ('A' + seed);
2063 if (v < 'A' || v > 'z')
2076 string_write_value (TestTypeNode *node,
2078 DBusTypeWriter *writer,
2081 char buf[MAX_SAMPLE_STRING_LEN];
2082 const char *v_string = buf;
2084 string_from_seed (buf, node->klass->subclass_detail,
2087 return _dbus_type_writer_write_basic (writer,
2088 node->klass->typecode,
2093 string_read_value (TestTypeNode *node,
2094 DBusTypeReader *reader,
2098 char buf[MAX_SAMPLE_STRING_LEN];
2100 check_expected_type (reader, node->klass->typecode);
2102 _dbus_type_reader_read_basic (reader,
2103 (const char **) &v);
2105 string_from_seed (buf, node->klass->subclass_detail,
2108 if (strcmp (buf, v) != 0)
2110 _dbus_warn ("read string '%s' expected '%s'\n",
2112 _dbus_assert_not_reached ("test failed");
2119 string_set_value (TestTypeNode *node,
2120 DBusTypeReader *reader,
2121 DBusTypeReader *realign_root,
2124 char buf[MAX_SAMPLE_STRING_LEN];
2125 const char *v_string = buf;
2127 string_from_seed (buf, node->klass->subclass_detail,
2130 #if RECURSIVE_MARSHAL_WRITE_TRACE
2133 _dbus_type_reader_read_basic (reader, &old);
2134 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2135 v_string, strlen (v_string), old, strlen (old));
2139 return _dbus_type_reader_set_basic (reader,
2144 #define BOOL_FROM_SEED(seed) (seed % 2)
2147 bool_write_value (TestTypeNode *node,
2149 DBusTypeWriter *writer,
2154 v = BOOL_FROM_SEED (seed);
2156 return _dbus_type_writer_write_basic (writer,
2157 node->klass->typecode,
2162 bool_read_value (TestTypeNode *node,
2163 DBusTypeReader *reader,
2168 check_expected_type (reader, node->klass->typecode);
2170 _dbus_type_reader_read_basic (reader,
2171 (unsigned char*) &v);
2173 _dbus_assert (v == BOOL_FROM_SEED (seed));
2179 bool_set_value (TestTypeNode *node,
2180 DBusTypeReader *reader,
2181 DBusTypeReader *realign_root,
2186 v = BOOL_FROM_SEED (seed);
2188 return _dbus_type_reader_set_basic (reader,
2193 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2196 byte_write_value (TestTypeNode *node,
2198 DBusTypeWriter *writer,
2203 v = BYTE_FROM_SEED (seed);
2205 return _dbus_type_writer_write_basic (writer,
2206 node->klass->typecode,
2211 byte_read_value (TestTypeNode *node,
2212 DBusTypeReader *reader,
2217 check_expected_type (reader, node->klass->typecode);
2219 _dbus_type_reader_read_basic (reader,
2220 (unsigned char*) &v);
2222 _dbus_assert (v == BYTE_FROM_SEED (seed));
2229 byte_set_value (TestTypeNode *node,
2230 DBusTypeReader *reader,
2231 DBusTypeReader *realign_root,
2236 v = BYTE_FROM_SEED (seed);
2238 return _dbus_type_reader_set_basic (reader,
2244 double_from_seed (int seed)
2246 return SAMPLE_INT32 * (double) seed + 0.3;
2250 double_write_value (TestTypeNode *node,
2252 DBusTypeWriter *writer,
2257 v = double_from_seed (seed);
2259 return _dbus_type_writer_write_basic (writer,
2260 node->klass->typecode,
2265 double_read_value (TestTypeNode *node,
2266 DBusTypeReader *reader,
2272 check_expected_type (reader, node->klass->typecode);
2274 _dbus_type_reader_read_basic (reader,
2277 expected = double_from_seed (seed);
2279 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2281 #ifdef DBUS_HAVE_INT64
2282 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2284 *(dbus_uint64_t*)(char*)&expected,
2285 *(dbus_uint64_t*)(char*)&v);
2287 _dbus_assert_not_reached ("test failed");
2294 double_set_value (TestTypeNode *node,
2295 DBusTypeReader *reader,
2296 DBusTypeReader *realign_root,
2301 v = double_from_seed (seed);
2303 return _dbus_type_reader_set_basic (reader,
2308 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2310 object_path_from_seed (char *buf,
2318 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2320 v = (unsigned char) ('A' + seed);
2325 if (v < 'A' || v > 'z')
2340 object_path_write_value (TestTypeNode *node,
2342 DBusTypeWriter *writer,
2345 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2346 const char *v_string = buf;
2348 object_path_from_seed (buf, seed);
2350 return _dbus_type_writer_write_basic (writer,
2351 node->klass->typecode,
2356 object_path_read_value (TestTypeNode *node,
2357 DBusTypeReader *reader,
2361 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2363 check_expected_type (reader, node->klass->typecode);
2365 _dbus_type_reader_read_basic (reader,
2366 (const char **) &v);
2368 object_path_from_seed (buf, seed);
2370 if (strcmp (buf, v) != 0)
2372 _dbus_warn ("read object path '%s' expected '%s'\n",
2374 _dbus_assert_not_reached ("test failed");
2381 object_path_set_value (TestTypeNode *node,
2382 DBusTypeReader *reader,
2383 DBusTypeReader *realign_root,
2386 char buf[MAX_SAMPLE_OBJECT_PATH_LEN];
2387 const char *v_string = buf;
2389 object_path_from_seed (buf, seed);
2391 return _dbus_type_reader_set_basic (reader,
2396 #define MAX_SAMPLE_SIGNATURE_LEN 10
2398 signature_from_seed (char *buf,
2403 /* try to avoid ascending, descending, or alternating length to help find bugs */
2404 const char *sample_signatures[] = {
2413 s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)];
2415 for (i = 0; s[i]; i++)
2423 signature_write_value (TestTypeNode *node,
2425 DBusTypeWriter *writer,
2428 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2429 const char *v_string = buf;
2431 signature_from_seed (buf, seed);
2433 return _dbus_type_writer_write_basic (writer,
2434 node->klass->typecode,
2439 signature_read_value (TestTypeNode *node,
2440 DBusTypeReader *reader,
2444 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2446 check_expected_type (reader, node->klass->typecode);
2448 _dbus_type_reader_read_basic (reader,
2449 (const char **) &v);
2451 signature_from_seed (buf, seed);
2453 if (strcmp (buf, v) != 0)
2455 _dbus_warn ("read signature value '%s' expected '%s'\n",
2457 _dbus_assert_not_reached ("test failed");
2465 signature_set_value (TestTypeNode *node,
2466 DBusTypeReader *reader,
2467 DBusTypeReader *realign_root,
2470 char buf[MAX_SAMPLE_SIGNATURE_LEN];
2471 const char *v_string = buf;
2473 signature_from_seed (buf, seed);
2475 return _dbus_type_reader_set_basic (reader,
2481 struct_write_value (TestTypeNode *node,
2483 DBusTypeWriter *writer,
2486 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2487 DataBlockState saved;
2492 n_copies = node->klass->subclass_detail;
2494 _dbus_assert (container->children != NULL);
2496 data_block_save (block, &saved);
2498 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2504 while (i < n_copies)
2508 link = _dbus_list_get_first_link (&container->children);
2509 while (link != NULL)
2511 TestTypeNode *child = link->data;
2512 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2514 if (!node_write_value (child, block, &sub, seed + i))
2516 data_block_restore (block, &saved);
2526 if (!_dbus_type_writer_unrecurse (writer, &sub))
2528 data_block_restore (block, &saved);
2536 struct_read_or_set_value (TestTypeNode *node,
2537 DBusTypeReader *reader,
2538 DBusTypeReader *realign_root,
2541 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2546 n_copies = node->klass->subclass_detail;
2548 check_expected_type (reader, DBUS_TYPE_STRUCT);
2550 _dbus_type_reader_recurse (reader, &sub);
2553 while (i < n_copies)
2557 link = _dbus_list_get_first_link (&container->children);
2558 while (link != NULL)
2560 TestTypeNode *child = link->data;
2561 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2563 if (realign_root == NULL)
2565 if (!node_read_value (child, &sub, seed + i))
2570 if (!node_set_value (child, &sub, realign_root, seed + i))
2574 if (i == (n_copies - 1) && next == NULL)
2575 NEXT_EXPECTING_FALSE (&sub);
2577 NEXT_EXPECTING_TRUE (&sub);
2589 struct_read_value (TestTypeNode *node,
2590 DBusTypeReader *reader,
2593 return struct_read_or_set_value (node, reader, NULL, seed);
2597 struct_set_value (TestTypeNode *node,
2598 DBusTypeReader *reader,
2599 DBusTypeReader *realign_root,
2602 return struct_read_or_set_value (node, reader, realign_root, seed);
2606 struct_build_signature (TestTypeNode *node,
2609 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2614 n_copies = node->klass->subclass_detail;
2616 orig_len = _dbus_string_get_length (str);
2618 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2622 while (i < n_copies)
2626 link = _dbus_list_get_first_link (&container->children);
2627 while (link != NULL)
2629 TestTypeNode *child = link->data;
2630 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2632 if (!node_build_signature (child, str))
2641 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
2647 _dbus_string_set_length (str, orig_len);
2652 array_write_value (TestTypeNode *node,
2654 DBusTypeWriter *writer,
2657 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2658 DataBlockState saved;
2660 DBusString element_signature;
2664 TestTypeNode *child;
2666 n_copies = node->klass->subclass_detail;
2668 _dbus_assert (container->children != NULL);
2670 data_block_save (block, &saved);
2672 if (!_dbus_string_init (&element_signature))
2675 child = _dbus_list_get_first (&container->children);
2677 if (!node_build_signature (child,
2678 &element_signature))
2681 element_type = first_type_in_signature (&element_signature, 0);
2683 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
2684 &element_signature, 0,
2688 if (arrays_write_fixed_in_blocks &&
2689 _dbus_type_is_fixed (element_type) &&
2690 child->klass->write_multi)
2692 if (!node_write_multi (child, block, &sub, seed, n_copies))
2698 while (i < n_copies)
2702 link = _dbus_list_get_first_link (&container->children);
2703 while (link != NULL)
2705 TestTypeNode *child = link->data;
2706 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2708 if (!node_write_value (child, block, &sub, seed + i))
2718 if (!_dbus_type_writer_unrecurse (writer, &sub))
2721 _dbus_string_free (&element_signature);
2725 data_block_restore (block, &saved);
2726 _dbus_string_free (&element_signature);
2731 array_read_or_set_value (TestTypeNode *node,
2732 DBusTypeReader *reader,
2733 DBusTypeReader *realign_root,
2736 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2740 TestTypeNode *child;
2742 n_copies = node->klass->subclass_detail;
2744 check_expected_type (reader, DBUS_TYPE_ARRAY);
2746 child = _dbus_list_get_first (&container->children);
2750 _dbus_type_reader_recurse (reader, &sub);
2752 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
2753 _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
2754 child->klass->read_multi)
2756 if (!node_read_multi (child, &sub, seed, n_copies))
2762 while (i < n_copies)
2766 link = _dbus_list_get_first_link (&container->children);
2767 while (link != NULL)
2769 TestTypeNode *child = link->data;
2770 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2772 _dbus_assert (child->klass->typecode ==
2773 _dbus_type_reader_get_element_type (reader));
2775 if (realign_root == NULL)
2777 if (!node_read_value (child, &sub, seed + i))
2782 if (!node_set_value (child, &sub, realign_root, seed + i))
2786 if (i == (n_copies - 1) && next == NULL)
2787 NEXT_EXPECTING_FALSE (&sub);
2789 NEXT_EXPECTING_TRUE (&sub);
2803 array_read_value (TestTypeNode *node,
2804 DBusTypeReader *reader,
2807 return array_read_or_set_value (node, reader, NULL, seed);
2811 array_set_value (TestTypeNode *node,
2812 DBusTypeReader *reader,
2813 DBusTypeReader *realign_root,
2816 return array_read_or_set_value (node, reader, realign_root, seed);
2820 array_build_signature (TestTypeNode *node,
2823 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2826 orig_len = _dbus_string_get_length (str);
2828 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
2831 if (!node_build_signature (_dbus_list_get_first (&container->children),
2838 _dbus_string_set_length (str, orig_len);
2842 /* 10 is random just to add another seed that we use in the suite */
2843 #define VARIANT_SEED 10
2846 variant_write_value (TestTypeNode *node,
2848 DBusTypeWriter *writer,
2851 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2852 DataBlockState saved;
2854 DBusString content_signature;
2855 TestTypeNode *child;
2857 _dbus_assert (container->children != NULL);
2858 _dbus_assert (_dbus_list_length_is_one (&container->children));
2860 child = _dbus_list_get_first (&container->children);
2862 data_block_save (block, &saved);
2864 if (!_dbus_string_init (&content_signature))
2867 if (!node_build_signature (child,
2868 &content_signature))
2871 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
2872 &content_signature, 0,
2876 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
2879 if (!_dbus_type_writer_unrecurse (writer, &sub))
2882 _dbus_string_free (&content_signature);
2886 data_block_restore (block, &saved);
2887 _dbus_string_free (&content_signature);
2892 variant_read_or_set_value (TestTypeNode *node,
2893 DBusTypeReader *reader,
2894 DBusTypeReader *realign_root,
2897 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2899 TestTypeNode *child;
2901 _dbus_assert (container->children != NULL);
2902 _dbus_assert (_dbus_list_length_is_one (&container->children));
2904 child = _dbus_list_get_first (&container->children);
2906 check_expected_type (reader, DBUS_TYPE_VARIANT);
2908 _dbus_type_reader_recurse (reader, &sub);
2910 if (realign_root == NULL)
2912 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
2917 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
2921 NEXT_EXPECTING_FALSE (&sub);
2927 variant_read_value (TestTypeNode *node,
2928 DBusTypeReader *reader,
2931 return variant_read_or_set_value (node, reader, NULL, seed);
2935 variant_set_value (TestTypeNode *node,
2936 DBusTypeReader *reader,
2937 DBusTypeReader *realign_root,
2940 return variant_read_or_set_value (node, reader, realign_root, seed);
2944 container_destroy (TestTypeNode *node)
2946 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2949 link = _dbus_list_get_first_link (&container->children);
2950 while (link != NULL)
2952 TestTypeNode *child = link->data;
2953 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2955 node_destroy (child);
2957 _dbus_list_free_link (link);
2963 #endif /* DBUS_BUILD_TESTS */