Как реализовать пользовательский stoff::streambuf's seekoff()?

У меня есть следующая реализация, основанная, например, на этом вопросе и ответе

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[] вводится в них в тестах (вместо того, чтобы полагаться на двоичные файлы).

2 ответа

Решение

Кажется, мне не хватало возврата с текущей позиции. Итак, окончательная реализация 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();
}
Другие вопросы по тегам