Coverage report for dbus/dbus-marshal-recursive.c.gcov

        -:    0:Source:dbus-marshal-recursive.c
        -:    0:Graph:.libs/dbus-marshal-recursive.gcno
        -:    0:Data:.libs/dbus-marshal-recursive.gcda
        -:    0:Runs:11824
        -:    0:Programs:5
        -:    1:/* -*- mode: C; c-file-style: "gnu" -*- */
        -:    2:/* dbus-marshal-recursive.c  Marshalling routines for recursive types
        -:    3: *
        -:    4: * Copyright (C) 2004, 2005 Red Hat, Inc.
        -:    5: *
        -:    6: * Licensed under the Academic Free License version 2.1
        -:    7: *
        -:    8: * This program is free software; you can redistribute it and/or modify
        -:    9: * it under the terms of the GNU General Public License as published by
        -:   10: * the Free Software Foundation; either version 2 of the License, or
        -:   11: * (at your option) any later version.
        -:   12: *
        -:   13: * This program is distributed in the hope that it will be useful,
        -:   14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
        -:   15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        -:   16: * GNU General Public License for more details.
        -:   17: *
        -:   18: * You should have received a copy of the GNU General Public License
        -:   19: * along with this program; if not, write to the Free Software
        -:   20: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        -:   21: *
        -:   22: */
        -:   23:
        -:   24:#include "dbus-marshal-recursive.h"
        -:   25:#include "dbus-marshal-basic.h"
        -:   26:#include "dbus-signature.h"
        -:   27:#include "dbus-internals.h"
        -:   28:
        -:   29:/**
        -:   30: * @addtogroup DBusMarshal
        -:   31: * @{
        -:   32: */
        -:   33:
        -:   34:/** turn this on to get deluged in TypeReader verbose spam */
        -:   35:#define RECURSIVE_MARSHAL_READ_TRACE  0
        -:   36:
        -:   37:/** turn this on to get deluged in TypeWriter verbose spam */
        -:   38:#define RECURSIVE_MARSHAL_WRITE_TRACE 0
        -:   39:
        -:   40:static void
        -:   41:free_fixups (DBusList **fixups)
function free_fixups called 492 returned 100% blocks executed 90%
      492:   42:{
        -:   43:  DBusList *link;
        -:   44:
      492:   45:  link = _dbus_list_get_first_link (fixups);
call    0 returned 100%
      987:   46:  while (link != NULL)
branch  0 taken 1%
branch  1 taken 99% (fallthrough)
        -:   47:    {
        -:   48:      DBusList *next;
        -:   49:
        3:   50:      next = _dbus_list_get_next_link (fixups, link);
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:   51:
        3:   52:      dbus_free (link->data);
call    0 returned 100%
        3:   53:      _dbus_list_free_link (link);
call    0 returned 100%
        -:   54:
        3:   55:      link = next;
        -:   56:    }
        -:   57:
      492:   58:  *fixups = NULL;
      492:   59:}
        -:   60:
        -:   61:static void
        -:   62:apply_and_free_fixups (DBusList      **fixups,
        -:   63:                       DBusTypeReader *reader)
function apply_and_free_fixups called 63666 returned 100% blocks executed 92%
    63666:   64:{
        -:   65:  DBusList *link;
        -:   66:
        -:   67:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -:   68:  if (*fixups)
        -:   69:    _dbus_verbose (" %d FIXUPS to apply\n",
        -:   70:                   _dbus_list_get_length (fixups));
        -:   71:#endif
        -:   72:
    63666:   73:  link = _dbus_list_get_first_link (fixups);
call    0 returned 100%
   161145:   74:  while (link != NULL)
branch  0 taken 35%
branch  1 taken 65% (fallthrough)
        -:   75:    {
        -:   76:      DBusList *next;
        -:   77:
    33813:   78:      next = _dbus_list_get_next_link (fixups, link);
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:   79:
    33813:   80:      if (reader)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:   81:        {
        -:   82:          DBusArrayLenFixup *f;
        -:   83:
    33813:   84:          f = link->data;
        -:   85:
        -:   86:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -:   87:          _dbus_verbose (" applying FIXUP to reader %p at pos %d new_len = %d old len %d\n",
        -:   88:                         reader, f->len_pos_in_reader, f->new_len,
        -:   89:                         _dbus_marshal_read_uint32 (reader->value_str,
        -:   90:                                                    f->len_pos_in_reader,
        -:   91:                                                    reader->byte_order, NULL));
        -:   92:#endif
        -:   93:
    33813:   94:          _dbus_marshal_set_uint32 ((DBusString*) reader->value_str,
call    0 returned 100%
        -:   95:                                    f->len_pos_in_reader,
        -:   96:                                    f->new_len,
        -:   97:                                    reader->byte_order);
        -:   98:        }
        -:   99:
    33813:  100:      dbus_free (link->data);
call    0 returned 100%
    33813:  101:      _dbus_list_free_link (link);
call    0 returned 100%
        -:  102:
    33813:  103:      link = next;
        -:  104:    }
        -:  105:
    63666:  106:  *fixups = NULL;
    63666:  107:}
        -:  108:
        -:  109:/**
        -:  110: * Virtual table for a type reader.
        -:  111: */
        -:  112:struct DBusTypeReaderClass
        -:  113:{
        -:  114:  const char *name;       /**< name for debugging */
        -:  115:  int         id;         /**< index in all_reader_classes */
        -:  116:  dbus_bool_t types_only; /**< only iterates over types, not values */
        -:  117:  void        (* recurse)          (DBusTypeReader        *sub,
        -:  118:                                    DBusTypeReader        *parent); /**< recurse with this reader as sub */
        -:  119:  dbus_bool_t (* check_finished)   (const DBusTypeReader  *reader); /**< check whether reader is at the end */
        -:  120:  void        (* next)             (DBusTypeReader        *reader,
        -:  121:                                    int                    current_type); /**< go to the next value */
        -:  122:  void        (* init_from_mark)   (DBusTypeReader        *reader,
        -:  123:                                    const DBusTypeMark    *mark);  /**< uncompress from a mark */
        -:  124:};
        -:  125:
        -:  126:static int
        -:  127:element_type_get_alignment (const DBusString *str,
        -:  128:                            int               pos)
function element_type_get_alignment called 1220987 returned 100% blocks executed 100%
  1220987:  129:{
  1220987:  130:  return _dbus_type_get_alignment (_dbus_first_type_in_signature (str, pos));
call    0 returned 100%
call    1 returned 100%
        -:  131:}
        -:  132:
        -:  133:static void
        -:  134:reader_init (DBusTypeReader    *reader,
        -:  135:             int                byte_order,
        -:  136:             const DBusString  *type_str,
        -:  137:             int                type_pos,
        -:  138:             const DBusString  *value_str,
        -:  139:             int                value_pos)
function reader_init called 17110600 returned 100% blocks executed 100%
 17110600:  140:{
 17110600:  141:  reader->byte_order = byte_order;
 17110600:  142:  reader->finished = FALSE;
 17110600:  143:  reader->type_str = type_str;
 17110600:  144:  reader->type_pos = type_pos;
 17110600:  145:  reader->value_str = value_str;
 17110600:  146:  reader->value_pos = value_pos;
 17110600:  147:}
        -:  148:
        -:  149:static void
        -:  150:base_reader_recurse (DBusTypeReader *sub,
        -:  151:                     DBusTypeReader *parent)
function base_reader_recurse called 15033976 returned 100% blocks executed 100%
 15033976:  152:{
        -:  153:  /* point subreader at the same place as parent */
 15033976:  154:  reader_init (sub,
call    0 returned 100%
        -:  155:               parent->byte_order,
        -:  156:               parent->type_str,
        -:  157:               parent->type_pos,
        -:  158:               parent->value_str,
        -:  159:               parent->value_pos);
 15033976:  160:}
        -:  161:
        -:  162:static void
        -:  163:struct_or_dict_entry_types_only_reader_recurse (DBusTypeReader *sub,
        -:  164:                                                DBusTypeReader *parent)
function struct_or_dict_entry_types_only_reader_recurse called 7490480 returned 100% blocks executed 89%
  7490480:  165:{
  7490480:  166:  base_reader_recurse (sub, parent);
call    0 returned 100%
        -:  167:  
  7490480:  168:  _dbus_assert (_dbus_string_get_byte (sub->type_str,
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
call    3 returned 100%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
call    6 returned 100%
        -:  169:                                       sub->type_pos) == DBUS_STRUCT_BEGIN_CHAR ||
        -:  170:                _dbus_string_get_byte (sub->type_str,
        -:  171:                                       sub->type_pos) == DBUS_DICT_ENTRY_BEGIN_CHAR);
        -:  172:
  7490480:  173:  sub->type_pos += 1;
  7490480:  174:}
        -:  175:
        -:  176:static void
        -:  177:struct_or_dict_entry_reader_recurse (DBusTypeReader *sub,
        -:  178:                                     DBusTypeReader *parent)
function struct_or_dict_entry_reader_recurse called 6506404 returned 100% blocks executed 100%
  6506404:  179:{
  6506404:  180:  struct_or_dict_entry_types_only_reader_recurse (sub, parent);
call    0 returned 100%
        -:  181:
        -:  182:  /* struct and dict entry have 8 byte alignment */
  6506404:  183:  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
  6506404:  184:}
        -:  185:
        -:  186:static void
        -:  187:array_types_only_reader_recurse (DBusTypeReader *sub,
        -:  188:                                 DBusTypeReader *parent)
function array_types_only_reader_recurse called 993042 returned 100% blocks executed 100%
   993042:  189:{
   993042:  190:  base_reader_recurse (sub, parent);
call    0 returned 100%
        -:  191:
        -:  192:  /* point type_pos at the array element type */
   993042:  193:  sub->type_pos += 1;
        -:  194:
        -:  195:  /* Init with values likely to crash things if misused */
   993042:  196:  sub->u.array.start_pos = _DBUS_INT_MAX;
   993042:  197:  sub->array_len_offset = 7;
   993042:  198:}
        -:  199:
        -:  200:/** compute position of array length given array_len_offset, which is
        -:  201:    the offset back from start_pos to end of the len */
        -:  202:#define ARRAY_READER_LEN_POS(reader) \
        -:  203:  ((reader)->u.array.start_pos - ((int)(reader)->array_len_offset) - 4)
        -:  204:
        -:  205:static int
        -:  206:array_reader_get_array_len (const DBusTypeReader *reader)
function array_reader_get_array_len called 14211453 returned 100% blocks executed 100%
 14211453:  207:{
        -:  208:  dbus_uint32_t array_len;
        -:  209:  int len_pos;
        -:  210:
 14211453:  211:  len_pos = ARRAY_READER_LEN_POS (reader);
        -:  212:
 14211453:  213:  _dbus_assert (_DBUS_ALIGN_VALUE (len_pos, 4) == (unsigned) len_pos);
call    0 returned 100%
 14211453:  214:  array_len = _dbus_unpack_uint32 (reader->byte_order,
call    0 returned 100%
call    1 returned 100%
        -:  215:                                   _dbus_string_get_const_data_len (reader->value_str, len_pos, 4));
        -:  216:
        -:  217:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  218:  _dbus_verbose ("   reader %p len_pos %d array len %u len_offset %d\n",
        -:  219:                 reader, len_pos, array_len, reader->array_len_offset);
        -:  220:#endif
        -:  221:
 14211453:  222:  _dbus_assert (reader->u.array.start_pos - len_pos - 4 < 8);
call    0 returned 100%
        -:  223:
 14211453:  224:  return array_len;
        -:  225:}
        -:  226:
        -:  227:static void
        -:  228:array_reader_recurse (DBusTypeReader *sub,
        -:  229:                      DBusTypeReader *parent)
function array_reader_recurse called 759614 returned 100% blocks executed 100%
   759614:  230:{
        -:  231:  int alignment;
        -:  232:  int len_pos;
        -:  233:
   759614:  234:  array_types_only_reader_recurse (sub, parent);
call    0 returned 100%
        -:  235:
   759614:  236:  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
        -:  237:
   759614:  238:  len_pos = sub->value_pos;
        -:  239:
   759614:  240:  sub->value_pos += 4; /* for the length */
        -:  241:
   759614:  242:  alignment = element_type_get_alignment (sub->type_str,
call    0 returned 100%
        -:  243:                                          sub->type_pos);
        -:  244:
   759614:  245:  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
        -:  246:
   759614:  247:  sub->u.array.start_pos = sub->value_pos;
   759614:  248:  _dbus_assert ((sub->u.array.start_pos - (len_pos + 4)) < 8); /* only 3 bits in array_len_offset */
call    0 returned 100%
   759614:  249:  sub->array_len_offset = sub->u.array.start_pos - (len_pos + 4);
        -:  250:
        -:  251:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  252:  _dbus_verbose ("    type reader %p array start = %d len_offset = %d array len = %d array element type = %s\n",
        -:  253:                 sub,
        -:  254:                 sub->u.array.start_pos,
        -:  255:                 sub->array_len_offset,
        -:  256:                 array_reader_get_array_len (sub),
        -:  257:                 _dbus_type_to_string (_dbus_first_type_in_signature (sub->type_str,
        -:  258:                                                                sub->type_pos)));
        -:  259:#endif
   759614:  260:}
        -:  261:
        -:  262:static void
        -:  263:variant_reader_recurse (DBusTypeReader *sub,
        -:  264:                        DBusTypeReader *parent)
function variant_reader_recurse called 6550454 returned 100% blocks executed 100%
  6550454:  265:{
        -:  266:  int sig_len;
        -:  267:  int contained_alignment;
        -:  268:
  6550454:  269:  base_reader_recurse (sub, parent);
call    0 returned 100%
        -:  270:
        -:  271:  /* Variant is 1 byte sig length (without nul), signature with nul,
        -:  272:   * padding to 8-boundary, then values
        -:  273:   */
        -:  274:
  6550454:  275:  sig_len = _dbus_string_get_byte (sub->value_str, sub->value_pos);
call    0 returned 100%
        -:  276:
  6550454:  277:  sub->type_str = sub->value_str;
  6550454:  278:  sub->type_pos = sub->value_pos + 1;
        -:  279:
  6550454:  280:  sub->value_pos = sub->type_pos + sig_len + 1;
        -:  281:
  6550454:  282:  contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (sub->type_str,
call    0 returned 100%
call    1 returned 100%
        -:  283:                                                                           sub->type_pos));
        -:  284:  
  6550454:  285:  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment);
        -:  286:
        -:  287:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  288:  _dbus_verbose ("    type reader %p variant containing '%s'\n",
        -:  289:                 sub,
        -:  290:                 _dbus_string_get_const_data_len (sub->type_str,
        -:  291:                                                  sub->type_pos, 0));
        -:  292:#endif
  6550454:  293:}
        -:  294:
        -:  295:static dbus_bool_t
        -:  296:array_reader_check_finished (const DBusTypeReader *reader)
function array_reader_check_finished called 11031140 returned 100% blocks executed 100%
 11031140:  297:{
        -:  298:  int end_pos;
        -:  299:
        -:  300:  /* return the array element type if elements remain, and
        -:  301:   * TYPE_INVALID otherwise
        -:  302:   */
        -:  303:
 11031140:  304:  end_pos = reader->u.array.start_pos + array_reader_get_array_len (reader);
call    0 returned 100%
        -:  305:
 11031140:  306:  _dbus_assert (reader->value_pos <= end_pos);
call    0 returned 100%
 11031140:  307:  _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
call    0 returned 100%
        -:  308:
 11031140:  309:  return reader->value_pos == end_pos;
        -:  310:}
        -:  311:
        -:  312:static void
        -:  313:skip_one_complete_type (const DBusString *type_str,
        -:  314:                        int              *type_pos)
function skip_one_complete_type called 2761043 returned 100% blocks executed 100%
  2761043:  315:{
  2761043:  316:  _dbus_type_signature_next (_dbus_string_get_const_data (type_str),
call    0 returned 100%
call    1 returned 100%
        -:  317:			     type_pos);
  2761043:  318:}
        -:  319:
        -:  320:/**
        -:  321: * Skips to the next "complete" type inside a type signature.
        -:  322: * The signature is read starting at type_pos, and the next
        -:  323: * type position is stored in the same variable.
        -:  324: *
        -:  325: * @param type_str a type signature (must be valid)
        -:  326: * @param type_pos an integer position in the type signtaure (in and out)
        -:  327: */
        -:  328:void
        -:  329:_dbus_type_signature_next (const char       *type_str,
        -:  330:			   int              *type_pos)
