1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-recursive.c Marshalling routines for recursive types
4 * Copyright (C) 2004 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-marshal-recursive.h"
25 #include "dbus-internals.h"
28 * @addtogroup DBusMarshal
33 first_type_in_signature (const DBusString *str,
38 t = _dbus_string_get_byte (str, pos);
40 if (t == DBUS_STRUCT_BEGIN_CHAR)
41 return DBUS_TYPE_STRUCT;
47 element_type_get_alignment (const DBusString *str,
50 return _dbus_type_get_alignment (first_type_in_signature (str, pos));
54 _dbus_type_reader_init (DBusTypeReader *reader,
56 const DBusString *type_str,
58 const DBusString *value_str,
61 reader->byte_order = byte_order;
62 reader->type_str = type_str;
63 reader->type_pos = type_pos;
64 reader->value_str = value_str;
65 reader->value_pos = value_pos;
66 reader->container_type = DBUS_TYPE_INVALID;
68 _dbus_verbose (" type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
69 reader, reader->type_pos, reader->value_pos,
70 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
74 _dbus_type_reader_get_current_type (DBusTypeReader *reader)
78 /* for INVALID t will == DBUS_TYPE_INVALID when we
79 * reach the end of type_str, for STRUCT we have to
80 * check the finished flag
82 if (reader->container_type == DBUS_TYPE_INVALID)
84 t = first_type_in_signature (reader->type_str,
87 else if (reader->container_type == DBUS_TYPE_STRUCT)
89 if (reader->u.strct.finished)
90 t = DBUS_TYPE_INVALID;
92 t = first_type_in_signature (reader->type_str,
95 else if (reader->container_type == DBUS_TYPE_ARRAY)
97 /* return the array element type if elements remain, and
98 * TYPE_INVALID otherwise
102 end_pos = reader->u.array.start_pos + reader->u.array.len;
104 _dbus_assert (reader->value_pos <= end_pos);
105 _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
107 if (reader->value_pos < end_pos)
108 t = reader->u.array.element_type;
110 t = DBUS_TYPE_INVALID;
114 _dbus_assert_not_reached ("reader->container_type should not be set to this");
115 t = DBUS_TYPE_INVALID; /* quiet gcc */
118 _dbus_assert (t != DBUS_STRUCT_END_CHAR);
119 _dbus_assert (t != DBUS_STRUCT_BEGIN_CHAR);
122 _dbus_verbose (" type reader %p current type_pos = %d type = %s\n",
123 reader, reader->type_pos,
124 _dbus_type_to_string (t));
131 _dbus_type_reader_array_is_empty (DBusTypeReader *reader)
133 dbus_uint32_t array_len;
136 _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY,
139 len_pos = _DBUS_ALIGN_VALUE (reader->value_pos, 4);
141 _dbus_demarshal_basic_type (reader->value_str,
147 return array_len == 0;
151 _dbus_type_reader_read_basic (DBusTypeReader *reader,
154 if (reader->container_type == DBUS_TYPE_INVALID ||
155 reader->container_type == DBUS_TYPE_STRUCT ||
156 reader->container_type == DBUS_TYPE_ARRAY)
161 t = _dbus_type_reader_get_current_type (reader);
163 next = reader->value_pos;
164 _dbus_demarshal_basic_type (reader->value_str,
170 _dbus_verbose (" type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",
171 reader, reader->type_pos, reader->value_pos, next,
172 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
176 _dbus_assert_not_reached ("reader->container_type should not be set to this");
181 _dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
191 * Initialize a new reader pointing to the first type and
192 * corresponding value that's a child of the current container. It's
193 * an error to call this if the current type is a non-container.
195 * Note that DBusTypeReader traverses values, not types. So if you
196 * have an empty array of array of int, you can't recurse into it. You
197 * can only recurse into each element.
199 * @param reader the reader
200 * @param sub a reader to init pointing to the first child
203 _dbus_type_reader_recurse (DBusTypeReader *reader,
208 t = first_type_in_signature (reader->type_str, reader->type_pos);
210 /* point subreader at the same place as reader */
211 _dbus_type_reader_init (sub,
218 if (t == DBUS_TYPE_STRUCT)
220 sub->container_type = DBUS_TYPE_STRUCT;
224 /* struct has 8 byte alignment */
225 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
227 sub->u.strct.finished = FALSE;
229 else if (t == DBUS_TYPE_ARRAY)
231 dbus_uint32_t array_len;
234 _dbus_return_if_fail (!_dbus_type_reader_array_is_empty (reader));
236 sub->container_type = DBUS_TYPE_ARRAY;
238 /* point type_pos at the array element type */
241 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
243 _dbus_demarshal_basic_type (sub->value_str,
249 sub->u.array.len = array_len;
251 alignment = element_type_get_alignment (sub->type_str,
254 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
256 sub->u.array.element_type = first_type_in_signature (sub->type_str,
258 sub->u.array.start_pos = sub->value_pos;
260 _dbus_verbose (" type reader %p array start = %d array len = %d array element type = %s\n",
262 sub->u.array.start_pos,
264 _dbus_type_to_string (sub->u.array.element_type));
268 _dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t));
269 #ifndef DBUS_DISABLE_CHECKS
270 if (t == DBUS_TYPE_INVALID)
271 _dbus_warn ("You can't recurse into an empty array or off the end of a message body\n");
272 #endif /* DBUS_DISABLE_CHECKS */
274 _dbus_assert_not_reached ("don't yet handle recursing into this type");
277 _dbus_verbose (" type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
278 sub, sub->type_pos, sub->value_pos,
279 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
283 skip_one_complete_type (const DBusString *type_str,
286 while (_dbus_string_get_byte (type_str, *type_pos) == DBUS_TYPE_ARRAY)
289 if (_dbus_string_get_byte (type_str, *type_pos) == DBUS_STRUCT_BEGIN_CHAR)
296 switch (_dbus_string_get_byte (type_str, *type_pos))
298 case DBUS_STRUCT_BEGIN_CHAR:
301 case DBUS_STRUCT_END_CHAR:
304 case DBUS_TYPE_INVALID:
305 _dbus_assert_not_reached ("unbalanced parens in signature");
316 skip_array_values (int element_type,
317 const DBusString *value_str,
321 dbus_uint32_t array_len;
325 pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
327 _dbus_demarshal_basic_type (value_str,
333 alignment = _dbus_type_get_alignment (element_type);
335 pos = _DBUS_ALIGN_VALUE (pos, alignment);
337 *value_pos = pos + array_len;
341 * Skip to the next value on this "level". e.g. the next field in a
342 * struct, the next value in an array, the next key or value in a
343 * dict. Returns FALSE at the end of the current container.
345 * @param reader the reader
346 * @returns FALSE if nothing more to read at or below this level
349 _dbus_type_reader_next (DBusTypeReader *reader)
353 t = _dbus_type_reader_get_current_type (reader);
355 _dbus_verbose (" type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
356 reader, reader->type_pos, reader->value_pos,
357 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
358 _dbus_type_to_string (t));
360 if (t == DBUS_TYPE_INVALID)
363 if (reader->container_type == DBUS_TYPE_INVALID ||
364 reader->container_type == DBUS_TYPE_STRUCT)
368 case DBUS_TYPE_STRUCT:
369 /* Scan forward over the entire container contents */
373 /* Recurse into the struct */
374 _dbus_type_reader_recurse (reader, &sub);
376 /* Skip everything in this subreader */
377 while (_dbus_type_reader_next (&sub))
382 /* Now we are at the end of this container */
383 reader->type_pos = sub.type_pos;
384 reader->value_pos = sub.value_pos;
388 case DBUS_TYPE_ARRAY:
390 skip_array_values (first_type_in_signature (reader->type_str,
391 reader->type_pos + 1),
392 reader->value_str, &reader->value_pos, reader->byte_order);
393 skip_one_complete_type (reader->type_str, &reader->type_pos);
398 _dbus_marshal_skip_basic_type (reader->value_str,
399 t, reader->byte_order,
401 reader->type_pos += 1;
405 /* for STRUCT containers we return FALSE at the end of the struct,
406 * for INVALID we return FALSE at the end of the signature.
407 * In both cases we arrange for get_current_type() to return INVALID
408 * which is defined to happen iff we're at the end (no more next())
410 if (reader->container_type == DBUS_TYPE_STRUCT)
412 t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
413 if (t == DBUS_STRUCT_END_CHAR)
415 reader->type_pos += 1;
416 reader->u.strct.finished = TRUE;
420 else if (reader->container_type == DBUS_TYPE_ARRAY)
422 /* Skip one array element */
425 end_pos = reader->u.array.start_pos + reader->u.array.len;
427 _dbus_assert (reader->value_pos < end_pos);
428 _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
430 if (reader->u.array.element_type == DBUS_TYPE_STRUCT)
434 /* Recurse into the struct */
435 _dbus_type_reader_recurse (reader, &sub);
437 /* Skip everything in this element */
438 while (_dbus_type_reader_next (&sub))
443 /* Now we are at the end of this element */
444 reader->value_pos = sub.value_pos;
446 else if (reader->u.array.element_type == DBUS_TYPE_ARRAY)
448 skip_array_values (first_type_in_signature (reader->type_str,
449 reader->type_pos + 1),
450 reader->value_str, &reader->value_pos, reader->byte_order);
454 _dbus_marshal_skip_basic_type (reader->value_str,
455 t, reader->byte_order,
459 _dbus_assert (reader->value_pos <= end_pos);
461 if (reader->value_pos == end_pos)
463 skip_one_complete_type (reader->type_str,
469 _dbus_assert_not_reached ("reader->container_type should not be set to this");
472 _dbus_verbose (" type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
473 reader, reader->type_pos, reader->value_pos,
474 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
475 _dbus_type_to_string (_dbus_type_reader_get_current_type (reader)));
477 return _dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID;
481 _dbus_type_writer_init (DBusTypeWriter *writer,
483 DBusString *type_str,
485 DBusString *value_str,
488 writer->byte_order = byte_order;
489 writer->type_str = type_str;
490 writer->type_pos = type_pos;
491 writer->value_str = value_str;
492 writer->value_pos = value_pos;
493 writer->container_type = DBUS_TYPE_INVALID;
494 writer->inside_array = FALSE;
496 _dbus_verbose ("writer %p init remaining sig '%s'\n", writer,
497 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
501 _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,
508 old_value_len = _dbus_string_get_length (writer->value_str);
510 if (!_dbus_marshal_basic_type (writer->value_str,
517 bytes_written = _dbus_string_get_length (writer->value_str) - old_value_len;
519 writer->value_pos += bytes_written;
524 /* If our parent is an array, things are a little bit complicated.
526 * The parent must have a complete element type, such as
527 * "i" or "aai" or "(ii)" or "a(ii)". There can't be
528 * unclosed parens, or an "a" with no following type.
530 * To recurse, the only allowed operation is to recurse into the
531 * first type in the element type. So for "i" you can't recurse, for
532 * "ai" you can recurse into the array, for "(ii)" you can recurse
535 * If you recurse into the array for "ai", then you must specify
536 * "i" for the element type of the array you recurse into.
538 * While inside an array at any level, we need to avoid writing to
539 * type_str, since the type only appears once for the whole array,
540 * it does not appear for each array element.
542 * While inside an array type_pos points to the expected next
543 * typecode, rather than the next place we could write a typecode.
546 writer_recurse_init_and_check (DBusTypeWriter *writer,
550 _dbus_type_writer_init (sub,
557 sub->container_type = container_type;
559 if (writer->inside_array || sub->container_type == DBUS_TYPE_ARRAY)
560 sub->inside_array = TRUE;
562 sub->inside_array = FALSE;
564 #ifndef DBUS_DISABLE_CHECKS
565 if (writer->inside_array)
569 expected = first_type_in_signature (writer->type_str, writer->type_pos);
571 if (expected != sub->container_type)
573 _dbus_warn ("Writing an element of type %s, but the expected type here is %s\n",
574 _dbus_type_to_string (sub->container_type),
575 _dbus_type_to_string (expected));
576 _dbus_assert_not_reached ("bad array element written");
579 #endif /* DBUS_DISABLE_CHECKS */
581 _dbus_verbose (" type writer %p recurse parent type_pos = %d value_pos = %d inside_array = %d container_type = %s remaining sig '%s'\n",
582 writer, writer->type_pos, writer->value_pos, writer->inside_array,
583 _dbus_type_to_string (writer->container_type),
584 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
585 _dbus_verbose (" type writer %p recurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
586 sub, sub->type_pos, sub->value_pos,
588 _dbus_type_to_string (sub->container_type));
592 write_or_verify_typecode (DBusTypeWriter *writer,
595 /* A subwriter inside an array will have type_pos pointing to the
596 * expected typecode; a writer not inside an array has type_pos
597 * pointing to the next place to insert a typecode.
599 _dbus_verbose (" type writer %p write_or_verify start type_pos = %d remaining sig '%s'\n",
600 writer, writer->type_pos,
601 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
603 if (writer->inside_array)
605 #ifndef DBUS_DISABLE_CHECKS
609 expected = _dbus_string_get_byte (writer->type_str, writer->type_pos);
611 if (expected != typecode)
613 _dbus_warn ("Array type requires that type %s be written, but %s was written\n",
614 _dbus_type_to_string (expected), _dbus_type_to_string (typecode));
615 _dbus_assert_not_reached ("bad type inserted somewhere inside an array");
618 #endif /* DBUS_DISABLE_CHECKS */
620 /* if immediately inside an array we'd always be appending an element,
621 * so the expected type doesn't change; if inside a struct or something
622 * below an array, we need to move through said struct or something.
624 if (writer->container_type != DBUS_TYPE_ARRAY)
625 writer->type_pos += 1;
629 if (!_dbus_string_insert_byte (writer->type_str,
634 writer->type_pos += 1;
637 _dbus_verbose (" type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
638 writer, writer->type_pos,
639 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
645 _dbus_type_writer_recurse (DBusTypeWriter *writer,
649 writer_recurse_init_and_check (writer, container_type, sub);
651 switch (container_type)
653 case DBUS_TYPE_STRUCT:
655 /* Ensure that we'll be able to add alignment padding and the typecode */
656 if (!_dbus_string_alloc_space (sub->value_str, 8))
659 if (!write_or_verify_typecode (sub, DBUS_STRUCT_BEGIN_CHAR))
660 _dbus_assert_not_reached ("failed to insert struct typecode after prealloc");
662 if (!_dbus_string_insert_bytes (sub->value_str,
664 _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
666 _dbus_assert_not_reached ("should not have failed to insert alignment padding for struct");
667 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
670 case DBUS_TYPE_ARRAY:
671 _dbus_assert_not_reached ("use recurse_array() for arrays");
674 _dbus_assert_not_reached ("container_type unhandled");
682 _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
683 const char *element_type,
686 int element_type_len;
687 DBusString element_type_str;
688 dbus_uint32_t value = 0;
693 writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, sub);
695 #ifndef DBUS_DISABLE_CHECKS
696 if (writer->container_type == DBUS_TYPE_ARRAY)
698 DBusString parent_elements;
700 _dbus_assert (element_type != NULL);
702 _dbus_string_init_const (&parent_elements,
703 _dbus_string_get_const_data_len (writer->type_str,
704 writer->u.array.element_type_pos + 1,
707 if (!_dbus_string_starts_with_c_str (&parent_elements, element_type))
709 _dbus_warn ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
711 _dbus_assert_not_reached ("incompatible type for child array");
714 #endif /* DBUS_DISABLE_CHECKS */
716 _dbus_string_init_const (&element_type_str, element_type);
717 element_type_len = _dbus_string_get_length (&element_type_str);
719 /* 4 bytes for the array length and 4 bytes possible padding */
720 if (!_dbus_string_alloc_space (sub->value_str, 8))
723 sub->type_pos += 1; /* move to point to the element type, since type_pos
724 * should be the expected type for further writes
726 sub->u.array.element_type_pos = sub->type_pos;
727 sub->u.array.element_type_len = element_type_len;
729 if (!writer->inside_array)
731 /* sub is a toplevel/outermost array so we need to write the type data */
733 /* alloc space for array typecode, element signature, possible 7
736 if (!_dbus_string_alloc_space (writer->type_str, 1 + element_type_len + 7))
739 if (!_dbus_string_insert_byte (writer->type_str,
742 _dbus_assert_not_reached ("failed to insert array typecode after prealloc");
744 if (!_dbus_string_copy (&element_type_str, 0,
745 sub->type_str, sub->u.array.element_type_pos))
746 _dbus_assert_not_reached ("should not have failed to insert array element typecodes");
749 /* Write the length */
750 sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
752 if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
754 _dbus_assert_not_reached ("should not have failed to insert array len");
756 _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);
758 /* Write alignment padding for array elements */
759 _dbus_string_init_const (&str, element_type);
760 alignment = element_type_get_alignment (&str, 0);
762 aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
763 if (aligned != sub->value_pos)
765 if (!_dbus_string_insert_bytes (sub->value_str,
767 aligned - sub->value_pos,
769 _dbus_assert_not_reached ("should not have failed to insert alignment padding");
771 sub->value_pos = aligned;
773 sub->u.array.start_pos = sub->value_pos;
775 _dbus_assert (sub->u.array.start_pos == sub->value_pos);
776 _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
778 _dbus_verbose (" type writer %p recurse array done remaining sig '%s'\n", sub,
779 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
785 _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
788 _dbus_assert (sub->type_pos > 0); /* can't be recursed if this fails */
790 _dbus_verbose (" type writer %p unrecurse type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
791 writer, writer->type_pos, writer->value_pos, writer->inside_array,
792 _dbus_type_to_string (writer->container_type));
793 _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
794 sub, sub->type_pos, sub->value_pos,
796 _dbus_type_to_string (sub->container_type));
798 if (sub->container_type == DBUS_TYPE_STRUCT)
800 if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
803 else if (sub->container_type == DBUS_TYPE_ARRAY)
807 /* Set the array length */
808 len = sub->value_pos - sub->u.array.start_pos;
809 _dbus_marshal_set_uint32 (sub->value_str,
811 sub->u.array.len_pos,
813 _dbus_verbose (" filled in sub array len to %u at len_pos %d\n",
814 len, sub->u.array.len_pos);
817 /* Jump the parent writer to the new location */
818 if (!writer->inside_array)
820 if (sub->inside_array)
822 /* Transition back to type_pos = insertion point from type_pos = expected */
824 _dbus_assert (sub->container_type == DBUS_TYPE_ARRAY);
825 writer->type_pos = sub->u.array.element_type_pos + sub->u.array.element_type_len;
829 writer->type_pos = sub->type_pos;
832 writer->value_pos = sub->value_pos;
835 _dbus_verbose (" type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n",
836 writer, writer->type_pos, writer->value_pos,
837 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
843 _dbus_type_writer_write_basic (DBusTypeWriter *writer,
849 /* First ensure that our type realloc will succeed */
850 if (!_dbus_string_alloc_space (writer->type_str, 1))
855 if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
858 if (!write_or_verify_typecode (writer, type))
859 _dbus_assert_not_reached ("failed to write typecode after prealloc");
864 _dbus_verbose (" type writer %p basic type_pos = %d value_pos = %d inside_array = %d\n",
865 writer, writer->type_pos, writer->value_pos, writer->inside_array);
871 _dbus_type_writer_write_array (DBusTypeWriter *writer,
880 /** @} */ /* end of DBusMarshal group */
882 #ifdef DBUS_BUILD_TESTS
883 #include "dbus-test.h"
889 DBusString signature;
900 data_block_init (DataBlock *block)
902 if (!_dbus_string_init (&block->signature))
905 if (!_dbus_string_init (&block->body))
907 _dbus_string_free (&block->signature);
915 data_block_free (DataBlock *block)
917 _dbus_string_free (&block->signature);
918 _dbus_string_free (&block->body);
922 data_block_save (DataBlock *block,
923 DataBlockState *state)
925 state->saved_sig_len = _dbus_string_get_length (&block->signature);
926 state->saved_body_len = _dbus_string_get_length (&block->body);
930 data_block_restore (DataBlock *block,
931 DataBlockState *state)
933 /* These set_length should be shortening things so should always work */
935 if (!_dbus_string_set_length (&block->signature,
936 state->saved_sig_len))
937 _dbus_assert_not_reached ("could not restore signature length");
939 if (!_dbus_string_set_length (&block->body,
940 state->saved_body_len))
941 _dbus_assert_not_reached ("could not restore body length");
945 data_block_init_reader_writer (DataBlock *block,
947 DBusTypeReader *reader,
948 DBusTypeWriter *writer)
950 _dbus_type_reader_init (reader,
953 _dbus_string_get_length (&block->signature),
955 _dbus_string_get_length (&block->body));
957 _dbus_type_writer_init (writer,
960 _dbus_string_get_length (&block->signature),
962 _dbus_string_get_length (&block->body));
965 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
967 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
968 _DBUS_FUNCTION_NAME, __LINE__); \
969 _dbus_assert_not_reached ("test failed"); \
973 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
975 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
976 _DBUS_FUNCTION_NAME, __LINE__); \
977 _dbus_assert_not_reached ("test failed"); \
979 check_expected_type (reader, DBUS_TYPE_INVALID); \
982 #define SAMPLE_INT32 12345678
983 #define SAMPLE_INT32_ALTERNATE 53781429
985 write_int32 (DataBlock *block,
986 DBusTypeWriter *writer)
988 dbus_int32_t v = SAMPLE_INT32;
990 return _dbus_type_writer_write_basic (writer,
996 real_check_expected_type (DBusTypeReader *reader,
998 const char *funcname,
1003 t = _dbus_type_reader_get_current_type (reader);
1007 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
1008 _dbus_type_to_string (t),
1009 _dbus_type_to_string (expected),
1016 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
1019 read_int32 (DataBlock *block,
1020 DBusTypeReader *reader)
1024 check_expected_type (reader, DBUS_TYPE_INT32);
1026 _dbus_type_reader_read_basic (reader,
1027 (dbus_int32_t*) &v);
1029 _dbus_assert (v == SAMPLE_INT32);
1035 write_struct_of_int32 (DataBlock *block,
1036 DBusTypeWriter *writer)
1039 DataBlockState saved;
1042 data_block_save (block, &saved);
1044 if (!_dbus_type_writer_recurse (writer,
1050 if (!_dbus_type_writer_write_basic (&sub,
1054 data_block_restore (block, &saved);
1058 v = SAMPLE_INT32_ALTERNATE;
1059 if (!_dbus_type_writer_write_basic (&sub,
1063 data_block_restore (block, &saved);
1067 if (!_dbus_type_writer_unrecurse (writer, &sub))
1069 data_block_restore (block, &saved);
1077 read_struct_of_int32 (DataBlock *block,
1078 DBusTypeReader *reader)
1083 check_expected_type (reader, DBUS_TYPE_STRUCT);
1085 _dbus_type_reader_recurse (reader, &sub);
1087 check_expected_type (&sub, DBUS_TYPE_INT32);
1089 _dbus_type_reader_read_basic (&sub,
1090 (dbus_int32_t*) &v);
1092 _dbus_assert (v == SAMPLE_INT32);
1094 NEXT_EXPECTING_TRUE (&sub);
1095 check_expected_type (&sub, DBUS_TYPE_INT32);
1097 _dbus_type_reader_read_basic (&sub,
1098 (dbus_int32_t*) &v);
1100 _dbus_assert (v == SAMPLE_INT32_ALTERNATE);
1102 NEXT_EXPECTING_FALSE (&sub);
1108 write_struct_of_structs (DataBlock *block,
1109 DBusTypeWriter *writer)
1111 DataBlockState saved;
1114 data_block_save (block, &saved);
1116 if (!_dbus_type_writer_recurse (writer,
1121 if (!write_struct_of_int32 (block, &sub))
1123 data_block_restore (block, &saved);
1126 if (!write_struct_of_int32 (block, &sub))
1128 data_block_restore (block, &saved);
1131 if (!write_struct_of_int32 (block, &sub))
1133 data_block_restore (block, &saved);
1137 if (!_dbus_type_writer_unrecurse (writer, &sub))
1139 data_block_restore (block, &saved);
1147 read_struct_of_structs (DataBlock *block,
1148 DBusTypeReader *reader)
1152 check_expected_type (reader, DBUS_TYPE_STRUCT);
1154 _dbus_type_reader_recurse (reader, &sub);
1156 if (!read_struct_of_int32 (block, &sub))
1159 NEXT_EXPECTING_TRUE (&sub);
1160 if (!read_struct_of_int32 (block, &sub))
1163 NEXT_EXPECTING_TRUE (&sub);
1164 if (!read_struct_of_int32 (block, &sub))
1167 NEXT_EXPECTING_FALSE (&sub);
1173 write_struct_of_structs_of_structs (DataBlock *block,
1174 DBusTypeWriter *writer)
1176 DataBlockState saved;
1179 data_block_save (block, &saved);
1181 if (!_dbus_type_writer_recurse (writer,
1186 if (!write_struct_of_structs (block, &sub))
1188 data_block_restore (block, &saved);
1191 if (!write_struct_of_structs (block, &sub))
1193 data_block_restore (block, &saved);
1197 if (!_dbus_type_writer_unrecurse (writer, &sub))
1199 data_block_restore (block, &saved);
1207 read_struct_of_structs_of_structs (DataBlock *block,
1208 DBusTypeReader *reader)
1212 check_expected_type (reader, DBUS_TYPE_STRUCT);
1214 _dbus_type_reader_recurse (reader, &sub);
1216 if (!read_struct_of_structs (block, &sub))
1219 NEXT_EXPECTING_TRUE (&sub);
1220 if (!read_struct_of_structs (block, &sub))
1223 NEXT_EXPECTING_FALSE (&sub);
1229 write_array_of_int32 (DataBlock *block,
1230 DBusTypeWriter *writer)
1233 DataBlockState saved;
1236 data_block_save (block, &saved);
1238 if (!_dbus_type_writer_recurse_array (writer,
1239 DBUS_TYPE_INT32_AS_STRING,
1243 v = SAMPLE_INT32_ALTERNATE;
1244 if (!_dbus_type_writer_write_basic (&sub,
1248 data_block_restore (block, &saved);
1253 if (!_dbus_type_writer_write_basic (&sub,
1257 data_block_restore (block, &saved);
1262 if (!_dbus_type_writer_write_basic (&sub,
1266 data_block_restore (block, &saved);
1270 if (!_dbus_type_writer_unrecurse (writer, &sub))
1272 data_block_restore (block, &saved);
1280 read_array_of_int32 (DataBlock *block,
1281 DBusTypeReader *reader)
1286 check_expected_type (reader, DBUS_TYPE_ARRAY);
1288 _dbus_type_reader_recurse (reader, &sub);
1290 check_expected_type (&sub, DBUS_TYPE_INT32);
1292 _dbus_type_reader_read_basic (&sub,
1293 (dbus_int32_t*) &v);
1295 _dbus_assert (v == SAMPLE_INT32_ALTERNATE);
1297 NEXT_EXPECTING_TRUE (&sub);
1298 check_expected_type (&sub, DBUS_TYPE_INT32);
1300 _dbus_type_reader_read_basic (&sub,
1301 (dbus_int32_t*) &v);
1303 _dbus_assert (v == SAMPLE_INT32);
1305 NEXT_EXPECTING_TRUE (&sub);
1306 check_expected_type (&sub, DBUS_TYPE_INT32);
1308 _dbus_type_reader_read_basic (&sub,
1309 (dbus_int32_t*) &v);
1311 _dbus_assert (v == SAMPLE_INT32);
1313 NEXT_EXPECTING_FALSE (&sub);
1320 write_array_of_int32_empty (DataBlock *block,
1321 DBusTypeWriter *writer)
1323 DataBlockState saved;
1326 data_block_save (block, &saved);
1328 if (!_dbus_type_writer_recurse_array (writer,
1329 DBUS_TYPE_INT32_AS_STRING,
1333 if (!_dbus_type_writer_unrecurse (writer, &sub))
1335 data_block_restore (block, &saved);
1343 read_array_of_int32_empty (DataBlock *block,
1344 DBusTypeReader *reader)
1346 check_expected_type (reader, DBUS_TYPE_ARRAY);
1348 /* We are iterating over values not types. Thus we can't recurse
1351 _dbus_assert (_dbus_type_reader_array_is_empty (reader));
1357 write_array_of_array_of_int32 (DataBlock *block,
1358 DBusTypeWriter *writer)
1360 DataBlockState saved;
1363 data_block_save (block, &saved);
1365 if (!_dbus_type_writer_recurse_array (writer,
1366 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1370 if (!write_array_of_int32 (block, &sub))
1372 data_block_restore (block, &saved);
1376 if (!write_array_of_int32 (block, &sub))
1378 data_block_restore (block, &saved);
1382 if (!write_array_of_int32_empty (block, &sub))
1384 data_block_restore (block, &saved);
1388 if (!write_array_of_int32 (block, &sub))
1390 data_block_restore (block, &saved);
1394 if (!_dbus_type_writer_unrecurse (writer, &sub))
1396 data_block_restore (block, &saved);
1404 read_array_of_array_of_int32 (DataBlock *block,
1405 DBusTypeReader *reader)
1409 check_expected_type (reader, DBUS_TYPE_ARRAY);
1411 _dbus_type_reader_recurse (reader, &sub);
1413 if (!read_array_of_int32 (block, &sub))
1416 NEXT_EXPECTING_TRUE (&sub);
1417 if (!read_array_of_int32 (block, &sub))
1420 NEXT_EXPECTING_TRUE (&sub);
1421 if (!read_array_of_int32_empty (block, &sub))
1424 NEXT_EXPECTING_TRUE (&sub);
1425 if (!read_array_of_int32 (block, &sub))
1428 NEXT_EXPECTING_FALSE (&sub);
1435 write_array_of_array_of_int32_empty (DataBlock *block,
1436 DBusTypeWriter *writer)
1438 DataBlockState saved;
1441 data_block_save (block, &saved);
1443 if (!_dbus_type_writer_recurse_array (writer,
1444 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1448 if (!_dbus_type_writer_unrecurse (writer, &sub))
1450 data_block_restore (block, &saved);
1458 read_array_of_array_of_int32_empty (DataBlock *block,
1459 DBusTypeReader *reader)
1461 check_expected_type (reader, DBUS_TYPE_ARRAY);
1463 /* We are iterating over values, not types. Thus
1464 * we can't recurse in here.
1467 _dbus_assert (_dbus_type_reader_array_is_empty (reader));
1473 write_array_of_array_of_array_of_int32 (DataBlock *block,
1474 DBusTypeWriter *writer)
1476 DataBlockState saved;
1479 data_block_save (block, &saved);
1481 if (!_dbus_type_writer_recurse_array (writer,
1482 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1486 if (!write_array_of_array_of_int32 (block, &sub))
1488 data_block_restore (block, &saved);
1492 if (!write_array_of_array_of_int32 (block, &sub))
1494 data_block_restore (block, &saved);
1498 if (!write_array_of_array_of_int32_empty (block, &sub))
1500 data_block_restore (block, &saved);
1504 if (!_dbus_type_writer_unrecurse (writer, &sub))
1506 data_block_restore (block, &saved);
1514 read_array_of_array_of_array_of_int32 (DataBlock *block,
1515 DBusTypeReader *reader)
1519 check_expected_type (reader, DBUS_TYPE_ARRAY);
1521 _dbus_type_reader_recurse (reader, &sub);
1523 if (!read_array_of_array_of_int32 (block, &sub))
1526 NEXT_EXPECTING_TRUE (&sub);
1527 if (!read_array_of_array_of_int32 (block, &sub))
1530 NEXT_EXPECTING_TRUE (&sub);
1531 if (!read_array_of_array_of_int32_empty (block, &sub))
1534 NEXT_EXPECTING_FALSE (&sub);
1540 write_struct_of_array_of_int32 (DataBlock *block,
1541 DBusTypeWriter *writer)
1543 DataBlockState saved;
1546 data_block_save (block, &saved);
1548 if (!_dbus_type_writer_recurse (writer,
1553 if (!write_array_of_int32 (block, &sub))
1555 data_block_restore (block, &saved);
1559 if (!write_array_of_int32_empty (block, &sub))
1561 data_block_restore (block, &saved);
1565 if (!_dbus_type_writer_unrecurse (writer, &sub))
1567 data_block_restore (block, &saved);
1575 read_struct_of_array_of_int32 (DataBlock *block,
1576 DBusTypeReader *reader)
1580 check_expected_type (reader, DBUS_TYPE_STRUCT);
1582 _dbus_type_reader_recurse (reader, &sub);
1584 check_expected_type (&sub, DBUS_TYPE_ARRAY);
1586 if (!read_array_of_int32 (block, &sub))
1589 NEXT_EXPECTING_TRUE (&sub);
1590 if (!read_array_of_int32_empty (block, &sub))
1593 NEXT_EXPECTING_FALSE (&sub);
1599 write_array_of_struct_of_int32 (DataBlock *block,
1600 DBusTypeWriter *writer)
1602 DataBlockState saved;
1605 data_block_save (block, &saved);
1607 if (!_dbus_type_writer_recurse_array (writer,
1608 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
1609 DBUS_TYPE_INT32_AS_STRING
1610 DBUS_TYPE_INT32_AS_STRING
1611 DBUS_STRUCT_END_CHAR_AS_STRING,
1615 if (!write_struct_of_int32 (block, &sub))
1617 data_block_restore (block, &saved);
1621 if (!write_struct_of_int32 (block, &sub))
1623 data_block_restore (block, &saved);
1627 if (!write_struct_of_int32 (block, &sub))
1629 data_block_restore (block, &saved);
1633 if (!_dbus_type_writer_unrecurse (writer, &sub))
1635 data_block_restore (block, &saved);
1643 read_array_of_struct_of_int32 (DataBlock *block,
1644 DBusTypeReader *reader)
1648 check_expected_type (reader, DBUS_TYPE_ARRAY);
1650 _dbus_type_reader_recurse (reader, &sub);
1652 check_expected_type (&sub, DBUS_TYPE_STRUCT);
1654 if (!read_struct_of_int32 (block, &sub))
1657 NEXT_EXPECTING_TRUE (&sub);
1659 if (!read_struct_of_int32 (block, &sub))
1662 NEXT_EXPECTING_TRUE (&sub);
1664 if (!read_struct_of_int32 (block, &sub))
1667 NEXT_EXPECTING_FALSE (&sub);
1675 ITEM_STRUCT_OF_INT32,
1676 ITEM_STRUCT_OF_STRUCTS,
1677 ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
1678 ITEM_ARRAY_OF_INT32,
1679 ITEM_ARRAY_OF_INT32_EMPTY,
1680 ITEM_ARRAY_OF_ARRAY_OF_INT32,
1681 ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,
1682 ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
1683 ITEM_STRUCT_OF_ARRAY_OF_INT32,
1684 ITEM_ARRAY_OF_STRUCT_OF_INT32,
1689 typedef dbus_bool_t (* WriteItemFunc) (DataBlock *block,
1690 DBusTypeWriter *writer);
1691 typedef dbus_bool_t (* ReadItemFunc) (DataBlock *block,
1692 DBusTypeReader *reader);
1698 WriteItemFunc write_item_func;
1699 ReadItemFunc read_item_func;
1702 static CheckMarshalItem items[] = {
1704 ITEM_INT32, write_int32, read_int32 },
1705 { "struct with two int32",
1706 ITEM_STRUCT_OF_INT32, write_struct_of_int32, read_struct_of_int32 },
1707 { "struct with three structs of two int32",
1708 ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
1709 { "struct of two structs of three structs of two int32",
1710 ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
1711 write_struct_of_structs_of_structs,
1712 read_struct_of_structs_of_structs },
1714 ITEM_ARRAY_OF_INT32, write_array_of_int32, read_array_of_int32 },
1715 { "empty array of int32",
1716 ITEM_ARRAY_OF_INT32_EMPTY, write_array_of_int32_empty, read_array_of_int32_empty },
1717 { "array of array of int32",
1718 ITEM_ARRAY_OF_ARRAY_OF_INT32,
1719 write_array_of_array_of_int32, read_array_of_array_of_int32 },
1720 { "empty array of array of int32",
1721 ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,
1722 write_array_of_array_of_int32_empty, read_array_of_array_of_int32_empty },
1723 { "array of array of array of int32",
1724 ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
1725 write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 },
1726 { "struct of array of int32",
1727 ITEM_STRUCT_OF_ARRAY_OF_INT32, write_struct_of_array_of_int32, read_struct_of_array_of_int32 },
1728 { "array of struct of int32",
1729 ITEM_ARRAY_OF_STRUCT_OF_INT32, write_array_of_struct_of_int32, read_array_of_struct_of_int32 },
1734 /* Array of items from the above items[]; -1 terminated */
1738 static TestRun runs[] = {
1739 { { ITEM_INVALID } },
1742 { { ITEM_INT32, ITEM_INVALID } },
1743 { { ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
1744 { { ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
1746 /* STRUCT_OF_INT32 */
1747 { { ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
1748 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
1749 { { ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
1750 { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
1751 { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
1753 /* STRUCT_OF_STRUCTS */
1754 { { ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1755 { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1756 { { ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1757 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1758 { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1759 { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
1761 /* STRUCT_OF_STRUCTS_OF_STRUCTS */
1762 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1763 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1764 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1765 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1766 { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1767 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1769 /* ARRAY_OF_INT32 */
1770 { { ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1771 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1772 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1773 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1774 { { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1775 { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1776 { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1777 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1778 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1779 { { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
1781 /* ARRAY_OF_ARRAY_OF_INT32 */
1782 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1783 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1784 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1785 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1786 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1787 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1788 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1789 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1790 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1791 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1793 /* ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32 */
1794 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1795 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1796 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1797 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1798 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
1799 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1800 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1801 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
1802 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1803 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1805 /* STRUCT_OF_ARRAY_OF_INT32 */
1806 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1807 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1808 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1809 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1810 { { ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1811 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
1813 /* ARRAY_OF_STRUCT_OF_INT32 */
1814 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
1815 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
1816 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
1817 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
1818 { { ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
1819 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }
1824 perform_one_run (DataBlock *block,
1828 DBusTypeReader reader;
1829 DBusTypeWriter writer;
1831 DataBlockState saved;
1837 _dbus_verbose ("run byteorder %s items ",
1838 byte_order == DBUS_LITTLE_ENDIAN ? "little" : "big");
1840 while (run->items[i] != ITEM_INVALID)
1842 CheckMarshalItem *item = &items[run->items[i]];
1844 _dbus_verbose ("%s ", item->desc);
1847 _dbus_verbose (" = %d items\n", i);
1850 data_block_save (block, &saved);
1852 data_block_init_reader_writer (block,
1857 while (run->items[i] != ITEM_INVALID)
1859 CheckMarshalItem *item = &items[run->items[i]];
1861 _dbus_verbose (">>writing %s\n", item->desc);
1863 if (!(* item->write_item_func) (block, &writer))
1869 while (run->items[i] != ITEM_INVALID)
1871 CheckMarshalItem *item = &items[run->items[i]];
1873 _dbus_verbose (">>data for reading %s\n", item->desc);
1875 _dbus_verbose_bytes_of_string (reader.type_str, 0,
1876 _dbus_string_get_length (reader.type_str));
1877 _dbus_verbose_bytes_of_string (reader.value_str, 0,
1878 _dbus_string_get_length (reader.value_str));
1880 _dbus_verbose (">>reading %s\n", item->desc);
1882 if (!(* item->read_item_func) (block, &reader))
1885 _dbus_type_reader_next (&reader);
1893 data_block_restore (block, &saved);
1898 perform_all_runs (int byte_order,
1907 if (!data_block_init (&block))
1910 if (!_dbus_string_lengthen (&block.signature, initial_offset))
1913 if (!_dbus_string_lengthen (&block.body, initial_offset))
1917 while (i < _DBUS_N_ELEMENTS (runs))
1919 if (!perform_one_run (&block, byte_order, &runs[i]))
1928 data_block_free (&block);
1934 perform_all_items (int byte_order,
1944 if (!data_block_init (&block))
1948 if (!_dbus_string_lengthen (&block.signature, initial_offset))
1951 if (!_dbus_string_lengthen (&block.body, initial_offset))
1954 /* Create a run containing all the items */
1956 while (i < _DBUS_N_ELEMENTS (items))
1958 _dbus_assert (i == items[i].which);
1960 run.items[i] = items[i].which;
1965 run.items[i] = ITEM_INVALID;
1967 if (!perform_one_run (&block, byte_order, &run))
1973 data_block_free (&block);
1979 recursive_marshal_test_iteration (void *data)
1986 if (!perform_all_runs (DBUS_LITTLE_ENDIAN, i))
1988 if (!perform_all_runs (DBUS_BIG_ENDIAN, i))
1990 if (!perform_all_items (DBUS_LITTLE_ENDIAN, i))
1992 if (!perform_all_items (DBUS_BIG_ENDIAN, i))
2001 dbus_bool_t _dbus_marshal_recursive_test (void);
2004 _dbus_marshal_recursive_test (void)
2006 _dbus_test_oom_handling ("recursive marshaling",
2007 recursive_marshal_test_iteration,
2015 main (int argc, char **argv)
2017 _dbus_marshal_recursive_test ();
2023 #endif /* DBUS_BUILD_TESTS */