D-Bus: dbus-marshal-recursive-util.c Source File

D-Bus 1.10.10

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List

dbus-marshal-recursive-util.c
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
3 *
4 * Copyright (C) 2004, 2005 Red Hat, Inc.
5 *
6 * Licensed under the Academic Free License version 2.1
7 *
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.
12 *
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.
17 *
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
21 *
22 */
23
24 #include <config.h>
25
26 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
27
28 #include "dbus-marshal-recursive.h"
29 #include "dbus-marshal-basic.h"
30 #include "dbus-signature.h"
31 #include "dbus-internals.h"
32 #include <string.h>
33
34 static void
35 basic_value_zero (DBusBasicValue *value)
36 {
37 value->u64 = 0;
38 }
39
40 static dbus_bool_t
41 basic_value_equal (int type,
42 DBusBasicValue *lhs,
43 DBusBasicValue *rhs)
44 {
45 if (type == DBUS_TYPE_STRING ||
46 type == DBUS_TYPE_SIGNATURE ||
47 type == DBUS_TYPE_OBJECT_PATH)
48 {
49 return strcmp (lhs->str, rhs->str) == 0;
50 }
51 else
52 {
53 return lhs->u64 == rhs->u64;
54 }
55 }
56
57 static dbus_bool_t
58 equal_values_helper (DBusTypeReader *lhs,
59 DBusTypeReader *rhs)
60 {
61 int lhs_type;
62 int rhs_type;
63
64 lhs_type = _dbus_type_reader_get_current_type (lhs);
65 rhs_type = _dbus_type_reader_get_current_type (rhs);
66
67 if (lhs_type != rhs_type)
68 return FALSE;
69
70 if (lhs_type == DBUS_TYPE_INVALID)
71 return TRUE;
72
73 if (dbus_type_is_basic (lhs_type))
74 {
75 DBusBasicValue lhs_value;
76 DBusBasicValue rhs_value;
77
78 basic_value_zero (&lhs_value);
79 basic_value_zero (&rhs_value);
80
81 _dbus_type_reader_read_basic (lhs, &lhs_value);
82 _dbus_type_reader_read_basic (rhs, &rhs_value);
83
84 return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
85 }
86 else
87 {
88 DBusTypeReader lhs_sub;
89 DBusTypeReader rhs_sub;
90
91 _dbus_type_reader_recurse (lhs, &lhs_sub);
92 _dbus_type_reader_recurse (rhs, &rhs_sub);
93
94 return equal_values_helper (&lhs_sub, &rhs_sub);
95 }
96 }
97
105 dbus_bool_t
106 _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
107 const DBusTypeReader *rhs)
108 {
109 DBusTypeReader copy_lhs = *lhs;
110 DBusTypeReader copy_rhs = *rhs;
111
112 return equal_values_helper (&copy_lhs, &copy_rhs);
113 }
114
115 /* TESTS */
116
117 #ifndef DOXYGEN_SHOULD_SKIP_THIS
118
119 #include "dbus-test.h"
120 #include "dbus-list.h"
121 #include <stdio.h>
122 #include <stdlib.h>
123
124 /* Whether to do the OOM stuff (only with other expensive tests) */
125 #define TEST_OOM_HANDLING 0
126 /* We do start offset 0 through 9, to get various alignment cases. Still this
127 * obviously makes the test suite run 10x as slow.
128 */
129 #define MAX_INITIAL_OFFSET 9
130
131 /* Largest iteration count to test copying, realignment,
132 * etc. with. i.e. we only test this stuff with some of the smaller
133 * data sets.
134 */
135 #define MAX_ITERATIONS_FOR_EXPENSIVE_TESTS 1000
136
137 typedef struct
138 {
139 int byte_order;
140 int initial_offset;
141 DBusString signature;
142 DBusString body;
143 } DataBlock;
144
145 typedef struct
146 {
147 int saved_sig_len;
148 int saved_body_len;
149 } DataBlockState;
150
151 #define N_FENCE_BYTES 5
152 #define FENCE_BYTES_STR "abcde"
153 #define INITIAL_PADDING_BYTE '\0'
154
155 static dbus_bool_t
156 data_block_init (DataBlock *block,
157 int byte_order,
158 int initial_offset)
159 {
160 if (!_dbus_string_init (&block->signature))
161 return FALSE;
162
163 if (!_dbus_string_init (&block->body))
164 {
165 _dbus_string_free (&block->signature);
166 return FALSE;
167 }
168
169 if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset,
170 INITIAL_PADDING_BYTE) ||
171 !_dbus_string_insert_bytes (&block->body, 0, initial_offset,
172 INITIAL_PADDING_BYTE) ||
173 !_dbus_string_append (&block->signature, FENCE_BYTES_STR) ||
174 !_dbus_string_append (&block->body, FENCE_BYTES_STR))
175 {
176 _dbus_string_free (&block->signature);
177 _dbus_string_free (&block->body);
178 return FALSE;
179 }
180
181 block->byte_order = byte_order;
182 block->initial_offset = initial_offset;
183
184 return TRUE;
185 }
186
187 static void
188 data_block_save (DataBlock *block,
189 DataBlockState *state)
190 {
191 state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES;
192 state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;
193 }
194
195 static void
196 data_block_restore (DataBlock *block,
197 DataBlockState *state)
198 {
199 _dbus_string_delete (&block->signature,
200 state->saved_sig_len,
201 _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES);
202 _dbus_string_delete (&block->body,
203 state->saved_body_len,
204 _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES);
205 }
206
207 static void
208 data_block_verify (DataBlock *block)
209 {
210 if (!_dbus_string_ends_with_c_str (&block->signature,
211 FENCE_BYTES_STR))
212 {
213 int offset;
214
215 offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8;
216 if (offset < 0)
217 offset = 0;
218
219 _dbus_verbose_bytes_of_string (&block->signature,
220 offset,
221 _dbus_string_get_length (&block->signature) - offset);
222 _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature");
223 }
224 if (!_dbus_string_ends_with_c_str (&block->body,
225 FENCE_BYTES_STR))
226 {
227 int offset;
228
229 offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8;
230 if (offset < 0)
231 offset = 0;
232
233 _dbus_verbose_bytes_of_string (&block->body,
234 offset,
235 _dbus_string_get_length (&block->body) - offset);
236 _dbus_assert_not_reached ("block did not verify: bad bytes at end of body");
237 }
238
239 _dbus_assert (_dbus_string_validate_nul (&block->signature,
240 0, block->initial_offset));
241 _dbus_assert (_dbus_string_validate_nul (&block->body,
242 0, block->initial_offset));
243 }
244
245 static void
246 data_block_free (DataBlock *block)
247 {
248 data_block_verify (block);
249
250 _dbus_string_free (&block->signature);
251 _dbus_string_free (&block->body);
252 }
253
254 static void
255 data_block_reset (DataBlock *block)
256 {
257 data_block_verify (block);
258
259 _dbus_string_delete (&block->signature,
260 block->initial_offset,
261 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset);
262 _dbus_string_delete (&block->body,
263 block->initial_offset,
264 _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset);
265
266 data_block_verify (block);
267 }
268
269 static void
270 data_block_init_reader_writer (DataBlock *block,
271 DBusTypeReader *reader,
272 DBusTypeWriter *writer)
273 {
274 if (reader)
275 _dbus_type_reader_init (reader,
276 block->byte_order,
277 &block->signature,
278 block->initial_offset,
279 &block->body,
280 block->initial_offset);
281
282 if (writer)
283 _dbus_type_writer_init (writer,
284 block->byte_order,
285 &block->signature,
286 _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,
287 &block->body,
288 _dbus_string_get_length (&block->body) - N_FENCE_BYTES);
289 }
290
291 static void
292 real_check_expected_type (DBusTypeReader *reader,
293 int expected,
294 const char *funcname,
295 int line)
296 {
297 int t;
298
299 t = _dbus_type_reader_get_current_type (reader);
300
301 if (t != expected)
302 {
303 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
304 _dbus_type_to_string (t),
305 _dbus_type_to_string (expected),
306 funcname, line);
307
308 _dbus_assert_not_reached ("read wrong type");
309 }
310 }
311
312 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
313
314 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
315 { \
316 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
317 _DBUS_FUNCTION_NAME, __LINE__); \
318 _dbus_assert_not_reached ("test failed"); \
319 } \
320 } while (0)
321
322 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
323 { \
324 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
325 _DBUS_FUNCTION_NAME, __LINE__); \
326 _dbus_assert_not_reached ("test failed"); \
327 } \
328 check_expected_type (reader, DBUS_TYPE_INVALID); \
329 } while (0)
330
331 typedef struct TestTypeNode TestTypeNode;
332 typedef struct TestTypeNodeClass TestTypeNodeClass;
333 typedef struct TestTypeNodeContainer TestTypeNodeContainer;
334 typedef struct TestTypeNodeContainerClass TestTypeNodeContainerClass;
335
336 struct TestTypeNode
337 {
338 const TestTypeNodeClass *klass;
339 };
340
341 struct TestTypeNodeContainer
342 {
343 TestTypeNode base;
344 DBusList *children;
345 };
346
347 struct TestTypeNodeClass
348 {
349 int typecode;
350
351 int instance_size;
352
353 int subclass_detail; /* a bad hack to avoid a bunch of subclass casting */
354
355 dbus_bool_t (* construct) (TestTypeNode *node);
356 void (* destroy) (TestTypeNode *node);
357
358 dbus_bool_t (* write_value) (TestTypeNode *node,
359 DataBlock *block,
360 DBusTypeWriter *writer,
361 int seed);
362 dbus_bool_t (* read_value) (TestTypeNode *node,
363 DBusTypeReader *reader,
364 int seed);
365 dbus_bool_t (* set_value) (TestTypeNode *node,
366 DBusTypeReader *reader,
367 DBusTypeReader *realign_root,
368 int seed);
369 dbus_bool_t (* build_signature) (TestTypeNode *node,
370 DBusString *str);
371 dbus_bool_t (* write_multi) (TestTypeNode *node,
372 DataBlock *block,
373 DBusTypeWriter *writer,
374 int seed,
375 int count);
376 dbus_bool_t (* read_multi) (TestTypeNode *node,
377 DBusTypeReader *reader,
378 int seed,
379 int count);
380 };
381
382 struct TestTypeNodeContainerClass
383 {
384 TestTypeNodeClass base;
385 };
386
387 /* FIXME this could be chilled out substantially by unifying
388 * the basic types into basic_write_value/basic_read_value
389 * and by merging read_value and set_value into one function
390 * taking a flag argument.
391 */
392 static dbus_bool_t int16_write_value (TestTypeNode *node,
393 DataBlock *block,
394 DBusTypeWriter *writer,
395 int seed);
396 static dbus_bool_t int16_read_value (TestTypeNode *node,
397 DBusTypeReader *reader,
398 int seed);
399 static dbus_bool_t int16_set_value (TestTypeNode *node,
400 DBusTypeReader *reader,
401 DBusTypeReader *realign_root,
402 int seed);
403 static dbus_bool_t int16_write_multi (TestTypeNode *node,
404 DataBlock *block,
405 DBusTypeWriter *writer,
406 int seed,
407 int count);
408 static dbus_bool_t int16_read_multi (TestTypeNode *node,
409 DBusTypeReader *reader,
410 int seed,
411 int count);
412 static dbus_bool_t int32_write_value (TestTypeNode *node,
413 DataBlock *block,
414 DBusTypeWriter *writer,
415 int seed);
416 static dbus_bool_t int32_read_value (TestTypeNode *node,
417 DBusTypeReader *reader,
418 int seed);
419 static dbus_bool_t int32_set_value (TestTypeNode *node,
420 DBusTypeReader *reader,
421 DBusTypeReader *realign_root,
422 int seed);
423 static dbus_bool_t int32_write_multi (TestTypeNode *node,
424 DataBlock *block,
425 DBusTypeWriter *writer,
426 int seed,
427 int count);
428 static dbus_bool_t int32_read_multi (TestTypeNode *node,
429 DBusTypeReader *reader,
430 int seed,
431 int count);
432 static dbus_bool_t int64_write_value (TestTypeNode *node,
433 DataBlock *block,
434 DBusTypeWriter *writer,
435 int seed);
436 static dbus_bool_t int64_read_value (TestTypeNode *node,
437 DBusTypeReader *reader,
438 int seed);
439 static dbus_bool_t int64_set_value (TestTypeNode *node,
440 DBusTypeReader *reader,
441 DBusTypeReader *realign_root,
442 int seed);
443 static dbus_bool_t string_write_value (TestTypeNode *node,
444 DataBlock *block,
445 DBusTypeWriter *writer,
446 int seed);
447 static dbus_bool_t string_read_value (TestTypeNode *node,
448 DBusTypeReader *reader,
449 int seed);
450 static dbus_bool_t string_set_value (TestTypeNode *node,
451 DBusTypeReader *reader,
452 DBusTypeReader *realign_root,
453 int seed);
454 static dbus_bool_t bool_write_value (TestTypeNode *node,
455 DataBlock *block,
456 DBusTypeWriter *writer,
457 int seed);
458 static dbus_bool_t bool_read_value (TestTypeNode *node,
459 DBusTypeReader *reader,
460 int seed);
461 static dbus_bool_t bool_set_value (TestTypeNode *node,
462 DBusTypeReader *reader,
463 DBusTypeReader *realign_root,
464 int seed);
465 static dbus_bool_t byte_write_value (TestTypeNode *node,
466 DataBlock *block,
467 DBusTypeWriter *writer,
468 int seed);
469 static dbus_bool_t byte_read_value (TestTypeNode *node,
470 DBusTypeReader *reader,
471 int seed);
472 static dbus_bool_t byte_set_value (TestTypeNode *node,
473 DBusTypeReader *reader,
474 DBusTypeReader *realign_root,
475 int seed);
476 static dbus_bool_t double_write_value (TestTypeNode *node,
477 DataBlock *block,
478 DBusTypeWriter *writer,
479 int seed);
480 static dbus_bool_t double_read_value (TestTypeNode *node,
481 DBusTypeReader *reader,
482 int seed);
483 static dbus_bool_t double_set_value (TestTypeNode *node,
484 DBusTypeReader *reader,
485 DBusTypeReader *realign_root,
486 int seed);
487 static dbus_bool_t object_path_write_value (TestTypeNode *node,
488 DataBlock *block,
489 DBusTypeWriter *writer,
490 int seed);
491 static dbus_bool_t object_path_read_value (TestTypeNode *node,
492 DBusTypeReader *reader,
493 int seed);
494 static dbus_bool_t object_path_set_value (TestTypeNode *node,
495 DBusTypeReader *reader,
496 DBusTypeReader *realign_root,
497 int seed);
498 static dbus_bool_t signature_write_value (TestTypeNode *node,
499 DataBlock *block,
500 DBusTypeWriter *writer,
501 int seed);
502 static dbus_bool_t signature_read_value (TestTypeNode *node,
503 DBusTypeReader *reader,
504 int seed);
505 static dbus_bool_t signature_set_value (TestTypeNode *node,
506 DBusTypeReader *reader,
507 DBusTypeReader *realign_root,
508 int seed);
509 static dbus_bool_t struct_write_value (TestTypeNode *node,
510 DataBlock *block,
511 DBusTypeWriter *writer,
512 int seed);
513 static dbus_bool_t struct_read_value (TestTypeNode *node,
514 DBusTypeReader *reader,
515 int seed);
516 static dbus_bool_t struct_set_value (TestTypeNode *node,
517 DBusTypeReader *reader,
518 DBusTypeReader *realign_root,
519 int seed);
520 static dbus_bool_t struct_build_signature (TestTypeNode *node,
521 DBusString *str);
522 static dbus_bool_t dict_write_value (TestTypeNode *node,
523 DataBlock *block,
524 DBusTypeWriter *writer,
525 int seed);
526 static dbus_bool_t dict_read_value (TestTypeNode *node,
527 DBusTypeReader *reader,
528 int seed);
529 static dbus_bool_t dict_set_value (TestTypeNode *node,
530 DBusTypeReader *reader,
531 DBusTypeReader *realign_root,
532 int seed);
533 static dbus_bool_t dict_build_signature (TestTypeNode *node,
534 DBusString *str);
535 static dbus_bool_t array_write_value (TestTypeNode *node,
536 DataBlock *block,
537 DBusTypeWriter *writer,
538 int seed);
539 static dbus_bool_t array_read_value (TestTypeNode *node,
540 DBusTypeReader *reader,
541 int seed);
542 static dbus_bool_t array_set_value (TestTypeNode *node,
543 DBusTypeReader *reader,
544 DBusTypeReader *realign_root,
545 int seed);
546 static dbus_bool_t array_build_signature (TestTypeNode *node,
547 DBusString *str);
548 static dbus_bool_t variant_write_value (TestTypeNode *node,
549 DataBlock *block,
550 DBusTypeWriter *writer,
551 int seed);
552 static dbus_bool_t variant_read_value (TestTypeNode *node,
553 DBusTypeReader *reader,
554 int seed);
555 static dbus_bool_t variant_set_value (TestTypeNode *node,
556 DBusTypeReader *reader,
557 DBusTypeReader *realign_root,
558 int seed);
559 static void container_destroy (TestTypeNode *node);
560
561
562
563 static const TestTypeNodeClass int16_class = {
564 DBUS_TYPE_INT16,
565 sizeof (TestTypeNode),
566 0,
567 NULL,
568 NULL,
569 int16_write_value,
570 int16_read_value,
571 int16_set_value,
572 NULL,
573 int16_write_multi,
574 int16_read_multi
575 };
576
577 static const TestTypeNodeClass uint16_class = {
578 DBUS_TYPE_UINT16,
579 sizeof (TestTypeNode),
580 0,
581 NULL,
582 NULL,
583 int16_write_value, /* recycle from int16 */
584 int16_read_value, /* recycle from int16 */
585 int16_set_value, /* recycle from int16 */
586 NULL,
587 int16_write_multi, /* recycle from int16 */
588 int16_read_multi /* recycle from int16 */
589 };
590
591 static const TestTypeNodeClass int32_class = {
592 DBUS_TYPE_INT32,
593 sizeof (TestTypeNode),
594 0,
595 NULL,
596 NULL,
597 int32_write_value,
598 int32_read_value,
599 int32_set_value,
600 NULL,
601 int32_write_multi,
602 int32_read_multi
603 };
604
605 static const TestTypeNodeClass uint32_class = {
606 DBUS_TYPE_UINT32,
607 sizeof (TestTypeNode),
608 0,
609 NULL,
610 NULL,
611 int32_write_value, /* recycle from int32 */
612 int32_read_value, /* recycle from int32 */
613 int32_set_value, /* recycle from int32 */
614 NULL,
615 int32_write_multi, /* recycle from int32 */
616 int32_read_multi /* recycle from int32 */
617 };
618
619 static const TestTypeNodeClass int64_class = {
620 DBUS_TYPE_INT64,
621 sizeof (TestTypeNode),
622 0,
623 NULL,
624 NULL,
625 int64_write_value,
626 int64_read_value,
627 int64_set_value,
628 NULL,
629 NULL, /* FIXME */
630 NULL /* FIXME */
631 };
632
633 static const TestTypeNodeClass uint64_class = {
634 DBUS_TYPE_UINT64,
635 sizeof (TestTypeNode),
636 0,
637 NULL,
638 NULL,
639 int64_write_value, /* recycle from int64 */
640 int64_read_value, /* recycle from int64 */
641 int64_set_value, /* recycle from int64 */
642 NULL,
643 NULL, /* FIXME */
644 NULL /* FIXME */
645 };
646
647 static const TestTypeNodeClass string_0_class = {
648 DBUS_TYPE_STRING,
649 sizeof (TestTypeNode),
650 0, /* string length */
651 NULL,
652 NULL,
653 string_write_value,
654 string_read_value,
655 string_set_value,
656 NULL,
657 NULL,
658 NULL
659 };
660
661 static const TestTypeNodeClass string_1_class = {
662 DBUS_TYPE_STRING,
663 sizeof (TestTypeNode),
664 1, /* string length */
665 NULL,
666 NULL,
667 string_write_value,
668 string_read_value,
669 string_set_value,
670 NULL,
671 NULL,
672 NULL
673 };
674
675 /* with nul, a len 3 string should fill 4 bytes and thus is "special" */
676 static const TestTypeNodeClass string_3_class = {
677 DBUS_TYPE_STRING,
678 sizeof (TestTypeNode),
679 3, /* string length */
680 NULL,
681 NULL,
682 string_write_value,
683 string_read_value,
684 string_set_value,
685 NULL,
686 NULL,
687 NULL
688 };
689
690 /* with nul, a len 8 string should fill 9 bytes and thus is "special" (far-fetched I suppose) */
691 static const TestTypeNodeClass string_8_class = {
692 DBUS_TYPE_STRING,
693 sizeof (TestTypeNode),
694 8, /* string length */
695 NULL,
696 NULL,
697 string_write_value,
698 string_read_value,
699 string_set_value,
700 NULL,
701 NULL,
702 NULL
703 };
704
705 static const TestTypeNodeClass bool_class = {
706 DBUS_TYPE_BOOLEAN,
707 sizeof (TestTypeNode),
708 0,
709 NULL,
710 NULL,
711 bool_write_value,
712 bool_read_value,
713 bool_set_value,
714 NULL,
715 NULL, /* FIXME */
716 NULL /* FIXME */
717 };
718
719 static const TestTypeNodeClass byte_class = {
720 DBUS_TYPE_BYTE,
721 sizeof (TestTypeNode),
722 0,
723 NULL,
724 NULL,
725 byte_write_value,
726 byte_read_value,
727 byte_set_value,
728 NULL,
729 NULL, /* FIXME */
730 NULL /* FIXME */
731 };
732
733 static const TestTypeNodeClass double_class = {
734 DBUS_TYPE_DOUBLE,
735 sizeof (TestTypeNode),
736 0,
737 NULL,
738 NULL,
739 double_write_value,
740 double_read_value,
741 double_set_value,
742 NULL,
743 NULL, /* FIXME */
744 NULL /* FIXME */
745 };
746
747 static const TestTypeNodeClass object_path_class = {
748 DBUS_TYPE_OBJECT_PATH,
749 sizeof (TestTypeNode),
750 0,
751 NULL,
752 NULL,
753 object_path_write_value,
754 object_path_read_value,
755 object_path_set_value,
756 NULL,
757 NULL,
758 NULL
759 };
760
761 static const TestTypeNodeClass signature_class = {
762 DBUS_TYPE_SIGNATURE,
763 sizeof (TestTypeNode),
764 0,
765 NULL,
766 NULL,
767 signature_write_value,
768 signature_read_value,
769 signature_set_value,
770 NULL,
771 NULL,
772 NULL
773 };
774
775 static const TestTypeNodeClass struct_1_class = {
776 DBUS_TYPE_STRUCT,
777 sizeof (TestTypeNodeContainer),
778 1, /* number of times children appear as fields */
779 NULL,
780 container_destroy,
781 struct_write_value,
782 struct_read_value,
783 struct_set_value,
784 struct_build_signature,
785 NULL,
786 NULL
787 };
788
789 static const TestTypeNodeClass struct_2_class = {
790 DBUS_TYPE_STRUCT,
791 sizeof (TestTypeNodeContainer),
792 2, /* number of times children appear as fields */
793 NULL,
794 container_destroy,
795 struct_write_value,
796 struct_read_value,
797 struct_set_value,
798 struct_build_signature,
799 NULL,
800 NULL
801 };
802
803 static const TestTypeNodeClass dict_1_class = {
804 DBUS_TYPE_ARRAY, /* this is correct, a dict is an array of dict entry */
805 sizeof (TestTypeNodeContainer),
806 1, /* number of entries */
807 NULL,
808 container_destroy,
809 dict_write_value,
810 dict_read_value,
811 dict_set_value,
812 dict_build_signature,
813 NULL,
814 NULL
815 };
816
817 static dbus_bool_t arrays_write_fixed_in_blocks = FALSE;
818
819 static const TestTypeNodeClass array_0_class = {
820 DBUS_TYPE_ARRAY,
821 sizeof (TestTypeNodeContainer),
822 0, /* number of array elements */
823 NULL,
824 container_destroy,
825 array_write_value,
826 array_read_value,
827 array_set_value,
828 array_build_signature,
829 NULL,
830 NULL
831 };
832
833 static const TestTypeNodeClass array_1_class = {
834 DBUS_TYPE_ARRAY,
835 sizeof (TestTypeNodeContainer),
836 1, /* number of array elements */
837 NULL,
838 container_destroy,
839 array_write_value,
840 array_read_value,
841 array_set_value,
842 array_build_signature,
843 NULL,
844 NULL
845 };
846
847 static const TestTypeNodeClass array_2_class = {
848 DBUS_TYPE_ARRAY,
849 sizeof (TestTypeNodeContainer),
850 2, /* number of array elements */
851 NULL,
852 container_destroy,
853 array_write_value,
854 array_read_value,
855 array_set_value,
856 array_build_signature,
857 NULL,
858 NULL
859 };
860
861 static const TestTypeNodeClass array_9_class = {
862 DBUS_TYPE_ARRAY,
863 sizeof (TestTypeNodeContainer),
864 9, /* number of array elements */
865 NULL,
866 container_destroy,
867 array_write_value,
868 array_read_value,
869 array_set_value,
870 array_build_signature,
871 NULL,
872 NULL
873 };
874
875 static const TestTypeNodeClass variant_class = {
876 DBUS_TYPE_VARIANT,
877 sizeof (TestTypeNodeContainer),
878 0,
879 NULL,
880 container_destroy,
881 variant_write_value,
882 variant_read_value,
883 variant_set_value,
884 NULL,
885 NULL,
886 NULL
887 };
888
889 static const TestTypeNodeClass* const
890 basic_nodes[] = {
891 &int16_class,
892 &uint16_class,
893 &int32_class,
894 &uint32_class,
895 &int64_class,
896 &uint64_class,
897 &bool_class,
898 &byte_class,
899 &double_class,
900 &string_0_class,
901 &string_1_class,
902 &string_3_class,
903 &string_8_class,
904 &object_path_class,
905 &signature_class
906 };
907 #define N_BASICS (_DBUS_N_ELEMENTS (basic_nodes))
908
909 static const TestTypeNodeClass* const
910 container_nodes[] = {
911 &struct_1_class,
912 &array_1_class,
913 &struct_2_class,
914 &array_0_class,
915 &array_2_class,
916 &variant_class,
917 &dict_1_class /* last since we want struct and array before it */
918 /* array_9_class is omitted on purpose, it's too slow;
919 * we only use it in one hardcoded test below
920 */
921 };
922 #define N_CONTAINERS (_DBUS_N_ELEMENTS (container_nodes))
923
924 static TestTypeNode*
925 node_new (const TestTypeNodeClass *klass)
926 {
927 TestTypeNode *node;
928
929 node = dbus_malloc0 (klass->instance_size);
930 if (node == NULL)
931 return NULL;
932
933 node->klass = klass;
934
935 if (klass->construct)
936 {
937 if (!(* klass->construct) (node))
938 {
939 dbus_free (node);
940 return NULL;
941 }
942 }
943
944 return node;
945 }
946
947 static void
948 node_destroy (TestTypeNode *node)
949 {
950 if (node->klass->destroy)
951 (* node->klass->destroy) (node);
952 dbus_free (node);
953 }
954
955 static dbus_bool_t
956 node_write_value (TestTypeNode *node,
957 DataBlock *block,
958 DBusTypeWriter *writer,
959 int seed)
960 {
961 dbus_bool_t retval;
962
963 retval = (* node->klass->write_value) (node, block, writer, seed);
964
965 #if 0
966 /* Handy to see where things break, but too expensive to do all the time */
967 data_block_verify (block);
968 #endif
969
970 return retval;
971 }
972
973 static dbus_bool_t
974 node_read_value (TestTypeNode *node,
975 DBusTypeReader *reader,
976 int seed)
977 {
978 /* DBusTypeReader restored; */
979
980 if (!(* node->klass->read_value) (node, reader, seed))
981 return FALSE;
982
983 return TRUE;
984 }
985
986 /* Warning: if this one fails due to OOM, it has side effects (can
987 * modify only some of the sub-values). OK in a test suite, but we
988 * never do this in real code.
989 */
990 static dbus_bool_t
991 node_set_value (TestTypeNode *node,
992 DBusTypeReader *reader,
993 DBusTypeReader *realign_root,
994 int seed)
995 {
996 if (!(* node->klass->set_value) (node, reader, realign_root, seed))
997 return FALSE;
998
999 return TRUE;
1000 }
1001
1002 static dbus_bool_t
1003 node_build_signature (TestTypeNode *node,
1004 DBusString *str)
1005 {
1006 if (node->klass->build_signature)
1007 return (* node->klass->build_signature) (node, str);
1008 else
1009 return _dbus_string_append_byte (str, node->klass->typecode);
1010 }
1011
1012 static dbus_bool_t
1013 node_append_child (TestTypeNode *node,
1014 TestTypeNode *child)
1015 {
1016 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1017
1018 _dbus_assert (node->klass->instance_size >= (int) sizeof (TestTypeNodeContainer));
1019
1020 if (!_dbus_list_append (&container->children, child))
1021 _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 */
1022
1023 return TRUE;
1024 }
1025
1026 static dbus_bool_t
1027 node_write_multi (TestTypeNode *node,
1028 DataBlock *block,
1029 DBusTypeWriter *writer,
1030 int seed,
1031 int n_copies)
1032 {
1033 dbus_bool_t retval;
1034
1035 _dbus_assert (node->klass->write_multi != NULL);
1036 retval = (* node->klass->write_multi) (node, block, writer, seed, n_copies);
1037
1038 #if 0
1039 /* Handy to see where things break, but too expensive to do all the time */
1040 data_block_verify (block);
1041 #endif
1042
1043 return retval;
1044 }
1045
1046 static dbus_bool_t
1047 node_read_multi (TestTypeNode *node,
1048 DBusTypeReader *reader,
1049 int seed,
1050 int n_copies)
1051 {
1052 _dbus_assert (node->klass->read_multi != NULL);
1053
1054 if (!(* node->klass->read_multi) (node, reader, seed, n_copies))
1055 return FALSE;
1056
1057 return TRUE;
1058 }
1059
1060 static int n_iterations_completed_total = 0;
1061 static int n_iterations_completed_this_test = 0;
1062 static int n_iterations_expected_this_test = 0;
1063
1064 typedef struct
1065 {
1066 const DBusString *signature;
1067 DataBlock *block;
1068 int type_offset;
1069 TestTypeNode **nodes;
1070 int n_nodes;
1071 } NodeIterationData;
1072
1073 static dbus_bool_t
1074 run_test_copy (NodeIterationData *nid)
1075 {
1076 DataBlock *src;
1077 DataBlock dest;
1078 dbus_bool_t retval;
1079 DBusTypeReader reader;
1080 DBusTypeWriter writer;
1081
1082 _dbus_verbose ("\n");
1083
1084 src = nid->block;
1085
1086 retval = FALSE;
1087
1088 if (!data_block_init (&dest, src->byte_order, src->initial_offset))
1089 return FALSE;
1090
1091 data_block_init_reader_writer (src, &reader, NULL);
1092 data_block_init_reader_writer (&dest, NULL, &writer);
1093
1094 /* DBusTypeWriter assumes it's writing into an existing signature,
1095 * so doesn't add nul on its own. We have to do that.
1096 */
1097 if (!_dbus_string_insert_byte (&dest.signature,
1098 dest.initial_offset, '\0'))
1099 goto out;
1100
1101 if (!_dbus_type_writer_write_reader (&writer, &reader))
1102 goto out;
1103
1104 /* Data blocks should now be identical */
1105 if (!_dbus_string_equal (&src->signature, &dest.signature))
1106 {
1107 _dbus_verbose ("SOURCE\n");
1108 _dbus_verbose_bytes_of_string (&src->signature, 0,
1109 _dbus_string_get_length (&src->signature));
1110 _dbus_verbose ("DEST\n");
1111 _dbus_verbose_bytes_of_string (&dest.signature, 0,
1112 _dbus_string_get_length (&dest.signature));
1113 _dbus_assert_not_reached ("signatures did not match");
1114 }
1115
1116 if (!_dbus_string_equal (&src->body, &dest.body))
1117 {
1118 _dbus_verbose ("SOURCE\n");
1119 _dbus_verbose_bytes_of_string (&src->body, 0,
1120 _dbus_string_get_length (&src->body));
1121 _dbus_verbose ("DEST\n");
1122 _dbus_verbose_bytes_of_string (&dest.body, 0,
1123 _dbus_string_get_length (&dest.body));
1124 _dbus_assert_not_reached ("bodies did not match");
1125 }
1126
1127 retval = TRUE;
1128
1129 out:
1130
1131 data_block_free (&dest);
1132
1133 return retval;
1134 }
1135
1136 static dbus_bool_t
1137 run_test_values_only_write (NodeIterationData *nid)
1138 {
1139 DBusTypeReader reader;
1140 DBusTypeWriter writer;
1141 int i;
1142 dbus_bool_t retval;
1143 int sig_len;
1144
1145 _dbus_verbose ("\n");
1146
1147 retval = FALSE;
1148
1149 data_block_reset (nid->block);
1150
1151 sig_len = _dbus_string_get_length (nid->signature);
1152
1153 _dbus_type_writer_init_values_only (&writer,
1154 nid->block->byte_order,
1155 nid->signature, 0,
1156 &nid->block->body,
1157 _dbus_string_get_length (&nid->block->body) - N_FENCE_BYTES);
1158 _dbus_type_reader_init (&reader,
1159 nid->block->byte_order,
1160 nid->signature, 0,
1161 &nid->block->body,
1162 nid->block->initial_offset);
1163
1164 i = 0;
1165 while (i < nid->n_nodes)
1166 {
1167 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1168 goto out;
1169
1170 ++i;
1171 }
1172
1173 /* if we wrote any typecodes then this would fail */
1174 _dbus_assert (sig_len == _dbus_string_get_length (nid->signature));
1175
1176 /* But be sure we wrote out the values correctly */
1177 i = 0;
1178 while (i < nid->n_nodes)
1179 {
1180 if (!node_read_value (nid->nodes[i], &reader, i))
1181 goto out;
1182
1183 if (i + 1 == nid->n_nodes)
1184 NEXT_EXPECTING_FALSE (&reader);
1185 else
1186 NEXT_EXPECTING_TRUE (&reader);
1187
1188 ++i;
1189 }
1190
1191 retval = TRUE;
1192
1193 out:
1194 data_block_reset (nid->block);
1195 return retval;
1196 }
1197
1198 /* offset the seed for setting, so we set different numbers than
1199 * we originally wrote. Don't offset by a huge number since in
1200 * some cases it's value = possibilities[seed % n_possibilities]
1201 * and we don't want to wrap around. bool_from_seed
1202 * is just seed % 2 even.
1203 */
1204 #define SET_SEED 1
1205 static dbus_bool_t
1206 run_test_set_values (NodeIterationData *nid)
1207 {
1208 DBusTypeReader reader;
1209 DBusTypeReader realign_root;
1210 dbus_bool_t retval;
1211 int i;
1212
1213 _dbus_verbose ("\n");
1214
1215 retval = FALSE;
1216
1217 data_block_init_reader_writer (nid->block,
1218 &reader, NULL);
1219
1220 realign_root = reader;
1221
1222 i = 0;
1223 while (i < nid->n_nodes)
1224 {
1225 if (!node_set_value (nid->nodes[i],
1226 &reader, &realign_root,
1227 i + SET_SEED))
1228 goto out;
1229
1230 if (i + 1 == nid->n_nodes)
1231 NEXT_EXPECTING_FALSE (&reader);
1232 else
1233 NEXT_EXPECTING_TRUE (&reader);
1234
1235 ++i;
1236 }
1237
1238 /* Check that the new values were set */
1239
1240 reader = realign_root;
1241
1242 i = 0;
1243 while (i < nid->n_nodes)
1244 {
1245 if (!node_read_value (nid->nodes[i], &reader,
1246 i + SET_SEED))
1247 goto out;
1248
1249 if (i + 1 == nid->n_nodes)
1250 NEXT_EXPECTING_FALSE (&reader);
1251 else
1252 NEXT_EXPECTING_TRUE (&reader);
1253
1254 ++i;
1255 }
1256
1257 retval = TRUE;
1258
1259 out:
1260 return retval;
1261 }
1262
1263 static dbus_bool_t
1264 run_test_delete_values (NodeIterationData *nid)
1265 {
1266 DBusTypeReader reader;
1267 dbus_bool_t retval;
1268 int t;
1269
1270 _dbus_verbose ("\n");
1271
1272 retval = FALSE;
1273
1274 data_block_init_reader_writer (nid->block,
1275 &reader, NULL);
1276
1277 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1278 {
1279 /* Right now, deleting only works on array elements. We delete
1280 * all array elements, and then verify that there aren't any
1281 * left.
1282 */
1283 if (t == DBUS_TYPE_ARRAY)
1284 {
1285 DBusTypeReader array;
1286 int n_elements;
1287 int elem_type;
1288
1289 _dbus_type_reader_recurse (&reader, &array);
1290 n_elements = 0;
1291 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1292 {
1293 n_elements += 1;
1294 _dbus_type_reader_next (&array);
1295 }
1296
1297 /* reset to start of array */
1298 _dbus_type_reader_recurse (&reader, &array);
1299 _dbus_verbose ("recursing into deletion loop reader.value_pos = %d array.value_pos = %d array.u.start_pos = %d\n",
1300 reader.value_pos, array.value_pos, array.u.array.start_pos);
1301 while ((elem_type = _dbus_type_reader_get_current_type (&array)) != DBUS_TYPE_INVALID)
1302 {
1303 /* We don't want to always delete from the same part of the array. */
1304 static int cycle = 0;
1305 int elem;
1306
1307 _dbus_assert (n_elements > 0);
1308
1309 elem = cycle;
1310 if (elem == 3 || elem >= n_elements) /* end of array */
1311 elem = n_elements - 1;
1312
1313 _dbus_verbose ("deleting array element %d of %d type %s cycle %d reader pos %d elem pos %d\n",
1314 elem, n_elements, _dbus_type_to_string (elem_type),
1315 cycle, reader.value_pos, array.value_pos);
1316 while (elem > 0)
1317 {
1318 if (!_dbus_type_reader_next (&array))
1319 _dbus_assert_not_reached ("should have had another element\n");
1320 --elem;
1321 }
1322
1323 if (!_dbus_type_reader_delete (&array, &reader))
1324 goto out;
1325
1326 n_elements -= 1;
1327
1328 /* reset */
1329 _dbus_type_reader_recurse (&reader, &array);
1330
1331 if (cycle > 2)
1332 cycle = 0;
1333 else
1334 cycle += 1;
1335 }
1336 }
1337 _dbus_type_reader_next (&reader);
1338 }
1339
1340 /* Check that there are no array elements left */
1341 data_block_init_reader_writer (nid->block,
1342 &reader, NULL);
1343
1344 while ((t = _dbus_type_reader_get_current_type (&reader)) != DBUS_TYPE_INVALID)
1345 {
1346 _dbus_type_reader_next (&reader);
1347 }
1348
1349 retval = TRUE;
1350
1351 out:
1352 return retval;
1353 }
1354
1355 static dbus_bool_t
1356 run_test_nodes_iteration (void *data)
1357 {
1358 NodeIterationData *nid = data;
1359 DBusTypeReader reader;
1360 DBusTypeWriter writer;
1361 int i;
1362 dbus_bool_t retval;
1363
1364 /* Stuff to do:
1365 * 1. write the value
1366 * 2. strcmp-compare with the signature we built
1367 * 3. read the value
1368 * 4. type-iterate the signature and the value and see if they are the same type-wise
1369 */
1370 retval = FALSE;
1371
1372 data_block_init_reader_writer (nid->block,
1373 &reader, &writer);
1374
1375 /* DBusTypeWriter assumes it's writing into an existing signature,
1376 * so doesn't add nul on its own. We have to do that.
1377 */
1378 if (!_dbus_string_insert_byte (&nid->block->signature,
1379 nid->type_offset, '\0'))
1380 goto out;
1381
1382 i = 0;
1383 while (i < nid->n_nodes)
1384 {
1385 if (!node_write_value (nid->nodes[i], nid->block, &writer, i))
1386 goto out;
1387
1388 ++i;
1389 }
1390
1391 if (!_dbus_string_equal_substring (nid->signature, 0, _dbus_string_get_length (nid->signature),
1392 &nid->block->signature, nid->type_offset))
1393 {
1394 _dbus_warn ("Expected signature '%s' and got '%s' with initial offset %d\n",
1395 _dbus_string_get_const_data (nid->signature),
1396 _dbus_string_get_const_data_len (&nid->block->signature, nid->type_offset, 0),
1397 nid->type_offset);
1398 _dbus_assert_not_reached ("wrong signature");
1399 }
1400
1401 i = 0;
1402 while (i < nid->n_nodes)
1403 {
1404 if (!node_read_value (nid->nodes[i], &reader, i))
1405 goto out;
1406
1407 if (i + 1 == nid->n_nodes)
1408 NEXT_EXPECTING_FALSE (&reader);
1409 else
1410 NEXT_EXPECTING_TRUE (&reader);
1411
1412 ++i;
1413 }
1414
1415 if (n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1416 {
1417 /* this set values test uses code from copy and
1418 * values_only_write so would ideally be last so you get a
1419 * simpler test case for problems with copying or values_only
1420 * writing; but it also needs an already-written DataBlock so it
1421 * has to go first. Comment it out if it breaks, and see if the
1422 * later tests also break - debug them first if so.
1423 */
1424 if (!run_test_set_values (nid))
1425 goto out;
1426
1427 if (!run_test_delete_values (nid))
1428 goto out;
1429
1430 if (!run_test_copy (nid))
1431 goto out;
1432
1433 if (!run_test_values_only_write (nid))
1434 goto out;
1435 }
1436
1437 /* FIXME type-iterate both signature and value and compare the resulting
1438 * tree to the node tree perhaps
1439 */
1440
1441 retval = TRUE;
1442
1443 out:
1444
1445 data_block_reset (nid->block);
1446
1447 return retval;
1448 }
1449
1450 static void
1451 run_test_nodes_in_one_configuration (TestTypeNode **nodes,
1452 int n_nodes,
1453 const DBusString *signature,
1454 int byte_order,
1455 int initial_offset)
1456 {
1457 DataBlock block;
1458 NodeIterationData nid;
1459
1460 if (!data_block_init (&block, byte_order, initial_offset))
1461 _dbus_assert_not_reached ("no memory");
1462
1463 nid.signature = signature;
1464 nid.block = &block;
1465 nid.type_offset = initial_offset;
1466 nid.nodes = nodes;
1467 nid.n_nodes = n_nodes;
1468
1469 if (TEST_OOM_HANDLING &&
1470 n_iterations_expected_this_test <= MAX_ITERATIONS_FOR_EXPENSIVE_TESTS)
1471 {
1472 _dbus_test_oom_handling ("running test node",
1473 run_test_nodes_iteration,
1474 &nid);
1475 }
1476 else
1477 {
1478 if (!run_test_nodes_iteration (&nid))
1479 _dbus_assert_not_reached ("no memory");
1480 }
1481
1482 data_block_free (&block);
1483 }
1484
1485 static void
1486 run_test_nodes (TestTypeNode **nodes,
1487 int n_nodes)
1488 {
1489 int i;
1490 DBusString signature;
1491
1492 if (!_dbus_string_init (&signature))
1493 _dbus_assert_not_reached ("no memory");
1494
1495 i = 0;
1496 while (i < n_nodes)
1497 {
1498 if (! node_build_signature (nodes[i], &signature))
1499 _dbus_assert_not_reached ("no memory");
1500
1501 ++i;
1502 }
1503
1504 _dbus_verbose (">>> test nodes with signature '%s'\n",
1505 _dbus_string_get_const_data (&signature));
1506
1507 i = 0;
1508 while (i <= MAX_INITIAL_OFFSET)
1509 {
1510 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1511 DBUS_LITTLE_ENDIAN, i);
1512 run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,
1513 DBUS_BIG_ENDIAN, i);
1514
1515 ++i;
1516 }
1517
1518 n_iterations_completed_this_test += 1;
1519 n_iterations_completed_total += 1;
1520
1521 if (n_iterations_completed_this_test == n_iterations_expected_this_test)
1522 {
1523 fprintf (stderr, " 100%% %d this test (%d cumulative)\n",
1524 n_iterations_completed_this_test,
1525 n_iterations_completed_total);
1526 }
1527 /* this happens to turn out well with mod == 1 */
1528 else if ((n_iterations_completed_this_test %
1529 (int)(n_iterations_expected_this_test / 10.0)) == 1)
1530 {
1531 fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100));
1532 }
1533
1534 _dbus_string_free (&signature);
1535 }
1536
1537 #define N_VALUES (N_BASICS * N_CONTAINERS + N_BASICS)
1538
1539 static TestTypeNode*
1540 value_generator (int *ip)
1541 {
1542 int i = *ip;
1543 const TestTypeNodeClass *child_klass;
1544 const TestTypeNodeClass *container_klass;
1545 TestTypeNode *child;
1546 TestTypeNode *node;
1547
1548 _dbus_assert (i <= N_VALUES);
1549
1550 if (i == N_VALUES)
1551 {
1552 return NULL;
1553 }
1554 else if (i < N_BASICS)
1555 {
1556 node = node_new (basic_nodes[i]);
1557 }
1558 else
1559 {
1560 /* imagine an array:
1561 * container 0 of basic 0
1562 * container 0 of basic 1
1563 * container 0 of basic 2
1564 * container 1 of basic 0
1565 * container 1 of basic 1
1566 * container 1 of basic 2
1567 */
1568 i -= N_BASICS;
1569
1570 container_klass = container_nodes[i / N_BASICS];
1571 child_klass = basic_nodes[i % N_BASICS];
1572
1573 node = node_new (container_klass);
1574 child = node_new (child_klass);
1575
1576 node_append_child (node, child);
1577 }
1578
1579 *ip += 1; /* increment the generator */
1580
1581 return node;
1582 }
1583
1584 static void
1585 build_body (TestTypeNode **nodes,
1586 int n_nodes,
1587 int byte_order,
1588 DBusString *signature,
1589 DBusString *body)
1590 {
1591 int i;
1592 DataBlock block;
1593 DBusTypeReader reader;
1594 DBusTypeWriter writer;
1595
1596 i = 0;
1597 while (i < n_nodes)
1598 {
1599 if (! node_build_signature (nodes[i], signature))
1600 _dbus_assert_not_reached ("no memory");
1601
1602 ++i;
1603 }
1604
1605 if (!data_block_init (&block, byte_order, 0))
1606 _dbus_assert_not_reached ("no memory");
1607
1608 data_block_init_reader_writer (&block,
1609 &reader, &writer);
1610
1611 /* DBusTypeWriter assumes it's writing into an existing signature,
1612 * so doesn't add nul on its own. We have to do that.
1613 */
1614 if (!_dbus_string_insert_byte (&block.signature,
1615 0, '\0'))
1616 _dbus_assert_not_reached ("no memory");
1617
1618 i = 0;
1619 while (i < n_nodes)
1620 {
1621 if (!node_write_value (nodes[i], &block, &writer, i))
1622 _dbus_assert_not_reached ("no memory");
1623
1624 ++i;
1625 }
1626
1627 if (!_dbus_string_copy_len (&block.body, 0,
1628 _dbus_string_get_length (&block.body) - N_FENCE_BYTES,
1629 body, 0))
1630 _dbus_assert_not_reached ("oom");
1631
1632 data_block_free (&block);
1633 }
1634
1635 dbus_bool_t
1636 dbus_internal_do_not_use_generate_bodies (int sequence,
1637 int byte_order,
1638 DBusString *signature,
1639 DBusString *body)
1640 {
1641 TestTypeNode *nodes[1];
1642 int i;
1643 int n_nodes;
1644
1645 nodes[0] = value_generator (&sequence);
1646
1647 if (nodes[0] == NULL)
1648 return FALSE;
1649
1650 n_nodes = 1;
1651
1652 build_body (nodes, n_nodes, byte_order, signature, body);
1653
1654
1655 i = 0;
1656 while (i < n_nodes)
1657 {
1658 node_destroy (nodes[i]);
1659 ++i;
1660 }
1661
1662 return TRUE;
1663 }
1664
1665 static void
1666 make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,
1667 int n_nested)
1668 {
1669 TestTypeNode *root;
1670 TestTypeNode *container;
1671 TestTypeNode *child;
1672 int i;
1673
1674 root = node_new (container_klass);
1675 container = root;
1676 for (i = 1; i < n_nested; i++)
1677 {
1678 child = node_new (container_klass);
1679 node_append_child (container, child);
1680 container = child;
1681 }
1682
1683 /* container should now be the most-nested container */
1684
1685 i = 0;
1686 while ((child = value_generator (&i)))
1687 {
1688 node_append_child (container, child);
1689
1690 run_test_nodes (&root, 1);
1691
1692 _dbus_list_clear (&((TestTypeNodeContainer*)container)->children);
1693 node_destroy (child);
1694 }
1695
1696 node_destroy (root);
1697 }
1698
1699 static void
1700 start_next_test (const char *format,
1701 int expected)
1702 {
1703 n_iterations_completed_this_test = 0;
1704 n_iterations_expected_this_test = expected;
1705
1706 fprintf (stderr, ">>> >>> ");
1707 fprintf (stderr, format,
1708 n_iterations_expected_this_test);
1709 }
1710
1711 static void
1712 make_and_run_test_nodes (void)
1713 {
1714 int i, j, k, m;
1715
1716 /* We try to do this in order of "complicatedness" so that test
1717 * failures tend to show up in the simplest test case that
1718 * demonstrates the failure. There are also some tests that run
1719 * more than once for this reason, first while going through simple
1720 * cases, second while going through a broader range of complex
1721 * cases.
1722 */
1723 /* Each basic node. The basic nodes should include:
1724 *
1725 * - each fixed-size type (in such a way that it has different values each time,
1726 * so we can tell if we mix two of them up)
1727 * - strings of various lengths
1728 * - object path
1729 * - signature
1730 */
1731 /* Each container node. The container nodes should include:
1732 *
1733 * struct with 1 and 2 copies of the contained item
1734 * array with 0, 1, 2 copies of the contained item
1735 * variant
1736 */
1737 /* Let a "value" be a basic node, or a container containing a single basic node.
1738 * Let n_values be the number of such values i.e. (n_container * n_basic + n_basic)
1739 * When iterating through all values to make combinations, do the basic types
1740 * first and the containers second.
1741 */
1742 /* Each item is shown with its number of iterations to complete so
1743 * we can keep a handle on this unit test
1744 */
1745
1746 /* FIXME test just an empty body, no types at all */
1747
1748 start_next_test ("Each value by itself %d iterations\n", N_VALUES);
1749 {
1750 TestTypeNode *node;
1751 i = 0;
1752 while ((node = value_generator (&i)))
1753 {
1754 run_test_nodes (&node, 1);
1755
1756 node_destroy (node);
1757 }
1758 }
1759
1760 start_next_test ("Each value by itself with arrays as blocks %d iterations\n", N_VALUES);
1761 arrays_write_fixed_in_blocks = TRUE;
1762 {
1763 TestTypeNode *node;
1764 i = 0;
1765 while ((node = value_generator (&i)))
1766 {
1767 run_test_nodes (&node, 1);
1768
1769 node_destroy (node);
1770 }
1771 }
1772 arrays_write_fixed_in_blocks = FALSE;
1773
1774 start_next_test ("All values in one big toplevel %d iteration\n", 1);
1775 {
1776 TestTypeNode *nodes[N_VALUES];
1777 TestTypeNode *node;
1778
1779 i = 0;
1780 while ((node = value_generator (&i)))
1781 {
1782 nodes[i - 1] = node;
1783 }
1784
1785 run_test_nodes (nodes, N_VALUES);
1786
1787 for (i = 0; i < N_VALUES; i++)
1788 node_destroy (nodes[i]);
1789 }
1790
1791 start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n",
1792 N_VALUES * N_VALUES);
1793 {
1794 TestTypeNode *nodes[2];
1795
1796 i = 0;
1797 while ((nodes[0] = value_generator (&i)))
1798 {
1799 j = 0;
1800 while ((nodes[1] = value_generator (&j)))
1801 {
1802 run_test_nodes (nodes, 2);
1803
1804 node_destroy (nodes[1]);
1805 }
1806
1807 node_destroy (nodes[0]);
1808 }
1809 }
1810
1811 start_next_test ("Each container containing each value %d iterations\n",
1812 N_CONTAINERS * N_VALUES);
1813 for (i = 0; i < N_CONTAINERS; i++)
1814 {
1815 const TestTypeNodeClass *container_klass = container_nodes[i];
1816
1817 make_and_run_values_inside_container (container_klass, 1);
1818 }
1819
1820 start_next_test ("Each container containing each value with arrays as blocks %d iterations\n",
1821 N_CONTAINERS * N_VALUES);
1822 arrays_write_fixed_in_blocks = TRUE;
1823 for (i = 0; i < N_CONTAINERS; i++)
1824 {
1825 const TestTypeNodeClass *container_klass = container_nodes[i];
1826
1827 make_and_run_values_inside_container (container_klass, 1);
1828 }
1829 arrays_write_fixed_in_blocks = FALSE;
1830
1831 start_next_test ("Each container of same container of each value %d iterations\n",
1832 N_CONTAINERS * N_VALUES);
1833 for (i = 0; i < N_CONTAINERS; i++)
1834 {
1835 const TestTypeNodeClass *container_klass = container_nodes[i];
1836
1837 make_and_run_values_inside_container (container_klass, 2);
1838 }
1839
1840 start_next_test ("Each container of same container of same container of each value %d iterations\n",
1841 N_CONTAINERS * N_VALUES);
1842 for (i = 0; i < N_CONTAINERS; i++)
1843 {
1844 const TestTypeNodeClass *container_klass = container_nodes[i];
1845
1846 make_and_run_values_inside_container (container_klass, 3);
1847 }
1848
1849 start_next_test ("Each value,value pair inside a struct %d iterations\n",
1850 N_VALUES * N_VALUES);
1851 {
1852 TestTypeNode *val1, *val2;
1853 TestTypeNode *node;
1854
1855 node = node_new (&struct_1_class);
1856
1857 i = 0;
1858 while ((val1 = value_generator (&i)))
1859 {
1860 j = 0;
1861 while ((val2 = value_generator (&j)))
1862 {
1863 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1864
1865 node_append_child (node, val1);
1866 node_append_child (node, val2);
1867
1868 run_test_nodes (&node, 1);
1869
1870 _dbus_list_clear (&container->children);
1871 node_destroy (val2);
1872 }
1873 node_destroy (val1);
1874 }
1875 node_destroy (node);
1876 }
1877
1878 start_next_test ("All values in one big struct %d iteration\n",
1879 1);
1880 {
1881 TestTypeNode *node;
1882 TestTypeNode *child;
1883
1884 node = node_new (&struct_1_class);
1885
1886 i = 0;
1887 while ((child = value_generator (&i)))
1888 node_append_child (node, child);
1889
1890 run_test_nodes (&node, 1);
1891
1892 node_destroy (node);
1893 }
1894
1895 start_next_test ("Each value in a large array %d iterations\n",
1896 N_VALUES);
1897 {
1898 TestTypeNode *val;
1899 TestTypeNode *node;
1900
1901 node = node_new (&array_9_class);
1902
1903 i = 0;
1904 while ((val = value_generator (&i)))
1905 {
1906 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
1907
1908 node_append_child (node, val);
1909
1910 run_test_nodes (&node, 1);
1911
1912 _dbus_list_clear (&container->children);
1913 node_destroy (val);
1914 }
1915
1916 node_destroy (node);
1917 }
1918
1919 if (_dbus_getenv ("DBUS_TEST_SLOW") == NULL ||
1920 atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 1)
1921 {
1922 fprintf (stderr, "skipping remaining marshal-recursive tests, "
1923 "run with DBUS_TEST_SLOW=1 (or more) to enable\n");
1924 goto out;
1925 }
1926
1927 start_next_test ("Each container of each container of each value %d iterations\n",
1928 N_CONTAINERS * N_CONTAINERS * N_VALUES);
1929 for (i = 0; i < N_CONTAINERS; i++)
1930 {
1931 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1932 TestTypeNode *outer_container = node_new (outer_container_klass);
1933
1934 for (j = 0; j < N_CONTAINERS; j++)
1935 {
1936 TestTypeNode *child;
1937 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1938 TestTypeNode *inner_container = node_new (inner_container_klass);
1939
1940 node_append_child (outer_container, inner_container);
1941
1942 m = 0;
1943 while ((child = value_generator (&m)))
1944 {
1945 node_append_child (inner_container, child);
1946
1947 run_test_nodes (&outer_container, 1);
1948
1949 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1950 node_destroy (child);
1951 }
1952 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1953 node_destroy (inner_container);
1954 }
1955 node_destroy (outer_container);
1956 }
1957
1958 start_next_test ("Each container of each container of each container of each value %d iterations\n",
1959 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);
1960 for (i = 0; i < N_CONTAINERS; i++)
1961 {
1962 const TestTypeNodeClass *outer_container_klass = container_nodes[i];
1963 TestTypeNode *outer_container = node_new (outer_container_klass);
1964
1965 for (j = 0; j < N_CONTAINERS; j++)
1966 {
1967 const TestTypeNodeClass *inner_container_klass = container_nodes[j];
1968 TestTypeNode *inner_container = node_new (inner_container_klass);
1969
1970 node_append_child (outer_container, inner_container);
1971
1972 for (k = 0; k < N_CONTAINERS; k++)
1973 {
1974 TestTypeNode *child;
1975 const TestTypeNodeClass *center_container_klass = container_nodes[k];
1976 TestTypeNode *center_container = node_new (center_container_klass);
1977
1978 node_append_child (inner_container, center_container);
1979
1980 m = 0;
1981 while ((child = value_generator (&m)))
1982 {
1983 node_append_child (center_container, child);
1984
1985 run_test_nodes (&outer_container, 1);
1986
1987 _dbus_list_clear (&((TestTypeNodeContainer*)center_container)->children);
1988 node_destroy (child);
1989 }
1990 _dbus_list_clear (&((TestTypeNodeContainer*)inner_container)->children);
1991 node_destroy (center_container);
1992 }
1993 _dbus_list_clear (&((TestTypeNodeContainer*)outer_container)->children);
1994 node_destroy (inner_container);
1995 }
1996 node_destroy (outer_container);
1997 }
1998
1999 /* This one takes a really long time (10 minutes on a Core2), so only enable
2000 * it if you're really sure */
2001 if (atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 2)
2002 {
2003 fprintf (stderr, "skipping really slow marshal-recursive test, "
2004 "run with DBUS_TEST_SLOW=2 (or more) to enable\n");
2005 goto out;
2006 }
2007
2008 start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n",
2009 N_VALUES * N_VALUES * N_VALUES);
2010 {
2011 TestTypeNode *nodes[3];
2012
2013 i = 0;
2014 while ((nodes[0] = value_generator (&i)))
2015 {
2016 j = 0;
2017 while ((nodes[1] = value_generator (&j)))
2018 {
2019 k = 0;
2020 while ((nodes[2] = value_generator (&k)))
2021 {
2022 run_test_nodes (nodes, 3);
2023
2024 node_destroy (nodes[2]);
2025 }
2026 node_destroy (nodes[1]);
2027 }
2028 node_destroy (nodes[0]);
2029 }
2030 }
2031
2032 out:
2033 fprintf (stderr, "%d total iterations of recursive marshaling tests\n",
2034 n_iterations_completed_total);
2035 fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n",
2036 MAX_INITIAL_OFFSET);
2037 fprintf (stderr, "out of memory handling %s tested\n",
2038 TEST_OOM_HANDLING ? "was" : "was not");
2039 }
2040
2041 dbus_bool_t
2042 _dbus_marshal_recursive_test (void)
2043 {
2044 make_and_run_test_nodes ();
2045
2046 return TRUE;
2047 }
2048
2049 /*
2050 *
2051 *
2052 * Implementations of each type node class
2053 *
2054 *
2055 *
2056 */
2057 #define MAX_MULTI_COUNT 5
2058
2059 #define SAMPLE_INT16 1234
2060 #define SAMPLE_INT16_ALTERNATE 6785
2061 static dbus_int16_t
2062 int16_from_seed (int seed)
2063 {
2064 /* Generate an integer value that's predictable from seed. We could
2065 * just use seed itself, but that would only ever touch one byte of
2066 * the int so would miss some kinds of bug.
2067 */
2068 dbus_int16_t v;
2069
2070 v = 42; /* just to quiet compiler afaik */
2071 switch (seed % 5)
2072 {
2073 case 0:
2074 v = SAMPLE_INT16;
2075 break;
2076 case 1:
2077 v = SAMPLE_INT16_ALTERNATE;
2078 break;
2079 case 2:
2080 v = -1;
2081 break;
2082 case 3:
2083 v = _DBUS_INT16_MAX;
2084 break;
2085 case 4:
2086 v = 1;
2087 break;
2088 }
2089
2090 if (seed > 1)
2091 v *= seed; /* wraps around eventually, which is fine */
2092
2093 return v;
2094 }
2095
2096 static dbus_bool_t
2097 int16_write_value (TestTypeNode *node,
2098 DataBlock *block,
2099 DBusTypeWriter *writer,
2100 int seed)
2101 {
2102 /* also used for uint16 */
2103 dbus_int16_t v;
2104
2105 v = int16_from_seed (seed);
2106
2107 return _dbus_type_writer_write_basic (writer,
2108 node->klass->typecode,
2109 &v);
2110 }
2111
2112 static dbus_bool_t
2113 int16_read_value (TestTypeNode *node,
2114 DBusTypeReader *reader,
2115 int seed)
2116 {
2117 /* also used for uint16 */
2118 dbus_int16_t v;
2119
2120 check_expected_type (reader, node->klass->typecode);
2121
2122 _dbus_type_reader_read_basic (reader,
2123 (dbus_int16_t*) &v);
2124
2125 _dbus_assert (v == int16_from_seed (seed));
2126
2127 return TRUE;
2128 }
2129
2130 static dbus_bool_t
2131 int16_set_value (TestTypeNode *node,
2132 DBusTypeReader *reader,
2133 DBusTypeReader *realign_root,
2134 int seed)
2135 {
2136 /* also used for uint16 */
2137 dbus_int16_t v;
2138
2139 v = int16_from_seed (seed);
2140
2141 return _dbus_type_reader_set_basic (reader,
2142 &v,
2143 realign_root);
2144 }
2145
2146 static dbus_bool_t
2147 int16_write_multi (TestTypeNode *node,
2148 DataBlock *block,
2149 DBusTypeWriter *writer,
2150 int seed,
2151 int count)
2152 {
2153 /* also used for uint16 */
2154 dbus_int16_t values[MAX_MULTI_COUNT];
2155 dbus_int16_t *v_ARRAY_INT16 = values;
2156 int i;
2157
2158 for (i = 0; i < count; ++i)
2159 values[i] = int16_from_seed (seed + i);
2160
2161 return _dbus_type_writer_write_fixed_multi (writer,
2162 node->klass->typecode,
2163 &v_ARRAY_INT16, count);
2164 }
2165
2166 static dbus_bool_t
2167 int16_read_multi (TestTypeNode *node,
2168 DBusTypeReader *reader,
2169 int seed,
2170 int count)
2171 {
2172 /* also used for uint16 */
2173 dbus_int16_t *values;
2174 int n_elements;
2175 int i;
2176
2177 check_expected_type (reader, node->klass->typecode);
2178
2179 _dbus_type_reader_read_fixed_multi (reader,
2180 &values,
2181 &n_elements);
2182
2183 if (n_elements != count)
2184 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2185 _dbus_assert (n_elements == count);
2186
2187 for (i = 0; i < count; i++)
2188 _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order,
2189 (const unsigned char*)values + (i * 2))) ==
2190 int16_from_seed (seed + i));
2191
2192 return TRUE;
2193 }
2194
2195
2196 #define SAMPLE_INT32 12345678
2197 #define SAMPLE_INT32_ALTERNATE 53781429
2198 static dbus_int32_t
2199 int32_from_seed (int seed)
2200 {
2201 /* Generate an integer value that's predictable from seed. We could
2202 * just use seed itself, but that would only ever touch one byte of
2203 * the int so would miss some kinds of bug.
2204 */
2205 dbus_int32_t v;
2206
2207 v = 42; /* just to quiet compiler afaik */
2208 switch (seed % 5)
2209 {
2210 case 0:
2211 v = SAMPLE_INT32;
2212 break;
2213 case 1:
2214 v = SAMPLE_INT32_ALTERNATE;
2215 break;
2216 case 2:
2217 v = -1;
2218 break;
2219 case 3:
2220 v = _DBUS_INT_MAX;
2221 break;
2222 case 4:
2223 v = 1;
2224 break;
2225 }
2226
2227 if (seed > 1)
2228 v *= seed; /* wraps around eventually, which is fine */
2229
2230 return v;
2231 }
2232
2233 static dbus_bool_t
2234 int32_write_value (TestTypeNode *node,
2235 DataBlock *block,
2236 DBusTypeWriter *writer,
2237 int seed)
2238 {
2239 /* also used for uint32 */
2240 dbus_int32_t v;
2241
2242 v = int32_from_seed (seed);
2243
2244 return _dbus_type_writer_write_basic (writer,
2245 node->klass->typecode,
2246 &v);
2247 }
2248
2249 static dbus_bool_t
2250 int32_read_value (TestTypeNode *node,
2251 DBusTypeReader *reader,
2252 int seed)
2253 {
2254 /* also used for uint32 */
2255 dbus_int32_t v;
2256
2257 check_expected_type (reader, node->klass->typecode);
2258
2259 _dbus_type_reader_read_basic (reader,
2260 (dbus_int32_t*) &v);
2261
2262 _dbus_assert (v == int32_from_seed (seed));
2263
2264 return TRUE;
2265 }
2266
2267 static dbus_bool_t
2268 int32_set_value (TestTypeNode *node,
2269 DBusTypeReader *reader,
2270 DBusTypeReader *realign_root,
2271 int seed)
2272 {
2273 /* also used for uint32 */
2274 dbus_int32_t v;
2275
2276 v = int32_from_seed (seed);
2277
2278 return _dbus_type_reader_set_basic (reader,
2279 &v,
2280 realign_root);
2281 }
2282
2283 static dbus_bool_t
2284 int32_write_multi (TestTypeNode *node,
2285 DataBlock *block,
2286 DBusTypeWriter *writer,
2287 int seed,
2288 int count)
2289 {
2290 /* also used for uint32 */
2291 dbus_int32_t values[MAX_MULTI_COUNT];
2292 dbus_int32_t *v_ARRAY_INT32 = values;
2293 int i;
2294
2295 for (i = 0; i < count; ++i)
2296 values[i] = int32_from_seed (seed + i);
2297
2298 return _dbus_type_writer_write_fixed_multi (writer,
2299 node->klass->typecode,
2300 &v_ARRAY_INT32, count);
2301 }
2302
2303 static dbus_bool_t
2304 int32_read_multi (TestTypeNode *node,
2305 DBusTypeReader *reader,
2306 int seed,
2307 int count)
2308 {
2309 /* also used for uint32 */
2310 dbus_int32_t *values;
2311 int n_elements;
2312 int i;
2313
2314 check_expected_type (reader, node->klass->typecode);
2315
2316 _dbus_type_reader_read_fixed_multi (reader,
2317 &values,
2318 &n_elements);
2319
2320 if (n_elements != count)
2321 _dbus_warn ("got %d elements expected %d\n", n_elements, count);
2322 _dbus_assert (n_elements == count);
2323
2324 for (i = 0; i < count; i++)
2325 _dbus_assert (((int)_dbus_unpack_uint32 (reader->byte_order,
2326 (const unsigned char*)values + (i * 4))) ==
2327 int32_from_seed (seed + i));
2328
2329 return TRUE;
2330 }
2331
2332 static dbus_int64_t
2333 int64_from_seed (int seed)
2334 {
2335 dbus_int32_t v32;
2336 dbus_int64_t v;
2337
2338 v32 = int32_from_seed (seed);
2339
2340 v = - (dbus_int32_t) ~ v32;
2341 v |= (((dbus_int64_t)v32) << 32);
2342
2343 return v;
2344 }
2345
2346 static dbus_bool_t
2347 int64_write_value (TestTypeNode *node,
2348 DataBlock *block,
2349 DBusTypeWriter *writer,
2350 int seed)
2351 {
2352 /* also used for uint64 */
2353 dbus_int64_t v;
2354
2355 v = int64_from_seed (seed);
2356
2357 return _dbus_type_writer_write_basic (writer,
2358 node->klass->typecode,
2359 &v);
2360 }
2361
2362 static dbus_bool_t
2363 int64_read_value (TestTypeNode *node,
2364 DBusTypeReader *reader,
2365 int seed)
2366 {
2367 /* also used for uint64 */
2368 dbus_int64_t v;
2369
2370 check_expected_type (reader, node->klass->typecode);
2371
2372 _dbus_type_reader_read_basic (reader,
2373 (dbus_int64_t*) &v);
2374
2375 _dbus_assert (v == int64_from_seed (seed));
2376
2377 return TRUE;
2378 }
2379
2380 static dbus_bool_t
2381 int64_set_value (TestTypeNode *node,
2382 DBusTypeReader *reader,
2383 DBusTypeReader *realign_root,
2384 int seed)
2385 {
2386 /* also used for uint64 */
2387 dbus_int64_t v;
2388
2389 v = int64_from_seed (seed);
2390
2391 return _dbus_type_reader_set_basic (reader,
2392 &v,
2393 realign_root);
2394 }
2395
2396 #define MAX_SAMPLE_STRING_LEN 10
2397 static void
2398 string_from_seed (char *buf,
2399 int len,
2400 int seed)
2401 {
2402 int i;
2403 unsigned char v;
2404
2405 _dbus_assert (len < MAX_SAMPLE_STRING_LEN);
2406
2407 /* vary the length slightly, though we also have multiple string
2408 * value types for this, varying it here tests the set_value code
2409 */
2410 switch (seed % 3)
2411 {
2412 case 1:
2413 len += 2;
2414 break;
2415 case 2:
2416 len -= 2;
2417 break;
2418 }
2419 if (len < 0)
2420 len = 0;
2421
2422 v = (unsigned char) ('A' + seed);
2423
2424 i = 0;
2425 while (i < len)
2426 {
2427 if (v < 'A' || v > 'z')
2428 v = 'A';
2429
2430 buf[i] = v;
2431
2432 v += 1;
2433 ++i;
2434 }
2435
2436 buf[i] = '\0';
2437 }
2438
2439 static dbus_bool_t
2440 string_write_value (TestTypeNode *node,
2441 DataBlock *block,
2442 DBusTypeWriter *writer,
2443 int seed)
2444 {
2445 char buf[MAX_SAMPLE_STRING_LEN + 1]="";
2446 const char *v_string = buf;
2447
2448
2449 string_from_seed (buf, node->klass->subclass_detail,
2450 seed);
2451
2452 return _dbus_type_writer_write_basic (writer,
2453 node->klass->typecode,
2454 &v_string);
2455 }
2456
2457 static dbus_bool_t
2458 string_read_value (TestTypeNode *node,
2459 DBusTypeReader *reader,
2460 int seed)
2461 {
2462 const char *v;
2463 char buf[MAX_SAMPLE_STRING_LEN + 1];
2464 v = buf;
2465
2466 check_expected_type (reader, node->klass->typecode);
2467
2468 _dbus_type_reader_read_basic (reader,
2469 (const char **) &v);
2470
2471 string_from_seed (buf, node->klass->subclass_detail,
2472 seed);
2473
2474 if (strcmp (buf, v) != 0)
2475 {
2476 _dbus_warn ("read string '%s' expected '%s'\n",
2477 v, buf);
2478 _dbus_assert_not_reached ("test failed");
2479 }
2480
2481 return TRUE;
2482 }
2483
2484 static dbus_bool_t
2485 string_set_value (TestTypeNode *node,
2486 DBusTypeReader *reader,
2487 DBusTypeReader *realign_root,
2488 int seed)
2489 {
2490 char buf[MAX_SAMPLE_STRING_LEN + 1];
2491 const char *v_string = buf;
2492
2493 string_from_seed (buf, node->klass->subclass_detail,
2494 seed);
2495
2496 #if RECURSIVE_MARSHAL_WRITE_TRACE
2497 {
2498 const char *old;
2499 _dbus_type_reader_read_basic (reader, &old);
2500 _dbus_verbose ("SETTING new string '%s' len %d in place of '%s' len %d\n",
2501 v_string, strlen (v_string), old, strlen (old));
2502 }
2503 #endif
2504
2505 return _dbus_type_reader_set_basic (reader,
2506 &v_string,
2507 realign_root);
2508 }
2509
2510 #define BOOL_FROM_SEED(seed) ((dbus_bool_t)((seed) % 2))
2511
2512 static dbus_bool_t
2513 bool_write_value (TestTypeNode *node,
2514 DataBlock *block,
2515 DBusTypeWriter *writer,
2516 int seed)
2517 {
2518 dbus_bool_t v;
2519
2520 v = BOOL_FROM_SEED (seed);
2521
2522 return _dbus_type_writer_write_basic (writer,
2523 node->klass->typecode,
2524 &v);
2525 }
2526
2527 static dbus_bool_t
2528 bool_read_value (TestTypeNode *node,
2529 DBusTypeReader *reader,
2530 int seed)
2531 {
2532 dbus_bool_t v;
2533
2534 check_expected_type (reader, node->klass->typecode);
2535
2536 _dbus_type_reader_read_basic (reader,
2537 (unsigned char*) &v);
2538
2539 _dbus_assert (v == BOOL_FROM_SEED (seed));
2540
2541 return TRUE;
2542 }
2543
2544 static dbus_bool_t
2545 bool_set_value (TestTypeNode *node,
2546 DBusTypeReader *reader,
2547 DBusTypeReader *realign_root,
2548 int seed)
2549 {
2550 dbus_bool_t v;
2551
2552 v = BOOL_FROM_SEED (seed);
2553
2554 return _dbus_type_reader_set_basic (reader,
2555 &v,
2556 realign_root);
2557 }
2558
2559 #define BYTE_FROM_SEED(seed) ((unsigned char) int32_from_seed (seed))
2560
2561 static dbus_bool_t
2562 byte_write_value (TestTypeNode *node,
2563 DataBlock *block,
2564 DBusTypeWriter *writer,
2565 int seed)
2566 {
2567 unsigned char v;
2568
2569 v = BYTE_FROM_SEED (seed);
2570
2571 return _dbus_type_writer_write_basic (writer,
2572 node->klass->typecode,
2573 &v);
2574 }
2575
2576 static dbus_bool_t
2577 byte_read_value (TestTypeNode *node,
2578 DBusTypeReader *reader,
2579 int seed)
2580 {
2581 unsigned char v;
2582
2583 check_expected_type (reader, node->klass->typecode);
2584
2585 _dbus_type_reader_read_basic (reader,
2586 (unsigned char*) &v);
2587
2588 _dbus_assert (v == BYTE_FROM_SEED (seed));
2589
2590 return TRUE;
2591 }
2592
2593
2594 static dbus_bool_t
2595 byte_set_value (TestTypeNode *node,
2596 DBusTypeReader *reader,
2597 DBusTypeReader *realign_root,
2598 int seed)
2599 {
2600 unsigned char v;
2601
2602 v = BYTE_FROM_SEED (seed);
2603
2604 return _dbus_type_reader_set_basic (reader,
2605 &v,
2606 realign_root);
2607 }
2608
2609 static double
2610 double_from_seed (int seed)
2611 {
2612 return SAMPLE_INT32 * (double) seed + 0.3;
2613 }
2614
2615 static dbus_bool_t
2616 double_write_value (TestTypeNode *node,
2617 DataBlock *block,
2618 DBusTypeWriter *writer,
2619 int seed)
2620 {
2621 double v;
2622
2623 v = double_from_seed (seed);
2624
2625 return _dbus_type_writer_write_basic (writer,
2626 node->klass->typecode,
2627 &v);
2628 }
2629
2630 static dbus_bool_t
2631 double_read_value (TestTypeNode *node,
2632 DBusTypeReader *reader,
2633 int seed)
2634 {
2635 double v;
2636 double expected;
2637
2638 check_expected_type (reader, node->klass->typecode);
2639
2640 _dbus_type_reader_read_basic (reader,
2641 (double*) &v);
2642
2643 expected = double_from_seed (seed);
2644
2645 if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
2646 {
2647 #ifdef DBUS_INT64_PRINTF_MODIFIER
2648 _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",
2649 expected, v,
2650 *(dbus_uint64_t*)(char*)&expected,
2651 *(dbus_uint64_t*)(char*)&v);
2652 #endif
2653 _dbus_assert_not_reached ("test failed");
2654 }
2655
2656 return TRUE;
2657 }
2658
2659 static dbus_bool_t
2660 double_set_value (TestTypeNode *node,
2661 DBusTypeReader *reader,
2662 DBusTypeReader *realign_root,
2663 int seed)
2664 {
2665 double v;
2666
2667 v = double_from_seed (seed);
2668
2669 return _dbus_type_reader_set_basic (reader,
2670 &v,
2671 realign_root);
2672 }
2673
2674 #define MAX_SAMPLE_OBJECT_PATH_LEN 10
2675 static void
2676 object_path_from_seed (char *buf,
2677 int seed)
2678 {
2679 int i;
2680 unsigned char v;
2681 int len;
2682
2683 len = seed % 9;
2684 _dbus_assert (len < MAX_SAMPLE_OBJECT_PATH_LEN);
2685
2686 v = (unsigned char) ('A' + seed);
2687
2688 if (len < 2)
2689 {
2690 buf[0] = '/';
2691 i = 1;
2692 }
2693 else
2694 {
2695 i = 0;
2696 while (i + 1 < len)
2697 {
2698 if (v < 'A' || v > 'z')
2699 v = 'A';
2700
2701 buf[i] = '/';
2702 ++i;
2703 buf[i] = v;
2704 ++i;
2705
2706 v += 1;
2707 }
2708 }
2709
2710 buf[i] = '\0';
2711 }
2712
2713 static dbus_bool_t
2714 object_path_write_value (TestTypeNode *node,
2715 DataBlock *block,
2716 DBusTypeWriter *writer,
2717 int seed)
2718 {
2719 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2720 const char *v_string = buf;
2721
2722 object_path_from_seed (buf, seed);
2723
2724 return _dbus_type_writer_write_basic (writer,
2725 node->klass->typecode,
2726 &v_string);
2727 }
2728
2729 static dbus_bool_t
2730 object_path_read_value (TestTypeNode *node,
2731 DBusTypeReader *reader,
2732 int seed)
2733 {
2734 const char *v;
2735 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2736
2737 check_expected_type (reader, node->klass->typecode);
2738
2739 _dbus_type_reader_read_basic (reader,
2740 (const char **) &v);
2741
2742 object_path_from_seed (buf, seed);
2743
2744 if (strcmp (buf, v) != 0)
2745 {
2746 _dbus_warn ("read object path '%s' expected '%s'\n",
2747 v, buf);
2748 _dbus_assert_not_reached ("test failed");
2749 }
2750
2751 return TRUE;
2752 }
2753
2754 static dbus_bool_t
2755 object_path_set_value (TestTypeNode *node,
2756 DBusTypeReader *reader,
2757 DBusTypeReader *realign_root,
2758 int seed)
2759 {
2760 char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1];
2761 const char *v_string = buf;
2762
2763 object_path_from_seed (buf, seed);
2764
2765 return _dbus_type_reader_set_basic (reader,
2766 &v_string,
2767 realign_root);
2768 }
2769
2770 #define MAX_SAMPLE_SIGNATURE_LEN 10
2771 static void
2772 signature_from_seed (char *buf,
2773 int seed)
2774 {
2775 /* try to avoid ascending, descending, or alternating length to help find bugs */
2776 const char *sample_signatures[] = {
2777 "asax",
2778 "",
2779 "asau(xxxx)",
2780 "x",
2781 "ai",
2782 "a(ii)"
2783 };
2784
2785 strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]);
2786 }
2787
2788 static dbus_bool_t
2789 signature_write_value (TestTypeNode *node,
2790 DataBlock *block,
2791 DBusTypeWriter *writer,
2792 int seed)
2793 {
2794 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2795 const char *v_string = buf;
2796
2797 signature_from_seed (buf, seed);
2798
2799 return _dbus_type_writer_write_basic (writer,
2800 node->klass->typecode,
2801 &v_string);
2802 }
2803
2804 static dbus_bool_t
2805 signature_read_value (TestTypeNode *node,
2806 DBusTypeReader *reader,
2807 int seed)
2808 {
2809 const char *v;
2810 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2811
2812 check_expected_type (reader, node->klass->typecode);
2813
2814 _dbus_type_reader_read_basic (reader,
2815 (const char **) &v);
2816
2817 signature_from_seed (buf, seed);
2818
2819 if (strcmp (buf, v) != 0)
2820 {
2821 _dbus_warn ("read signature value '%s' expected '%s'\n",
2822 v, buf);
2823 _dbus_assert_not_reached ("test failed");
2824 }
2825
2826 return TRUE;
2827 }
2828
2829
2830 static dbus_bool_t
2831 signature_set_value (TestTypeNode *node,
2832 DBusTypeReader *reader,
2833 DBusTypeReader *realign_root,
2834 int seed)
2835 {
2836 char buf[MAX_SAMPLE_SIGNATURE_LEN + 1];
2837 const char *v_string = buf;
2838
2839 signature_from_seed (buf, seed);
2840
2841 return _dbus_type_reader_set_basic (reader,
2842 &v_string,
2843 realign_root);
2844 }
2845
2846 static dbus_bool_t
2847 struct_write_value (TestTypeNode *node,
2848 DataBlock *block,
2849 DBusTypeWriter *writer,
2850 int seed)
2851 {
2852 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2853 DataBlockState saved;
2854 DBusTypeWriter sub;
2855 int i;
2856 int n_copies;
2857
2858 n_copies = node->klass->subclass_detail;
2859
2860 _dbus_assert (container->children != NULL);
2861
2862 data_block_save (block, &saved);
2863
2864 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
2865 NULL, 0,
2866 &sub))
2867 return FALSE;
2868
2869 i = 0;
2870 while (i < n_copies)
2871 {
2872 DBusList *link;
2873
2874 link = _dbus_list_get_first_link (&container->children);
2875 while (link != NULL)
2876 {
2877 TestTypeNode *child = link->data;
2878 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2879
2880 if (!node_write_value (child, block, &sub, seed + i))
2881 {
2882 data_block_restore (block, &saved);
2883 return FALSE;
2884 }
2885
2886 link = next;
2887 }
2888
2889 ++i;
2890 }
2891
2892 if (!_dbus_type_writer_unrecurse (writer, &sub))
2893 {
2894 data_block_restore (block, &saved);
2895 return FALSE;
2896 }
2897
2898 return TRUE;
2899 }
2900
2901 static dbus_bool_t
2902 struct_read_or_set_value (TestTypeNode *node,
2903 DBusTypeReader *reader,
2904 DBusTypeReader *realign_root,
2905 int seed)
2906 {
2907 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2908 DBusTypeReader sub;
2909 int i;
2910 int n_copies;
2911
2912 n_copies = node->klass->subclass_detail;
2913
2914 check_expected_type (reader, DBUS_TYPE_STRUCT);
2915
2916 _dbus_type_reader_recurse (reader, &sub);
2917
2918 i = 0;
2919 while (i < n_copies)
2920 {
2921 DBusList *link;
2922
2923 link = _dbus_list_get_first_link (&container->children);
2924 while (link != NULL)
2925 {
2926 TestTypeNode *child = link->data;
2927 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2928
2929 if (realign_root == NULL)
2930 {
2931 if (!node_read_value (child, &sub, seed + i))
2932 return FALSE;
2933 }
2934 else
2935 {
2936 if (!node_set_value (child, &sub, realign_root, seed + i))
2937 return FALSE;
2938 }
2939
2940 if (i == (n_copies - 1) && next == NULL)
2941 NEXT_EXPECTING_FALSE (&sub);
2942 else
2943 NEXT_EXPECTING_TRUE (&sub);
2944
2945 link = next;
2946 }
2947
2948 ++i;
2949 }
2950
2951 return TRUE;
2952 }
2953
2954 static dbus_bool_t
2955 struct_read_value (TestTypeNode *node,
2956 DBusTypeReader *reader,
2957 int seed)
2958 {
2959 return struct_read_or_set_value (node, reader, NULL, seed);
2960 }
2961
2962 static dbus_bool_t
2963 struct_set_value (TestTypeNode *node,
2964 DBusTypeReader *reader,
2965 DBusTypeReader *realign_root,
2966 int seed)
2967 {
2968 return struct_read_or_set_value (node, reader, realign_root, seed);
2969 }
2970
2971 static dbus_bool_t
2972 struct_build_signature (TestTypeNode *node,
2973 DBusString *str)
2974 {
2975 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
2976 int i;
2977 int orig_len;
2978 int n_copies;
2979
2980 n_copies = node->klass->subclass_detail;
2981
2982 orig_len = _dbus_string_get_length (str);
2983
2984 if (!_dbus_string_append_byte (str, DBUS_STRUCT_BEGIN_CHAR))
2985 goto oom;
2986
2987 i = 0;
2988 while (i < n_copies)
2989 {
2990 DBusList *link;
2991
2992 link = _dbus_list_get_first_link (&container->children);
2993 while (link != NULL)
2994 {
2995 TestTypeNode *child = link->data;
2996 DBusList *next = _dbus_list_get_next_link (&container->children, link);
2997
2998 if (!node_build_signature (child, str))
2999 goto oom;
3000
3001 link = next;
3002 }
3003
3004 ++i;
3005 }
3006
3007 if (!_dbus_string_append_byte (str, DBUS_STRUCT_END_CHAR))
3008 goto oom;
3009
3010 return TRUE;
3011
3012 oom:
3013 _dbus_string_set_length (str, orig_len);
3014 return FALSE;
3015 }
3016
3017 static dbus_bool_t
3018 array_write_value (TestTypeNode *node,
3019 DataBlock *block,
3020 DBusTypeWriter *writer,
3021 int seed)
3022 {
3023 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3024 DataBlockState saved;
3025 DBusTypeWriter sub;
3026 DBusString element_signature;
3027 int i;
3028 int n_copies;
3029 int element_type;
3030 TestTypeNode *child;
3031
3032 n_copies = node->klass->subclass_detail;
3033
3034 _dbus_assert (container->children != NULL);
3035
3036 data_block_save (block, &saved);
3037
3038 if (!_dbus_string_init (&element_signature))
3039 return FALSE;
3040
3041 child = _dbus_list_get_first (&container->children);
3042
3043 if (!node_build_signature (child,
3044 &element_signature))
3045 goto oom;
3046
3047 element_type = _dbus_first_type_in_signature (&element_signature, 0);
3048
3049 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3050 &element_signature, 0,
3051 &sub))
3052 goto oom;
3053
3054 if (arrays_write_fixed_in_blocks &&
3055 dbus_type_is_fixed (element_type) &&
3056 child->klass->write_multi)
3057 {
3058 if (!node_write_multi (child, block, &sub, seed, n_copies))
3059 goto oom;
3060 }
3061 else
3062 {
3063 i = 0;
3064 while (i < n_copies)
3065 {
3066 DBusList *link;
3067
3068 link = _dbus_list_get_first_link (&container->children);
3069 while (link != NULL)
3070 {
3071 TestTypeNode *child = link->data;
3072 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3073
3074 if (!node_write_value (child, block, &sub, seed + i))
3075 goto oom;
3076
3077 link = next;
3078 }
3079
3080 ++i;
3081 }
3082 }
3083
3084 if (!_dbus_type_writer_unrecurse (writer, &sub))
3085 goto oom;
3086
3087 _dbus_string_free (&element_signature);
3088 return TRUE;
3089
3090 oom:
3091 data_block_restore (block, &saved);
3092 _dbus_string_free (&element_signature);
3093 return FALSE;
3094 }
3095
3096 static dbus_bool_t
3097 array_read_or_set_value (TestTypeNode *node,
3098 DBusTypeReader *reader,
3099 DBusTypeReader *realign_root,
3100 int seed)
3101 {
3102 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3103 DBusTypeReader sub;
3104 int i;
3105 int n_copies;
3106 TestTypeNode *child;
3107
3108 n_copies = node->klass->subclass_detail;
3109
3110 check_expected_type (reader, DBUS_TYPE_ARRAY);
3111
3112 child = _dbus_list_get_first (&container->children);
3113
3114 if (n_copies > 0)
3115 {
3116 _dbus_type_reader_recurse (reader, &sub);
3117
3118 if (realign_root == NULL && arrays_write_fixed_in_blocks &&
3119 dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) &&
3120 child->klass->read_multi)
3121 {
3122 if (!node_read_multi (child, &sub, seed, n_copies))
3123 return FALSE;
3124 }
3125 else
3126 {
3127 i = 0;
3128 while (i < n_copies)
3129 {
3130 DBusList *link;
3131
3132 link = _dbus_list_get_first_link (&container->children);
3133 while (link != NULL)
3134 {
3135 TestTypeNode *child = link->data;
3136 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3137
3138 _dbus_assert (child->klass->typecode ==
3139 _dbus_type_reader_get_element_type (reader));
3140
3141 if (realign_root == NULL)
3142 {
3143 if (!node_read_value (child, &sub, seed + i))
3144 return FALSE;
3145 }
3146 else
3147 {
3148 if (!node_set_value (child, &sub, realign_root, seed + i))
3149 return FALSE;
3150 }
3151
3152 if (i == (n_copies - 1) && next == NULL)
3153 NEXT_EXPECTING_FALSE (&sub);
3154 else
3155 NEXT_EXPECTING_TRUE (&sub);
3156
3157 link = next;
3158 }
3159
3160 ++i;
3161 }
3162 }
3163 }
3164
3165 return TRUE;
3166 }
3167
3168 static dbus_bool_t
3169 array_read_value (TestTypeNode *node,
3170 DBusTypeReader *reader,
3171 int seed)
3172 {
3173 return array_read_or_set_value (node, reader, NULL, seed);
3174 }
3175
3176 static dbus_bool_t
3177 array_set_value (TestTypeNode *node,
3178 DBusTypeReader *reader,
3179 DBusTypeReader *realign_root,
3180 int seed)
3181 {
3182 return array_read_or_set_value (node, reader, realign_root, seed);
3183 }
3184
3185 static dbus_bool_t
3186 array_build_signature (TestTypeNode *node,
3187 DBusString *str)
3188 {
3189 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3190 int orig_len;
3191
3192 orig_len = _dbus_string_get_length (str);
3193
3194 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3195 goto oom;
3196
3197 if (!node_build_signature (_dbus_list_get_first (&container->children),
3198 str))
3199 goto oom;
3200
3201 return TRUE;
3202
3203 oom:
3204 _dbus_string_set_length (str, orig_len);
3205 return FALSE;
3206 }
3207
3208 /* 10 is random just to add another seed that we use in the suite */
3209 #define VARIANT_SEED 10
3210
3211 static dbus_bool_t
3212 variant_write_value (TestTypeNode *node,
3213 DataBlock *block,
3214 DBusTypeWriter *writer,
3215 int seed)
3216 {
3217 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3218 DataBlockState saved;
3219 DBusTypeWriter sub;
3220 DBusString content_signature;
3221 TestTypeNode *child;
3222
3223 _dbus_assert (container->children != NULL);
3224 _dbus_assert (_dbus_list_length_is_one (&container->children));
3225
3226 child = _dbus_list_get_first (&container->children);
3227
3228 data_block_save (block, &saved);
3229
3230 if (!_dbus_string_init (&content_signature))
3231 return FALSE;
3232
3233 if (!node_build_signature (child,
3234 &content_signature))
3235 goto oom;
3236
3237 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_VARIANT,
3238 &content_signature, 0,
3239 &sub))
3240 goto oom;
3241
3242 if (!node_write_value (child, block, &sub, seed + VARIANT_SEED))
3243 goto oom;
3244
3245 if (!_dbus_type_writer_unrecurse (writer, &sub))
3246 goto oom;
3247
3248 _dbus_string_free (&content_signature);
3249 return TRUE;
3250
3251 oom:
3252 data_block_restore (block, &saved);
3253 _dbus_string_free (&content_signature);
3254 return FALSE;
3255 }
3256
3257 static dbus_bool_t
3258 variant_read_or_set_value (TestTypeNode *node,
3259 DBusTypeReader *reader,
3260 DBusTypeReader *realign_root,
3261 int seed)
3262 {
3263 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3264 DBusTypeReader sub;
3265 TestTypeNode *child;
3266
3267 _dbus_assert (container->children != NULL);
3268 _dbus_assert (_dbus_list_length_is_one (&container->children));
3269
3270 child = _dbus_list_get_first (&container->children);
3271
3272 check_expected_type (reader, DBUS_TYPE_VARIANT);
3273
3274 _dbus_type_reader_recurse (reader, &sub);
3275
3276 if (realign_root == NULL)
3277 {
3278 if (!node_read_value (child, &sub, seed + VARIANT_SEED))
3279 return FALSE;
3280 }
3281 else
3282 {
3283 if (!node_set_value (child, &sub, realign_root, seed + VARIANT_SEED))
3284 return FALSE;
3285 }
3286
3287 NEXT_EXPECTING_FALSE (&sub);
3288
3289 return TRUE;
3290 }
3291
3292 static dbus_bool_t
3293 variant_read_value (TestTypeNode *node,
3294 DBusTypeReader *reader,
3295 int seed)
3296 {
3297 return variant_read_or_set_value (node, reader, NULL, seed);
3298 }
3299
3300 static dbus_bool_t
3301 variant_set_value (TestTypeNode *node,
3302 DBusTypeReader *reader,
3303 DBusTypeReader *realign_root,
3304 int seed)
3305 {
3306 return variant_read_or_set_value (node, reader, realign_root, seed);
3307 }
3308
3309 static dbus_bool_t
3310 dict_write_value (TestTypeNode *node,
3311 DataBlock *block,
3312 DBusTypeWriter *writer,
3313 int seed)
3314 {
3315 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3316 DataBlockState saved;
3317 DBusTypeWriter sub;
3318 DBusString entry_value_signature;
3319 DBusString dict_entry_signature;
3320 int i;
3321 int n_entries;
3322 TestTypeNode *child;
3323
3324 n_entries = node->klass->subclass_detail;
3325
3326 _dbus_assert (container->children != NULL);
3327
3328 data_block_save (block, &saved);
3329
3330 if (!_dbus_string_init (&entry_value_signature))
3331 return FALSE;
3332
3333 if (!_dbus_string_init (&dict_entry_signature))
3334 {
3335 _dbus_string_free (&entry_value_signature);
3336 return FALSE;
3337 }
3338
3339 child = _dbus_list_get_first (&container->children);
3340
3341 if (!node_build_signature (child,
3342 &entry_value_signature))
3343 goto oom;
3344
3345 if (!_dbus_string_append (&dict_entry_signature,
3346 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3347 DBUS_TYPE_INT32_AS_STRING))
3348 goto oom;
3349
3350 if (!_dbus_string_copy (&entry_value_signature, 0,
3351 &dict_entry_signature,
3352 _dbus_string_get_length (&dict_entry_signature)))
3353 goto oom;
3354
3355 if (!_dbus_string_append_byte (&dict_entry_signature,
3356 DBUS_DICT_ENTRY_END_CHAR))
3357 goto oom;
3358
3359 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY,
3360 &dict_entry_signature, 0,
3361 &sub))
3362 goto oom;
3363
3364 i = 0;
3365 while (i < n_entries)
3366 {
3367 DBusTypeWriter entry_sub;
3368 dbus_int32_t key;
3369
3370 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY,
3371 NULL, 0,
3372 &entry_sub))
3373 goto oom;
3374
3375 key = int32_from_seed (seed + i);
3376
3377 if (!_dbus_type_writer_write_basic (&entry_sub,
3378 DBUS_TYPE_INT32,
3379 &key))
3380 goto oom;
3381
3382 if (!node_write_value (child, block, &entry_sub, seed + i))
3383 goto oom;
3384
3385 if (!_dbus_type_writer_unrecurse (&sub, &entry_sub))
3386 goto oom;
3387
3388 ++i;
3389 }
3390
3391 if (!_dbus_type_writer_unrecurse (writer, &sub))
3392 goto oom;
3393
3394 _dbus_string_free (&entry_value_signature);
3395 _dbus_string_free (&dict_entry_signature);
3396 return TRUE;
3397
3398 oom:
3399 data_block_restore (block, &saved);
3400 _dbus_string_free (&entry_value_signature);
3401 _dbus_string_free (&dict_entry_signature);
3402 return FALSE;
3403 }
3404
3405 static dbus_bool_t
3406 dict_read_or_set_value (TestTypeNode *node,
3407 DBusTypeReader *reader,
3408 DBusTypeReader *realign_root,
3409 int seed)
3410 {
3411 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3412 DBusTypeReader sub;
3413 int i;
3414 int n_entries;
3415 TestTypeNode *child;
3416
3417 n_entries = node->klass->subclass_detail;
3418
3419 check_expected_type (reader, DBUS_TYPE_ARRAY);
3420
3421 child = _dbus_list_get_first (&container->children);
3422
3423 if (n_entries > 0)
3424 {
3425 _dbus_type_reader_recurse (reader, &sub);
3426
3427 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3428
3429 i = 0;
3430 while (i < n_entries)
3431 {
3432 DBusTypeReader entry_sub;
3433
3434 check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY);
3435
3436 _dbus_type_reader_recurse (&sub, &entry_sub);
3437
3438 if (realign_root == NULL)
3439 {
3440 dbus_int32_t v;
3441
3442 check_expected_type (&entry_sub, DBUS_TYPE_INT32);
3443
3444 _dbus_type_reader_read_basic (&entry_sub,
3445 (dbus_int32_t*) &v);
3446
3447 _dbus_assert (v == int32_from_seed (seed + i));
3448
3449 NEXT_EXPECTING_TRUE (&entry_sub);
3450
3451 if (!node_read_value (child, &entry_sub, seed + i))
3452 return FALSE;
3453
3454 NEXT_EXPECTING_FALSE (&entry_sub);
3455 }
3456 else
3457 {
3458 dbus_int32_t v;
3459
3460 v = int32_from_seed (seed + i);
3461
3462 if (!_dbus_type_reader_set_basic (&entry_sub,
3463 &v,
3464 realign_root))
3465 return FALSE;
3466
3467 NEXT_EXPECTING_TRUE (&entry_sub);
3468
3469 if (!node_set_value (child, &entry_sub, realign_root, seed + i))
3470 return FALSE;
3471
3472 NEXT_EXPECTING_FALSE (&entry_sub);
3473 }
3474
3475 if (i == (n_entries - 1))
3476 NEXT_EXPECTING_FALSE (&sub);
3477 else
3478 NEXT_EXPECTING_TRUE (&sub);
3479
3480 ++i;
3481 }
3482 }
3483
3484 return TRUE;
3485 }
3486
3487 static dbus_bool_t
3488 dict_read_value (TestTypeNode *node,
3489 DBusTypeReader *reader,
3490 int seed)
3491 {
3492 return dict_read_or_set_value (node, reader, NULL, seed);
3493 }
3494
3495 static dbus_bool_t
3496 dict_set_value (TestTypeNode *node,
3497 DBusTypeReader *reader,
3498 DBusTypeReader *realign_root,
3499 int seed)
3500 {
3501 return dict_read_or_set_value (node, reader, realign_root, seed);
3502 }
3503
3504 static dbus_bool_t
3505 dict_build_signature (TestTypeNode *node,
3506 DBusString *str)
3507 {
3508 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3509 int orig_len;
3510
3511 orig_len = _dbus_string_get_length (str);
3512
3513 if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY))
3514 goto oom;
3515
3516 if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING))
3517 goto oom;
3518
3519 if (!node_build_signature (_dbus_list_get_first (&container->children),
3520 str))
3521 goto oom;
3522
3523 if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR))
3524 goto oom;
3525
3526 return TRUE;
3527
3528 oom:
3529 _dbus_string_set_length (str, orig_len);
3530 return FALSE;
3531 }
3532
3533 static void
3534 container_destroy (TestTypeNode *node)
3535 {
3536 TestTypeNodeContainer *container = (TestTypeNodeContainer*) node;
3537 DBusList *link;
3538
3539 link = _dbus_list_get_first_link (&container->children);
3540 while (link != NULL)
3541 {
3542 TestTypeNode *child = link->data;
3543 DBusList *next = _dbus_list_get_next_link (&container->children, link);
3544
3545 node_destroy (child);
3546
3547 _dbus_list_free_link (link);
3548
3549 link = next;
3550 }
3551 }
3552
3553 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
3554
3555 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
dbus_type_is_fixed
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value...
Definition: dbus-signature.c:349
_dbus_string_insert_bytes
dbus_bool_t _dbus_string_insert_bytes(DBusString *str, int i, int n_bytes, unsigned char byte)
Inserts a number of bytes of a given value at the given position.
Definition: dbus-string.c:584
_dbus_type_reader_read_fixed_multi
void _dbus_type_reader_read_fixed_multi(const DBusTypeReader *reader, void *value, int *n_elements)
Reads a block of fixed-length basic values, from the current point in an array to the end of the arra...
Definition: dbus-marshal-recursive.c:924
_dbus_string_append
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:935
DBUS_TYPE_UINT16
#define DBUS_TYPE_UINT16
Type code marking a 16-bit unsigned integer.
Definition: dbus-protocol.h:78
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
_dbus_string_equal
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2013
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
_dbus_first_type_in_signature
int _dbus_first_type_in_signature(const DBusString *str, int pos)
Get the first type in the signature.
Definition: dbus-marshal-basic.c:1416
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:64
_dbus_list_length_is_one
dbus_bool_t _dbus_list_length_is_one(DBusList **list)
Check whether length is exactly one.
Definition: dbus-list.c:783
_dbus_type_reader_recurse
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
Definition: dbus-marshal-recursive.c:989
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
Definition: dbus-protocol.h:136
DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures...
Definition: dbus-protocol.h:143
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:148
DBusList::data
void * data
Data stored at this element.
Definition: dbus-list.h:38
DBUS_TYPE_BYTE
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
_dbus_type_writer_write_basic
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
Definition: dbus-marshal-recursive.c:2311
DBusBasicValue::u64
dbus_uint64_t u64
as int64
Definition: dbus-types.h:146
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
DBusBasicValue::str
char * str
as char* (string, object path or signature)
Definition: dbus-types.h:150
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1283
DBUS_STRUCT_END_CHAR
#define DBUS_STRUCT_END_CHAR
Code marking the end of a struct type in a type signature.
Definition: dbus-protocol.h:160
DBUS_TYPE_DOUBLE
#define DBUS_TYPE_DOUBLE
Type code marking an 8-byte double in IEEE 754 format.
Definition: dbus-protocol.h:98
_dbus_string_ends_with_c_str
dbus_bool_t _dbus_string_ends_with_c_str(const DBusString *a, const char *c_str)
Returns whether a string ends with the given suffix.
Definition: dbus-string-util.c:46
_dbus_list_get_first
void * _dbus_list_get_first(DBusList **list)
Gets the first data in the list.
Definition: dbus-list.c:612
_dbus_list_get_next_link
#define _dbus_list_get_next_link(list, link)
Gets the next link in the list, or NULL if there are no more links.
Definition: dbus-list.h:116
_DBUS_INT_MAX
#define _DBUS_INT_MAX
Maximum value of type "int".
Definition: dbus-internals.h:263
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
DBUS_TYPE_INT64
#define DBUS_TYPE_INT64
Type code marking a 64-bit signed integer.
Definition: dbus-protocol.h:90
_dbus_unpack_uint32
dbus_uint32_t _dbus_unpack_uint32(int byte_order, const unsigned char *data)
Unpacks a 32 bit unsigned integer from a data pointer.
Definition: dbus-marshal-basic.c:182
_dbus_type_reader_delete
dbus_bool_t _dbus_type_reader_delete(DBusTypeReader *reader, const DBusTypeReader *realign_root)
Recursively deletes any value pointed to by the reader, leaving the reader valid to continue reading...
Definition: dbus-marshal-recursive.c:1420
_dbus_type_writer_init_values_only
void _dbus_type_writer_init_values_only(DBusTypeWriter *writer, int byte_order, const DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Like _dbus_type_writer_init(), except the type string passed in should correspond to an existing sign...
Definition: dbus-marshal-recursive.c:1584
_dbus_type_reader_set_basic
dbus_bool_t _dbus_type_reader_set_basic(DBusTypeReader *reader, const void *value, const DBusTypeReader *realign_root)
Sets a new value for the basic type value pointed to by the reader, leaving the reader valid to conti...
Definition: dbus-marshal-recursive.c:1363
DBusString
Definition: dbus-string.h:42
_dbus_type_writer_unrecurse
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
Definition: dbus-marshal-recursive.c:2179
dbus_type_is_basic
dbus_bool_t dbus_type_is_basic(int typecode)
A "basic type" is a somewhat arbitrary concept, but the intent is to include those types that are ful...
Definition: dbus-signature.c:318
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_dbus_type_reader_read_basic
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
Definition: dbus-marshal-recursive.c:870
dbus_uint64_t
_DBUS_GNUC_EXTENSION typedef unsigned long long dbus_uint64_t
A 64-bit unsigned integer.
Definition: dbus-arch-deps.h:37
DBUS_TYPE_INT32_AS_STRING
#define DBUS_TYPE_INT32_AS_STRING
DBUS_TYPE_INT32 as a string literal instead of a int literal
Definition: dbus-protocol.h:84
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1193
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:270
_dbus_unpack_uint16
dbus_uint16_t _dbus_unpack_uint16(int byte_order, const unsigned char *data)
Unpacks a 16 bit unsigned integer from a data pointer.
Definition: dbus-marshal-basic.c:161
DBUS_TYPE_INT32
#define DBUS_TYPE_INT32
Type code marking a 32-bit signed integer.
Definition: dbus-protocol.h:82
_dbus_type_reader_next
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
Definition: dbus-marshal-recursive.c:1054
dbus_int64_t
_DBUS_GNUC_EXTENSION typedef long long dbus_int64_t
A 64-bit signed integer.
Definition: dbus-arch-deps.h:36
DBUS_BIG_ENDIAN
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:54
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_dbus_string_equal_substring
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2104
DBUS_TYPE_UINT64
#define DBUS_TYPE_UINT64
Type code marking a 64-bit unsigned integer.
Definition: dbus-protocol.h:94
DBUS_STRUCT_BEGIN_CHAR
#define DBUS_STRUCT_BEGIN_CHAR
Code marking the start of a struct type in a type signature.
Definition: dbus-protocol.h:156
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
_DBUS_N_ELEMENTS
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
Definition: dbus-internals.h:189
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
DBusTypeReader::byte_order
dbus_uint32_t byte_order
byte order of the block
Definition: dbus-marshal-recursive.h:41
_dbus_string_insert_byte
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:614
dbus_int16_t
short dbus_int16_t
A 16-bit signed integer on all platforms.
Definition: dbus-arch-deps.h:45
_dbus_string_append_byte
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1157
DBusTypeWriter::byte_order
dbus_uint32_t byte_order
byte order to write values with
Definition: dbus-marshal-recursive.h:66
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:39
TRUE
#define TRUE
Expands to "1".
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:159
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR as a string literal instead of a int literal
Definition: dbus-protocol.h:166
_dbus_list_free_link
void _dbus_list_free_link(DBusList *link)
Frees a linked list node allocated with _dbus_list_alloc_link.
Definition: dbus-list.c:254
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
_dbus_type_writer_write_reader
dbus_bool_t _dbus_type_writer_write_reader(DBusTypeWriter *writer, DBusTypeReader *reader)
Iterate through all values in the given reader, writing a copy of each value to the writer...
Definition: dbus-marshal-recursive.c:2731
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
_dbus_type_reader_init
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
Definition: dbus-marshal-recursive.c:733
DBusTypeReader::u
union DBusTypeReader::@1 u
class-specific data
DBusList
A node in a linked list.
Definition: dbus-list.h:34
DBUS_TYPE_INT16
#define DBUS_TYPE_INT16
Type code marking a 16-bit signed integer.
Definition: dbus-protocol.h:74
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
_dbus_type_reader_get_element_type
int _dbus_type_reader_get_element_type(const DBusTypeReader *reader)
Gets the type of an element of the array the reader is currently pointing to.
Definition: dbus-marshal-recursive.c:821
_dbus_type_writer_init
void _dbus_type_writer_init(DBusTypeWriter *writer, int byte_order, DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Initialize a write iterator, which is used to write out values in serialized D-Bus format...
Definition: dbus-marshal-recursive.c:1493
DBusBasicValue
A simple value union that lets you access bytes as if they were various types; useful when dealing wi...
Definition: dbus-types.h:137
_dbus_string_validate_nul
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2653
_dbus_type_reader_get_current_type
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
Definition: dbus-marshal-recursive.c:786
_dbus_list_get_first_link
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list.
Definition: dbus-list.c:567
FALSE
#define FALSE
Expands to "0".
DBUS_DICT_ENTRY_END_CHAR
#define DBUS_DICT_ENTRY_END_CHAR
Code marking the end of a dict entry type in a type signature.
Definition: dbus-protocol.h:168
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
_dbus_type_to_string
const char * _dbus_type_to_string(int typecode)
Returns a string describing the given type.
Definition: dbus-marshal-basic.c:1219
_dbus_string_copy_len
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1375
dbus_malloc0
void * dbus_malloc0(size_t bytes)
Allocates the given number of bytes, as with standard malloc(), but all bytes are initialized to zero...
Definition: dbus-memory.c:531
_dbus_type_writer_write_fixed_multi
dbus_bool_t _dbus_type_writer_write_fixed_multi(DBusTypeWriter *writer, int element_type, const void *value, int n_elements)
Writes a block of fixed-length basic values, i.e.
Definition: dbus-marshal-recursive.c:2359
_dbus_verbose_bytes_of_string
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
Definition: dbus-marshal-basic.c:1360
dbus_int32_t
int dbus_int32_t
A 32-bit signed integer on all platforms.
Definition: dbus-arch-deps.h:42
_DBUS_INT16_MAX
#define _DBUS_INT16_MAX
Maximum value of type "int16".
Definition: dbus-internals.h:256
DBusTypeReader::value_pos
int value_pos
current position in values
Definition: dbus-marshal-recursive.h:50
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
_dbus_type_writer_recurse
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
Definition: dbus-marshal-recursive.c:2109
_DBUS_DOUBLES_BITWISE_EQUAL
#define _DBUS_DOUBLES_BITWISE_EQUAL(a, b)
On x86 there is an 80-bit FPU, and if you do "a == b" it may have a or b in an 80-bit register...
Definition: dbus-sysdeps.h:589
_dbus_list_clear
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:542
DBUS_LITTLE_ENDIAN
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:53