25 #include "dbus-marshal-recursive.h" 26 #include "dbus-marshal-basic.h" 27 #include "dbus-signature.h" 28 #include "dbus-internals.h" 43 int start_after_new_pos,
44 int start_after_new_len,
48 #define RECURSIVE_MARSHAL_READ_TRACE 0 51 #define RECURSIVE_MARSHAL_WRITE_TRACE 0 75 apply_and_free_fixups (
DBusList **fixups,
80 #if RECURSIVE_MARSHAL_WRITE_TRACE 82 _dbus_verbose (
" %d FIXUPS to apply\n",
99 #if RECURSIVE_MARSHAL_WRITE_TRACE 100 _dbus_verbose (
" applying FIXUP to reader %p at pos %d new_len = %d old len %d\n",
138 element_type_get_alignment (
const DBusString *str,
175 struct_or_dict_entry_types_only_reader_recurse (
DBusTypeReader *sub,
178 base_reader_recurse (sub, parent);
182 _dbus_string_get_byte (sub->
type_str,
192 struct_or_dict_entry_types_only_reader_recurse (sub, parent);
202 base_reader_recurse (sub, parent);
214 #define ARRAY_READER_LEN_POS(reader) \ 215 ((reader)->u.array.start_pos - ((int)(reader)->array_len_offset) - 4) 220 dbus_uint32_t array_len;
225 _dbus_assert (_DBUS_ALIGN_VALUE (len_pos, 4) == (
unsigned) len_pos);
227 _dbus_string_get_const_data_len (reader->
value_str, len_pos, 4));
229 #if RECURSIVE_MARSHAL_READ_TRACE 230 _dbus_verbose (
" reader %p len_pos %d array len %u len_offset %d\n",
246 array_types_only_reader_recurse (sub, parent);
254 alignment = element_type_get_alignment (sub->
type_str,
263 #if RECURSIVE_MARSHAL_READ_TRACE 264 _dbus_verbose (
" type reader %p array start = %d len_offset = %d array len = %d array element type = %s\n",
266 sub->
u.array.start_pos,
268 array_reader_get_array_len (sub),
279 int contained_alignment;
281 base_reader_recurse (sub, parent);
299 #if RECURSIVE_MARSHAL_READ_TRACE 300 _dbus_verbose (
" type reader %p variant containing '%s'\n",
302 _dbus_string_get_const_data_len (sub->
type_str,
316 end_pos = reader->
u.array.start_pos + array_reader_get_array_len (reader);
325 skip_one_complete_type (
const DBusString *type_str,
344 const unsigned char *p;
345 const unsigned char *start;
351 p = start + *type_pos;
421 *type_pos = (int) (p - start);
425 find_len_of_complete_type (
const DBusString *type_str,
432 skip_one_complete_type (type_str, &end);
434 return end - type_pos;
441 switch (current_type)
508 base_reader_next (reader, current_type);
529 base_reader_next (reader, current_type);
563 end_pos = reader->
u.array.start_pos + array_reader_get_array_len (reader);
565 #if RECURSIVE_MARSHAL_READ_TRACE 566 _dbus_verbose (
" reader %p array next START start_pos = %d end_pos = %d value_pos = %d current_type = %s\n",
568 reader->
u.array.start_pos,
618 #if RECURSIVE_MARSHAL_READ_TRACE 619 _dbus_verbose (
" reader %p array next END start_pos = %d end_pos = %d value_pos = %d current_type = %s\n",
621 reader->
u.array.start_pos,
630 skip_one_complete_type (reader->
type_str,
654 struct_or_dict_entry_reader_recurse,
662 struct_or_dict_entry_types_only_reader_recurse,
670 struct_or_dict_entry_reader_recurse,
672 dict_entry_reader_next
676 "dict_entry types", 5,
678 struct_or_dict_entry_types_only_reader_recurse,
680 dict_entry_reader_next
686 array_reader_recurse,
687 array_reader_check_finished,
694 array_types_only_reader_recurse,
696 array_types_only_reader_next
702 variant_reader_recurse,
707 #ifndef DBUS_DISABLE_ASSERT 709 all_reader_classes[] = {
711 &body_types_only_reader_class,
712 &struct_reader_class,
713 &struct_types_only_reader_class,
714 &dict_entry_reader_class,
715 &dict_entry_types_only_reader_class,
717 &array_types_only_reader_class,
718 &variant_reader_class
740 reader_init (reader, byte_order, type_str, type_pos,
741 value_str, value_pos);
743 reader->
klass = &body_reader_class;
745 #if RECURSIVE_MARSHAL_READ_TRACE 746 _dbus_verbose (
" type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
765 reader_init (reader, DBUS_COMPILER_BYTE_ORDER ,
768 reader->
klass = &body_types_only_reader_class;
770 #if RECURSIVE_MARSHAL_READ_TRACE 771 _dbus_verbose (
" type reader %p init types only type_pos = %d remaining sig '%s'\n",
804 _dbus_verbose (
" type reader %p current type_pos = %d type = %s\n",
854 const unsigned char **value_location)
858 *value_location = _dbus_string_get_const_data_len (reader->
value_str,
886 #if RECURSIVE_MARSHAL_READ_TRACE 887 _dbus_verbose (
" type reader %p read basic type_pos = %d value_pos = %d remaining sig '%s'\n",
905 return array_reader_get_array_len (reader);
947 total_len = array_reader_get_array_len (reader);
948 end_pos = reader->
u.array.start_pos + total_len;
949 remaining_len = end_pos - reader->
value_pos;
951 #if RECURSIVE_MARSHAL_READ_TRACE 952 _dbus_verbose (
"end_pos %d total_len %d remaining_len %d value_pos %d\n",
953 end_pos, total_len, remaining_len, reader->
value_pos);
958 if (remaining_len == 0)
962 (
void*) _dbus_string_get_const_data_len (reader->
value_str,
966 *n_elements = remaining_len / alignment;
969 #if RECURSIVE_MARSHAL_READ_TRACE 970 _dbus_verbose (
" type reader %p read fixed array type_pos = %d value_pos = %d remaining sig '%s'\n",
1001 klass = &struct_types_only_reader_class;
1003 klass = &struct_reader_class;
1007 klass = &dict_entry_types_only_reader_class;
1009 klass = &dict_entry_reader_class;
1013 klass = &array_types_only_reader_class;
1015 klass = &array_reader_class;
1021 klass = &variant_reader_class;
1025 #ifndef DBUS_DISABLE_CHECKS 1035 (* klass->
recurse) (sub, reader);
1038 #if RECURSIVE_MARSHAL_READ_TRACE 1039 _dbus_verbose (
" type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
1060 #if RECURSIVE_MARSHAL_READ_TRACE 1061 _dbus_verbose (
" type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
1072 #if RECURSIVE_MARSHAL_READ_TRACE 1073 _dbus_verbose (
" type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
1175 orig_len = _dbus_string_get_length (&block->
replacement);
1177 realign_reader = *realign_root;
1179 #if RECURSIVE_MARSHAL_WRITE_TRACE 1180 _dbus_verbose (
"INITIALIZING replacement block writer %p at value_pos %d\n",
1181 &writer, _dbus_string_get_length (&block->
replacement));
1192 #if RECURSIVE_MARSHAL_WRITE_TRACE 1193 _dbus_verbose (
"COPYING from reader at value_pos %d to writer %p starting after value_pos %d\n",
1197 if (!_dbus_type_writer_write_reader_partial (&writer,
1205 #if RECURSIVE_MARSHAL_WRITE_TRACE 1206 _dbus_verbose (
"REPLACEMENT at padding %d len %d\n", block->
padding,
1210 _dbus_verbose (
"TO BE REPLACED at value_pos = %d (align pad %d) len %d realign_reader.value_pos %d\n",
1230 apply_and_free_fixups (&fixups, reader);
1236 free_fixups (&fixups);
1283 if (!replacement_block_init (&block, reader))
1287 #if RECURSIVE_MARSHAL_WRITE_TRACE 1288 _dbus_verbose (
"INITIALIZING writer %p to write basic value at value_pos %d of replacement string\n",
1289 &writer, _dbus_string_get_length (&block.
replacement));
1297 #if RECURSIVE_MARSHAL_WRITE_TRACE 1298 _dbus_verbose (
"WRITING basic value to writer %p (replacement string)\n", &writer);
1303 if (!replacement_block_replace (&block,
1311 replacement_block_free (&block);
1375 #if RECURSIVE_MARSHAL_WRITE_TRACE 1376 _dbus_verbose (
" SET BASIC type reader %p type_pos = %d value_pos = %d remaining sig '%s' realign_root = %p with value_pos %d current_type = %s\n",
1380 realign_root ? realign_root->
value_pos : -1,
1383 _dbus_string_get_length (realign_root->
value_str) -
1391 reader_set_basic_fixed_length (reader, current_type, value);
1397 return reader_set_basic_variable_length (reader, current_type,
1398 value, realign_root);
1431 if (!replacement_block_init (&block, reader))
1434 if (!replacement_block_replace (&block,
1442 replacement_block_free (&block);
1509 #if RECURSIVE_MARSHAL_WRITE_TRACE 1510 _dbus_verbose (
"writer %p init remaining sig '%s'\n", writer,
1534 NULL, 0, value_str, value_pos);
1593 value_str, value_pos);
1599 _dbus_type_writer_write_basic_no_typecode (
DBusTypeWriter *writer,
1657 #ifndef DBUS_DISABLE_CHECKS 1668 "The overall signature expected here was '%s' and we are on byte %d of that signature.\n",
1674 "The overall signature expected here was '%s' and we are on byte %d of that signature.\n",
1683 #if RECURSIVE_MARSHAL_WRITE_TRACE 1684 _dbus_verbose (
" type writer %p recurse parent %s type_pos = %d value_pos = %d is_expectation = %d remaining sig '%s' enabled = %d\n",
1692 _dbus_verbose (
" type writer %p recurse sub %s type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n",
1710 #if RECURSIVE_MARSHAL_WRITE_TRACE 1711 _dbus_verbose (
" type writer %p write_or_verify start type_pos = %d remaining sig '%s' enabled = %d\n",
1724 #ifndef DBUS_DISABLE_CHECKS 1730 if (expected != typecode)
1734 "The overall signature expected here was '%s' and we are on byte %d of that signature.\n",
1738 _dbus_warn_check_failed (
"Array or variant type wasn't expecting any more values to be written into it, but a value %s was written.\n" 1739 "The overall signature expected here was '%s' and we are on byte %d of that signature.\n",
1764 #if RECURSIVE_MARSHAL_WRITE_TRACE 1765 _dbus_verbose (
" type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
1777 int contained_type_start,
1778 int contained_type_len,
1793 if (!write_or_verify_typecode (sub, begin_char))
1813 int contained_type_start,
1814 int contained_type_len,
1818 dbus_uint32_t value = 0;
1822 #ifndef DBUS_DISABLE_CHECKS 1827 contained_type_start,
1830 writer->
u.array.element_type_pos + 1))
1832 _dbus_warn_check_failed (
"Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
1833 _dbus_string_get_const_data_len (contained_type,
1834 contained_type_start,
1835 contained_type_len));
1841 if (writer->
enabled && !is_array_append)
1855 sub->
u.array.element_type_pos = sub->
type_pos;
1872 contained_type_start, contained_type_len,
1874 sub->
u.array.element_type_pos))
1884 writer->
type_pos += 1 + contained_type_len;
1892 sub->
u.array.len_pos = _DBUS_ALIGN_VALUE (sub->
value_pos, 4);
1894 if (is_array_append)
1911 alignment = element_type_get_alignment (contained_type, contained_type_start);
1913 aligned = _DBUS_ALIGN_VALUE (sub->
value_pos, alignment);
1916 if (!is_array_append)
1930 if (is_array_append)
1934 _dbus_assert (_DBUS_ALIGN_VALUE (sub->
u.array.len_pos, 4) ==
1935 (
unsigned) sub->
u.array.len_pos);
1937 _dbus_string_get_const_data_len (sub->
value_str,
1938 sub->
u.array.len_pos,
1947 sub->
u.array.len_pos = -1;
1954 #if RECURSIVE_MARSHAL_WRITE_TRACE 1955 _dbus_verbose (
" type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d value_pos = %d\n", sub,
1959 sub->
u.array.start_pos, sub->
u.array.len_pos, sub->
value_pos);
1986 int contained_type_start,
1987 int contained_type_len,
1990 int contained_alignment;
2020 contained_type_len))
2058 int contained_type_start,
2059 int contained_type_len,
2063 writer_recurse_init_and_check (writer, container_type, sub);
2065 switch (container_type)
2068 return writer_recurse_struct_or_dict_entry (writer,
2071 contained_type_start, contained_type_len,
2075 return writer_recurse_struct_or_dict_entry (writer,
2078 contained_type_start, contained_type_len,
2082 return writer_recurse_array (writer,
2083 contained_type, contained_type_start, contained_type_len,
2084 sub, is_array_append);
2087 return writer_recurse_variant (writer,
2088 contained_type, contained_type_start, contained_type_len,
2112 int contained_type_start,
2115 int contained_type_len;
2118 contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
2120 contained_type_len = 0;
2122 return _dbus_type_writer_recurse_contained_len (writer, container_type,
2124 contained_type_start,
2145 int contained_type_start,
2148 int contained_type_len;
2151 contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
2153 contained_type_len = 0;
2155 return _dbus_type_writer_recurse_contained_len (writer,
DBUS_TYPE_ARRAY,
2157 contained_type_start,
2167 return writer->
value_pos - writer->
u.array.start_pos;
2186 #if RECURSIVE_MARSHAL_WRITE_TRACE 2187 _dbus_verbose (
" type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
2190 _dbus_verbose (
" type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
2208 if (sub->
u.array.len_pos >= 0)
2213 len = writer_get_array_len (sub);
2215 sub->
u.array.len_pos,
2218 #if RECURSIVE_MARSHAL_WRITE_TRACE 2219 _dbus_verbose (
" filled in sub array len to %u at len_pos %d\n",
2220 len, sub->
u.array.len_pos);
2223 #if RECURSIVE_MARSHAL_WRITE_TRACE 2226 _dbus_verbose (
" not filling in sub array len because we were disabled when we passed the len\n");
2291 #if RECURSIVE_MARSHAL_WRITE_TRACE 1997