Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unbuffered std streambuf implementation

for some quick testing of a serialization library I want to create a streambuf that can read/write to/from a socket. I do not want to use a buffer in the streambuf, but let the socket handle this. I am sure the serialization lib will only call std::istream::read and std::ostream::write. A quick look at Microsoft's basic_streambuf implementation shows that these calls are practically directly forwarded to xsputn and xsgetn.

The question is: can I derive from a streambuf and just implement xsputn and xsgetn, and be sure that the streams that use my implementation will always call these methods, and not sync/overflow/underflow/pback/... ? Or else should I override sync etc to return errors, or does the standard guarantee that the default implementations are fine? Preferrably this should work on any common platform, and I cannot use the boost::iostreams.

Practically I'd use something like this:

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;
};
like image 251
stijn Avatar asked Aug 18 '11 11:08

stijn


1 Answers

It's (almost?) impossible to implement a std::streambuf without a buffer. You will have to overload underflow and overflow as many of the public interfaces to std::streambuf won't go via xsputn or xsgetn. E.g. sputc, sbumpc, etc. Even sputn is not guaranteed to cause a call xsputn depending on the state of the internal buffer and the particular std::streambuf implementation.

like image 172
CB Bailey Avatar answered Sep 28 '22 15:09

CB Bailey