Re: How to override basic_streambuf::seekoff?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Krzysztof Żelechowski wrote:

"Tom Widmer [VC++ MVP]" wrote:

Krzysztof Żelechowski wrote:
To refresh your memory, here is my original post of May 26:

I am trying to implement the method pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode) in my buffer. I have two important questions:

What should the seekoff method return when it moves both pointers at once?
If should fail for basic_ios::cur, otherwise return the new position.

What should the seekoff method do when it fails? Is it required to leave the buffer intact, or is it undefined behaviour?
It shouldn't be undefined behaviour. Your code should attempt to leave the streambuf in a consistent state. If the error is unrecoverable, throw an exception (which will cause the owning stream to set badbit) - in this case, you should make sure that at least the destructor will work and deallocate resources correctly. If it is recoverable, return -1 and leave things in a state where the other member functions can be called (e.g. the stream position can be queried to see where it was left).


The failure required by the standard in this case is not a failure of the buffer, it is a failure of the interface that is unable to return the return value using the channel provided. In any case it is not a hard failure and the standard does not say that such a call causes undefined behaviour — it only specifies the return value in such a case. If I understand your position correctly, it is conformant to advance both pointers by the argument value and return -1, isn't it?

Yes - streambuf doesn't place any constraints on the behaviour of seekoff and seekpos for its derived classes (indeed, many streambufs I've seen don't override them at all, so they just return -1), so you can do pretty much what you like. OTOH, I wouldn't really advocate writing a streambuf that works that way. It isn't too important a case anyway, since std::basic_iostream has separate functions for in and out seeking.

I cannot reply in the ordinary way because this topic is not current any more. The problem is Mrs Langner's book does not address buffer consistency at all; the exact quote is "you are basically free to implement whatever behaviour seems reasonable". It does not address the question what behaviour is reasonable in the situation where the the buffer is asked to seek both pointers from the current position and the current positions of both pointers are accidentally equal.
I think in that case it is reasonable to do nothing other than return -1 - making a special case for that is probably not a good idea, and the user can work around the problem by seeking the two positions with separate calls.

BTW the book says that the behaviour of the implementation should be documented. It is not the case with MSDN: you cannot tell whether the stream buffer state is allowed to change after an unsuccessful seekoff.
The filebuf::seekoff documentation is not very clear in MSDN - it just says it fails, and not what state it leaves the filebuf in. But of course, the state is likely to change, if for example the buffer flush succeeds but the seek fails. You can do better of course...

I have not tested a filebuf because it can obviously have side effects, including launching a charged intercontinental missile.

That's not very probable, unless you happen to be writing a charged intercontinental missile launch program.

I have tested a
stringbuf and it is left intact, although it is not documented.

The standard specifies stringbuf quite well - I don't see any latitude for it to do anything but the obvious. Do you have a copy of the standard? (it was only $18 last time I checked)

This has put
me into much confusion and hence my question about what the best practice should be and why.

I suppose, where you have independent in and out positions, do what stringbuf does, as far as is possible. I would throw an exception in the cases when you can't.

Tom
.



Relevant Pages

  • Re: How to override basic_streambuf::seekoff?
    ... If the error is unrecoverable, throw an exception (which will cause the owning stream to set badbit) - in this case, you should make sure that at least the destructor will work and deallocate resources correctly. ... The problem is Mrs Langner's book does not address buffer consistency at all; the exact quote is "you are basically free to implement whatever behaviour seems reasonable". ... It does not address the question what behaviour is reasonable in the situation where the the buffer is asked to seek both pointers from the current position and the current positions of both pointers are accidentally equal. ... description of seekoff is equally vague there since Mr Josuttis is also one of the authors of Mrs Langner's book. ...
    (microsoft.public.vc.stl)
  • Re: How to override basic_streambuf::seekoff?
    ... What should the seekoff method return when it moves both pointers at once? ... It shouldn't be undefined behaviour. ... buffer, it is a failure of the interface that is unable to return the return ... says it fails, and not what state it leaves the filebuf in. ...
    (microsoft.public.vc.stl)
  • Re: I/O buffering
    ... StreamReader also buffers data? ... so they buffer as well. ... Neither StreamReader nor StreamWriter inherit from FileStream. ... What StreamReader and StreamWriter _do_ use is any Stream instance. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Assembly conversion to Pocket Pc format
    ... But in my case it is throwing exception before executing that statement what ... That is before reading buffer size it is throwing ... Stream respStream = resp.GetResponseStream; ... upload and download files in compact framework. ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: scanf() quesion?
    ... characters are intended to ... When a stream is fully buffered, ... when a buffer is filled. ... If standard output refers to an interactive device, ...
    (comp.lang.c)