From: EMalenfant@interstarinc.com
Consider the following, using dictionary_output_filter from the tutorial: (http://www.boost.org/libs/iostreams/doc/index.html?path=2.2.6.3)
namespace io = boost::iostreams;
const std::string source("This foo will be bar");
io::example::dictionary dict; dict.add("foo", "bar");
io::filtering_istream in; in.push(io::invert(io::example::dictionary_output_filter(dict))); in.push(io::array_source(source.c_str(), source.length()));
io::copy(in, std::cout);
Output: This bar will be
instead of the expected: This bar will be bar
Digging a bit, I found that I could "fix" that problem by modifying invert::read() as follows: template<typename Source> std::streamsize read(Source& src, char* s, std::streamsize n) { typedef detail::counted_array_sink<char_type> array_sink; typedef composite<filter_ref, array_sink> filtered_array_sink; assert((flags() & f_write) == 0); if (flags() == 0) { flags() = f_read; buf().set(0, 0); } filtered_array_sink snk(filter(), array_sink(s, n)); int_type status; for ( status = traits_type::good(); snk.second().count() < n && status == traits_type::good(); ) { status = buf().fill(src); buf().flush(snk); } // "Fix": When eof is reached on the input, close the filter so that it writes // any buffered input it may have. if ((snk.second().count() == 0) && (status == traits_type::eof())){ snk.close(); } //... "fix" ends here return snk.second().count() == 0 && status == traits_type::eof() ? -1 : snk.second().count(); } Looking at this, however, I wondered what would happen if the filter has buffered more characters than what would fit in the array_sink. So I tested with a very long (around 300) last word in the input. Result: An infinite loop in non_blocking_adapter::write(), desperately calling write() on a full counted_array_sink. Guess I'll forget about invert and write an InputFilter...