Boost logo

Boost Users :

Subject: Re: [Boost-users] [iostreams] filtering_istream not working asintended..
From: Eric MALENFANT (Eric.Malenfant_at_[hidden])
Date: 2009-06-17 10:24:55


mmocny wrote:
> boost::iostreams::file log_file("sample.txt", std::ios::trunc);
> boost::iostreams::filtering_istream in;
> in.push(
> boost::iostreams::invert(boost::iostreams::tee(log_file)) ) /* this
> part is optional */
> in.push( std::cin );
> std::string s;
> int i;
[snip]
> /* step 2 */
> getline(in,s); /* note: filtering_istream wrapping
> std::cin passed here */
> in >> i;
> std::cin.ignore(
> std::numeric_limits<std::streamsize>::max(), '\n' );
> std::cout << s << std::endl << i << std::endl;
[snip]
> The filtering_istream blocks on input, and will not resume
> until *4* EOF characters are sent. If I remove the
> invert(tee(log_file)) only *2* EOF need to be sent.

The problem comes from the buffering, which is in multiple places.
Neglecting the invert(tee(file)) for the moment, disabling buffering when push()-ing std::cin like this:

  filtering_istream in;
  in.push(std::cin, 0); //Note the "0 buffer size" passed here

causes the rest of your example program to function properly.

Buffering around the invert(tee(file)) can be made similarly:

  in.push(invert(tee(log_file)), 0);

But this not enough, because of the way invert works: When reading from it, it first fills a buffer, and then flushes that buffer to the sink. What happens here is that not enough input can be read for filling the buffer, and this step thus blocks.

I'm not sure this is efficient, but setting a buffer size of 1 on the "invert" seems to work. (Annoyingly, the invert() function does not take a buffer size parameter, so I have to explicitely construct an inverse in what follows).

Summing up, constructing the filtering_istream as follows "works":

  namespace bio = boost::iostreams;
  bio::file log_file("deleteme.txt", std::ios::trunc);
  bio::filtering_istream in;
  in.push(bio::inverse<bio::tee_filter<bio::file> >(bio::tee(log_file), 1), 0);
  in.push(std::cin, 0);

HTH,

Éric Malenfant


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net