00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef GZSTREAM_H
00033 #define GZSTREAM_H 1
00034
00035
00036 #include <iostream>
00037 #include <fstream>
00038 #include <zlib.h>
00039 #include <string.h>
00040
00041 #ifdef GZSTREAM_NAMESPACE
00042 namespace GZSTREAM_NAMESPACE {
00043 #endif
00044
00045
00046
00047
00048
00049 class gzstreambuf : public std::streambuf {
00050 private:
00051 static const int bufferSize = 47+256;
00052
00053
00054 gzFile file;
00055 char buffer[bufferSize];
00056 char opened;
00057 int mode;
00058
00059 public:
00060 gzstreambuf() : opened(0) {
00061 setp( buffer, buffer + (bufferSize-1));
00062 setg( buffer + 4,
00063 buffer + 4,
00064 buffer + 4);
00065
00066 }
00067 int is_open() { return opened; }
00068 ~gzstreambuf() { close(); }
00069
00070 gzstreambuf* open( const char* name, int open_mode) {
00071 if ( is_open())
00072 return (gzstreambuf*)0;
00073 mode = open_mode;
00074
00075 if ((mode & std::ios::ate) || (mode & std::ios::app)
00076 || ((mode & std::ios::in) && (mode & std::ios::out)))
00077 return (gzstreambuf*)0;
00078 char fmode[10];
00079 char* fmodeptr = fmode;
00080 if ( mode & std::ios::in)
00081 *fmodeptr++ = 'r';
00082 else if ( mode & std::ios::out)
00083 *fmodeptr++ = 'w';
00084 *fmodeptr++ = 'b';
00085 *fmodeptr = '\0';
00086 file = gzopen( name, fmode);
00087 if (file == 0)
00088 return (gzstreambuf*)0;
00089 opened = 1;
00090 return this;
00091 }
00092
00093 gzstreambuf * close() {
00094 if ( is_open()) {
00095 sync();
00096 opened = 0;
00097 if ( gzclose( file) == Z_OK)
00098 return this;
00099 }
00100 return (gzstreambuf*)0;
00101 }
00102
00103 int underflow() {
00104 if ( gptr() && ( gptr() < egptr()))
00105 return * reinterpret_cast<unsigned char *>( gptr());
00106
00107 if ( ! (mode & std::ios::in) || ! opened)
00108 return EOF;
00109
00110 int n_putback = gptr() - eback();
00111 if ( n_putback > 4)
00112 n_putback = 4;
00113 memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
00114
00115 int num = gzread( file, buffer+4, bufferSize-4);
00116 if (num <= 0)
00117 return EOF;
00118
00119
00120 setg( buffer + (4 - n_putback),
00121 buffer + 4,
00122 buffer + 4 + num);
00123
00124
00125 return * reinterpret_cast<unsigned char *>( gptr());
00126 }
00127
00128 int overflow( int c) {
00129 if ( ! ( mode & std::ios::out) || ! opened)
00130 return EOF;
00131 int w = pptr() - pbase();
00132 if (c != EOF) {
00133 *pptr() = c;
00134 ++w;
00135 }
00136 if ( gzwrite( file, pbase(), w)) {
00137 setp( pbase(), epptr() - 1);
00138 return c;
00139 } else
00140 return EOF;
00141 }
00142
00143 int sync() {
00144 if ( pptr() && pptr() > pbase()) {
00145 int c = overflow( EOF);
00146 if ( c == EOF)
00147 return -1;
00148 }
00149 return 0;
00150 }
00151 };
00152
00153 class gzstreambase : virtual public std::ios {
00154 protected:
00155 gzstreambuf buf;
00156 public:
00157 gzstreambase() { init(&buf); }
00158
00159 gzstreambase( const char* name, int mode) {
00160 init( &buf);
00161 open( name, mode);
00162 }
00163
00164 ~gzstreambase() {
00165 buf.close();
00166 }
00167
00168 void open( const char* name, int open_mode) {
00169 if ( ! buf.open( name, open_mode))
00170 clear( rdstate() & std::ios::badbit);
00171 }
00172
00173 void close() {
00174 if ( buf.is_open())
00175 if ( ! buf.close())
00176 clear( rdstate() & std::ios::badbit);
00177 }
00178
00179 gzstreambuf* rdbuf() { return &buf; }
00180 };
00181
00182
00183
00184
00185
00186
00187
00188 class igzstream : public gzstreambase, public std::istream {
00189 public:
00190 igzstream() : std::istream( &buf) {}
00191 igzstream( const char* name, int open_mode = std::ios::in)
00192 : gzstreambase( name, open_mode), std::istream( &buf) {}
00193 gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
00194 void open( const char* name, int open_mode = std::ios::in) {
00195 gzstreambase::open( name, open_mode);
00196 }
00197 };
00198
00199 class ogzstream : public gzstreambase, public std::ostream {
00200 public:
00201 ogzstream() : std::ostream( &buf) {}
00202 ogzstream( const char* name, int mode = std::ios::out)
00203 : gzstreambase( name, mode), std::ostream( &buf) {}
00204 gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
00205 void open( const char* name, int open_mode = std::ios::out) {
00206 gzstreambase::open( name, open_mode);
00207 }
00208 };
00209
00210 #ifdef GZSTREAM_NAMESPACE
00211 }
00212 #endif
00213
00214 #endif // GZSTREAM_H
00215
00216
00217