将数据序列化到 std::streambuf

发布于 2024-11-26 14:39:47 字数 1928 浏览 0 评论 0原文

我有一个 Visual Studio 2008 C++ 项目,我试图将多个类中的数据序列化为自定义 std::streambuf 实现。

数据类及其序列化:

struct Header { /*...*/ };

inline std::ostream& operator<<( std::ostream& os, const Header& h ) 
{ 
    /* serialize the members of Header here */
    os.write( h.some_member, sizeof( h.some_member ) );
    return os;
}

struct Info { /*...*/ };

inline std::ostream& operator<<( std::ostream& os, const Info& i ) 
{ 
    /* serialize the members of Info here */
    return os;
}

streambuffer 实现提供缓冲 I/O 并覆盖下溢上溢

class MyStreamBuf : public std::streambuf
{
public:
    MyStreamBuf() { InitBuffers(); };

private:

    void InitBuffers()
    {
        recv_buffer_.resize( buff_size );
        send_buffer_.resize( buff_size );
        setg( &recv_buffer_[ 0 ], &recv_buffer_[ 0 ], &recv_buffer_[ 0 ] );
        setp( &send_buffer_[ 0 ], &send_buffer_[ 0 ] );
    };

    enum { buff_size = 512 };

    std::vector< char_type > recv_buffer_;
    std::vector< char_type > send_buffer_;

    int_type underflow() { /* ... */ };

    int_type overflow( char_type c )
    {
        *pptr() = c;
        pbump( 1 );
        // if the buffer is full, flush the data
        if( pptr() == epptr() )
            flush();
        return c;
    };

    void flush()
    {
        std::ptrdiff_t n = pptr() - pbase();
        int written = /* send n bytes to the data destination */
        pbump( -written );
    };
}; // class MyStreamBuf

我的预期用法是这样的:

Header h( /* some useful info */ );
Info i( /* some useful info */ );

MyStreamBuf dest;
std::iostream my_stream( &dest );
dest << h << i; // MyStreambuf::overflow() is never called!

但是,MyStreambuf::overflow 永远不会被调用。我需要做什么才能将数据获取到缓冲区?

谢谢, 保罗·H

I have a Visual Studio 2008 C++ project where I'm trying to serialize data from several classes to a custom std::streambuf implementation.

The data classes with their serialization:

struct Header { /*...*/ };

inline std::ostream& operator<<( std::ostream& os, const Header& h ) 
{ 
    /* serialize the members of Header here */
    os.write( h.some_member, sizeof( h.some_member ) );
    return os;
}

struct Info { /*...*/ };

inline std::ostream& operator<<( std::ostream& os, const Info& i ) 
{ 
    /* serialize the members of Info here */
    return os;
}

The streambuffer implementation provides buffered i/o and overrides underflow and overflow.

class MyStreamBuf : public std::streambuf
{
public:
    MyStreamBuf() { InitBuffers(); };

private:

    void InitBuffers()
    {
        recv_buffer_.resize( buff_size );
        send_buffer_.resize( buff_size );
        setg( &recv_buffer_[ 0 ], &recv_buffer_[ 0 ], &recv_buffer_[ 0 ] );
        setp( &send_buffer_[ 0 ], &send_buffer_[ 0 ] );
    };

    enum { buff_size = 512 };

    std::vector< char_type > recv_buffer_;
    std::vector< char_type > send_buffer_;

    int_type underflow() { /* ... */ };

    int_type overflow( char_type c )
    {
        *pptr() = c;
        pbump( 1 );
        // if the buffer is full, flush the data
        if( pptr() == epptr() )
            flush();
        return c;
    };

    void flush()
    {
        std::ptrdiff_t n = pptr() - pbase();
        int written = /* send n bytes to the data destination */
        pbump( -written );
    };
}; // class MyStreamBuf

My intended usage is something like this:

Header h( /* some useful info */ );
Info i( /* some useful info */ );

MyStreamBuf dest;
std::iostream my_stream( &dest );
dest << h << i; // MyStreambuf::overflow() is never called!

But, MyStreambuf::overflow is never called. What do I need to do to get the data to my buffer?

Thanks,
PaulH

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北方的韩爷 2024-12-03 14:39:47

您需要在 iostream 上调用 flush() (或在您的 Streambuf 上调用 pubsync())。

传统上,您可以在 Streambuf 的析构函数中执行此操作(与 filebuf 的析构函数调用 close() 的方式相同),在这种情况下,您只需销毁它即可。

此外,通常提供一个继承自 iostream 的类,该类拥有 Streambuf 的实例,并确保在适当的时候刷新/销毁它。

You need to call flush() on the iostream (or call pubsync() on your streambuf).

Traditionally you'd do this in the destructor of your streambuf (in the same way that filebuf's destructor calls close()), in which case you just need to destroy it.

Also it's conventional to provide a class inheriting from iostream that owns an instance of your streambuf and ensures it is flushed/destroyed when appropriate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文