33 std::istream* decorated;
35 enum { BUFFER_SIZE = 5000 };
36 char ibuffer[BUFFER_SIZE];
37 char obuffer[BUFFER_SIZE];
38 bz_stream bzip_stream;
49 std::istream* decorated_);
53 virtual int underflow()
override;
57 std::istream* decorated_) :
58 decorated(decorated_),
60 assert(decorated !=
nullptr);
63 std::memset(&bzip_stream, 0,
sizeof(bzip_stream));
64 auto info_(BZ2_bzDecompressInit(&bzip_stream, 0, 0 ));
65 assert(info_ == BZ_OK);
71 BZ2_bzDecompressEnd(&bzip_stream);
74 int Bzip2IStream::Buffer::underflow() {
77 return traits_type::eof();
80 bzip_stream.next_out = obuffer;
81 bzip_stream.avail_out = BUFFER_SIZE;
86 std::memmove(ibuffer, bzip_stream.next_in, bzip_stream.avail_in);
89 decorated->read(ibuffer, BUFFER_SIZE - bzip_stream.avail_in);
90 auto read_bytes_(decorated->gcount());
91 if(read_bytes_ <= 0 && bzip_stream.avail_in == 0) {
93 return traits_type::eof();
97 bzip_stream.next_in = ibuffer;
98 bzip_stream.avail_in += read_bytes_;
99 info_ = BZ2_bzDecompress(&bzip_stream);
100 assert(info_ == BZ_OK || info_ == BZ_STREAM_END);
102 while(info_ != BZ_STREAM_END && bzip_stream.next_out == obuffer);
106 if(info_ == BZ_STREAM_END) {
110 if(obuffer == bzip_stream.next_out)
111 return traits_type::eof();
113 assert(obuffer != bzip_stream.next_out);
116 setg(obuffer, obuffer, bzip_stream.next_out);
118 return traits_type::to_int_type(*obuffer);
122 std::istream* decorated_) :
123 buffer(new
Buffer(decorated_)) {