| #ifndef moses_gzfile_buf_h |
| #define moses_gzfile_buf_h |
|
|
| #include <stdexcept> |
| #include <streambuf> |
| #include <zlib.h> |
| #include <cstring> |
|
|
| namespace probingpt |
| { |
|
|
| |
| |
| |
| 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 ) { |
| throw; |
| } |
|
|
| |
| virtual std::streamsize xsputn(const char* , std::streamsize ) { |
| throw; |
| } |
|
|
| virtual std::streampos seekpos(std::streampos , |
| std::ios_base::openmode ) { |
| 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 |
|
|