Another desperate request for help with a simple IOStreams sink and filter

I'm looking for some help with the following code where I try to
implement an aggregate filter and a sink. This super simple example is
supposed to print the xorred input but instead it prints:
The result is:
do_filter
write: 01+x1+x,*!x76=
Does anyone understand why the filtering and sink.write are not done
as part of the copy operation? The last two lines should be printed as
part of the copy process! It seems they are executed as part of
destructing these objects instead?
This stuff should be so simple :-/
S.
#include <cctype>
#include <iostream>
#include <memory>
#include <string>
#include

On Feb 4, 2008 6:33 PM, Stefan Arentz
I'm looking for some help with the following code where I try to implement an aggregate filter and a sink. This super simple example is supposed to print the xorred input but instead it prints:
The result is: do_filter write: 01+x1+x,*!x76=
Does anyone understand why the filtering and sink.write are not done as part of the copy operation? The last two lines should be printed as part of the copy process! It seems they are executed as part of destructing these objects instead?
I got a very useful hint on the #boost irc channel about this: calling out.reset() after the copy() made the code work correctly. I'm a confused about this though since the documentation of copy states: "The function template copy reads data from a given model of Source and writes it to a given model of Sink until the end of stream is reached. It then closes both components, using the function template close, and returns the number of characters written." But when looking at the source of copy() I see there is no close() done at all. Is anyone actually using the library? I can't believe I'm the first finding a bug like this in a 5 year old library. S.

Stefan Arentz wrote:
Does anyone understand why the filtering and sink.write are not done as part of the copy operation? The last two lines should be printed as part of the copy process! It seems they are executed as part of destructing these objects instead?
I got a very useful hint on the #boost irc channel about this: calling out.reset() after the copy() made the code work correctly.
I'm a confused about this though since the documentation of copy states:
"The function template copy reads data from a given model of Source and writes it to a given model of Sink until the end of stream is reached. It then closes both components, using the function template close, and returns the number of characters written."
But when looking at the source of copy() I see there is no close() done at all.
It's in there: see lines 132-33. The problem is that filtering_stream does not model Closable, so close() is a no-op. This is counterintuitive and probably represent a less than ideal design, but when I wrote the library I couldn't think of a satisfactory way to define close() for a filtering stream. You might think that the way to define close() would simply be to close all the filters and devices in the chain. Unfortunately, this is not correct. The reason is that while filters are designed to be reusable, devices are in general one-use only. For example, when a compression filter is closed, it is expected to be in a state where it can be used to compress a fresh stream of data. But when a file is closed, it is not reset to the state it was in when it was first opened: it has to be manually reopened with a new user-provided pathname. So simply closing all the filters and devices in the chain would leave the chain in an unusable state. The closest I could come to defining a non-trivial close() for filtering_streams was to have close() call pop() -- in effect, closing all the filters and discarding the final device. However, my feeling was that this behavior would be considered counterintuitive. I knew this could cause problems with copy, but I decided to wait for user feedback before making any changes. The issue never came up, and I forgot about it until now. It could be that not many are using the library, as you suggest, or that people discovered that you can solve the problem by calling reset() or pop() -- as you heard on the IRC channel -- and never bothered to bring it up on this list. I've created a ticket for this issue: http://svn.boost.org/trac/boost/ticket/1624. At the very least it should be a FAQ.
Is anyone actually using the library? I can't believe I'm the first finding a bug like this in a 5 year old library.
S.
-- Jonathan Turkanis CodeRage http://www.coderage.com
participants (2)
-
Jonathan Turkanis
-
Stefan Arentz