mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-09-11 11:25:40 +03:00
89 lines
2.2 KiB
C++
89 lines
2.2 KiB
C++
#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), // beginning of putback area
|
|
_buff+sizeof(int), // read position
|
|
_buff+sizeof(int)); // end position
|
|
}
|
|
~gzfilebuf() {
|
|
gzclose(_gzf);
|
|
}
|
|
protected:
|
|
virtual int_type overflow (int_type c) {
|
|
throw;
|
|
}
|
|
|
|
// write multiple characters
|
|
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;
|
|
}
|
|
|
|
//read one character
|
|
virtual int_type underflow () {
|
|
// is read position before end of _buff?
|
|
if (gptr() < egptr()) {
|
|
return traits_type::to_int_type(*gptr());
|
|
}
|
|
|
|
/* process size of putback area
|
|
* - use number of characters read
|
|
* - but at most four
|
|
*/
|
|
unsigned int numPutback = gptr() - eback();
|
|
if (numPutback > sizeof(int)) {
|
|
numPutback = sizeof(int);
|
|
}
|
|
|
|
/* copy up to four characters previously read into
|
|
* the putback _buff (area of first four characters)
|
|
*/
|
|
std::memmove (_buff+(sizeof(int)-numPutback), gptr()-numPutback,
|
|
numPutback);
|
|
|
|
// read new characters
|
|
int num = gzread(_gzf, _buff+sizeof(int), _buffsize-sizeof(int));
|
|
if (num <= 0) {
|
|
// ERROR or EOF
|
|
return EOF;
|
|
}
|
|
|
|
// reset _buff pointers
|
|
setg (_buff+(sizeof(int)-numPutback), // beginning of putback area
|
|
_buff+sizeof(int), // read position
|
|
_buff+sizeof(int)+num); // end of buffer
|
|
|
|
// return next character
|
|
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
|