function _dbus_type_signature_next called 2761161 returned 100% blocks executed 94%
  2761161:  331:{
        -:  332:  const unsigned char *p;
        -:  333:  const unsigned char *start;
        -:  334:
  2761161:  335:  _dbus_assert (type_str != NULL);
call    0 returned 100%
  2761161:  336:  _dbus_assert (type_pos != NULL);
call    0 returned 100%
        -:  337:  
  2761161:  338:  start = type_str;
  2761161:  339:  p = start + *type_pos;
        -:  340:
  2761161:  341:  _dbus_assert (*p != DBUS_STRUCT_END_CHAR);
call    0 returned 100%
  2761161:  342:  _dbus_assert (*p != DBUS_DICT_ENTRY_END_CHAR);
call    0 returned 100%
        -:  343:  
  5881139:  344:  while (*p == DBUS_TYPE_ARRAY)
branch  0 taken 12%
branch  1 taken 88% (fallthrough)
   358817:  345:    ++p;
        -:  346:
  2761161:  347:  _dbus_assert (*p != DBUS_STRUCT_END_CHAR);
call    0 returned 100%
  2761161:  348:  _dbus_assert (*p != DBUS_DICT_ENTRY_END_CHAR);
call    0 returned 100%
        -:  349:  
  2761161:  350:  if (*p == DBUS_STRUCT_BEGIN_CHAR)
branch  0 taken 49% (fallthrough)
branch  1 taken 51%
        -:  351:    {
        -:  352:      int depth;
        -:  353:
  1362319:  354:      depth = 1;
        -:  355:
        -:  356:      while (TRUE)
        -:  357:        {
  4086957:  358:          _dbus_assert (*p != DBUS_TYPE_INVALID);
call    0 returned 100%
        -:  359:
  4086957:  360:          ++p;
        -:  361:
  4086957:  362:          _dbus_assert (*p != DBUS_TYPE_INVALID);
call    0 returned 100%
        -:  363:
  4086957:  364:          if (*p == DBUS_STRUCT_BEGIN_CHAR)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  365:            depth += 1;
  4086957:  366:          else if (*p == DBUS_STRUCT_END_CHAR)
branch  0 taken 33% (fallthrough)
branch  1 taken 67%
        -:  367:            {
  1362319:  368:              depth -= 1;
  1362319:  369:              if (depth == 0)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  370:                {
  1362319:  371:                  ++p;
        -:  372:                  break;
        -:  373:                }
        -:  374:            }
  2724638:  375:        }
        -:  376:    }
  1398842:  377:  else if (*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  378:    {
        -:  379:      int depth;
        -:  380:
    12904:  381:      depth = 1;
        -:  382:
        -:  383:      while (TRUE)
        -:  384:        {
    38712:  385:          _dbus_assert (*p != DBUS_TYPE_INVALID);
call    0 returned 100%
        -:  386:
    38712:  387:          ++p;
        -:  388:
    38712:  389:          _dbus_assert (*p != DBUS_TYPE_INVALID);
call    0 returned 100%
        -:  390:
    38712:  391:          if (*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  392:            depth += 1;
    38712:  393:          else if (*p == DBUS_DICT_ENTRY_END_CHAR)
branch  0 taken 33% (fallthrough)
branch  1 taken 67%
        -:  394:            {
    12904:  395:              depth -= 1;
    12904:  396:              if (depth == 0)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  397:                {
    12904:  398:                  ++p;
        -:  399:                  break;
        -:  400:                }
        -:  401:            }
    25808:  402:        }
        -:  403:    }
        -:  404:  else
        -:  405:    {
  1385938:  406:      ++p;
        -:  407:    }
        -:  408:
  2761161:  409:  *type_pos = (int) (p - start);
  2761161:  410:}
        -:  411:
        -:  412:static int
        -:  413:find_len_of_complete_type (const DBusString *type_str,
        -:  414:                           int               type_pos)
function find_len_of_complete_type called 1877848 returned 100% blocks executed 100%
  1877848:  415:{
        -:  416:  int end;
        -:  417:
  1877848:  418:  end = type_pos;
        -:  419:
  1877848:  420:  skip_one_complete_type (type_str, &end);
call    0 returned 100%
        -:  421:
  1877848:  422:  return end - type_pos;
        -:  423:}
        -:  424:
        -:  425:static void
        -:  426:base_reader_next (DBusTypeReader *reader,
        -:  427:                  int             current_type)
function base_reader_next called 18894064 returned 100% blocks executed 100%
 18894064:  428:{
 18894064:  429:  switch (current_type)
branch  0 taken 23%
branch  1 taken 1%
branch  2 taken 76%
        -:  430:    {
        -:  431:    case DBUS_TYPE_DICT_ENTRY:
        -:  432:    case DBUS_TYPE_STRUCT:
        -:  433:    case DBUS_TYPE_VARIANT:
        -:  434:      /* Scan forward over the entire container contents */
        -:  435:      {
        -:  436:        DBusTypeReader sub;
        -:  437:
  4395181:  438:        if (reader->klass->types_only && current_type == DBUS_TYPE_VARIANT)
branch  0 taken 21% (fallthrough)
branch  1 taken 79%
branch  2 taken 99% (fallthrough)
branch  3 taken 1%
        -:  439:          ;
        -:  440:        else
        -:  441:          {
        -:  442:            /* Recurse into the struct or variant */
  3502138:  443:            _dbus_type_reader_recurse (reader, &sub);
call    0 returned 100%
        -:  444:
        -:  445:            /* Skip everything in this subreader */
  3506887:  446:            while (_dbus_type_reader_next (&sub))
call    0 returned 100%
branch  1 taken 1%
branch  2 taken 99% (fallthrough)
        -:  447:              {
        -:  448:                /* nothing */;
        -:  449:              }
        -:  450:          }
  4395181:  451:        if (!reader->klass->types_only)
branch  0 taken 79% (fallthrough)
branch  1 taken 21%
  3493108:  452:          reader->value_pos = sub.value_pos;
        -:  453:
        -:  454:        /* Now we are at the end of this container; for variants, the
        -:  455:         * subreader's type_pos is totally inapplicable (it's in the
        -:  456:         * value string) but we know that we increment by one past the
        -:  457:         * DBUS_TYPE_VARIANT
        -:  458:         */
  4395181:  459:        if (current_type == DBUS_TYPE_VARIANT)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
  4386151:  460:          reader->type_pos += 1;
        -:  461:        else
     9030:  462:          reader->type_pos = sub.type_pos;
        -:  463:      }
  4395181:  464:      break;
        -:  465:
        -:  466:    case DBUS_TYPE_ARRAY:
        -:  467:      {
   215818:  468:        if (!reader->klass->types_only)
branch  0 taken 29% (fallthrough)
branch  1 taken 71%
    62584:  469:          _dbus_marshal_skip_array (reader->value_str,
call    0 returned 100%
call    1 returned 100%
        -:  470:                                    _dbus_first_type_in_signature (reader->type_str,
        -:  471:                                                                   reader->type_pos + 1),
        -:  472:                                    reader->byte_order,
        -:  473:                                    &reader->value_pos);
        -:  474:
   215818:  475:        skip_one_complete_type (reader->type_str, &reader->type_pos);
call    0 returned 100%
        -:  476:      }
   215818:  477:      break;
        -:  478:
        -:  479:    default:
 14283065:  480:      if (!reader->klass->types_only)
branch  0 taken 77% (fallthrough)
branch  1 taken 23%
 10965390:  481:        _dbus_marshal_skip_basic (reader->value_str,
call    0 returned 100%
        -:  482:                                  current_type, reader->byte_order,
        -:  483:                                  &reader->value_pos);
        -:  484:
 14283065:  485:      reader->type_pos += 1;
        -:  486:      break;
        -:  487:    }
 18894064:  488:}
        -:  489:
        -:  490:static void
        -:  491:struct_reader_next (DBusTypeReader *reader,
        -:  492:                    int             current_type)
function struct_reader_next called 11609935 returned 100% blocks executed 100%
 11609935:  493:{
        -:  494:  int t;
        -:  495:
 11609935:  496:  base_reader_next (reader, current_type);
call    0 returned 100%
        -:  497:
        -:  498:  /* for STRUCT containers we return FALSE at the end of the struct,
        -:  499:   * for INVALID we return FALSE at the end of the signature.
        -:  500:   * In both cases we arrange for get_current_type() to return INVALID
        -:  501:   * which is defined to happen iff we're at the end (no more next())
        -:  502:   */
 11609935:  503:  t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
call    0 returned 100%
 11609935:  504:  if (t == DBUS_STRUCT_END_CHAR)
branch  0 taken 38% (fallthrough)
branch  1 taken 62%
        -:  505:    {
  4399999:  506:      reader->type_pos += 1;
  4399999:  507:      reader->finished = TRUE;
        -:  508:    }
 11609935:  509:}
        -:  510:
        -:  511:static void
        -:  512:dict_entry_reader_next (DBusTypeReader *reader,
        -:  513:                        int             current_type)
function dict_entry_reader_next called 12264 returned 100% blocks executed 100%
    12264:  514:{
        -:  515:  int t;
        -:  516:
    12264:  517:  base_reader_next (reader, current_type);
call    0 returned 100%
        -:  518:
        -:  519:  /* for STRUCT containers we return FALSE at the end of the struct,
        -:  520:   * for INVALID we return FALSE at the end of the signature.
        -:  521:   * In both cases we arrange for get_current_type() to return INVALID
        -:  522:   * which is defined to happen iff we're at the end (no more next())
        -:  523:   */
    12264:  524:  t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
call    0 returned 100%
    12264:  525:  if (t == DBUS_DICT_ENTRY_END_CHAR)
branch  0 taken 48% (fallthrough)
branch  1 taken 52%
        -:  526:    {
     5847:  527:      reader->type_pos += 1;
     5847:  528:      reader->finished = TRUE;
        -:  529:    }
    12264:  530:}
        -:  531:
        -:  532:static void
        -:  533:array_types_only_reader_next (DBusTypeReader *reader,
        -:  534:                              int             current_type)
function array_types_only_reader_next called 0 returned 0% blocks executed 0%
    #####:  535:{
        -:  536:  /* We have one "element" to be iterated over
        -:  537:   * in each array, which is its element type.
        -:  538:   * So the finished flag indicates whether we've
        -:  539:   * iterated over it yet or not.
        -:  540:   */
    #####:  541:  reader->finished = TRUE;
    #####:  542:}
        -:  543:
        -:  544:static void
        -:  545:array_reader_next (DBusTypeReader *reader,
        -:  546:                   int             current_type)
function array_reader_next called 3180292 returned 100% blocks executed 82%
  3180292:  547:{
        -:  548:  /* Skip one array element */
        -:  549:  int end_pos;
        -:  550:
  3180292:  551:  end_pos = reader->u.array.start_pos + array_reader_get_array_len (reader);
call    0 returned 100%
        -:  552:
        -:  553:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  554:  _dbus_verbose ("  reader %p array next START start_pos = %d end_pos = %d value_pos = %d current_type = %s\n",
        -:  555:                 reader,
        -:  556:                 reader->u.array.start_pos,
        -:  557:                 end_pos, reader->value_pos,
        -:  558:                 _dbus_type_to_string (current_type));
        -:  559:#endif
        -:  560:
  3180292:  561:  _dbus_assert (reader->value_pos < end_pos);
call    0 returned 100%
  3180292:  562:  _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
call    0 returned 100%
        -:  563:
        -:  564:  switch (_dbus_first_type_in_signature (reader->type_str,
  3180292:  565:                                   reader->type_pos))
call    0 returned 100%
branch  1 taken 99%
branch  2 taken 0%
branch  3 taken 1%
        -:  566:    {
        -:  567:    case DBUS_TYPE_DICT_ENTRY:
        -:  568:    case DBUS_TYPE_STRUCT:
        -:  569:    case DBUS_TYPE_VARIANT:
        -:  570:      {
        -:  571:        DBusTypeReader sub;
        -:  572:
        -:  573:        /* Recurse into the struct or variant */
  3180268:  574:        _dbus_type_reader_recurse (reader, &sub);
call    0 returned 100%
        -:  575:
        -:  576:        /* Skip everything in this element */
  6360536:  577:        while (_dbus_type_reader_next (&sub))
call    0 returned 100%
branch  1 taken 50%
branch  2 taken 50% (fallthrough)
        -:  578:          {
        -:  579:            /* nothing */;
        -:  580:          }
        -:  581:
        -:  582:        /* Now we are at the end of this element */
  3180268:  583:        reader->value_pos = sub.value_pos;
        -:  584:      }
  3180268:  585:      break;
        -:  586:
        -:  587:    case DBUS_TYPE_ARRAY:
        -:  588:      {
    #####:  589:        _dbus_marshal_skip_array (reader->value_str,
call    0 never executed
call    1 never executed
        -:  590:                                  _dbus_first_type_in_signature (reader->type_str,
        -:  591:                                                           reader->type_pos + 1),
        -:  592:                                  reader->byte_order,
        -:  593:                                  &reader->value_pos);
        -:  594:      }
    #####:  595:      break;
        -:  596:
        -:  597:    default:
        -:  598:      {
       24:  599:        _dbus_marshal_skip_basic (reader->value_str,
call    0 returned 100%
        -:  600:                                  current_type, reader->byte_order,
        -:  601:                                  &reader->value_pos);
        -:  602:      }
        -:  603:      break;
        -:  604:    }
        -:  605:
        -:  606:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  607:  _dbus_verbose ("  reader %p array next END start_pos = %d end_pos = %d value_pos = %d current_type = %s\n",
        -:  608:                 reader,
        -:  609:                 reader->u.array.start_pos,
        -:  610:                 end_pos, reader->value_pos,
        -:  611:                 _dbus_type_to_string (current_type));
        -:  612:#endif
        -:  613:
  3180292:  614:  _dbus_assert (reader->value_pos <= end_pos);
call    0 returned 100%
        -:  615:
  3180292:  616:  if (reader->value_pos == end_pos)
branch  0 taken 21% (fallthrough)
branch  1 taken 79%
        -:  617:    {
   667377:  618:      skip_one_complete_type (reader->type_str,
call    0 returned 100%
        -:  619:                              &reader->type_pos);
        -:  620:    }
  3180292:  621:}
        -:  622:
        -:  623:static void
        -:  624:array_init_from_mark (DBusTypeReader     *reader,
        -:  625:                      const DBusTypeMark *mark)
function array_init_from_mark called 0 returned 0% blocks executed 0%
    #####:  626:{
        -:  627:  /* Fill in the array-specific fields from the mark. The general
        -:  628:   * fields are already filled in.
        -:  629:   */
    #####:  630:  reader->u.array.start_pos = mark->array_start_pos;
    #####:  631:  reader->array_len_offset = mark->array_len_offset;
    #####:  632:}
        -:  633:
        -:  634:static const DBusTypeReaderClass body_reader_class = {
        -:  635:  "body", 0,
        -:  636:  FALSE,
        -:  637:  NULL, /* body is always toplevel, so doesn't get recursed into */
        -:  638:  NULL,
        -:  639:  base_reader_next,
        -:  640:  NULL
        -:  641:};
        -:  642:
        -:  643:static const DBusTypeReaderClass body_types_only_reader_class = {
        -:  644:  "body types", 1,
        -:  645:  TRUE,
        -:  646:  NULL, /* body is always toplevel, so doesn't get recursed into */
        -:  647:  NULL,
        -:  648:  base_reader_next,
        -:  649:  NULL
        -:  650:};
        -:  651:
        -:  652:static const DBusTypeReaderClass struct_reader_class = {
        -:  653:  "struct", 2,
        -:  654:  FALSE,
        -:  655:  struct_or_dict_entry_reader_recurse,
        -:  656:  NULL,
        -:  657:  struct_reader_next,
        -:  658:  NULL
        -:  659:};
        -:  660:
        -:  661:static const DBusTypeReaderClass struct_types_only_reader_class = {
        -:  662:  "struct types", 3,
        -:  663:  TRUE,
        -:  664:  struct_or_dict_entry_types_only_reader_recurse,
        -:  665:  NULL,
        -:  666:  struct_reader_next,
        -:  667:  NULL
        -:  668:};
        -:  669:
        -:  670:static const DBusTypeReaderClass dict_entry_reader_class = {
        -:  671:  "dict_entry", 4,
        -:  672:  FALSE,
        -:  673:  struct_or_dict_entry_reader_recurse,
        -:  674:  NULL,
        -:  675:  dict_entry_reader_next,
        -:  676:  NULL
        -:  677:};
        -:  678:
        -:  679:static const DBusTypeReaderClass dict_entry_types_only_reader_class = {
        -:  680:  "dict_entry types", 5,
        -:  681:  TRUE,
        -:  682:  struct_or_dict_entry_types_only_reader_recurse,
        -:  683:  NULL,
        -:  684:  dict_entry_reader_next,
        -:  685:  NULL
        -:  686:};
        -:  687:
        -:  688:static const DBusTypeReaderClass array_reader_class = {
        -:  689:  "array", 6,
        -:  690:  FALSE,
        -:  691:  array_reader_recurse,
        -:  692:  array_reader_check_finished,
        -:  693:  array_reader_next,
        -:  694:  array_init_from_mark
        -:  695:};
        -:  696:
        -:  697:static const DBusTypeReaderClass array_types_only_reader_class = {
        -:  698:  "array types", 7,
        -:  699:  TRUE,
        -:  700:  array_types_only_reader_recurse,
        -:  701:  NULL,
        -:  702:  array_types_only_reader_next,
        -:  703:  NULL
        -:  704:};
        -:  705:
        -:  706:static const DBusTypeReaderClass variant_reader_class = {
        -:  707:  "variant", 8,
        -:  708:  FALSE,
        -:  709:  variant_reader_recurse,
        -:  710:  NULL,
        -:  711:  base_reader_next,
        -:  712:  NULL
        -:  713:};
        -:  714:
        -:  715:static const DBusTypeReaderClass const *
        -:  716:all_reader_classes[] = {
        -:  717:  &body_reader_class,
        -:  718:  &body_types_only_reader_class,
        -:  719:  &struct_reader_class,
        -:  720:  &struct_types_only_reader_class,
        -:  721:  &dict_entry_reader_class,
        -:  722:  &dict_entry_types_only_reader_class,
        -:  723:  &array_reader_class,
        -:  724:  &array_types_only_reader_class,
        -:  725:  &variant_reader_class
        -:  726:};
        -:  727:
        -:  728:/**
        -:  729: * Initializes a type reader.
        -:  730: *
        -:  731: * @param reader the reader
        -:  732: * @param byte_order the byte order of the block to read
        -:  733: * @param type_str the signature of the block to read
        -:  734: * @param type_pos location of signature
        -:  735: * @param value_str the string containing values block
        -:  736: * @param value_pos start of values block
        -:  737: */
        -:  738:void
        -:  739:_dbus_type_reader_init (DBusTypeReader    *reader,
        -:  740:                        int                byte_order,
        -:  741:                        const DBusString  *type_str,
        -:  742:                        int                type_pos,
        -:  743:                        const DBusString  *value_str,
        -:  744:                        int                value_pos)
function _dbus_type_reader_init called 802739 returned 100% blocks executed 100%
   802739:  745:{
   802739:  746:  reader->klass = &body_reader_class;
        -:  747:
   802739:  748:  reader_init (reader, byte_order, type_str, type_pos,
call    0 returned 100%
        -:  749:               value_str, value_pos);
        -:  750:
        -:  751:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  752:  _dbus_verbose ("  type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
        -:  753:                 reader, reader->type_pos, reader->value_pos,
        -:  754:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -:  755:#endif
   802739:  756:}
        -:  757:
        -:  758:/**
        -:  759: * Initializes a type reader that's been compressed into a
        -:  760: * DBusTypeMark.  The args have to be the same as those passed in to
        -:  761: * create the original #DBusTypeReader.
        -:  762: *
        -:  763: * @param reader the reader
        -:  764: * @param byte_order the byte order of the value block
        -:  765: * @param type_str string containing the type signature
        -:  766: * @param value_str string containing the values block
        -:  767: * @param mark the mark to decompress from
        -:  768: */
        -:  769:void
        -:  770:_dbus_type_reader_init_from_mark (DBusTypeReader     *reader,
        -:  771:                                  int                 byte_order,
        -:  772:                                  const DBusString   *type_str,
        -:  773:                                  const DBusString   *value_str,
        -:  774:                                  const DBusTypeMark *mark)
function _dbus_type_reader_init_from_mark called 0 returned 0% blocks executed 0%
    #####:  775:{
    #####:  776:  reader->klass = all_reader_classes[mark->container_type];
        -:  777:
    #####:  778:  reader_init (reader, byte_order,
branch  0 never executed
branch  1 never executed
call    2 never executed
        -:  779:               mark->type_pos_in_value_str ? value_str : type_str,
        -:  780:               mark->type_pos,
        -:  781:               value_str, mark->value_pos);
        -:  782:
    #####:  783:  if (reader->klass->init_from_mark)
branch  0 never executed
branch  1 never executed
    #####:  784:    (* reader->klass->init_from_mark) (reader, mark);
call    0 never executed
        -:  785:
        -:  786:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  787:  _dbus_verbose ("  type reader %p init from mark type_pos = %d value_pos = %d remaining sig '%s'\n",
        -:  788:                 reader, reader->type_pos, reader->value_pos,
        -:  789:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -:  790:#endif
    #####:  791:}
        -:  792:
        -:  793:/**
        -:  794: * Like _dbus_type_reader_init() but the iteration is over the
        -:  795: * signature, not over values.
        -:  796: *
        -:  797: * @param reader the reader
        -:  798: * @param type_str the signature string
        -:  799: * @param type_pos location in the signature string
        -:  800: */
        -:  801:void
        -:  802:_dbus_type_reader_init_types_only (DBusTypeReader    *reader,
        -:  803:                                   const DBusString  *type_str,
        -:  804:                                   int                type_pos)
function _dbus_type_reader_init_types_only called 1273885 returned 100% blocks executed 100%
  1273885:  805:{
  1273885:  806:  reader->klass = &body_types_only_reader_class;
        -:  807:
  1273885:  808:  reader_init (reader, DBUS_COMPILER_BYTE_ORDER /* irrelevant */,
call    0 returned 100%
        -:  809:               type_str, type_pos, NULL, _DBUS_INT_MAX /* crashes if we screw up */);
        -:  810:
        -:  811:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  812:  _dbus_verbose ("  type reader %p init types only type_pos = %d remaining sig '%s'\n",
        -:  813:                 reader, reader->type_pos,
        -:  814:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -:  815:#endif
  1273885:  816:}
        -:  817:
        -:  818:/**
        -:  819: * Like _dbus_type_reader_init_from_mark() but only iterates over
        -:  820: * the signature, not the values.
        -:  821: *
        -:  822: * @param reader the reader
        -:  823: * @param type_str the signature string
        -:  824: * @param mark the mark to decompress from
        -:  825: */
        -:  826:void
        -:  827:_dbus_type_reader_init_types_only_from_mark (DBusTypeReader     *reader,
        -:  828:                                             const DBusString   *type_str,
        -:  829:                                             const DBusTypeMark *mark)
function _dbus_type_reader_init_types_only_from_mark called 0 returned 0% blocks executed 0%
    #####:  830:{
    #####:  831:  reader->klass = all_reader_classes[mark->container_type];
    #####:  832:  _dbus_assert (reader->klass->types_only);
call    0 never executed
    #####:  833:  _dbus_assert (!mark->type_pos_in_value_str);
call    0 never executed
        -:  834:
    #####:  835:  reader_init (reader, DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
call    0 never executed
        -:  836:               type_str, mark->type_pos,
        -:  837:               NULL, _DBUS_INT_MAX /* crashes if we screw up */);
        -:  838:
    #####:  839:  if (reader->klass->init_from_mark)
branch  0 never executed
branch  1 never executed
    #####:  840:    (* reader->klass->init_from_mark) (reader, mark);
call    0 never executed
        -:  841:
        -:  842:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  843:  _dbus_verbose ("  type reader %p init types only from mark type_pos = %d remaining sig '%s'\n",
        -:  844:                 reader, reader->type_pos,
        -:  845:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -:  846:#endif
    #####:  847:}
        -:  848:
        -:  849:/**
        -:  850: * Compresses a type reader into a #DBusTypeMark, useful for example
        -:  851: * if you want to cache a bunch of positions in a block of values.
        -:  852: *
        -:  853: * @param reader the reader
        -:  854: * @param mark the mark to init
        -:  855: */
        -:  856:void
        -:  857:_dbus_type_reader_save_mark (const DBusTypeReader *reader,
        -:  858:                             DBusTypeMark         *mark)
function _dbus_type_reader_save_mark called 0 returned 0% blocks executed 0%
    #####:  859:{
    #####:  860:  mark->type_pos_in_value_str = (reader->type_str == reader->value_str);
    #####:  861:  mark->container_type = reader->klass->id;
    #####:  862:  _dbus_assert (all_reader_classes[reader->klass->id] == reader->klass);
call    0 never executed
        -:  863:
    #####:  864:  mark->type_pos = reader->type_pos;
    #####:  865:  mark->value_pos = reader->value_pos;
        -:  866:
        -:  867:  /* these are just junk if the reader isn't really an array of course */
    #####:  868:  mark->array_len_offset = reader->array_len_offset;
    #####:  869:  mark->array_start_pos = reader->u.array.start_pos;
    #####:  870:}
        -:  871:
        -:  872:/**
        -:  873: * Gets the type of the value the reader is currently pointing to;
        -:  874: * or for a types-only reader gets the type it's currently pointing to.
        -:  875: * If the reader is at the end of a block or end of a container such
        -:  876: * as an array, returns #DBUS_TYPE_INVALID.
        -:  877: *
        -:  878: * @param reader the reader
        -:  879: */
        -:  880:int
        -:  881:_dbus_type_reader_get_current_type (const DBusTypeReader *reader)
function _dbus_type_reader_get_current_type called 71431060 returned 100% blocks executed 100%
 71431060:  882:{
        -:  883:  int t;
        -:  884:
 78401450:  885:  if (reader->finished ||
branch  0 taken 92% (fallthrough)
branch  1 taken 8%
branch  2 taken 17% (fallthrough)
branch  3 taken 83%
call    4 returned 100%
branch  5 taken 12% (fallthrough)
branch  6 taken 88%
        -:  886:      (reader->klass->check_finished &&
        -:  887:       (* reader->klass->check_finished) (reader)))
  6970390:  888:    t = DBUS_TYPE_INVALID;
        -:  889:  else
 64460670:  890:    t = _dbus_first_type_in_signature (reader->type_str,
call    0 returned 100%
        -:  891:                                       reader->type_pos);
        -:  892:
 71431060:  893:  _dbus_assert (t != DBUS_STRUCT_END_CHAR);
call    0 returned 100%
 71431060:  894:  _dbus_assert (t != DBUS_STRUCT_BEGIN_CHAR);
call    0 returned 100%
 71431060:  895:  _dbus_assert (t != DBUS_DICT_ENTRY_END_CHAR);
call    0 returned 100%
 71431060:  896:  _dbus_assert (t != DBUS_DICT_ENTRY_BEGIN_CHAR);
call    0 returned 100%
        -:  897:  
        -:  898:#if 0
        -:  899:  _dbus_verbose ("  type reader %p current type_pos = %d type = %s\n",
        -:  900:                 reader, reader->type_pos,
        -:  901:                 _dbus_type_to_string (t));
        -:  902:#endif
        -:  903:
 71431060:  904:  return t;
        -:  905:}
        -:  906:
        -:  907:/**
        -:  908: * Gets the type of an element of the array the reader is currently
        -:  909: * pointing to. It's an error to call this if
        -:  910: * _dbus_type_reader_get_current_type() doesn't return #DBUS_TYPE_ARRAY
        -:  911: * for this reader.
        -:  912: *
        -:  913: * @param reader the reader
        -:  914: */
        -:  915:int
        -:  916:_dbus_type_reader_get_element_type (const DBusTypeReader  *reader)
function _dbus_type_reader_get_element_type called 241084 returned 100% blocks executed 100%
   241084:  917:{
        -:  918:  int element_type;
        -:  919:
   241084:  920:  _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY);
call    0 returned 100%
call    1 returned 100%
        -:  921:
   241084:  922:  element_type = _dbus_first_type_in_signature (reader->type_str,
call    0 returned 100%
        -:  923:                                          reader->type_pos + 1);
        -:  924:
   241084:  925:  return element_type;
        -:  926:}
        -:  927:
        -:  928:/**
        -:  929: * Gets the current position in the value block
        -:  930: * @param reader the reader
        -:  931: */
        -:  932:int
        -:  933:_dbus_type_reader_get_value_pos (const DBusTypeReader  *reader)
function _dbus_type_reader_get_value_pos called 3592870 returned 100% blocks executed 100%
  3592870:  934:{
  3592870:  935:  return reader->value_pos;
        -:  936:}
        -:  937:
        -:  938:/**
        -:  939: * Get the address of the marshaled value in the data being read.  The
        -:  940: * address may not be aligned; you have to align it to the type of the
        -:  941: * value you want to read. Most of the demarshal routines do this for
        -:  942: * you.
        -:  943: *
        -:  944: * @param reader the reader
        -:  945: * @param value_location the address of the marshaled value
        -:  946: */
        -:  947:void
        -:  948:_dbus_type_reader_read_raw (const DBusTypeReader  *reader,
        -:  949:                            const unsigned char  **value_location)
function _dbus_type_reader_read_raw called 0 returned 0% blocks executed 0%
    #####:  950:{
    #####:  951:  _dbus_assert (!reader->klass->types_only);
call    0 never executed
        -:  952:
    #####:  953:  *value_location = _dbus_string_get_const_data_len (reader->value_str,
call    0 never executed
        -:  954:                                                     reader->value_pos,
        -:  955:                                                     0);
    #####:  956:}
        -:  957:
        -:  958:/**
        -:  959: * Reads a basic-typed value, as with _dbus_marshal_read_basic().
        -:  960: *
        -:  961: * @param reader the reader
        -:  962: * @param value the address of the value
        -:  963: */
        -:  964:void
        -:  965:_dbus_type_reader_read_basic (const DBusTypeReader    *reader,
        -:  966:                              void                    *value)
function _dbus_type_reader_read_basic called 4556356 returned 100% blocks executed 100%
  4556356:  967:{
        -:  968:  int t;
        -:  969:
  4556356:  970:  _dbus_assert (!reader->klass->types_only);
call    0 returned 100%
        -:  971:
  4556356:  972:  t = _dbus_type_reader_get_current_type (reader);
call    0 returned 100%
        -:  973:
  4556356:  974:  _dbus_marshal_read_basic (reader->value_str,
call    0 returned 100%
        -:  975:                            reader->value_pos,
        -:  976:                            t, value,
        -:  977:                            reader->byte_order,
        -:  978:                            NULL);
        -:  979:
        -:  980:
        -:  981:#if RECURSIVE_MARSHAL_READ_TRACE
        -:  982:  _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d remaining sig '%s'\n",
        -:  983:                 reader, reader->type_pos, reader->value_pos,
        -:  984:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -:  985:#endif
  4556356:  986:}
        -:  987:
        -:  988:/**
        -:  989: * Returns the number of values remaining in the current array reader.
        -:  990: *
        -:  991: * @param reader the reader to read from
        -:  992: * @returns the number of elements remaining in the array
        -:  993: */
        -:  994:int
        -:  995:_dbus_type_reader_get_array_length (const DBusTypeReader  *reader)
function _dbus_type_reader_get_array_length called 0 returned 0% blocks executed 0%
    #####:  996:{
    #####:  997:  _dbus_assert (!reader->klass->types_only);
call    0 never executed
    #####:  998:  _dbus_assert (reader->klass == &array_reader_class);
call    0 never executed
        -:  999:
    #####: 1000:  return array_reader_get_array_len (reader);
call    0 never executed
        -: 1001:}
        -: 1002:
        -: 1003:/**
        -: 1004: * Reads a block of fixed-length basic values, from the current point
        -: 1005: * in an array to the end of the array.  Does not work for arrays of
        -: 1006: * string or container types.
        -: 1007: *
        -: 1008: * This function returns the array in-place; it does not make a copy,
        -: 1009: * and it does not swap the bytes.
        -: 1010: *
        -: 1011: * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back
        -: 1012: * and the "value" argument should be a "const double**" and so on.
        -: 1013: *
        -: 1014: * @param reader the reader to read from
        -: 1015: * @param value place to return the array values
        -: 1016: * @param n_elements place to return number of array elements
        -: 1017: */
        -: 1018:void
        -: 1019:_dbus_type_reader_read_fixed_multi (const DBusTypeReader  *reader,
        -: 1020:                                    void                  *value,
        -: 1021:                                    int                   *n_elements)
