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
32 struct DBusTypeReaderClass
35 dbus_bool_t types_only; /* only iterates over types, not values */
36 void (* recurse) (DBusTypeReader *sub,
37 DBusTypeReader *parent);
38 int (* get_current_type) (DBusTypeReader *reader);
39 void (* next) (DBusTypeReader *reader,
44 first_type_in_signature (const DBusString *str,
49 t = _dbus_string_get_byte (str, pos);
51 if (t == DBUS_STRUCT_BEGIN_CHAR)
52 return DBUS_TYPE_STRUCT;
58 element_type_get_alignment (const DBusString *str,
61 return _dbus_type_get_alignment (first_type_in_signature (str, pos));
65 reader_init (DBusTypeReader *reader,
67 const DBusString *type_str,
69 const DBusString *value_str,
72 reader->byte_order = byte_order;
73 reader->finished = FALSE;
74 reader->type_str = type_str;
75 reader->type_pos = type_pos;
76 reader->value_str = value_str;
77 reader->value_pos = value_pos;
81 base_reader_recurse (DBusTypeReader *sub,
82 DBusTypeReader *parent)
84 /* point subreader at the same place as parent */
94 struct_types_only_reader_recurse (DBusTypeReader *sub,
95 DBusTypeReader *parent)
97 base_reader_recurse (sub, parent);
99 _dbus_assert (_dbus_string_get_byte (sub->type_str,
100 sub->type_pos) == DBUS_STRUCT_BEGIN_CHAR);
106 struct_reader_recurse (DBusTypeReader *sub,
107 DBusTypeReader *parent)
109 struct_types_only_reader_recurse (sub, parent);
111 /* struct has 8 byte alignment */
112 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
116 array_types_only_reader_recurse (DBusTypeReader *sub,
117 DBusTypeReader *parent)
119 base_reader_recurse (sub, parent);
121 /* point type_pos at the array element type */
124 sub->u.array.element_type = first_type_in_signature (sub->type_str,
127 /* Init with values likely to crash things if misused */
128 sub->u.array.start_pos = _DBUS_INT_MAX;
129 sub->u.array.len = _DBUS_INT_MAX;
133 array_reader_recurse (DBusTypeReader *sub,
134 DBusTypeReader *parent)
136 dbus_uint32_t array_len;
139 _dbus_assert (!_dbus_type_reader_array_is_empty (parent));
141 array_types_only_reader_recurse (sub, parent);
143 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
145 _dbus_demarshal_basic_type (sub->value_str,
151 sub->u.array.len = array_len;
153 alignment = element_type_get_alignment (sub->type_str,
156 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
158 sub->u.array.start_pos = sub->value_pos;
160 _dbus_verbose (" type reader %p array start = %d array len = %d array element type = %s\n",
162 sub->u.array.start_pos,
164 _dbus_type_to_string (sub->u.array.element_type));
168 variant_reader_recurse (DBusTypeReader *sub,
169 DBusTypeReader *parent)
173 _dbus_assert (!_dbus_type_reader_array_is_empty (parent));
175 base_reader_recurse (sub, parent);
177 /* Variant is 1 byte sig length (without nul), signature with nul,
178 * padding to 8-boundary, then values
181 sig_len = _dbus_string_get_byte (sub->value_str, sub->value_pos);
183 sub->type_str = sub->value_str;
184 sub->type_pos = sub->value_pos + 1;
186 sub->value_pos = sub->type_pos + sig_len + 1;
188 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
190 _dbus_verbose (" type reader %p variant containing '%s'\n",
192 _dbus_string_get_const_data_len (sub->type_str,
197 base_reader_get_current_type (DBusTypeReader *reader)
201 t = first_type_in_signature (reader->type_str,
208 struct_reader_get_current_type (DBusTypeReader *reader)
212 if (reader->finished)
213 t = DBUS_TYPE_INVALID;
215 t = first_type_in_signature (reader->type_str,
222 array_types_only_reader_get_current_type (DBusTypeReader *reader)
226 if (reader->finished)
227 t = DBUS_TYPE_INVALID;
229 t = reader->u.array.element_type;
235 array_reader_get_current_type (DBusTypeReader *reader)
240 /* return the array element type if elements remain, and
241 * TYPE_INVALID otherwise
244 end_pos = reader->u.array.start_pos + reader->u.array.len;
246 _dbus_assert (reader->value_pos <= end_pos);
247 _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
249 if (reader->value_pos < end_pos)
250 t = reader->u.array.element_type;
252 t = DBUS_TYPE_INVALID;
258 skip_one_complete_type (const DBusString *type_str,
261 while (_dbus_string_get_byte (type_str, *type_pos) == DBUS_TYPE_ARRAY)
264 if (_dbus_string_get_byte (type_str, *type_pos) == DBUS_STRUCT_BEGIN_CHAR)
271 switch (_dbus_string_get_byte (type_str, *type_pos))
273 case DBUS_STRUCT_BEGIN_CHAR:
276 case DBUS_STRUCT_END_CHAR:
279 case DBUS_TYPE_INVALID:
280 _dbus_assert_not_reached ("unbalanced parens in signature");
291 skip_array_values (int element_type,
292 const DBusString *value_str,
296 dbus_uint32_t array_len;
300 pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
302 _dbus_demarshal_basic_type (value_str,
308 alignment = _dbus_type_get_alignment (element_type);
310 pos = _DBUS_ALIGN_VALUE (pos, alignment);
312 *value_pos = pos + array_len;
316 base_reader_next (DBusTypeReader *reader,
319 switch (current_type)
321 case DBUS_TYPE_STRUCT:
322 /* Scan forward over the entire container contents */
326 /* Recurse into the struct */
327 _dbus_type_reader_recurse (reader, &sub);
329 /* Skip everything in this subreader */
330 while (_dbus_type_reader_next (&sub))
335 /* Now we are at the end of this container */
336 reader->type_pos = sub.type_pos;
338 if (!reader->klass->types_only)
339 reader->value_pos = sub.value_pos;
343 case DBUS_TYPE_ARRAY:
345 if (!reader->klass->types_only)
346 skip_array_values (first_type_in_signature (reader->type_str,
347 reader->type_pos + 1),
348 reader->value_str, &reader->value_pos, reader->byte_order);
350 skip_one_complete_type (reader->type_str, &reader->type_pos);
355 if (!reader->klass->types_only)
356 _dbus_marshal_skip_basic_type (reader->value_str,
357 current_type, reader->byte_order,
360 reader->type_pos += 1;
366 struct_reader_next (DBusTypeReader *reader,
371 base_reader_next (reader, current_type);
373 /* for STRUCT containers we return FALSE at the end of the struct,
374 * for INVALID we return FALSE at the end of the signature.
375 * In both cases we arrange for get_current_type() to return INVALID
376 * which is defined to happen iff we're at the end (no more next())
378 t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
379 if (t == DBUS_STRUCT_END_CHAR)
381 reader->type_pos += 1;
382 reader->finished = TRUE;
387 array_types_only_reader_next (DBusTypeReader *reader,
390 /* We have one "element" to be iterated over
391 * in each array, which is its element type.
392 * So the finished flag indicates whether we've
393 * iterated over it yet or not.
395 reader->finished = TRUE;
399 array_reader_next (DBusTypeReader *reader,
402 /* Skip one array element */
405 end_pos = reader->u.array.start_pos + reader->u.array.len;
407 _dbus_assert (reader->value_pos < end_pos);
408 _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
410 if (reader->u.array.element_type == DBUS_TYPE_STRUCT)
414 /* Recurse into the struct */
415 _dbus_type_reader_recurse (reader, &sub);
417 /* Skip everything in this element */
418 while (_dbus_type_reader_next (&sub))
423 /* Now we are at the end of this element */
424 reader->value_pos = sub.value_pos;
426 else if (reader->u.array.element_type == DBUS_TYPE_ARRAY)
428 skip_array_values (first_type_in_signature (reader->type_str,
429 reader->type_pos + 1),
430 reader->value_str, &reader->value_pos, reader->byte_order);
434 _dbus_marshal_skip_basic_type (reader->value_str,
435 current_type, reader->byte_order,
439 _dbus_assert (reader->value_pos <= end_pos);
441 if (reader->value_pos == end_pos)
443 skip_one_complete_type (reader->type_str,
448 static const DBusTypeReaderClass body_reader_class = {
451 NULL, /* body is always toplevel, so doesn't get recursed into */
452 base_reader_get_current_type,
456 static const DBusTypeReaderClass body_types_only_reader_class = {
459 NULL, /* body is always toplevel, so doesn't get recursed into */
460 base_reader_get_current_type,
464 static const DBusTypeReaderClass struct_reader_class = {
467 struct_reader_recurse,
468 struct_reader_get_current_type,
472 static const DBusTypeReaderClass struct_types_only_reader_class = {
475 struct_types_only_reader_recurse,
476 struct_reader_get_current_type,
480 static const DBusTypeReaderClass array_reader_class = {
483 array_reader_recurse,
484 array_reader_get_current_type,
488 static const DBusTypeReaderClass array_types_only_reader_class = {
491 array_types_only_reader_recurse,
492 array_types_only_reader_get_current_type,
493 array_types_only_reader_next
496 static const DBusTypeReaderClass variant_reader_class = {
499 variant_reader_recurse,
500 base_reader_get_current_type,
505 _dbus_type_reader_init (DBusTypeReader *reader,
507 const DBusString *type_str,
509 const DBusString *value_str,
512 reader->klass = &body_reader_class;
514 reader_init (reader, byte_order, type_str, type_pos,
515 value_str, value_pos);
517 _dbus_verbose (" type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
518 reader, reader->type_pos, reader->value_pos,
519 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
523 _dbus_type_reader_init_types_only (DBusTypeReader *reader,
524 const DBusString *type_str,
527 reader->klass = &body_types_only_reader_class;
529 reader_init (reader, DBUS_COMPILER_BYTE_ORDER /* irrelevant */,
530 type_str, type_pos, NULL, _DBUS_INT_MAX /* crashes if we screw up */);
532 _dbus_verbose (" type reader %p init types only type_pos = %d remaining sig '%s'\n",
533 reader, reader->type_pos,
534 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
538 _dbus_type_reader_get_current_type (DBusTypeReader *reader)
542 t = (* reader->klass->get_current_type) (reader);
544 _dbus_assert (t != DBUS_STRUCT_END_CHAR);
545 _dbus_assert (t != DBUS_STRUCT_BEGIN_CHAR);
548 _dbus_verbose (" type reader %p current type_pos = %d type = %s\n",
549 reader, reader->type_pos,
550 _dbus_type_to_string (t));
557 _dbus_type_reader_array_is_empty (DBusTypeReader *reader)
559 dbus_uint32_t array_len;
562 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY);
563 _dbus_assert (!reader->klass->types_only);
565 len_pos = _DBUS_ALIGN_VALUE (reader->value_pos, 4);
567 _dbus_demarshal_basic_type (reader->value_str,
573 return array_len == 0;
577 _dbus_type_reader_read_basic (DBusTypeReader *reader,
583 _dbus_assert (!reader->klass->types_only);
585 t = _dbus_type_reader_get_current_type (reader);
587 next = reader->value_pos;
588 _dbus_demarshal_basic_type (reader->value_str,
594 _dbus_verbose (" type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",
595 reader, reader->type_pos, reader->value_pos, next,
596 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
600 _dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
605 _dbus_assert (!reader->klass->types_only);
610 * Initialize a new reader pointing to the first type and
611 * corresponding value that's a child of the current container. It's
612 * an error to call this if the current type is a non-container.
614 * Note that DBusTypeReader traverses values, not types. So if you
615 * have an empty array of array of int, you can't recurse into it. You
616 * can only recurse into each element.
618 * @param reader the reader
619 * @param sub a reader to init pointing to the first child
622 _dbus_type_reader_recurse (DBusTypeReader *reader,
627 t = first_type_in_signature (reader->type_str, reader->type_pos);
631 case DBUS_TYPE_STRUCT:
632 if (reader->klass->types_only)
633 sub->klass = &struct_types_only_reader_class;
635 sub->klass = &struct_reader_class;
637 case DBUS_TYPE_ARRAY:
638 if (reader->klass->types_only)
639 sub->klass = &array_types_only_reader_class;
641 sub->klass = &array_reader_class;
643 case DBUS_TYPE_VARIANT:
644 if (reader->klass->types_only)
645 _dbus_assert_not_reached ("variant types are inside the variant value, not in the signature");
647 sub->klass = &variant_reader_class;
650 _dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t));
651 #ifndef DBUS_DISABLE_CHECKS
652 if (t == DBUS_TYPE_INVALID)
653 _dbus_warn ("You can't recurse into an empty array or off the end of a message body\n");
654 #endif /* DBUS_DISABLE_CHECKS */
656 _dbus_assert_not_reached ("don't yet handle recursing into this type");
659 (* sub->klass->recurse) (sub, reader);
661 _dbus_verbose (" type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
662 sub, sub->type_pos, sub->value_pos,
663 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
667 * Skip to the next value on this "level". e.g. the next field in a
668 * struct, the next value in an array, the next key or value in a
669 * dict. Returns FALSE at the end of the current container.
671 * @param reader the reader
672 * @returns FALSE if nothing more to read at or below this level
675 _dbus_type_reader_next (DBusTypeReader *reader)
679 t = _dbus_type_reader_get_current_type (reader);
681 _dbus_verbose (" type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
682 reader, reader->type_pos, reader->value_pos,
683 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
684 _dbus_type_to_string (t));
686 if (t == DBUS_TYPE_INVALID)
689 (* reader->klass->next) (reader, t);
691 _dbus_verbose (" type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
692 reader, reader->type_pos, reader->value_pos,
693 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
694 _dbus_type_to_string (_dbus_type_reader_get_current_type (reader)));
696 return _dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID;
710 _dbus_type_writer_init (DBusTypeWriter *writer,
712 DBusString *type_str,
714 DBusString *value_str,
717 writer->byte_order = byte_order;
718 writer->type_str = type_str;
719 writer->type_pos = type_pos;
720 writer->value_str = value_str;
721 writer->value_pos = value_pos;
722 writer->container_type = DBUS_TYPE_INVALID;
723 writer->type_pos_is_expectation = FALSE;
725 _dbus_verbose ("writer %p init remaining sig '%s'\n", writer,
726 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
730 _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,
737 old_value_len = _dbus_string_get_length (writer->value_str);
739 if (!_dbus_marshal_basic_type (writer->value_str,
746 bytes_written = _dbus_string_get_length (writer->value_str) - old_value_len;
748 writer->value_pos += bytes_written;
753 /* If our parent is an array, things are a little bit complicated.
755 * The parent must have a complete element type, such as
756 * "i" or "aai" or "(ii)" or "a(ii)". There can't be
757 * unclosed parens, or an "a" with no following type.
759 * To recurse, the only allowed operation is to recurse into the
760 * first type in the element type. So for "i" you can't recurse, for
761 * "ai" you can recurse into the array, for "(ii)" you can recurse
764 * If you recurse into the array for "ai", then you must specify
765 * "i" for the element type of the array you recurse into.
767 * While inside an array at any level, we need to avoid writing to
768 * type_str, since the type only appears once for the whole array,
769 * it does not appear for each array element.
771 * While inside an array type_pos points to the expected next
772 * typecode, rather than the next place we could write a typecode.
775 writer_recurse_init_and_check (DBusTypeWriter *writer,
779 _dbus_type_writer_init (sub,
786 sub->container_type = container_type;
788 if (writer->type_pos_is_expectation ||
789 (sub->container_type == DBUS_TYPE_ARRAY || sub->container_type == DBUS_TYPE_VARIANT))
790 sub->type_pos_is_expectation = TRUE;
792 sub->type_pos_is_expectation = FALSE;
794 #ifndef DBUS_DISABLE_CHECKS
795 if (writer->type_pos_is_expectation)
799 expected = first_type_in_signature (writer->type_str, writer->type_pos);
801 if (expected != sub->container_type)
803 _dbus_warn ("Writing an element of type %s, but the expected type here is %s\n",
804 _dbus_type_to_string (sub->container_type),
805 _dbus_type_to_string (expected));
806 _dbus_assert_not_reached ("bad array element or variant content written");
809 #endif /* DBUS_DISABLE_CHECKS */
811 _dbus_verbose (" type writer %p recurse parent type_pos = %d value_pos = %d is_expectation = %d container_type = %s remaining sig '%s'\n",
812 writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
813 _dbus_type_to_string (writer->container_type),
814 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
815 _dbus_verbose (" type writer %p recurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
816 sub, sub->type_pos, sub->value_pos,
817 sub->type_pos_is_expectation,
818 _dbus_type_to_string (sub->container_type));
822 write_or_verify_typecode (DBusTypeWriter *writer,
825 /* A subwriter inside an array or variant will have type_pos
826 * pointing to the expected typecode; a writer not inside an array
827 * or variant has type_pos pointing to the next place to insert a
830 _dbus_verbose (" type writer %p write_or_verify start type_pos = %d remaining sig '%s'\n",
831 writer, writer->type_pos,
832 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
834 if (writer->type_pos_is_expectation)
836 #ifndef DBUS_DISABLE_CHECKS
840 expected = _dbus_string_get_byte (writer->type_str, writer->type_pos);
842 if (expected != typecode)
844 _dbus_warn ("Array or Variant type requires that type %s be written, but %s was written\n",
845 _dbus_type_to_string (expected), _dbus_type_to_string (typecode));
846 _dbus_assert_not_reached ("bad type inserted somewhere inside an array or variant");
849 #endif /* DBUS_DISABLE_CHECKS */
851 /* if immediately inside an array we'd always be appending an element,
852 * so the expected type doesn't change; if inside a struct or something
853 * below an array, we need to move through said struct or something.
855 if (writer->container_type != DBUS_TYPE_ARRAY)
856 writer->type_pos += 1;
860 if (!_dbus_string_insert_byte (writer->type_str,
865 writer->type_pos += 1;
868 _dbus_verbose (" type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
869 writer, writer->type_pos,
870 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
876 _dbus_type_writer_recurse_struct (DBusTypeWriter *writer,
879 writer_recurse_init_and_check (writer, DBUS_TYPE_STRUCT, sub);
881 /* Ensure that we'll be able to add alignment padding and the typecode */
882 if (!_dbus_string_alloc_space (sub->value_str, 8))
885 if (!write_or_verify_typecode (sub, DBUS_STRUCT_BEGIN_CHAR))
886 _dbus_assert_not_reached ("failed to insert struct typecode after prealloc");
888 if (!_dbus_string_insert_bytes (sub->value_str,
890 _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
892 _dbus_assert_not_reached ("should not have failed to insert alignment padding for struct");
893 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
899 _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
900 const char *element_type,
903 int element_type_len;
904 DBusString element_type_str;
905 dbus_uint32_t value = 0;
910 writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, sub);
912 #ifndef DBUS_DISABLE_CHECKS
913 if (writer->container_type == DBUS_TYPE_ARRAY)
915 DBusString parent_elements;
917 _dbus_assert (element_type != NULL);
919 _dbus_string_init_const (&parent_elements,
920 _dbus_string_get_const_data_len (writer->type_str,
921 writer->u.array.element_type_pos + 1,
924 if (!_dbus_string_starts_with_c_str (&parent_elements, element_type))
926 _dbus_warn ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
928 _dbus_assert_not_reached ("incompatible type for child array");
931 #endif /* DBUS_DISABLE_CHECKS */
933 _dbus_string_init_const (&element_type_str, element_type);
934 element_type_len = _dbus_string_get_length (&element_type_str);
936 /* 4 bytes for the array length and 4 bytes possible padding */
937 if (!_dbus_string_alloc_space (sub->value_str, 8))
940 sub->type_pos += 1; /* move to point to the element type, since type_pos
941 * should be the expected type for further writes
943 sub->u.array.element_type_pos = sub->type_pos;
945 if (!writer->type_pos_is_expectation)
947 /* sub is a toplevel/outermost array so we need to write the type data */
949 /* alloc space for array typecode, element signature, possible 7
952 if (!_dbus_string_alloc_space (writer->type_str, 1 + element_type_len + 7))
955 if (!_dbus_string_insert_byte (writer->type_str,
958 _dbus_assert_not_reached ("failed to insert array typecode after prealloc");
960 if (!_dbus_string_copy (&element_type_str, 0,
961 sub->type_str, sub->u.array.element_type_pos))
962 _dbus_assert_not_reached ("should not have failed to insert array element typecodes");
965 /* If the parent is an array, we hold type_pos pointing at the array element type;
966 * otherwise advance it to reflect the array value we just recursed into
968 if (writer->container_type != DBUS_TYPE_ARRAY)
969 writer->type_pos += 1 + element_type_len;
971 _dbus_assert (writer->type_pos_is_expectation); /* because it's an array */
973 /* Write the length */
974 sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
976 if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
978 _dbus_assert_not_reached ("should not have failed to insert array len");
980 _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);
982 /* Write alignment padding for array elements */
983 _dbus_string_init_const (&str, element_type);
984 alignment = element_type_get_alignment (&str, 0);
986 aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
987 if (aligned != sub->value_pos)
989 if (!_dbus_string_insert_bytes (sub->value_str,
991 aligned - sub->value_pos,
993 _dbus_assert_not_reached ("should not have failed to insert alignment padding");
995 sub->value_pos = aligned;
997 sub->u.array.start_pos = sub->value_pos;
999 _dbus_assert (sub->u.array.start_pos == sub->value_pos);
1000 _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
1002 _dbus_verbose (" type writer %p recurse array done remaining sig '%s'\n", sub,
1003 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
1008 /* Variant value will normally have:
1009 * 1 byte signature length not including nul
1010 * signature typecodes (nul terminated)
1011 * padding to 8-boundary
1012 * body according to signature
1014 * The signature string can only have a single type
1015 * in it but that type may be complex/recursive.
1017 * So a typical variant type with the integer 3 will have these
1019 * 0x1 'i' '\0' [padding to 8-boundary] 0x0 0x0 0x0 0x3
1021 * For an array of 4-byte types stuffed into variants, the padding to
1022 * 8-boundary is only the 1 byte that is required for the 4-boundary
1023 * anyhow for all array elements after the first one. And for single
1024 * variants in isolation, wasting a few bytes is hardly a big deal.
1026 * The main world of hurt for writing out a variant is that the type
1027 * string is the same string as the value string. Which means
1028 * inserting to the type string will move the value_pos; and it means
1029 * that inserting to the type string could break type alignment.
1031 * This type alignment issue is why the body of the variant is always
1032 * 8-aligned. Then we know that re-8-aligning the start of the body
1033 * will always correctly align the full contents of the variant type.
1036 _dbus_type_writer_recurse_variant (DBusTypeWriter *writer,
1037 const char *contained_type,
1038 DBusTypeWriter *sub)
1040 int contained_type_len;
1041 DBusString contained_type_str;
1043 writer_recurse_init_and_check (writer, DBUS_TYPE_VARIANT, sub);
1045 _dbus_string_init_const (&contained_type_str, contained_type);
1047 contained_type_len = _dbus_string_get_length (&contained_type_str);
1049 /* Allocate space for the worst case, which is 1 byte sig
1050 * length, nul byte at end of sig, and 7 bytes padding to
1053 if (!_dbus_string_alloc_space (sub->value_str, contained_type_len + 9))
1056 /* write VARIANT typecode to the parent's type string */
1057 if (!write_or_verify_typecode (sub, DBUS_TYPE_VARIANT))
1060 if (!_dbus_string_insert_byte (sub->value_str,
1062 contained_type_len))
1063 _dbus_assert_not_reached ("should not have failed to insert variant type sig len");
1065 sub->value_pos += 1;
1067 /* Here we switch over to the expected type sig we're about to write */
1068 sub->type_str = sub->value_str;
1069 sub->type_pos = sub->value_pos;
1071 if (!_dbus_string_copy (&contained_type_str, 0,
1072 sub->value_str, sub->value_pos))
1073 _dbus_assert_not_reached ("should not have failed to insert variant type sig");
1075 sub->value_pos += contained_type_len;
1077 if (!_dbus_string_insert_byte (sub->value_str,
1080 _dbus_assert_not_reached ("should not have failed to insert variant type nul termination");
1082 sub->value_pos += 1;
1084 if (!_dbus_string_insert_bytes (sub->value_str,
1086 _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
1088 _dbus_assert_not_reached ("should not have failed to insert alignment padding for variant body");
1089 sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
1095 _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
1096 DBusTypeWriter *sub)
1098 _dbus_assert (sub->type_pos > 0); /* can't be recursed if this fails */
1100 /* type_pos_is_expectation never gets unset once set, or we'd get all hosed */
1101 _dbus_assert (!writer->type_pos_is_expectation ||
1102 (writer->type_pos_is_expectation && sub->type_pos_is_expectation));
1104 _dbus_verbose (" type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
1105 writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
1106 _dbus_type_to_string (writer->container_type));
1107 _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
1108 sub, sub->type_pos, sub->value_pos,
1109 sub->type_pos_is_expectation,
1110 _dbus_type_to_string (sub->container_type));
1112 if (sub->container_type == DBUS_TYPE_STRUCT)
1114 if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
1117 else if (sub->container_type == DBUS_TYPE_ARRAY)
1121 /* Set the array length */
1122 len = sub->value_pos - sub->u.array.start_pos;
1123 _dbus_marshal_set_uint32 (sub->value_str,
1125 sub->u.array.len_pos,
1127 _dbus_verbose (" filled in sub array len to %u at len_pos %d\n",
1128 len, sub->u.array.len_pos);
1131 /* Now get type_pos right for the parent writer. Here are the cases:
1133 * Cases !writer->type_pos_is_expectation:
1134 * (in these cases we want to update to the new insertion point)
1136 * - if we recursed into a STRUCT then we didn't know in advance
1137 * what the types in the struct would be; so we have to fill in
1138 * that information now.
1139 * writer->type_pos = sub->type_pos
1141 * - if we recursed into anything else, we knew the full array
1142 * type, or knew the single typecode marking VARIANT, so
1143 * writer->type_pos is already correct.
1144 * writer->type_pos should remain as-is
1146 * - note that the parent is never an ARRAY or VARIANT, if it were
1147 * then type_pos_is_expectation would be TRUE. The parent
1148 * is thus known to be a toplevel or STRUCT.
1150 * Cases where writer->type_pos_is_expectation:
1151 * (in these cases we want to update to next expected type to write)
1153 * - we recursed from STRUCT into STRUCT and we didn't increment
1154 * type_pos in the parent just to stay consistent with the
1155 * !writer->type_pos_is_expectation case (though we could
1156 * special-case this in recurse_struct instead if we wanted)
1157 * writer->type_pos = sub->type_pos
1159 * - we recursed from STRUCT into ARRAY or VARIANT and type_pos
1160 * for parent should have been incremented already
1161 * writer->type_pos should remain as-is
1163 * - we recursed from ARRAY into a sub-element, so type_pos in the
1164 * parent is the element type and should remain the element type
1165 * for the benefit of the next child element
1166 * writer->type_pos should remain as-is
1168 * - we recursed from VARIANT into its value, so type_pos in the
1169 * parent makes no difference since there's only one value
1170 * and we just finished writing it and won't use type_pos again
1171 * writer->type_pos should remain as-is
1173 if (sub->container_type == DBUS_TYPE_STRUCT &&
1174 (writer->container_type == DBUS_TYPE_STRUCT ||
1175 writer->container_type == DBUS_TYPE_INVALID))
1177 /* Advance the parent to the next struct field */
1178 writer->type_pos = sub->type_pos;
1181 writer->value_pos = sub->value_pos;
1183 _dbus_verbose (" type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n",
1184 writer, writer->type_pos, writer->value_pos,
1185 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
1191 _dbus_type_writer_write_basic (DBusTypeWriter *writer,
1197 /* First ensure that our type realloc will succeed */
1198 if (!_dbus_string_alloc_space (writer->type_str, 1))
1203 if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
1206 if (!write_or_verify_typecode (writer, type))
1207 _dbus_assert_not_reached ("failed to write typecode after prealloc");
1212 _dbus_verbose (" type writer %p basic type_pos = %d value_pos = %d is_expectation = %d\n",
1213 writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation);
1219 _dbus_type_writer_write_array (DBusTypeWriter *writer,
1228 /** @} */ /* end of DBusMarshal group */
1230 #ifdef DBUS_BUILD_TESTS
1231 #include "dbus-test.h"
1237 DBusString signature;
1248 data_block_init (DataBlock *block)
1250 if (!_dbus_string_init (&block->signature))
1253 if (!_dbus_string_init (&block->body))
1255 _dbus_string_free (&block->signature);
1263 data_block_free (DataBlock *block)
1265 _dbus_string_free (&block->signature);
1266 _dbus_string_free (&block->body);
1270 data_block_save (DataBlock *block,
1271 DataBlockState *state)
1273 state->saved_sig_len = _dbus_string_get_length (&block->signature);
1274 state->saved_body_len = _dbus_string_get_length (&block->body);
1278 data_block_restore (DataBlock *block,
1279 DataBlockState *state)
1281 /* These set_length should be shortening things so should always work */
1283 if (!_dbus_string_set_length (&block->signature,
1284 state->saved_sig_len))
1285 _dbus_assert_not_reached ("could not restore signature length");
1287 if (!_dbus_string_set_length (&block->body,
1288 state->saved_body_len))
1289 _dbus_assert_not_reached ("could not restore body length");
1293 data_block_init_reader_writer (DataBlock *block,
1295 DBusTypeReader *reader,
1296 DBusTypeWriter *writer)
1298 _dbus_type_reader_init (reader,
1301 _dbus_string_get_length (&block->signature),
1303 _dbus_string_get_length (&block->body));
1305 _dbus_type_writer_init (writer,
1308 _dbus_string_get_length (&block->signature),
1310 _dbus_string_get_length (&block->body));
1313 #define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
1315 _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
1316 _DBUS_FUNCTION_NAME, __LINE__); \
1317 _dbus_assert_not_reached ("test failed"); \
1321 #define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
1323 _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
1324 _DBUS_FUNCTION_NAME, __LINE__); \
1325 _dbus_assert_not_reached ("test failed"); \
1327 check_expected_type (reader, DBUS_TYPE_INVALID); \
1330 #define SAMPLE_INT32 12345678
1331 #define SAMPLE_INT32_ALTERNATE 53781429
1333 write_int32 (DataBlock *block,
1334 DBusTypeWriter *writer)
1336 dbus_int32_t v = SAMPLE_INT32;
1338 return _dbus_type_writer_write_basic (writer,
1344 real_check_expected_type (DBusTypeReader *reader,
1346 const char *funcname,
1351 t = _dbus_type_reader_get_current_type (reader);
1355 _dbus_warn ("Read type %s while expecting %s at %s line %d\n",
1356 _dbus_type_to_string (t),
1357 _dbus_type_to_string (expected),
1364 #define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
1367 read_int32 (DataBlock *block,
1368 DBusTypeReader *reader)
1372 check_expected_type (reader, DBUS_TYPE_INT32);
1374 _dbus_type_reader_read_basic (reader,
1375 (dbus_int32_t*) &v);
1377 _dbus_assert (v == SAMPLE_INT32);
1383 write_struct_of_int32 (DataBlock *block,
1384 DBusTypeWriter *writer)
1387 DataBlockState saved;
1390 data_block_save (block, &saved);
1392 if (!_dbus_type_writer_recurse_struct (writer,
1397 if (!_dbus_type_writer_write_basic (&sub,
1401 data_block_restore (block, &saved);
1405 v = SAMPLE_INT32_ALTERNATE;
1406 if (!_dbus_type_writer_write_basic (&sub,
1410 data_block_restore (block, &saved);
1414 if (!_dbus_type_writer_unrecurse (writer, &sub))
1416 data_block_restore (block, &saved);
1424 read_struct_of_int32 (DataBlock *block,
1425 DBusTypeReader *reader)
1430 check_expected_type (reader, DBUS_TYPE_STRUCT);
1432 _dbus_type_reader_recurse (reader, &sub);
1434 check_expected_type (&sub, DBUS_TYPE_INT32);
1436 _dbus_type_reader_read_basic (&sub,
1437 (dbus_int32_t*) &v);
1439 _dbus_assert (v == SAMPLE_INT32);
1441 NEXT_EXPECTING_TRUE (&sub);
1442 check_expected_type (&sub, DBUS_TYPE_INT32);
1444 _dbus_type_reader_read_basic (&sub,
1445 (dbus_int32_t*) &v);
1447 _dbus_assert (v == SAMPLE_INT32_ALTERNATE);
1449 NEXT_EXPECTING_FALSE (&sub);
1455 write_struct_of_structs (DataBlock *block,
1456 DBusTypeWriter *writer)
1458 DataBlockState saved;
1461 data_block_save (block, &saved);
1463 if (!_dbus_type_writer_recurse_struct (writer,
1467 if (!write_struct_of_int32 (block, &sub))
1469 data_block_restore (block, &saved);
1472 if (!write_struct_of_int32 (block, &sub))
1474 data_block_restore (block, &saved);
1477 if (!write_struct_of_int32 (block, &sub))
1479 data_block_restore (block, &saved);
1483 if (!_dbus_type_writer_unrecurse (writer, &sub))
1485 data_block_restore (block, &saved);
1493 read_struct_of_structs (DataBlock *block,
1494 DBusTypeReader *reader)
1498 check_expected_type (reader, DBUS_TYPE_STRUCT);
1500 _dbus_type_reader_recurse (reader, &sub);
1502 if (!read_struct_of_int32 (block, &sub))
1505 NEXT_EXPECTING_TRUE (&sub);
1506 if (!read_struct_of_int32 (block, &sub))
1509 NEXT_EXPECTING_TRUE (&sub);
1510 if (!read_struct_of_int32 (block, &sub))
1513 NEXT_EXPECTING_FALSE (&sub);
1519 write_struct_of_structs_of_structs (DataBlock *block,
1520 DBusTypeWriter *writer)
1522 DataBlockState saved;
1525 data_block_save (block, &saved);
1527 if (!_dbus_type_writer_recurse_struct (writer,
1531 if (!write_struct_of_structs (block, &sub))
1533 data_block_restore (block, &saved);
1536 if (!write_struct_of_structs (block, &sub))
1538 data_block_restore (block, &saved);
1542 if (!_dbus_type_writer_unrecurse (writer, &sub))
1544 data_block_restore (block, &saved);
1552 read_struct_of_structs_of_structs (DataBlock *block,
1553 DBusTypeReader *reader)
1557 check_expected_type (reader, DBUS_TYPE_STRUCT);
1559 _dbus_type_reader_recurse (reader, &sub);
1561 if (!read_struct_of_structs (block, &sub))
1564 NEXT_EXPECTING_TRUE (&sub);
1565 if (!read_struct_of_structs (block, &sub))
1568 NEXT_EXPECTING_FALSE (&sub);
1574 write_array_of_int32 (DataBlock *block,
1575 DBusTypeWriter *writer)
1578 DataBlockState saved;
1581 data_block_save (block, &saved);
1583 if (!_dbus_type_writer_recurse_array (writer,
1584 DBUS_TYPE_INT32_AS_STRING,
1588 v = SAMPLE_INT32_ALTERNATE;
1589 if (!_dbus_type_writer_write_basic (&sub,
1593 data_block_restore (block, &saved);
1598 if (!_dbus_type_writer_write_basic (&sub,
1602 data_block_restore (block, &saved);
1607 if (!_dbus_type_writer_write_basic (&sub,
1611 data_block_restore (block, &saved);
1615 if (!_dbus_type_writer_unrecurse (writer, &sub))
1617 data_block_restore (block, &saved);
1625 read_array_of_int32 (DataBlock *block,
1626 DBusTypeReader *reader)
1631 check_expected_type (reader, DBUS_TYPE_ARRAY);
1633 _dbus_type_reader_recurse (reader, &sub);
1635 check_expected_type (&sub, DBUS_TYPE_INT32);
1637 _dbus_type_reader_read_basic (&sub,
1638 (dbus_int32_t*) &v);
1640 _dbus_assert (v == SAMPLE_INT32_ALTERNATE);
1642 NEXT_EXPECTING_TRUE (&sub);
1643 check_expected_type (&sub, DBUS_TYPE_INT32);
1645 _dbus_type_reader_read_basic (&sub,
1646 (dbus_int32_t*) &v);
1648 _dbus_assert (v == SAMPLE_INT32);
1650 NEXT_EXPECTING_TRUE (&sub);
1651 check_expected_type (&sub, DBUS_TYPE_INT32);
1653 _dbus_type_reader_read_basic (&sub,
1654 (dbus_int32_t*) &v);
1656 _dbus_assert (v == SAMPLE_INT32);
1658 NEXT_EXPECTING_FALSE (&sub);
1665 write_array_of_int32_empty (DataBlock *block,
1666 DBusTypeWriter *writer)
1668 DataBlockState saved;
1671 data_block_save (block, &saved);
1673 if (!_dbus_type_writer_recurse_array (writer,
1674 DBUS_TYPE_INT32_AS_STRING,
1678 if (!_dbus_type_writer_unrecurse (writer, &sub))
1680 data_block_restore (block, &saved);
1688 read_array_of_int32_empty (DataBlock *block,
1689 DBusTypeReader *reader)
1691 check_expected_type (reader, DBUS_TYPE_ARRAY);
1693 /* We are iterating over values not types. Thus we can't recurse
1696 _dbus_assert (_dbus_type_reader_array_is_empty (reader));
1702 write_array_of_array_of_int32 (DataBlock *block,
1703 DBusTypeWriter *writer)
1705 DataBlockState saved;
1708 data_block_save (block, &saved);
1710 if (!_dbus_type_writer_recurse_array (writer,
1711 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1715 if (!write_array_of_int32 (block, &sub))
1717 data_block_restore (block, &saved);
1721 if (!write_array_of_int32 (block, &sub))
1723 data_block_restore (block, &saved);
1727 if (!write_array_of_int32_empty (block, &sub))
1729 data_block_restore (block, &saved);
1733 if (!write_array_of_int32 (block, &sub))
1735 data_block_restore (block, &saved);
1739 if (!_dbus_type_writer_unrecurse (writer, &sub))
1741 data_block_restore (block, &saved);
1749 read_array_of_array_of_int32 (DataBlock *block,
1750 DBusTypeReader *reader)
1754 check_expected_type (reader, DBUS_TYPE_ARRAY);
1756 _dbus_type_reader_recurse (reader, &sub);
1758 if (!read_array_of_int32 (block, &sub))
1761 NEXT_EXPECTING_TRUE (&sub);
1762 if (!read_array_of_int32 (block, &sub))
1765 NEXT_EXPECTING_TRUE (&sub);
1766 if (!read_array_of_int32_empty (block, &sub))
1769 NEXT_EXPECTING_TRUE (&sub);
1770 if (!read_array_of_int32 (block, &sub))
1773 NEXT_EXPECTING_FALSE (&sub);
1780 write_array_of_array_of_int32_empty (DataBlock *block,
1781 DBusTypeWriter *writer)
1783 DataBlockState saved;
1786 data_block_save (block, &saved);
1788 if (!_dbus_type_writer_recurse_array (writer,
1789 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1793 if (!_dbus_type_writer_unrecurse (writer, &sub))
1795 data_block_restore (block, &saved);
1803 read_array_of_array_of_int32_empty (DataBlock *block,
1804 DBusTypeReader *reader)
1806 check_expected_type (reader, DBUS_TYPE_ARRAY);
1808 /* We are iterating over values, not types. Thus
1809 * we can't recurse in here.
1812 _dbus_assert (_dbus_type_reader_array_is_empty (reader));
1818 write_array_of_array_of_array_of_int32 (DataBlock *block,
1819 DBusTypeWriter *writer)
1821 DataBlockState saved;
1824 data_block_save (block, &saved);
1826 if (!_dbus_type_writer_recurse_array (writer,
1827 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
1831 if (!write_array_of_array_of_int32 (block, &sub))
1833 data_block_restore (block, &saved);
1837 if (!write_array_of_array_of_int32 (block, &sub))
1839 data_block_restore (block, &saved);
1843 if (!write_array_of_array_of_int32_empty (block, &sub))
1845 data_block_restore (block, &saved);
1849 if (!_dbus_type_writer_unrecurse (writer, &sub))
1851 data_block_restore (block, &saved);
1859 read_array_of_array_of_array_of_int32 (DataBlock *block,
1860 DBusTypeReader *reader)
1864 check_expected_type (reader, DBUS_TYPE_ARRAY);
1866 _dbus_type_reader_recurse (reader, &sub);
1868 if (!read_array_of_array_of_int32 (block, &sub))
1871 NEXT_EXPECTING_TRUE (&sub);
1872 if (!read_array_of_array_of_int32 (block, &sub))
1875 NEXT_EXPECTING_TRUE (&sub);
1876 if (!read_array_of_array_of_int32_empty (block, &sub))
1879 NEXT_EXPECTING_FALSE (&sub);
1885 write_struct_of_array_of_int32 (DataBlock *block,
1886 DBusTypeWriter *writer)
1888 DataBlockState saved;
1891 data_block_save (block, &saved);
1893 if (!_dbus_type_writer_recurse_struct (writer,
1897 if (!write_array_of_int32 (block, &sub))
1899 data_block_restore (block, &saved);
1903 if (!write_array_of_int32_empty (block, &sub))
1905 data_block_restore (block, &saved);
1909 if (!_dbus_type_writer_unrecurse (writer, &sub))
1911 data_block_restore (block, &saved);
1919 read_struct_of_array_of_int32 (DataBlock *block,
1920 DBusTypeReader *reader)
1924 check_expected_type (reader, DBUS_TYPE_STRUCT);
1926 _dbus_type_reader_recurse (reader, &sub);
1928 check_expected_type (&sub, DBUS_TYPE_ARRAY);
1930 if (!read_array_of_int32 (block, &sub))
1933 NEXT_EXPECTING_TRUE (&sub);
1934 if (!read_array_of_int32_empty (block, &sub))
1937 NEXT_EXPECTING_FALSE (&sub);
1943 write_struct_of_struct_of_array_of_int32 (DataBlock *block,
1944 DBusTypeWriter *writer)
1946 DataBlockState saved;
1949 data_block_save (block, &saved);
1951 if (!_dbus_type_writer_recurse_struct (writer,
1955 if (!write_struct_of_array_of_int32 (block, &sub))
1957 data_block_restore (block, &saved);
1960 if (!write_struct_of_array_of_int32 (block, &sub))
1962 data_block_restore (block, &saved);
1965 if (!write_struct_of_array_of_int32 (block, &sub))
1967 data_block_restore (block, &saved);
1971 if (!_dbus_type_writer_unrecurse (writer, &sub))
1973 data_block_restore (block, &saved);
1981 read_struct_of_struct_of_array_of_int32 (DataBlock *block,
1982 DBusTypeReader *reader)
1986 check_expected_type (reader, DBUS_TYPE_STRUCT);
1988 _dbus_type_reader_recurse (reader, &sub);
1990 if (!read_struct_of_array_of_int32 (block, &sub))
1993 NEXT_EXPECTING_TRUE (&sub);
1994 if (!read_struct_of_array_of_int32 (block, &sub))
1997 NEXT_EXPECTING_TRUE (&sub);
1998 if (!read_struct_of_array_of_int32 (block, &sub))
2001 NEXT_EXPECTING_FALSE (&sub);
2007 write_array_of_struct_of_int32 (DataBlock *block,
2008 DBusTypeWriter *writer)
2010 DataBlockState saved;
2013 data_block_save (block, &saved);
2015 if (!_dbus_type_writer_recurse_array (writer,
2016 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
2017 DBUS_TYPE_INT32_AS_STRING
2018 DBUS_TYPE_INT32_AS_STRING
2019 DBUS_STRUCT_END_CHAR_AS_STRING,
2023 if (!write_struct_of_int32 (block, &sub))
2025 data_block_restore (block, &saved);
2029 if (!write_struct_of_int32 (block, &sub))
2031 data_block_restore (block, &saved);
2035 if (!write_struct_of_int32 (block, &sub))
2037 data_block_restore (block, &saved);
2041 if (!_dbus_type_writer_unrecurse (writer, &sub))
2043 data_block_restore (block, &saved);
2051 read_array_of_struct_of_int32 (DataBlock *block,
2052 DBusTypeReader *reader)
2056 check_expected_type (reader, DBUS_TYPE_ARRAY);
2058 _dbus_type_reader_recurse (reader, &sub);
2060 check_expected_type (&sub, DBUS_TYPE_STRUCT);
2062 if (!read_struct_of_int32 (block, &sub))
2065 NEXT_EXPECTING_TRUE (&sub);
2067 if (!read_struct_of_int32 (block, &sub))
2070 NEXT_EXPECTING_TRUE (&sub);
2072 if (!read_struct_of_int32 (block, &sub))
2075 NEXT_EXPECTING_FALSE (&sub);
2082 write_array_of_array_of_struct_of_int32 (DataBlock *block,
2083 DBusTypeWriter *writer)
2085 DataBlockState saved;
2088 data_block_save (block, &saved);
2090 if (!_dbus_type_writer_recurse_array (writer,
2091 DBUS_TYPE_ARRAY_AS_STRING
2092 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
2093 DBUS_TYPE_INT32_AS_STRING
2094 DBUS_TYPE_INT32_AS_STRING
2095 DBUS_STRUCT_END_CHAR_AS_STRING,
2099 if (!write_array_of_struct_of_int32 (block, &sub))
2101 data_block_restore (block, &saved);
2105 if (!write_array_of_struct_of_int32 (block, &sub))
2107 data_block_restore (block, &saved);
2111 if (!write_array_of_struct_of_int32 (block, &sub))
2113 data_block_restore (block, &saved);
2117 if (!_dbus_type_writer_unrecurse (writer, &sub))
2119 data_block_restore (block, &saved);
2127 read_array_of_array_of_struct_of_int32 (DataBlock *block,
2128 DBusTypeReader *reader)
2132 check_expected_type (reader, DBUS_TYPE_ARRAY);
2134 _dbus_type_reader_recurse (reader, &sub);
2136 check_expected_type (&sub, DBUS_TYPE_ARRAY);
2138 if (!read_array_of_struct_of_int32 (block, &sub))
2141 NEXT_EXPECTING_TRUE (&sub);
2143 if (!read_array_of_struct_of_int32 (block, &sub))
2146 NEXT_EXPECTING_TRUE (&sub);
2148 if (!read_array_of_struct_of_int32 (block, &sub))
2151 NEXT_EXPECTING_FALSE (&sub);
2157 write_struct_of_array_of_struct_of_int32 (DataBlock *block,
2158 DBusTypeWriter *writer)
2160 DataBlockState saved;
2163 data_block_save (block, &saved);
2165 if (!_dbus_type_writer_recurse_struct (writer,
2169 if (!write_array_of_struct_of_int32 (block, &sub))
2171 data_block_restore (block, &saved);
2174 if (!write_array_of_struct_of_int32 (block, &sub))
2176 data_block_restore (block, &saved);
2179 if (!write_array_of_struct_of_int32 (block, &sub))
2181 data_block_restore (block, &saved);
2185 if (!_dbus_type_writer_unrecurse (writer, &sub))
2187 data_block_restore (block, &saved);
2195 read_struct_of_array_of_struct_of_int32 (DataBlock *block,
2196 DBusTypeReader *reader)
2200 check_expected_type (reader, DBUS_TYPE_STRUCT);
2202 _dbus_type_reader_recurse (reader, &sub);
2204 if (!read_array_of_struct_of_int32 (block, &sub))
2207 NEXT_EXPECTING_TRUE (&sub);
2208 if (!read_array_of_struct_of_int32 (block, &sub))
2211 NEXT_EXPECTING_TRUE (&sub);
2212 if (!read_array_of_struct_of_int32 (block, &sub))
2215 NEXT_EXPECTING_FALSE (&sub);
2221 write_array_of_struct_of_array_of_int32 (DataBlock *block,
2222 DBusTypeWriter *writer)
2224 DataBlockState saved;
2227 data_block_save (block, &saved);
2229 if (!_dbus_type_writer_recurse_array (writer,
2230 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
2231 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING
2232 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING
2233 DBUS_STRUCT_END_CHAR_AS_STRING,
2237 if (!write_struct_of_array_of_int32 (block, &sub))
2239 data_block_restore (block, &saved);
2243 if (!write_struct_of_array_of_int32 (block, &sub))
2245 data_block_restore (block, &saved);
2249 if (!write_struct_of_array_of_int32 (block, &sub))
2251 data_block_restore (block, &saved);
2255 if (!_dbus_type_writer_unrecurse (writer, &sub))
2257 data_block_restore (block, &saved);
2265 read_array_of_struct_of_array_of_int32 (DataBlock *block,
2266 DBusTypeReader *reader)
2270 check_expected_type (reader, DBUS_TYPE_ARRAY);
2272 _dbus_type_reader_recurse (reader, &sub);
2274 check_expected_type (&sub, DBUS_TYPE_STRUCT);
2276 if (!read_struct_of_array_of_int32 (block, &sub))
2279 NEXT_EXPECTING_TRUE (&sub);
2281 if (!read_struct_of_array_of_int32 (block, &sub))
2284 NEXT_EXPECTING_TRUE (&sub);
2286 if (!read_struct_of_array_of_int32 (block, &sub))
2289 NEXT_EXPECTING_FALSE (&sub);
2299 ITEM_STRUCT_OF_INT32,
2300 ITEM_STRUCT_OF_STRUCTS,
2301 ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
2303 ITEM_ARRAY_OF_INT32,
2304 ITEM_ARRAY_OF_INT32_EMPTY,
2305 ITEM_ARRAY_OF_ARRAY_OF_INT32,
2306 ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,
2307 ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
2309 ITEM_STRUCT_OF_ARRAY_OF_INT32,
2310 ITEM_STRUCT_OF_STRUCT_OF_ARRAY_OF_INT32,
2312 ITEM_ARRAY_OF_STRUCT_OF_INT32,
2313 ITEM_ARRAY_OF_ARRAY_OF_STRUCT_OF_INT32,
2315 ITEM_STRUCT_OF_ARRAY_OF_STRUCT_OF_INT32,
2316 ITEM_ARRAY_OF_STRUCT_OF_ARRAY_OF_INT32,
2322 typedef dbus_bool_t (* WriteItemFunc) (DataBlock *block,
2323 DBusTypeWriter *writer);
2324 typedef dbus_bool_t (* ReadItemFunc) (DataBlock *block,
2325 DBusTypeReader *reader);
2331 WriteItemFunc write_item_func;
2332 ReadItemFunc read_item_func;
2335 static CheckMarshalItem items[] = {
2337 ITEM_INT32, write_int32, read_int32 },
2338 { "struct with two int32",
2339 ITEM_STRUCT_OF_INT32, write_struct_of_int32, read_struct_of_int32 },
2340 { "struct with three structs of two int32",
2341 ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
2342 { "struct of two structs of three structs of two int32",
2343 ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
2344 write_struct_of_structs_of_structs,
2345 read_struct_of_structs_of_structs },
2347 ITEM_ARRAY_OF_INT32, write_array_of_int32, read_array_of_int32 },
2348 { "empty array of int32",
2349 ITEM_ARRAY_OF_INT32_EMPTY, write_array_of_int32_empty, read_array_of_int32_empty },
2350 { "array of array of int32",
2351 ITEM_ARRAY_OF_ARRAY_OF_INT32,
2352 write_array_of_array_of_int32, read_array_of_array_of_int32 },
2353 { "empty array of array of int32",
2354 ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,
2355 write_array_of_array_of_int32_empty, read_array_of_array_of_int32_empty },
2356 { "array of array of array of int32",
2357 ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
2358 write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 },
2359 { "struct of array of int32",
2360 ITEM_STRUCT_OF_ARRAY_OF_INT32, write_struct_of_array_of_int32, read_struct_of_array_of_int32 },
2361 { "struct of struct of array of int32",
2362 ITEM_STRUCT_OF_STRUCT_OF_ARRAY_OF_INT32,
2363 write_struct_of_struct_of_array_of_int32, read_struct_of_struct_of_array_of_int32 },
2364 { "array of struct of int32",
2365 ITEM_ARRAY_OF_STRUCT_OF_INT32, write_array_of_struct_of_int32, read_array_of_struct_of_int32 },
2366 { "array of array of struct of int32",
2367 ITEM_ARRAY_OF_ARRAY_OF_STRUCT_OF_INT32,
2368 write_array_of_array_of_struct_of_int32, read_array_of_array_of_struct_of_int32 },
2370 { "struct of array of struct of int32",
2371 ITEM_STRUCT_OF_ARRAY_OF_STRUCT_OF_INT32,
2372 write_struct_of_array_of_struct_of_int32, read_struct_of_array_of_struct_of_int32 },
2373 { "array of struct of array of int32",
2374 ITEM_ARRAY_OF_STRUCT_OF_ARRAY_OF_INT32,
2375 write_array_of_struct_of_array_of_int32, read_array_of_struct_of_array_of_int32 },
2380 /* Array of items from the above items[]; -1 terminated */
2384 static TestRun runs[] = {
2385 { { ITEM_INVALID } },
2388 { { ITEM_INT32, ITEM_INVALID } },
2389 { { ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
2390 { { ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
2392 /* STRUCT_OF_INT32 */
2393 { { ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
2394 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
2395 { { ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
2396 { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
2397 { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
2399 /* STRUCT_OF_STRUCTS */
2400 { { ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2401 { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2402 { { ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2403 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2404 { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2405 { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
2407 /* STRUCT_OF_STRUCTS_OF_STRUCTS */
2408 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2409 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2410 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2411 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2412 { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2413 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2415 /* ARRAY_OF_INT32 */
2416 { { ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2417 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2418 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2419 { { ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
2420 { { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
2421 { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2422 { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2423 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2424 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2425 { { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
2427 /* ARRAY_OF_ARRAY_OF_INT32 */
2428 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2429 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2430 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2431 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
2432 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
2433 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2434 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2435 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2436 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2437 { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2439 /* ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32 */
2440 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2441 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2442 { { 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 } },
2443 { { 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 } },
2444 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_INVALID } },
2445 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2446 { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2447 { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
2448 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2449 { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2451 /* STRUCT_OF_ARRAY_OF_INT32 */
2452 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2453 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2454 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2455 { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2456 { { ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2457 { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2459 /* STRUCT_OF_STRUCT_OF_ARRAY_OF_INT32 */
2460 { { ITEM_STRUCT_OF_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2462 /* ARRAY_OF_STRUCT_OF_INT32 */
2463 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2464 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2465 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2466 { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2467 { { ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2468 { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2470 /* ARRAY_OF_ARRAY_OF_STRUCT_OF_INT32 */
2471 { { ITEM_ARRAY_OF_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2473 /* STRUCT_OF_ARRAY_OF_STRUCT_OF_INT32 */
2474 { { ITEM_STRUCT_OF_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
2476 /* ARRAY_OF_STRUCT_OF_ARRAY_OF_INT32 */
2477 { { ITEM_ARRAY_OF_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
2482 perform_one_run (DataBlock *block,
2486 DBusTypeReader reader;
2487 DBusTypeWriter writer;
2489 DataBlockState saved;
2495 _dbus_verbose ("run byteorder %s items ",
2496 byte_order == DBUS_LITTLE_ENDIAN ? "little" : "big");
2498 while (run->items[i] != ITEM_INVALID)
2500 CheckMarshalItem *item = &items[run->items[i]];
2502 _dbus_verbose ("%s ", item->desc);
2505 _dbus_verbose (" = %d items\n", i);
2508 data_block_save (block, &saved);
2510 data_block_init_reader_writer (block,
2515 while (run->items[i] != ITEM_INVALID)
2517 CheckMarshalItem *item = &items[run->items[i]];
2519 _dbus_verbose (">>writing %s\n", item->desc);
2521 if (!(* item->write_item_func) (block, &writer))
2527 while (run->items[i] != ITEM_INVALID)
2529 CheckMarshalItem *item = &items[run->items[i]];
2531 _dbus_verbose (">>data for reading %s\n", item->desc);
2533 _dbus_verbose_bytes_of_string (reader.type_str, 0,
2534 _dbus_string_get_length (reader.type_str));
2535 _dbus_verbose_bytes_of_string (reader.value_str, 0,
2536 _dbus_string_get_length (reader.value_str));
2538 _dbus_verbose (">>reading %s\n", item->desc);
2540 if (!(* item->read_item_func) (block, &reader))
2543 _dbus_type_reader_next (&reader);
2551 data_block_restore (block, &saved);
2556 perform_all_runs (int byte_order,
2565 if (!data_block_init (&block))
2568 if (!_dbus_string_lengthen (&block.signature, initial_offset))
2571 if (!_dbus_string_lengthen (&block.body, initial_offset))
2575 while (i < _DBUS_N_ELEMENTS (runs))
2577 if (!perform_one_run (&block, byte_order, &runs[i]))
2586 data_block_free (&block);
2592 perform_all_items (int byte_order,
2602 if (!data_block_init (&block))
2606 if (!_dbus_string_lengthen (&block.signature, initial_offset))
2609 if (!_dbus_string_lengthen (&block.body, initial_offset))
2612 /* Create a run containing all the items */
2614 while (i < _DBUS_N_ELEMENTS (items))
2616 _dbus_assert (i == items[i].which);
2618 run.items[i] = items[i].which;
2623 run.items[i] = ITEM_INVALID;
2625 if (!perform_one_run (&block, byte_order, &run))
2631 data_block_free (&block);
2637 recursive_marshal_test_iteration (void *data)
2644 if (!perform_all_runs (DBUS_LITTLE_ENDIAN, i))
2646 if (!perform_all_runs (DBUS_BIG_ENDIAN, i))
2648 if (!perform_all_items (DBUS_LITTLE_ENDIAN, i))
2650 if (!perform_all_items (DBUS_BIG_ENDIAN, i))
2659 dbus_bool_t _dbus_marshal_recursive_test (void);
2662 _dbus_marshal_recursive_test (void)
2664 _dbus_test_oom_handling ("recursive marshaling",
2665 recursive_marshal_test_iteration,
2673 main (int argc, char **argv)
2675 _dbus_marshal_recursive_test ();
2681 #endif /* DBUS_BUILD_TESTS */