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