On Fri, 15 Oct 2010 22:48:20 +0400, Kagamin <[email protected]> wrote:
Denis Koroskin Wrote:
// A generic stream
interface Stream
{
@property InputStream input();
@property OutputStream output();
@property SeekableStream seekable();
@property bool endOfStream();
void close();
}
I think, it's better to inherit Stream from InputStream and OutputStream.
Do you even need endOfStream? From my experience, it's ok to
blocked-read and determine end when 0 is read. Even if you read from
network, is there a point in non-blocking read?
Probably, I think I'll try both ways and see which one turns out to be
better.
InputStream doesn't really has many methods:
interface InputStream
{
// reads up to buffer.length bytes from a stream
// returns number of bytes read
// throws on error
size_t read(ubyte[] buffer);
I've found
ubyte[] read(ubyte[] buffer)
more usable:
ubyte[] buffer=new ubyte[sz];
size_t rd=stream.read(buffer);
ubyte[] rdata=buffer[0..rd];
ubyte[] buffer=new ubyte[sz];
ubyte[] rdata=stream.read(buffer);
And you can instantly pass the read data to some other function.
myProcessor.Process(stream.read(buffer));
Either way is fine with me. But I agree yours is handy, too.
I was actually thinking about a plain ubyte[] read(); method:
struct BufferedStream
{
ubyte[] read(); // just give me something
}
because in many cases you don't really care about buffer size or don't
even know amount of data you can read (e.g. socket stream).
// reads from current position
AsyncReadRequest readAsync(ubyte[] buffer, Mailbox* mailbox = null);
}
I also have an implementation of asyncronous stream with interface
similar to one of .net, though recently I came to another design.
///What one can name "an actual stream" that holds the handle
interface AsyncStreamSource
{
///Advances position on each read
AsyncStream createStream();
///Leaves position intact - adjust manually or rather don't adjust
AsyncStream createStillStream();
}
///An accessor for AsyncStreamSource that wraps an io completion port or
its analogue. Contains stream position at which io is done on
AsyncStreamSource (that's why it's stream - it works like unshared
blocking stream with asynchronous access).
interface AsyncStream
{
void beginRead(ubyte[] buffer);
ubyte[] endRead();
long position() @property;
void position(long newPosition) @property;
}
Multiple AsyncStreams can be created for one AsyncStreamSource. So
effectively one AsyncStreamSource can be shared through different
AsyncStreams, while individual AsyncStreams cannot be shared. With this
design you won't new AsyncResult for each io operation.
Interesting, I think I'll give it a try. This will reduce basic Stream
interface size, and some implementations can return null unless they
support async read/write.
Though such desing can be problematic for linux as its async io
functionality is quite... errmmm... linux way as I remember.
:)