"Thomas Søîdergaard" <tsondergaard / speakanet.com> wrote in message news:DFC899CCE177624AB6A2F121DD0CC976B55B / granada.speakanet.com... >> Has this discussion stalled? Matz asked for a concrete proposal about >> a "Stream" API but none materialized. I understand his request -- I >> am a bit fuzzy on what this RCR is actually requesting myself. > >Yep, it has stalled. I posted the RCR because with rubyzip I'm faced with the challenge of >creating an object that can be used in place of an instance of IO. Take any client-code that >uses an IO instance. I'd like to be able to supply that client-code with an instance of, say, >ZipInputStream, and it should just work. This is trivial with java.io streams and possible >with C++ iostreams. It is *hard* with IO. > >I feel that IO mixes a lot of stuff together, which is possibly nice for client-code, but terrible >for implementers of IO "subclasses". Conesequently the RCR for breaking it into >orthogonal parts, that can easily be specialized and reused. Implementing a new datasink >should be a matter of implementing a very simple interface, e.g with two methods write >(aString) and close. It should not be necessary to reimplement convenience methods such >as puts, printf, etc. The same goes for data sources. As far as ZIP files, or MIME-encoded email, that doesn't seem to me a stream issue, but more of a "resource managment" issue. Perhaps an object abstraction which allows derivations to enumerate their resources, complete with MIME type information, etc., could be of use there. They could, in turn, use streams to send/receive their resources, however. But where I/O is concerned, here's a base implementation that I use and have found very extensible to all sorts of streams. Currently, I have stdio, file, sockets (plain and SSL), string and memory buffers using a system of class functionally identical to what I describe below: result code ranges: success endoffile tryagain closed readerror writeerror buffererror timeout pure base abstraction (which must be implemented by any derivations) bool _rewind long _getlength long _tell long _seek result _truncate result _read(buffer, size) result _write(buffer, size) result _waitforread(seconds) result _waitforwrite(seconds) base implementation, inherits pure base bool rewind long getlength long tell long seek result truncate result putc result getc result peekc result puts result gets result printf result read result write The pure base abstraction contains functions which all must be implemented by the higher derivations. Even if they just give an error because they don't support the feature. For the most part, it just reads and writes blocks of data which are then maintained in a buffer by the base implementation. The base implementation does most of the grunt work, reading and maintaining an internal data buffer for efficiency (speed mostly), reallocating the buffer when it has run out, etc. When calls are made to seek, truncate or rewind on streams that support it the buffer is destroyed and the true I/O pointer is corrected to reflect where it should be were the data not being buffered. Essentially, any IO stream that can read and write should be able to use this sort of abstraction. When it can't support seeking, etc, oh well, toss an error. Sean