}
static void
-struct_types_only_reader_recurse (DBusTypeReader *sub,
- DBusTypeReader *parent)
+struct_or_dict_entry_types_only_reader_recurse (DBusTypeReader *sub,
+ DBusTypeReader *parent)
{
base_reader_recurse (sub, parent);
-
+
_dbus_assert (_dbus_string_get_byte (sub->type_str,
- sub->type_pos) == DBUS_STRUCT_BEGIN_CHAR);
+ sub->type_pos) == DBUS_STRUCT_BEGIN_CHAR ||
+ _dbus_string_get_byte (sub->type_str,
+ sub->type_pos) == DBUS_DICT_ENTRY_BEGIN_CHAR);
sub->type_pos += 1;
}
static void
-struct_reader_recurse (DBusTypeReader *sub,
- DBusTypeReader *parent)
+struct_or_dict_entry_reader_recurse (DBusTypeReader *sub,
+ DBusTypeReader *parent)
{
- struct_types_only_reader_recurse (sub, parent);
+ struct_or_dict_entry_types_only_reader_recurse (sub, parent);
- /* struct has 8 byte alignment */
+ /* struct and dict entry have 8 byte alignment */
sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
}
p = start + *type_pos;
_dbus_assert (*p != DBUS_STRUCT_END_CHAR);
+ _dbus_assert (*p != DBUS_DICT_ENTRY_END_CHAR);
while (*p == DBUS_TYPE_ARRAY)
++p;
_dbus_assert (*p != DBUS_STRUCT_END_CHAR);
+ _dbus_assert (*p != DBUS_DICT_ENTRY_END_CHAR);
if (*p == DBUS_STRUCT_BEGIN_CHAR)
{
}
}
}
+ else if (*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
+ {
+ int depth;
+
+ depth = 1;
+
+ while (TRUE)
+ {
+ _dbus_assert (*p != DBUS_TYPE_INVALID);
+
+ ++p;
+
+ _dbus_assert (*p != DBUS_TYPE_INVALID);
+
+ if (*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
+ depth += 1;
+ else if (*p == DBUS_DICT_ENTRY_END_CHAR)
+ {
+ depth -= 1;
+ if (depth == 0)
+ {
+ ++p;
+ break;
+ }
+ }
+ }
+ }
else
{
++p;
{
switch (current_type)
{
+ case DBUS_TYPE_DICT_ENTRY:
case DBUS_TYPE_STRUCT:
case DBUS_TYPE_VARIANT:
/* Scan forward over the entire container contents */
}
static void
+dict_entry_reader_next (DBusTypeReader *reader,
+ int current_type)
+{
+ int t;
+
+ base_reader_next (reader, current_type);
+
+ /* for STRUCT containers we return FALSE at the end of the struct,
+ * for INVALID we return FALSE at the end of the signature.
+ * In both cases we arrange for get_current_type() to return INVALID
+ * which is defined to happen iff we're at the end (no more next())
+ */
+ t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+ if (t == DBUS_DICT_ENTRY_END_CHAR)
+ {
+ reader->type_pos += 1;
+ reader->finished = TRUE;
+ }
+}
+
+static void
array_types_only_reader_next (DBusTypeReader *reader,
int current_type)
{
switch (_dbus_first_type_in_signature (reader->type_str,
reader->type_pos))
{
+ case DBUS_TYPE_DICT_ENTRY:
case DBUS_TYPE_STRUCT:
case DBUS_TYPE_VARIANT:
{
static const DBusTypeReaderClass struct_reader_class = {
"struct", 2,
FALSE,
- struct_reader_recurse,
+ struct_or_dict_entry_reader_recurse,
NULL,
struct_reader_next,
NULL
static const DBusTypeReaderClass struct_types_only_reader_class = {
"struct types", 3,
TRUE,
- struct_types_only_reader_recurse,
+ struct_or_dict_entry_types_only_reader_recurse,
NULL,
struct_reader_next,
NULL
};
+static const DBusTypeReaderClass dict_entry_reader_class = {
+ "dict_entry", 4,
+ FALSE,
+ struct_or_dict_entry_reader_recurse,
+ NULL,
+ dict_entry_reader_next,
+ NULL
+};
+
+static const DBusTypeReaderClass dict_entry_types_only_reader_class = {
+ "dict_entry types", 5,
+ TRUE,
+ struct_or_dict_entry_types_only_reader_recurse,
+ NULL,
+ dict_entry_reader_next,
+ NULL
+};
+
static const DBusTypeReaderClass array_reader_class = {
- "array", 4,
+ "array", 6,
FALSE,
array_reader_recurse,
array_reader_check_finished,
};
static const DBusTypeReaderClass array_types_only_reader_class = {
- "array types", 5,
+ "array types", 7,
TRUE,
array_types_only_reader_recurse,
NULL,
};
static const DBusTypeReaderClass variant_reader_class = {
- "variant", 6,
+ "variant", 8,
FALSE,
variant_reader_recurse,
NULL,
&body_types_only_reader_class,
&struct_reader_class,
&struct_types_only_reader_class,
+ &dict_entry_reader_class,
+ &dict_entry_types_only_reader_class,
&array_reader_class,
&array_types_only_reader_class,
&variant_reader_class
t = DBUS_TYPE_INVALID;
else
t = _dbus_first_type_in_signature (reader->type_str,
- reader->type_pos);
+ reader->type_pos);
_dbus_assert (t != DBUS_STRUCT_END_CHAR);
_dbus_assert (t != DBUS_STRUCT_BEGIN_CHAR);
-
+ _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR);
+ _dbus_assert (t != DBUS_DICT_ENTRY_BEGIN_CHAR);
+
#if 0
_dbus_verbose (" type reader %p current type_pos = %d type = %s\n",
reader, reader->type_pos,
else
sub->klass = &struct_reader_class;
break;
+ case DBUS_TYPE_DICT_ENTRY:
+ if (reader->klass->types_only)
+ sub->klass = &dict_entry_types_only_reader_class;
+ else
+ sub->klass = &dict_entry_reader_class;
+ break;
case DBUS_TYPE_ARRAY:
if (reader->klass->types_only)
sub->klass = &array_types_only_reader_class;
}
static dbus_bool_t
-writer_recurse_struct (DBusTypeWriter *writer,
- const DBusString *contained_type,
- int contained_type_start,
- int contained_type_len,
- DBusTypeWriter *sub)
+writer_recurse_struct_or_dict_entry (DBusTypeWriter *writer,
+ int begin_char,
+ const DBusString *contained_type,
+ int contained_type_start,
+ int contained_type_len,
+ DBusTypeWriter *sub)
{
/* FIXME right now contained_type is ignored; we could probably
* almost trivially fix the code so if it's present we
return FALSE;
}
- if (!write_or_verify_typecode (sub, DBUS_STRUCT_BEGIN_CHAR))
+ if (!write_or_verify_typecode (sub, begin_char))
_dbus_assert_not_reached ("failed to insert struct typecode after prealloc");
if (writer->enabled)
switch (container_type)
{
case DBUS_TYPE_STRUCT:
- return writer_recurse_struct (writer,
- contained_type, contained_type_start, contained_type_len,
- sub);
+ return writer_recurse_struct_or_dict_entry (writer,
+ DBUS_STRUCT_BEGIN_CHAR,
+ contained_type,
+ contained_type_start, contained_type_len,
+ sub);
+ break;
+ case DBUS_TYPE_DICT_ENTRY:
+ return writer_recurse_struct_or_dict_entry (writer,
+ DBUS_DICT_ENTRY_BEGIN_CHAR,
+ contained_type,
+ contained_type_start, contained_type_len,
+ sub);
break;
case DBUS_TYPE_ARRAY:
return writer_recurse_array (writer,
if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
return FALSE;
}
+ else if (sub->container_type == DBUS_TYPE_DICT_ENTRY)
+ {
+ if (!write_or_verify_typecode (sub, DBUS_DICT_ENTRY_END_CHAR))
+ return FALSE;
+ }
else if (sub->container_type == DBUS_TYPE_ARRAY)
{
if (sub->u.array.len_pos >= 0) /* len_pos == -1 if we weren't enabled when we passed it */
* parent makes no difference since there's only one value
* and we just finished writing it and won't use type_pos again
* writer->type_pos should remain as-is
+ *
+ *
+ * For all these, DICT_ENTRY is the same as STRUCT
*/
if (writer->type_str != NULL)
{
- if (sub->container_type == DBUS_TYPE_STRUCT &&
+ if ((sub->container_type == DBUS_TYPE_STRUCT ||
+ sub->container_type == DBUS_TYPE_DICT_ENTRY) &&
(writer->container_type == DBUS_TYPE_STRUCT ||
+ writer->container_type == DBUS_TYPE_DICT_ENTRY ||
writer->container_type == DBUS_TYPE_INVALID))
{
/* Advance the parent to the next struct field */