Skip to content

Commit 6d3a800

Browse files
committed
Add flushing support for gzip filter. Uses Z_FULL_FLUSH
1 parent 601244b commit 6d3a800

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

include/boost/iostreams/filter/gzip.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
193193
struct category
194194
: dual_use,
195195
filter_tag,
196+
flushable_tag,
196197
multichar_tag,
197198
closable_tag
198199
{ };
@@ -271,6 +272,12 @@ class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
271272
}
272273
close_impl();
273274
}
275+
276+
template<typename Sink>
277+
bool flush(Sink& snk) {
278+
base_type::force_flush(snk);
279+
return true;
280+
}
274281
private:
275282
static gzip_params normalize_params(gzip_params p);
276283
void prepare_footer();

include/boost/iostreams/filter/symmetric.hpp

+22
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,28 @@ class symmetric_filter {
185185
close_impl();
186186
}
187187
}
188+
189+
template<typename Sink>
190+
void force_flush(Sink &snk) {
191+
if (!(state() & f_write))
192+
begin_write();
193+
try {
194+
buffer_type& buf = pimpl_->buf_;
195+
char_type dummy;
196+
const char_type* end = &dummy;
197+
// Repeatedly invoke filter() with no input.
198+
bool again = true;
199+
while(again) {
200+
if(buf.ptr() != buf.eptr()) {
201+
again = filter().force_flush(end, end, buf.ptr(), buf.eptr());
202+
}
203+
flush(snk);
204+
}
205+
} catch (...) {
206+
throw;
207+
}
208+
}
209+
188210
SymmetricFilter& filter() { return *pimpl_; }
189211
string_type unconsumed_input() const;
190212

include/boost/iostreams/filter/zlib.hpp

+15
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ BOOST_IOSTREAMS_DECL extern const int buf_error;
8484
BOOST_IOSTREAMS_DECL extern const int finish;
8585
BOOST_IOSTREAMS_DECL extern const int no_flush;
8686
BOOST_IOSTREAMS_DECL extern const int sync_flush;
87+
BOOST_IOSTREAMS_DECL extern const int full_flush;
8788

8889
// Code for current OS
8990

@@ -232,6 +233,8 @@ class zlib_compressor_impl : public zlib_base, public zlib_allocator<Alloc> {
232233
bool filter( const char*& src_begin, const char* src_end,
233234
char*& dest_begin, char* dest_end, bool flush );
234235
void close();
236+
bool force_flush( const char*& src_begin, const char* src_end,
237+
char*& dest_begin, char* dest_end);
235238
};
236239

237240
//
@@ -361,6 +364,18 @@ bool zlib_compressor_impl<Alloc>::filter
361364
template<typename Alloc>
362365
void zlib_compressor_impl<Alloc>::close() { reset(true, true); }
363366

367+
template<typename Alloc>
368+
bool zlib_compressor_impl<Alloc>::force_flush
369+
( const char*& src_begin, const char* src_end,
370+
char*& dest_begin, char* dest_end)
371+
{
372+
before(src_begin, src_end, dest_begin, dest_end);
373+
int result = xdeflate(zlib::full_flush);
374+
after(src_begin, dest_begin, true);
375+
zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result);
376+
return result == zlib::okay;
377+
}
378+
364379
//------------------Implementation of zlib_decompressor_impl------------------//
365380

366381
template<typename Alloc>

src/zlib.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const int buf_error = Z_BUF_ERROR;
5858
const int finish = Z_FINISH;
5959
const int no_flush = Z_NO_FLUSH;
6060
const int sync_flush = Z_SYNC_FLUSH;
61+
const int full_flush = Z_FULL_FLUSH;
6162

6263
// Code for current OS
6364

@@ -76,7 +77,7 @@ void zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error)
7677
switch (error) {
7778
case Z_OK:
7879
case Z_STREAM_END:
79-
//case Z_BUF_ERROR:
80+
case Z_BUF_ERROR:
8081
return;
8182
case Z_MEM_ERROR:
8283
boost::throw_exception(std::bad_alloc());

0 commit comments

Comments
 (0)