function _dbus_type_reader_read_fixed_multi called 21 returned 100% blocks executed 94%
       21: 1022:{
        -: 1023:  int element_type;
        -: 1024:  int end_pos;
        -: 1025:  int remaining_len;
        -: 1026:  int alignment;
        -: 1027:  int total_len;
        -: 1028:
       21: 1029:  _dbus_assert (!reader->klass->types_only);
call    0 returned 100%
       21: 1030:  _dbus_assert (reader->klass == &array_reader_class);
call    0 returned 100%
        -: 1031:
       21: 1032:  element_type = _dbus_first_type_in_signature (reader->type_str,
call    0 returned 100%
        -: 1033:                                                reader->type_pos);
        -: 1034:
       21: 1035:  _dbus_assert (element_type != DBUS_TYPE_INVALID); /* why we don't use get_current_type() */
call    0 returned 100%
       21: 1036:  _dbus_assert (dbus_type_is_fixed (element_type));
call    0 returned 100%
call    1 returned 100%
        -: 1037:
       21: 1038:  alignment = _dbus_type_get_alignment (element_type);
call    0 returned 100%
        -: 1039:
       21: 1040:  _dbus_assert (reader->value_pos >= reader->u.array.start_pos);
call    0 returned 100%
        -: 1041:
       21: 1042:  total_len = array_reader_get_array_len (reader);
call    0 returned 100%
       21: 1043:  end_pos = reader->u.array.start_pos + total_len;
       21: 1044:  remaining_len = end_pos - reader->value_pos;
        -: 1045:
        -: 1046:#if RECURSIVE_MARSHAL_READ_TRACE
        -: 1047:  _dbus_verbose ("end_pos %d total_len %d remaining_len %d value_pos %d\n",
        -: 1048:                 end_pos, total_len, remaining_len, reader->value_pos);
        -: 1049:#endif
        -: 1050:
       21: 1051:  _dbus_assert (remaining_len <= total_len);
call    0 returned 100%
        -: 1052:
       21: 1053:  if (remaining_len == 0)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####: 1054:    *(const DBusBasicValue**) value = NULL;
        -: 1055:  else
       21: 1056:    *(const DBusBasicValue**) value =
call    0 returned 100%
        -: 1057:      (void*) _dbus_string_get_const_data_len (reader->value_str,
        -: 1058:                                               reader->value_pos,
        -: 1059:                                               remaining_len);
        -: 1060:
       21: 1061:  *n_elements = remaining_len / alignment;
       21: 1062:  _dbus_assert ((remaining_len % alignment) == 0);
call    0 returned 100%
        -: 1063:
        -: 1064:#if RECURSIVE_MARSHAL_READ_TRACE
        -: 1065:  _dbus_verbose ("  type reader %p read fixed array type_pos = %d value_pos = %d remaining sig '%s'\n",
        -: 1066:                 reader, reader->type_pos, reader->value_pos,
        -: 1067:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
        -: 1068:#endif
       21: 1069:}
        -: 1070:
        -: 1071:/**
        -: 1072: * Initialize a new reader pointing to the first type and
        -: 1073: * corresponding value that's a child of the current container. It's
        -: 1074: * an error to call this if the current type is a non-container.
        -: 1075: *
        -: 1076: * Note that DBusTypeReader traverses values, not types. So if you
        -: 1077: * have an empty array of array of int, you can't recurse into it. You
        -: 1078: * can only recurse into each element.
        -: 1079: *
        -: 1080: * @param reader the reader
        -: 1081: * @param sub a reader to init pointing to the first child
        -: 1082: */
        -: 1083:void
        -: 1084:_dbus_type_reader_recurse (DBusTypeReader *reader,
        -: 1085:                           DBusTypeReader *sub)
function _dbus_type_reader_recurse called 15033976 returned 100% blocks executed 76%
 15033976: 1086:{
        -: 1087:  int t;
        -: 1088:
 15033976: 1089:  t = _dbus_first_type_in_signature (reader->type_str, reader->type_pos);
call    0 returned 100%
        -: 1090:
 15033976: 1091:  switch (t)
branch  0 taken 50%
branch  1 taken 1%
branch  2 taken 7%
branch  3 taken 44%
branch  4 taken 0%
        -: 1092:    {
        -: 1093:    case DBUS_TYPE_STRUCT:
  7483976: 1094:      if (reader->klass->types_only)
branch  0 taken 13% (fallthrough)
branch  1 taken 87%
   977632: 1095:        sub->klass = &struct_types_only_reader_class;
        -: 1096:      else
  6506344: 1097:        sub->klass = &struct_reader_class;
  7483976: 1098:      break;
        -: 1099:    case DBUS_TYPE_DICT_ENTRY:
     6504: 1100:      if (reader->klass->types_only)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
     6444: 1101:        sub->klass = &dict_entry_types_only_reader_class;
        -: 1102:      else
       60: 1103:        sub->klass = &dict_entry_reader_class;
     6504: 1104:      break;
        -: 1105:    case DBUS_TYPE_ARRAY:
   993042: 1106:      if (reader->klass->types_only)
branch  0 taken 24% (fallthrough)
branch  1 taken 76%
   233428: 1107:        sub->klass = &array_types_only_reader_class;
        -: 1108:      else
   759614: 1109:        sub->klass = &array_reader_class;
   993042: 1110:      break;
        -: 1111:    case DBUS_TYPE_VARIANT:
  6550454: 1112:      if (reader->klass->types_only)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####: 1113:        _dbus_assert_not_reached ("can't recurse into variant typecode");
call    0 never executed
        -: 1114:      else
  6550454: 1115:        sub->klass = &variant_reader_class;
  6550454: 1116:      break;
        -: 1117:    default:
    #####: 1118:      _dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t));
call    0 never executed
call    1 never executed
        -: 1119:#ifndef DBUS_DISABLE_CHECKS
    #####: 1120:      if (t == DBUS_TYPE_INVALID)
branch  0 never executed
branch  1 never executed
    #####: 1121:        _dbus_warn ("You can't recurse into an empty array or off the end of a message body\n");
call    0 never executed
        -: 1122:#endif /* DBUS_DISABLE_CHECKS */
        -: 1123:
    #####: 1124:      _dbus_assert_not_reached ("don't yet handle recursing into this type");
call    0 never executed
        -: 1125:    }
        -: 1126:
 15033976: 1127:  _dbus_assert (sub->klass == all_reader_classes[sub->klass->id]);
call    0 returned 100%
        -: 1128:
 15033976: 1129:  (* sub->klass->recurse) (sub, reader);
call    0 returned 100%
        -: 1130:
        -: 1131:#if RECURSIVE_MARSHAL_READ_TRACE
        -: 1132:  _dbus_verbose ("  type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
        -: 1133:                 sub, sub->type_pos, sub->value_pos,
        -: 1134:                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
        -: 1135:#endif
 15033976: 1136:}
        -: 1137:
        -: 1138:/**
        -: 1139: * Skip to the next value on this "level". e.g. the next field in a
        -: 1140: * struct, the next value in an array. Returns FALSE at the end of the
        -: 1141: * current container.
        -: 1142: *
        -: 1143: * @param reader the reader
        -: 1144: * @returns FALSE if nothing more to read at or below this level
        -: 1145: */
        -: 1146:dbus_bool_t
        -: 1147:_dbus_type_reader_next (DBusTypeReader *reader)
function _dbus_type_reader_next called 22074359 returned 100% blocks executed 100%
 22074359: 1148:{
        -: 1149:  int t;
        -: 1150:
 22074359: 1151:  t = _dbus_type_reader_get_current_type (reader);
call    0 returned 100%
        -: 1152:
        -: 1153:#if RECURSIVE_MARSHAL_READ_TRACE
        -: 1154:  _dbus_verbose ("  type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
        -: 1155:                 reader, reader->type_pos, reader->value_pos,
        -: 1156:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
        -: 1157:                 _dbus_type_to_string (t));
        -: 1158:#endif
        -: 1159:
 22074359: 1160:  if (t == DBUS_TYPE_INVALID)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        3: 1161:    return FALSE;
        -: 1162:
 22074356: 1163:  (* reader->klass->next) (reader, t);
call    0 returned 100%
        -: 1164:
        -: 1165:#if RECURSIVE_MARSHAL_READ_TRACE
        -: 1166:  _dbus_verbose ("  type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n",
        -: 1167:                 reader, reader->type_pos, reader->value_pos,
        -: 1168:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
        -: 1169:                 _dbus_type_to_string (_dbus_type_reader_get_current_type (reader)));
        -: 1170:#endif
        -: 1171:
 22074356: 1172:  return _dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID;
call    0 returned 100%
        -: 1173:}
        -: 1174:
        -: 1175:/**
        -: 1176: * Check whether there's another value on this "level". e.g. the next
        -: 1177: * field in a struct, the next value in an array. Returns FALSE at the
        -: 1178: * end of the current container.
        -: 1179: *
        -: 1180: * You probably don't want to use this; it makes for an awkward for/while
        -: 1181: * loop. A nicer one is "while ((current_type = get_current_type()) != INVALID)"
        -: 1182: *
        -: 1183: * @param reader the reader
        -: 1184: * @returns FALSE if nothing more to read at or below this level
        -: 1185: */
        -: 1186:dbus_bool_t
        -: 1187:_dbus_type_reader_has_next (const DBusTypeReader *reader)
function _dbus_type_reader_has_next called 0 returned 0% blocks executed 0%
    #####: 1188:{
        -: 1189:  /* Not efficient but works for now. */
        -: 1190:  DBusTypeReader copy;
        -: 1191:
    #####: 1192:  copy = *reader;
    #####: 1193:  return _dbus_type_reader_next (&copy);
call    0 never executed
        -: 1194:}
        -: 1195:
        -: 1196:/**
        -: 1197: * Gets the string and range of said string containing the signature
        -: 1198: * of the current value. Essentially a more complete version of
        -: 1199: * _dbus_type_reader_get_current_type() (returns the full type
        -: 1200: * rather than only the outside of the onion).
        -: 1201: *
        -: 1202: * Note though that the first byte in a struct signature is
        -: 1203: * #DBUS_STRUCT_BEGIN_CHAR while the current type will be
        -: 1204: * #DBUS_TYPE_STRUCT so it isn't true that the first byte of the
        -: 1205: * signature is always the same as the current type. Another
        -: 1206: * difference is that this function will still return a signature when
        -: 1207: * inside an empty array; say you recurse into empty array of int32,
        -: 1208: * the signature is "i" but the current type will always be
        -: 1209: * #DBUS_TYPE_INVALID since there are no elements to be currently
        -: 1210: * pointing to.
        -: 1211: *
        -: 1212: * @param reader the reader
        -: 1213: * @param str_p place to return the string with the type in it
        -: 1214: * @param start_p place to return start of the type
        -: 1215: * @param len_p place to return the length of the type
        -: 1216: */
        -: 1217:void
        -: 1218:_dbus_type_reader_get_signature (const DBusTypeReader  *reader,
        -: 1219:                                 const DBusString     **str_p,
        -: 1220:                                 int                   *start_p,
        -: 1221:                                 int                   *len_p)
function _dbus_type_reader_get_signature called 689321 returned 100% blocks executed 100%
   689321: 1222:{
   689321: 1223:  *str_p = reader->type_str;
   689321: 1224:  *start_p = reader->type_pos;
   689321: 1225:  *len_p = find_len_of_complete_type (reader->type_str, reader->type_pos);
call    0 returned 100%
   689321: 1226:}
        -: 1227:
        -: 1228:typedef struct
        -: 1229:{
        -: 1230:  DBusString replacement;
        -: 1231:  int padding;
        -: 1232:} ReplacementBlock;
        -: 1233:
        -: 1234:static dbus_bool_t
        -: 1235:replacement_block_init (ReplacementBlock *block,
        -: 1236:                        DBusTypeReader   *reader)
function replacement_block_init called 63458 returned 100% blocks executed 100%
    63458: 1237:{
    63458: 1238:  if (!_dbus_string_init (&block->replacement))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      115: 1239:    return FALSE;
        -: 1240:
        -: 1241:  /* % 8 is the padding to have the same align properties in
        -: 1242:   * our replacement string as we do at the position being replaced
        -: 1243:   */
    63343: 1244:  block->padding = reader->value_pos % 8;
        -: 1245:
    63343: 1246:  if (!_dbus_string_lengthen (&block->replacement, block->padding))
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
      102: 1247:    goto oom;
        -: 1248:
    63241: 1249:  return TRUE;
        -: 1250:
      102: 1251: oom:
      102: 1252:  _dbus_string_free (&block->replacement);
call    0 returned 100%
      102: 1253:  return FALSE;
        -: 1254:}
        -: 1255:
        -: 1256:static dbus_bool_t
        -: 1257:replacement_block_replace (ReplacementBlock     *block,
        -: 1258:                           DBusTypeReader       *reader,
        -: 1259:                           const DBusTypeReader *realign_root)
function replacement_block_replace called 63031 returned 100% blocks executed 100%
    63031: 1260:{
        -: 1261:  DBusTypeWriter writer;
        -: 1262:  DBusTypeReader realign_reader;
        -: 1263:  DBusList *fixups;
        -: 1264:  int orig_len;
        -: 1265:
    63031: 1266:  _dbus_assert (realign_root != NULL);
call    0 returned 100%
        -: 1267:
    63031: 1268:  orig_len = _dbus_string_get_length (&block->replacement);
call    0 returned 100%
        -: 1269:
    63031: 1270:  realign_reader = *realign_root;
        -: 1271:
        -: 1272:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1273:  _dbus_verbose ("INITIALIZING replacement block writer %p at value_pos %d\n",
        -: 1274:                 &writer, _dbus_string_get_length (&block->replacement));
        -: 1275:#endif
    63031: 1276:  _dbus_type_writer_init_values_only (&writer,
call    0 returned 100%
call    1 returned 100%
        -: 1277:                                      realign_reader.byte_order,
        -: 1278:                                      realign_reader.type_str,
        -: 1279:                                      realign_reader.type_pos,
        -: 1280:                                      &block->replacement,
        -: 1281:                                      _dbus_string_get_length (&block->replacement));
        -: 1282:
    63031: 1283:  _dbus_assert (realign_reader.value_pos <= reader->value_pos);
call    0 returned 100%
        -: 1284:
        -: 1285:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1286:  _dbus_verbose ("COPYING from reader at value_pos %d to writer %p starting after value_pos %d\n",
        -: 1287:                 realign_reader.value_pos, &writer, reader->value_pos);
        -: 1288:#endif
    63031: 1289:  fixups = NULL;
    63031: 1290:  if (!_dbus_type_writer_write_reader_partial (&writer,
call    0 returned 100%
call    1 returned 100%
branch  2 taken 99% (fallthrough)
branch  3 taken 1%
        -: 1291:                                               &realign_reader,
        -: 1292:                                               reader,
        -: 1293:                                               block->padding,
        -: 1294:                                               _dbus_string_get_length (&block->replacement) - block->padding,
        -: 1295:                                               &fixups))
      471: 1296:    goto oom;
        -: 1297:
        -: 1298:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1299:  _dbus_verbose ("REPLACEMENT at padding %d len %d\n", block->padding,
        -: 1300:                 _dbus_string_get_length (&block->replacement) - block->padding);
        -: 1301:  _dbus_verbose_bytes_of_string (&block->replacement, block->padding,
        -: 1302:                                 _dbus_string_get_length (&block->replacement) - block->padding);
        -: 1303:  _dbus_verbose ("TO BE REPLACED at value_pos = %d (align pad %d) len %d realign_reader.value_pos %d\n",
        -: 1304:                 reader->value_pos, reader->value_pos % 8,
        -: 1305:                 realign_reader.value_pos - reader->value_pos,
        -: 1306:                 realign_reader.value_pos);
        -: 1307:  _dbus_verbose_bytes_of_string (reader->value_str,
        -: 1308:                                 reader->value_pos,
        -: 1309:                                 realign_reader.value_pos - reader->value_pos);
        -: 1310:#endif
        -: 1311:
        -: 1312:  /* Move the replacement into position
        -: 1313:   * (realign_reader should now be at the end of the block to be replaced)
        -: 1314:   */
    62560: 1315:  if (!_dbus_string_replace_len (&block->replacement, block->padding,
call    0 returned 100%
call    1 returned 100%
branch  2 taken 1% (fallthrough)
branch  3 taken 99%
        -: 1316:                                 _dbus_string_get_length (&block->replacement) - block->padding,
        -: 1317:                                 (DBusString*) reader->value_str,
        -: 1318:                                 reader->value_pos,
        -: 1319:                                 realign_reader.value_pos - reader->value_pos))
       21: 1320:    goto oom;
        -: 1321:
        -: 1322:  /* Process our fixups now that we can't have an OOM error */
    62539: 1323:  apply_and_free_fixups (&fixups, reader);
call    0 returned 100%
        -: 1324:
    62539: 1325:  return TRUE;
        -: 1326:
      492: 1327: oom:
      492: 1328:  _dbus_string_set_length (&block->replacement, orig_len);
call    0 returned 100%
      492: 1329:  free_fixups (&fixups);
call    0 returned 100%
      492: 1330:  return FALSE;
        -: 1331:}
        -: 1332:
        -: 1333:static void
        -: 1334:replacement_block_free (ReplacementBlock *block)
function replacement_block_free called 63241 returned 100% blocks executed 100%
    63241: 1335:{
    63241: 1336:  _dbus_string_free (&block->replacement);
call    0 returned 100%
    63241: 1337:}
        -: 1338:
        -: 1339:/* In the variable-length case, we have to fix alignment after we insert.
        -: 1340: * The strategy is as follows:
        -: 1341: *
        -: 1342: *  - pad a new string to have the same alignment as the
        -: 1343: *    start of the current basic value
        -: 1344: *  - write the new basic value
        -: 1345: *  - copy from the original reader to the new string,
        -: 1346: *    which will fix the alignment of types following
        -: 1347: *    the new value
        -: 1348: *    - this copy has to start at realign_root,
        -: 1349: *      but not really write anything until it
        -: 1350: *      passes the value being set
        -: 1351: *    - as an optimization, we can stop copying
        -: 1352: *      when the source and dest values are both
        -: 1353: *      on an 8-boundary, since we know all following
        -: 1354: *      padding and alignment will be identical
        -: 1355: *  - copy the new string back to the original
        -: 1356: *    string, replacing the relevant part of the
        -: 1357: *    original string
        -: 1358: *  - now any arrays in the original string that
        -: 1359: *    contained the replaced string may have the
        -: 1360: *    wrong length; so we have to fix that
        -: 1361: */
        -: 1362:static dbus_bool_t
        -: 1363:reader_set_basic_variable_length (DBusTypeReader       *reader,
        -: 1364:                                  int                   current_type,
        -: 1365:                                  const void           *value,
        -: 1366:                                  const DBusTypeReader *realign_root)
function reader_set_basic_variable_length called 63453 returned 100% blocks executed 100%
    63453: 1367:{
        -: 1368:  dbus_bool_t retval;
        -: 1369:  ReplacementBlock block;
        -: 1370:  DBusTypeWriter writer;
        -: 1371:
    63453: 1372:  _dbus_assert (realign_root != NULL);
call    0 returned 100%
        -: 1373:
    63453: 1374:  retval = FALSE;
        -: 1375:
    63453: 1376:  if (!replacement_block_init (&block, reader))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      217: 1377:    return FALSE;
        -: 1378:
        -: 1379:  /* Write the new basic value */
        -: 1380:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1381:  _dbus_verbose ("INITIALIZING writer %p to write basic value at value_pos %d of replacement string\n",
        -: 1382:                 &writer, _dbus_string_get_length (&block.replacement));
        -: 1383:#endif
    63236: 1384:  _dbus_type_writer_init_values_only (&writer,
call    0 returned 100%
call    1 returned 100%
        -: 1385:                                      reader->byte_order,
        -: 1386:                                      reader->type_str,
        -: 1387:                                      reader->type_pos,
        -: 1388:                                      &block.replacement,
        -: 1389:                                      _dbus_string_get_length (&block.replacement));
        -: 1390:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1391:  _dbus_verbose ("WRITING basic value to writer %p (replacement string)\n", &writer);
        -: 1392:#endif
    63236: 1393:  if (!_dbus_type_writer_write_basic (&writer, current_type, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      210: 1394:    goto out;
        -: 1395:
    63026: 1396:  if (!replacement_block_replace (&block,
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -: 1397:                                  reader,
        -: 1398:                                  realign_root))
      492: 1399:    goto out;
        -: 1400:
    62534: 1401:  retval = TRUE;
        -: 1402:
    63236: 1403: out:
    63236: 1404:  replacement_block_free (&block);
call    0 returned 100%
    63236: 1405:  return retval;
        -: 1406:}
        -: 1407:
        -: 1408:static void
        -: 1409:reader_set_basic_fixed_length (DBusTypeReader *reader,
        -: 1410:                               int             current_type,
        -: 1411:                               const void     *value)
function reader_set_basic_fixed_length called 3441 returned 100% blocks executed 100%
     3441: 1412:{
     3441: 1413:  _dbus_marshal_set_basic ((DBusString*) reader->value_str,
call    0 returned 100%
        -: 1414:                           reader->value_pos,
        -: 1415:                           current_type,
        -: 1416:                           value,
        -: 1417:                           reader->byte_order,
        -: 1418:                           NULL, NULL);
     3441: 1419:}
        -: 1420:
        -: 1421:/**
        -: 1422: * Sets a new value for the basic type value pointed to by the reader,
        -: 1423: * leaving the reader valid to continue reading. Any other readers
        -: 1424: * will be invalidated if you set a variable-length type such as a
        -: 1425: * string.
        -: 1426: *
        -: 1427: * The provided realign_root is the reader to start from when
        -: 1428: * realigning the data that follows the newly-set value. The reader
        -: 1429: * parameter must point to a value below the realign_root parameter.
        -: 1430: * If the type being set is fixed-length, then realign_root may be
        -: 1431: * #NULL. Only values reachable from realign_root will be realigned,
        -: 1432: * so if your string contains other values you will need to deal with
        -: 1433: * those somehow yourself. It is OK if realign_root is the same
        -: 1434: * reader as the reader parameter, though if you aren't setting the
        -: 1435: * root it may not be such a good idea.
        -: 1436: *
        -: 1437: * @todo DBusTypeReader currently takes "const" versions of the type
        -: 1438: * and value strings, and this function modifies those strings by
        -: 1439: * casting away the const, which is of course bad if we want to get
        -: 1440: * picky. (To be truly clean you'd have an object which contained the
        -: 1441: * type and value strings and set_basic would be a method on that
        -: 1442: * object... this would also make DBusTypeReader the same thing as
        -: 1443: * DBusTypeMark. But since DBusMessage is effectively that object for
        -: 1444: * D-BUS it doesn't seem worth creating some random object.)
        -: 1445: *
        -: 1446: * @todo optimize this by only rewriting until the old and new values
        -: 1447: * are at the same alignment. Frequently this should result in only
        -: 1448: * replacing the value that's immediately at hand.
        -: 1449: *
        -: 1450: * @param reader reader indicating where to set a new value
        -: 1451: * @param value address of the value to set
        -: 1452: * @param realign_root realign from here
        -: 1453: * @returns #FALSE if not enough memory
        -: 1454: */
        -: 1455:dbus_bool_t
        -: 1456:_dbus_type_reader_set_basic (DBusTypeReader       *reader,
        -: 1457:                             const void           *value,
        -: 1458:                             const DBusTypeReader *realign_root)
function _dbus_type_reader_set_basic called 66894 returned 100% blocks executed 100%
    66894: 1459:{
        -: 1460:  int current_type;
        -: 1461:
    66894: 1462:  _dbus_assert (!reader->klass->types_only);
call    0 returned 100%
    66894: 1463:  _dbus_assert (reader->value_str == realign_root->value_str);
call    0 returned 100%
    66894: 1464:  _dbus_assert (reader->value_pos >= realign_root->value_pos);
call    0 returned 100%
        -: 1465:
    66894: 1466:  current_type = _dbus_type_reader_get_current_type (reader);
call    0 returned 100%
        -: 1467:
        -: 1468:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1469:  _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",
        -: 1470:                 reader, reader->type_pos, reader->value_pos,
        -: 1471:                 _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0),
        -: 1472:                 realign_root,
        -: 1473:                 realign_root ? realign_root->value_pos : -1,
        -: 1474:                 _dbus_type_to_string (current_type));
        -: 1475:  _dbus_verbose_bytes_of_string (realign_root->value_str, realign_root->value_pos,
        -: 1476:                                 _dbus_string_get_length (realign_root->value_str) -
        -: 1477:                                 realign_root->value_pos);
        -: 1478:#endif
        -: 1479:
    66894: 1480:  _dbus_assert (dbus_type_is_basic (current_type));
call    0 returned 100%
call    1 returned 100%
        -: 1481:
    66894: 1482:  if (dbus_type_is_fixed (current_type))
call    0 returned 100%
branch  1 taken 5% (fallthrough)
branch  2 taken 95%
        -: 1483:    {
     3441: 1484:      reader_set_basic_fixed_length (reader, current_type, value);
call    0 returned 100%
     3441: 1485:      return TRUE;
        -: 1486:    }
        -: 1487:  else
        -: 1488:    {
    63453: 1489:      _dbus_assert (realign_root != NULL);
call    0 returned 100%
    63453: 1490:      return reader_set_basic_variable_length (reader, current_type,
call    0 returned 100%
        -: 1491:                                               value, realign_root);
        -: 1492:    }
        -: 1493:}
        -: 1494:
        -: 1495:/**
        -: 1496: * Recursively deletes any value pointed to by the reader, leaving the
        -: 1497: * reader valid to continue reading. Any other readers will be
        -: 1498: * invalidated.
        -: 1499: *
        -: 1500: * The provided realign_root is the reader to start from when
        -: 1501: * realigning the data that follows the newly-set value.
        -: 1502: * See _dbus_type_reader_set_basic() for more details on the
        -: 1503: * realign_root paramter.
        -: 1504: *
        -: 1505: * @todo for now this does not delete the typecodes associated with
        -: 1506: * the value, so this function should only be used for array elements.
        -: 1507: *
        -: 1508: * @param reader reader indicating where to delete a value
        -: 1509: * @param realign_root realign from here
        -: 1510: * @returns #FALSE if not enough memory
        -: 1511: */
        -: 1512:dbus_bool_t
        -: 1513:_dbus_type_reader_delete (DBusTypeReader        *reader,
        -: 1514:                          const DBusTypeReader  *realign_root)
function _dbus_type_reader_delete called 5 returned 100% blocks executed 83%
        5: 1515:{
        -: 1516:  dbus_bool_t retval;
        -: 1517:  ReplacementBlock block;
        -: 1518:
        5: 1519:  _dbus_assert (realign_root != NULL);
call    0 returned 100%
        5: 1520:  _dbus_assert (reader->klass == &array_reader_class);
call    0 returned 100%
        -: 1521:
        5: 1522:  retval = FALSE;
        -: 1523:
        5: 1524:  if (!replacement_block_init (&block, reader))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1525:    return FALSE;
        -: 1526:
        5: 1527:  if (!replacement_block_replace (&block,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1528:                                  reader,
        -: 1529:                                  realign_root))
    #####: 1530:    goto out;
        -: 1531:
        5: 1532:  retval = TRUE;
        -: 1533:
        5: 1534: out:
        5: 1535:  replacement_block_free (&block);
call    0 returned 100%
        5: 1536:  return retval;
        -: 1537:}
        -: 1538:
        -: 1539:/**
        -: 1540: * Compares two readers, which must be iterating over the same value data.
        -: 1541: * Returns #TRUE if the first parameter is further along than the second parameter.
        -: 1542: *
        -: 1543: * @param lhs left-hand-side (first) parameter
        -: 1544: * @param rhs left-hand-side (first) parameter
        -: 1545: * @returns whether lhs is greater than rhs
        -: 1546: */
        -: 1547:dbus_bool_t
        -: 1548:_dbus_type_reader_greater_than (const DBusTypeReader  *lhs,
        -: 1549:                                const DBusTypeReader  *rhs)
function _dbus_type_reader_greater_than called 3581438 returned 100% blocks executed 100%
  3581438: 1550:{
  3581438: 1551:  _dbus_assert (lhs->value_str == rhs->value_str);
call    0 returned 100%
        -: 1552:
  3581438: 1553:  return lhs->value_pos > rhs->value_pos;
        -: 1554:}
        -: 1555:
        -: 1556:/*
        -: 1557: *
        -: 1558: *
        -: 1559: *         DBusTypeWriter
        -: 1560: *
        -: 1561: *
        -: 1562: *
        -: 1563: */
        -: 1564:
        -: 1565:/**
        -: 1566: * Initialize a write iterator, which is used to write out values in
        -: 1567: * serialized D-BUS format.
        -: 1568: *
        -: 1569: * The type_pos passed in is expected to be inside an already-valid,
        -: 1570: * though potentially empty, type signature. This means that the byte
        -: 1571: * after type_pos must be either #DBUS_TYPE_INVALID (aka nul) or some
        -: 1572: * other valid type. #DBusTypeWriter won't enforce that the signature
        -: 1573: * is already valid (you can append the nul byte at the end if you
        -: 1574: * like), but just be aware that you need the nul byte eventually and
        -: 1575: * #DBusTypeWriter isn't going to write it for you.
        -: 1576: *
        -: 1577: * @param writer the writer to init
        -: 1578: * @param byte_order the byte order to marshal into
        -: 1579: * @param type_str the string to write typecodes into
        -: 1580: * @param type_pos where to insert typecodes
        -: 1581: * @param value_str the string to write values into
        -: 1582: * @param value_pos where to insert values
        -: 1583: *
        -: 1584: */
        -: 1585:void
        -: 1586:_dbus_type_writer_init (DBusTypeWriter *writer,
        -: 1587:                        int             byte_order,
        -: 1588:                        DBusString     *type_str,
        -: 1589:                        int             type_pos,
        -: 1590:                        DBusString     *value_str,
        -: 1591:                        int             value_pos)
function _dbus_type_writer_init called 3284777 returned 100% blocks executed 100%
  3284777: 1592:{
  3284777: 1593:  writer->byte_order = byte_order;
  3284777: 1594:  writer->type_str = type_str;
  3284777: 1595:  writer->type_pos = type_pos;
  3284777: 1596:  writer->value_str = value_str;
  3284777: 1597:  writer->value_pos = value_pos;
  3284777: 1598:  writer->container_type = DBUS_TYPE_INVALID;
  3284777: 1599:  writer->type_pos_is_expectation = FALSE;
  3284777: 1600:  writer->enabled = TRUE;
        -: 1601:
        -: 1602:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1603:  _dbus_verbose ("writer %p init remaining sig '%s'\n", writer,
        -: 1604:                 writer->type_str ?
        -: 1605:                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0) :
        -: 1606:                 "unknown");
        -: 1607:#endif
  3284777: 1608:}
        -: 1609:
        -: 1610:/**
        -: 1611: * Initialize a write iterator, with the signature to be provided
        -: 1612: * later.
        -: 1613: *
        -: 1614: * @param writer the writer to init
        -: 1615: * @param byte_order the byte order to marshal into
        -: 1616: * @param value_str the string to write values into
        -: 1617: * @param value_pos where to insert values
        -: 1618: *
        -: 1619: */
        -: 1620:void
        -: 1621:_dbus_type_writer_init_types_delayed (DBusTypeWriter *writer,
        -: 1622:                                      int             byte_order,
        -: 1623:                                      DBusString     *value_str,
        -: 1624:                                      int             value_pos)
