00001
00002
00003 #ifndef _GZFILEBUF_H_
00004 #define _GZFILEBUF_H_
00005
00006 #include <streambuf>
00007 #include <cstring>
00008 #include <zlib.h>
00009 #include <iostream>
00010
00011 class gzfilebuf : public std::streambuf
00012 {
00013 public:
00014 gzfilebuf(const char *filename) {
00015 _gzf = gzopen(filename, "rb");
00016 setg (_buff+sizeof(int),
00017 _buff+sizeof(int),
00018 _buff+sizeof(int));
00019 }
00020 ~gzfilebuf() {
00021 gzclose(_gzf);
00022 }
00023 protected:
00024 virtual int_type overflow (int_type ) {
00025 std::cerr << "gzfilebuf::overflow is not implemented" << std::endl;;
00026 throw;
00027 }
00028
00029
00030 virtual std::streamsize xsputn (const char* , std::streamsize ) {
00031 std::cerr << "gzfilebuf::xsputn is not implemented" << std::endl;;
00032 throw;
00033 }
00034
00035 virtual std::streampos seekpos ( std::streampos , std::ios_base::openmode = std::ios_base::in | std::ios_base::out ) {
00036 std::cerr << "gzfilebuf::seekpos is not implemented" << std::endl;;
00037 throw;
00038 }
00039
00040
00041 virtual int_type underflow () {
00042
00043 if (gptr() < egptr()) {
00044 return traits_type::to_int_type(*gptr());
00045 }
00046
00047
00048
00049
00050
00051 unsigned int numPutback = gptr() - eback();
00052 if (numPutback > sizeof(int)) {
00053 numPutback = sizeof(int);
00054 }
00055
00056
00057
00058
00059 std::memmove (_buff+(sizeof(int)-numPutback), gptr()-numPutback,
00060 numPutback);
00061
00062
00063 int num = gzread(_gzf, _buff+sizeof(int), _buffsize-sizeof(int));
00064 if (num <= 0) {
00065
00066 return EOF;
00067 }
00068
00069
00070 setg (_buff+(sizeof(int)-numPutback),
00071 _buff+sizeof(int),
00072 _buff+sizeof(int)+num);
00073
00074
00075 return traits_type::to_int_type(*gptr());
00076 }
00077
00078 std::streamsize xsgetn (char* s,
00079 std::streamsize num) {
00080 return gzread(_gzf,s,num);
00081 }
00082
00083 private:
00084 gzFile _gzf;
00085 static const unsigned int _buffsize = 1024;
00086 char _buff[_buffsize];
00087 };
00088
00089 #endif