将数据序列化到 std::streambuf
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要在 iostream 上调用
flush()
(或在您的 Streambuf 上调用pubsync()
)。传统上,您可以在 Streambuf 的析构函数中执行此操作(与 filebuf 的析构函数调用
close()
的方式相同),在这种情况下,您只需销毁它即可。此外,通常提供一个继承自 iostream 的类,该类拥有 Streambuf 的实例,并确保在适当的时候刷新/销毁它。
You need to call
flush()
on the iostream (or callpubsync()
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.