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) 
  225   _dbus_assert (_DBUS_ALIGN_VALUE (len_pos, 4) == (
unsigned) len_pos);
 
  227                                    _dbus_string_get_const_udata_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;
 
  350   start = (
const unsigned char *)type_str;
 
  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_udata_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 
 1036   (* klass->
recurse) (sub, reader);
 
 1039 #if RECURSIVE_MARSHAL_READ_TRACE 
 1040   _dbus_verbose (
"  type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
 
 1061 #if RECURSIVE_MARSHAL_READ_TRACE 
 1062   _dbus_verbose (
"  type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
 
 1073 #if RECURSIVE_MARSHAL_READ_TRACE 
 1074   _dbus_verbose (
"  type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
 
 1176   orig_len = _dbus_string_get_length (&block->
replacement);
 
 1178   realign_reader = *realign_root;
 
 1180 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1181   _dbus_verbose (
"INITIALIZING replacement block writer %p at value_pos %d\n",
 
 1182                  &writer, _dbus_string_get_length (&block->
replacement));
 
 1193 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1194   _dbus_verbose (
"COPYING from reader at value_pos %d to writer %p starting after value_pos %d\n",
 
 1198   if (!_dbus_type_writer_write_reader_partial (&writer,
 
 1206 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1207   _dbus_verbose (
"REPLACEMENT at padding %d len %d\n", block->
padding,
 
 1211   _dbus_verbose (
"TO BE REPLACED at value_pos = %d (align pad %d) len %d realign_reader.value_pos %d\n",
 
 1231   apply_and_free_fixups (&fixups, reader);
 
 1237   free_fixups (&fixups);
 
 1284   if (!replacement_block_init (&block, reader))
 
 1288 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1289   _dbus_verbose (
"INITIALIZING writer %p to write basic value at value_pos %d of replacement string\n",
 
 1290                  &writer, _dbus_string_get_length (&block.
replacement));
 
 1298 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1299   _dbus_verbose (
"WRITING basic value to writer %p (replacement string)\n", &writer);
 
 1304   if (!replacement_block_replace (&block,
 
 1312   replacement_block_free (&block);
 
 1376 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1377   _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",
 
 1381                  realign_root ? realign_root->
value_pos : -1,
 
 1384                                  _dbus_string_get_length (realign_root->
value_str) -
 
 1392       reader_set_basic_fixed_length (reader, current_type, value);
 
 1398       return reader_set_basic_variable_length (reader, current_type,
 
 1399                                                value, realign_root);
 
 1432   if (!replacement_block_init (&block, reader))
 
 1435   if (!replacement_block_replace (&block,
 
 1443   replacement_block_free (&block);
 
 1510 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1511   _dbus_verbose (
"writer %p init remaining sig '%s'\n", writer,
 
 1535                           NULL, 0, value_str, value_pos);
 
 1594                           value_str, value_pos);
 
 1600 _dbus_type_writer_write_basic_no_typecode (
DBusTypeWriter *writer,
 
 1658 #ifndef DBUS_DISABLE_CHECKS 
 1669                                      "The overall signature expected here was '%s' and we are on byte %d of that signature.",
 
 1675                                      "The overall signature expected here was '%s' and we are on byte %d of that signature.",
 
 1684 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1685   _dbus_verbose (
"  type writer %p recurse parent %s type_pos = %d value_pos = %d is_expectation = %d remaining sig '%s' enabled = %d\n",
 
 1693   _dbus_verbose (
"  type writer %p recurse sub %s   type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n",
 
 1711 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1712   _dbus_verbose (
"  type writer %p write_or_verify start type_pos = %d remaining sig '%s' enabled = %d\n",
 
 1725 #ifndef DBUS_DISABLE_CHECKS 
 1731         if (expected != typecode)
 
 1735                                        "The overall signature expected here was '%s' and we are on byte %d of that signature.",
 
 1739               _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" 
 1740                                        "The overall signature expected here was '%s' and we are on byte %d of that signature.",
 
 1765 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1766   _dbus_verbose (
"  type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
 
 1778                                      int               contained_type_start,
 
 1779                                      int               contained_type_len,
 
 1794   if (!write_or_verify_typecode (sub, begin_char))
 
 1814                       int               contained_type_start,
 
 1815                       int               contained_type_len,
 
 1823 #ifndef DBUS_DISABLE_CHECKS 
 1828                                          contained_type_start,
 
 1831                                          writer->
u.array.element_type_pos + 1))
 
 1833           _dbus_warn_check_failed (
"Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array",
 
 1834                                    _dbus_string_get_const_data_len (contained_type,
 
 1835                                                                     contained_type_start,
 
 1836                                                                     contained_type_len));
 
 1842   if (writer->
enabled && !is_array_append)
 
 1856       sub->
u.array.element_type_pos = sub->
type_pos;
 
 1873                                   contained_type_start, contained_type_len,
 
 1875                                   sub->
u.array.element_type_pos))
 
 1885         writer->
type_pos += 1 + contained_type_len;
 
 1893       sub->
u.array.len_pos = _DBUS_ALIGN_VALUE (sub->
value_pos, 4);
 
 1895       if (is_array_append)
 
 1912       alignment = element_type_get_alignment (contained_type, contained_type_start);
 
 1914       aligned = _DBUS_ALIGN_VALUE (sub->
value_pos, alignment);
 
 1917           if (!is_array_append)
 
 1931       if (is_array_append)
 
 1935           _dbus_assert (_DBUS_ALIGN_VALUE (sub->
u.array.len_pos, 4) ==
 
 1936                         (
unsigned) sub->
u.array.len_pos);
 
 1938                                      _dbus_string_get_const_udata_len (sub->
value_str,
 
 1939                                                                       sub->
u.array.len_pos,
 
 1948       sub->
u.array.len_pos = -1;
 
 1955 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 1956       _dbus_verbose (
"  type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d value_pos = %d\n", sub,
 
 1960                      sub->
u.array.start_pos, sub->
u.array.len_pos, sub->
value_pos);
 
 1987                         int               contained_type_start,
 
 1988                         int               contained_type_len,
 
 1991   int contained_alignment;
 
 2021                                  contained_type_len))
 
 2059                                          int               contained_type_start,
 
 2060                                          int               contained_type_len,
 
 2064   writer_recurse_init_and_check (writer, container_type, sub);
 
 2066   switch (container_type)
 
 2069       return writer_recurse_struct_or_dict_entry (writer,
 
 2072                                                   contained_type_start, contained_type_len,
 
 2076       return writer_recurse_struct_or_dict_entry (writer,
 
 2079                                                   contained_type_start, contained_type_len,
 
 2083       return writer_recurse_array (writer,
 
 2084                                    contained_type, contained_type_start, contained_type_len,
 
 2085                                    sub, is_array_append);
 
 2088       return writer_recurse_variant (writer,
 
 2089                                      contained_type, contained_type_start, contained_type_len,
 
 2113                            int               contained_type_start,
 
 2116   int contained_type_len;
 
 2119     contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
 
 2121     contained_type_len = 0;
 
 2123   return _dbus_type_writer_recurse_contained_len (writer, container_type,
 
 2125                                                   contained_type_start,
 
 2146                                 int               contained_type_start,
 
 2149   int contained_type_len;
 
 2152     contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
 
 2154     contained_type_len = 0;
 
 2156   return _dbus_type_writer_recurse_contained_len (writer, 
DBUS_TYPE_ARRAY,
 
 2158                                                   contained_type_start,
 
 2168   return writer->
value_pos - writer->
u.array.start_pos;
 
 2187 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2188   _dbus_verbose (
"  type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
 
 2191   _dbus_verbose (
"  type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
 
 2209       if (sub->
u.array.len_pos >= 0) 
 
 2214           len = writer_get_array_len (sub);
 
 2216                                     sub->
u.array.len_pos,
 
 2219 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2220           _dbus_verbose (
"    filled in sub array len to %u at len_pos %d\n",
 
 2221                          len, sub->
u.array.len_pos);
 
 2224 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2227           _dbus_verbose (
"    not filling in sub array len because we were disabled when we passed the len\n");
 
 2292 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2293   _dbus_verbose (
"  type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n",
 
 2327   if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
 
 2330   if (!write_or_verify_typecode (writer, type))
 
 2336 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2337   _dbus_verbose (
"  type writer %p basic type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n",
 
 2370 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2371   _dbus_verbose (
"  type writer %p entering fixed multi type_pos = %d value_pos = %d n_elements %d\n",
 
 2375   if (!write_or_verify_typecode (writer, element_type))
 
 2390 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2391   _dbus_verbose (
"  type writer %p fixed multi written new type_pos = %d new value_pos = %d n_elements %d\n",
 
 2405       if (!writer->
enabled && _dbus_type_reader_greater_than (reader, start_after))
 
 2407           _dbus_type_writer_set_enabled (writer, 
TRUE);
 
 2408 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2409           _dbus_verbose (
"ENABLING writer %p at %d because reader at value_pos %d is after reader at value_pos %d\n",
 
 2414       _dbus_assert ((!writer->
enabled && !_dbus_type_reader_greater_than (reader, start_after)) ||
 
 2415                     (writer->
enabled && _dbus_type_reader_greater_than (reader, start_after)));
 
 2450                             int                   start_after_new_pos,
 
 2451                             int                   start_after_new_len,
 
 2468           int reader_array_len_pos;
 
 2469           int reader_array_start_pos;
 
 2477           if (!inside_start_after && start_after &&
 
 2481             this_is_start_after = 
TRUE;
 
 2483             this_is_start_after = 
FALSE;
 
 2490               reader_array_start_pos = subreader.
u.array.start_pos;
 
 2495               reader_array_len_pos = -1;
 
 2496               reader_array_start_pos = -1;
 
 2500                                            &sig_start, &sig_len);
 
 2502 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2503           _dbus_verbose (
"about to recurse into %s reader at %d subreader at %d writer at %d start_after reader at %d write target len %d inside_start_after = %d this_is_start_after = %d\n",
 
 2508                          start_after ? start_after->
value_pos : -1,
 
 2509                          _dbus_string_get_length (writer->
value_str),
 
 2510                          inside_start_after, this_is_start_after);
 
 2513           if (!inside_start_after && !this_is_start_after)
 
 2514             enable_if_after (writer, &subreader, start_after);
 
 2515           enabled_at_recurse = writer->
enabled;
 
 2516           if (!_dbus_type_writer_recurse_contained_len (writer, current_type,
 
 2517                                                         sig_str, sig_start, sig_len,
 
 2521 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2522           _dbus_verbose (
"recursed into subwriter at %d write target len %d\n",
 
 2524                          _dbus_string_get_length (subwriter.
value_str));
 
 2527           if (!writer_write_reader_helper (&subwriter, &subreader, start_after,
 
 2528                                            start_after_new_pos, start_after_new_len,
 
 2530                                            inside_start_after ||
 
 2531                                            this_is_start_after))
 
 2534 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2535           _dbus_verbose (
"about to unrecurse from %s subreader at %d writer at %d subwriter at %d  write target len %d\n",
 
 2540                          _dbus_string_get_length (writer->
value_str));
 
 2543           if (!inside_start_after && !this_is_start_after)
 
 2544             enable_if_after (writer, &subreader, start_after);
 
 2545           past_start_after = writer->
enabled;
 
 2554           if (start_after != 
NULL &&
 
 2555               !enabled_at_recurse && past_start_after &&
 
 2560               int bytes_written_after_start_after;
 
 2561               int bytes_before_start_after;
 
 2568               bytes_written_after_start_after = writer_get_array_len (&subwriter);
 
 2570               bytes_before_start_after =
 
 2571                 start_after->
value_pos - reader_array_start_pos;
 
 2575                 bytes_before_start_after +
 
 2576                 start_after_new_len +
 
 2577                 bytes_written_after_start_after;
 
 2583                                              _dbus_string_get_const_udata_len (reader->
value_str,
 
 2586               if (old_len != fixup.
new_len && !append_fixup (fixups, &fixup))
 
 2589 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2590               _dbus_verbose (
"Generated fixup len_pos_in_reader = %d new_len = %d reader_array_start_pos = %d start_after->value_pos = %d bytes_before_start_after = %d start_after_new_len = %d bytes_written_after_start_after = %d\n",
 
 2593                              reader_array_start_pos,
 
 2595                              bytes_before_start_after,
 
 2596                              start_after_new_len,
 
 2597                              bytes_written_after_start_after);
 
 2607 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2608           _dbus_verbose (
"Reading basic value %s at %d\n",
 
 2615 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2616           _dbus_verbose (
"Writing basic value %s at %d write target len %d inside_start_after = %d\n",
 
 2619                          _dbus_string_get_length (writer->
value_str),
 
 2620                          inside_start_after);
 
 2622           if (!inside_start_after)
 
 2623             enable_if_after (writer, reader, start_after);
 
 2626 #if RECURSIVE_MARSHAL_WRITE_TRACE 
 2627           _dbus_verbose (
"Wrote basic value %s, new value_pos %d write target len %d\n",
 
 2630                          _dbus_string_get_length (writer->
value_str));
 
 2641     apply_and_free_fixups (fixups, 
NULL); 
 
 2681                                         int                   start_after_new_pos,
 
 2682                                         int                   start_after_new_len,
 
 2692   orig_type_len = _dbus_string_get_length (writer->
type_str);
 
 2693   orig_value_len = _dbus_string_get_length (writer->
value_str);
 
 2694   orig_enabled = writer->
enabled;
 
 2697     _dbus_type_writer_set_enabled (writer, 
FALSE);
 
 2699   if (!writer_write_reader_helper (writer, reader, start_after,
 
 2700                                    start_after_new_pos,
 
 2701                                    start_after_new_len,
 
 2705   _dbus_type_writer_set_enabled (writer, orig_enabled);
 
 2711       new_bytes = _dbus_string_get_length (writer->
type_str) - orig_type_len;
 
 2714   new_bytes = _dbus_string_get_length (writer->
value_str) - orig_value_len;
 
 2735   return _dbus_type_writer_write_reader_partial (writer, reader, 
NULL, 0, 0, 
NULL);