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,
987 DBusTypeReader restored;
989 _dbus_type_reader_save_mark (reader, &mark);
991 if (!(* node->klass->read_value) (node, reader, seed))
994 _dbus_type_reader_init_from_mark (&restored,
1000 if (!(* node->klass->read_value) (node, &restored, seed))
1006 /* Warning: if this one fails due to OOM, it has side effects (can
1007 * modify only some of the sub-values). OK in a test suite, but we
1008 * never do this in real code.
1011 node_set_value (TestTypeNode *node,
1012 DBusTypeReader *reader,
1013 DBusTypeReader *realign_root,
1016 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
1023 node_build_signature (TestTypeNode *node,
1026 if (node->klass->build_signature)
1027 return (* node->klass->build_signature) (node, str);
1029 return _dbus_string_append_byte (str, node->klass->typecode);
1033 node_append_child (TestTypeNode *node,
1034 TestTypeNode *child)
1036 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1038 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
1040 if (!_dbus_list_append (&container->children, child))
1041 _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 */
1047 node_write_multi (TestTypeNode *node,
1049 DBusTypeWriter *writer,
1055 _dbus_assert (node->klass->write_multi != NULL);
1056 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
1059 /* Handy to see where things break, but too expensive to do all the time */
1060 data_block_verify (block);
1067 node_read_multi (TestTypeNode *node,
1068 DBusTypeReader *reader,
1072 _dbus_assert (node->klass->read_multi != NULL);
1074 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1080 static int n_iterations_completed_total = 0;
1081 static int n_iterations_completed_this_test = 0;
1082 static int n_iterations_expected_this_test = 0;
1086 const DBusString *signature;
1089 TestTypeNode **nodes;
1091 } NodeIterationData;
1094 run_test_copy (NodeIterationData *nid)
1099 DBusTypeReader reader;
1100 DBusTypeWriter writer;
1102 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1108 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1111 data_block_init_reader_writer (src, &reader, NULL);
1112 data_block_init_reader_writer (&dest, NULL, &writer);
1114 /* DBusTypeWriter assumes it's writing into an existing signature,
1115 * so doesn't add nul on its own. We have to do that.
1117 if (!_dbus_string_insert_byte (&dest.signature,
1118 dest.initial_offset, '\0'))
1121 if (!_dbus_type_writer_write_reader (&writer, &reader))
1124 /* Data blocks should now be identical */
1125 if (!_dbus_string_equal (&src->signature, &dest.signature))
1127 _dbus_verbose ("SOURCE\n");
1128 _dbus_verbose_bytes_of_string (&src->signature, 0,
1129 _dbus_string_get_length (&src->signature));
1130 _dbus_verbose ("DEST\n");
1131 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1132 _dbus_string_get_length (&dest.signature));
1133 _dbus_assert_not_reached ("signatures did not match");
1136 if (!_dbus_string_equal (&src->body, &dest.body))
1138 _dbus_verbose ("SOURCE\n");
1139 _dbus_verbose_bytes_of_string (&src->body, 0,
1140 _dbus_string_get_length (&src->body));
1141 _dbus_verbose ("DEST\n");
1142 _dbus_verbose_bytes_of_string (&dest.body, 0,
1143 _dbus_string_get_length (&dest.body));
1144 _dbus_assert_not_reached ("bodies did not match");
1151 data_block_free (&dest);
1157 run_test_values_only_write (NodeIterationData *nid)
1159 DBusTypeReader reader;
1160 DBusTypeWriter writer;
1165 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1169 data_block_reset (nid->block);
1171 sig_len = _dbus_string_get_length (nid->signature);
1173 _dbus_type_writer_init_values_only (&writer,
1174 nid->block->byte_order,
1177 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1178 _dbus_type_reader_init (&reader,
1179 nid->block->byte_order,
1182 nid->block->initial_offset);
1185 while (i < nid->n_nodes)
1187 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1193 /* if we wrote any typecodes then this would fail */
1194 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1196 /* But be sure we wrote out the values correctly */
1198 while (i < nid->n_nodes)
1200 if (!node_read_value (nid->nodes[i], &reader, i))
1203 if (i + 1 == nid->n_nodes)
1204 NEXT_EXPECTING_FALSE (&reader);
1206 NEXT_EXPECTING_TRUE (&reader);
1214 data_block_reset (nid->block);
1218 /* offset the seed for setting, so we set different numbers than
1219 * we originally wrote. Don't offset by a huge number since in
1220 * some cases it's value = possibilities[seed % n_possibilities]
1221 * and we don't want to wrap around. bool_from_seed
1222 * is just seed % 2 even.
1226 run_test_set_values (NodeIterationData *nid)
1228 DBusTypeReader reader;
1229 DBusTypeReader realign_root;
1233 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1237 data_block_init_reader_writer (nid->block,
1240 realign_root = reader;
1243 while (i < nid->n_nodes)
1245 if (!node_set_value (nid->nodes[i],
1246 &reader, &realign_root,
1250 if (i + 1 == nid->n_nodes)
1251 NEXT_EXPECTING_FALSE (&reader);
1253 NEXT_EXPECTING_TRUE (&reader);
1258 /* Check that the new values were set */
1260 reader = realign_root;
1263 while (i < nid->n_nodes)
1265 if (!node_read_value (nid->nodes[i], &reader,
1269 if (i + 1 == nid->n_nodes)
1270 NEXT_EXPECTING_FALSE (&reader);
1272 NEXT_EXPECTING_TRUE (&reader);
1284 run_test_delete_values (NodeIterationData *nid)
1286 DBusTypeReader reader;
1290 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1294 data_block_init_reader_writer (nid->block,
1297 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1299 /* Right now, deleting only works on array elements. We delete
1300 * all array elements, and then verify that there aren't any
1303 if (t == DBUS_TYPE_ARRAY)
1305 DBusTypeReader array;
1309 _dbus_type_reader_recurse (&reader, &array);
1311 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1314 _dbus_type_reader_next (&array);
1317 /* reset to start of array */
1318 _dbus_type_reader_recurse (&reader, &array);
1319 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1320 reader.value_pos, array.value_pos, array.u.array.start_pos);
1321 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1323 /* We don't want to always delete from the same part of the array. */
1324 static int cycle = 0;
1327 _dbus_assert (n_elements > 0);
1330 if (elem == 3 || elem >= n_elements) /* end of array */
1331 elem = n_elements - 1;
1333 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1334 elem, n_elements, _dbus_type_to_string (elem_type),
1335 cycle, reader.value_pos, array.value_pos);
1338 if (!_dbus_type_reader_next (&array))
1339 _dbus_assert_not_reached ("should have had another element\n");
1343 if (!_dbus_type_reader_delete (&array, &reader))
1349 _dbus_type_reader_recurse (&reader, &array);
1357 _dbus_type_reader_next (&reader);
1360 /* Check that there are no array elements left */
1361 data_block_init_reader_writer (nid->block,
1364 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1366 _dbus_type_reader_next (&reader);
1376 run_test_nodes_iteration (void *data)
1378 NodeIterationData *nid = data;
1379 DBusTypeReader reader;
1380 DBusTypeWriter writer;
1385 * 1. write the value
1386 * 2. strcmp-compare with the signature we built
1388 * 4. type-iterate the signature and the value and see if they are the same type-wise
1392 data_block_init_reader_writer (nid->block,
1395 /* DBusTypeWriter assumes it's writing into an existing signature,
1396 * so doesn't add nul on its own. We have to do that.
1398 if (!_dbus_string_insert_byte (&nid->block->signature,
1399 nid->type_offset, '\0'))
1403 while (i < nid->n_nodes)
1405 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1411 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1412 &nid->block->signature, nid->type_offset))
1414 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1415 _dbus_string_get_const_data (nid->signature),
1416 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1418 _dbus_assert_not_reached ("wrong signature");
1422 while (i < nid->n_nodes)
1424 if (!node_read_value (nid->nodes[i], &reader, i))
1427 if (i + 1 == nid->n_nodes)
1428 NEXT_EXPECTING_FALSE (&reader);
1430 NEXT_EXPECTING_TRUE (&reader);
1435 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1437 /* this set values test uses code from copy and
1438 * values_only_write so would ideally be last so you get a
1439 * simpler test case for problems with copying or values_only
1440 * writing; but it also needs an already-written DataBlock so it
1441 * has to go first. Comment it out if it breaks, and see if the
1442 * later tests also break - debug them first if so.
1444 if (!run_test_set_values (nid))
1447 if (!run_test_delete_values (nid))
1450 if (!run_test_copy (nid))
1453 if (!run_test_values_only_write (nid))
1457 /* FIXME type-iterate both signature and value and compare the resulting
1458 * tree to the node tree perhaps
1465 data_block_reset (nid->block);
1471 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1473 const DBusString *signature,
1478 NodeIterationData nid;
1480 if (!data_block_init (&block, byte_order, initial_offset))
1481 _dbus_assert_not_reached ("no memory");
1483 nid.signature = signature;
1485 nid.type_offset = initial_offset;
1487 nid.n_nodes = n_nodes;
1489 if (TEST_OOM_HANDLING &&
1490 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1492 _dbus_test_oom_handling ("running test node",
1493 run_test_nodes_iteration,
1498 if (!run_test_nodes_iteration (&nid))
1499 _dbus_assert_not_reached ("no memory");
1502 data_block_free (&block);
1506 run_test_nodes (TestTypeNode **nodes,
1510 DBusString signature;
1512 if (!_dbus_string_init (&signature))
1513 _dbus_assert_not_reached ("no memory");
1518 if (! node_build_signature (nodes[i], &signature))
1519 _dbus_assert_not_reached ("no memory");
1524 _dbus_verbose (">>> test nodes with signature '%s'\n",
1525 _dbus_string_get_const_data (&signature));
1528 while (i <= MAX_INITIAL_OFFSET)
1530 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1531 DBUS_LITTLE_ENDIAN, i);
1532 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1533 DBUS_BIG_ENDIAN, i);
1538 n_iterations_completed_this_test += 1;
1539 n_iterations_completed_total += 1;
1541 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1543 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1544 n_iterations_completed_this_test,
1545 n_iterations_completed_total);
1547 /* this happens to turn out well with mod == 1 */
1548 else if ((n_iterations_completed_this_test %
1549 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1551 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1554 _dbus_string_free (&signature);
1557 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1559 static TestTypeNode*
1560 value_generator (int *ip)
1563 const TestTypeNodeClass *child_klass;
1564 const TestTypeNodeClass *container_klass;
1565 TestTypeNode *child;
1568 _dbus_assert (i <= N_VALUES);
1574 else if (i < N_BASICS)
1576 node = node_new (basic_nodes[i]);
1580 /* imagine an array:
1581 * container 0 of basic 0
1582 * container 0 of basic 1
1583 * container 0 of basic 2
1584 * container 1 of basic 0
1585 * container 1 of basic 1
1586 * container 1 of basic 2
1590 container_klass = container_nodes[i / N_BASICS];
1591 child_klass = basic_nodes[i % N_BASICS];
1593 node = node_new (container_klass);
1594 child = node_new (child_klass);
1596 node_append_child (node, child);
1599 *ip += 1; /* increment the generator */
1605 build_body (TestTypeNode **nodes,
1608 DBusString *signature,
1613 DBusTypeReader reader;
1614 DBusTypeWriter writer;
1619 if (! node_build_signature (nodes[i], signature))
1620 _dbus_assert_not_reached ("no memory");
1625 if (!data_block_init (&block, byte_order, 0))
1626 _dbus_assert_not_reached ("no memory");
1628 data_block_init_reader_writer (&block,
1631 /* DBusTypeWriter assumes it's writing into an existing signature,
1632 * so doesn't add nul on its own. We have to do that.
1634 if (!_dbus_string_insert_byte (&block.signature,
1636 _dbus_assert_not_reached ("no memory");
1641 if (!node_write_value (nodes[i], &block, &writer, i))
1642 _dbus_assert_not_reached ("no memory");
1647 if (!_dbus_string_copy_len (&block.body, 0,
1648 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1650 _dbus_assert_not_reached ("oom");
1652 data_block_free (&block);
1656 dbus_internal_do_not_use_generate_bodies (int sequence,
1658 DBusString *signature,
1661 TestTypeNode *nodes[1];
1665 nodes[0] = value_generator (&sequence);
1667 if (nodes[0] == NULL)
1672 build_body (nodes, n_nodes, byte_order, signature, body);
1678 node_destroy (nodes[i]);
1686 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1690 TestTypeNode *container;
1691 TestTypeNode *child;
1694 root = node_new (container_klass);
1696 for (i = 1; i < n_nested; i++)
1698 child = node_new (container_klass);
1699 node_append_child (container, child);
1703 /* container should now be the most-nested container */
1706 while ((child = value_generator (&i)))
1708 node_append_child (container, child);
1710 run_test_nodes (&root, 1);
1712 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1713 node_destroy (child);
1716 node_destroy (root);
1720 start_next_test (const char *format,
1723 n_iterations_completed_this_test = 0;
1724 n_iterations_expected_this_test = expected;
1726 fprintf (stderr, ">>> >>> ");
1727 fprintf (stderr, format,
1728 n_iterations_expected_this_test);
1732 make_and_run_test_nodes (void)
1736 /* We try to do this in order of "complicatedness" so that test
1737 * failures tend to show up in the simplest test case that
1738 * demonstrates the failure. There are also some tests that run
1739 * more than once for this reason, first while going through simple
1740 * cases, second while going through a broader range of complex
1743 /* Each basic node. The basic nodes should include:
1745 * - each fixed-size type (in such a way that it has different values each time,
1746 * so we can tell if we mix two of them up)
1747 * - strings of various lengths
1751 /* Each container node. The container nodes should include:
1753 * struct with 1 and 2 copies of the contained item
1754 * array with 0, 1, 2 copies of the contained item
1757 /* Let a "value" be a basic node, or a container containing a single basic node.
1758 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1759 * When iterating through all values to make combinations, do the basic types
1760 * first and the containers second.
1762 /* Each item is shown with its number of iterations to complete so
1763 * we can keep a handle on this unit test
1766 /* FIXME test just an empty body, no types at all */
1768 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1772 while ((node = value_generator (&i)))
1774 run_test_nodes (&node, 1);
1776 node_destroy (node);
1780 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1781 arrays_write_fixed_in_blocks = TRUE;
1785 while ((node = value_generator (&i)))
1787 run_test_nodes (&node, 1);
1789 node_destroy (node);
1792 arrays_write_fixed_in_blocks = FALSE;
1794 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1796 TestTypeNode *nodes[N_VALUES];
1799 while ((nodes[i] = value_generator (&i)))
1802 run_test_nodes (nodes, N_VALUES);
1804 for (i = 0; i < N_VALUES; i++)
1805 node_destroy (nodes[i]);
1808 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1809 N_VALUES * N_VALUES);
1811 TestTypeNode *nodes[2];
1814 while ((nodes[0] = value_generator (&i)))
1817 while ((nodes[1] = value_generator (&j)))
1819 run_test_nodes (nodes, 2);
1821 node_destroy (nodes[1]);
1824 node_destroy (nodes[0]);
1828 start_next_test ("Each container containing each value %d iterations\n",
1829 N_CONTAINERS * N_VALUES);
1830 for (i = 0; i < N_CONTAINERS; i++)
1832 const TestTypeNodeClass *container_klass = container_nodes[i];
1834 make_and_run_values_inside_container (container_klass, 1);
1837 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1838 N_CONTAINERS * N_VALUES);
1839 arrays_write_fixed_in_blocks = TRUE;
1840 for (i = 0; i < N_CONTAINERS; i++)
1842 const TestTypeNodeClass *container_klass = container_nodes[i];
1844 make_and_run_values_inside_container (container_klass, 1);
1846 arrays_write_fixed_in_blocks = FALSE;
1848 start_next_test ("Each container of same container of each value %d iterations\n",
1849 N_CONTAINERS * N_VALUES);
1850 for (i = 0; i < N_CONTAINERS; i++)
1852 const TestTypeNodeClass *container_klass = container_nodes[i];
1854 make_and_run_values_inside_container (container_klass, 2);
1857 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1858 N_CONTAINERS * N_VALUES);
1859 for (i = 0; i < N_CONTAINERS; i++)
1861 const TestTypeNodeClass *container_klass = container_nodes[i];
1863 make_and_run_values_inside_container (container_klass, 3);
1866 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1867 N_VALUES * N_VALUES);
1869 TestTypeNode *val1, *val2;
1872 node = node_new (&struct_1_class);
1875 while ((val1 = value_generator (&i)))
1878 while ((val2 = value_generator (&j)))
1880 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1882 node_append_child (node, val1);
1883 node_append_child (node, val2);
1885 run_test_nodes (&node, 1);
1887 _dbus_list_clear (&container->children);
1888 node_destroy (val2);
1890 node_destroy (val1);
1892 node_destroy (node);
1895 start_next_test ("All values in one big struct %d iteration\n",
1899 TestTypeNode *child;
1901 node = node_new (&struct_1_class);
1904 while ((child = value_generator (&i)))
1905 node_append_child (node, child);
1907 run_test_nodes (&node, 1);
1909 node_destroy (node);
1912 start_next_test ("Each value in a large array %d iterations\n",
1918 node = node_new (&array_9_class);
1921 while ((val = value_generator (&i)))
1923 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1925 node_append_child (node, val);
1927 run_test_nodes (&node, 1);
1929 _dbus_list_clear (&container->children);
1933 node_destroy (node);
1936 start_next_test ("Each container of each container of each value %d iterations\n",
1937 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1938 for (i = 0; i < N_CONTAINERS; i++)
1940 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1941 TestTypeNode *outer_container = node_new (outer_container_klass);
1943 for (j = 0; j < N_CONTAINERS; j++)
1945 TestTypeNode *child;
1946 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1947 TestTypeNode *inner_container = node_new (inner_container_klass);
1949 node_append_child (outer_container, inner_container);
1952 while ((child = value_generator (&m)))
1954 node_append_child (inner_container, child);
1956 run_test_nodes (&outer_container, 1);
1958 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1959 node_destroy (child);
1961 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1962 node_destroy (inner_container);
1964 node_destroy (outer_container);
1967 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1968 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1969 for (i = 0; i < N_CONTAINERS; i++)
1971 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1972 TestTypeNode *outer_container = node_new (outer_container_klass);
1974 for (j = 0; j < N_CONTAINERS; j++)
1976 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1977 TestTypeNode *inner_container = node_new (inner_container_klass);
1979 node_append_child (outer_container, inner_container);
1981 for (k = 0; k < N_CONTAINERS; k++)
1983 TestTypeNode *child;
1984 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1985 TestTypeNode *center_container = node_new (center_container_klass);
1987 node_append_child (inner_container, center_container);
1990 while ((child = value_generator (&m)))
1992 node_append_child (center_container, child);
1994 run_test_nodes (&outer_container, 1);
1996 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1997 node_destroy (child);
1999 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
2000 node_destroy (center_container);
2002 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
2003 node_destroy (inner_container);
2005 node_destroy (outer_container);
2009 /* This one takes a really long time, so comment it out for now */
2010 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
2011 N_VALUES * N_VALUES * N_VALUES);
2013 TestTypeNode *nodes[3];
2016 while ((nodes[0] = value_generator (&i)))
2019 while ((nodes[1] = value_generator (&j)))
2022 while ((nodes[2] = value_generator (&k)))
2024 run_test_nodes (nodes, 3);
2026 node_destroy (nodes[2]);
2028 node_destroy (nodes[1]);
2030 node_destroy (nodes[0]);
2033 #endif /* #if 0 expensive test */
2035 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
2036 n_iterations_completed_total);
2037 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
2038 MAX_INITIAL_OFFSET);
2039 fprintf (stderr, "out of memory handling %s tested\n",
2040 TEST_OOM_HANDLING ? "was" : "was not");
2044 _dbus_marshal_recursive_test (void)
2046 make_and_run_test_nodes ();
2054 * Implementations of each type node class
2059 #define MAX_MULTI_COUNT 5
2061 #define SAMPLE_INT16 1234
2062 #define SAMPLE_INT16_ALTERNATE 6785
2064 int16_from_seed (int seed)
2066 /* Generate an integer value that's predictable from seed. We could
2067 * just use seed itself, but that would only ever touch one byte of
2068 * the int so would miss some kinds of bug.
2072 v = 42; /* just to quiet compiler afaik */
2079 v = SAMPLE_INT16_ALTERNATE;
2085 v = _DBUS_INT16_MAX;
2093 v *= seed; /* wraps around eventually, which is fine */
2099 int16_write_value (TestTypeNode *node,
2101 DBusTypeWriter *writer,
2104 /* also used for uint16 */
2107 v = int16_from_seed (seed);
2109 return _dbus_type_writer_write_basic (writer,
2110 node->klass->typecode,
2115 int16_read_value (TestTypeNode *node,
2116 DBusTypeReader *reader,
2119 /* also used for uint16 */
2122 check_expected_type (reader, node->klass->typecode);
2124 _dbus_type_reader_read_basic (reader,
2125 (dbus_int16_t*) &v);
2127 _dbus_assert (v == int16_from_seed (seed));
2133 int16_set_value (TestTypeNode *node,
2134 DBusTypeReader *reader,
2135 DBusTypeReader *realign_root,
2138 /* also used for uint16 */
2141 v = int16_from_seed (seed);
2143 return _dbus_type_reader_set_basic (reader,
2149 int16_write_multi (TestTypeNode *node,
2151 DBusTypeWriter *writer,
2155 /* also used for uint16 */
2156 dbus_int16_t values[MAX_MULTI_COUNT];
2157 dbus_int16_t *v_ARRAY_INT16 = values;
2160 for (i = 0; i < count; ++i)
2161 values[i] = int16_from_seed (seed + i);
2163 return _dbus_type_writer_write_fixed_multi (writer,
2164 node->klass->typecode,
2165 &v_ARRAY_INT16, count);
2169 int16_read_multi (TestTypeNode *node,
2170 DBusTypeReader *reader,
2174 /* also used for uint16 */
2175 dbus_int16_t *values;
2179 check_expected_type (reader, node->klass->typecode);
2181 _dbus_type_reader_read_fixed_multi (reader,
2185 if (n_elements != count)
2186 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2187 _dbus_assert (n_elements == count);
2189 for (i = 0; i < count; i++)
2190 _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
2191 (const unsigned char*)values + (i * 2))) ==
2192 int16_from_seed (seed + i));
2198 #define SAMPLE_INT32 12345678
2199 #define SAMPLE_INT32_ALTERNATE 53781429
2201 int32_from_seed (int seed)
2203 /* Generate an integer value that's predictable from seed. We could
2204 * just use seed itself, but that would only ever touch one byte of
2205 * the int so would miss some kinds of bug.
2209 v = 42; /* just to quiet compiler afaik */
2216 v = SAMPLE_INT32_ALTERNATE;
2230 v *= seed; /* wraps around eventually, which is fine */
2236 int32_write_value (TestTypeNode *node,
2238 DBusTypeWriter *writer,
2241 /* also used for uint32 */
2244 v = int32_from_seed (seed);
2246 return _dbus_type_writer_write_basic (writer,
2247 node->klass->typecode,
2252 int32_read_value (TestTypeNode *node,
2253 DBusTypeReader *reader,
2256 /* also used for uint32 */
2259 check_expected_type (reader, node->klass->typecode);
2261 _dbus_type_reader_read_basic (reader,
2262 (dbus_int32_t*) &v);
2264 _dbus_assert (v == int32_from_seed (seed));
2270 int32_set_value (TestTypeNode *node,
2271 DBusTypeReader *reader,
2272 DBusTypeReader *realign_root,
2275 /* also used for uint32 */
2278 v = int32_from_seed (seed);
2280 return _dbus_type_reader_set_basic (reader,
2286 int32_write_multi (TestTypeNode *node,
2288 DBusTypeWriter *writer,
2292 /* also used for uint32 */
2293 dbus_int32_t values[MAX_MULTI_COUNT];
2294 dbus_int32_t *v_ARRAY_INT32 = values;
2297 for (i = 0; i < count; ++i)
2298 values[i] = int32_from_seed (seed + i);
2300 return _dbus_type_writer_write_fixed_multi (writer,
2301 node->klass->typecode,
2302 &v_ARRAY_INT32, count);
2306 int32_read_multi (TestTypeNode *node,
2307 DBusTypeReader *reader,
2311 /* also used for uint32 */
2312 dbus_int32_t *values;
2316 check_expected_type (reader, node->klass->typecode);
2318 _dbus_type_reader_read_fixed_multi (reader,
2322 if (n_elements != count)
2323 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2324 _dbus_assert (n_elements == count);
2326 for (i = 0; i < count; i++)
2327 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2328 (const unsigned char*)values + (i * 4))) ==
2329 int32_from_seed (seed + i));
2334 #ifdef DBUS_HAVE_INT64
2336 int64_from_seed (int seed)
2341 v32 = int32_from_seed (seed);
2343 v = - (dbus_int32_t) ~ v32;
2344 v |= (((dbus_int64_t)v32) << 32);
2351 int64_write_value (TestTypeNode *node,
2353 DBusTypeWriter *writer,
2356 #ifdef DBUS_HAVE_INT64
2357 /* also used for uint64 */
2360 v = int64_from_seed (seed);
2362 return _dbus_type_writer_write_basic (writer,
2363 node->klass->typecode,
2371 int64_read_value (TestTypeNode *node,
2372 DBusTypeReader *reader,
2375 #ifdef DBUS_HAVE_INT64
2376 /* also used for uint64 */
2379 check_expected_type (reader, node->klass->typecode);
2381 _dbus_type_reader_read_basic (reader,
2382 (dbus_int64_t*) &v);
2384 _dbus_assert (v == int64_from_seed (seed));
2393 int64_set_value (TestTypeNode *node,
2394 DBusTypeReader *reader,
2395 DBusTypeReader *realign_root,
2398 #ifdef DBUS_HAVE_INT64
2399 /* also used for uint64 */
2402 v = int64_from_seed (seed);
2404 return _dbus_type_reader_set_basic (reader,
2412 #define MAX_SAMPLE_STRING_LEN 10
2414 string_from_seed (char *buf,
2421 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2423 /* vary the length slightly, though we also have multiple string
2424 * value types for this, varying it here tests the set_value code
2438 v = (unsigned char) ('A' + seed);
2443 if (v < 'A' || v > 'z')
2456 string_write_value (TestTypeNode *node,
2458 DBusTypeWriter *writer,
2461 char buf[MAX_SAMPLE_STRING_LEN + 1]="";
2462 const char *v_string = buf;
2465 string_from_seed (buf, node->klass->subclass_detail,
2468 return _dbus_type_writer_write_basic (writer,
2469 node->klass->typecode,
2474 string_read_value (TestTypeNode *node,
2475 DBusTypeReader *reader,
2479 char buf[MAX_SAMPLE_STRING_LEN + 1];
2482 check_expected_type (reader, node->klass->typecode);
2484 _dbus_type_reader_read_basic (reader,
2485 (const char **) &v);
2487 string_from_seed (buf, node->klass->subclass_detail,
2490 if (strcmp (buf, v) != 0)
2492 _dbus_warn ("read string '%s' expected '%s'\n",
2494 _dbus_assert_not_reached ("test failed");
2501 string_set_value (TestTypeNode *node,
2502 DBusTypeReader *reader,
2503 DBusTypeReader *realign_root,
2506 char buf[MAX_SAMPLE_STRING_LEN + 1];
2507 const char *v_string = buf;
2509 string_from_seed (buf, node->klass->subclass_detail,
2512 #if RECURSIVE_MARSHAL_WRITE_TRACE
2515 _dbus_type_reader_read_basic (reader, &old);
2516 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2517 v_string, strlen (v_string), old, strlen (old));
2521 return _dbus_type_reader_set_basic (reader,
2526 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2529 bool_write_value (TestTypeNode *node,
2531 DBusTypeWriter *writer,
2536 v = BOOL_FROM_SEED (seed);
2538 return _dbus_type_writer_write_basic (writer,
2539 node->klass->typecode,
2544 bool_read_value (TestTypeNode *node,
2545 DBusTypeReader *reader,
2550 check_expected_type (reader, node->klass->typecode);
2552 _dbus_type_reader_read_basic (reader,
2553 (unsigned char*) &v);
2555 _dbus_assert (v == BOOL_FROM_SEED (seed));
2561 bool_set_value (TestTypeNode *node,
2562 DBusTypeReader *reader,
2563 DBusTypeReader *realign_root,
2568 v = BOOL_FROM_SEED (seed);
2570 return _dbus_type_reader_set_basic (reader,
2575 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2578 byte_write_value (TestTypeNode *node,
2580 DBusTypeWriter *writer,
2585 v = BYTE_FROM_SEED (seed);
2587 return _dbus_type_writer_write_basic (writer,
2588 node->klass->typecode,
2593 byte_read_value (TestTypeNode *node,
2594 DBusTypeReader *reader,
2599 check_expected_type (reader, node->klass->typecode);
2601 _dbus_type_reader_read_basic (reader,
2602 (unsigned char*) &v);
2604 _dbus_assert (v == BYTE_FROM_SEED (seed));
2611 byte_set_value (TestTypeNode *node,
2612 DBusTypeReader *reader,
2613 DBusTypeReader *realign_root,
2618 v = BYTE_FROM_SEED (seed);
2620 return _dbus_type_reader_set_basic (reader,
2626 double_from_seed (int seed)
2628 return SAMPLE_INT32 * (double) seed + 0.3;
2632 double_write_value (TestTypeNode *node,
2634 DBusTypeWriter *writer,
2639 v = double_from_seed (seed);
2641 return _dbus_type_writer_write_basic (writer,
2642 node->klass->typecode,
2647 double_read_value (TestTypeNode *node,
2648 DBusTypeReader *reader,
2654 check_expected_type (reader, node->klass->typecode);
2656 _dbus_type_reader_read_basic (reader,
2659 expected = double_from_seed (seed);
2661 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2663 #ifdef DBUS_HAVE_INT64
2664 _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
2666 *(dbus_uint64_t*)(char*)&expected,
2667 *(dbus_uint64_t*)(char*)&v);
2669 _dbus_assert_not_reached ("test failed");
2676 double_set_value (TestTypeNode *node,
2677 DBusTypeReader *reader,
2678 DBusTypeReader *realign_root,
2683 v = double_from_seed (seed);
2685 return _dbus_type_reader_set_basic (reader,
2690 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2692 object_path_from_seed (char *buf,
2700 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2702 v = (unsigned char) ('A' + seed);
2714 if (v < 'A' || v > 'z')
2730 object_path_write_value (TestTypeNode *node,
2732 DBusTypeWriter *writer,
2735 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2736 const char *v_string = buf;
2738 object_path_from_seed (buf, seed);
2740 return _dbus_type_writer_write_basic (writer,
2741 node->klass->typecode,
2746 object_path_read_value (TestTypeNode *node,
2747 DBusTypeReader *reader,
2751 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2753 check_expected_type (reader, node->klass->typecode);
2755 _dbus_type_reader_read_basic (reader,
2756 (const char **) &v);
2758 object_path_from_seed (buf, seed);
2760 if (strcmp (buf, v) != 0)
2762 _dbus_warn ("read object path '%s' expected '%s'\n",
2764 _dbus_assert_not_reached ("test failed");
2771 object_path_set_value (TestTypeNode *node,
2772 DBusTypeReader *reader,
2773 DBusTypeReader *realign_root,
2776 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2777 const char *v_string = buf;
2779 object_path_from_seed (buf, seed);
2781 return _dbus_type_reader_set_basic (reader,
2786 #define MAX_SAMPLE_SIGNATURE_LEN 10
2788 signature_from_seed (char *buf,
2791 /* try to avoid ascending, descending, or alternating length to help find bugs */
2792 const char *sample_signatures[] = {
2801 strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
2805 signature_write_value (TestTypeNode *node,
2807 DBusTypeWriter *writer,
2810 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2811 const char *v_string = buf;
2813 signature_from_seed (buf, seed);
2815 return _dbus_type_writer_write_basic (writer,
2816 node->klass->typecode,
2821 signature_read_value (TestTypeNode *node,
2822 DBusTypeReader *reader,
2826 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2828 check_expected_type (reader, node->klass->typecode);
2830 _dbus_type_reader_read_basic (reader,
2831 (const char **) &v);
2833 signature_from_seed (buf, seed);
2835 if (strcmp (buf, v) != 0)
2837 _dbus_warn ("read signature value '%s' expected '%s'\n",
2839 _dbus_assert_not_reached ("test failed");
2847 signature_set_value (TestTypeNode *node,
2848 DBusTypeReader *reader,
2849 DBusTypeReader *realign_root,
2852 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2853 const char *v_string = buf;
2855 signature_from_seed (buf, seed);
2857 return _dbus_type_reader_set_basic (reader,
2863 struct_write_value (TestTypeNode *node,
2865 DBusTypeWriter *writer,
2868 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2869 DataBlockState saved;
2874 n_copies = node->klass->subclass_detail;
2876 _dbus_assert (container->children != NULL);
2878 data_block_save (block, &saved);
2880 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2886 while (i < n_copies)
2890 link = _dbus_list_get_first_link (&container->children);
2891 while (link != NULL)
2893 TestTypeNode *child = link->data;
2894 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2896 if (!node_write_value (child, block, &sub, seed + i))
2898 data_block_restore (block, &saved);
2908 if (!_dbus_type_writer_unrecurse (writer, &sub))
2910 data_block_restore (block, &saved);
2918 struct_read_or_set_value (TestTypeNode *node,
2919 DBusTypeReader *reader,
2920 DBusTypeReader *realign_root,
2923 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2928 n_copies = node->klass->subclass_detail;
2930 check_expected_type (reader, DBUS_TYPE_STRUCT);
2932 _dbus_type_reader_recurse (reader, &sub);
2935 while (i < n_copies)
2939 link = _dbus_list_get_first_link (&container->children);
2940 while (link != NULL)
2942 TestTypeNode *child = link->data;
2943 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2945 if (realign_root == NULL)
2947 if (!node_read_value (child, &sub, seed + i))
2952 if (!node_set_value (child, &sub, realign_root, seed + i))
2956 if (i == (n_copies - 1) && next == NULL)
2957 NEXT_EXPECTING_FALSE (&sub);
2959 NEXT_EXPECTING_TRUE (&sub);
2971 struct_read_value (TestTypeNode *node,
2972 DBusTypeReader *reader,
2975 return struct_read_or_set_value (node, reader, NULL, seed);
2979 struct_set_value (TestTypeNode *node,
2980 DBusTypeReader *reader,
2981 DBusTypeReader *realign_root,
2984 return struct_read_or_set_value (node, reader, realign_root, seed);
2988 struct_build_signature (TestTypeNode *node,
2991 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2996 n_copies = node->klass->subclass_detail;
2998 orig_len = _dbus_string_get_length (str);
3000 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
3004 while (i < n_copies)
3008 link = _dbus_list_get_first_link (&container->children);
3009 while (link != NULL)
3011 TestTypeNode *child = link->data;
3012 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3014 if (!node_build_signature (child, str))
3023 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
3029 _dbus_string_set_length (str, orig_len);
3034 array_write_value (TestTypeNode *node,
3036 DBusTypeWriter *writer,
3039 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3040 DataBlockState saved;
3042 DBusString element_signature;
3046 TestTypeNode *child;
3048 n_copies = node->klass->subclass_detail;
3050 _dbus_assert (container->children != NULL);
3052 data_block_save (block, &saved);
3054 if (!_dbus_string_init (&element_signature))
3057 child = _dbus_list_get_first (&container->children);
3059 if (!node_build_signature (child,
3060 &element_signature))
3063 element_type = _dbus_first_type_in_signature (&element_signature, 0);
3065 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3066 &element_signature, 0,
3070 if (arrays_write_fixed_in_blocks &&
3071 dbus_type_is_fixed (element_type) &&
3072 child->klass->write_multi)
3074 if (!node_write_multi (child, block, &sub, seed, n_copies))
3080 while (i < n_copies)
3084 link = _dbus_list_get_first_link (&container->children);
3085 while (link != NULL)
3087 TestTypeNode *child = link->data;
3088 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3090 if (!node_write_value (child, block, &sub, seed + i))
3100 if (!_dbus_type_writer_unrecurse (writer, &sub))
3103 _dbus_string_free (&element_signature);
3107 data_block_restore (block, &saved);
3108 _dbus_string_free (&element_signature);
3113 array_read_or_set_value (TestTypeNode *node,
3114 DBusTypeReader *reader,
3115 DBusTypeReader *realign_root,
3118 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3122 TestTypeNode *child;
3124 n_copies = node->klass->subclass_detail;
3126 check_expected_type (reader, DBUS_TYPE_ARRAY);
3128 child = _dbus_list_get_first (&container->children);
3132 _dbus_type_reader_recurse (reader, &sub);
3134 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
3135 dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
3136 child->klass->read_multi)
3138 if (!node_read_multi (child, &sub, seed, n_copies))
3144 while (i < n_copies)
3148 link = _dbus_list_get_first_link (&container->children);
3149 while (link != NULL)
3151 TestTypeNode *child = link->data;
3152 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3154 _dbus_assert (child->klass->typecode ==
3155 _dbus_type_reader_get_element_type (reader));
3157 if (realign_root == NULL)
3159 if (!node_read_value (child, &sub, seed + i))
3164 if (!node_set_value (child, &sub, realign_root, seed + i))
3168 if (i == (n_copies - 1) && next == NULL)
3169 NEXT_EXPECTING_FALSE (&sub);
3171 NEXT_EXPECTING_TRUE (&sub);
3185 array_read_value (TestTypeNode *node,
3186 DBusTypeReader *reader,
3189 return array_read_or_set_value (node, reader, NULL, seed);
3193 array_set_value (TestTypeNode *node,
3194 DBusTypeReader *reader,
3195 DBusTypeReader *realign_root,
3198 return array_read_or_set_value (node, reader, realign_root, seed);
3202 array_build_signature (TestTypeNode *node,
3205 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3208 orig_len = _dbus_string_get_length (str);
3210 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3213 if (!node_build_signature (_dbus_list_get_first (&container->children),
3220 _dbus_string_set_length (str, orig_len);
3224 /* 10 is random just to add another seed that we use in the suite */
3225 #define VARIANT_SEED 10
3228 variant_write_value (TestTypeNode *node,
3230 DBusTypeWriter *writer,
3233 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3234 DataBlockState saved;
3236 DBusString content_signature;
3237 TestTypeNode *child;
3239 _dbus_assert (container->children != NULL);
3240 _dbus_assert (_dbus_list_length_is_one (&container->children));
3242 child = _dbus_list_get_first (&container->children);
3244 data_block_save (block, &saved);
3246 if (!_dbus_string_init (&content_signature))
3249 if (!node_build_signature (child,
3250 &content_signature))
3253 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3254 &content_signature, 0,
3258 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3261 if (!_dbus_type_writer_unrecurse (writer, &sub))
3264 _dbus_string_free (&content_signature);
3268 data_block_restore (block, &saved);
3269 _dbus_string_free (&content_signature);
3274 variant_read_or_set_value (TestTypeNode *node,
3275 DBusTypeReader *reader,
3276 DBusTypeReader *realign_root,
3279 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3281 TestTypeNode *child;
3283 _dbus_assert (container->children != NULL);
3284 _dbus_assert (_dbus_list_length_is_one (&container->children));
3286 child = _dbus_list_get_first (&container->children);
3288 check_expected_type (reader, DBUS_TYPE_VARIANT);
3290 _dbus_type_reader_recurse (reader, &sub);
3292 if (realign_root == NULL)
3294 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3299 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3303 NEXT_EXPECTING_FALSE (&sub);
3309 variant_read_value (TestTypeNode *node,
3310 DBusTypeReader *reader,
3313 return variant_read_or_set_value (node, reader, NULL, seed);
3317 variant_set_value (TestTypeNode *node,
3318 DBusTypeReader *reader,
3319 DBusTypeReader *realign_root,
3322 return variant_read_or_set_value (node, reader, realign_root, seed);
3326 dict_write_value (TestTypeNode *node,
3328 DBusTypeWriter *writer,
3331 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3332 DataBlockState saved;
3334 DBusString entry_value_signature;
3335 DBusString dict_entry_signature;
3338 int entry_value_type;
3339 TestTypeNode *child;
3341 n_entries = node->klass->subclass_detail;
3343 _dbus_assert (container->children != NULL);
3345 data_block_save (block, &saved);
3347 if (!_dbus_string_init (&entry_value_signature))
3350 if (!_dbus_string_init (&dict_entry_signature))
3352 _dbus_string_free (&entry_value_signature);
3356 child = _dbus_list_get_first (&container->children);
3358 if (!node_build_signature (child,
3359 &entry_value_signature))
3362 if (!_dbus_string_append (&dict_entry_signature,
3363 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3364 DBUS_TYPE_INT32_AS_STRING))
3367 if (!_dbus_string_copy (&entry_value_signature, 0,
3368 &dict_entry_signature,
3369 _dbus_string_get_length (&dict_entry_signature)))
3372 if (!_dbus_string_append_byte (&dict_entry_signature,
3373 DBUS_DICT_ENTRY_END_CHAR))
3376 entry_value_type = _dbus_first_type_in_signature (&entry_value_signature, 0);
3378 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3379 &dict_entry_signature, 0,
3384 while (i < n_entries)
3386 DBusTypeWriter entry_sub;
3389 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
3394 key = int32_from_seed (seed + i);
3396 if (!_dbus_type_writer_write_basic (&entry_sub,
3401 if (!node_write_value (child, block, &entry_sub, seed + i))
3404 if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
3410 if (!_dbus_type_writer_unrecurse (writer, &sub))
3413 _dbus_string_free (&entry_value_signature);
3414 _dbus_string_free (&dict_entry_signature);
3418 data_block_restore (block, &saved);
3419 _dbus_string_free (&entry_value_signature);
3420 _dbus_string_free (&dict_entry_signature);
3425 dict_read_or_set_value (TestTypeNode *node,
3426 DBusTypeReader *reader,
3427 DBusTypeReader *realign_root,
3430 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3434 TestTypeNode *child;
3436 n_entries = node->klass->subclass_detail;
3438 check_expected_type (reader, DBUS_TYPE_ARRAY);
3440 child = _dbus_list_get_first (&container->children);
3444 _dbus_type_reader_recurse (reader, &sub);
3446 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3449 while (i < n_entries)
3451 DBusTypeReader entry_sub;
3453 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3455 _dbus_type_reader_recurse (&sub, &entry_sub);
3457 if (realign_root == NULL)
3461 check_expected_type (&entry_sub, DBUS_TYPE_INT32);
3463 _dbus_type_reader_read_basic (&entry_sub,
3464 (dbus_int32_t*) &v);
3466 _dbus_assert (v == int32_from_seed (seed + i));
3468 NEXT_EXPECTING_TRUE (&entry_sub);
3470 if (!node_read_value (child, &entry_sub, seed + i))
3473 NEXT_EXPECTING_FALSE (&entry_sub);
3479 v = int32_from_seed (seed + i);
3481 if (!_dbus_type_reader_set_basic (&entry_sub,
3486 NEXT_EXPECTING_TRUE (&entry_sub);
3488 if (!node_set_value (child, &entry_sub, realign_root, seed + i))
3491 NEXT_EXPECTING_FALSE (&entry_sub);
3494 if (i == (n_entries - 1))
3495 NEXT_EXPECTING_FALSE (&sub);
3497 NEXT_EXPECTING_TRUE (&sub);
3507 dict_read_value (TestTypeNode *node,
3508 DBusTypeReader *reader,
3511 return dict_read_or_set_value (node, reader, NULL, seed);
3515 dict_set_value (TestTypeNode *node,
3516 DBusTypeReader *reader,
3517 DBusTypeReader *realign_root,
3520 return dict_read_or_set_value (node, reader, realign_root, seed);
3524 dict_build_signature (TestTypeNode *node,
3527 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3530 orig_len = _dbus_string_get_length (str);
3532 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3535 if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
3538 if (!node_build_signature (_dbus_list_get_first (&container->children),
3542 if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
3548 _dbus_string_set_length (str, orig_len);
3553 container_destroy (TestTypeNode *node)
3555 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3558 link = _dbus_list_get_first_link (&container->children);
3559 while (link != NULL)
3561 TestTypeNode *child = link->data;
3562 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3564 node_destroy (child);
3566 _dbus_list_free_link (link);
3572 #endif /* DBUS_BUILD_TESTS */