Listing 2: The cdc_data_flush function

int cdc_data_flush(cdc_t *cdc)
{
  int rc;

  rc = 0;
  if (cdc->data.cluster.dirty)
  {
    unsigned long bat_entry;
    unsigned long bat_entry_next;
    const char   *ptr;
    unsigned long count;
    size_t        zsize;
    unsigned long compress_flag;

    cdc->data.cluster.dirty = 0;
    count      = cdc->data.blocks;
    ptr        = cdc->data.cluster.buffer;
    compress_flag = 0;

    zsize = cdc->data.size;
    rc = cdc->env->deflate.fn(
      cdc->env->deflate.arg,
      cdc->data.zbuffer,
      &zsize,
      cdc->data.cluster.buffer,
      cdc->data.size
      );
    if (0 == rc)
    {
      /*
       * success! but if we don't save at least 1 block, 
       * don't bother
       */
      count = (zsize + cdc->blk.size - 1) / cdc->blk.size;
      if (count < cdc->data.blocks)
      {
        compress_flag = MAP_FLAG_COMPRESSED;
        ptr = cdc->data.zbuffer;
      }
    }
    rc = cdc_map_entry_get(cdc, cdc->data.cluster.cluster, 
                           &bat_entry);

    if (0 == rc)
    {
      if (BAT_ENTRY_EOL == bat_entry)
      {
        /* get a free bat entry */
        rc = cdc_bat_entry_alloc(cdc, &bat_entry); 
        if (0 == rc)
        {
          rc = cdc_map_entry_set(
            cdc,
            cdc->data.cluster.cluster,
            bat_entry | compress_flag
            );
        }
      } else
      {
        unsigned long map_entry;

        map_entry = bat_entry;
        if (compress_flag)
        {
          map_entry |= MAP_FLAG_COMPRESSED;
        } else
        {
          map_entry &= ~MAP_FLAG_COMPRESSED;
        }
        if (bat_entry != map_entry)
        {
          rc = cdc_map_entry_set(cdc, cdc->data.cluster.cluster, 
                                 map_entry);
        }
        bat_entry &= ~MAP_FLAG_COMPRESSED;
      }
    }
    while ((0 == rc) && count)
    {
      rc = data_block_write(cdc, bat_entry, ptr);
      if (0 == rc)
      {
        rc = cdc_bat_entry_get(cdc, bat_entry, &bat_entry_next);
      }
      if (0 == rc)
      {
        count--;
        if (count)
        {
          ptr += cdc->blk.size;

          if (0 == rc)
          {
            if (BAT_ENTRY_EOL == bat_entry_next)
            {
              rc = cdc_bat_entry_alloc(cdc, &bat_entry_next);
              if (0 == rc)
              {
                rc = cdc_bat_entry_set(cdc, bat_entry, 
                                       bat_entry_next);
              }
            }
            bat_entry = bat_entry_next;
          }
        }
      }
    }
    /*
     * free up any remaining entries
     *   --- occurs if the current cluster compresses to less than
     *       the previous one
     */
    if ((0 == rc) && (BAT_ENTRY_EOL != bat_entry_next))
    {
      /* mark the end */
      cdc_bat_entry_set(cdc, bat_entry, BAT_ENTRY_EOL); 
      do
      {
        bat_entry = bat_entry_next;
        rc = cdc_bat_entry_get(cdc, bat_entry, &bat_entry_next);
        if (0 == rc)
        {
          rc = cdc_bat_entry_free(cdc, bat_entry);
        }
      } while ((0 == rc) && (BAT_ENTRY_EOL != bat_entry_next));
    }
  }
  return rc;
}
— End of Listing —