Skip to content

Commit

Permalink
Add flushing support for gzip filter. Uses Z_FULL_FLUSH
Browse files Browse the repository at this point in the history
  • Loading branch information
sidhant007 committed May 20, 2020
1 parent 601244b commit 6d3a800
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 1 deletion.
7 changes: 7 additions & 0 deletions include/boost/iostreams/filter/gzip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
struct category
: dual_use,
filter_tag,
flushable_tag,
multichar_tag,
closable_tag
{ };
Expand Down Expand Up @@ -271,6 +272,12 @@ class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
}
close_impl();
}

template<typename Sink>
bool flush(Sink& snk) {
base_type::force_flush(snk);
return true;
}
private:
static gzip_params normalize_params(gzip_params p);
void prepare_footer();
Expand Down
22 changes: 22 additions & 0 deletions include/boost/iostreams/filter/symmetric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,28 @@ class symmetric_filter {
close_impl();
}
}

template<typename Sink>
void force_flush(Sink &snk) {
if (!(state() & f_write))
begin_write();
try {
buffer_type& buf = pimpl_->buf_;
char_type dummy;
const char_type* end = &dummy;
// Repeatedly invoke filter() with no input.
bool again = true;
while(again) {
if(buf.ptr() != buf.eptr()) {
again = filter().force_flush(end, end, buf.ptr(), buf.eptr());
}
flush(snk);
}
} catch (...) {
throw;
}
}

SymmetricFilter& filter() { return *pimpl_; }
string_type unconsumed_input() const;

Expand Down
15 changes: 15 additions & 0 deletions include/boost/iostreams/filter/zlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ BOOST_IOSTREAMS_DECL extern const int buf_error;
BOOST_IOSTREAMS_DECL extern const int finish;
BOOST_IOSTREAMS_DECL extern const int no_flush;
BOOST_IOSTREAMS_DECL extern const int sync_flush;
BOOST_IOSTREAMS_DECL extern const int full_flush;

// Code for current OS

Expand Down Expand Up @@ -232,6 +233,8 @@ class zlib_compressor_impl : public zlib_base, public zlib_allocator<Alloc> {
bool filter( const char*& src_begin, const char* src_end,
char*& dest_begin, char* dest_end, bool flush );
void close();
bool force_flush( const char*& src_begin, const char* src_end,
char*& dest_begin, char* dest_end);
};

//
Expand Down Expand Up @@ -361,6 +364,18 @@ bool zlib_compressor_impl<Alloc>::filter
template<typename Alloc>
void zlib_compressor_impl<Alloc>::close() { reset(true, true); }

template<typename Alloc>
bool zlib_compressor_impl<Alloc>::force_flush
( const char*& src_begin, const char* src_end,
char*& dest_begin, char* dest_end)
{
before(src_begin, src_end, dest_begin, dest_end);
int result = xdeflate(zlib::full_flush);
after(src_begin, dest_begin, true);
zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result);
return result == zlib::okay;
}

//------------------Implementation of zlib_decompressor_impl------------------//

template<typename Alloc>
Expand Down
3 changes: 2 additions & 1 deletion src/zlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const int buf_error = Z_BUF_ERROR;
const int finish = Z_FINISH;
const int no_flush = Z_NO_FLUSH;
const int sync_flush = Z_SYNC_FLUSH;
const int full_flush = Z_FULL_FLUSH;

// Code for current OS

Expand All @@ -76,7 +77,7 @@ void zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error)
switch (error) {
case Z_OK:
case Z_STREAM_END:
//case Z_BUF_ERROR:
case Z_BUF_ERROR:
return;
case Z_MEM_ERROR:
boost::throw_exception(std::bad_alloc());
Expand Down

0 comments on commit 6d3a800

Please sign in to comment.