1

By looking in the standard library documentation, it seems that for subclassing iostream, there are no other choice than implementing a streambuf class by overloading overflow and underflow.

In some cases, it is a good idea. But when you want to implement an iostream class for wrapping around an already buffered device (a compression library, a cryptographic library, etc...) it seems really not convenient, because:

  • If you set a zero-sized buffer, for instance with setp(nullptr, nullptr), overflow will be called once per byte, even if the iostream::write function is called with large buffers, this seems poor regarding performance
  • Implementing a fully functional buffer adds useless complexity if the underlying device is already buffered and accepts block writes, and if we just want to write a wrapper.

Did I miss something? Why isn't it possible to simply overload iostream write() and read()?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
galinette
  • 8,896
  • 2
  • 36
  • 87
  • Separating the buffers from the actions to perform on the content of those buffers is good design in principle. The iostreams library is far from perfect, but `read`and `write` are mostly just convenience methods for the underlying buffer, if all you need are those two I'd argue that you don't need the streams in the first place. – user657267 May 18 '16 at 07:43
  • What is the problem you're actually trying to solve? – uh oh somebody needs a pupper May 18 '16 at 07:45
  • You might want to look at [Boost.Iostreams](http://www.boost.org/doc/libs/release/libs/iostreams/doc/index.html), which already comes with various compression algorithms, and a framework for "filtering" streams that could probably be used for crypto purposes as well. Then there is [Crypto++](http://www.cryptopp.com/). Generally speaking, you don't want to inherit from `std::` classes. – DevSolar May 18 '16 at 07:47
  • 1
    @user657267 : just suppose I have a library which can output some data to a std::ostream*. I do not want to write the data to disk "as is" but I want to feed it to some encryption or compression system. There can be many reasons why I cannot/don't want to store the whole output to a memory buffer (such as std::stringstream) before further processing – galinette May 18 '16 at 08:05
  • @DevSolar : I know there are many better alternatives, such as boost, Qt... But some libraries which output data have no other interfaces than a file name or a std::ostream pointer, for instance. – galinette May 18 '16 at 08:10
  • I'm assuming the libraries you intend to wrap have a low level pointer interface to their underlying buffers, if so it should be possible to write a wrapper `basic_streambuf` that doesn't have a buffer itself. Note that your first point is wrong, the effect of calling `pubsetbuf(nullptr, 0)` on a streambuf is entirely up the underlying type, if you're writing it you can make it do anything you like including ignoring the call. As for `sgetn` and `sputn` there's actually no guarantee that `read` and `write` will call these (although I'm guessing nearly all implementations will). – user657267 May 18 '16 at 08:18

0 Answers0