非缓冲的 std streambuf 实现

6
为了快速测试一个序列化库,我想创建一个streambuf,它可以读取/写入socket。我不想在streambuf中使用缓冲区,而是让socket处理这个问题。我确信序列化库只会调用std::istream::read和std::ostream::write。快速查看Microsoft的basic_streambuf实现显示,这些调用实际上直接转发到xsputn和xsgetn。
问题是:我能否从streambuf派生并只实现xsputn和xsgetn,并确保使用我的实现的流将始终调用这些方法,而不是sync/overflow/underflow/pback/...?否则,我应该重写sync等以返回错误,还是标准保证默认实现很好?最好这在任何常见平台上都可以工作,并且我不能使用boost::iostreams。
实际上,我会使用类似以下的东西:
class socket_buf : public std::streambuf
{
public:
    //Socket is a class with std::stream-like read/write methods
  MyBuf( Socket& s ) : sock( s ) {}

protected:
  std::streamsize xsputn( const char* s, std::streamsize n )
  {
    return sock.write( s, n );
  }

  std::streamsize xsgetn( char* s, std::streamsize n )
  {
    return sock.read( s, n );
  }

private:
  Socket& sock;
};
1个回答

7
几乎不可能在没有缓冲区的情况下实现std::streambuf。你需要重载underflow和overflow函数,因为许多public接口到std::streambuf不会通过xsputn或xsgetn进行。例如,sputc、sbumpc等。甚至sputn也不能保证会导致调用xsputn,这取决于内部缓冲区的状态和特定的std::streambuf实现。

+1. sputn和xsputn通常是基于sputc实现的,除非它们可以更高效地实现。 - Pete
那么实现溢出、下溢、同步以及xsputn/xsgetn是否足够呢? - stijn
1
@stijn:是的,你不需要实现xsputnxsgetn。一旦你有了一个可用的overflow实现,你可能会发现使用自定义的xsputn并没有任何优势。你不需要重载uflow,因为默认实现已经使用underflow实现了。 - CB Bailey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接