On Sat, 03 Sep 2011 21:47:53 -0400, Andrei Alexandrescu
<[email protected]> wrote:
On 9/3/11 3:54 PM, Andrei Alexandrescu wrote:
http://erdani.com/d/new-stdio/phobos-prerelease/std_stdio.html
Here are a few points following a pass through the dox:
* After thinking some more about it, I find the approach seek() plus
enumerated Anchor undesirable. It's a bad case of logical coupling as
one never calls seek() passing an anchor as a variable. It's really
three functions - seekForward, seekBackward, and seekAbsolute. Heck,
knowing what seek does, it should be just seekAbsolute. But then there
are several possible designs; a logically coupled seek() is not a good
turn in any case.
I think you need to support all three, but they could be individual
functions. It just is easy to provide the same interface the OS handle
provides. Let's entertain changing to three separate functions.
But I think we need to support seek from front, seek from end, and seek
from current. I don't know about the three you mentioned. How would you
seek to the end if you didn't have seekEnd? And seeking forward or
backward I think is captured much better via a positive or negative
integer. I can imagine having to write code like this:
if(pos < cur)
seekBackward(cur - pos);
else
seekForward(pos - cur);
* Seekable should document that tell() is O(1) and seek() can be
considered O(1) but with a large constant factor.
OK, docs need lots of TLC for sure.
* Why is close() not part of Seekable, since Seekable seems to be the
base of all streams?
Hm... not really sure. I suppose it could be! But then, should the
interface be called Seekable? What about just Stream?
* Class File is IMHO not going to cut the mustard. It needs to be a
struct with a destructor. One should be able to _get_ an InputStream or
an OutputStream interface out of a File object (i.e. a file is a factory
of such interfaces), but the File itself must be a struct.
I'm seeing a large backlash on this decision. I'm going to revisit it.
Note, however, that it was a poor choice of name for File on my part.
File is *not* equivalent to the current stdio.File, in that it's not
buffered, and is not text-based.
* I don't understand the difference between read() and readComplete().
read() gets as much data as it can from the buffer and from the stream
using at most one low-level read. readComplete() will continually read
until either EOF is encountered, or the requested data is read. I started
making read() do what readComplete does, but it surprisingly is a very
difficult low-level thing to write. However, readComplete() is trivial to
implement on top of read(), which is why I split the two functions.
Please, come up with a better name, I hate readComplete :)
* readUntil is a bit tenuous. I was hoping for a simpler interface to
buffered streams, e.g. just expose the buffer as a ubyte[].
I think we need a const(ubyte)[] peek(size_t nbytes). Would this suffice?
* readUntil(const(ubyte)[]) does not give a cheap means to figure
whether the read ended because file ended or the terminator was met.
You are right. I'll think about this.
* There's several readUntil but only one appendUntil. Why?
Didn't get around to it yet. The overloads for readUntil are trivial, so
can be copied easily enough to appendUntil.
* Document the difference between skip and seek. Also, skip should take
a ulong.
skip is buffer-only. It will never trigger a low-level call.
I will fill the docs more completely.
Given this, I think size_t is the right type, as a buffer cannot be more
than size_t bytes in length.
* I see encoder and decoder() in DInput, should both be decoder?
Yes. encoder is for DOutput, copy-paste error.
* StreamWidth, TextXXX and friends are a bit sudden because they
introduce a higher-level abstraction in a module so far only preoccupied
to transferring bytes. I was thinking that kind of stuff would belong to
a formatter/serializer module.
Could be moved. However, stdin stderr and stdout are traditionally
text-based, and stdio contains them. I wanted to split out text-handling
from the basic buffered stream, since it's very specific. For example,
having to deal with an object that supports formatted text i/o for a
network socket seems uncommon.
I'm open to suggestions.
Note, I must have had a brain-malfunction when I gave what I thought was a
fairly completely-documented module. I missed some very important
declarations and functions. I'll work on fixing the docs and giving you a
new copy. Thanks again for hosting it.
-Steve