【问题标题】:How to implement seekg/seekpos on an in-memory buffer?如何在内存缓冲区上实现 seekg/seekpos?
【发布时间】:2016-12-14 11:13:17
【问题描述】:

结合this answer on in-memory streamsthis answer on seekoff,我实现了一个内存缓冲区,如下所示:

struct membuf : std::streambuf {
    membuf(char const* base, size_t size) {
        char* p(const_cast<char*>(base));
        this->setg(p, p, p + size);
    }
};
struct imemstream : virtual membuf, std::istream {
    imemstream(char const* base, size_t size) :
        membuf(base, size),
        std::istream(static_cast<std::streambuf*>(this)) {
    }

    std::iostream::pos_type seekoff(std::iostream::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();
    }
};

但是,as explained in the comments of the first aswer,我们仍然需要让seekg/seekpos 正常工作。那么这里如何正确实现seekpos呢?

PS This question 方向相同,但给出了更具体的答案。

【问题讨论】:

  • 如果你的流缓冲区是一个简单的内存缓冲区,那么 seekpos 应该简单地设置当前的读取位置指针/索引。我看你没有这些。默认情况下 seekg 这是 basic_streambuf 中的 NOP,因为并非所有流缓冲区都支持搜索的想法(想象一下网络字节流)。所以你需要添加更多代码来维护你自己的“当前读取位置”并从 gptr() 等返回它
  • @RichardHodges 维护该位置似乎没有问题:seekoff 返回正确的结果。相反,我不知道如何设置该位置。所以我正在寻找的是在 C++ 代码中“简单地设置当前读取位置指针/索引”。
  • 我认为你必须在你的 streambuf 派生类中实现和维护这些位置
  • @RichardHodges 该职位肯定已经在gptr() 中保持。有用。它正确地递增和一切。因此,基类已经以某种方式对其进行了维护。我正在寻找正确更改 gptr 值的代码。

标签: c++ buffer iostream


【解决方案1】:

由于此问题尚未得到解答,我将发布建议的实现here

pos_type seekpos(pos_type sp, std::ios_base::openmode which) override {
  return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which);
}

此外,在其他方向的情况下,seekoff 的实现对我不起作用。考虑通过以下方式对其进行修改:

pos_type seekoff(off_type off,
                 std::ios_base::seekdir dir,
                 std::ios_base::openmode which = std::ios_base::in) override {
  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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 2021-12-27
    • 2018-06-25
    • 2012-11-17
    • 2010-10-24
    • 2020-11-22
    • 1970-01-01
    • 2013-03-12
    相关资源
    最近更新 更多