summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-marshal-recursive.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2004-12-29 05:04:01 +0000
committerHavoc Pennington <hp@redhat.com>2004-12-29 05:04:01 +0000
commit160cf6f8081c8a4b1f14ec221016f7f1abd88262 (patch)
tree3612544f7da9b4f83df0f399edca630ac3776fd3 /dbus/dbus-marshal-recursive.c
parentd9afb9b5f1d32e49598b88ed04dc4726aec108d1 (diff)
checkpoint with array-of-struct working
Diffstat (limited to 'dbus/dbus-marshal-recursive.c')
-rw-r--r--dbus/dbus-marshal-recursive.c675
1 files changed, 444 insertions, 231 deletions
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c
index ee4683ee..d821a11c 100644
--- a/dbus/dbus-marshal-recursive.c
+++ b/dbus/dbus-marshal-recursive.c
@@ -170,11 +170,6 @@ _dbus_type_reader_read_basic (DBusTypeReader *reader,
_dbus_verbose (" type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",
reader, reader->type_pos, reader->value_pos, next,
_dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
-
- _dbus_verbose_bytes_of_string (reader->value_str,
- reader->value_pos,
- MIN (16,
- _dbus_string_get_length (reader->value_str) - reader->value_pos));
}
else
{
@@ -271,8 +266,10 @@ _dbus_type_reader_recurse (DBusTypeReader *reader,
else
{
_dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t));
+#ifndef DBUS_DISABLE_CHECKS
if (t == DBUS_TYPE_INVALID)
_dbus_warn ("You can't recurse into an empty array or off the end of a message body\n");
+#endif /* DBUS_DISABLE_CHECKS */
_dbus_assert_not_reached ("don't yet handle recursing into this type");
}
@@ -316,22 +313,28 @@ skip_one_complete_type (const DBusString *type_str,
}
static void
-skip_array_values (const DBusString *value_str,
+skip_array_values (int element_type,
+ const DBusString *value_str,
int *value_pos,
int byte_order)
{
dbus_uint32_t array_len;
- int len_pos;
+ int pos;
+ int alignment;
- len_pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
+ pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
_dbus_demarshal_basic_type (value_str,
DBUS_TYPE_UINT32,
&array_len,
byte_order,
- &len_pos);
+ &pos);
+
+ alignment = _dbus_type_get_alignment (element_type);
+
+ pos = _DBUS_ALIGN_VALUE (pos, alignment);
- *value_pos = len_pos + array_len;
+ *value_pos = pos + array_len;
}
/**
@@ -384,7 +387,9 @@ _dbus_type_reader_next (DBusTypeReader *reader)
case DBUS_TYPE_ARRAY:
{
- skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order);
+ skip_array_values (first_type_in_signature (reader->type_str,
+ reader->type_pos + 1),
+ reader->value_str, &reader->value_pos, reader->byte_order);
skip_one_complete_type (reader->type_str, &reader->type_pos);
}
break;
@@ -440,7 +445,9 @@ _dbus_type_reader_next (DBusTypeReader *reader)
}
else if (reader->u.array.element_type == DBUS_TYPE_ARRAY)
{
- skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order);
+ skip_array_values (first_type_in_signature (reader->type_str,
+ reader->type_pos + 1),
+ reader->value_str, &reader->value_pos, reader->byte_order);
}
else
{
@@ -485,6 +492,9 @@ _dbus_type_writer_init (DBusTypeWriter *writer,
writer->value_pos = value_pos;
writer->container_type = DBUS_TYPE_INVALID;
writer->inside_array = FALSE;
+
+ _dbus_verbose ("writer %p init remaining sig '%s'\n", writer,
+ _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
}
static dbus_bool_t
@@ -511,56 +521,30 @@ _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,
return TRUE;
}
-dbus_bool_t
-_dbus_type_writer_write_basic (DBusTypeWriter *writer,
- int type,
- const void *value)
-{
- dbus_bool_t retval;
-
- /* First ensure that our type realloc will succeed */
- if (!_dbus_string_alloc_space (writer->type_str, 1))
- return FALSE;
-
- retval = FALSE;
-
- if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
- goto out;
-
- /* Now insert the type unless we're already covered by the array signature */
- if (!writer->inside_array)
- {
- if (!_dbus_string_insert_byte (writer->type_str,
- writer->type_pos,
- type))
- _dbus_assert_not_reached ("failed to insert byte after prealloc");
-
- writer->type_pos += 1;
- }
-
- retval = TRUE;
-
- out:
- _dbus_verbose (" type writer %p basic type_pos = %d value_pos = %d inside_array = %d\n",
- writer, writer->type_pos, writer->value_pos, writer->inside_array);
-
- return retval;
-}
-
-dbus_bool_t
-_dbus_type_writer_write_array (DBusTypeWriter *writer,
- int type,
- const void *array,
- int array_len)
-{
-
-
-}
-
+/* If our parent is an array, things are a little bit complicated.
+ *
+ * The parent must have a complete element type, such as
+ * "i" or "aai" or "(ii)" or "a(ii)". There can't be
+ * unclosed parens, or an "a" with no following type.
+ *
+ * To recurse, the only allowed operation is to recurse into the
+ * first type in the element type. So for "i" you can't recurse, for
+ * "ai" you can recurse into the array, for "(ii)" you can recurse
+ * into the struct.
+ *
+ * If you recurse into the array for "ai", then you must specify
+ * "i" for the element type of the array you recurse into.
+ *
+ * While inside an array at any level, we need to avoid writing to
+ * type_str, since the type only appears once for the whole array,
+ * it does not appear for each array element.
+ *
+ * While inside an array type_pos points to the expected next
+ * typecode, rather than the next place we could write a typecode.
+ */
static void
writer_recurse_init_and_check (DBusTypeWriter *writer,
int container_type,
- const char *array_element_type,
DBusTypeWriter *sub)
{
_dbus_type_writer_init (sub,
@@ -572,72 +556,89 @@ writer_recurse_init_and_check (DBusTypeWriter *writer,
sub->container_type = container_type;
- /* While inside an array, we never want to write to the type str.
- * We are inside an array if we're currently recursing into one.
- */
if (writer->inside_array || sub->container_type == DBUS_TYPE_ARRAY)
sub->inside_array = TRUE;
else
sub->inside_array = FALSE;
-
- /* If our parent is an array, things are a little bit complicated.
- *
- * The parent must have a complete element type, such as
- * "i" or "aai" or "(ii)" or "a(ii)". There can't be
- * unclosed parens, or an "a" with no following type.
- *
- * To recurse, the only allowed operation is to recurse into the
- * first type in the element type. So for "i" you can't recurse, for
- * "ai" you can recurse into the array, for "(ii)" you can recurse
- * into the struct.
- *
- * If you recurse into the array for "ai", then you must specify
- * "i" for the element type of the array you recurse into.
- *
- * While inside an array at any level, we need to avoid writing to
- * type_str, since the type only appears once for the whole array,
- * it does not appear for each array element.
- */
+
#ifndef DBUS_DISABLE_CHECKS
- if (writer->container_type == DBUS_TYPE_ARRAY)
+ if (writer->inside_array)
{
- if ((sub->container_type == DBUS_TYPE_STRUCT &&
- writer->u.array.element_type[0] != DBUS_STRUCT_BEGIN_CHAR) ||
- (sub->container_type != DBUS_TYPE_STRUCT &&
- writer->u.array.element_type[0] != sub->container_type))
- {
- _dbus_warn ("Recursing into an array with element type %s not allowed with container type %s\n",
- writer->u.array.element_type, _dbus_type_to_string (sub->container_type));
- }
+ int expected;
- if (sub->container_type == DBUS_TYPE_ARRAY)
+ expected = first_type_in_signature (writer->type_str, writer->type_pos);
+
+ if (expected != sub->container_type)
{
- DBusString parent_elements;
- DBusString our_elements;
-
- _dbus_assert (writer->u.array.element_type[0] == DBUS_TYPE_ARRAY);
-
- _dbus_string_init_const (&parent_elements, &writer->u.array.element_type[1]);
- _dbus_string_init_const (&our_elements, array_element_type);
-
- if (!_dbus_string_equal (&parent_elements, &our_elements))
- {
- _dbus_warn ("Parent array expects elements '%s' and we are writing an array of '%s'\n",
- writer->u.array.element_type,
- array_element_type);
- }
+ _dbus_warn ("Writing an element of type %s, but the expected type here is %s\n",
+ _dbus_type_to_string (sub->container_type),
+ _dbus_type_to_string (expected));
+ _dbus_assert_not_reached ("bad array element written");
}
}
#endif /* DBUS_DISABLE_CHECKS */
- _dbus_verbose (" type writer %p recurse type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
+ _dbus_verbose (" type writer %p recurse parent type_pos = %d value_pos = %d inside_array = %d container_type = %s remaining sig '%s'\n",
writer, writer->type_pos, writer->value_pos, writer->inside_array,
- _dbus_type_to_string (writer->container_type));
- _dbus_verbose (" type writer %p new sub type_pos = %d value_pos = %d inside_array = %d container_type = %s element_type = '%s'\n",
+ _dbus_type_to_string (writer->container_type),
+ _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
+ _dbus_verbose (" type writer %p recurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
sub, sub->type_pos, sub->value_pos,
sub->inside_array,
- _dbus_type_to_string (sub->container_type),
- array_element_type ? array_element_type : "n/a");
+ _dbus_type_to_string (sub->container_type));
+}
+
+static dbus_bool_t
+write_or_verify_typecode (DBusTypeWriter *writer,
+ int typecode)
+{
+ /* A subwriter inside an array will have type_pos pointing to the
+ * expected typecode; a writer not inside an array has type_pos
+ * pointing to the next place to insert a typecode.
+ */
+ _dbus_verbose (" type writer %p write_or_verify start type_pos = %d remaining sig '%s'\n",
+ writer, writer->type_pos,
+ _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
+
+ if (writer->inside_array)
+ {
+#ifndef DBUS_DISABLE_CHECKS
+ {
+ int expected;
+
+ expected = _dbus_string_get_byte (writer->type_str, writer->type_pos);
+
+ if (expected != typecode)
+ {
+ _dbus_warn ("Array type requires that type %s be written, but %s was written\n",
+ _dbus_type_to_string (expected), _dbus_type_to_string (typecode));
+ _dbus_assert_not_reached ("bad type inserted somewhere inside an array");
+ }
+ }
+#endif /* DBUS_DISABLE_CHECKS */
+
+ /* if immediately inside an array we'd always be appending an element,
+ * so the expected type doesn't change; if inside a struct or something
+ * below an array, we need to move through said struct or something.
+ */
+ if (writer->container_type != DBUS_TYPE_ARRAY)
+ writer->type_pos += 1;
+ }
+ else
+ {
+ if (!_dbus_string_insert_byte (writer->type_str,
+ writer->type_pos,
+ typecode))
+ return FALSE;
+
+ writer->type_pos += 1;
+ }
+
+ _dbus_verbose (" type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
+ writer, writer->type_pos,
+ _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
+
+ return TRUE;
}
dbus_bool_t
@@ -645,26 +646,19 @@ _dbus_type_writer_recurse (DBusTypeWriter *writer,
int container_type,
DBusTypeWriter *sub)
{
- writer_recurse_init_and_check (writer, container_type, NULL, sub);
+ writer_recurse_init_and_check (writer, container_type, sub);
switch (container_type)
{
case DBUS_TYPE_STRUCT:
{
- if (!writer->inside_array)
- {
- /* Ensure that we'll be able to add alignment padding */
- if (!_dbus_string_alloc_space (sub->value_str, 8))
- return FALSE;
-
- if (!_dbus_string_insert_byte (sub->type_str,
- sub->type_pos,
- DBUS_STRUCT_BEGIN_CHAR))
- return FALSE;
-
- sub->type_pos += 1;
- }
+ /* Ensure that we'll be able to add alignment padding and the typecode */
+ if (!_dbus_string_alloc_space (sub->value_str, 8))
+ return FALSE;
+ if (!write_or_verify_typecode (sub, DBUS_STRUCT_BEGIN_CHAR))
+ _dbus_assert_not_reached ("failed to insert struct typecode after prealloc");
+
if (!_dbus_string_insert_bytes (sub->value_str,
sub->value_pos,
_DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
@@ -691,9 +685,34 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
{
int element_type_len;
DBusString element_type_str;
+ dbus_uint32_t value = 0;
+ int alignment;
+ int aligned;
+ DBusString str;
- writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, element_type, sub);
+ writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, sub);
+
+#ifndef DBUS_DISABLE_CHECKS
+ if (writer->container_type == DBUS_TYPE_ARRAY)
+ {
+ DBusString parent_elements;
+ _dbus_assert (element_type != NULL);
+
+ _dbus_string_init_const (&parent_elements,
+ _dbus_string_get_const_data_len (writer->type_str,
+ writer->u.array.element_type_pos + 1,
+ 0));
+
+ if (!_dbus_string_starts_with_c_str (&parent_elements, element_type))
+ {
+ _dbus_warn ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
+ element_type);
+ _dbus_assert_not_reached ("incompatible type for child array");
+ }
+ }
+#endif /* DBUS_DISABLE_CHECKS */
+
_dbus_string_init_const (&element_type_str, element_type);
element_type_len = _dbus_string_get_length (&element_type_str);
@@ -701,71 +720,64 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
if (!_dbus_string_alloc_space (sub->value_str, 8))
return FALSE;
+ sub->type_pos += 1; /* move to point to the element type, since type_pos
+ * should be the expected type for further writes
+ */
+ sub->u.array.element_type_pos = sub->type_pos;
+ sub->u.array.element_type_len = element_type_len;
+
if (!writer->inside_array)
{
+ /* sub is a toplevel/outermost array so we need to write the type data */
+
/* alloc space for array typecode, element signature, possible 7
* bytes of padding
*/
- if (!_dbus_string_alloc_space (sub->type_str, 1 + element_type_len + 7))
+ if (!_dbus_string_alloc_space (writer->type_str, 1 + element_type_len + 7))
return FALSE;
- }
-
- if (!_dbus_string_copy_data (&element_type_str,
- &sub->u.array.element_type))
- return FALSE;
- if (!writer->inside_array)
- {
- if (!_dbus_string_insert_byte (sub->type_str,
- sub->type_pos,
+ if (!_dbus_string_insert_byte (writer->type_str,
+ writer->type_pos,
DBUS_TYPE_ARRAY))
- _dbus_assert_not_reached ("should not have failed to insert array typecode");
+ _dbus_assert_not_reached ("failed to insert array typecode after prealloc");
- sub->type_pos += 1;
-
if (!_dbus_string_copy (&element_type_str, 0,
- sub->type_str, sub->type_pos))
+ sub->type_str, sub->u.array.element_type_pos))
_dbus_assert_not_reached ("should not have failed to insert array element typecodes");
-
- sub->type_pos += element_type_len;
}
-
+
+ /* Write the length */
sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
- {
- dbus_uint32_t value = 0;
- int alignment;
- int aligned;
- DBusString str;
-
- if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
- &value))
- _dbus_assert_not_reached ("should not have failed to insert array len");
-
- _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);
-
- _dbus_string_init_const (&str, element_type);
- alignment = element_type_get_alignment (&str, 0);
-
- aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
- if (aligned != sub->value_pos)
- {
- if (!_dbus_string_insert_bytes (sub->value_str,
- sub->value_pos,
- aligned - sub->value_pos,
- '\0'))
- _dbus_assert_not_reached ("should not have failed to insert alignment padding");
+ if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
+ &value))
+ _dbus_assert_not_reached ("should not have failed to insert array len");
+
+ _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);
- sub->value_pos = aligned;
- }
- sub->u.array.start_pos = sub->value_pos;
- }
+ /* Write alignment padding for array elements */
+ _dbus_string_init_const (&str, element_type);
+ alignment = element_type_get_alignment (&str, 0);
+
+ aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
+ if (aligned != sub->value_pos)
+ {
+ if (!_dbus_string_insert_bytes (sub->value_str,
+ sub->value_pos,
+ aligned - sub->value_pos,
+ '\0'))
+ _dbus_assert_not_reached ("should not have failed to insert alignment padding");
+
+ sub->value_pos = aligned;
+ }
+ sub->u.array.start_pos = sub->value_pos;
_dbus_assert (sub->u.array.start_pos == sub->value_pos);
_dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
-
- /* value_pos now points to the place for array data, and len_pos to the length */
+ _dbus_verbose (" type writer %p recurse array done remaining sig '%s'\n", sub,
+ _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
+
return TRUE;
}
@@ -778,30 +790,19 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
_dbus_verbose (" type writer %p unrecurse type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
writer, writer->type_pos, writer->value_pos, writer->inside_array,
_dbus_type_to_string (writer->container_type));
- _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s element_type = '%s'\n",
+ _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",
sub, sub->type_pos, sub->value_pos,
sub->inside_array,
- _dbus_type_to_string (sub->container_type),
- sub->container_type == DBUS_TYPE_ARRAY ?
- sub->u.array.element_type : "n/a");
+ _dbus_type_to_string (sub->container_type));
if (sub->container_type == DBUS_TYPE_STRUCT)
{
- if (!sub->inside_array)
- {
- if (!_dbus_string_insert_byte (sub->type_str,
- sub->type_pos,
- DBUS_STRUCT_END_CHAR))
- return FALSE;
- sub->type_pos += 1;
- }
+ if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
+ return FALSE;
}
else if (sub->container_type == DBUS_TYPE_ARRAY)
{
dbus_uint32_t len;
-
- dbus_free (sub->u.array.element_type);
- sub->u.array.element_type = NULL;
/* Set the array length */
len = sub->value_pos - sub->u.array.start_pos;
@@ -814,12 +815,68 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
}
/* Jump the parent writer to the new location */
- writer->type_pos = sub->type_pos;
+ if (!writer->inside_array)
+ {
+ if (sub->inside_array)
+ {
+ /* Transition back to type_pos = insertion point from type_pos = expected */
+
+ _dbus_assert (sub->container_type == DBUS_TYPE_ARRAY);
+ writer->type_pos = sub->u.array.element_type_pos + sub->u.array.element_type_len;
+ }
+ else
+ {
+ writer->type_pos = sub->type_pos;
+ }
+ }
writer->value_pos = sub->value_pos;
+
+
+ _dbus_verbose (" type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n",
+ writer, writer->type_pos, writer->value_pos,
+ _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
return TRUE;
}
+dbus_bool_t
+_dbus_type_writer_write_basic (DBusTypeWriter *writer,
+ int type,
+ const void *value)
+{
+ dbus_bool_t retval;
+
+ /* First ensure that our type realloc will succeed */
+ if (!_dbus_string_alloc_space (writer->type_str, 1))
+ return FALSE;
+
+ retval = FALSE;
+
+ if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
+ goto out;
+
+ if (!write_or_verify_typecode (writer, type))
+ _dbus_assert_not_reached ("failed to write typecode after prealloc");
+
+ retval = TRUE;
+
+ out:
+ _dbus_verbose (" type writer %p basic type_pos = %d value_pos = %d inside_array = %d\n",
+ writer, writer->type_pos, writer->value_pos, writer->inside_array);
+
+ return retval;
+}
+
+dbus_bool_t
+_dbus_type_writer_write_array (DBusTypeWriter *writer,
+ int type,
+ const void *array,
+ int array_len)
+{
+
+
+}
+
/** @} */ /* end of DBusMarshal group */
#ifdef DBUS_BUILD_TESTS
@@ -905,21 +962,21 @@ data_block_init_reader_writer (DataBlock *block,
_dbus_string_get_length (&block->body));
}
-#define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
- { \
- _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d", \
- _DBUS_FUNCTION_NAME, __LINE__); \
- _dbus_assert_not_reached ("test failed"); \
- } \
+#define NEXT_EXPECTING_TRUE(reader) do { if (!_dbus_type_reader_next (reader)) \
+ { \
+ _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n", \
+ _DBUS_FUNCTION_NAME, __LINE__); \
+ _dbus_assert_not_reached ("test failed"); \
+ } \
} while (0)
-#define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
- { \
- _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d", \
- _DBUS_FUNCTION_NAME, __LINE__); \
- _dbus_assert_not_reached ("test failed"); \
- } \
- check_expected_type (reader, DBUS_TYPE_INVALID); \
+#define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader)) \
+ { \
+ _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n", \
+ _DBUS_FUNCTION_NAME, __LINE__); \
+ _dbus_assert_not_reached ("test failed"); \
+ } \
+ check_expected_type (reader, DBUS_TYPE_INVALID); \
} while (0)
#define SAMPLE_INT32 12345678
@@ -951,11 +1008,6 @@ real_check_expected_type (DBusTypeReader *reader,
_dbus_type_to_string (t),
_dbus_type_to_string (expected),
funcname, line);
-
- _dbus_verbose_bytes_of_string (reader->type_str, 0,
- _dbus_string_get_length (reader->type_str));
- _dbus_verbose_bytes_of_string (reader->value_str, 0,
- _dbus_string_get_length (reader->value_str));
exit (1);
}
@@ -980,8 +1032,8 @@ read_int32 (DataBlock *block,
}
static dbus_bool_t
-write_struct_with_int32s (DataBlock *block,
- DBusTypeWriter *writer)
+write_struct_of_int32 (DataBlock *block,
+ DBusTypeWriter *writer)
{
dbus_int32_t v;
DataBlockState saved;
@@ -1022,8 +1074,8 @@ write_struct_with_int32s (DataBlock *block,
}
static dbus_bool_t
-read_struct_with_int32s (DataBlock *block,
- DBusTypeReader *reader)
+read_struct_of_int32 (DataBlock *block,
+ DBusTypeReader *reader)
{
dbus_int32_t v;
DBusTypeReader sub;
@@ -1066,17 +1118,17 @@ write_struct_of_structs (DataBlock *block,
&sub))
return FALSE;
- if (!write_struct_with_int32s (block, &sub))
+ if (!write_struct_of_int32 (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!write_struct_with_int32s (block, &sub))
+ if (!write_struct_of_int32 (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!write_struct_with_int32s (block, &sub))
+ if (!write_struct_of_int32 (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
@@ -1101,15 +1153,15 @@ read_struct_of_structs (DataBlock *block,
_dbus_type_reader_recurse (reader, &sub);
- if (!read_struct_with_int32s (block, &sub))
+ if (!read_struct_of_int32 (block, &sub))
return FALSE;
NEXT_EXPECTING_TRUE (&sub);
- if (!read_struct_with_int32s (block, &sub))
+ if (!read_struct_of_int32 (block, &sub))
return FALSE;
NEXT_EXPECTING_TRUE (&sub);
- if (!read_struct_with_int32s (block, &sub))
+ if (!read_struct_of_int32 (block, &sub))
return FALSE;
NEXT_EXPECTING_FALSE (&sub);
@@ -1484,10 +1536,143 @@ read_array_of_array_of_array_of_int32 (DataBlock *block,
return TRUE;
}
+static dbus_bool_t
+write_struct_of_array_of_int32 (DataBlock *block,
+ DBusTypeWriter *writer)
+{
+ DataBlockState saved;
+ DBusTypeWriter sub;
+
+ data_block_save (block, &saved);
+
+ if (!_dbus_type_writer_recurse (writer,
+ DBUS_TYPE_STRUCT,
+ &sub))
+ return FALSE;
+
+ if (!write_array_of_int32 (block, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ if (!write_array_of_int32_empty (block, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ if (!_dbus_type_writer_unrecurse (writer, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static dbus_bool_t
+read_struct_of_array_of_int32 (DataBlock *block,
+ DBusTypeReader *reader)
+{
+ DBusTypeReader sub;
+
+ check_expected_type (reader, DBUS_TYPE_STRUCT);
+
+ _dbus_type_reader_recurse (reader, &sub);
+
+ check_expected_type (&sub, DBUS_TYPE_ARRAY);
+
+ if (!read_array_of_int32 (block, &sub))
+ return FALSE;
+
+ NEXT_EXPECTING_TRUE (&sub);
+ if (!read_array_of_int32_empty (block, &sub))
+ return FALSE;
+
+ NEXT_EXPECTING_FALSE (&sub);
+
+ return TRUE;
+}
+
+static dbus_bool_t
+write_array_of_struct_of_int32 (DataBlock *block,
+ DBusTypeWriter *writer)
+{
+ DataBlockState saved;
+ DBusTypeWriter sub;
+
+ data_block_save (block, &saved);
+
+ if (!_dbus_type_writer_recurse_array (writer,
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_INT32_AS_STRING
+ DBUS_TYPE_INT32_AS_STRING
+ DBUS_STRUCT_END_CHAR_AS_STRING,
+ &sub))
+ return FALSE;
+
+ if (!write_struct_of_int32 (block, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ if (!write_struct_of_int32 (block, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ if (!write_struct_of_int32 (block, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ if (!_dbus_type_writer_unrecurse (writer, &sub))
+ {
+ data_block_restore (block, &saved);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static dbus_bool_t
+read_array_of_struct_of_int32 (DataBlock *block,
+ DBusTypeReader *reader)
+{
+ DBusTypeReader sub;
+
+ check_expected_type (reader, DBUS_TYPE_ARRAY);
+
+ _dbus_type_reader_recurse (reader, &sub);
+
+ check_expected_type (&sub, DBUS_TYPE_STRUCT);
+
+ if (!read_struct_of_int32 (block, &sub))
+ return FALSE;
+
+ NEXT_EXPECTING_TRUE (&sub);
+
+ if (!read_struct_of_int32 (block, &sub))
+ return FALSE;
+
+ NEXT_EXPECTING_TRUE (&sub);
+
+ if (!read_struct_of_int32 (block, &sub))
+ return FALSE;
+
+ NEXT_EXPECTING_FALSE (&sub);
+
+ return TRUE;
+}
+
typedef enum {
ITEM_INVALID = -1,
ITEM_INT32 = 0,
- ITEM_STRUCT_WITH_INT32S,
+ ITEM_STRUCT_OF_INT32,
ITEM_STRUCT_OF_STRUCTS,
ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
ITEM_ARRAY_OF_INT32,
@@ -1495,6 +1680,8 @@ typedef enum {
ITEM_ARRAY_OF_ARRAY_OF_INT32,
ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,
ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
+ ITEM_STRUCT_OF_ARRAY_OF_INT32,
+ ITEM_ARRAY_OF_STRUCT_OF_INT32,
ITEM_LAST
} WhichItem;
@@ -1516,7 +1703,7 @@ static CheckMarshalItem items[] = {
{ "int32",
ITEM_INT32, write_int32, read_int32 },
{ "struct with two int32",
- ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s },
+ ITEM_STRUCT_OF_INT32, write_struct_of_int32, read_struct_of_int32 },
{ "struct with three structs of two int32",
ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
{ "struct of two structs of three structs of two int32",
@@ -1535,7 +1722,11 @@ static CheckMarshalItem items[] = {
write_array_of_array_of_int32_empty, read_array_of_array_of_int32_empty },
{ "array of array of array of int32",
ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32,
- write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 }
+ write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 },
+ { "struct of array of int32",
+ ITEM_STRUCT_OF_ARRAY_OF_INT32, write_struct_of_array_of_int32, read_struct_of_array_of_int32 },
+ { "array of struct of int32",
+ ITEM_ARRAY_OF_STRUCT_OF_INT32, write_array_of_struct_of_int32, read_array_of_struct_of_int32 },
};
typedef struct
@@ -1552,18 +1743,18 @@ static TestRun runs[] = {
{ { ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INVALID } },
- /* STRUCT_WITH_INT32S */
- { { ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } },
- { { ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } },
- { { ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } },
+ /* STRUCT_OF_INT32 */
+ { { ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },
/* STRUCT_OF_STRUCTS */
{ { ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },
@@ -1571,7 +1762,7 @@ static TestRun runs[] = {
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
@@ -1584,7 +1775,7 @@ static TestRun runs[] = {
{ { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
{ { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },
/* ARRAY_OF_ARRAY_OF_INT32 */
@@ -1596,7 +1787,7 @@ static TestRun runs[] = {
{ { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
{ { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
/* ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32 */
@@ -1608,9 +1799,24 @@ static TestRun runs[] = {
{ { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
{ { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
{ { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },
- { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
- { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } }
-
+ { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+
+ /* STRUCT_OF_ARRAY_OF_INT32 */
+ { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } },
+
+ /* ARRAY_OF_STRUCT_OF_INT32 */
+ { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } },
+ { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }
};
@@ -1664,6 +1870,13 @@ perform_one_run (DataBlock *block,
{
CheckMarshalItem *item = &items[run->items[i]];
+ _dbus_verbose (">>data for reading %s\n", item->desc);
+
+ _dbus_verbose_bytes_of_string (reader.type_str, 0,
+ _dbus_string_get_length (reader.type_str));
+ _dbus_verbose_bytes_of_string (reader.value_str, 0,
+ _dbus_string_get_length (reader.value_str));
+
_dbus_verbose (">>reading %s\n", item->desc);
if (!(* item->read_item_func) (block, &reader))