
"George M. Garner Jr." <gmgarner@erols.com> wrote in message news:ci01a3$a6n$1@sea.gmane.org...
Johnathan,
Now for some real fun. I am going to try and attach an overlapped filebuf to one of your
streams. :-)
Good luck!
That worked without a hitch.
Great!
But that is only because my overlapped_filebuf uses blocking semantics.
Yeah, I know.
My original goal was to be able to transparently interchange regular files and sockets as "sinks" and this will allow me to do that. But the std stream and filebuf interfaces are really a straight-jacket when it comes to more advanced applications, such as truly asynchronous io; and the sooner we realize that the better.
I agree. If you haven't already read it see 'Future Directions' (http://tinyurl.com/6r8p2). Forgive me if I repeat myself a bit: My view is that to handle asynchronous i/o properly one will need to define an AsyncronousResource concept. Using AsyncronousResources and filters one should be able to define a number of different i/o abstractions, some of which may be standard streams and stream buffers, but some of which may be entirely different. I think the crucial design question now is to make sure that current filters will work with future AsyncronousResources, and I have tentatively concluded that it suffices to give filters a way to indicate that fewer than the requested number of characters have been read or written, even though EOF has not been reached and no error has occured. The only hard part is the return type of the member function get() for an input filter. I suggested that it could return a class type convertible to the character type which can be explicitly tested for eof or temporary unavailability of data. It would work like this: "Jonathan Turkanis" <technews@kangaroologic.com> wrote:
... looking at the alphabet_input filter from the tutorial, instead of
struct alphabetic_input_filter : public input_filter { template<typename Source> int get(Source& src) { int c; while ((c = boost::io::get(src)) != EOF && !isalpha(c)) ; return c; } };
you'd write:
struct alphabetic_input_filter : public input_filter { template<typename Source> int get(Source& src) { character c; while ((c = boost::io::get(src)).good() && !isalpha(c)) ; return c; } }; Here, eof and fail values are passed on to the caller unchanged. If you want to send an eof or fail notification explicitly, you'd write return eof() or return fail().
I'd like to get your input on this idea.
Imagine if, for example, instead of doing write(char_type*, size_t) you could do write(ref_string<char_type>&) or write(ref_string_plus_overlapped<char_type>&). An observer could transparently pass the buffer to the next layer without modification while an asynchronous sink could take ownership of buffer by calling a swap() member function and then pass the buffer to a waiting thread. The buffer could grow or shrink as it passes from one filter to another. The buffer could even pass in round robin fashion back to its origin if every observer or filter called swap() in turn. But that is just a dream.
My hope is that this will all be possible. It sounds like you think we might need AynchronousFilters as well. Is that right? I'm hoping to avoid this, since I wouldn't want to force people to write several versions of rhe same filter, one for blocking i/o, one for asyn i/o, etc. In particular, I'm interested in interoperability with Hugo Duncan's library (see http://tinyurl.com/w0f7 and http://tinyurl.com/6w2l ), but I haven't contacted hime yet. By the way, if I'm not mistaken, you haven't yet submitted a formal review. Would you care to do so? Best Regards, Jonathan