mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-07 13:18:01 +02:00
arrays are working, woot
This commit is contained in:
parent
7debfd9ff5
commit
d9afb9b5f1
2 changed files with 126 additions and 57 deletions
|
|
@ -127,12 +127,24 @@ _dbus_type_reader_get_current_type (DBusTypeReader *reader)
|
|||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
_dbus_type_reader_get_array_length (DBusTypeReader *reader)
|
||||
dbus_bool_t
|
||||
_dbus_type_reader_array_is_empty (DBusTypeReader *reader)
|
||||
{
|
||||
/* FIXME if this is in number of elements I don't know how to compute it
|
||||
* since we only have bytes and elements are variable-length
|
||||
*/
|
||||
dbus_uint32_t array_len;
|
||||
int len_pos;
|
||||
|
||||
_dbus_return_val_if_fail (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY,
|
||||
TRUE);
|
||||
|
||||
len_pos = _DBUS_ALIGN_VALUE (reader->value_pos, 4);
|
||||
|
||||
_dbus_demarshal_basic_type (reader->value_str,
|
||||
DBUS_TYPE_UINT32,
|
||||
&array_len,
|
||||
reader->byte_order,
|
||||
&len_pos);
|
||||
|
||||
return array_len == 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -184,6 +196,10 @@ _dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
|
|||
* Initialize a new reader pointing to the first type and
|
||||
* corresponding value that's a child of the current container. It's
|
||||
* an error to call this if the current type is a non-container.
|
||||
*
|
||||
* Note that DBusTypeReader traverses values, not types. So if you
|
||||
* have an empty array of array of int, you can't recurse into it. You
|
||||
* can only recurse into each element.
|
||||
*
|
||||
* @param reader the reader
|
||||
* @param sub a reader to init pointing to the first child
|
||||
|
|
@ -193,16 +209,6 @@ _dbus_type_reader_recurse (DBusTypeReader *reader,
|
|||
DBusTypeReader *sub)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* FIXME are we recursing over the type signature or over the values.
|
||||
* Arrays don't necessarily have values for each element of the type
|
||||
* signature. Thus we get a mismatch where we need to "bail out" and
|
||||
* return the signature of each element, but can't return an element
|
||||
* or recurse into the element signature. Not sure how to handle this;
|
||||
* maybe think about how we will handle variant types and do something
|
||||
* similar since they also have the idea of a signature for the whole
|
||||
* sub-item?
|
||||
*/
|
||||
|
||||
t = first_type_in_signature (reader->type_str, reader->type_pos);
|
||||
|
||||
|
|
@ -230,6 +236,8 @@ _dbus_type_reader_recurse (DBusTypeReader *reader,
|
|||
dbus_uint32_t array_len;
|
||||
int alignment;
|
||||
|
||||
_dbus_return_if_fail (!_dbus_type_reader_array_is_empty (reader));
|
||||
|
||||
sub->container_type = DBUS_TYPE_ARRAY;
|
||||
|
||||
/* point type_pos at the array element type */
|
||||
|
|
@ -307,6 +315,25 @@ skip_one_complete_type (const DBusString *type_str,
|
|||
*type_pos += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
skip_array_values (const DBusString *value_str,
|
||||
int *value_pos,
|
||||
int byte_order)
|
||||
{
|
||||
dbus_uint32_t array_len;
|
||||
int len_pos;
|
||||
|
||||
len_pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
|
||||
|
||||
_dbus_demarshal_basic_type (value_str,
|
||||
DBUS_TYPE_UINT32,
|
||||
&array_len,
|
||||
byte_order,
|
||||
&len_pos);
|
||||
|
||||
*value_pos = len_pos + array_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip to the next value on this "level". e.g. the next field in a
|
||||
* struct, the next value in an array, the next key or value in a
|
||||
|
|
@ -336,11 +363,7 @@ _dbus_type_reader_next (DBusTypeReader *reader)
|
|||
switch (t)
|
||||
{
|
||||
case DBUS_TYPE_STRUCT:
|
||||
case DBUS_TYPE_ARRAY:
|
||||
/* Scan forward over the entire container contents */
|
||||
/* FIXME this is super slow for arrays. We need to special
|
||||
* case skipping all the elements at once instead of scanning.
|
||||
*/
|
||||
{
|
||||
DBusTypeReader sub;
|
||||
|
||||
|
|
@ -358,6 +381,13 @@ _dbus_type_reader_next (DBusTypeReader *reader)
|
|||
reader->value_pos = sub.value_pos;
|
||||
}
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_ARRAY:
|
||||
{
|
||||
skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order);
|
||||
skip_one_complete_type (reader->type_str, &reader->type_pos);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_dbus_marshal_skip_basic_type (reader->value_str,
|
||||
|
|
@ -392,12 +422,11 @@ _dbus_type_reader_next (DBusTypeReader *reader)
|
|||
_dbus_assert (reader->value_pos < end_pos);
|
||||
_dbus_assert (reader->value_pos >= reader->u.array.start_pos);
|
||||
|
||||
if (reader->u.array.element_type == DBUS_TYPE_ARRAY ||
|
||||
reader->u.array.element_type == DBUS_TYPE_STRUCT)
|
||||
if (reader->u.array.element_type == DBUS_TYPE_STRUCT)
|
||||
{
|
||||
DBusTypeReader sub;
|
||||
|
||||
/* Recurse into the array element */
|
||||
/* Recurse into the struct */
|
||||
_dbus_type_reader_recurse (reader, &sub);
|
||||
|
||||
/* Skip everything in this element */
|
||||
|
|
@ -409,6 +438,10 @@ _dbus_type_reader_next (DBusTypeReader *reader)
|
|||
/* Now we are at the end of this element */
|
||||
reader->value_pos = sub.value_pos;
|
||||
}
|
||||
else if (reader->u.array.element_type == DBUS_TYPE_ARRAY)
|
||||
{
|
||||
skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbus_marshal_skip_basic_type (reader->value_str,
|
||||
|
|
@ -697,7 +730,7 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
|
|||
sub->type_pos += element_type_len;
|
||||
}
|
||||
|
||||
sub->u.array.len_pos = sub->value_pos;
|
||||
sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
|
||||
|
||||
{
|
||||
dbus_uint32_t value = 0;
|
||||
|
|
@ -709,6 +742,8 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,
|
|||
&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);
|
||||
|
||||
|
|
@ -870,6 +905,23 @@ 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"); \
|
||||
} \
|
||||
} 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); \
|
||||
} while (0)
|
||||
|
||||
#define SAMPLE_INT32 12345678
|
||||
#define SAMPLE_INT32_ALTERNATE 53781429
|
||||
static dbus_bool_t
|
||||
|
|
@ -884,8 +936,10 @@ write_int32 (DataBlock *block,
|
|||
}
|
||||
|
||||
static void
|
||||
check_expected_type (DBusTypeReader *reader,
|
||||
int expected)
|
||||
real_check_expected_type (DBusTypeReader *reader,
|
||||
int expected,
|
||||
const char *funcname,
|
||||
int line)
|
||||
{
|
||||
int t;
|
||||
|
||||
|
|
@ -893,9 +947,10 @@ check_expected_type (DBusTypeReader *reader,
|
|||
|
||||
if (t != expected)
|
||||
{
|
||||
_dbus_warn ("Read type %s while expecting %s\n",
|
||||
_dbus_warn ("Read type %s while expecting %s at %s line %d\n",
|
||||
_dbus_type_to_string (t),
|
||||
_dbus_type_to_string (expected));
|
||||
_dbus_type_to_string (expected),
|
||||
funcname, line);
|
||||
|
||||
_dbus_verbose_bytes_of_string (reader->type_str, 0,
|
||||
_dbus_string_get_length (reader->type_str));
|
||||
|
|
@ -906,6 +961,8 @@ check_expected_type (DBusTypeReader *reader,
|
|||
}
|
||||
}
|
||||
|
||||
#define check_expected_type(reader, expected) real_check_expected_type (reader, expected, _DBUS_FUNCTION_NAME, __LINE__)
|
||||
|
||||
static dbus_bool_t
|
||||
read_int32 (DataBlock *block,
|
||||
DBusTypeReader *reader)
|
||||
|
|
@ -982,13 +1039,15 @@ read_struct_with_int32s (DataBlock *block,
|
|||
|
||||
_dbus_assert (v == SAMPLE_INT32);
|
||||
|
||||
_dbus_type_reader_next (&sub);
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
check_expected_type (&sub, DBUS_TYPE_INT32);
|
||||
|
||||
_dbus_type_reader_read_basic (&sub,
|
||||
(dbus_int32_t*) &v);
|
||||
|
||||
_dbus_assert (v == SAMPLE_INT32_ALTERNATE);
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1044,13 +1103,17 @@ read_struct_of_structs (DataBlock *block,
|
|||
|
||||
if (!read_struct_with_int32s (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_struct_with_int32s (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_struct_with_int32s (block, &sub))
|
||||
return FALSE;
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1100,9 +1163,12 @@ read_struct_of_structs_of_structs (DataBlock *block,
|
|||
|
||||
if (!read_struct_of_structs (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_struct_of_structs (block, &sub))
|
||||
return FALSE;
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1176,7 +1242,7 @@ read_array_of_int32 (DataBlock *block,
|
|||
|
||||
_dbus_assert (v == SAMPLE_INT32_ALTERNATE);
|
||||
|
||||
_dbus_type_reader_next (&sub);
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
check_expected_type (&sub, DBUS_TYPE_INT32);
|
||||
|
||||
_dbus_type_reader_read_basic (&sub,
|
||||
|
|
@ -1184,13 +1250,15 @@ read_array_of_int32 (DataBlock *block,
|
|||
|
||||
_dbus_assert (v == SAMPLE_INT32);
|
||||
|
||||
_dbus_type_reader_next (&sub);
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
check_expected_type (&sub, DBUS_TYPE_INT32);
|
||||
|
||||
_dbus_type_reader_read_basic (&sub,
|
||||
(dbus_int32_t*) &v);
|
||||
|
||||
_dbus_assert (v == SAMPLE_INT32);
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1223,13 +1291,12 @@ static dbus_bool_t
|
|||
read_array_of_int32_empty (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_INVALID);
|
||||
/* We are iterating over values not types. Thus we can't recurse
|
||||
* into the array
|
||||
*/
|
||||
_dbus_assert (_dbus_type_reader_array_is_empty (reader));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1293,16 +1360,20 @@ read_array_of_array_of_int32 (DataBlock *block,
|
|||
|
||||
if (!read_array_of_int32 (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_array_of_int32 (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_array_of_int32_empty (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_array_of_int32 (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1334,19 +1405,14 @@ write_array_of_array_of_int32_empty (DataBlock *block,
|
|||
static dbus_bool_t
|
||||
read_array_of_array_of_int32_empty (DataBlock *block,
|
||||
DBusTypeReader *reader)
|
||||
{
|
||||
DBusTypeReader sub;
|
||||
DBusTypeReader sub2;
|
||||
|
||||
check_expected_type (reader, DBUS_TYPE_ARRAY);
|
||||
|
||||
_dbus_type_reader_recurse (reader, &sub);
|
||||
|
||||
{
|
||||
check_expected_type (reader, DBUS_TYPE_ARRAY);
|
||||
|
||||
_dbus_type_reader_recurse (&sub, &sub2);
|
||||
|
||||
check_expected_type (reader, DBUS_TYPE_INVALID);
|
||||
/* We are iterating over values, not types. Thus
|
||||
* we can't recurse in here.
|
||||
*/
|
||||
|
||||
_dbus_assert (_dbus_type_reader_array_is_empty (reader));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1404,13 +1470,16 @@ read_array_of_array_of_array_of_int32 (DataBlock *block,
|
|||
|
||||
if (!read_array_of_array_of_int32 (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_array_of_array_of_int32 (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_TRUE (&sub);
|
||||
if (!read_array_of_array_of_int32_empty (block, &sub))
|
||||
return FALSE;
|
||||
_dbus_type_reader_next (&sub);
|
||||
|
||||
NEXT_EXPECTING_FALSE (&sub);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void _dbus_type_reader_init (DBusTypeReader *reader,
|
|||
const DBusString *value_str,
|
||||
int value_pos);
|
||||
int _dbus_type_reader_get_current_type (DBusTypeReader *reader);
|
||||
int _dbus_type_reader_get_array_length (DBusTypeReader *reader);
|
||||
dbus_bool_t _dbus_type_reader_array_is_empty (DBusTypeReader *reader);
|
||||
void _dbus_type_reader_read_basic (DBusTypeReader *reader,
|
||||
void *value);
|
||||
dbus_bool_t _dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue