I've had a look at readUntil API, and it's not completely clear. Is the delegate supposed to remember what it has read and interpreted so far, or does it have to start from scratch each time ? Where could I see an implementation of a delegate suitable for readUntil ?
Basically, in both your and my API, a stream is giving some more characters to a readFrom method, as long as it asks for more. What I am not sure is if readFrom is supposed to build the read object like in my API , or if it is supposed to be built after with the string returned by readUntil. I think the main difference is that your API is written from the stream point of view, whereas my API is written from the point of view of the object being read, which will make implementation of readFrom easier by the users, who will not have to worry about their delegate being called multiple time. If I have more time, I may look deeper into Phobos stdin and your stdin proposal, but I'm not sure I should afford that... In the mean time, I hope I gave you nice ideas to improve your own proposal. Here are some more... I will sum up the different ways to deal with buffering and any one of your API for readUntil, and my proposed API: 1/ _use only peek_ -the API is written to peek only one character at a time. You definitely lose the possibility for a stream to give a char[] directly to the parsing function, even for streams that are not files... 2/ _use c for low level stdin_ -the default stream derived from stdin or from a file peeks only one character at a time. Everything works fine with c functions. -you can still explicitly create a stream object from a File to make double buffering and return several characters, but that makes the File no longer suitable for c functions, since some unread buffer can be hidden in the object performing the streaming operations. 3/ _hack into c functions_ -the default stream stream hacks into FILE* to use it's own internal buffer. This may not be easy to implement, but should be feasible by a system programmer, shouldn't it ? 4/ _WTH, d should not rely on c functions to do all low level jobs_ -the default stream peeks several characters. c functions are broken. -you can still rewrite c-like functions. For example, scanf could be the same as readf, but would support 0-terminated strings, and be implemented as a c-style variadic function (avoiding multiple template instanciation which make the generated code so big Walter refuses to use it). -if you need, you can still instanciate a FILE* that will never be seen by the d library, and that will work fine with c functions. 5/ _variation on 2 and 4_ - File are still compatible with current Phobos API, and the default streaming mode for file only peek one caracter at a time. - Some new struct can perform file operations in a d-like way that is incompatible with c function. However, no accessible File object is ever created for this structure, so no one will mix c and d read/write function. #2 makes a first implementation of the API easy. Nothing must get broken for it to work, everybody is happy and can start implementing readFrom without breakinf any old code (as long as no other changes are made in stdio's API). #3 can be implemented later, if it is possible, and all changes will occur at the library level, so it should not break code (even if explicit streams breaking scanf get useless). #4 is a step forward to make d a langage that do not rely in c anymore. That may or may not be desirable. Some code will have to change, even if my propositions to replace scanf and should temper. #5 allow to make everything you want the d-way, while keeping old File working. One last point: any comments about using writeTo with my "stream" API like readFrom ? -- Christophe Travert