Streaming transport interfaces: input

Steven Schveighoffer schveiguy at yahoo.com
Thu Oct 14 10:27:19 PDT 2010


On Thu, 14 Oct 2010 11:34:12 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Starting a new thread from Denis' question:
>
>> Can we outline basic Stream interface now so that we could move on?
>
> Here's the input transport layer. Transport has no concern for  
> formatting - it just moves stuff around.
>
> interface TransportBase
> {
>      /// True if stream has no more data.
>      @property bool empty();
>      /// True if the position property works
>      @property bool positionable();
>      /// Gives current position in stream
>      @property ulong position();
>      /// Moves stream to absolute position pos
>      @property void position(ulong pos);
> }

Please, use the term "seek", and allow an anchor.  Every OS allows this,  
it makes no sense not to provide it.

Other than that, I like the idea (assuming output transport is forthcoming  
and implements TransportBase).

>
> interface InputBinaryTransport : TransportBase
> {
>      /// Reads up to target.length bytes into target,
>      /// returns size of data read. If target.length < 1 throws.
>      size_t read(ubyte[] target);
>      /// Appends to target up until delimiter is found or end of stream.
>      /// The delimiter is included in the target. Returns number
>      /// of bytes read.
>      size_t appendDelim(ref ubyte[] target, in ubyte[] delimiter);
> }

I don't like appendDelim.  We don't need to define that until we have  
buffering.  The simple function of an input stream is to read data.  With  
buffering you get all the goodies that you want, but the buffer should be  
in control of its data buffer.

Basically, appendDelim can be defined outside this class, because the  
primitive read is enough.

> interface InputTextTransport : TransportBase
> {
>      /// Returns the native character size: 1 for UTF-8, 2 for UTF-16,
>      /// 4 for UTF-32, 0 for nonstandard native encodings.
>      @property size_t nativeUTFWidth();
>
>      /// Reads complete UTF code points into target, without going
>      /// beyond target.length. Returns number of code units read.
>      /// If target.length < 4 throws.
>      size_t read(char[] target);
>      /// Appends to target up until delimiter is found or end of stream.
>      /// The delimiter is included in the target. Returns number of
>      /// code units read.
>      size_t appendDelim(ref char[] target, in char[] delimiter);
>
>      /// Reads complete UTF code points into target, without going
>      /// beyond target.length. Returns number of code units read.
>      /// If target.length < 2 throws.
>      size_t read(wchar[] target);
>      /// Appends to target up until delimiter is found or end of stream.
>      /// The delimiter is included in the target. Returns number of
>      /// code units read.
>      size_t appendDelim(ref wchar[] target, in wchar[] delimiter);
>
>      /// Reads complete UTF code points into target, without going
>      /// beyond target.length. Returns number of code units read.
>      /// If target.length < 1 throws.
>      size_t read(dchar[] target);
>      /// Appends to target up until delimiter is found or end of stream.
>      /// The delimiter is included in the target. Returns number of
>      /// code units read.
>      size_t appendDelim(ref dchar[] target, in dchar[] delimiter);
> }

Shouldn't the text transport be defined on top of the binary transport?   
And in any case, I'd expect buffering to go between the two.  If all you  
are adding are the different widths of characters, I don't think you need  
this extra layer.  It's going to make the buffering layer more difficult  
to implement (now it must handle both a text version and abinary version).

-Steve


More information about the Digitalmars-d mailing list