调整C ++ std / boost iostreams以提供对内存块的循环写入

时间:2014-02-06 08:26:55

标签: c++ boost iostream

背景: 我正在尝试优化日志系统,以便它使用内存映射文件。我需要提供一个类似std :: ostream的接口,以便日志记录系统可以写入该内存。 我已经识别出std :: strstream(虽然不赞成使用),boost :: iostreams :: basic_array_sink可以满足我的需求。

现在我希望记录循环,这意味着当输出指针靠近内存块的末尾时,它应该再次从头开始。 我的问题是,为了实现这一特定行为,最佳起点是什么。

我对std :: iostreams类层次结构感到不知所措,并没有像现在这样掌握所有内部工作原理。 我不确定我是否应该/需要从ostream,streambuf或两者中获得? 这些是为了衍生出来的吗?

或者使用boost:iostreams,我是否需要编写自己的Sink?


编辑: 以下尝试编译并生成预期输出:

class rollingstreambuf : public std::basic_streambuf<TCHAR>
{
public:
    typedef std::basic_streambuf<TCHAR> Base;

    rollingstreambuf(Base::char_type* baseptr, size_t size)
    {
        setp(baseptr, baseptr + size);
    }

protected:
    virtual int_type overflow (int_type c)
    {
        // reset position to start of buffer
        setp(pbase(), epptr());
        return putchar(c);
    }

    virtual std::streamsize xsputn (const char* s, std::streamsize n)
    {
        if (n >= epptr() - pptr())
            // reset position to start of buffer
            setp(pbase(), epptr());
        return Base::xsputn(s, n);
    }
};

char buffer[100];
rollingstreambuf buf(buffer, sizeof(buffer));
std::basic_ostream<TCHAR> out(&buf);

for (int i=0; i<10; i++)
{
    out << "Mumblemumble " << i << '\n';
}
out << std::ends;  //write terminating NULL char

打印缓冲区给出:

Mumblemumble 6
Mumblemumble 7
Mumblemumble 8
Mumblemumble 9

(确认已发生翻车)

它的作用是使streambuf使用提供的缓冲区作为循环输出缓冲区(放置区域),而不会在输出序列(流)中推进缓冲区窗口。 (使用http://en.cppreference.com/w/cpp/io/basic_streambuf

中的术语

现在我对这种实现的稳健性和质量感到非常不确定。请查看并评论。

1 个答案:

答案 0 :(得分:2)

这是一种有效的方法。 overflow()应该返回:

  

traits :: eof()或在函数失败时抛出异常。否则,返回traits :: eof()以外的一些值来表示成功。

E.g:

virtual int_type overflow (int_type c)
{
    // reset position to start of buffer
    setp(pbase(), epptr());
    return traits::not_eof(c);
}

xsputn()应该将序列的开头写入缓冲区的末尾,然后将其余的序列倒回并写入缓冲区的前面。您可以使用xsputn()的默认实现来为每个字符调用sputc(c),然后在缓冲区已满时调用overflow()