Streams: an open discussion

Ben Hinkle bhinkle at mathworks.com
Thu Mar 16 06:35:44 PST 2006


<surferjeff at excite.com> wrote in message 
news:dvaupb$1ok0$1 at digitaldaemon.com...
> In article <dtsbc3$1c8g$1 at digitaldaemon.com>, Ben Hinkle says...
>>
>>
>><surferjeff at excite.com> wrote in message
>>news:dtribg$eui$1 at digitaldaemon.com...
>>> The interface for InputStream and OutputStream is huge.  I often have to
>>> create
>>> my own streambufs in C++, which only requires implementing about 5
>>> methods.  If
>>> I want to write my own class that implements InputStream, then I have to
>>> implement about 50 methods, and another 50 if I want to implement
>>> OutputStream
>>> too!
>>>
>>> It would useful if there were smaller interfaces.  For example, a read()
>>> method
>>> and eof() for input, and that's it.  Then have a util class that takes 
>>> one
>>> of
>>> these small interfaces and implements the full 50 methods in the bigger
>>> interface.
>>>
>>> Yes, I could do this in my own code, but I think many people will have 
>>> to
>>> re-invent this wheel in D, and each re-invention will be different and 
>>> not
>>> interchangeable.
>>
>>
>>Subclass Stream or FilterStream. You'll probably have to override 3 
>>methods:
>>readBlock, writeBlock and seek. The interfaces are primarily for users to
>>restrict their API - not for library writers to shoe-horn their classes
>>into. Look at any of the small stream classes in std.stream to get an idea
>>how easy it is to do.
>>
>
> I see. Not so bad.  Thanks.
>
> Instead of the "Inherit 20 methods, implement 3 pure virtual methods" 
> approach,
> how about "implement the same 3 pure virtual methods in an interface, pass 
> the
> interface to a class that uses it to implement the 20 methods."  I've used 
> the
> former pattern a lot in C++, and have found it difficult to reuse.  I 
> recently
> learned the latter pattern in Objective-C and Cocoa, and have found it 
> much
> easier to reuse.

Sure, one can trade-off flexibility and ease-of-use. For example 
std.stream.File could just implement the 3 pure virtual methods and then 
user code would write
 Stream file = new Stream(new File("foo.txt"));
So the flexibility of multiple classes and interfaces results in user code 
having to do more to hook things up. There are many many ways to slice 
things up. At one point I posted a suggestion to have a Stream subclass that 
accepted delegates for the 3 methods and then one wouldn't have to write a 
class at all - one can just write 3 nested functions and pass those to the 
constructor. For example
 void foo() {
    char buf[100];
    size_t readBlock(void* buffer, size_t size) {
       ... do something with buf ...
    }
    .. 2 more nested functions for writeBlock and seek ...
    Stream s = new DelegateStream(&readBlock, &writeBlock, &seek);
    ... use s as any other stream ...
    }
but I don't recall that suggestion getting any lovin' so I dropped it.
I think if you have concrete suggestions go ahead and post them, see what 
kind of response you get and based on the response make changes and submit 
them to Walter and see how things go.

-Ben 





More information about the Digitalmars-d mailing list