【发布时间】:2011-02-22 12:55:36
【问题描述】:
我有一个使用 IStreams 的 Visual Studio 2008 C++ 应用程序。我想在std::ostream 中使用IStream 连接。像这样的:
IStream* stream = /*create valid IStream instance...*/;
IStreamBuf< WIN32_FIND_DATA > sb( stream );
std::ostream os( &sb );
WIN32_FIND_DATA d = { 0 };
// send the structure along the IStream
os << d;
为此,我实现了以下代码:
template< class _CharT, class _Traits >
inline std::basic_ostream< _CharT, _Traits >&
operator<<( std::basic_ostream< _CharT, _Traits >& os, const WIN32_FIND_DATA& i )
{
const _CharT* c = reinterpret_cast< const _CharT* >( &i );
const _CharT* const end = c + sizeof( WIN32_FIND_DATA ) / sizeof( _CharT );
for( c; c < end; ++c ) os << *c;
return os;
}
template< typename T >
class IStreamBuf : public std::streambuf
{
public:
IStreamBuf( IStream* stream ) : stream_( stream )
{
setp( reinterpret_cast< char* >( &buffer_ ),
reinterpret_cast< char* >( &buffer_ ) + sizeof( buffer_ ) );
};
virtual ~IStreamBuf()
{
sync();
};
protected:
traits_type::int_type FlushBuffer()
{
int bytes = std::min< int >( pptr() - pbase(), sizeof( buffer_ ) );
DWORD written = 0;
HRESULT hr = stream_->Write( &buffer_, bytes, &written );
if( FAILED( hr ) )
{
return traits_type::eof();
}
pbump( -bytes );
return bytes;
};
virtual int sync()
{
if( FlushBuffer() == traits_type::eof() )
return -1;
return 0;
};
traits_type::int_type overflow( traits_type::int_type ch )
{
if( FlushBuffer() == traits_type::eof() )
return traits_type::eof();
if( ch != traits_type::eof() )
{
*pptr() = ch;
pbump( 1 );
}
return ch;
};
private:
/// data queued up to be sent
T buffer_;
/// output stream
IStream* stream_;
}; // class IStreamBuf
是的,代码可以编译并且似乎可以工作,但我以前没有实现过std::streambuf 的乐趣。所以,我只想知道它是否正确和完整。
谢谢, 保罗H
【问题讨论】:
-
除了你的观点,我知道,但我仍然必须把它从胸中拿出来:你
operator<<让我畏缩。<<不是用于二进制输出,而是用于文本输出。三年后,维护此代码的人写了std::cerr << "value of x: " << x '\n'进行调试,而共享他办公室的人变得暴躁,当事实证明x不是他想的那样,但是一些struct以二进制形式流式传输,@ 987654331@ 铃声,口哨和所有。 -
@sbi - 你有什么推荐的?我认为
std::streambuf类需要重载的operator<<才能工作。 -
我不确定。我只是对使用
operator<<流式传输二进制内容感到难过。也许现在风靡一时,我错过了炒作,但它曾经只用于文本输出。毕竟,这就是流实际做的事情:将二进制数据作为文本流式传输所需的格式。其余的(缓冲和实际设备 IO)留给流缓冲区。 -
@sbi - 因为这是二进制数据,如果我将它从
std::streambuf更改为std::basic_streambuf< byte >并将我的std::basic_ostream<>模板修复为std::basic_ostream<byte>。这意味着您不会意外std::cerr << "value of x: " << x '\n'。你怎么看?