У меня есть следующая реализация, основанная, например, на этот вопрос и ответ
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...
}
};
Я хотел бы использовать его в моих методах следующим образом:
char buffer[] = { 0x01, 0x0a };
membuf sbuf(buffer, buffer + sizeof(buffer));
std::istream in(&sbuf);
а затем позвоните, например, tellg()
на in
и получите правильный результат.
Пока это почти идеально — это не останавливается в конце потока.
Как мне обновить это, чтобы оно работало правильно?
Моя главная мотивация — подражать std::ifstream
поведение, но с двоичным char[]
вводится в них в тестах (вместо того, чтобы полагаться на двоичные файлы).
Кажется, мне не хватало возврата с текущей позиции. Итак, окончательная реализация seekoff
похоже:
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();
}
Принятый ответ не работает для случаев, когда направление поиска установлено на std::ios_base::beg
или же std::ios_base::end
, Чтобы поддержать эти случаи, расширьте реализацию:
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();
}