1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #ifdef DBUS_ENABLE_EMBEDDED_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->eight.first32 = 0;
42 value->eight.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->eight.first32 == rhs->eight.first32 &&
63 lhs->eight.second32 == rhs->eight.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);
128 #ifndef DOXYGEN_SHOULD_SKIP_THIS
130 #include "dbus-test.h"
131 #include "dbus-list.h"
135 /* Whether to do the OOM stuff (only with other expensive tests) */
136 #define TEST_OOM_HANDLING 0
137 /* We do start offset 0 through 9, to get various alignment cases. Still this
138 * obviously makes the test suite run 10x as slow.
140 #define MAX_INITIAL_OFFSET 9
142 /* Largest iteration count to test copying, realignment,
143 * etc. with. i.e. we only test this stuff with some of the smaller
146 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
152 DBusString signature;
162 #define N_FENCE_BYTES 5
163 #define FENCE_BYTES_STR "abcde"
164 #define INITIAL_PADDING_BYTE '\0'
167 data_block_init (DataBlock *block,
171 if (!_dbus_string_init (&block->signature))
174 if (!_dbus_string_init (&block->body))
176 _dbus_string_free (&block->signature);
180 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
181 INITIAL_PADDING_BYTE) ||
182 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
183 INITIAL_PADDING_BYTE) ||
184 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
185 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
187 _dbus_string_free (&block->signature);
188 _dbus_string_free (&block->body);
192 block->byte_order = byte_order;
193 block->initial_offset = initial_offset;
199 data_block_save (DataBlock *block,
200 DataBlockState *state)
202 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
203 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
207 data_block_restore (DataBlock *block,
208 DataBlockState *state)
210 _dbus_string_delete (&block->signature,
211 state->saved_sig_len,
212 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
213 _dbus_string_delete (&block->body,
214 state->saved_body_len,
215 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
219 data_block_verify (DataBlock *block)
221 if (!_dbus_string_ends_with_c_str (&block->signature,
226 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
230 _dbus_verbose_bytes_of_string (&block->signature,
232 _dbus_string_get_length (&block->signature) - offset);
233 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
235 if (!_dbus_string_ends_with_c_str (&block->body,
240 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
244 _dbus_verbose_bytes_of_string (&block->body,
246 _dbus_string_get_length (&block->body) - offset);
247 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
250 _dbus_assert (_dbus_string_validate_nul (&block->signature,
251 0, block->initial_offset));
252 _dbus_assert (_dbus_string_validate_nul (&block->body,
253 0, block->initial_offset));
257 data_block_free (DataBlock *block)
259 data_block_verify (block);
261 _dbus_string_free (&block->signature);
262 _dbus_string_free (&block->body);
266 data_block_reset (DataBlock *block)
268 data_block_verify (block);
270 _dbus_string_delete (&block->signature,
271 block->initial_offset,
272 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
273 _dbus_string_delete (&block->body,
274 block->initial_offset,
275 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
277 data_block_verify (block);
281 data_block_init_reader_writer (DataBlock *block,
282 DBusTypeReader *reader,
283 DBusTypeWriter *writer)
286 _dbus_type_reader_init (reader,
289 block->initial_offset,
291 block->initial_offset);
294 _dbus_type_writer_init (writer,
297 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
299 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
303 real_check_expected_type (DBusTypeReader *reader,
305 const char *funcname,
310 t = _dbus_type_reader_get_current_type (reader);
314 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
315 _dbus_type_to_string (t),
316 _dbus_type_to_string (expected),
319 _dbus_assert_not_reached ("read wrong type");
323 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
325 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
327 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
328 _DBUS_FUNCTION_NAME, __LINE__); \
329 _dbus_assert_not_reached ("test failed"); \
333 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
335 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
336 _DBUS_FUNCTION_NAME, __LINE__); \
337 _dbus_assert_not_reached ("test failed"); \
339 check_expected_type (reader, DBUS_TYPE_INVALID); \
342 typedef struct TestTypeNode TestTypeNode;
343 typedef struct TestTypeNodeClass TestTypeNodeClass;
344 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
345 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
349 const TestTypeNodeClass *klass;
352 struct TestTypeNodeContainer
358 struct TestTypeNodeClass
364 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
366 dbus_bool_t (* construct) (TestTypeNode *node);
367 void (* destroy) (TestTypeNode *node);
369 dbus_bool_t (* write_value) (TestTypeNode *node,
371 DBusTypeWriter *writer,
373 dbus_bool_t (* read_value) (TestTypeNode *node,
374 DBusTypeReader *reader,
376 dbus_bool_t (* set_value) (TestTypeNode *node,
377 DBusTypeReader *reader,
378 DBusTypeReader *realign_root,
380 dbus_bool_t (* build_signature) (TestTypeNode *node,
382 dbus_bool_t (* write_multi) (TestTypeNode *node,
384 DBusTypeWriter *writer,
387 dbus_bool_t (* read_multi) (TestTypeNode *node,
388 DBusTypeReader *reader,
393 struct TestTypeNodeContainerClass
395 TestTypeNodeClass base;
398 /* FIXME this could be chilled out substantially by unifying
399 * the basic types into basic_write_value/basic_read_value
400 * and by merging read_value and set_value into one function
401 * taking a flag argument.
403 static dbus_bool_t int16_write_value (TestTypeNode *node,
405 DBusTypeWriter *writer,
407 static dbus_bool_t int16_read_value (TestTypeNode *node,
408 DBusTypeReader *reader,
410 static dbus_bool_t int16_set_value (TestTypeNode *node,
411 DBusTypeReader *reader,
412 DBusTypeReader *realign_root,
414 static dbus_bool_t int16_write_multi (TestTypeNode *node,
416 DBusTypeWriter *writer,
419 static dbus_bool_t int16_read_multi (TestTypeNode *node,
420 DBusTypeReader *reader,
423 static dbus_bool_t int32_write_value (TestTypeNode *node,
425 DBusTypeWriter *writer,
427 static dbus_bool_t int32_read_value (TestTypeNode *node,
428 DBusTypeReader *reader,
430 static dbus_bool_t int32_set_value (TestTypeNode *node,
431 DBusTypeReader *reader,
432 DBusTypeReader *realign_root,
434 static dbus_bool_t int32_write_multi (TestTypeNode *node,
436 DBusTypeWriter *writer,
439 static dbus_bool_t int32_read_multi (TestTypeNode *node,
440 DBusTypeReader *reader,
443 static dbus_bool_t int64_write_value (TestTypeNode *node,
445 DBusTypeWriter *writer,
447 static dbus_bool_t int64_read_value (TestTypeNode *node,
448 DBusTypeReader *reader,
450 static dbus_bool_t int64_set_value (TestTypeNode *node,
451 DBusTypeReader *reader,
452 DBusTypeReader *realign_root,
454 static dbus_bool_t string_write_value (TestTypeNode *node,
456 DBusTypeWriter *writer,
458 static dbus_bool_t string_read_value (TestTypeNode *node,
459 DBusTypeReader *reader,
461 static dbus_bool_t string_set_value (TestTypeNode *node,
462 DBusTypeReader *reader,
463 DBusTypeReader *realign_root,
465 static dbus_bool_t bool_write_value (TestTypeNode *node,
467 DBusTypeWriter *writer,
469 static dbus_bool_t bool_read_value (TestTypeNode *node,
470 DBusTypeReader *reader,
472 static dbus_bool_t bool_set_value (TestTypeNode *node,
473 DBusTypeReader *reader,
474 DBusTypeReader *realign_root,
476 static dbus_bool_t byte_write_value (TestTypeNode *node,
478 DBusTypeWriter *writer,
480 static dbus_bool_t byte_read_value (TestTypeNode *node,
481 DBusTypeReader *reader,
483 static dbus_bool_t byte_set_value (TestTypeNode *node,
484 DBusTypeReader *reader,
485 DBusTypeReader *realign_root,
487 static dbus_bool_t double_write_value (TestTypeNode *node,
489 DBusTypeWriter *writer,
491 static dbus_bool_t double_read_value (TestTypeNode *node,
492 DBusTypeReader *reader,
494 static dbus_bool_t double_set_value (TestTypeNode *node,
495 DBusTypeReader *reader,
496 DBusTypeReader *realign_root,
498 static dbus_bool_t object_path_write_value (TestTypeNode *node,
500 DBusTypeWriter *writer,
502 static dbus_bool_t object_path_read_value (TestTypeNode *node,
503 DBusTypeReader *reader,
505 static dbus_bool_t object_path_set_value (TestTypeNode *node,
506 DBusTypeReader *reader,
507 DBusTypeReader *realign_root,
509 static dbus_bool_t signature_write_value (TestTypeNode *node,
511 DBusTypeWriter *writer,
513 static dbus_bool_t signature_read_value (TestTypeNode *node,
514 DBusTypeReader *reader,
516 static dbus_bool_t signature_set_value (TestTypeNode *node,
517 DBusTypeReader *reader,
518 DBusTypeReader *realign_root,
520 static dbus_bool_t struct_write_value (TestTypeNode *node,
522 DBusTypeWriter *writer,
524 static dbus_bool_t struct_read_value (TestTypeNode *node,
525 DBusTypeReader *reader,
527 static dbus_bool_t struct_set_value (TestTypeNode *node,
528 DBusTypeReader *reader,
529 DBusTypeReader *realign_root,
531 static dbus_bool_t struct_build_signature (TestTypeNode *node,
533 static dbus_bool_t dict_write_value (TestTypeNode *node,
535 DBusTypeWriter *writer,
537 static dbus_bool_t dict_read_value (TestTypeNode *node,
538 DBusTypeReader *reader,
540 static dbus_bool_t dict_set_value (TestTypeNode *node,
541 DBusTypeReader *reader,
542 DBusTypeReader *realign_root,
544 static dbus_bool_t dict_build_signature (TestTypeNode *node,
546 static dbus_bool_t array_write_value (TestTypeNode *node,
548 DBusTypeWriter *writer,
550 static dbus_bool_t array_read_value (TestTypeNode *node,
551 DBusTypeReader *reader,
553 static dbus_bool_t array_set_value (TestTypeNode *node,
554 DBusTypeReader *reader,
555 DBusTypeReader *realign_root,
557 static dbus_bool_t array_build_signature (TestTypeNode *node,
559 static dbus_bool_t variant_write_value (TestTypeNode *node,
561 DBusTypeWriter *writer,
563 static dbus_bool_t variant_read_value (TestTypeNode *node,
564 DBusTypeReader *reader,
566 static dbus_bool_t variant_set_value (TestTypeNode *node,
567 DBusTypeReader *reader,
568 DBusTypeReader *realign_root,
570 static void container_destroy (TestTypeNode *node);
574 static const TestTypeNodeClass int16_class = {
576 sizeof (TestTypeNode),
588 static const TestTypeNodeClass uint16_class = {
590 sizeof (TestTypeNode),
594 int16_write_value, /* recycle from int16 */
595 int16_read_value, /* recycle from int16 */
596 int16_set_value, /* recycle from int16 */
598 int16_write_multi, /* recycle from int16 */
599 int16_read_multi /* recycle from int16 */
602 static const TestTypeNodeClass int32_class = {
604 sizeof (TestTypeNode),
616 static const TestTypeNodeClass uint32_class = {
618 sizeof (TestTypeNode),
622 int32_write_value, /* recycle from int32 */
623 int32_read_value, /* recycle from int32 */
624 int32_set_value, /* recycle from int32 */
626 int32_write_multi, /* recycle from int32 */
627 int32_read_multi /* recycle from int32 */
630 static const TestTypeNodeClass int64_class = {
632 sizeof (TestTypeNode),
644 static const TestTypeNodeClass uint64_class = {
646 sizeof (TestTypeNode),
650 int64_write_value, /* recycle from int64 */
651 int64_read_value, /* recycle from int64 */
652 int64_set_value, /* recycle from int64 */
658 static const TestTypeNodeClass string_0_class = {
660 sizeof (TestTypeNode),
661 0, /* string length */
672 static const TestTypeNodeClass string_1_class = {
674 sizeof (TestTypeNode),
675 1, /* string length */
686 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
687 static const TestTypeNodeClass string_3_class = {
689 sizeof (TestTypeNode),
690 3, /* string length */
701 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
702 static const TestTypeNodeClass string_8_class = {
704 sizeof (TestTypeNode),
705 8, /* string length */
716 static const TestTypeNodeClass bool_class = {
718 sizeof (TestTypeNode),
730 static const TestTypeNodeClass byte_class = {
732 sizeof (TestTypeNode),
744 static const TestTypeNodeClass double_class = {
746 sizeof (TestTypeNode),
758 static const TestTypeNodeClass object_path_class = {
759 DBUS_TYPE_OBJECT_PATH,
760 sizeof (TestTypeNode),
764 object_path_write_value,
765 object_path_read_value,
766 object_path_set_value,
772 static const TestTypeNodeClass signature_class = {
774 sizeof (TestTypeNode),
778 signature_write_value,
779 signature_read_value,
786 static const TestTypeNodeClass struct_1_class = {
788 sizeof (TestTypeNodeContainer),
789 1, /* number of times children appear as fields */
795 struct_build_signature,
800 static const TestTypeNodeClass struct_2_class = {
802 sizeof (TestTypeNodeContainer),
803 2, /* number of times children appear as fields */
809 struct_build_signature,
814 static const TestTypeNodeClass dict_1_class = {
815 DBUS_TYPE_ARRAY, /* this is correct, a dict is an array of dict entry */
816 sizeof (TestTypeNodeContainer),
817 1, /* number of entries */
823 dict_build_signature,
828 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
830 static const TestTypeNodeClass array_0_class = {
832 sizeof (TestTypeNodeContainer),
833 0, /* number of array elements */
839 array_build_signature,
844 static const TestTypeNodeClass array_1_class = {
846 sizeof (TestTypeNodeContainer),
847 1, /* number of array elements */
853 array_build_signature,
858 static const TestTypeNodeClass array_2_class = {
860 sizeof (TestTypeNodeContainer),
861 2, /* number of array elements */
867 array_build_signature,
872 static const TestTypeNodeClass array_9_class = {
874 sizeof (TestTypeNodeContainer),
875 9, /* number of array elements */
881 array_build_signature,
886 static const TestTypeNodeClass variant_class = {
888 sizeof (TestTypeNodeContainer),
900 static const TestTypeNodeClass* const
918 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
920 static const TestTypeNodeClass* const
921 container_nodes[] = {
928 &dict_1_class /* last since we want struct and array before it */
929 /* array_9_class is omitted on purpose, it's too slow;
930 * we only use it in one hardcoded test below
933 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
936 node_new (const TestTypeNodeClass *klass)
940 node = dbus_malloc0 (klass->instance_size);
946 if (klass->construct)
948 if (!(* klass->construct) (node))
959 node_destroy (TestTypeNode *node)
961 if (node->klass->destroy)
962 (* node->klass->destroy) (node);
967 node_write_value (TestTypeNode *node,
969 DBusTypeWriter *writer,
974 retval = (* node->klass->write_value) (node, block, writer, seed);
977 /* Handy to see where things break, but too expensive to do all the time */
978 data_block_verify (block);
985 node_read_value (TestTypeNode *node,
986 DBusTypeReader *reader,
989 /* DBusTypeReader restored; */
991 if (!(* node->klass->read_value) (node, reader, seed))
997 /* Warning: if this one fails due to OOM, it has side effects (can
998 * modify only some of the sub-values). OK in a test suite, but we
999 * never do this in real code.
1002 node_set_value (TestTypeNode *node,
1003 DBusTypeReader *reader,
1004 DBusTypeReader *realign_root,
1007 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
1014 node_build_signature (TestTypeNode *node,
1017 if (node->klass->build_signature)
1018 return (* node->klass->build_signature) (node, str);
1020 return _dbus_string_append_byte (str, node->klass->typecode);
1024 node_append_child (TestTypeNode *node,
1025 TestTypeNode *child)
1027 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1029 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
1031 if (!_dbus_list_append (&container->children, child))
1032 _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 */
1038 node_write_multi (TestTypeNode *node,
1040 DBusTypeWriter *writer,
1046 _dbus_assert (node->klass->write_multi != NULL);
1047 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
1050 /* Handy to see where things break, but too expensive to do all the time */
1051 data_block_verify (block);
1058 node_read_multi (TestTypeNode *node,
1059 DBusTypeReader *reader,
1063 _dbus_assert (node->klass->read_multi != NULL);
1065 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1071 static int n_iterations_completed_total = 0;
1072 static int n_iterations_completed_this_test = 0;
1073 static int n_iterations_expected_this_test = 0;
1077 const DBusString *signature;
1080 TestTypeNode **nodes;
1082 } NodeIterationData;
1085 run_test_copy (NodeIterationData *nid)
1090 DBusTypeReader reader;
1091 DBusTypeWriter writer;
1093 _dbus_verbose ("\n");
1099 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1102 data_block_init_reader_writer (src, &reader, NULL);
1103 data_block_init_reader_writer (&dest, NULL, &writer);
1105 /* DBusTypeWriter assumes it's writing into an existing signature,
1106 * so doesn't add nul on its own. We have to do that.
1108 if (!_dbus_string_insert_byte (&dest.signature,
1109 dest.initial_offset, '\0'))
1112 if (!_dbus_type_writer_write_reader (&writer, &reader))
1115 /* Data blocks should now be identical */
1116 if (!_dbus_string_equal (&src->signature, &dest.signature))
1118 _dbus_verbose ("SOURCE\n");
1119 _dbus_verbose_bytes_of_string (&src->signature, 0,
1120 _dbus_string_get_length (&src->signature));
1121 _dbus_verbose ("DEST\n");
1122 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1123 _dbus_string_get_length (&dest.signature));
1124 _dbus_assert_not_reached ("signatures did not match");
1127 if (!_dbus_string_equal (&src->body, &dest.body))
1129 _dbus_verbose ("SOURCE\n");
1130 _dbus_verbose_bytes_of_string (&src->body, 0,
1131 _dbus_string_get_length (&src->body));
1132 _dbus_verbose ("DEST\n");
1133 _dbus_verbose_bytes_of_string (&dest.body, 0,
1134 _dbus_string_get_length (&dest.body));
1135 _dbus_assert_not_reached ("bodies did not match");
1142 data_block_free (&dest);
1148 run_test_values_only_write (NodeIterationData *nid)
1150 DBusTypeReader reader;
1151 DBusTypeWriter writer;
1156 _dbus_verbose ("\n");
1160 data_block_reset (nid->block);
1162 sig_len = _dbus_string_get_length (nid->signature);
1164 _dbus_type_writer_init_values_only (&writer,
1165 nid->block->byte_order,
1168 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1169 _dbus_type_reader_init (&reader,
1170 nid->block->byte_order,
1173 nid->block->initial_offset);
1176 while (i < nid->n_nodes)
1178 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1184 /* if we wrote any typecodes then this would fail */
1185 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1187 /* But be sure we wrote out the values correctly */
1189 while (i < nid->n_nodes)
1191 if (!node_read_value (nid->nodes[i], &reader, i))
1194 if (i + 1 == nid->n_nodes)
1195 NEXT_EXPECTING_FALSE (&reader);
1197 NEXT_EXPECTING_TRUE (&reader);
1205 data_block_reset (nid->block);
1209 /* offset the seed for setting, so we set different numbers than
1210 * we originally wrote. Don't offset by a huge number since in
1211 * some cases it's value = possibilities[seed % n_possibilities]
1212 * and we don't want to wrap around. bool_from_seed
1213 * is just seed % 2 even.
1217 run_test_set_values (NodeIterationData *nid)
1219 DBusTypeReader reader;
1220 DBusTypeReader realign_root;
1224 _dbus_verbose ("\n");
1228 data_block_init_reader_writer (nid->block,
1231 realign_root = reader;
1234 while (i < nid->n_nodes)
1236 if (!node_set_value (nid->nodes[i],
1237 &reader, &realign_root,
1241 if (i + 1 == nid->n_nodes)
1242 NEXT_EXPECTING_FALSE (&reader);
1244 NEXT_EXPECTING_TRUE (&reader);
1249 /* Check that the new values were set */
1251 reader = realign_root;
1254 while (i < nid->n_nodes)
1256 if (!node_read_value (nid->nodes[i], &reader,
1260 if (i + 1 == nid->n_nodes)
1261 NEXT_EXPECTING_FALSE (&reader);
1263 NEXT_EXPECTING_TRUE (&reader);
1275 run_test_delete_values (NodeIterationData *nid)
1277 DBusTypeReader reader;
1281 _dbus_verbose ("\n");
1285 data_block_init_reader_writer (nid->block,
1288 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1290 /* Right now, deleting only works on array elements. We delete
1291 * all array elements, and then verify that there aren't any
1294 if (t == DBUS_TYPE_ARRAY)
1296 DBusTypeReader array;
1300 _dbus_type_reader_recurse (&reader, &array);
1302 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1305 _dbus_type_reader_next (&array);
1308 /* reset to start of array */
1309 _dbus_type_reader_recurse (&reader, &array);
1310 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1311 reader.value_pos, array.value_pos, array.u.array.start_pos);
1312 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1314 /* We don't want to always delete from the same part of the array. */
1315 static int cycle = 0;
1318 _dbus_assert (n_elements > 0);
1321 if (elem == 3 || elem >= n_elements) /* end of array */
1322 elem = n_elements - 1;
1324 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1325 elem, n_elements, _dbus_type_to_string (elem_type),
1326 cycle, reader.value_pos, array.value_pos);
1329 if (!_dbus_type_reader_next (&array))
1330 _dbus_assert_not_reached ("should have had another element\n");
1334 if (!_dbus_type_reader_delete (&array, &reader))
1340 _dbus_type_reader_recurse (&reader, &array);
1348 _dbus_type_reader_next (&reader);
1351 /* Check that there are no array elements left */
1352 data_block_init_reader_writer (nid->block,
1355 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1357 _dbus_type_reader_next (&reader);
1367 run_test_nodes_iteration (void *data)
1369 NodeIterationData *nid = data;
1370 DBusTypeReader reader;
1371 DBusTypeWriter writer;
1376 * 1. write the value
1377 * 2. strcmp-compare with the signature we built
1379 * 4. type-iterate the signature and the value and see if they are the same type-wise
1383 data_block_init_reader_writer (nid->block,
1386 /* DBusTypeWriter assumes it's writing into an existing signature,
1387 * so doesn't add nul on its own. We have to do that.
1389 if (!_dbus_string_insert_byte (&nid->block->signature,
1390 nid->type_offset, '\0'))
1394 while (i < nid->n_nodes)
1396 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1402 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1403 &nid->block->signature, nid->type_offset))
1405 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1406 _dbus_string_get_const_data (nid->signature),
1407 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1409 _dbus_assert_not_reached ("wrong signature");
1413 while (i < nid->n_nodes)
1415 if (!node_read_value (nid->nodes[i], &reader, i))
1418 if (i + 1 == nid->n_nodes)
1419 NEXT_EXPECTING_FALSE (&reader);
1421 NEXT_EXPECTING_TRUE (&reader);
1426 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1428 /* this set values test uses code from copy and
1429 * values_only_write so would ideally be last so you get a
1430 * simpler test case for problems with copying or values_only
1431 * writing; but it also needs an already-written DataBlock so it
1432 * has to go first. Comment it out if it breaks, and see if the
1433 * later tests also break - debug them first if so.
1435 if (!run_test_set_values (nid))
1438 if (!run_test_delete_values (nid))
1441 if (!run_test_copy (nid))
1444 if (!run_test_values_only_write (nid))
1448 /* FIXME type-iterate both signature and value and compare the resulting
1449 * tree to the node tree perhaps
1456 data_block_reset (nid->block);
1462 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1464 const DBusString *signature,
1469 NodeIterationData nid;
1471 if (!data_block_init (&block, byte_order, initial_offset))
1472 _dbus_assert_not_reached ("no memory");
1474 nid.signature = signature;
1476 nid.type_offset = initial_offset;
1478 nid.n_nodes = n_nodes;
1480 if (TEST_OOM_HANDLING &&
1481 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1483 _dbus_test_oom_handling ("running test node",
1484 run_test_nodes_iteration,
1489 if (!run_test_nodes_iteration (&nid))
1490 _dbus_assert_not_reached ("no memory");
1493 data_block_free (&block);
1497 run_test_nodes (TestTypeNode **nodes,
1501 DBusString signature;
1503 if (!_dbus_string_init (&signature))
1504 _dbus_assert_not_reached ("no memory");
1509 if (! node_build_signature (nodes[i], &signature))
1510 _dbus_assert_not_reached ("no memory");
1515 _dbus_verbose (">>> test nodes with signature '%s'\n",
1516 _dbus_string_get_const_data (&signature));
1519 while (i <= MAX_INITIAL_OFFSET)
1521 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1522 DBUS_LITTLE_ENDIAN, i);
1523 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1524 DBUS_BIG_ENDIAN, i);
1529 n_iterations_completed_this_test += 1;
1530 n_iterations_completed_total += 1;
1532 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1534 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1535 n_iterations_completed_this_test,
1536 n_iterations_completed_total);
1538 /* this happens to turn out well with mod == 1 */
1539 else if ((n_iterations_completed_this_test %
1540 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1542 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1545 _dbus_string_free (&signature);
1548 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1550 static TestTypeNode*
1551 value_generator (int *ip)
1554 const TestTypeNodeClass *child_klass;
1555 const TestTypeNodeClass *container_klass;
1556 TestTypeNode *child;
1559 _dbus_assert (i <= N_VALUES);
1565 else if (i < N_BASICS)
1567 node = node_new (basic_nodes[i]);
1571 /* imagine an array:
1572 * container 0 of basic 0
1573 * container 0 of basic 1
1574 * container 0 of basic 2
1575 * container 1 of basic 0
1576 * container 1 of basic 1
1577 * container 1 of basic 2
1581 container_klass = container_nodes[i / N_BASICS];
1582 child_klass = basic_nodes[i % N_BASICS];
1584 node = node_new (container_klass);
1585 child = node_new (child_klass);
1587 node_append_child (node, child);
1590 *ip += 1; /* increment the generator */
1596 build_body (TestTypeNode **nodes,
1599 DBusString *signature,
1604 DBusTypeReader reader;
1605 DBusTypeWriter writer;
1610 if (! node_build_signature (nodes[i], signature))
1611 _dbus_assert_not_reached ("no memory");
1616 if (!data_block_init (&block, byte_order, 0))
1617 _dbus_assert_not_reached ("no memory");
1619 data_block_init_reader_writer (&block,
1622 /* DBusTypeWriter assumes it's writing into an existing signature,
1623 * so doesn't add nul on its own. We have to do that.
1625 if (!_dbus_string_insert_byte (&block.signature,
1627 _dbus_assert_not_reached ("no memory");
1632 if (!node_write_value (nodes[i], &block, &writer, i))
1633 _dbus_assert_not_reached ("no memory");
1638 if (!_dbus_string_copy_len (&block.body, 0,
1639 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1641 _dbus_assert_not_reached ("oom");
1643 data_block_free (&block);
1647 dbus_internal_do_not_use_generate_bodies (int sequence,
1649 DBusString *signature,
1652 TestTypeNode *nodes[1];
1656 nodes[0] = value_generator (&sequence);
1658 if (nodes[0] == NULL)
1663 build_body (nodes, n_nodes, byte_order, signature, body);
1669 node_destroy (nodes[i]);
1677 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1681 TestTypeNode *container;
1682 TestTypeNode *child;
1685 root = node_new (container_klass);
1687 for (i = 1; i < n_nested; i++)
1689 child = node_new (container_klass);
1690 node_append_child (container, child);
1694 /* container should now be the most-nested container */
1697 while ((child = value_generator (&i)))
1699 node_append_child (container, child);
1701 run_test_nodes (&root, 1);
1703 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1704 node_destroy (child);
1707 node_destroy (root);
1711 start_next_test (const char *format,
1714 n_iterations_completed_this_test = 0;
1715 n_iterations_expected_this_test = expected;
1717 fprintf (stderr, ">>> >>> ");
1718 fprintf (stderr, format,
1719 n_iterations_expected_this_test);
1723 make_and_run_test_nodes (void)
1727 /* We try to do this in order of "complicatedness" so that test
1728 * failures tend to show up in the simplest test case that
1729 * demonstrates the failure. There are also some tests that run
1730 * more than once for this reason, first while going through simple
1731 * cases, second while going through a broader range of complex
1734 /* Each basic node. The basic nodes should include:
1736 * - each fixed-size type (in such a way that it has different values each time,
1737 * so we can tell if we mix two of them up)
1738 * - strings of various lengths
1742 /* Each container node. The container nodes should include:
1744 * struct with 1 and 2 copies of the contained item
1745 * array with 0, 1, 2 copies of the contained item
1748 /* Let a "value" be a basic node, or a container containing a single basic node.
1749 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1750 * When iterating through all values to make combinations, do the basic types
1751 * first and the containers second.
1753 /* Each item is shown with its number of iterations to complete so
1754 * we can keep a handle on this unit test
1757 /* FIXME test just an empty body, no types at all */
1759 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1763 while ((node = value_generator (&i)))
1765 run_test_nodes (&node, 1);
1767 node_destroy (node);
1771 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1772 arrays_write_fixed_in_blocks = TRUE;
1776 while ((node = value_generator (&i)))
1778 run_test_nodes (&node, 1);
1780 node_destroy (node);
1783 arrays_write_fixed_in_blocks = FALSE;
1785 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1787 TestTypeNode *nodes[N_VALUES];
1790 while ((nodes[i] = value_generator (&i)))
1793 run_test_nodes (nodes, N_VALUES);
1795 for (i = 0; i < N_VALUES; i++)
1796 node_destroy (nodes[i]);
1799 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1800 N_VALUES * N_VALUES);
1802 TestTypeNode *nodes[2];
1805 while ((nodes[0] = value_generator (&i)))
1808 while ((nodes[1] = value_generator (&j)))
1810 run_test_nodes (nodes, 2);
1812 node_destroy (nodes[1]);
1815 node_destroy (nodes[0]);
1819 start_next_test ("Each container containing each value %d iterations\n",
1820 N_CONTAINERS * N_VALUES);
1821 for (i = 0; i < N_CONTAINERS; i++)
1823 const TestTypeNodeClass *container_klass = container_nodes[i];
1825 make_and_run_values_inside_container (container_klass, 1);
1828 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1829 N_CONTAINERS * N_VALUES);
1830 arrays_write_fixed_in_blocks = TRUE;
1831 for (i = 0; i < N_CONTAINERS; i++)
1833 const TestTypeNodeClass *container_klass = container_nodes[i];
1835 make_and_run_values_inside_container (container_klass, 1);
1837 arrays_write_fixed_in_blocks = FALSE;
1839 start_next_test ("Each container of same container of each value %d iterations\n",
1840 N_CONTAINERS * N_VALUES);
1841 for (i = 0; i < N_CONTAINERS; i++)
1843 const TestTypeNodeClass *container_klass = container_nodes[i];
1845 make_and_run_values_inside_container (container_klass, 2);
1848 start_next_test ("Each container of same 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, 3);
1857 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1858 N_VALUES * N_VALUES);
1860 TestTypeNode *val1, *val2;
1863 node = node_new (&struct_1_class);
1866 while ((val1 = value_generator (&i)))
1869 while ((val2 = value_generator (&j)))
1871 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1873 node_append_child (node, val1);
1874 node_append_child (node, val2);
1876 run_test_nodes (&node, 1);
1878 _dbus_list_clear (&container->children);
1879 node_destroy (val2);
1881 node_destroy (val1);
1883 node_destroy (node);
1886 start_next_test ("All values in one big struct %d iteration\n",
1890 TestTypeNode *child;
1892 node = node_new (&struct_1_class);
1895 while ((child = value_generator (&i)))
1896 node_append_child (node, child);
1898 run_test_nodes (&node, 1);
1900 node_destroy (node);
1903 start_next_test ("Each value in a large array %d iterations\n",
1909 node = node_new (&array_9_class);
1912 while ((val = value_generator (&i)))
1914 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1916 node_append_child (node, val);
1918 run_test_nodes (&node, 1);
1920 _dbus_list_clear (&container->children);
1924 node_destroy (node);
1927 if (_dbus_getenv ("DBUS_TEST_SLOW") == NULL ||
1928 atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 1)
1930 fprintf (stderr, "skipping remaining marshal-recursive tests, "
1931 "run with DBUS_TEST_SLOW=1 (or more) to enable\n");
1935 start_next_test ("Each container of each container of each value %d iterations\n",
1936 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1937 for (i = 0; i < N_CONTAINERS; i++)
1939 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1940 TestTypeNode *outer_container = node_new (outer_container_klass);
1942 for (j = 0; j < N_CONTAINERS; j++)
1944 TestTypeNode *child;
1945 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1946 TestTypeNode *inner_container = node_new (inner_container_klass);
1948 node_append_child (outer_container, inner_container);
1951 while ((child = value_generator (&m)))
1953 node_append_child (inner_container, child);
1955 run_test_nodes (&outer_container, 1);
1957 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1958 node_destroy (child);
1960 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1961 node_destroy (inner_container);
1963 node_destroy (outer_container);
1966 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1967 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1968 for (i = 0; i < N_CONTAINERS; i++)
1970 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1971 TestTypeNode *outer_container = node_new (outer_container_klass);
1973 for (j = 0; j < N_CONTAINERS; j++)
1975 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1976 TestTypeNode *inner_container = node_new (inner_container_klass);
1978 node_append_child (outer_container, inner_container);
1980 for (k = 0; k < N_CONTAINERS; k++)
1982 TestTypeNode *child;
1983 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1984 TestTypeNode *center_container = node_new (center_container_klass);
1986 node_append_child (inner_container, center_container);
1989 while ((child = value_generator (&m)))
1991 node_append_child (center_container, child);
1993 run_test_nodes (&outer_container, 1);
1995 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1996 node_destroy (child);
1998 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1999 node_destroy (center_container);
2001 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
2002 node_destroy (inner_container);
2004 node_destroy (outer_container);
2007 /* This one takes a really long time (10 minutes on a Core2), so only enable
2008 * it if you're really sure */
2009 if (atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 2)
2011 fprintf (stderr, "skipping really slow marshal-recursive test, "
2012 "run with DBUS_TEST_SLOW=2 (or more) to enable\n");
2016 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
2017 N_VALUES * N_VALUES * N_VALUES);
2019 TestTypeNode *nodes[3];
2022 while ((nodes[0] = value_generator (&i)))
2025 while ((nodes[1] = value_generator (&j)))
2028 while ((nodes[2] = value_generator (&k)))
2030 run_test_nodes (nodes, 3);
2032 node_destroy (nodes[2]);
2034 node_destroy (nodes[1]);
2036 node_destroy (nodes[0]);
2041 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
2042 n_iterations_completed_total);
2043 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
2044 MAX_INITIAL_OFFSET);
2045 fprintf (stderr, "out of memory handling %s tested\n",
2046 TEST_OOM_HANDLING ? "was" : "was not");
2050 _dbus_marshal_recursive_test (void)
2052 make_and_run_test_nodes ();
2060 * Implementations of each type node class
2065 #define MAX_MULTI_COUNT 5
2067 #define SAMPLE_INT16 1234
2068 #define SAMPLE_INT16_ALTERNATE 6785
2070 int16_from_seed (int seed)
2072 /* Generate an integer value that's predictable from seed. We could
2073 * just use seed itself, but that would only ever touch one byte of
2074 * the int so would miss some kinds of bug.
2078 v = 42; /* just to quiet compiler afaik */
2085 v = SAMPLE_INT16_ALTERNATE;
2091 v = _DBUS_INT16_MAX;
2099 v *= seed; /* wraps around eventually, which is fine */
2105 int16_write_value (TestTypeNode *node,
2107 DBusTypeWriter *writer,
2110 /* also used for uint16 */
2113 v = int16_from_seed (seed);
2115 return _dbus_type_writer_write_basic (writer,
2116 node->klass->typecode,
2121 int16_read_value (TestTypeNode *node,
2122 DBusTypeReader *reader,
2125 /* also used for uint16 */
2128 check_expected_type (reader, node->klass->typecode);
2130 _dbus_type_reader_read_basic (reader,
2131 (dbus_int16_t*) &v);
2133 _dbus_assert (v == int16_from_seed (seed));
2139 int16_set_value (TestTypeNode *node,
2140 DBusTypeReader *reader,
2141 DBusTypeReader *realign_root,
2144 /* also used for uint16 */
2147 v = int16_from_seed (seed);
2149 return _dbus_type_reader_set_basic (reader,
2155 int16_write_multi (TestTypeNode *node,
2157 DBusTypeWriter *writer,
2161 /* also used for uint16 */
2162 dbus_int16_t values[MAX_MULTI_COUNT];
2163 dbus_int16_t *v_ARRAY_INT16 = values;
2166 for (i = 0; i < count; ++i)
2167 values[i] = int16_from_seed (seed + i);
2169 return _dbus_type_writer_write_fixed_multi (writer,
2170 node->klass->typecode,
2171 &v_ARRAY_INT16, count);
2175 int16_read_multi (TestTypeNode *node,
2176 DBusTypeReader *reader,
2180 /* also used for uint16 */
2181 dbus_int16_t *values;
2185 check_expected_type (reader, node->klass->typecode);
2187 _dbus_type_reader_read_fixed_multi (reader,
2191 if (n_elements != count)
2192 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2193 _dbus_assert (n_elements == count);
2195 for (i = 0; i < count; i++)
2196 _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
2197 (const unsigned char*)values + (i * 2))) ==
2198 int16_from_seed (seed + i));
2204 #define SAMPLE_INT32 12345678
2205 #define SAMPLE_INT32_ALTERNATE 53781429
2207 int32_from_seed (int seed)
2209 /* Generate an integer value that's predictable from seed. We could
2210 * just use seed itself, but that would only ever touch one byte of
2211 * the int so would miss some kinds of bug.
2215 v = 42; /* just to quiet compiler afaik */
2222 v = SAMPLE_INT32_ALTERNATE;
2236 v *= seed; /* wraps around eventually, which is fine */
2242 int32_write_value (TestTypeNode *node,
2244 DBusTypeWriter *writer,
2247 /* also used for uint32 */
2250 v = int32_from_seed (seed);
2252 return _dbus_type_writer_write_basic (writer,
2253 node->klass->typecode,
2258 int32_read_value (TestTypeNode *node,
2259 DBusTypeReader *reader,
2262 /* also used for uint32 */
2265 check_expected_type (reader, node->klass->typecode);
2267 _dbus_type_reader_read_basic (reader,
2268 (dbus_int32_t*) &v);
2270 _dbus_assert (v == int32_from_seed (seed));
2276 int32_set_value (TestTypeNode *node,
2277 DBusTypeReader *reader,
2278 DBusTypeReader *realign_root,
2281 /* also used for uint32 */
2284 v = int32_from_seed (seed);
2286 return _dbus_type_reader_set_basic (reader,
2292 int32_write_multi (TestTypeNode *node,
2294 DBusTypeWriter *writer,
2298 /* also used for uint32 */
2299 dbus_int32_t values[MAX_MULTI_COUNT];
2300 dbus_int32_t *v_ARRAY_INT32 = values;
2303 for (i = 0; i < count; ++i)
2304 values[i] = int32_from_seed (seed + i);
2306 return _dbus_type_writer_write_fixed_multi (writer,
2307 node->klass->typecode,
2308 &v_ARRAY_INT32, count);
2312 int32_read_multi (TestTypeNode *node,
2313 DBusTypeReader *reader,
2317 /* also used for uint32 */
2318 dbus_int32_t *values;
2322 check_expected_type (reader, node->klass->typecode);
2324 _dbus_type_reader_read_fixed_multi (reader,
2328 if (n_elements != count)
2329 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2330 _dbus_assert (n_elements == count);
2332 for (i = 0; i < count; i++)
2333 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2334 (const unsigned char*)values + (i * 4))) ==
2335 int32_from_seed (seed + i));
2340 #ifdef DBUS_HAVE_INT64
2342 int64_from_seed (int seed)
2347 v32 = int32_from_seed (seed);
2349 v = - (dbus_int32_t) ~ v32;
2350 v |= (((dbus_int64_t)v32) << 32);
2357 int64_write_value (TestTypeNode *node,
2359 DBusTypeWriter *writer,
2362 #ifdef DBUS_HAVE_INT64
2363 /* also used for uint64 */
2366 v = int64_from_seed (seed);
2368 return _dbus_type_writer_write_basic (writer,
2369 node->klass->typecode,
2377 int64_read_value (TestTypeNode *node,
2378 DBusTypeReader *reader,
2381 #ifdef DBUS_HAVE_INT64
2382 /* also used for uint64 */
2385 check_expected_type (reader, node->klass->typecode);
2387 _dbus_type_reader_read_basic (reader,
2388 (dbus_int64_t*) &v);
2390 _dbus_assert (v == int64_from_seed (seed));
2399 int64_set_value (TestTypeNode *node,
2400 DBusTypeReader *reader,
2401 DBusTypeReader *realign_root,
2404 #ifdef DBUS_HAVE_INT64
2405 /* also used for uint64 */
2408 v = int64_from_seed (seed);
2410 return _dbus_type_reader_set_basic (reader,
2418 #define MAX_SAMPLE_STRING_LEN 10
2420 string_from_seed (char *buf,
2427 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2429 /* vary the length slightly, though we also have multiple string
2430 * value types for this, varying it here tests the set_value code
2444 v = (unsigned char) ('A' + seed);
2449 if (v < 'A' || v > 'z')
2462 string_write_value (TestTypeNode *node,
2464 DBusTypeWriter *writer,
2467 char buf[MAX_SAMPLE_STRING_LEN + 1]="";
2468 const char *v_string = buf;
2471 string_from_seed (buf, node->klass->subclass_detail,
2474 return _dbus_type_writer_write_basic (writer,
2475 node->klass->typecode,
2480 string_read_value (TestTypeNode *node,
2481 DBusTypeReader *reader,
2485 char buf[MAX_SAMPLE_STRING_LEN + 1];
2488 check_expected_type (reader, node->klass->typecode);
2490 _dbus_type_reader_read_basic (reader,
2491 (const char **) &v);
2493 string_from_seed (buf, node->klass->subclass_detail,
2496 if (strcmp (buf, v) != 0)
2498 _dbus_warn ("read string '%s' expected '%s'\n",
2500 _dbus_assert_not_reached ("test failed");
2507 string_set_value (TestTypeNode *node,
2508 DBusTypeReader *reader,
2509 DBusTypeReader *realign_root,
2512 char buf[MAX_SAMPLE_STRING_LEN + 1];
2513 const char *v_string = buf;
2515 string_from_seed (buf, node->klass->subclass_detail,
2518 #if RECURSIVE_MARSHAL_WRITE_TRACE
2521 _dbus_type_reader_read_basic (reader, &old);
2522 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2523 v_string, strlen (v_string), old, strlen (old));
2527 return _dbus_type_reader_set_basic (reader,
2532 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2535 bool_write_value (TestTypeNode *node,
2537 DBusTypeWriter *writer,
2542 v = BOOL_FROM_SEED (seed);
2544 return _dbus_type_writer_write_basic (writer,
2545 node->klass->typecode,
2550 bool_read_value (TestTypeNode *node,
2551 DBusTypeReader *reader,
2556 check_expected_type (reader, node->klass->typecode);
2558 _dbus_type_reader_read_basic (reader,
2559 (unsigned char*) &v);
2561 _dbus_assert (v == BOOL_FROM_SEED (seed));
2567 bool_set_value (TestTypeNode *node,
2568 DBusTypeReader *reader,
2569 DBusTypeReader *realign_root,
2574 v = BOOL_FROM_SEED (seed);
2576 return _dbus_type_reader_set_basic (reader,
2581 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2584 byte_write_value (TestTypeNode *node,
2586 DBusTypeWriter *writer,
2591 v = BYTE_FROM_SEED (seed);
2593 return _dbus_type_writer_write_basic (writer,
2594 node->klass->typecode,
2599 byte_read_value (TestTypeNode *node,
2600 DBusTypeReader *reader,
2605 check_expected_type (reader, node->klass->typecode);
2607 _dbus_type_reader_read_basic (reader,
2608 (unsigned char*) &v);
2610 _dbus_assert (v == BYTE_FROM_SEED (seed));
2617 byte_set_value (TestTypeNode *node,
2618 DBusTypeReader *reader,
2619 DBusTypeReader *realign_root,
2624 v = BYTE_FROM_SEED (seed);
2626 return _dbus_type_reader_set_basic (reader,
2632 double_from_seed (int seed)
2634 return SAMPLE_INT32 * (double) seed + 0.3;
2638 double_write_value (TestTypeNode *node,
2640 DBusTypeWriter *writer,
2645 v = double_from_seed (seed);
2647 return _dbus_type_writer_write_basic (writer,
2648 node->klass->typecode,
2653 double_read_value (TestTypeNode *node,
2654 DBusTypeReader *reader,
2660 check_expected_type (reader, node->klass->typecode);
2662 _dbus_type_reader_read_basic (reader,
2665 expected = double_from_seed (seed);
2667 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2669 #ifdef DBUS_INT64_PRINTF_MODIFIER
2670 _dbus_warn ("Expected double %g got %g\n bits = 0x%" DBUS_INT64_PRINTF_MODIFIER "x vs.\n bits = 0x%" DBUS_INT64_PRINTF_MODIFIER "x)\n",
2672 *(dbus_uint64_t*)(char*)&expected,
2673 *(dbus_uint64_t*)(char*)&v);
2675 _dbus_assert_not_reached ("test failed");
2682 double_set_value (TestTypeNode *node,
2683 DBusTypeReader *reader,
2684 DBusTypeReader *realign_root,
2689 v = double_from_seed (seed);
2691 return _dbus_type_reader_set_basic (reader,
2696 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2698 object_path_from_seed (char *buf,
2706 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2708 v = (unsigned char) ('A' + seed);
2720 if (v < 'A' || v > 'z')
2736 object_path_write_value (TestTypeNode *node,
2738 DBusTypeWriter *writer,
2741 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2742 const char *v_string = buf;
2744 object_path_from_seed (buf, seed);
2746 return _dbus_type_writer_write_basic (writer,
2747 node->klass->typecode,
2752 object_path_read_value (TestTypeNode *node,
2753 DBusTypeReader *reader,
2757 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2759 check_expected_type (reader, node->klass->typecode);
2761 _dbus_type_reader_read_basic (reader,
2762 (const char **) &v);
2764 object_path_from_seed (buf, seed);
2766 if (strcmp (buf, v) != 0)
2768 _dbus_warn ("read object path '%s' expected '%s'\n",
2770 _dbus_assert_not_reached ("test failed");
2777 object_path_set_value (TestTypeNode *node,
2778 DBusTypeReader *reader,
2779 DBusTypeReader *realign_root,
2782 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2783 const char *v_string = buf;
2785 object_path_from_seed (buf, seed);
2787 return _dbus_type_reader_set_basic (reader,
2792 #define MAX_SAMPLE_SIGNATURE_LEN 10
2794 signature_from_seed (char *buf,
2797 /* try to avoid ascending, descending, or alternating length to help find bugs */
2798 const char *sample_signatures[] = {
2807 strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
2811 signature_write_value (TestTypeNode *node,
2813 DBusTypeWriter *writer,
2816 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2817 const char *v_string = buf;
2819 signature_from_seed (buf, seed);
2821 return _dbus_type_writer_write_basic (writer,
2822 node->klass->typecode,
2827 signature_read_value (TestTypeNode *node,
2828 DBusTypeReader *reader,
2832 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2834 check_expected_type (reader, node->klass->typecode);
2836 _dbus_type_reader_read_basic (reader,
2837 (const char **) &v);
2839 signature_from_seed (buf, seed);
2841 if (strcmp (buf, v) != 0)
2843 _dbus_warn ("read signature value '%s' expected '%s'\n",
2845 _dbus_assert_not_reached ("test failed");
2853 signature_set_value (TestTypeNode *node,
2854 DBusTypeReader *reader,
2855 DBusTypeReader *realign_root,
2858 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2859 const char *v_string = buf;
2861 signature_from_seed (buf, seed);
2863 return _dbus_type_reader_set_basic (reader,
2869 struct_write_value (TestTypeNode *node,
2871 DBusTypeWriter *writer,
2874 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2875 DataBlockState saved;
2880 n_copies = node->klass->subclass_detail;
2882 _dbus_assert (container->children != NULL);
2884 data_block_save (block, &saved);
2886 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2892 while (i < n_copies)
2896 link = _dbus_list_get_first_link (&container->children);
2897 while (link != NULL)
2899 TestTypeNode *child = link->data;
2900 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2902 if (!node_write_value (child, block, &sub, seed + i))
2904 data_block_restore (block, &saved);
2914 if (!_dbus_type_writer_unrecurse (writer, &sub))
2916 data_block_restore (block, &saved);
2924 struct_read_or_set_value (TestTypeNode *node,
2925 DBusTypeReader *reader,
2926 DBusTypeReader *realign_root,
2929 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2934 n_copies = node->klass->subclass_detail;
2936 check_expected_type (reader, DBUS_TYPE_STRUCT);
2938 _dbus_type_reader_recurse (reader, &sub);
2941 while (i < n_copies)
2945 link = _dbus_list_get_first_link (&container->children);
2946 while (link != NULL)
2948 TestTypeNode *child = link->data;
2949 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2951 if (realign_root == NULL)
2953 if (!node_read_value (child, &sub, seed + i))
2958 if (!node_set_value (child, &sub, realign_root, seed + i))
2962 if (i == (n_copies - 1) && next == NULL)
2963 NEXT_EXPECTING_FALSE (&sub);
2965 NEXT_EXPECTING_TRUE (&sub);
2977 struct_read_value (TestTypeNode *node,
2978 DBusTypeReader *reader,
2981 return struct_read_or_set_value (node, reader, NULL, seed);
2985 struct_set_value (TestTypeNode *node,
2986 DBusTypeReader *reader,
2987 DBusTypeReader *realign_root,
2990 return struct_read_or_set_value (node, reader, realign_root, seed);
2994 struct_build_signature (TestTypeNode *node,
2997 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3002 n_copies = node->klass->subclass_detail;
3004 orig_len = _dbus_string_get_length (str);
3006 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
3010 while (i < n_copies)
3014 link = _dbus_list_get_first_link (&container->children);
3015 while (link != NULL)
3017 TestTypeNode *child = link->data;
3018 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3020 if (!node_build_signature (child, str))
3029 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
3035 _dbus_string_set_length (str, orig_len);
3040 array_write_value (TestTypeNode *node,
3042 DBusTypeWriter *writer,
3045 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3046 DataBlockState saved;
3048 DBusString element_signature;
3052 TestTypeNode *child;
3054 n_copies = node->klass->subclass_detail;
3056 _dbus_assert (container->children != NULL);
3058 data_block_save (block, &saved);
3060 if (!_dbus_string_init (&element_signature))
3063 child = _dbus_list_get_first (&container->children);
3065 if (!node_build_signature (child,
3066 &element_signature))
3069 element_type = _dbus_first_type_in_signature (&element_signature, 0);
3071 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3072 &element_signature, 0,
3076 if (arrays_write_fixed_in_blocks &&
3077 dbus_type_is_fixed (element_type) &&
3078 child->klass->write_multi)
3080 if (!node_write_multi (child, block, &sub, seed, n_copies))
3086 while (i < n_copies)
3090 link = _dbus_list_get_first_link (&container->children);
3091 while (link != NULL)
3093 TestTypeNode *child = link->data;
3094 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3096 if (!node_write_value (child, block, &sub, seed + i))
3106 if (!_dbus_type_writer_unrecurse (writer, &sub))
3109 _dbus_string_free (&element_signature);
3113 data_block_restore (block, &saved);
3114 _dbus_string_free (&element_signature);
3119 array_read_or_set_value (TestTypeNode *node,
3120 DBusTypeReader *reader,
3121 DBusTypeReader *realign_root,
3124 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3128 TestTypeNode *child;
3130 n_copies = node->klass->subclass_detail;
3132 check_expected_type (reader, DBUS_TYPE_ARRAY);
3134 child = _dbus_list_get_first (&container->children);
3138 _dbus_type_reader_recurse (reader, &sub);
3140 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
3141 dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
3142 child->klass->read_multi)
3144 if (!node_read_multi (child, &sub, seed, n_copies))
3150 while (i < n_copies)
3154 link = _dbus_list_get_first_link (&container->children);
3155 while (link != NULL)
3157 TestTypeNode *child = link->data;
3158 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3160 _dbus_assert (child->klass->typecode ==
3161 _dbus_type_reader_get_element_type (reader));
3163 if (realign_root == NULL)
3165 if (!node_read_value (child, &sub, seed + i))
3170 if (!node_set_value (child, &sub, realign_root, seed + i))
3174 if (i == (n_copies - 1) && next == NULL)
3175 NEXT_EXPECTING_FALSE (&sub);
3177 NEXT_EXPECTING_TRUE (&sub);
3191 array_read_value (TestTypeNode *node,
3192 DBusTypeReader *reader,
3195 return array_read_or_set_value (node, reader, NULL, seed);
3199 array_set_value (TestTypeNode *node,
3200 DBusTypeReader *reader,
3201 DBusTypeReader *realign_root,
3204 return array_read_or_set_value (node, reader, realign_root, seed);
3208 array_build_signature (TestTypeNode *node,
3211 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3214 orig_len = _dbus_string_get_length (str);
3216 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3219 if (!node_build_signature (_dbus_list_get_first (&container->children),
3226 _dbus_string_set_length (str, orig_len);
3230 /* 10 is random just to add another seed that we use in the suite */
3231 #define VARIANT_SEED 10
3234 variant_write_value (TestTypeNode *node,
3236 DBusTypeWriter *writer,
3239 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3240 DataBlockState saved;
3242 DBusString content_signature;
3243 TestTypeNode *child;
3245 _dbus_assert (container->children != NULL);
3246 _dbus_assert (_dbus_list_length_is_one (&container->children));
3248 child = _dbus_list_get_first (&container->children);
3250 data_block_save (block, &saved);
3252 if (!_dbus_string_init (&content_signature))
3255 if (!node_build_signature (child,
3256 &content_signature))
3259 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3260 &content_signature, 0,
3264 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3267 if (!_dbus_type_writer_unrecurse (writer, &sub))
3270 _dbus_string_free (&content_signature);
3274 data_block_restore (block, &saved);
3275 _dbus_string_free (&content_signature);
3280 variant_read_or_set_value (TestTypeNode *node,
3281 DBusTypeReader *reader,
3282 DBusTypeReader *realign_root,
3285 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3287 TestTypeNode *child;
3289 _dbus_assert (container->children != NULL);
3290 _dbus_assert (_dbus_list_length_is_one (&container->children));
3292 child = _dbus_list_get_first (&container->children);
3294 check_expected_type (reader, DBUS_TYPE_VARIANT);
3296 _dbus_type_reader_recurse (reader, &sub);
3298 if (realign_root == NULL)
3300 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3305 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3309 NEXT_EXPECTING_FALSE (&sub);
3315 variant_read_value (TestTypeNode *node,
3316 DBusTypeReader *reader,
3319 return variant_read_or_set_value (node, reader, NULL, seed);
3323 variant_set_value (TestTypeNode *node,
3324 DBusTypeReader *reader,
3325 DBusTypeReader *realign_root,
3328 return variant_read_or_set_value (node, reader, realign_root, seed);
3332 dict_write_value (TestTypeNode *node,
3334 DBusTypeWriter *writer,
3337 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3338 DataBlockState saved;
3340 DBusString entry_value_signature;
3341 DBusString dict_entry_signature;
3344 TestTypeNode *child;
3346 n_entries = node->klass->subclass_detail;
3348 _dbus_assert (container->children != NULL);
3350 data_block_save (block, &saved);
3352 if (!_dbus_string_init (&entry_value_signature))
3355 if (!_dbus_string_init (&dict_entry_signature))
3357 _dbus_string_free (&entry_value_signature);
3361 child = _dbus_list_get_first (&container->children);
3363 if (!node_build_signature (child,
3364 &entry_value_signature))
3367 if (!_dbus_string_append (&dict_entry_signature,
3368 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3369 DBUS_TYPE_INT32_AS_STRING))
3372 if (!_dbus_string_copy (&entry_value_signature, 0,
3373 &dict_entry_signature,
3374 _dbus_string_get_length (&dict_entry_signature)))
3377 if (!_dbus_string_append_byte (&dict_entry_signature,
3378 DBUS_DICT_ENTRY_END_CHAR))
3381 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3382 &dict_entry_signature, 0,
3387 while (i < n_entries)
3389 DBusTypeWriter entry_sub;
3392 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
3397 key = int32_from_seed (seed + i);
3399 if (!_dbus_type_writer_write_basic (&entry_sub,
3404 if (!node_write_value (child, block, &entry_sub, seed + i))
3407 if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
3413 if (!_dbus_type_writer_unrecurse (writer, &sub))
3416 _dbus_string_free (&entry_value_signature);
3417 _dbus_string_free (&dict_entry_signature);
3421 data_block_restore (block, &saved);
3422 _dbus_string_free (&entry_value_signature);
3423 _dbus_string_free (&dict_entry_signature);
3428 dict_read_or_set_value (TestTypeNode *node,
3429 DBusTypeReader *reader,
3430 DBusTypeReader *realign_root,
3433 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3437 TestTypeNode *child;
3439 n_entries = node->klass->subclass_detail;
3441 check_expected_type (reader, DBUS_TYPE_ARRAY);
3443 child = _dbus_list_get_first (&container->children);
3447 _dbus_type_reader_recurse (reader, &sub);
3449 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3452 while (i < n_entries)
3454 DBusTypeReader entry_sub;
3456 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3458 _dbus_type_reader_recurse (&sub, &entry_sub);
3460 if (realign_root == NULL)
3464 check_expected_type (&entry_sub, DBUS_TYPE_INT32);
3466 _dbus_type_reader_read_basic (&entry_sub,
3467 (dbus_int32_t*) &v);
3469 _dbus_assert (v == int32_from_seed (seed + i));
3471 NEXT_EXPECTING_TRUE (&entry_sub);
3473 if (!node_read_value (child, &entry_sub, seed + i))
3476 NEXT_EXPECTING_FALSE (&entry_sub);
3482 v = int32_from_seed (seed + i);
3484 if (!_dbus_type_reader_set_basic (&entry_sub,
3489 NEXT_EXPECTING_TRUE (&entry_sub);
3491 if (!node_set_value (child, &entry_sub, realign_root, seed + i))
3494 NEXT_EXPECTING_FALSE (&entry_sub);
3497 if (i == (n_entries - 1))
3498 NEXT_EXPECTING_FALSE (&sub);
3500 NEXT_EXPECTING_TRUE (&sub);
3510 dict_read_value (TestTypeNode *node,
3511 DBusTypeReader *reader,
3514 return dict_read_or_set_value (node, reader, NULL, seed);
3518 dict_set_value (TestTypeNode *node,
3519 DBusTypeReader *reader,
3520 DBusTypeReader *realign_root,
3523 return dict_read_or_set_value (node, reader, realign_root, seed);
3527 dict_build_signature (TestTypeNode *node,
3530 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3533 orig_len = _dbus_string_get_length (str);
3535 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3538 if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
3541 if (!node_build_signature (_dbus_list_get_first (&container->children),
3545 if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
3551 _dbus_string_set_length (str, orig_len);
3556 container_destroy (TestTypeNode *node)
3558 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3561 link = _dbus_list_get_first_link (&container->children);
3562 while (link != NULL)
3564 TestTypeNode *child = link->data;
3565 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3567 node_destroy (child);
3569 _dbus_list_free_link (link);
3575 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
3577 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */