【问题标题】:How to implement custom std::streambuf's seekoff()?如何实现自定义 std::streambuf 的 seekoff()?
【发布时间】:2016-05-06 02:34:24
【问题描述】:

我有以下基于例如的实现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...
  }
};

我想通过以下方式在我的方法中使用它:

  char buffer[] = { 0x01, 0x0a };
  membuf sbuf(buffer, buffer + sizeof(buffer));
  std::istream in(&sbuf);

然后调用例如tellg() on in 并得到正确的结果。

到目前为止,它几乎是完美的——它不会在流的末尾停止。

我应该如何升级它以使其正常工作?

我的主要动机是模仿 std::ifstream 的行为,但在测试中将二进制 char[] 输入它们(而不是依赖二进制文件)。

【问题讨论】:

  • “它不会停止”是什么意思?
  • @SergeyA 在我的客户端代码的某个地方我调用in.tellg() 并检查它是否小于我想要的“目标”位置。这失败并在循环中读取了一个比我想要的多一个元素。
  • 目前还不清楚你所说的“失败”是什么意思。 Tellg 预计会告诉你缓冲区的当前位置,不多也不少。如果你设法超出了缓冲区限制,tellg 会告诉你。
  • @SergeyA 我想我明白了。我在评论部分添加了return gptr() - eback();,现在它可以工作了:)

标签: c++ istream seek streambuf


【解决方案1】:

接受的答案不适用于搜索方向设置为std::ios_base::begstd::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();
}

【讨论】:

    【解决方案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();
      }
    

    【讨论】:

    • 致 -1 的人:有什么评论为什么?
    • 如果off 将get 指针推到缓冲区的开头或结尾之外怎么办?如果有人试图寻找开始或结束呢?
    猜你喜欢
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多