Boost logo

Boost :

Subject: [boost] [iostream] Device::read return inconsistency
From: Richard Smith (richard_at_[hidden])
Date: 2009-05-08 08:43:26


The example in the documentation for the Source concept in
Boost.Iostreams says:

     std::streamsize read(char* s, std::streamsize n)
     {
         // Read up to n characters from the input
         // sequence into the buffer s, returning
         // the number of characters read, or -1
         // to indicate end-of-sequence.
     }

(The same text appears in 'valid expressions / semantics'
table, which is probably more definitive.)

What does a return of less than n actually mean?

Nowhere on the documentation pages for the Source concept or
the read function template does it say what a return value
in the range [0,n) means. And from the comment in the
example, it would appear that read is permitted to return
less than n if the some smaller number of characters are
currently available /without/ implying that a subsequent
call will hit eof.

This seems to be confirmed by the use of
non_blocking_adapter in places in the library where you want
code to block until the n bytes are available, and to
guarantee eof (or, I guess, an error) for a subsequent call.

However, the comment in the BidirectionalDevice seems to
disagree:

     std::streamsize read(char* s, std::streamsize n)
         {
             // Reads up to n characters from the input
             // sequence into the buffer s, returning the number
             // of characters read. Returning a value less than n
             // indicates end-of-sequence.
         }

(Again, the same text appears in the 'valid expressions /
semantics' table.)

So which is it? I don't believe it is the library's
intention for a [0,n) return to have different meanings in
BidirectionalDevice and Source.

I haven't located any code in the library itself that
assumes a non-zero return of less than n signifies eof
(though I haven't searched all that hard), but third-party
code and/or any other boost libraries that use
Boost.Iostreams may well do.

However there do seem to be places where a return of zero is
taken to mean eof. For example,
indirect_streambuf::underflow seems to treat zero as eof.

At the very least the documentation needs fixing to be
consistent. And ideally it needs to document what a return
of 0 means (presumably undefined behaviour unless n == 0)
and whether a return in the range (0,n) implies that the
next call to read will return eof (probably not).

(Also, a minor typo: in the example on the Sink concept
documentation, write should return std::streamsize, not
void.)

Richard Smith


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk