diff options
| -rw-r--r-- | decoder/gzstream.cc | 25 | ||||
| -rw-r--r-- | decoder/gzstream.h | 24 | 
2 files changed, 35 insertions, 14 deletions
| diff --git a/decoder/gzstream.cc b/decoder/gzstream.cc index 9703e6ad..aa015bff 100644 --- a/decoder/gzstream.cc +++ b/decoder/gzstream.cc @@ -21,14 +21,15 @@  // Revision      : $Revision: 1.1 $  // Revision_date : $Date: 2006/03/30 04:05:52 $  // Author(s)     : Deepak Bandyopadhyay, Lutz Kettner -//  -// Standard streambuf implementation following Nicolai Josuttis, "The  +// +// Standard streambuf implementation following Nicolai Josuttis, "The  // Standard C++ Library".  // ============================================================================  #include "gzstream.h"  #include <iostream>  #include <cstring> +#include <stdexcept>  #ifdef GZSTREAM_NAMESPACE  namespace GZSTREAM_NAMESPACE { @@ -59,6 +60,7 @@ gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {      *fmodeptr++ = 'b';      *fmodeptr = '\0';      file = gzopen( name, fmode); +    if (!file) handle_gzerror();      if (file == 0)          return (gzstreambuf*)0;      opened = 1; @@ -71,10 +73,19 @@ gzstreambuf * gzstreambuf::close() {          opened = 0;          if ( gzclose( file) == Z_OK)              return this; +        else +            handle_gzerror();      }      return (gzstreambuf*)0;  } +void gzstreambuf::handle_gzerror() { +    int errnum; +    const char *errmsg=gzerror(file,&errnum); +    if (errnum==Z_DATA_ERROR) errmsg="CRC error reading gzip"; +    throw std::runtime_error(std::string("gzstreambuf error: ")+errmsg); +} +  int gzstreambuf::underflow() { // used for input buffer only      if ( gptr() && ( gptr() < egptr()))          return * reinterpret_cast<unsigned char *>( gptr()); @@ -89,7 +100,11 @@ int gzstreambuf::underflow() { // used for input buffer only      int num = gzread( file, buffer+4, bufferSize-4);      if (num <= 0) // ERROR or EOF -        return EOF; +    { +        if (gzeof(file)) +            return EOF; +        handle_gzerror(); +    }      // reset buffer pointers      setg( buffer + (4 - n_putback),   // beginning of putback area @@ -97,7 +112,7 @@ int gzstreambuf::underflow() { // used for input buffer only            buffer + 4 + num);          // end of buffer      // return next character -    return * reinterpret_cast<unsigned char *>( gptr());     +    return * reinterpret_cast<unsigned char *>( gptr());  }  int gzstreambuf::flush_buffer() { @@ -105,7 +120,7 @@ int gzstreambuf::flush_buffer() {      // sync() operation.      int w = pptr() - pbase();      if ( gzwrite( file, pbase(), w) != w) -        return EOF; +        handle_gzerror();      pbump( -w);      return w;  } diff --git a/decoder/gzstream.h b/decoder/gzstream.h index ad9785fd..5c709490 100644 --- a/decoder/gzstream.h +++ b/decoder/gzstream.h @@ -21,8 +21,8 @@  // Revision      : $Revision: 1.1 $  // Revision_date : $Date: 2006/03/30 04:05:52 $  // Author(s)     : Deepak Bandyopadhyay, Lutz Kettner -//  -// Standard streambuf implementation following Nicolai Josuttis, "The  +// +// Standard streambuf implementation following Nicolai Josuttis, "The  // Standard C++ Library".  // ============================================================================ @@ -44,7 +44,7 @@ namespace GZSTREAM_NAMESPACE {  class gzstreambuf : public std::streambuf {  private: -    static const int bufferSize = 47+256;    // size of data buff +  static const int bufferSize = 47+(1024*256);    // size of data buff      // totals 512 bytes under g++ for igzstream at the end.      gzFile           file;               // file handle for compressed file @@ -53,19 +53,25 @@ private:      int              mode;               // I/O mode      int flush_buffer(); +    void handle_gzerror(); // throws exception  public: +#if defined(_WIN32) && !defined(CYGWIN) && !defined(EOF) +	enum { +		EOF = -1 +	}; +#endif      gzstreambuf() : opened(0) {          setp( buffer, buffer + (bufferSize-1));          setg( buffer + 4,     // beginning of putback area                buffer + 4,     // read position -              buffer + 4);    // end position       +              buffer + 4);    // end position          // ASSERT: both input & output capabilities will not be used together      }      int is_open() { return opened; }      gzstreambuf* open( const char* name, int open_mode);      gzstreambuf* close();      ~gzstreambuf() { close(); } -     +      virtual int     overflow( int c = EOF);      virtual int     underflow();      virtual int     sync(); @@ -85,15 +91,15 @@ public:  // ----------------------------------------------------------------------------  // User classes. Use igzstream and ogzstream analogously to ifstream and -// ofstream respectively. They read and write files based on the gz*  +// ofstream respectively. They read and write files based on the gz*  // function interface of the zlib. Files are compatible with gzip compression.  // ----------------------------------------------------------------------------  class igzstream : public gzstreambase, public std::istream {  public: -    igzstream() : std::istream( &buf) {}  +    igzstream() : std::istream( &buf) {}      igzstream( const char* name, int open_mode = std::ios::in) -        : gzstreambase( name, open_mode), std::istream( &buf) {}   +        : gzstreambase( name, std::ios::in | open_mode), std::istream( &buf) {}      gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }      void open( const char* name, int open_mode = std::ios::in) {          gzstreambase::open( name, open_mode); @@ -104,7 +110,7 @@ class ogzstream : public gzstreambase, public std::ostream {  public:      ogzstream() : std::ostream( &buf) {}      ogzstream( const char* name, int mode = std::ios::out) -        : gzstreambase( name, mode), std::ostream( &buf) {}   +        : gzstreambase( name, mode), std::ostream( &buf) {}      gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }      void open( const char* name, int open_mode = std::ios::out) {          gzstreambase::open( name, open_mode); | 
