1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-recursive-util.c Would be in dbus-marshal-recursive.c, but only used in bus/tests
4 * Copyright (C) 2004, 2005 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #ifdef DBUS_BUILD_TESTS
28 #include "dbus-marshal-recursive.h"
29 #include "dbus-marshal-basic.h"
30 #include "dbus-signature.h"
31 #include "dbus-internals.h"
35 basic_value_zero (DBusBasicValue *value)
38 #ifdef DBUS_HAVE_INT64
41 value->u64.first32 = 0;
42 value->u64.second32 = 0;
47 basic_value_equal (int type,
51 if (type == DBUS_TYPE_STRING ||
52 type == DBUS_TYPE_SIGNATURE ||
53 type == DBUS_TYPE_OBJECT_PATH)
55 return strcmp (lhs->str, rhs->str) == 0;
59 #ifdef DBUS_HAVE_INT64
60 return lhs->u64 == rhs->u64;
62 return lhs->u64.first32 == rhs->u64.first32 &&
63 lhs->u64.second32 == rhs->u64.second32;
69 equal_values_helper (DBusTypeReader *lhs,
75 lhs_type = _dbus_type_reader_get_current_type (lhs);
76 rhs_type = _dbus_type_reader_get_current_type (rhs);
78 if (lhs_type != rhs_type)
81 if (lhs_type == DBUS_TYPE_INVALID)
84 if (dbus_type_is_basic (lhs_type))
86 DBusBasicValue lhs_value;
87 DBusBasicValue rhs_value;
89 basic_value_zero (&lhs_value);
90 basic_value_zero (&rhs_value);
92 _dbus_type_reader_read_basic (lhs, &lhs_value);
93 _dbus_type_reader_read_basic (rhs, &rhs_value);
95 return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
99 DBusTypeReader lhs_sub;
100 DBusTypeReader rhs_sub;
102 _dbus_type_reader_recurse (lhs, &lhs_sub);
103 _dbus_type_reader_recurse (rhs, &rhs_sub);
105 return equal_values_helper (&lhs_sub, &rhs_sub);
110 * See whether the two readers point to identical data blocks.
112 * @param lhs reader 1
113 * @param rhs reader 2
114 * @returns #TRUE if the data blocks have the same values
117 _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
118 const DBusTypeReader *rhs)
120 DBusTypeReader copy_lhs = *lhs;
121 DBusTypeReader copy_rhs = *rhs;
123 return equal_values_helper (©_lhs, ©_rhs);
127 #include "dbus-test.h"
128 #include "dbus-list.h"
132 /* Whether to do the OOM stuff (only with other expensive tests) */
133 #define TEST_OOM_HANDLING 0
134 /* We do start offset 0 through 9, to get various alignment cases. Still this
135 * obviously makes the test suite run 10x as slow.
137 #define MAX_INITIAL_OFFSET 9
139 /* Largest iteration count to test copying, realignment,
140 * etc. with. i.e. we only test this stuff with some of the smaller
143 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
149 DBusString signature;
159 #define N_FENCE_BYTES 5
160 #define FENCE_BYTES_STR "abcde"
161 #define INITIAL_PADDING_BYTE '\0'
164 data_block_init (DataBlock *block,
168 if (!_dbus_string_init (&block->signature))
171 if (!_dbus_string_init (&block->body))
173 _dbus_string_free (&block->signature);
177 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
178 INITIAL_PADDING_BYTE) ||
179 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
180 INITIAL_PADDING_BYTE) ||
181 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
182 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
184 _dbus_string_free (&block->signature);
185 _dbus_string_free (&block->body);
189 block->byte_order = byte_order;
190 block->initial_offset = initial_offset;
196 data_block_save (DataBlock *block,
197 DataBlockState *state)
199 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
200 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
204 data_block_restore (DataBlock *block,
205 DataBlockState *state)
207 _dbus_string_delete (&block->signature,
208 state->saved_sig_len,
209 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
210 _dbus_string_delete (&block->body,
211 state->saved_body_len,
212 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
216 data_block_verify (DataBlock *block)
218 if (!_dbus_string_ends_with_c_str (&block->signature,
223 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
227 _dbus_verbose_bytes_of_string (&block->signature,
229 _dbus_string_get_length (&block->signature) - offset);
230 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
232 if (!_dbus_string_ends_with_c_str (&block->body,
237 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
241 _dbus_verbose_bytes_of_string (&block->body,
243 _dbus_string_get_length (&block->body) - offset);
244 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
247 _dbus_assert (_dbus_string_validate_nul (&block->signature,
248 0, block->initial_offset));
249 _dbus_assert (_dbus_string_validate_nul (&block->body,
250 0, block->initial_offset));
254 data_block_free (DataBlock *block)
256 data_block_verify (block);
258 _dbus_string_free (&block->signature);
259 _dbus_string_free (&block->body);
263 data_block_reset (DataBlock *block)
265 data_block_verify (block);
267 _dbus_string_delete (&block->signature,
268 block->initial_offset,
269 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
270 _dbus_string_delete (&block->body,
271 block->initial_offset,
272 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
274 data_block_verify (block);
278 data_block_init_reader_writer (DataBlock *block,
279 DBusTypeReader *reader,
280 DBusTypeWriter *writer)
283 _dbus_type_reader_init (reader,
286 block->initial_offset,
288 block->initial_offset);
291 _dbus_type_writer_init (writer,
294 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
296 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
300 real_check_expected_type (DBusTypeReader *reader,
302 const char *funcname,
307 t = _dbus_type_reader_get_current_type (reader);
311 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
312 _dbus_type_to_string (t),
313 _dbus_type_to_string (expected),
316 _dbus_assert_not_reached ("read wrong type");
320 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
322 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
324 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
325 _DBUS_FUNCTION_NAME, __LINE__); \
326 _dbus_assert_not_reached ("test failed"); \
330 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
332 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
333 _DBUS_FUNCTION_NAME, __LINE__); \
334 _dbus_assert_not_reached ("test failed"); \
336 check_expected_type (reader, DBUS_TYPE_INVALID); \
339 typedef struct TestTypeNode TestTypeNode;
340 typedef struct TestTypeNodeClass TestTypeNodeClass;
341 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
342 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
346 const TestTypeNodeClass *klass;
349 struct TestTypeNodeContainer
355 struct TestTypeNodeClass
361 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
363 dbus_bool_t (* construct) (TestTypeNode *node);
364 void (* destroy) (TestTypeNode *node);
366 dbus_bool_t (* write_value) (TestTypeNode *node,
368 DBusTypeWriter *writer,
370 dbus_bool_t (* read_value) (TestTypeNode *node,
371 DBusTypeReader *reader,
373 dbus_bool_t (* set_value) (TestTypeNode *node,
374 DBusTypeReader *reader,
375 DBusTypeReader *realign_root,
377 dbus_bool_t (* build_signature) (TestTypeNode *node,
379 dbus_bool_t (* write_multi) (TestTypeNode *node,
381 DBusTypeWriter *writer,
384 dbus_bool_t (* read_multi) (TestTypeNode *node,
385 DBusTypeReader *reader,
390 struct TestTypeNodeContainerClass
392 TestTypeNodeClass base;
395 /* FIXME this could be chilled out substantially by unifying
396 * the basic types into basic_write_value/basic_read_value
397 * and by merging read_value and set_value into one function
398 * taking a flag argument.
400 static dbus_bool_t int16_write_value (TestTypeNode *node,
402 DBusTypeWriter *writer,
404 static dbus_bool_t int16_read_value (TestTypeNode *node,
405 DBusTypeReader *reader,
407 static dbus_bool_t int16_set_value (TestTypeNode *node,
408 DBusTypeReader *reader,
409 DBusTypeReader *realign_root,
411 static dbus_bool_t int16_write_multi (TestTypeNode *node,
413 DBusTypeWriter *writer,
416 static dbus_bool_t int16_read_multi (TestTypeNode *node,
417 DBusTypeReader *reader,
420 static dbus_bool_t int32_write_value (TestTypeNode *node,
422 DBusTypeWriter *writer,
424 static dbus_bool_t int32_read_value (TestTypeNode *node,
425 DBusTypeReader *reader,
427 static dbus_bool_t int32_set_value (TestTypeNode *node,
428 DBusTypeReader *reader,
429 DBusTypeReader *realign_root,
431 static dbus_bool_t int32_write_multi (TestTypeNode *node,
433 DBusTypeWriter *writer,
436 static dbus_bool_t int32_read_multi (TestTypeNode *node,
437 DBusTypeReader *reader,
440 static dbus_bool_t int64_write_value (TestTypeNode *node,
442 DBusTypeWriter *writer,
444 static dbus_bool_t int64_read_value (TestTypeNode *node,
445 DBusTypeReader *reader,
447 static dbus_bool_t int64_set_value (TestTypeNode *node,
448 DBusTypeReader *reader,
449 DBusTypeReader *realign_root,
451 static dbus_bool_t string_write_value (TestTypeNode *node,
453 DBusTypeWriter *writer,
455 static dbus_bool_t string_read_value (TestTypeNode *node,
456 DBusTypeReader *reader,
458 static dbus_bool_t string_set_value (TestTypeNode *node,
459 DBusTypeReader *reader,
460 DBusTypeReader *realign_root,
462 static dbus_bool_t bool_write_value (TestTypeNode *node,
464 DBusTypeWriter *writer,
466 static dbus_bool_t bool_read_value (TestTypeNode *node,
467 DBusTypeReader *reader,
469 static dbus_bool_t bool_set_value (TestTypeNode *node,
470 DBusTypeReader *reader,
471 DBusTypeReader *realign_root,
473 static dbus_bool_t byte_write_value (TestTypeNode *node,
475 DBusTypeWriter *writer,
477 static dbus_bool_t byte_read_value (TestTypeNode *node,
478 DBusTypeReader *reader,
480 static dbus_bool_t byte_set_value (TestTypeNode *node,
481 DBusTypeReader *reader,
482 DBusTypeReader *realign_root,
484 static dbus_bool_t double_write_value (TestTypeNode *node,
486 DBusTypeWriter *writer,
488 static dbus_bool_t double_read_value (TestTypeNode *node,
489 DBusTypeReader *reader,
491 static dbus_bool_t double_set_value (TestTypeNode *node,
492 DBusTypeReader *reader,
493 DBusTypeReader *realign_root,
495 static dbus_bool_t object_path_write_value (TestTypeNode *node,
497 DBusTypeWriter *writer,
499 static dbus_bool_t object_path_read_value (TestTypeNode *node,
500 DBusTypeReader *reader,
502 static dbus_bool_t object_path_set_value (TestTypeNode *node,
503 DBusTypeReader *reader,
504 DBusTypeReader *realign_root,
506 static dbus_bool_t signature_write_value (TestTypeNode *node,
508 DBusTypeWriter *writer,
510 static dbus_bool_t signature_read_value (TestTypeNode *node,
511 DBusTypeReader *reader,
513 static dbus_bool_t signature_set_value (TestTypeNode *node,
514 DBusTypeReader *reader,
515 DBusTypeReader *realign_root,
517 static dbus_bool_t struct_write_value (TestTypeNode *node,
519 DBusTypeWriter *writer,
521 static dbus_bool_t struct_read_value (TestTypeNode *node,
522 DBusTypeReader *reader,
524 static dbus_bool_t struct_set_value (TestTypeNode *node,
525 DBusTypeReader *reader,
526 DBusTypeReader *realign_root,
528 static dbus_bool_t struct_build_signature (TestTypeNode *node,
530 static dbus_bool_t dict_write_value (TestTypeNode *node,
532 DBusTypeWriter *writer,
534 static dbus_bool_t dict_read_value (TestTypeNode *node,
535 DBusTypeReader *reader,
537 static dbus_bool_t dict_set_value (TestTypeNode *node,
538 DBusTypeReader *reader,
539 DBusTypeReader *realign_root,
541 static dbus_bool_t dict_build_signature (TestTypeNode *node,
543 static dbus_bool_t array_write_value (TestTypeNode *node,
545 DBusTypeWriter *writer,
547 static dbus_bool_t array_read_value (TestTypeNode *node,
548 DBusTypeReader *reader,
550 static dbus_bool_t array_set_value (TestTypeNode *node,
551 DBusTypeReader *reader,
552 DBusTypeReader *realign_root,
554 static dbus_bool_t array_build_signature (TestTypeNode *node,
556 static dbus_bool_t variant_write_value (TestTypeNode *node,
558 DBusTypeWriter *writer,
560 static dbus_bool_t variant_read_value (TestTypeNode *node,
561 DBusTypeReader *reader,
563 static dbus_bool_t variant_set_value (TestTypeNode *node,
564 DBusTypeReader *reader,
565 DBusTypeReader *realign_root,
567 static void container_destroy (TestTypeNode *node);
571 static const TestTypeNodeClass int16_class = {
573 sizeof (TestTypeNode),
585 static const TestTypeNodeClass uint16_class = {
587 sizeof (TestTypeNode),
591 int16_write_value, /* recycle from int16 */
592 int16_read_value, /* recycle from int16 */
593 int16_set_value, /* recycle from int16 */
595 int16_write_multi, /* recycle from int16 */
596 int16_read_multi /* recycle from int16 */
599 static const TestTypeNodeClass int32_class = {
601 sizeof (TestTypeNode),
613 static const TestTypeNodeClass uint32_class = {
615 sizeof (TestTypeNode),
619 int32_write_value, /* recycle from int32 */
620 int32_read_value, /* recycle from int32 */
621 int32_set_value, /* recycle from int32 */
623 int32_write_multi, /* recycle from int32 */
624 int32_read_multi /* recycle from int32 */
627 static const TestTypeNodeClass int64_class = {
629 sizeof (TestTypeNode),
641 static const TestTypeNodeClass uint64_class = {
643 sizeof (TestTypeNode),
647 int64_write_value, /* recycle from int64 */
648 int64_read_value, /* recycle from int64 */
649 int64_set_value, /* recycle from int64 */
655 static const TestTypeNodeClass string_0_class = {
657 sizeof (TestTypeNode),
658 0, /* string length */
669 static const TestTypeNodeClass string_1_class = {
671 sizeof (TestTypeNode),
672 1, /* string length */
683 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
684 static const TestTypeNodeClass string_3_class = {
686 sizeof (TestTypeNode),
687 3, /* string length */
698 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
699 static const TestTypeNodeClass string_8_class = {
701 sizeof (TestTypeNode),
702 8, /* string length */
713 static const TestTypeNodeClass bool_class = {
715 sizeof (TestTypeNode),
727 static const TestTypeNodeClass byte_class = {
729 sizeof (TestTypeNode),
741 static const TestTypeNodeClass double_class = {
743 sizeof (TestTypeNode),
755 static const TestTypeNodeClass object_path_class = {
756 DBUS_TYPE_OBJECT_PATH,
757 sizeof (TestTypeNode),
761 object_path_write_value,
762 object_path_read_value,
763 object_path_set_value,
769 static const TestTypeNodeClass signature_class = {
771 sizeof (TestTypeNode),
775 signature_write_value,
776 signature_read_value,
783 static const TestTypeNodeClass struct_1_class = {
785 sizeof (TestTypeNodeContainer),
786 1, /* number of times children appear as fields */
792 struct_build_signature,
797 static const TestTypeNodeClass struct_2_class = {
799 sizeof (TestTypeNodeContainer),
800 2, /* number of times children appear as fields */
806 struct_build_signature,
811 static const TestTypeNodeClass dict_1_class = {
812 DBUS_TYPE_ARRAY, /* this is correct, a dict is an array of dict entry */
813 sizeof (TestTypeNodeContainer),
814 1, /* number of entries */
820 dict_build_signature,
825 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
827 static const TestTypeNodeClass array_0_class = {
829 sizeof (TestTypeNodeContainer),
830 0, /* number of array elements */
836 array_build_signature,
841 static const TestTypeNodeClass array_1_class = {
843 sizeof (TestTypeNodeContainer),
844 1, /* number of array elements */
850 array_build_signature,
855 static const TestTypeNodeClass array_2_class = {
857 sizeof (TestTypeNodeContainer),
858 2, /* number of array elements */
864 array_build_signature,
869 static const TestTypeNodeClass array_9_class = {
871 sizeof (TestTypeNodeContainer),
872 9, /* number of array elements */
878 array_build_signature,
883 static const TestTypeNodeClass variant_class = {
885 sizeof (TestTypeNodeContainer),
897 static const TestTypeNodeClass* const
915 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
917 static const TestTypeNodeClass* const
918 container_nodes[] = {
925 &dict_1_class /* last since we want struct and array before it */
926 /* array_9_class is omitted on purpose, it's too slow;
927 * we only use it in one hardcoded test below
930 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
933 node_new (const TestTypeNodeClass *klass)
937 node = dbus_malloc0 (klass->instance_size);
943 if (klass->construct)
945 if (!(* klass->construct) (node))
956 node_destroy (TestTypeNode *node)
958 if (node->klass->destroy)
959 (* node->klass->destroy) (node);
964 node_write_value (TestTypeNode *node,
966 DBusTypeWriter *writer,
971 retval = (* node->klass->write_value) (node, block, writer, seed);
974 /* Handy to see where things break, but too expensive to do all the time */
975 data_block_verify (block);
982 node_read_value (TestTypeNode *node,
983 DBusTypeReader *reader,
986 DBusTypeReader restored;
988 if (!(* node->klass->read_value) (node, reader, seed))
994 /* Warning: if this one fails due to OOM, it has side effects (can
995 * modify only some of the sub-values). OK in a test suite, but we
996 * never do this in real code.
999 node_set_value (TestTypeNode *node,
1000 DBusTypeReader *reader,
1001 DBusTypeReader *realign_root,
1004 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
1011 node_build_signature (TestTypeNode *node,
1014 if (node->klass->build_signature)
1015 return (* node->klass->build_signature) (node, str);
1017 return _dbus_string_append_byte (str, node->klass->typecode);
1021 node_append_child (TestTypeNode *node,
1022 TestTypeNode *child)
1024 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1026 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
1028 if (!_dbus_list_append (&container->children, child))
1029 _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 */
1035 node_write_multi (TestTypeNode *node,
1037 DBusTypeWriter *writer,
1043 _dbus_assert (node->klass->write_multi != NULL);
1044 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
1047 /* Handy to see where things break, but too expensive to do all the time */
1048 data_block_verify (block);
1055 node_read_multi (TestTypeNode *node,
1056 DBusTypeReader *reader,
1060 _dbus_assert (node->klass->read_multi != NULL);
1062 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1068 static int n_iterations_completed_total = 0;
1069 static int n_iterations_completed_this_test = 0;
1070 static int n_iterations_expected_this_test = 0;
1074 const DBusString *signature;
1077 TestTypeNode **nodes;
1079 } NodeIterationData;
1082 run_test_copy (NodeIterationData *nid)
1087 DBusTypeReader reader;
1088 DBusTypeWriter writer;
1090 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1096 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1099 data_block_init_reader_writer (src, &reader, NULL);
1100 data_block_init_reader_writer (&dest, NULL, &writer);
1102 /* DBusTypeWriter assumes it's writing into an existing signature,
1103 * so doesn't add nul on its own. We have to do that.
1105 if (!_dbus_string_insert_byte (&dest.signature,
1106 dest.initial_offset, '\0'))
1109 if (!_dbus_type_writer_write_reader (&writer, &reader))
1112 /* Data blocks should now be identical */
1113 if (!_dbus_string_equal (&src->signature, &dest.signature))
1115 _dbus_verbose ("SOURCE\n");
1116 _dbus_verbose_bytes_of_string (&src->signature, 0,
1117 _dbus_string_get_length (&src->signature));
1118 _dbus_verbose ("DEST\n");
1119 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1120 _dbus_string_get_length (&dest.signature));
1121 _dbus_assert_not_reached ("signatures did not match");
1124 if (!_dbus_string_equal (&src->body, &dest.body))
1126 _dbus_verbose ("SOURCE\n");
1127 _dbus_verbose_bytes_of_string (&src->body, 0,
1128 _dbus_string_get_length (&src->body));
1129 _dbus_verbose ("DEST\n");
1130 _dbus_verbose_bytes_of_string (&dest.body, 0,
1131 _dbus_string_get_length (&dest.body));
1132 _dbus_assert_not_reached ("bodies did not match");
1139 data_block_free (&dest);
1145 run_test_values_only_write (NodeIterationData *nid)
1147 DBusTypeReader reader;
1148 DBusTypeWriter writer;
1153 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1157 data_block_reset (nid->block);
1159 sig_len = _dbus_string_get_length (nid->signature);
1161 _dbus_type_writer_init_values_only (&writer,
1162 nid->block->byte_order,
1165 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1166 _dbus_type_reader_init (&reader,
1167 nid->block->byte_order,
1170 nid->block->initial_offset);
1173 while (i < nid->n_nodes)
1175 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1181 /* if we wrote any typecodes then this would fail */
1182 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1184 /* But be sure we wrote out the values correctly */
1186 while (i < nid->n_nodes)
1188 if (!node_read_value (nid->nodes[i], &reader, i))
1191 if (i + 1 == nid->n_nodes)
1192 NEXT_EXPECTING_FALSE (&reader);
1194 NEXT_EXPECTING_TRUE (&reader);
1202 data_block_reset (nid->block);
1206 /* offset the seed for setting, so we set different numbers than
1207 * we originally wrote. Don't offset by a huge number since in
1208 * some cases it's value = possibilities[seed % n_possibilities]
1209 * and we don't want to wrap around. bool_from_seed
1210 * is just seed % 2 even.
1214 run_test_set_values (NodeIterationData *nid)
1216 DBusTypeReader reader;
1217 DBusTypeReader realign_root;
1221 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1225 data_block_init_reader_writer (nid->block,
1228 realign_root = reader;
1231 while (i < nid->n_nodes)
1233 if (!node_set_value (nid->nodes[i],
1234 &reader, &realign_root,
1238 if (i + 1 == nid->n_nodes)
1239 NEXT_EXPECTING_FALSE (&reader);
1241 NEXT_EXPECTING_TRUE (&reader);
1246 /* Check that the new values were set */
1248 reader = realign_root;
1251 while (i < nid->n_nodes)
1253 if (!node_read_value (nid->nodes[i], &reader,
1257 if (i + 1 == nid->n_nodes)
1258 NEXT_EXPECTING_FALSE (&reader);
1260 NEXT_EXPECTING_TRUE (&reader);
1272 run_test_delete_values (NodeIterationData *nid)
1274 DBusTypeReader reader;
1278 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1282 data_block_init_reader_writer (nid->block,
1285 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1287 /* Right now, deleting only works on array elements. We delete
1288 * all array elements, and then verify that there aren't any
1291 if (t == DBUS_TYPE_ARRAY)
1293 DBusTypeReader array;
1297 _dbus_type_reader_recurse (&reader, &array);
1299 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1302 _dbus_type_reader_next (&array);
1305 /* reset to start of array */
1306 _dbus_type_reader_recurse (&reader, &array);
1307 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1308 reader.value_pos, array.value_pos, array.u.array.start_pos);
1309 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1311 /* We don't want to always delete from the same part of the array. */
1312 static int cycle = 0;
1315 _dbus_assert (n_elements > 0);
1318 if (elem == 3 || elem >= n_elements) /* end of array */
1319 elem = n_elements - 1;
1321 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1322 elem, n_elements, _dbus_type_to_string (elem_type),
1323 cycle, reader.value_pos, array.value_pos);
1326 if (!_dbus_type_reader_next (&array))
1327 _dbus_assert_not_reached ("should have had another element\n");
1331 if (!_dbus_type_reader_delete (&array, &reader))
1337 _dbus_type_reader_recurse (&reader, &array);
1345 _dbus_type_reader_next (&reader);
1348 /* Check that there are no array elements left */
1349 data_block_init_reader_writer (nid->block,
1352 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1354 _dbus_type_reader_next (&reader);
1364 run_test_nodes_iteration (void *data)
1366 NodeIterationData *nid = data;
1367 DBusTypeReader reader;
1368 DBusTypeWriter writer;
1373 * 1. write the value
1374 * 2. strcmp-compare with the signature we built
1376 * 4. type-iterate the signature and the value and see if they are the same type-wise
1380 data_block_init_reader_writer (nid->block,
1383 /* DBusTypeWriter assumes it's writing into an existing signature,
1384 * so doesn't add nul on its own. We have to do that.
1386 if (!_dbus_string_insert_byte (&nid->block->signature,
1387 nid->type_offset, '\0'))
1391 while (i < nid->n_nodes)
1393 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1399 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1400 &nid->block->signature, nid->type_offset))
1402 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1403 _dbus_string_get_const_data (nid->signature),
1404 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1406 _dbus_assert_not_reached ("wrong signature");
1410 while (i < nid->n_nodes)
1412 if (!node_read_value (nid->nodes[i], &reader, i))
1415 if (i + 1 == nid->n_nodes)
1416 NEXT_EXPECTING_FALSE (&reader);
1418 NEXT_EXPECTING_TRUE (&reader);
1423 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1425 /* this set values test uses code from copy and
1426 * values_only_write so would ideally be last so you get a
1427 * simpler test case for problems with copying or values_only
1428 * writing; but it also needs an already-written DataBlock so it
1429 * has to go first. Comment it out if it breaks, and see if the
1430 * later tests also break - debug them first if so.
1432 if (!run_test_set_values (nid))
1435 if (!run_test_delete_values (nid))
1438 if (!run_test_copy (nid))
1441 if (!run_test_values_only_write (nid))
1445 /* FIXME type-iterate both signature and value and compare the resulting
1446 * tree to the node tree perhaps
1453 data_block_reset (nid->block);
1459 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1461 const DBusString *signature,
1466 NodeIterationData nid;
1468 if (!data_block_init (&block, byte_order, initial_offset))
1469 _dbus_assert_not_reached ("no memory");
1471 nid.signature = signature;
1473 nid.type_offset = initial_offset;
1475 nid.n_nodes = n_nodes;
1477 if (TEST_OOM_HANDLING &&
1478 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1480 _dbus_test_oom_handling ("running test node",
1481 run_test_nodes_iteration,
1486 if (!run_test_nodes_iteration (&nid))
1487 _dbus_assert_not_reached ("no memory");
1490 data_block_free (&block);
1494 run_test_nodes (TestTypeNode **nodes,
1498 DBusString signature;
1500 if (!_dbus_string_init (&signature))
1501 _dbus_assert_not_reached ("no memory");
1506 if (! node_build_signature (nodes[i], &signature))
1507 _dbus_assert_not_reached ("no memory");
1512 _dbus_verbose (">>> test nodes with signature '%s'\n",
1513 _dbus_string_get_const_data (&signature));
1516 while (i <= MAX_INITIAL_OFFSET)
1518 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1519 DBUS_LITTLE_ENDIAN, i);
1520 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1521 DBUS_BIG_ENDIAN, i);
1526 n_iterations_completed_this_test += 1;
1527 n_iterations_completed_total += 1;
1529 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1531 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1532 n_iterations_completed_this_test,
1533 n_iterations_completed_total);
1535 /* this happens to turn out well with mod == 1 */
1536 else if ((n_iterations_completed_this_test %
1537 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1539 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1542 _dbus_string_free (&signature);
1545 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1547 static TestTypeNode*
1548 value_generator (int *ip)
1551 const TestTypeNodeClass *child_klass;
1552 const TestTypeNodeClass *container_klass;
1553 TestTypeNode *child;
1556 _dbus_assert (i <= N_VALUES);
1562 else if (i < N_BASICS)
1564 node = node_new (basic_nodes[i]);
1568 /* imagine an array:
1569 * container 0 of basic 0
1570 * container 0 of basic 1
1571 * container 0 of basic 2
1572 * container 1 of basic 0
1573 * container 1 of basic 1
1574 * container 1 of basic 2
1578 container_klass = container_nodes[i / N_BASICS];
1579 child_klass = basic_nodes[i % N_BASICS];
1581 node = node_new (container_klass);
1582 child = node_new (child_klass);
1584 node_append_child (node, child);
1587 *ip += 1; /* increment the generator */
1593 build_body (TestTypeNode **nodes,
1596 DBusString *signature,
1601 DBusTypeReader reader;
1602 DBusTypeWriter writer;
1607 if (! node_build_signature (nodes[i], signature))
1608 _dbus_assert_not_reached ("no memory");
1613 if (!data_block_init (&block, byte_order, 0))
1614 _dbus_assert_not_reached ("no memory");
1616 data_block_init_reader_writer (&block,
1619 /* DBusTypeWriter assumes it's writing into an existing signature,
1620 * so doesn't add nul on its own. We have to do that.
1622 if (!_dbus_string_insert_byte (&block.signature,
1624 _dbus_assert_not_reached ("no memory");
1629 if (!node_write_value (nodes[i], &block, &writer, i))
1630 _dbus_assert_not_reached ("no memory");
1635 if (!_dbus_string_copy_len (&block.body, 0,
1636 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1638 _dbus_assert_not_reached ("oom");
1640 data_block_free (&block);
1644 dbus_internal_do_not_use_generate_bodies (int sequence,
1646 DBusString *signature,
1649 TestTypeNode *nodes[1];
1653 nodes[0] = value_generator (&sequence);
1655 if (nodes[0] == NULL)
1660 build_body (nodes, n_nodes, byte_order, signature, body);
1666 node_destroy (nodes[i]);
1674 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1678 TestTypeNode *container;
1679 TestTypeNode *child;
1682 root = node_new (container_klass);
1684 for (i = 1; i < n_nested; i++)
1686 child = node_new (container_klass);
1687 node_append_child (container, child);
1691 /* container should now be the most-nested container */
1694 while ((child = value_generator (&i)))
1696 node_append_child (container, child);
1698 run_test_nodes (&root, 1);
1700 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1701 node_destroy (child);
1704 node_destroy (root);
1708 start_next_test (const char *format,
1711 n_iterations_completed_this_test = 0;
1712 n_iterations_expected_this_test = expected;
1714 fprintf (stderr, ">>> >>> ");
1715 fprintf (stderr, format,
1716 n_iterations_expected_this_test);
1720 make_and_run_test_nodes (void)
1724 /* We try to do this in order of "complicatedness" so that test
1725 * failures tend to show up in the simplest test case that
1726 * demonstrates the failure. There are also some tests that run
1727 * more than once for this reason, first while going through simple
1728 * cases, second while going through a broader range of complex
1731 /* Each basic node. The basic nodes should include:
1733 * - each fixed-size type (in such a way that it has different values each time,
1734 * so we can tell if we mix two of them up)
1735 * - strings of various lengths
1739 /* Each container node. The container nodes should include:
1741 * struct with 1 and 2 copies of the contained item
1742 * array with 0, 1, 2 copies of the contained item
1745 /* Let a "value" be a basic node, or a container containing a single basic node.
1746 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1747 * When iterating through all values to make combinations, do the basic types
1748 * first and the containers second.
1750 /* Each item is shown with its number of iterations to complete so
1751 * we can keep a handle on this unit test
1754 /* FIXME test just an empty body, no types at all */
1756 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1760 while ((node = value_generator (&i)))
1762 run_test_nodes (&node, 1);
1764 node_destroy (node);
1768 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1769 arrays_write_fixed_in_blocks = TRUE;
1773 while ((node = value_generator (&i)))
1775 run_test_nodes (&node, 1);
1777 node_destroy (node);
1780 arrays_write_fixed_in_blocks = FALSE;
1782 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1784 TestTypeNode *nodes[N_VALUES];
1787 while ((nodes[i] = value_generator (&i)))
1790 run_test_nodes (nodes, N_VALUES);
1792 for (i = 0; i < N_VALUES; i++)
1793 node_destroy (nodes[i]);
1796 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1797 N_VALUES * N_VALUES);
1799 TestTypeNode *nodes[2];
1802 while ((nodes[0] = value_generator (&i)))
1805 while ((nodes[1] = value_generator (&j)))
1807 run_test_nodes (nodes, 2);
1809 node_destroy (nodes[1]);
1812 node_destroy (nodes[0]);
1816 start_next_test ("Each container containing each value %d iterations\n",
1817 N_CONTAINERS * N_VALUES);
1818 for (i = 0; i < N_CONTAINERS; i++)
1820 const TestTypeNodeClass *container_klass = container_nodes[i];
1822 make_and_run_values_inside_container (container_klass, 1);
1825 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1826 N_CONTAINERS * N_VALUES);
1827 arrays_write_fixed_in_blocks = TRUE;
1828 for (i = 0; i < N_CONTAINERS; i++)
1830 const TestTypeNodeClass *container_klass = container_nodes[i];
1832 make_and_run_values_inside_container (container_klass, 1);
1834 arrays_write_fixed_in_blocks = FALSE;
1836 start_next_test ("Each container of same container of each value %d iterations\n",
1837 N_CONTAINERS * N_VALUES);
1838 for (i = 0; i < N_CONTAINERS; i++)
1840 const TestTypeNodeClass *container_klass = container_nodes[i];
1842 make_and_run_values_inside_container (container_klass, 2);
1845 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1846 N_CONTAINERS * N_VALUES);
1847 for (i = 0; i < N_CONTAINERS; i++)
1849 const TestTypeNodeClass *container_klass = container_nodes[i];
1851 make_and_run_values_inside_container (container_klass, 3);
1854 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1855 N_VALUES * N_VALUES);
1857 TestTypeNode *val1, *val2;
1860 node = node_new (&struct_1_class);
1863 while ((val1 = value_generator (&i)))
1866 while ((val2 = value_generator (&j)))
1868 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1870 node_append_child (node, val1);
1871 node_append_child (node, val2);
1873 run_test_nodes (&node, 1);
1875 _dbus_list_clear (&container->children);
1876 node_destroy (val2);
1878 node_destroy (val1);
1880 node_destroy (node);
1883 start_next_test ("All values in one big struct %d iteration\n",
1887 TestTypeNode *child;
1889 node = node_new (&struct_1_class);
1892 while ((child = value_generator (&i)))
1893 node_append_child (node, child);
1895 run_test_nodes (&node, 1);
1897 node_destroy (node);
1900 start_next_test ("Each value in a large array %d iterations\n",
1906 node = node_new (&array_9_class);
1909 while ((val = value_generator (&i)))
1911 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1913 node_append_child (node, val);
1915 run_test_nodes (&node, 1);
1917 _dbus_list_clear (&container->children);
1921 node_destroy (node);
1924 start_next_test ("Each container of each container of each value %d iterations\n",
1925 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1926 for (i = 0; i < N_CONTAINERS; i++)
1928 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1929 TestTypeNode *outer_container = node_new (outer_container_klass);
1931 for (j = 0; j < N_CONTAINERS; j++)
1933 TestTypeNode *child;
1934 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1935 TestTypeNode *inner_container = node_new (inner_container_klass);
1937 node_append_child (outer_container, inner_container);
1940 while ((child = value_generator (&m)))
1942 node_append_child (inner_container, child);
1944 run_test_nodes (&outer_container, 1);
1946 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1947 node_destroy (child);
1949 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1950 node_destroy (inner_container);
1952 node_destroy (outer_container);
1955 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1956 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1957 for (i = 0; i < N_CONTAINERS; i++)
1959 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1960 TestTypeNode *outer_container = node_new (outer_container_klass);
1962 for (j = 0; j < N_CONTAINERS; j++)
1964 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1965 TestTypeNode *inner_container = node_new (inner_container_klass);
1967 node_append_child (outer_container, inner_container);
1969 for (k = 0; k < N_CONTAINERS; k++)
1971 TestTypeNode *child;
1972 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1973 TestTypeNode *center_container = node_new (center_container_klass);
1975 node_append_child (inner_container, center_container);
1978 while ((child = value_generator (&m)))
1980 node_append_child (center_container, child);
1982 run_test_nodes (&outer_container, 1);
1984 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1985 node_destroy (child);
1987 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1988 node_destroy (center_container);
1990 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1991 node_destroy (inner_container);
1993 node_destroy (outer_container);
1997 /* This one takes a really long time, so comment it out for now */
1998 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
1999 N_VALUES * N_VALUES * N_VALUES);
2001 TestTypeNode *nodes[3];
2004 while ((nodes[0] = value_generator (&i)))
2007 while ((nodes[1] = value_generator (&j)))
2010 while ((nodes[2] = value_generator (&k)))
2012 run_test_nodes (nodes, 3);
2014 node_destroy (nodes[2]);
2016 node_destroy (nodes[1]);
2018 node_destroy (nodes[0]);
2021 #endif /* #if 0 expensive test */
2023 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
2024 n_iterations_completed_total);
2025 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
2026 MAX_INITIAL_OFFSET);
2027 fprintf (stderr, "out of memory handling %s tested\n",
2028 TEST_OOM_HANDLING ? "was" : "was not");
2032 _dbus_marshal_recursive_test (void)
2034 make_and_run_test_nodes ();
2042 * Implementations of each type node class
2047 #define MAX_MULTI_COUNT 5
2049 #define SAMPLE_INT16 1234
2050 #define SAMPLE_INT16_ALTERNATE 6785
2052 int16_from_seed (int seed)
2054 /* Generate an integer value that's predictable from seed. We could
2055 * just use seed itself, but that would only ever touch one byte of
2056 * the int so would miss some kinds of bug.
2060 v = 42; /* just to quiet compiler afaik */
2067 v = SAMPLE_INT16_ALTERNATE;
2073 v = _DBUS_INT16_MAX;
2081 v *= seed; /* wraps around eventually, which is fine */
2087 int16_write_value (TestTypeNode *node,
2089 DBusTypeWriter *writer,
2092 /* also used for uint16 */
2095 v = int16_from_seed (seed);
2097 return _dbus_type_writer_write_basic (writer,
2098 node->klass->typecode,
2103 int16_read_value (TestTypeNode *node,
2104 DBusTypeReader *reader,
2107 /* also used for uint16 */
2110 check_expected_type (reader, node->klass->typecode);
2112 _dbus_type_reader_read_basic (reader,
2113 (dbus_int16_t*) &v);
2115 _dbus_assert (v == int16_from_seed (seed));
2121 int16_set_value (TestTypeNode *node,
2122 DBusTypeReader *reader,
2123 DBusTypeReader *realign_root,
2126 /* also used for uint16 */
2129 v = int16_from_seed (seed);
2131 return _dbus_type_reader_set_basic (reader,
2137 int16_write_multi (TestTypeNode *node,
2139 DBusTypeWriter *writer,
2143 /* also used for uint16 */
2144 dbus_int16_t values[MAX_MULTI_COUNT];
2145 dbus_int16_t *v_ARRAY_INT16 = values;
2148 for (i = 0; i < count; ++i)
2149 values[i] = int16_from_seed (seed + i);
2151 return _dbus_type_writer_write_fixed_multi (writer,
2152 node->klass->typecode,
2153 &v_ARRAY_INT16, count);
2157 int16_read_multi (TestTypeNode *node,
2158 DBusTypeReader *reader,
2162 /* also used for uint16 */
2163 dbus_int16_t *values;
2167 check_expected_type (reader, node->klass->typecode);
2169 _dbus_type_reader_read_fixed_multi (reader,
2173 if (n_elements != count)
2174 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2175 _dbus_assert (n_elements == count);
2177 for (i = 0; i < count; i++)
2178 _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
2179 (const unsigned char*)values + (i * 2))) ==
2180 int16_from_seed (seed + i));
2186 #define SAMPLE_INT32 12345678
2187 #define SAMPLE_INT32_ALTERNATE 53781429
2189 int32_from_seed (int seed)
2191 /* Generate an integer value that's predictable from seed. We could
2192 * just use seed itself, but that would only ever touch one byte of
2193 * the int so would miss some kinds of bug.
2197 v = 42; /* just to quiet compiler afaik */
2204 v = SAMPLE_INT32_ALTERNATE;
2218 v *= seed; /* wraps around eventually, which is fine */
2224 int32_write_value (TestTypeNode *node,
2226 DBusTypeWriter *writer,
2229 /* also used for uint32 */
2232 v = int32_from_seed (seed);
2234 return _dbus_type_writer_write_basic (writer,
2235 node->klass->typecode,
2240 int32_read_value (TestTypeNode *node,
2241 DBusTypeReader *reader,
2244 /* also used for uint32 */
2247 check_expected_type (reader, node->klass->typecode);
2249 _dbus_type_reader_read_basic (reader,
2250 (dbus_int32_t*) &v);
2252 _dbus_assert (v == int32_from_seed (seed));
2258 int32_set_value (TestTypeNode *node,
2259 DBusTypeReader *reader,
2260 DBusTypeReader *realign_root,
2263 /* also used for uint32 */
2266 v = int32_from_seed (seed);
2268 return _dbus_type_reader_set_basic (reader,
2274 int32_write_multi (TestTypeNode *node,
2276 DBusTypeWriter *writer,
2280 /* also used for uint32 */
2281 dbus_int32_t values[MAX_MULTI_COUNT];
2282 dbus_int32_t *v_ARRAY_INT32 = values;
2285 for (i = 0; i < count; ++i)
2286 values[i] = int32_from_seed (seed + i);
2288 return _dbus_type_writer_write_fixed_multi (writer,
2289 node->klass->typecode,
2290 &v_ARRAY_INT32, count);
2294 int32_read_multi (TestTypeNode *node,
2295 DBusTypeReader *reader,
2299 /* also used for uint32 */
2300 dbus_int32_t *values;
2304 check_expected_type (reader, node->klass->typecode);
2306 _dbus_type_reader_read_fixed_multi (reader,
2310 if (n_elements != count)
2311 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2312 _dbus_assert (n_elements == count);
2314 for (i = 0; i < count; i++)
2315 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2316 (const unsigned char*)values + (i * 4))) ==
2317 int32_from_seed (seed + i));
2322 #ifdef DBUS_HAVE_INT64
2324 int64_from_seed (int seed)
2329 v32 = int32_from_seed (seed);
2331 v = - (dbus_int32_t) ~ v32;
2332 v |= (((dbus_int64_t)v32) << 32);
2339 int64_write_value (TestTypeNode *node,
2341 DBusTypeWriter *writer,
2344 #ifdef DBUS_HAVE_INT64
2345 /* also used for uint64 */
2348 v = int64_from_seed (seed);
2350 return _dbus_type_writer_write_basic (writer,
2351 node->klass->typecode,
2359 int64_read_value (TestTypeNode *node,
2360 DBusTypeReader *reader,
2363 #ifdef DBUS_HAVE_INT64
2364 /* also used for uint64 */
2367 check_expected_type (reader, node->klass->typecode);
2369 _dbus_type_reader_read_basic (reader,
2370 (dbus_int64_t*) &v);
2372 _dbus_assert (v == int64_from_seed (seed));
2381 int64_set_value (TestTypeNode *node,
2382 DBusTypeReader *reader,
2383 DBusTypeReader *realign_root,
2386 #ifdef DBUS_HAVE_INT64
2387 /* also used for uint64 */
2390 v = int64_from_seed (seed);
2392 return _dbus_type_reader_set_basic (reader,
2400 #define MAX_SAMPLE_STRING_LEN 10
2402 string_from_seed (char *buf,
2409 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2411 /* vary the length slightly, though we also have multiple string
2412 * value types for this, varying it here tests the set_value code
2426 v = (unsigned char) ('A' + seed);
2431 if (v < 'A' || v > 'z')
2444 string_write_value (TestTypeNode *node,
2446 DBusTypeWriter *writer,
2449 char buf[MAX_SAMPLE_STRING_LEN + 1]="";
2450 const char *v_string = buf;
2453 string_from_seed (buf, node->klass->subclass_detail,
2456 return _dbus_type_writer_write_basic (writer,
2457 node->klass->typecode,
2462 string_read_value (TestTypeNode *node,
2463 DBusTypeReader *reader,
2467 char buf[MAX_SAMPLE_STRING_LEN + 1];
2470 check_expected_type (reader, node->klass->typecode);
2472 _dbus_type_reader_read_basic (reader,
2473 (const char **) &v);
2475 string_from_seed (buf, node->klass->subclass_detail,
2478 if (strcmp (buf, v) != 0)
2480 _dbus_warn ("read string '%s' expected '%s'\n",
2482 _dbus_assert_not_reached ("test failed");
2489 string_set_value (TestTypeNode *node,
2490 DBusTypeReader *reader,
2491 DBusTypeReader *realign_root,
2494 char buf[MAX_SAMPLE_STRING_LEN + 1];
2495 const char *v_string = buf;
2497 string_from_seed (buf, node->klass->subclass_detail,
2500 #if RECURSIVE_MARSHAL_WRITE_TRACE
2503 _dbus_type_reader_read_basic (reader, &old);
2504 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2505 v_string, strlen (v_string), old, strlen (old));
2509 return _dbus_type_reader_set_basic (reader,
2514 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2517 bool_write_value (TestTypeNode *node,
2519 DBusTypeWriter *writer,
2524 v = BOOL_FROM_SEED (seed);
2526 return _dbus_type_writer_write_basic (writer,
2527 node->klass->typecode,
2532 bool_read_value (TestTypeNode *node,
2533 DBusTypeReader *reader,
2538 check_expected_type (reader, node->klass->typecode);
2540 _dbus_type_reader_read_basic (reader,
2541 (unsigned char*) &v);
2543 _dbus_assert (v == BOOL_FROM_SEED (seed));
2549 bool_set_value (TestTypeNode *node,
2550 DBusTypeReader *reader,
2551 DBusTypeReader *realign_root,
2556 v = BOOL_FROM_SEED (seed);
2558 return _dbus_type_reader_set_basic (reader,
2563 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2566 byte_write_value (TestTypeNode *node,
2568 DBusTypeWriter *writer,
2573 v = BYTE_FROM_SEED (seed);
2575 return _dbus_type_writer_write_basic (writer,
2576 node->klass->typecode,
2581 byte_read_value (TestTypeNode *node,
2582 DBusTypeReader *reader,
2587 check_expected_type (reader, node->klass->typecode);
2589 _dbus_type_reader_read_basic (reader,
2590 (unsigned char*) &v);
2592 _dbus_assert (v == BYTE_FROM_SEED (seed));
2599 byte_set_value (TestTypeNode *node,
2600 DBusTypeReader *reader,
2601 DBusTypeReader *realign_root,
2606 v = BYTE_FROM_SEED (seed);
2608 return _dbus_type_reader_set_basic (reader,
2614 double_from_seed (int seed)
2616 return SAMPLE_INT32 * (double) seed + 0.3;
2620 double_write_value (TestTypeNode *node,
2622 DBusTypeWriter *writer,
2627 v = double_from_seed (seed);
2629 return _dbus_type_writer_write_basic (writer,
2630 node->klass->typecode,
2635 double_read_value (TestTypeNode *node,
2636 DBusTypeReader *reader,
2642 check_expected_type (reader, node->klass->typecode);
2644 _dbus_type_reader_read_basic (reader,
2647 expected = double_from_seed (seed);
2649 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2651 #ifdef DBUS_HAVE_INT64
2652 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2654 *(dbus_uint64_t*)(char*)&expected,
2655 *(dbus_uint64_t*)(char*)&v);
2657 _dbus_assert_not_reached ("test failed");
2664 double_set_value (TestTypeNode *node,
2665 DBusTypeReader *reader,
2666 DBusTypeReader *realign_root,
2671 v = double_from_seed (seed);
2673 return _dbus_type_reader_set_basic (reader,
2678 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2680 object_path_from_seed (char *buf,
2688 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2690 v = (unsigned char) ('A' + seed);
2702 if (v < 'A' || v > 'z')
2718 object_path_write_value (TestTypeNode *node,
2720 DBusTypeWriter *writer,
2723 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2724 const char *v_string = buf;
2726 object_path_from_seed (buf, seed);
2728 return _dbus_type_writer_write_basic (writer,
2729 node->klass->typecode,
2734 object_path_read_value (TestTypeNode *node,
2735 DBusTypeReader *reader,
2739 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2741 check_expected_type (reader, node->klass->typecode);
2743 _dbus_type_reader_read_basic (reader,
2744 (const char **) &v);
2746 object_path_from_seed (buf, seed);
2748 if (strcmp (buf, v) != 0)
2750 _dbus_warn ("read object path '%s' expected '%s'\n",
2752 _dbus_assert_not_reached ("test failed");
2759 object_path_set_value (TestTypeNode *node,
2760 DBusTypeReader *reader,
2761 DBusTypeReader *realign_root,
2764 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2765 const char *v_string = buf;
2767 object_path_from_seed (buf, seed);
2769 return _dbus_type_reader_set_basic (reader,
2774 #define MAX_SAMPLE_SIGNATURE_LEN 10
2776 signature_from_seed (char *buf,
2779 /* try to avoid ascending, descending, or alternating length to help find bugs */
2780 const char *sample_signatures[] = {
2789 strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
2793 signature_write_value (TestTypeNode *node,
2795 DBusTypeWriter *writer,
2798 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2799 const char *v_string = buf;
2801 signature_from_seed (buf, seed);
2803 return _dbus_type_writer_write_basic (writer,
2804 node->klass->typecode,
2809 signature_read_value (TestTypeNode *node,
2810 DBusTypeReader *reader,
2814 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2816 check_expected_type (reader, node->klass->typecode);
2818 _dbus_type_reader_read_basic (reader,
2819 (const char **) &v);
2821 signature_from_seed (buf, seed);
2823 if (strcmp (buf, v) != 0)
2825 _dbus_warn ("read signature value '%s' expected '%s'\n",
2827 _dbus_assert_not_reached ("test failed");
2835 signature_set_value (TestTypeNode *node,
2836 DBusTypeReader *reader,
2837 DBusTypeReader *realign_root,
2840 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2841 const char *v_string = buf;
2843 signature_from_seed (buf, seed);
2845 return _dbus_type_reader_set_basic (reader,
2851 struct_write_value (TestTypeNode *node,
2853 DBusTypeWriter *writer,
2856 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2857 DataBlockState saved;
2862 n_copies = node->klass->subclass_detail;
2864 _dbus_assert (container->children != NULL);
2866 data_block_save (block, &saved);
2868 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2874 while (i < n_copies)
2878 link = _dbus_list_get_first_link (&container->children);
2879 while (link != NULL)
2881 TestTypeNode *child = link->data;
2882 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2884 if (!node_write_value (child, block, &sub, seed + i))
2886 data_block_restore (block, &saved);
2896 if (!_dbus_type_writer_unrecurse (writer, &sub))
2898 data_block_restore (block, &saved);
2906 struct_read_or_set_value (TestTypeNode *node,
2907 DBusTypeReader *reader,
2908 DBusTypeReader *realign_root,
2911 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2916 n_copies = node->klass->subclass_detail;
2918 check_expected_type (reader, DBUS_TYPE_STRUCT);
2920 _dbus_type_reader_recurse (reader, &sub);
2923 while (i < n_copies)
2927 link = _dbus_list_get_first_link (&container->children);
2928 while (link != NULL)
2930 TestTypeNode *child = link->data;
2931 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2933 if (realign_root == NULL)
2935 if (!node_read_value (child, &sub, seed + i))
2940 if (!node_set_value (child, &sub, realign_root, seed + i))
2944 if (i == (n_copies - 1) && next == NULL)
2945 NEXT_EXPECTING_FALSE (&sub);
2947 NEXT_EXPECTING_TRUE (&sub);
2959 struct_read_value (TestTypeNode *node,
2960 DBusTypeReader *reader,
2963 return struct_read_or_set_value (node, reader, NULL, seed);
2967 struct_set_value (TestTypeNode *node,
2968 DBusTypeReader *reader,
2969 DBusTypeReader *realign_root,
2972 return struct_read_or_set_value (node, reader, realign_root, seed);
2976 struct_build_signature (TestTypeNode *node,
2979 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2984 n_copies = node->klass->subclass_detail;
2986 orig_len = _dbus_string_get_length (str);
2988 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2992 while (i < n_copies)
2996 link = _dbus_list_get_first_link (&container->children);
2997 while (link != NULL)
2999 TestTypeNode *child = link->data;
3000 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3002 if (!node_build_signature (child, str))
3011 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
3017 _dbus_string_set_length (str, orig_len);
3022 array_write_value (TestTypeNode *node,
3024 DBusTypeWriter *writer,
3027 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3028 DataBlockState saved;
3030 DBusString element_signature;
3034 TestTypeNode *child;
3036 n_copies = node->klass->subclass_detail;
3038 _dbus_assert (container->children != NULL);
3040 data_block_save (block, &saved);
3042 if (!_dbus_string_init (&element_signature))
3045 child = _dbus_list_get_first (&container->children);
3047 if (!node_build_signature (child,
3048 &element_signature))
3051 element_type = _dbus_first_type_in_signature (&element_signature, 0);
3053 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3054 &element_signature, 0,
3058 if (arrays_write_fixed_in_blocks &&
3059 dbus_type_is_fixed (element_type) &&
3060 child->klass->write_multi)
3062 if (!node_write_multi (child, block, &sub, seed, n_copies))
3068 while (i < n_copies)
3072 link = _dbus_list_get_first_link (&container->children);
3073 while (link != NULL)
3075 TestTypeNode *child = link->data;
3076 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3078 if (!node_write_value (child, block, &sub, seed + i))
3088 if (!_dbus_type_writer_unrecurse (writer, &sub))
3091 _dbus_string_free (&element_signature);
3095 data_block_restore (block, &saved);
3096 _dbus_string_free (&element_signature);
3101 array_read_or_set_value (TestTypeNode *node,
3102 DBusTypeReader *reader,
3103 DBusTypeReader *realign_root,
3106 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3110 TestTypeNode *child;
3112 n_copies = node->klass->subclass_detail;
3114 check_expected_type (reader, DBUS_TYPE_ARRAY);
3116 child = _dbus_list_get_first (&container->children);
3120 _dbus_type_reader_recurse (reader, &sub);
3122 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
3123 dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
3124 child->klass->read_multi)
3126 if (!node_read_multi (child, &sub, seed, n_copies))
3132 while (i < n_copies)
3136 link = _dbus_list_get_first_link (&container->children);
3137 while (link != NULL)
3139 TestTypeNode *child = link->data;
3140 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3142 _dbus_assert (child->klass->typecode ==
3143 _dbus_type_reader_get_element_type (reader));
3145 if (realign_root == NULL)
3147 if (!node_read_value (child, &sub, seed + i))
3152 if (!node_set_value (child, &sub, realign_root, seed + i))
3156 if (i == (n_copies - 1) && next == NULL)
3157 NEXT_EXPECTING_FALSE (&sub);
3159 NEXT_EXPECTING_TRUE (&sub);
3173 array_read_value (TestTypeNode *node,
3174 DBusTypeReader *reader,
3177 return array_read_or_set_value (node, reader, NULL, seed);
3181 array_set_value (TestTypeNode *node,
3182 DBusTypeReader *reader,
3183 DBusTypeReader *realign_root,
3186 return array_read_or_set_value (node, reader, realign_root, seed);
3190 array_build_signature (TestTypeNode *node,
3193 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3196 orig_len = _dbus_string_get_length (str);
3198 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3201 if (!node_build_signature (_dbus_list_get_first (&container->children),
3208 _dbus_string_set_length (str, orig_len);
3212 /* 10 is random just to add another seed that we use in the suite */
3213 #define VARIANT_SEED 10
3216 variant_write_value (TestTypeNode *node,
3218 DBusTypeWriter *writer,
3221 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3222 DataBlockState saved;
3224 DBusString content_signature;
3225 TestTypeNode *child;
3227 _dbus_assert (container->children != NULL);
3228 _dbus_assert (_dbus_list_length_is_one (&container->children));
3230 child = _dbus_list_get_first (&container->children);
3232 data_block_save (block, &saved);
3234 if (!_dbus_string_init (&content_signature))
3237 if (!node_build_signature (child,
3238 &content_signature))
3241 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3242 &content_signature, 0,
3246 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3249 if (!_dbus_type_writer_unrecurse (writer, &sub))
3252 _dbus_string_free (&content_signature);
3256 data_block_restore (block, &saved);
3257 _dbus_string_free (&content_signature);
3262 variant_read_or_set_value (TestTypeNode *node,
3263 DBusTypeReader *reader,
3264 DBusTypeReader *realign_root,
3267 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3269 TestTypeNode *child;
3271 _dbus_assert (container->children != NULL);
3272 _dbus_assert (_dbus_list_length_is_one (&container->children));
3274 child = _dbus_list_get_first (&container->children);
3276 check_expected_type (reader, DBUS_TYPE_VARIANT);
3278 _dbus_type_reader_recurse (reader, &sub);
3280 if (realign_root == NULL)
3282 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3287 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3291 NEXT_EXPECTING_FALSE (&sub);
3297 variant_read_value (TestTypeNode *node,
3298 DBusTypeReader *reader,
3301 return variant_read_or_set_value (node, reader, NULL, seed);
3305 variant_set_value (TestTypeNode *node,
3306 DBusTypeReader *reader,
3307 DBusTypeReader *realign_root,
3310 return variant_read_or_set_value (node, reader, realign_root, seed);
3314 dict_write_value (TestTypeNode *node,
3316 DBusTypeWriter *writer,
3319 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3320 DataBlockState saved;
3322 DBusString entry_value_signature;
3323 DBusString dict_entry_signature;
3326 int entry_value_type;
3327 TestTypeNode *child;
3329 n_entries = node->klass->subclass_detail;
3331 _dbus_assert (container->children != NULL);
3333 data_block_save (block, &saved);
3335 if (!_dbus_string_init (&entry_value_signature))
3338 if (!_dbus_string_init (&dict_entry_signature))
3340 _dbus_string_free (&entry_value_signature);
3344 child = _dbus_list_get_first (&container->children);
3346 if (!node_build_signature (child,
3347 &entry_value_signature))
3350 if (!_dbus_string_append (&dict_entry_signature,
3351 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3352 DBUS_TYPE_INT32_AS_STRING))
3355 if (!_dbus_string_copy (&entry_value_signature, 0,
3356 &dict_entry_signature,
3357 _dbus_string_get_length (&dict_entry_signature)))
3360 if (!_dbus_string_append_byte (&dict_entry_signature,
3361 DBUS_DICT_ENTRY_END_CHAR))
3364 entry_value_type = _dbus_first_type_in_signature (&entry_value_signature, 0);
3366 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3367 &dict_entry_signature, 0,
3372 while (i < n_entries)
3374 DBusTypeWriter entry_sub;
3377 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
3382 key = int32_from_seed (seed + i);
3384 if (!_dbus_type_writer_write_basic (&entry_sub,
3389 if (!node_write_value (child, block, &entry_sub, seed + i))
3392 if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
3398 if (!_dbus_type_writer_unrecurse (writer, &sub))
3401 _dbus_string_free (&entry_value_signature);
3402 _dbus_string_free (&dict_entry_signature);
3406 data_block_restore (block, &saved);
3407 _dbus_string_free (&entry_value_signature);
3408 _dbus_string_free (&dict_entry_signature);
3413 dict_read_or_set_value (TestTypeNode *node,
3414 DBusTypeReader *reader,
3415 DBusTypeReader *realign_root,
3418 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3422 TestTypeNode *child;
3424 n_entries = node->klass->subclass_detail;
3426 check_expected_type (reader, DBUS_TYPE_ARRAY);
3428 child = _dbus_list_get_first (&container->children);
3432 _dbus_type_reader_recurse (reader, &sub);
3434 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3437 while (i < n_entries)
3439 DBusTypeReader entry_sub;
3441 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3443 _dbus_type_reader_recurse (&sub, &entry_sub);
3445 if (realign_root == NULL)
3449 check_expected_type (&entry_sub, DBUS_TYPE_INT32);
3451 _dbus_type_reader_read_basic (&entry_sub,
3452 (dbus_int32_t*) &v);
3454 _dbus_assert (v == int32_from_seed (seed + i));
3456 NEXT_EXPECTING_TRUE (&entry_sub);
3458 if (!node_read_value (child, &entry_sub, seed + i))
3461 NEXT_EXPECTING_FALSE (&entry_sub);
3467 v = int32_from_seed (seed + i);
3469 if (!_dbus_type_reader_set_basic (&entry_sub,
3474 NEXT_EXPECTING_TRUE (&entry_sub);
3476 if (!node_set_value (child, &entry_sub, realign_root, seed + i))
3479 NEXT_EXPECTING_FALSE (&entry_sub);
3482 if (i == (n_entries - 1))
3483 NEXT_EXPECTING_FALSE (&sub);
3485 NEXT_EXPECTING_TRUE (&sub);
3495 dict_read_value (TestTypeNode *node,
3496 DBusTypeReader *reader,
3499 return dict_read_or_set_value (node, reader, NULL, seed);
3503 dict_set_value (TestTypeNode *node,
3504 DBusTypeReader *reader,
3505 DBusTypeReader *realign_root,
3508 return dict_read_or_set_value (node, reader, realign_root, seed);
3512 dict_build_signature (TestTypeNode *node,
3515 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3518 orig_len = _dbus_string_get_length (str);
3520 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3523 if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
3526 if (!node_build_signature (_dbus_list_get_first (&container->children),
3530 if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
3536 _dbus_string_set_length (str, orig_len);
3541 container_destroy (TestTypeNode *node)
3543 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3546 link = _dbus_list_get_first_link (&container->children);
3547 while (link != NULL)
3549 TestTypeNode *child = link->data;
3550 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3552 node_destroy (child);
3554 _dbus_list_free_link (link);
3560 #endif /* DBUS_BUILD_TESTS */