On Tue, 06 Sep 2011 10:07:23 -0400, Christophe <trav...@phare.normalesup.org> wrote:

"Steven Schveighoffer" , dans le message (digitalmars.D:143998), a
 écrit :
void readFrom(const(char)[] delegate(size_t) stream,
              in char[] format = null);

-format is the usual format specifier.
-stream is a delegate that takes a size_t argument, discards as many
characters from its internal buffer, and returns data to read from.
The returned data has any length, but must be empty only when the end of
all the data to be read is reached. stream may overwrite previously
returned data.

So essentially, stream "peeks" at buffered data, and also discards data
you deem "consumed"?  Note that with the current stdio package, you can
only peek at one character.

Wouldn't your life be easier if you could ? :P

I'd love to, which is why I wrote the revamped stdio ;)

Well, I thought there were be some internal buffer in the read functions
of stdio, and in scanf (although it is not accessible). Maybe that's why
it is so slow. Anyway, stream is allowed to return a one-character
const(char)[], although it might not be optimal at all.

Yes, if you look at the input range given to formattedRead in std.stdio.File, it's a one-char-at-a-time range.

It works by calling fgetc, then immediately putting it back using fungetc.

If the "stream" comes from stdin, either chars are peeked one by one and
no changes are to be made to stdin, or all stdin functions must use the
"stream" or at least the same buffer.
The same can be said to std.stdio.File, if we want to make all File
instances compatible with this way of reading.
The readFrom API could be changed to use peek/get delegate instead of
stream, but wouldn't that be such a loss of power ?

That means double-buffering. So FILE * will be buffering the data for you, then you will also buffer the data in File so you can have access to it.

Plus, that makes File incompatible with C functions (i.e. fscanf) since those functions will be unaware of your "unconsumed" buffer.

| const(char)[] delegate(size_t) myFileStream(File file, size_t size)
| {
|   char[] chunk = new char[size];
|   int i=0;
| chunk = file.rawRead(chunk); // @Bug?: file is read in binary mode...
|   return (size_t n)
|     {
|       i += n;
|       if (i>=chunk.length) chunk = file.rawRead(chunk);
|       return chunk[i..$];
|     };
| }

This doesn't work.  What happens to unconsumed data from chunk?  You can
only put one char back on the stream.

Nothing should be read from file you put in myFileStream if not by the
stream itself. Why putting characters back then ?

rawRead removes the characters from the stream.

no API exists that allows you to peek at more than one character for FILE *. This is part of the problem of why I've been working on a new stdio -- there is no good direct buffer access.

-Steve

Reply via email to