function _dbus_type_writer_init_types_delayed called 51837 returned 100% blocks executed 100%
    51837: 1625:{
    51837: 1626:  _dbus_type_writer_init (writer, byte_order,
call    0 returned 100%
        -: 1627:                          NULL, 0, value_str, value_pos);
    51837: 1628:}
        -: 1629:
        -: 1630:/**
        -: 1631: * Adds type string to the writer, if it had none.
        -: 1632: *
        -: 1633: * @param writer the writer to init
        -: 1634: * @param type_str type string to add
        -: 1635: * @param type_pos type position
        -: 1636: *
        -: 1637: */
        -: 1638:void
        -: 1639:_dbus_type_writer_add_types (DBusTypeWriter *writer,
        -: 1640:                             DBusString     *type_str,
        -: 1641:                             int             type_pos)
function _dbus_type_writer_add_types called 85791 returned 100% blocks executed 100%
    85791: 1642:{
    85791: 1643:  if (writer->type_str == NULL) /* keeps us from using this as setter */
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 1644:    {
    85791: 1645:      writer->type_str = type_str;
    85791: 1646:      writer->type_pos = type_pos;
        -: 1647:    }
    85791: 1648:}
        -: 1649:
        -: 1650:/**
        -: 1651: * Removes type string from the writer.
        -: 1652: *
        -: 1653: * @param writer the writer to remove from
        -: 1654: */
        -: 1655:void
        -: 1656:_dbus_type_writer_remove_types (DBusTypeWriter *writer)
