| #ifndef moses_gzfile_buf_h |
| #define moses_gzfile_buf_h |
|
|
| #include <stdexcept> |
| #include <streambuf> |
| #include <zlib.h> |
| #include <cstring> |
|
|
| class gzfilebuf : public std::streambuf |
| { |
| public: |
| gzfilebuf(const char *filename) { |
| _gzf = gzopen(filename, "rb"); |
| if (!_gzf) |
| throw std::runtime_error("Could not open " + std::string(filename) + "."); |
| setg (_buff+sizeof(int), |
| _buff+sizeof(int), |
| _buff+sizeof(int)); |
| } |
| ~gzfilebuf() { |
| gzclose(_gzf); |
| } |
| protected: |
| virtual int_type overflow (int_type c) { |
| throw; |
| } |
|
|
| |
| virtual |
| std::streamsize xsputn (const char* s, |
| std::streamsize num) { |
| throw; |
| } |
|
|
| virtual std::streampos seekpos ( std::streampos sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) { |
| throw; |
| } |
|
|
| |
| virtual int_type underflow () { |
| |
| if (gptr() < egptr()) { |
| return traits_type::to_int_type(*gptr()); |
| } |
|
|
| |
| |
| |
| |
| unsigned int numPutback = gptr() - eback(); |
| if (numPutback > sizeof(int)) { |
| numPutback = sizeof(int); |
| } |
|
|
| |
| |
| |
| std::memmove (_buff+(sizeof(int)-numPutback), gptr()-numPutback, |
| numPutback); |
|
|
| |
| int num = gzread(_gzf, _buff+sizeof(int), _buffsize-sizeof(int)); |
| if (num <= 0) { |
| |
| return EOF; |
| } |
|
|
| |
| setg (_buff+(sizeof(int)-numPutback), |
| _buff+sizeof(int), |
| _buff+sizeof(int)+num); |
|
|
| |
| return traits_type::to_int_type(*gptr()); |
| } |
|
|
| std::streamsize xsgetn (char* s, |
| std::streamsize num) { |
| return gzread(_gzf,s,num); |
| } |
|
|
| private: |
| gzFile _gzf; |
| static const unsigned int _buffsize = 1024; |
| char _buff[_buffsize]; |
| }; |
|
|
| #endif |
|
|