I'm trying to find a method to get the number of characters read or written to a stream that is reliable even if there is an error and the read/write ends short.
I was doing something like this:
return stream.rdbuf()->sputn(buffer, buffer_size);
but if the streambuf implementation of overflow
is permitted to throw excpections this won't work. Is it? I've not been able to find it documented anywhere.
basic_streambuf::overflow
is allowed to throw an exception upon failure as documented in 27.6.3.4.5/6, and sadly there's no way to ensure compile-time that the function won't ever throw an exception.
Seems like you are running out of luck and the only way to be 100% sure that overflow
won't throw an exception is to write your own streambuf
that just doesn't do that upon failure.
[27.6.3.4.5/2-3] int_type overflow(int_type = c = traits::eof ())
...
[27.6.3.4.5/5]
Requires: Every overriding definition of this virtual function shall obey the following constraints:
1) The effect of consuming a character on the associated output
sequence is specified309
2) Let r be the number of characters in the pending sequence not
consumed. If r is non-zero then pbase() and pptr() shall be set so
that: pptr() - pbase()
== r and the r characters starting at pbase() are the associated output stream. In case r is zero (all characters of the pending
sequence have been consumed) then either pbase() is set to NULL, or
pbase() and pptr() are both set to the same NULL non-value.
3) The function may fail if either appending some character to the
associated output stream fails or if it is unable to establish pbase()
and pptr() according to the above rules.
[27.6.3.4.5/6]
Returns: traits::eof ()
or throws an exception if the function fails