function _dbus_type_writer_remove_types called 85791 returned 100% blocks executed 100%
    85791: 1657:{
    85791: 1658:  writer->type_str = NULL;
    85791: 1659:  writer->type_pos = -1;
    85791: 1660:}
        -: 1661:
        -: 1662:/**
        -: 1663: * Like _dbus_type_writer_init(), except the type string
        -: 1664: * passed in should correspond to an existing signature that
        -: 1665: * matches what you're going to write out. The writer will
        -: 1666: * check what you write vs. this existing signature.
        -: 1667: *
        -: 1668: * @param writer the writer to init
        -: 1669: * @param byte_order the byte order to marshal into
        -: 1670: * @param type_str the string with signature
        -: 1671: * @param type_pos start of signature
        -: 1672: * @param value_str the string to write values into
        -: 1673: * @param value_pos where to insert values
        -: 1674: *
        -: 1675: */
        -: 1676:void
        -: 1677:_dbus_type_writer_init_values_only (DBusTypeWriter   *writer,
        -: 1678:                                    int               byte_order,
        -: 1679:                                    const DBusString *type_str,
        -: 1680:                                    int               type_pos,
        -: 1681:                                    DBusString       *value_str,
        -: 1682:                                    int               value_pos)
function _dbus_type_writer_init_values_only called 561295 returned 100% blocks executed 100%
   561295: 1683:{
   561295: 1684:  _dbus_type_writer_init (writer, byte_order,
call    0 returned 100%
        -: 1685:                          (DBusString*)type_str, type_pos,
        -: 1686:                          value_str, value_pos);
        -: 1687:
   561295: 1688:  writer->type_pos_is_expectation = TRUE;
   561295: 1689:}
        -: 1690:
        -: 1691:static dbus_bool_t
        -: 1692:_dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,
        -: 1693:                                           int             type,
        -: 1694:                                           const void     *value)
function _dbus_type_writer_write_basic_no_typecode called 3310951 returned 100% blocks executed 100%
  3310951: 1695:{
  3310951: 1696:  if (writer->enabled)
branch  0 taken 85% (fallthrough)
branch  1 taken 15%
  2826889: 1697:    return _dbus_marshal_write_basic (writer->value_str,
call    0 returned 100%
        -: 1698:                                      writer->value_pos,
        -: 1699:                                      type,
        -: 1700:                                      value,
        -: 1701:                                      writer->byte_order,
        -: 1702:                                      &writer->value_pos);
        -: 1703:  else
   484062: 1704:    return TRUE;
        -: 1705:}
        -: 1706:
        -: 1707:/* If our parent is an array, things are a little bit complicated.
        -: 1708: *
        -: 1709: * The parent must have a complete element type, such as
        -: 1710: * "i" or "aai" or "(ii)" or "a(ii)". There can't be
        -: 1711: * unclosed parens, or an "a" with no following type.
        -: 1712: *
        -: 1713: * To recurse, the only allowed operation is to recurse into the
        -: 1714: * first type in the element type. So for "i" you can't recurse, for
        -: 1715: * "ai" you can recurse into the array, for "(ii)" you can recurse
        -: 1716: * into the struct.
        -: 1717: *
        -: 1718: * If you recurse into the array for "ai", then you must specify
        -: 1719: * "i" for the element type of the array you recurse into.
        -: 1720: *
        -: 1721: * While inside an array at any level, we need to avoid writing to
        -: 1722: * type_str, since the type only appears once for the whole array,
        -: 1723: * it does not appear for each array element.
        -: 1724: *
        -: 1725: * While inside an array type_pos points to the expected next
        -: 1726: * typecode, rather than the next place we could write a typecode.
        -: 1727: */
        -: 1728:static void
        -: 1729:writer_recurse_init_and_check (DBusTypeWriter *writer,
        -: 1730:                               int             container_type,
        -: 1731:                               DBusTypeWriter *sub)
function writer_recurse_init_and_check called 2619404 returned 100% blocks executed 73%
  2619404: 1732:{
  2619404: 1733:  _dbus_type_writer_init (sub,
call    0 returned 100%
        -: 1734:                          writer->byte_order,
        -: 1735:                          writer->type_str,
        -: 1736:                          writer->type_pos,
        -: 1737:                          writer->value_str,
        -: 1738:                          writer->value_pos);
        -: 1739:
  2619404: 1740:  sub->container_type = container_type;
        -: 1741:
  5225352: 1742:  if (writer->type_pos_is_expectation ||
branch  0 taken 2% (fallthrough)
branch  1 taken 98%
branch  2 taken 43% (fallthrough)
branch  3 taken 57%
branch  4 taken 32% (fallthrough)
branch  5 taken 68%
        -: 1743:      (sub->container_type == DBUS_TYPE_ARRAY || sub->container_type == DBUS_TYPE_VARIANT))
  2605948: 1744:    sub->type_pos_is_expectation = TRUE;
        -: 1745:  else
    13456: 1746:    sub->type_pos_is_expectation = FALSE;
        -: 1747:
  2619404: 1748:  sub->enabled = writer->enabled;
        -: 1749:
        -: 1750:#ifndef DBUS_DISABLE_CHECKS
  2619404: 1751:  if (writer->type_pos_is_expectation && writer->type_str)
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
        -: 1752:    {
        -: 1753:      int expected;
        -: 1754:
  2573241: 1755:      expected = _dbus_first_type_in_signature (writer->type_str, writer->type_pos);
call    0 returned 100%
        -: 1756:
  2573241: 1757:      if (expected != sub->container_type)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1758:        {
    #####: 1759:          _dbus_warn ("Writing an element of type %s, but the expected type here is %s\n",
call    0 never executed
call    1 never executed
call    2 never executed
        -: 1760:                      _dbus_type_to_string (sub->container_type),
        -: 1761:                      _dbus_type_to_string (expected));
    #####: 1762:          _dbus_assert_not_reached ("bad array element or variant content written");
call    0 never executed
        -: 1763:        }
        -: 1764:    }
        -: 1765:#endif /* DBUS_DISABLE_CHECKS */
        -: 1766:
        -: 1767:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1768:  _dbus_verbose ("  type writer %p recurse parent %s type_pos = %d value_pos = %d is_expectation = %d remaining sig '%s' enabled = %d\n",
        -: 1769:                 writer,
        -: 1770:                 _dbus_type_to_string (writer->container_type),
        -: 1771:                 writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
        -: 1772:                 writer->type_str ?
        -: 1773:                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0) :
        -: 1774:                 "unknown",
        -: 1775:                 writer->enabled);
        -: 1776:  _dbus_verbose ("  type writer %p recurse sub %s   type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n",
        -: 1777:                 sub,
        -: 1778:                 _dbus_type_to_string (sub->container_type),
        -: 1779:                 sub->type_pos, sub->value_pos,
        -: 1780:                 sub->type_pos_is_expectation,
        -: 1781:                 sub->enabled);
        -: 1782:#endif
  2619404: 1783:}
        -: 1784:
        -: 1785:static dbus_bool_t
        -: 1786:write_or_verify_typecode (DBusTypeWriter *writer,
        -: 1787:                          int             typecode)
