Logo Search packages:      
Sourcecode: tardy version File versions  Download package

int tar_input_filter_gunzip::read_data ( void *  buffer,
int  buffer_length 
) [virtual]

The read_data method is used to read a block of data from the input. The `buffer_length' argument specifies the maximum number of bytes in the `buffer'. Returns the number of bytes read, or 0 at end of file.

Reimplemented from tar_input_filter.

Definition at line 339 of file gunzip.cc.

References buf, buffered_read(), buffered_unread(), crc, deflated_file_length, deflated_file_pos, tar_input::fatal(), get_long(), inflated_file_length, inflated_file_pos, pass_through, tar_input_filter::read_data(), stream, z_eof, and zlib_fatal_error().

{
    if (pass_through)
      return tar_input_filter::read_data(data, len);

    if (z_eof)
      return 0;

    stream.next_out = (Bytef *)data;
    stream.avail_out = len;

    while (stream.avail_out > 0)
    {
      if (stream.avail_in == 0)
      {
          // assert(buf);
          stream.next_in = buf;
          stream.avail_in = buffered_read(buf, Z_BUFSIZE);

          /*
           * There should always be something left on the
           * input, because we have the CRC and Length
           * to follow.  Fatal error if not.
           */
          if (stream.avail_in <= 0)
            fatal("premature end of file");
      }
      int err = inflate(&stream, Z_PARTIAL_FLUSH);
      if (err < 0)
          zlib_fatal_error(err);
      if (err == Z_STREAM_END)
      {
          z_eof = true;

          /*
           * Push back the unused portion of the input stream.
           * (There shouldn't be much.)
           */
          if (stream.avail_in > 0)
            buffered_unread(stream.next_in, stream.avail_in);

          /*
           * Fall out of the loop.
           */
          break;
      }
    }

    /*
     * Calculate the running CRC
     */
    long result = stream.next_out - (Bytef *)data;
    crc = crc32(crc, (Bytef *)data, (uInt)result);

    /*
     * Update the file position.
     */
    inflated_file_pos += result;

    /*
     * At end-of-file we need to do some checking.
     */
    if (z_eof)
    {
      /*
       * Check CRC
       *
       * Watch out for 64-bit machines.  This is what
       * those aparrently redundant 0xFFFFFFFF are for.
       */
      unsigned long icrc = get_long();
      if ((icrc & 0xFFFFFFFF) != (crc & 0xFFFFFFFF))
          fatal("gunzip: checksum mismatch (%lX != %lX)", icrc, crc);

      /*
       * The uncompressed length here may be different
       * from pos in case of concatenated .gz
       * files.  But we don't write them that way,
       * so give an error if it happens.
       *
       * We shouldn't have 64-bit problems in this case.
       */
      unsigned long ilen = get_long();
      if (ilen != inflated_file_pos)
          fatal("gunzip: length mismatch (%ld != %ld)", ilen, (long)inflated_file_pos);
      if (inflated_file_pos != inflated_file_length)
          fatal("inflated length mismatch");
      if (deflated_file_pos != deflated_file_length)
          fatal("deflated length mismatch");

      /*
       * Finished with this stream.
       */
      int err = inflateEnd(&stream);
      if (err < 0)
          zlib_fatal_error(err);
    }

    /*
     * Return success (failure always goes via input_format_error,
     * or zlib_fatal_error).
     */
    return result;
}


Generated by  Doxygen 1.6.0   Back to index