[fpc-pascal] TStream.ReadBuffer doesn't try hard enough to read the requested bytes
ewald at yellowcouch.org
Sun Jun 16 02:30:20 CEST 2013
On 16 Jun 2013, at 01:08, Michalis Kamburelis wrote:
> Which means that ReadBuffer should retry calling Read, in a loop, trying to finish the reading. ReadBuffer should raise an exception only when Read returns zero (before we can gather all the Count bytes).
And what with non-blocking pipes pipes? Wait for a *some* period until you get all data? It is up to the programmer to do this INHO. Also, if you would enforce this behaviour on all kinds of streams, you might (`will`, actually) get unexpected performance drops...
> For example: on Linux, TFileStream.Read calls fpRead which is a system call, and it definitely can return less than requested amount of bytes, and it doesn't mean that stream ended. (See e.g. Libc docs: http://www.gnu.org/software/libc/manual/html_mono/libc.html#I_002fO-Primitives : "If read returns at least one character, there is no way you can tell whether end-of-file was reached. But if you did reach the end, the next read will return zero. ") So if you use TFileStream with ReadBuffer, your code is working purely by accident right now...
But if you work with a blocking fd (which, for example, a TFileStream uses IIRC) you will always get your data. If there is more data to be read(), but it would take time, it simply takes time. The only case where zero is returned, is IIRC (like you quoted) when the end of the `fd` (e.g. pipe, socket, file) is reached on *blocking filedescriptors*.
Note that the above is a rather sumarized explanation, but it should make the point.
FYI: I've never had the problem of a `partial read` (e.g. SomeStream.Read(50) returning 36 or something) on linux, osx and windows; so perhaps you have exposed some bug in an obscure TStream descendant?
More information about the fpc-pascal