function write_or_verify_typecode called 6289973 returned 100% blocks executed 72%
  6289973: 1788:{
        -: 1789:  /* A subwriter inside an array or variant will have type_pos
        -: 1790:   * pointing to the expected typecode; a writer not inside an array
        -: 1791:   * or variant has type_pos pointing to the next place to insert a
        -: 1792:   * typecode.
        -: 1793:   */
        -: 1794:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1795:  _dbus_verbose ("  type writer %p write_or_verify start type_pos = %d remaining sig '%s' enabled = %d\n",
        -: 1796:                 writer, writer->type_pos,
        -: 1797:                 writer->type_str ?
        -: 1798:                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0) :
        -: 1799:                 "unknown",
        -: 1800:                 writer->enabled);
        -: 1801:#endif
        -: 1802:
  6289973: 1803:  if (writer->type_str == NULL)
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
   242031: 1804:    return TRUE;
        -: 1805:
  6047942: 1806:  if (writer->type_pos_is_expectation)
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
        -: 1807:    {
        -: 1808:#ifndef DBUS_DISABLE_CHECKS
        -: 1809:      {
        -: 1810:        int expected;
        -: 1811:
  5902441: 1812:        expected = _dbus_string_get_byte (writer->type_str, writer->type_pos);
call    0 returned 100%
        -: 1813:
  5902441: 1814:        if (expected != typecode)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1815:          {
    #####: 1816:            _dbus_warn ("Array or variant type requires that type %s be written, but %s was written\n",
call    0 never executed
call    1 never executed
call    2 never executed
        -: 1817:                        _dbus_type_to_string (expected), _dbus_type_to_string (typecode));
    #####: 1818:            _dbus_assert_not_reached ("bad type inserted somewhere inside an array or variant");
call    0 never executed
        -: 1819:          }
        -: 1820:      }
        -: 1821:#endif /* DBUS_DISABLE_CHECKS */
        -: 1822:
        -: 1823:      /* if immediately inside an array we'd always be appending an element,
        -: 1824:       * so the expected type doesn't change; if inside a struct or something
        -: 1825:       * below an array, we need to move through said struct or something.
        -: 1826:       */
  5902441: 1827:      if (writer->container_type != DBUS_TYPE_ARRAY)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
  5882594: 1828:        writer->type_pos += 1;
        -: 1829:    }
        -: 1830:  else
        -: 1831:    {
   145501: 1832:      if (!_dbus_string_insert_byte (writer->type_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1833:                                     writer->type_pos,
        -: 1834:                                     typecode))
    #####: 1835:        return FALSE;
        -: 1836:
   145501: 1837:      writer->type_pos += 1;
        -: 1838:    }
        -: 1839:
        -: 1840:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 1841:  _dbus_verbose ("  type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n",
        -: 1842:                 writer, writer->type_pos,
        -: 1843:                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));
        -: 1844:#endif
        -: 1845:
  6047942: 1846:  return TRUE;
        -: 1847:}
        -: 1848:
        -: 1849:static dbus_bool_t
        -: 1850:writer_recurse_struct_or_dict_entry (DBusTypeWriter   *writer,
        -: 1851:                                     int               begin_char,
        -: 1852:                                     const DBusString *contained_type,
        -: 1853:                                     int               contained_type_start,
        -: 1854:                                     int               contained_type_len,
        -: 1855:                                     DBusTypeWriter   *sub)
function writer_recurse_struct_or_dict_entry called 1054786 returned 100% blocks executed 86%
  1054786: 1856:{
        -: 1857:  /* FIXME right now contained_type is ignored; we could probably
        -: 1858:   * almost trivially fix the code so if it's present we
        -: 1859:   * write it out and then set type_pos_is_expectation
        -: 1860:   */
        -: 1861:
        -: 1862:  /* Ensure that we'll be able to add alignment padding and the typecode */
  1054786: 1863:  if (writer->enabled)
branch  0 taken 77% (fallthrough)
branch  1 taken 23%
        -: 1864:    {
   812755: 1865:      if (!_dbus_string_alloc_space (sub->value_str, 8))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      222: 1866:        return FALSE;
        -: 1867:    }
        -: 1868:
  1054564: 1869:  if (!write_or_verify_typecode (sub, begin_char))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1870:    _dbus_assert_not_reached ("failed to insert struct typecode after prealloc");
call    0 never executed
        -: 1871:
  1054564: 1872:  if (writer->enabled)
branch  0 taken 77% (fallthrough)
branch  1 taken 23%
        -: 1873:    {
   812533: 1874:      if (!_dbus_string_insert_bytes (sub->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1875:                                      sub->value_pos,
        -: 1876:                                      _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
        -: 1877:                                      '\0'))
    #####: 1878:        _dbus_assert_not_reached ("should not have failed to insert alignment padding for struct");
call    0 never executed
   812533: 1879:      sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
        -: 1880:    }
        -: 1881:
  1054564: 1882:  return TRUE;
        -: 1883:}
        -: 1884:
        -: 1885:
        -: 1886:static dbus_bool_t
        -: 1887:writer_recurse_array (DBusTypeWriter   *writer,
        -: 1888:                      const DBusString *contained_type,
        -: 1889:                      int               contained_type_start,
        -: 1890:                      int               contained_type_len,
        -: 1891:                      DBusTypeWriter   *sub,
        -: 1892:                      dbus_bool_t       is_array_append)
function writer_recurse_array called 524404 returned 100% blocks executed 75%
   524404: 1893:{
   524404: 1894:  dbus_uint32_t value = 0;
        -: 1895:  int alignment;
        -: 1896:  int aligned;
        -: 1897:
        -: 1898:#ifndef DBUS_DISABLE_CHECKS
   524404: 1899:  if (writer->container_type == DBUS_TYPE_ARRAY &&
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
        -: 1900:      writer->type_str)
        -: 1901:    {
    #####: 1902:      if (!_dbus_string_equal_substring (contained_type,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1903:                                         contained_type_start,
        -: 1904:                                         contained_type_len,
        -: 1905:                                         writer->type_str,
        -: 1906:                                         writer->u.array.element_type_pos + 1))
        -: 1907:        {
    #####: 1908:          _dbus_warn ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
call    0 never executed
call    1 never executed
        -: 1909:                      _dbus_string_get_const_data_len (contained_type,
        -: 1910:                                                       contained_type_start,
        -: 1911:                                                       contained_type_len));
    #####: 1912:          _dbus_assert_not_reached ("incompatible type for child array");
call    0 never executed
        -: 1913:        }
        -: 1914:    }
        -: 1915:#endif /* DBUS_DISABLE_CHECKS */
        -: 1916:
   524404: 1917:  if (writer->enabled && !is_array_append)
branch  0 taken 88% (fallthrough)
branch  1 taken 12%
branch  2 taken 37% (fallthrough)
branch  3 taken 63%
        -: 1918:    {
        -: 1919:      /* 3 pad + 4 bytes for the array length, and 4 bytes possible padding
        -: 1920:       * before array values
        -: 1921:       */
   169337: 1922:      if (!_dbus_string_alloc_space (sub->value_str, 3 + 4 + 4))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1923:        return FALSE;
        -: 1924:    }
        -: 1925:
   524404: 1926:  if (writer->type_str != NULL)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 1927:    {
   524404: 1928:      sub->type_pos += 1; /* move to point to the element type, since type_pos
        -: 1929:                           * should be the expected type for further writes
        -: 1930:                           */
   524404: 1931:      sub->u.array.element_type_pos = sub->type_pos;
        -: 1932:    }
        -: 1933:
   524404: 1934:  if (!writer->type_pos_is_expectation)
branch  0 taken 5% (fallthrough)
branch  1 taken 95%
        -: 1935:    {
        -: 1936:      /* sub is a toplevel/outermost array so we need to write the type data */
        -: 1937:
        -: 1938:      /* alloc space for array typecode, element signature */
    26345: 1939:      if (!_dbus_string_alloc_space (writer->type_str, 1 + contained_type_len))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1940:        return FALSE;
        -: 1941:
    26345: 1942:      if (!_dbus_string_insert_byte (writer->type_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1943:                                     writer->type_pos,
        -: 1944:                                     DBUS_TYPE_ARRAY))
    #####: 1945:        _dbus_assert_not_reached ("failed to insert array typecode after prealloc");
call    0 never executed
        -: 1946:
    26345: 1947:      if (!_dbus_string_copy_len (contained_type,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1948:                                  contained_type_start, contained_type_len,
        -: 1949:                                  sub->type_str,
        -: 1950:                                  sub->u.array.element_type_pos))
    #####: 1951:        _dbus_assert_not_reached ("should not have failed to insert array element typecodes");
call    0 never executed
        -: 1952:    }
        -: 1953:
   524404: 1954:  if (writer->type_str != NULL)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 1955:    {
        -: 1956:      /* If the parent is an array, we hold type_pos pointing at the array element type;
        -: 1957:       * otherwise advance it to reflect the array value we just recursed into
        -: 1958:       */
   524404: 1959:      if (writer->container_type != DBUS_TYPE_ARRAY)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
   524404: 1960:        writer->type_pos += 1 + contained_type_len;
        -: 1961:      else
    #####: 1962:        _dbus_assert (writer->type_pos_is_expectation); /* because it's an array */
call    0 never executed
        -: 1963:    }
        -: 1964:
   524404: 1965:  if (writer->enabled)
branch  0 taken 88% (fallthrough)
branch  1 taken 12%
        -: 1966:    {
        -: 1967:      /* Write (or jump over, if is_array_append) the length */
   461373: 1968:      sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);
        -: 1969:
   461373: 1970:      if (is_array_append)
branch  0 taken 63% (fallthrough)
branch  1 taken 37%
        -: 1971:        {
   292036: 1972:          sub->value_pos += 4;
        -: 1973:        }
        -: 1974:      else
        -: 1975:        {
   169337: 1976:          if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1977:                                                          &value))
    #####: 1978:            _dbus_assert_not_reached ("should not have failed to insert array len");
call    0 never executed
        -: 1979:        }
        -: 1980:
   461373: 1981:      _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);
call    0 returned 100%
        -: 1982:
        -: 1983:      /* Write alignment padding for array elements
        -: 1984:       * Note that we write the padding *even for empty arrays*
        -: 1985:       * to avoid wonky special cases
        -: 1986:       */
   461373: 1987:      alignment = element_type_get_alignment (contained_type, contained_type_start);
call    0 returned 100%
        -: 1988:
   461373: 1989:      aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
   461373: 1990:      if (aligned != sub->value_pos)
branch  0 taken 2% (fallthrough)
branch  1 taken 98%
        -: 1991:        {
    11228: 1992:          if (!is_array_append)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 1993:            {
    11228: 1994:              if (!_dbus_string_insert_bytes (sub->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1995:                                              sub->value_pos,
        -: 1996:                                              aligned - sub->value_pos,
        -: 1997:                                              '\0'))
    #####: 1998:                _dbus_assert_not_reached ("should not have failed to insert alignment padding");
call    0 never executed
        -: 1999:            }
        -: 2000:
    11228: 2001:          sub->value_pos = aligned;
        -: 2002:        }
        -: 2003:
   461373: 2004:      sub->u.array.start_pos = sub->value_pos;
        -: 2005:
   461373: 2006:      if (is_array_append)
branch  0 taken 63% (fallthrough)
branch  1 taken 37%
        -: 2007:        {
        -: 2008:          dbus_uint32_t len;
        -: 2009:
   292036: 2010:          _dbus_assert (_DBUS_ALIGN_VALUE (sub->u.array.len_pos, 4) ==
call    0 returned 100%
        -: 2011:                        (unsigned) sub->u.array.len_pos);
   292036: 2012:          len = _dbus_unpack_uint32 (sub->byte_order,
call    0 returned 100%
call    1 returned 100%
        -: 2013:                                     _dbus_string_get_const_data_len (sub->value_str,
        -: 2014:                                                                      sub->u.array.len_pos,
        -: 2015:                                                                      4));
        -: 2016:
   292036: 2017:          sub->value_pos += len;
        -: 2018:        }
        -: 2019:    }
        -: 2020:  else
        -: 2021:    {
        -: 2022:      /* not enabled, so we won't write the len_pos; set it to -1 to so indicate */
    63031: 2023:      sub->u.array.len_pos = -1;
    63031: 2024:      sub->u.array.start_pos = sub->value_pos;
        -: 2025:    }
        -: 2026:
   524404: 2027:  _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
call    0 returned 100%
   524404: 2028:  _dbus_assert (is_array_append || sub->u.array.start_pos == sub->value_pos);
branch  0 taken 44% (fallthrough)
branch  1 taken 56%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
call    4 returned 100%
        -: 2029:
        -: 2030:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2031:      _dbus_verbose ("  type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d value_pos = %d\n", sub,
        -: 2032:                     sub->type_str ?
        -: 2033:                     _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0) :
        -: 2034:                     "unknown",
        -: 2035:                     sub->u.array.start_pos, sub->u.array.len_pos, sub->value_pos);
        -: 2036:#endif
        -: 2037:
   524404: 2038:  return TRUE;
        -: 2039:}
        -: 2040:
        -: 2041:/* Variant value will normally have:
        -: 2042: *   1 byte signature length not including nul
        -: 2043: *   signature typecodes (nul terminated)
        -: 2044: *   padding to alignment of contained type
        -: 2045: *   body according to signature
        -: 2046: *
        -: 2047: * The signature string can only have a single type
        -: 2048: * in it but that type may be complex/recursive.
        -: 2049: *
        -: 2050: * So a typical variant type with the integer 3 will have these
        -: 2051: * octets:
        -: 2052: *   0x1 'i' '\0' [1 byte padding to alignment boundary] 0x0 0x0 0x0 0x3
        -: 2053: *
        -: 2054: * The main world of hurt for writing out a variant is that the type
        -: 2055: * string is the same string as the value string. Which means
        -: 2056: * inserting to the type string will move the value_pos; and it means
        -: 2057: * that inserting to the type string could break type alignment.
        -: 2058: */
        -: 2059:static dbus_bool_t
        -: 2060:writer_recurse_variant (DBusTypeWriter   *writer,
        -: 2061:                        const DBusString *contained_type,
        -: 2062:                        int               contained_type_start,
        -: 2063:                        int               contained_type_len,
        -: 2064:                        DBusTypeWriter   *sub)
function writer_recurse_variant called 1040214 returned 100% blocks executed 80%
  1040214: 2065:{
        -: 2066:  int contained_alignment;
        -: 2067:  
  1040214: 2068:  if (writer->enabled)
branch  0 taken 77% (fallthrough)
branch  1 taken 23%
        -: 2069:    {
        -: 2070:      /* Allocate space for the worst case, which is 1 byte sig
        -: 2071:       * length, nul byte at end of sig, and 7 bytes padding to
        -: 2072:       * 8-boundary.
        -: 2073:       */
   798183: 2074:      if (!_dbus_string_alloc_space (sub->value_str, contained_type_len + 9))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      237: 2075:        return FALSE;
        -: 2076:    }
        -: 2077:
        -: 2078:  /* write VARIANT typecode to the parent's type string */
  1039977: 2079:  if (!write_or_verify_typecode (writer, DBUS_TYPE_VARIANT))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2080:    return FALSE;
        -: 2081:
        -: 2082:  /* If not enabled, mark that we have no type_str anymore ... */
        -: 2083:
  1039977: 2084:  if (!writer->enabled)
branch  0 taken 23% (fallthrough)
branch  1 taken 77%
        -: 2085:    {
   242031: 2086:      sub->type_str = NULL;
   242031: 2087:      sub->type_pos = -1;
        -: 2088:
   242031: 2089:      return TRUE;
        -: 2090:    }
        -: 2091:
        -: 2092:  /* If we're enabled then continue ... */
        -: 2093:
   797946: 2094:  if (!_dbus_string_insert_byte (sub->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 2095:                                 sub->value_pos,
        -: 2096:                                 contained_type_len))
    #####: 2097:    _dbus_assert_not_reached ("should not have failed to insert variant type sig len");
call    0 never executed
        -: 2098:
   797946: 2099:  sub->value_pos += 1;
        -: 2100:
        -: 2101:  /* Here we switch over to the expected type sig we're about to write */
   797946: 2102:  sub->type_str = sub->value_str;
   797946: 2103:  sub->type_pos = sub->value_pos;
        -: 2104:
   797946: 2105:  if (!_dbus_string_copy_len (contained_type, contained_type_start, contained_type_len,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 2106:                              sub->value_str, sub->value_pos))
    #####: 2107:    _dbus_assert_not_reached ("should not have failed to insert variant type sig");
call    0 never executed
        -: 2108:
   797946: 2109:  sub->value_pos += contained_type_len;
        -: 2110:
   797946: 2111:  if (!_dbus_string_insert_byte (sub->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 2112:                                 sub->value_pos,
        -: 2113:                                 DBUS_TYPE_INVALID))
    #####: 2114:    _dbus_assert_not_reached ("should not have failed to insert variant type nul termination");
call    0 never executed
        -: 2115:
   797946: 2116:  sub->value_pos += 1;
        -: 2117:
   797946: 2118:  contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (contained_type, contained_type_start));
call    0 returned 100%
call    1 returned 100%
        -: 2119:  
   797946: 2120:  if (!_dbus_string_insert_bytes (sub->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 2121:                                  sub->value_pos,
        -: 2122:                                  _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment) - sub->value_pos,
        -: 2123:                                  '\0'))
    #####: 2124:    _dbus_assert_not_reached ("should not have failed to insert alignment padding for variant body");
call    0 never executed
   797946: 2125:  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment);
        -: 2126:
   797946: 2127:  return TRUE;
        -: 2128:}
        -: 2129:
        -: 2130:static dbus_bool_t
        -: 2131:_dbus_type_writer_recurse_contained_len (DBusTypeWriter   *writer,
        -: 2132:                                         int               container_type,
        -: 2133:                                         const DBusString *contained_type,
        -: 2134:                                         int               contained_type_start,
        -: 2135:                                         int               contained_type_len,
        -: 2136:                                         DBusTypeWriter   *sub,
        -: 2137:                                         dbus_bool_t       is_array_append)
