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