|
#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 |
|
|