问题
I have the following implementation based on e.g. this question and answer
struct membuf : std::streambuf
{
membuf(char* begin, char* end)
{
this->setg(begin, begin, end);
}
protected:
virtual pos_type seekoff(off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which = std::ios_base::in)
{
std::istream::pos_type ret;
if(dir == std::ios_base::cur)
{
this->gbump(off);
}
// something is missing here...
}
};
I would like to use it in my methods in the following way:
char buffer[] = { 0x01, 0x0a };
membuf sbuf(buffer, buffer + sizeof(buffer));
std::istream in(&sbuf);
and then call e.g. tellg()
on in
and get the correct result.
So far it's almost perfect - it doesn't stop at the end of the stream.
How should I upgrade this so that it works correctly?
My main motivation is to mimic std::ifstream
behavior but with binary char[]
fed into them in tests (instead of relying on binary files).
回答1:
The accepted answer does not work for cases where the seek direction is set to either std::ios_base::beg
or std::ios_base::end
. To support these cases, extend the implementation by:
pos_type seekoff(off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which = std::ios_base::in) {
if (dir == std::ios_base::cur)
gbump(off);
else if (dir == std::ios_base::end)
setg(eback(), egptr() + off, egptr());
else if (dir == std::ios_base::beg)
setg(eback(), eback() + off, egptr());
return gptr() - eback();
}
回答2:
It seems that I was missing the return with current position. So the final implementation of seekoff
looks like:
pos_type seekoff(off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which = std::ios_base::in)
{
if (dir == std::ios_base::cur) gbump(off);
return gptr() - eback();
}
来源:https://stackoverflow.com/questions/35066207/how-to-implement-custom-stdstreambufs-seekoff