function _dbus_type_writer_recurse_contained_len called 2619404 returned 100% blocks executed 92%
  2619404: 2138:{
  2619404: 2139:  writer_recurse_init_and_check (writer, container_type, sub);
call    0 returned 100%
        -: 2140:
  2619404: 2141:  switch (container_type)
branch  0 taken 40%
branch  1 taken 1%
branch  2 taken 20%
branch  3 taken 40%
branch  4 taken 0%
        -: 2142:    {
        -: 2143:    case DBUS_TYPE_STRUCT:
  1047530: 2144:      return writer_recurse_struct_or_dict_entry (writer,
call    0 returned 100%
        -: 2145:                                                  DBUS_STRUCT_BEGIN_CHAR,
        -: 2146:                                                  contained_type,
        -: 2147:                                                  contained_type_start, contained_type_len,
        -: 2148:                                                  sub);
        -: 2149:      break;
        -: 2150:    case DBUS_TYPE_DICT_ENTRY:
     7256: 2151:      return writer_recurse_struct_or_dict_entry (writer,
call    0 returned 100%
        -: 2152:                                                  DBUS_DICT_ENTRY_BEGIN_CHAR,
        -: 2153:                                                  contained_type,
        -: 2154:                                                  contained_type_start, contained_type_len,
        -: 2155:                                                  sub);
        -: 2156:      break;
        -: 2157:    case DBUS_TYPE_ARRAY:
   524404: 2158:      return writer_recurse_array (writer,
call    0 returned 100%
        -: 2159:                                   contained_type, contained_type_start, contained_type_len,
        -: 2160:                                   sub, is_array_append);
        -: 2161:      break;
        -: 2162:    case DBUS_TYPE_VARIANT:
  1040214: 2163:      return writer_recurse_variant (writer,
call    0 returned 100%
        -: 2164:                                     contained_type, contained_type_start, contained_type_len,
        -: 2165:                                     sub);
        -: 2166:      break;
        -: 2167:    default:
    #####: 2168:      _dbus_assert_not_reached ("tried to recurse into type that doesn't support that");
call    0 never executed
        -: 2169:      return FALSE;
        -: 2170:      break;
        -: 2171:    }
        -: 2172:}
        -: 2173:
        -: 2174:/**
        -: 2175: * Opens a new container and writes out the initial information for that container.
        -: 2176: *
        -: 2177: * @param writer the writer
        -: 2178: * @param container_type the type of the container to open
        -: 2179: * @param contained_type the array element type or variant content type
        -: 2180: * @param contained_type_start position to look for the type
        -: 2181: * @param sub the new sub-writer to write container contents
        -: 2182: * @returns #FALSE if no memory
        -: 2183: */
        -: 2184:dbus_bool_t
        -: 2185:_dbus_type_writer_recurse (DBusTypeWriter   *writer,
        -: 2186:                           int               container_type,
        -: 2187:                           const DBusString *contained_type,
        -: 2188:                           int               contained_type_start,
        -: 2189:                           DBusTypeWriter   *sub)
function _dbus_type_writer_recurse called 1638071 returned 100% blocks executed 100%
  1638071: 2190:{
        -: 2191:  int contained_type_len;
        -: 2192:
  1638071: 2193:  if (contained_type)
branch  0 taken 55% (fallthrough)
branch  1 taken 45%
   896491: 2194:    contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
call    0 returned 100%
        -: 2195:  else
   741580: 2196:    contained_type_len = 0;
        -: 2197:
  1638071: 2198:  return _dbus_type_writer_recurse_contained_len (writer, container_type,
call    0 returned 100%
        -: 2199:                                                  contained_type,
        -: 2200:                                                  contained_type_start,
        -: 2201:                                                  contained_type_len,
        -: 2202:                                                  sub,
        -: 2203:                                                  FALSE);
        -: 2204:}
        -: 2205:
        -: 2206:/**
        -: 2207: * Append to an existing array. Essentially, the writer will read an
        -: 2208: * existing length at the write location; jump over that length; and
        -: 2209: * write new fields. On unrecurse(), the existing length will be
        -: 2210: * updated.
        -: 2211: *
        -: 2212: * @param writer the writer
        -: 2213: * @param contained_type element type
        -: 2214: * @param contained_type_start position of element type
        -: 2215: * @param sub the subwriter to init
        -: 2216: * @returns #FALSE if no memory
        -: 2217: */
        -: 2218:dbus_bool_t
        -: 2219:_dbus_type_writer_append_array (DBusTypeWriter   *writer,
        -: 2220:                                const DBusString *contained_type,
        -: 2221:                                int               contained_type_start,
        -: 2222:                                DBusTypeWriter   *sub)
function _dbus_type_writer_append_array called 292036 returned 100% blocks executed 83%
   292036: 2223:{
        -: 2224:  int contained_type_len;
        -: 2225:
   292036: 2226:  if (contained_type)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
   292036: 2227:    contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
call    0 returned 100%
        -: 2228:  else
    #####: 2229:    contained_type_len = 0;
        -: 2230:
   292036: 2231:  return _dbus_type_writer_recurse_contained_len (writer, DBUS_TYPE_ARRAY,
call    0 returned 100%
        -: 2232:                                                  contained_type,
        -: 2233:                                                  contained_type_start,
        -: 2234:                                                  contained_type_len,
        -: 2235:                                                  sub,
        -: 2236:                                                  TRUE);
        -: 2237:}
        -: 2238:
        -: 2239:static int
        -: 2240:writer_get_array_len (DBusTypeWriter *writer)
function writer_get_array_len called 523801 returned 100% blocks executed 100%
   523801: 2241:{
   523801: 2242:  _dbus_assert (writer->container_type == DBUS_TYPE_ARRAY);
call    0 returned 100%
   523801: 2243:  return writer->value_pos - writer->u.array.start_pos;
        -: 2244:}
        -: 2245:
        -: 2246:/**
        -: 2247: * Closes a container created by _dbus_type_writer_recurse()
        -: 2248: * and writes any additional information to the values block.
        -: 2249: *
        -: 2250: * @param writer the writer
        -: 2251: * @param sub the sub-writer created by _dbus_type_writer_recurse()
        -: 2252: * @returns #FALSE if no memory
        -: 2253: */
        -: 2254:dbus_bool_t
        -: 2255:_dbus_type_writer_unrecurse (DBusTypeWriter *writer,
        -: 2256:                             DBusTypeWriter *sub)
function _dbus_type_writer_unrecurse called 2617817 returned 100% blocks executed 90%
  2617817: 2257:{
        -: 2258:  /* type_pos_is_expectation never gets unset once set, or we'd get all hosed */
  2617817: 2259:  _dbus_assert (!writer->type_pos_is_expectation ||
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
call    6 returned 100%
        -: 2260:                (writer->type_pos_is_expectation && sub->type_pos_is_expectation));
        -: 2261:
        -: 2262:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2263:  _dbus_verbose ("  type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
        -: 2264:                 writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
        -: 2265:                 _dbus_type_to_string (writer->container_type));
        -: 2266:  _dbus_verbose ("  type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n",
        -: 2267:                 sub, sub->type_pos, sub->value_pos,
        -: 2268:                 sub->type_pos_is_expectation,
        -: 2269:                 _dbus_type_to_string (sub->container_type));
        -: 2270:#endif
        -: 2271:
  2617817: 2272:  if (sub->container_type == DBUS_TYPE_STRUCT)
branch  0 taken 40% (fallthrough)
branch  1 taken 60%
        -: 2273:    {
  1046927: 2274:      if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2275:        return FALSE;
        -: 2276:    }
  1570890: 2277:  else if (sub->container_type == DBUS_TYPE_DICT_ENTRY)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -: 2278:    {
     7256: 2279:      if (!write_or_verify_typecode (sub, DBUS_DICT_ENTRY_END_CHAR))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2280:        return FALSE;
        -: 2281:    }
  1563634: 2282:  else if (sub->container_type == DBUS_TYPE_ARRAY)
branch  0 taken 33% (fallthrough)
branch  1 taken 67%
        -: 2283:    {
   523801: 2284:      if (sub->u.array.len_pos >= 0) /* len_pos == -1 if we weren't enabled when we passed it */
branch  0 taken 88% (fallthrough)
branch  1 taken 12%
        -: 2285:        {
        -: 2286:          dbus_uint32_t len;
        -: 2287:
        -: 2288:          /* Set the array length */
   461136: 2289:          len = writer_get_array_len (sub);
call    0 returned 100%
   461136: 2290:          _dbus_marshal_set_uint32 (sub->value_str,
call    0 returned 100%
        -: 2291:                                    sub->u.array.len_pos,
        -: 2292:                                    len,
        -: 2293:                                    sub->byte_order);
        -: 2294:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2295:          _dbus_verbose ("    filled in sub array len to %u at len_pos %d\n",
        -: 2296:                         len, sub->u.array.len_pos);
        -: 2297:#endif
        -: 2298:        }
        -: 2299:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2300:      else
        -: 2301:        {
        -: 2302:          _dbus_verbose ("    not filling in sub array len because we were disabled when we passed the len\n");
        -: 2303:        }
        -: 2304:#endif
        -: 2305:    }
        -: 2306:
        -: 2307:  /* Now get type_pos right for the parent writer. Here are the cases:
        -: 2308:   *
        -: 2309:   * Cases !writer->type_pos_is_expectation:
        -: 2310:   *   (in these cases we want to update to the new insertion point)
        -: 2311:   *
        -: 2312:   * - if we recursed into a STRUCT then we didn't know in advance
        -: 2313:   *   what the types in the struct would be; so we have to fill in
        -: 2314:   *   that information now.
        -: 2315:   *       writer->type_pos = sub->type_pos
        -: 2316:   *
        -: 2317:   * - if we recursed into anything else, we knew the full array
        -: 2318:   *   type, or knew the single typecode marking VARIANT, so
        -: 2319:   *   writer->type_pos is already correct.
        -: 2320:   *       writer->type_pos should remain as-is
        -: 2321:   *
        -: 2322:   * - note that the parent is never an ARRAY or VARIANT, if it were
        -: 2323:   *   then type_pos_is_expectation would be TRUE. The parent
        -: 2324:   *   is thus known to be a toplevel or STRUCT.
        -: 2325:   *
        -: 2326:   * Cases where writer->type_pos_is_expectation:
        -: 2327:   *   (in these cases we want to update to next expected type to write)
        -: 2328:   *
        -: 2329:   * - we recursed from STRUCT into STRUCT and we didn't increment
        -: 2330:   *   type_pos in the parent just to stay consistent with the
        -: 2331:   *   !writer->type_pos_is_expectation case (though we could
        -: 2332:   *   special-case this in recurse_struct instead if we wanted)
        -: 2333:   *       writer->type_pos = sub->type_pos
        -: 2334:   *
        -: 2335:   * - we recursed from STRUCT into ARRAY or VARIANT and type_pos
        -: 2336:   *   for parent should have been incremented already
        -: 2337:   *       writer->type_pos should remain as-is
        -: 2338:   *
        -: 2339:   * - we recursed from ARRAY into a sub-element, so type_pos in the
        -: 2340:   *   parent is the element type and should remain the element type
        -: 2341:   *   for the benefit of the next child element
        -: 2342:   *       writer->type_pos should remain as-is
        -: 2343:   *
        -: 2344:   * - we recursed from VARIANT into its value, so type_pos in the
        -: 2345:   *   parent makes no difference since there's only one value
        -: 2346:   *   and we just finished writing it and won't use type_pos again
        -: 2347:   *       writer->type_pos should remain as-is
        -: 2348:   *
        -: 2349:   *
        -: 2350:   * For all these, DICT_ENTRY is the same as STRUCT
        -: 2351:   */
  2617817: 2352:  if (writer->type_str != NULL)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 2353:    {
  2617817: 2354:      if ((sub->container_type == DBUS_TYPE_STRUCT ||
branch  0 taken 60% (fallthrough)
branch  1 taken 40%
branch  2 taken 1% (fallthrough)
branch  3 taken 99%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 1% (fallthrough)
branch  9 taken 99%
        -: 2355:           sub->container_type == DBUS_TYPE_DICT_ENTRY) &&
        -: 2356:          (writer->container_type == DBUS_TYPE_STRUCT ||
        -: 2357:           writer->container_type == DBUS_TYPE_DICT_ENTRY ||
        -: 2358:           writer->container_type == DBUS_TYPE_INVALID))
        -: 2359:        {
        -: 2360:          /* Advance the parent to the next struct field */
    13456: 2361:          writer->type_pos = sub->type_pos;
        -: 2362:        }
        -: 2363:    }
        -: 2364:
  2617817: 2365:  writer->value_pos = sub->value_pos;
        -: 2366:
        -: 2367:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2368:  _dbus_verbose ("  type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n",
        -: 2369:                 writer, writer->type_pos, writer->value_pos,
        -: 2370:                 writer->type_str ?
        -: 2371:                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0) :
        -: 2372:                 "unknown");
        -: 2373:#endif
        -: 2374:
  2617817: 2375:  return TRUE;
        -: 2376:}
        -: 2377:
        -: 2378:/**
        -: 2379: * Writes out a basic type.
        -: 2380: *
        -: 2381: * @param writer the writer
        -: 2382: * @param type the type to write
        -: 2383: * @param value the address of the value to write
        -: 2384: * @returns #FALSE if no memory
        -: 2385: */
        -: 2386:dbus_bool_t
        -: 2387:_dbus_type_writer_write_basic (DBusTypeWriter *writer,
        -: 2388:                               int             type,
        -: 2389:                               const void     *value)
function _dbus_type_writer_write_basic called 3141614 returned 100% blocks executed 86%
  3141614: 2390:{
        -: 2391:  dbus_bool_t retval;
        -: 2392:
        -: 2393:  /* First ensure that our type realloc will succeed */
  3141614: 2394:  if (!writer->type_pos_is_expectation && writer->type_str != NULL)
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
        -: 2395:    {
   112245: 2396:      if (!_dbus_string_alloc_space (writer->type_str, 1))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2397:        return FALSE;
        -: 2398:    }
        -: 2399:
  3141614: 2400:  retval = FALSE;
        -: 2401:
  3141614: 2402:  if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      372: 2403:    goto out;
        -: 2404:
  3141242: 2405:  if (!write_or_verify_typecode (writer, type))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2406:    _dbus_assert_not_reached ("failed to write typecode after prealloc");
call    0 never executed
        -: 2407:
  3141242: 2408:  retval = TRUE;
        -: 2409:
  3141614: 2410: out:
        -: 2411:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2412:  _dbus_verbose ("  type writer %p basic type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n",
        -: 2413:                 writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
        -: 2414:                 writer->enabled);
        -: 2415:#endif
        -: 2416:
  3141614: 2417:  return retval;
        -: 2418:}
        -: 2419:
        -: 2420:/**
        -: 2421: * Writes a block of fixed-length basic values, i.e. those that are
        -: 2422: * both dbus_type_is_fixed() and _dbus_type_is_basic(). The block
        -: 2423: * must be written inside an array.
        -: 2424: *
        -: 2425: * The value parameter should be the address of said array of values,
        -: 2426: * so e.g. if it's an array of double, pass in "const double**"
        -: 2427: *
        -: 2428: * @param writer the writer
        -: 2429: * @param element_type type of stuff in the array
        -: 2430: * @param value address of the array
        -: 2431: * @param n_elements number of elements in the array
        -: 2432: * @returns #FALSE if no memory
        -: 2433: */
        -: 2434:dbus_bool_t
        -: 2435:_dbus_type_writer_write_fixed_multi (DBusTypeWriter        *writer,
        -: 2436:                                     int                    element_type,
        -: 2437:                                     const void            *value,
        -: 2438:                                     int                    n_elements)
function _dbus_type_writer_write_fixed_multi called 7 returned 100% blocks executed 86%
        7: 2439:{
        7: 2440:  _dbus_assert (writer->container_type == DBUS_TYPE_ARRAY);
call    0 returned 100%
        7: 2441:  _dbus_assert (dbus_type_is_fixed (element_type));
call    0 returned 100%
call    1 returned 100%
        7: 2442:  _dbus_assert (writer->type_pos_is_expectation);
call    0 returned 100%
        7: 2443:  _dbus_assert (n_elements >= 0);
call    0 returned 100%
        -: 2444:
        -: 2445:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2446:  _dbus_verbose ("  type writer %p entering fixed multi type_pos = %d value_pos = %d n_elements %d\n",
        -: 2447:                 writer, writer->type_pos, writer->value_pos, n_elements);
        -: 2448:#endif
        -: 2449:
        7: 2450:  if (!write_or_verify_typecode (writer, element_type))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2451:    _dbus_assert_not_reached ("OOM should not happen if only verifying typecode");
call    0 never executed
        -: 2452:
        7: 2453:  if (writer->enabled)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 2454:    {
        7: 2455:      if (!_dbus_marshal_write_fixed_multi (writer->value_str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 2456:                                            writer->value_pos,
        -: 2457:                                            element_type,
        -: 2458:                                            value,
        -: 2459:                                            n_elements,
        -: 2460:                                            writer->byte_order,
        -: 2461:                                            &writer->value_pos))
    #####: 2462:        return FALSE;
        -: 2463:    }
        -: 2464:
        -: 2465:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2466:  _dbus_verbose ("  type writer %p fixed multi written new type_pos = %d new value_pos = %d n_elements %d\n",
        -: 2467:                 writer, writer->type_pos, writer->value_pos, n_elements);
        -: 2468:#endif
        -: 2469:
        7: 2470:  return TRUE;
        -: 2471:}
        -: 2472:
        -: 2473:static void
        -: 2474:enable_if_after (DBusTypeWriter       *writer,
        -: 2475:                 DBusTypeReader       *reader,
        -: 2476:                 const DBusTypeReader *start_after)
function enable_if_after called 2003582 returned 100% blocks executed 93%
  2003582: 2477:{
  2003582: 2478:  if (start_after)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -: 2479:    {
  2003582: 2480:      if (!writer->enabled && _dbus_type_reader_greater_than (reader, start_after))
branch  0 taken 79% (fallthrough)
branch  1 taken 21%
call    2 returned 100%
branch  3 taken 12% (fallthrough)
branch  4 taken 88%
        -: 2481:        {
   188721: 2482:          _dbus_type_writer_set_enabled (writer, TRUE);
call    0 returned 100%
        -: 2483:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2484:          _dbus_verbose ("ENABLING writer %p at %d because reader at value_pos %d is after reader at value_pos %d\n",
        -: 2485:                         writer, writer->value_pos, reader->value_pos, start_after->value_pos);
        -: 2486:#endif
        -: 2487:        }
        -: 2488:
  2003582: 2489:      _dbus_assert ((!writer->enabled && !_dbus_type_reader_greater_than (reader, start_after)) ||
branch  0 taken 69% (fallthrough)
branch  1 taken 31%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
branch  5 taken 100% (fallthrough)
branch  6 taken 0%
call    7 returned 100%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
call   10 returned 100%
        -: 2490:                    (writer->enabled && _dbus_type_reader_greater_than (reader, start_after)));
        -: 2491:    }
  2003582: 2492:}
        -: 2493:
        -: 2494:static dbus_bool_t
        -: 2495:append_fixup (DBusList               **fixups,
        -: 2496:              const DBusArrayLenFixup *fixup)
function append_fixup called 33921 returned 100% blocks executed 100%
    33921: 2497:{
        -: 2498:  DBusArrayLenFixup *f;
        -: 2499:
    33921: 2500:  f = dbus_new (DBusArrayLenFixup, 1);
call    0 returned 100%
    33921: 2501:  if (f == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
       50: 2502:    return FALSE;
        -: 2503:
    33871: 2504:  *f = *fixup;
        -: 2505:
    33871: 2506:  if (!_dbus_list_append (fixups, f))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -: 2507:    {
       55: 2508:      dbus_free (f);
call    0 returned 100%
       55: 2509:      return FALSE;
        -: 2510:    }
        -: 2511:
    33816: 2512:  _dbus_assert (f->len_pos_in_reader == fixup->len_pos_in_reader);
call    0 returned 100%
    33816: 2513:  _dbus_assert (f->new_len == fixup->new_len);
call    0 returned 100%
        -: 2514:
    33816: 2515:  return TRUE;
        -: 2516:}
        -: 2517:
        -: 2518:/* This loop is trivial if you ignore all the start_after nonsense,
        -: 2519: * so if you're trying to figure it out, start by ignoring that
        -: 2520: */
        -: 2521:static dbus_bool_t
        -: 2522:writer_write_reader_helper (DBusTypeWriter       *writer,
        -: 2523:                            DBusTypeReader       *reader,
        -: 2524:                            const DBusTypeReader *start_after,
        -: 2525:                            int                   start_after_new_pos,
        -: 2526:                            int                   start_after_new_len,
        -: 2527:                            DBusList            **fixups,
        -: 2528:                            dbus_bool_t           inside_start_after)
function writer_write_reader_helper called 752032 returned 100% blocks executed 98%
   752032: 2529:{
        -: 2530:  int current_type;
        -: 2531:
  2818204: 2532:  while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
call    0 returned 100%
branch  1 taken 64%
branch  2 taken 36% (fallthrough)
        -: 2533:    {
  1315267: 2534:      if (dbus_type_is_container (current_type))
call    0 returned 100%
branch  1 taken 52% (fallthrough)
branch  2 taken 48%
        -: 2535:        {
        -: 2536:          DBusTypeReader subreader;
        -: 2537:          DBusTypeWriter subwriter;
        -: 2538:          const DBusString *sig_str;
        -: 2539:          int sig_start;
        -: 2540:          int sig_len;
        -: 2541:          dbus_bool_t enabled_at_recurse;
        -: 2542:          dbus_bool_t past_start_after;
        -: 2543:          int reader_array_len_pos;
        -: 2544:          int reader_array_start_pos;
        -: 2545:          dbus_bool_t this_is_start_after;
        -: 2546:
        -: 2547:          /* type_pos is checked since e.g. in a struct the struct
        -: 2548:           * and its first field have the same value_pos.
        -: 2549:           * type_str will differ in reader/start_after for variants
        -: 2550:           * where type_str is inside the value_str
        -: 2551:           */
   689302: 2552:          if (!inside_start_after && start_after &&
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 1% (fallthrough)
branch  5 taken 99%
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
        -: 2553:              reader->value_pos == start_after->value_pos &&
        -: 2554:              reader->type_str == start_after->type_str &&
        -: 2555:              reader->type_pos == start_after->type_pos)
        5: 2556:            this_is_start_after = TRUE;
        -: 2557:          else
   689292: 2558:            this_is_start_after = FALSE;
        -: 2559:
   689297: 2560:          _dbus_type_reader_recurse (reader, &subreader);
call    0 returned 100%
        -: 2561:
   689297: 2562:          if (current_type == DBUS_TYPE_ARRAY)
branch  0 taken 9% (fallthrough)
branch  1 taken 91%
        -: 2563:            {
    63031: 2564:              reader_array_len_pos = ARRAY_READER_LEN_POS (&subreader);
    63031: 2565:              reader_array_start_pos = subreader.u.array.start_pos;
        -: 2566:            }
        -: 2567:          else
        -: 2568:            {
        -: 2569:              /* quiet gcc */
   626266: 2570:              reader_array_len_pos = -1;
   626266: 2571:              reader_array_start_pos = -1;
        -: 2572:            }
        -: 2573:
   689297: 2574:          _dbus_type_reader_get_signature (&subreader, &sig_str,
call    0 returned 100%
        -: 2575:                                           &sig_start, &sig_len);
        -: 2576:
        -: 2577:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2578:          _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",
        -: 2579:                         _dbus_type_to_string (current_type),
        -: 2580:                         reader->value_pos,
        -: 2581:                         subreader.value_pos,
        -: 2582:                         writer->value_pos,
        -: 2583:                         start_after ? start_after->value_pos : -1,
        -: 2584:                         _dbus_string_get_length (writer->value_str),
        -: 2585:                         inside_start_after, this_is_start_after);
        -: 2586:#endif
        -: 2587:
   689297: 2588:          if (!inside_start_after && !this_is_start_after)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
branch  2 taken 99% (fallthrough)
branch  3 taken 1%
   689287: 2589:            enable_if_after (writer, &subreader, start_after);
call    0 returned 100%
   689297: 2590:          enabled_at_recurse = writer->enabled;
   689297: 2591:          if (!_dbus_type_writer_recurse_contained_len (writer, current_type,
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
        -: 2592:                                                        sig_str, sig_start, sig_len,
        -: 2593:                                                        &subwriter, FALSE))
      296: 2594:            goto oom;
        -: 2595:
        -: 2596:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2597:          _dbus_verbose ("recursed into subwriter at %d write target len %d\n",
        -: 2598:                         subwriter.value_pos,
        -: 2599:                         _dbus_string_get_length (subwriter.value_str));
        -: 2600:#endif
        -: 2601:
   689001: 2602:          if (!writer_write_reader_helper (&subwriter, &subreader, start_after,
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
branch  2 taken 1% (fallthrough)
branch  3 taken 99%
call    4 returned 100%
branch  5 taken 1% (fallthrough)
branch  6 taken 99%
        -: 2603:                                           start_after_new_pos, start_after_new_len,
        -: 2604:                                           fixups,
        -: 2605:                                           inside_start_after ||
        -: 2606:                                           this_is_start_after))
      656: 2607:            goto oom;
        -: 2608:
        -: 2609:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2610:          _dbus_verbose ("about to unrecurse from %s subreader at %d writer at %d subwriter at %d  write target len %d\n",
        -: 2611:                         _dbus_type_to_string (current_type),
        -: 2612:                         subreader.value_pos,
        -: 2613:                         writer->value_pos,
        -: 2614:                         subwriter.value_pos,
        -: 2615:                         _dbus_string_get_length (writer->value_str));
        -: 2616:#endif
        -: 2617:
   688345: 2618:          if (!inside_start_after && !this_is_start_after)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
branch  2 taken 99% (fallthrough)
branch  3 taken 1%
   688335: 2619:            enable_if_after (writer, &subreader, start_after);
call    0 returned 100%
   688345: 2620:          past_start_after = writer->enabled;
   688345: 2621:          if (!_dbus_type_writer_unrecurse (writer, &subwriter))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 2622:            goto oom;
        -: 2623:
        -: 2624:          /* If we weren't enabled when we recursed, we didn't
        -: 2625:           * write an array len; if we passed start_after
        -: 2626:           * somewhere inside the array, then we need to generate
        -: 2627:           * a fixup.
        -: 2628:           */
   688345: 2629:          if (start_after != NULL &&
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 79% (fallthrough)
branch  3 taken 21%
branch  4 taken 35% (fallthrough)
branch  5 taken 65%
branch  6 taken 33% (fallthrough)
branch  7 taken 67%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
        -: 2630:              !enabled_at_recurse && past_start_after &&
        -: 2631:              current_type == DBUS_TYPE_ARRAY &&
        -: 2632:              fixups != NULL)
        -: 2633:            {
        -: 2634:              DBusArrayLenFixup fixup;
        -: 2635:              int bytes_written_after_start_after;
        -: 2636:              int bytes_before_start_after;
        -: 2637:              int old_len;
        -: 2638:
        -: 2639:              /* this subwriter access is moderately unkosher since we
        -: 2640:               * already unrecursed, but it works as long as unrecurse
        -: 2641:               * doesn't break us on purpose
        -: 2642:               */
    62665: 2643:              bytes_written_after_start_after = writer_get_array_len (&subwriter);
call    0 returned 100%
        -: 2644:
    62665: 2645:              bytes_before_start_after =
        -: 2646:                start_after->value_pos - reader_array_start_pos;
        -: 2647:
    62665: 2648:              fixup.len_pos_in_reader = reader_array_len_pos;
    62665: 2649:              fixup.new_len =
        -: 2650:                bytes_before_start_after +
        -: 2651:                start_after_new_len +
        -: 2652:                bytes_written_after_start_after;
        -: 2653:
    62665: 2654:              _dbus_assert (_DBUS_ALIGN_VALUE (fixup.len_pos_in_reader, 4) ==
call    0 returned 100%
        -: 2655:                            (unsigned) fixup.len_pos_in_reader);
        -: 2656:
    62665: 2657:              old_len = _dbus_unpack_uint32 (reader->byte_order,
call    0 returned 100%
call    1 returned 100%
        -: 2658:                                             _dbus_string_get_const_data_len (reader->value_str,
        -: 2659:                                                                              fixup.len_pos_in_reader, 4));
        -: 2660:
    62665: 2661:              if (old_len != fixup.new_len && !append_fixup (fixups, &fixup))
branch  0 taken 54% (fallthrough)
branch  1 taken 46%
call    2 returned 100%
branch  3 taken 1% (fallthrough)
branch  4 taken 99%
      105: 2662:                goto oom;
        -: 2663:
        -: 2664:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2665:              _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",
        -: 2666:                             fixup.len_pos_in_reader,
        -: 2667:                             fixup.new_len,
        -: 2668:                             reader_array_start_pos,
        -: 2669:                             start_after->value_pos,
        -: 2670:                             bytes_before_start_after,
        -: 2671:                             start_after_new_len,
        -: 2672:                             bytes_written_after_start_after);
        -: 2673:#endif
        -: 2674:            }
        -: 2675:        }
        -: 2676:      else
        -: 2677:        {
        -: 2678:          DBusBasicValue val;
        -: 2679:
   625970: 2680:          _dbus_assert (dbus_type_is_basic (current_type));
call    0 returned 100%
call    1 returned 100%
        -: 2681:
        -: 2682:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2683:          _dbus_verbose ("Reading basic value %s at %d\n",
        -: 2684:                         _dbus_type_to_string (current_type),
        -: 2685:                         reader->value_pos);
        -: 2686:#endif
        -: 2687:
   625970: 2688:          _dbus_type_reader_read_basic (reader, &val);
call    0 returned 100%
        -: 2689:
        -: 2690:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2691:          _dbus_verbose ("Writing basic value %s at %d write target len %d inside_start_after = %d\n",
        -: 2692:                         _dbus_type_to_string (current_type),
        -: 2693:                         writer->value_pos,
        -: 2694:                         _dbus_string_get_length (writer->value_str),
        -: 2695:                         inside_start_after);
        -: 2696:#endif
   625970: 2697:          if (!inside_start_after)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
   625960: 2698:            enable_if_after (writer, reader, start_after);
call    0 returned 100%
   625970: 2699:          if (!_dbus_type_writer_write_basic (writer, current_type, &val))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
       70: 2700:            goto oom;
        -: 2701:#if RECURSIVE_MARSHAL_WRITE_TRACE
        -: 2702:          _dbus_verbose ("Wrote basic value %s, new value_pos %d write target len %d\n",
        -: 2703:                         _dbus_type_to_string (current_type),
        -: 2704:                         writer->value_pos,
        -: 2705:                         _dbus_string_get_length (writer->value_str));
        -: 2706:#endif
        -: 2707:        }
        -: 2708:
  1314140: 2709:      _dbus_type_reader_next (reader);
call    0 returned 100%
        -: 2710:    }
        -: 2711:
   750905: 2712:  return TRUE;
        -: 2713:
     1127: 2714: oom:
     1127: 2715:  if (fixups)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
     1127: 2716:    apply_and_free_fixups (fixups, NULL); /* NULL for reader to apply to */
call    0 returned 100%
        -: 2717:
     1127: 2718:  return FALSE;
        -: 2719:}
        -: 2720:
        -: 2721:/**
        -: 2722: * Iterate through all values in the given reader, writing a copy of
        -: 2723: * each value to the writer.  The reader will be moved forward to its
        -: 2724: * end position.
        -: 2725: *
        -: 2726: * If a reader start_after is provided, it should be a reader for the
        -: 2727: * same data as the reader to be written. Only values occurring after
        -: 2728: * the value pointed to by start_after will be written to the writer.
        -: 2729: *
        -: 2730: * If start_after is provided, then the copy of the reader will be
        -: 2731: * partial. This means that array lengths will not have been copied.
        -: 2732: * The assumption is that you wrote a new version of the value at
        -: 2733: * start_after to the writer. You have to pass in the start position
        -: 2734: * and length of the new value. (If you are deleting the value
        -: 2735: * at start_after, pass in 0 for the length.)
        -: 2736: *
        -: 2737: * If the fixups parameter is non-#NULL, then any array length that
        -: 2738: * was read but not written due to start_after will be provided
        -: 2739: * as a #DBusArrayLenFixup. The fixup contains the position of the
        -: 2740: * array length in the source data, and the correct array length
        -: 2741: * assuming you combine the source data before start_after with
        -: 2742: * the written data at start_after and beyond.
        -: 2743: *
        -: 2744: * @param writer the writer to copy to
        -: 2745: * @param reader the reader to copy from
        -: 2746: * @param start_after #NULL or a reader showing where to start
        -: 2747: * @param start_after_new_pos the position of start_after equivalent in the target data
        -: 2748: * @param start_after_new_len the length of start_after equivalent in the target data
        -: 2749: * @param fixups list to append #DBusArrayLenFixup if the write was partial
        -: 2750: * @returns #FALSE if no memory
        -: 2751: */
        -: 2752:dbus_bool_t
        -: 2753:_dbus_type_writer_write_reader_partial (DBusTypeWriter       *writer,
        -: 2754:                                        DBusTypeReader       *reader,
        -: 2755:                                        const DBusTypeReader *start_after,
        -: 2756:                                        int                   start_after_new_pos,
        -: 2757:                                        int                   start_after_new_len,
        -: 2758:                                        DBusList            **fixups)
function _dbus_type_writer_write_reader_partial called 63031 returned 100% blocks executed 88%
    63031: 2759:{
        -: 2760:  DBusTypeWriter orig;
        -: 2761:  int orig_type_len;
        -: 2762:  int orig_value_len;
        -: 2763:  int new_bytes;
        -: 2764:  int orig_enabled;
        -: 2765:
    63031: 2766:  orig = *writer;
    63031: 2767:  orig_type_len = _dbus_string_get_length (writer->type_str);
call    0 returned 100%
    63031: 2768:  orig_value_len = _dbus_string_get_length (writer->value_str);
call    0 returned 100%
    63031: 2769:  orig_enabled = writer->enabled;
        -: 2770:
    63031: 2771:  if (start_after)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
    63031: 2772:    _dbus_type_writer_set_enabled (writer, FALSE);
call    0 returned 100%
        -: 2773:
    63031: 2774:  if (!writer_write_reader_helper (writer, reader, start_after,
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
        -: 2775:                                   start_after_new_pos,
        -: 2776:                                   start_after_new_len,
        -: 2777:                                   fixups, FALSE))
      471: 2778:    goto oom;
        -: 2779:
    62560: 2780:  _dbus_type_writer_set_enabled (writer, orig_enabled);
call    0 returned 100%
    62560: 2781:  return TRUE;
        -: 2782:
      471: 2783: oom:
      471: 2784:  if (!writer->type_pos_is_expectation)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 2785:    {
    #####: 2786:      new_bytes = _dbus_string_get_length (writer->type_str) - orig_type_len;
call    0 never executed
    #####: 2787:      _dbus_string_delete (writer->type_str, orig.type_pos, new_bytes);
call    0 never executed
        -: 2788:    }
      471: 2789:  new_bytes = _dbus_string_get_length (writer->value_str) - orig_value_len;
call    0 returned 100%
      471: 2790:  _dbus_string_delete (writer->value_str, orig.value_pos, new_bytes);
call    0 returned 100%
        -: 2791:
      471: 2792:  *writer = orig;
        -: 2793:
      471: 2794:  return FALSE;
        -: 2795:}
        -: 2796:
        -: 2797:/**
        -: 2798: * Iterate through all values in the given reader, writing a copy of
        -: 2799: * each value to the writer.  The reader will be moved forward to its
        -: 2800: * end position.
        -: 2801: *
        -: 2802: * @param writer the writer to copy to
        -: 2803: * @param reader the reader to copy from
        -: 2804: * @returns #FALSE if no memory
        -: 2805: */
        -: 2806:dbus_bool_t
        -: 2807:_dbus_type_writer_write_reader (DBusTypeWriter       *writer,
        -: 2808:                                DBusTypeReader       *reader)
function _dbus_type_writer_write_reader called 0 returned 0% blocks executed 0%
    #####: 2809:{
    #####: 2810:  return _dbus_type_writer_write_reader_partial (writer, reader, NULL, 0, 0, NULL);
call    0 never executed
        -: 2811:}
        -: 2812:
        -: 2813:/**
        -: 2814: * If disabled, a writer can still be iterated forward and recursed/unrecursed
        -: 2815: * but won't write any values. Types will still be written unless the
        -: 2816: * writer is a "values only" writer, because the writer needs access to
        -: 2817: * a valid signature to be able to iterate.
        -: 2818: *
        -: 2819: * @param writer the type writer
        -: 2820: * @param enabled #TRUE if values should be written
        -: 2821: */
        -: 2822:void
        -: 2823:_dbus_type_writer_set_enabled (DBusTypeWriter   *writer,
        -: 2824:                               dbus_bool_t       enabled)
function _dbus_type_writer_set_enabled called 314312 returned 100% blocks executed 100%
   314312: 2825:{
   314312: 2826:  writer->enabled = enabled != FALSE;
   314312: 2827:}
        -: 2828:
        -: 2829:/** @} */ /* end of DBusMarshal group */
        -: 2830:
        -: 2831:/* tests in dbus-marshal-recursive-util.c */