Itβs not very clear what you are doing, although it sounds rudely correct. To be sure: all of your ostream
handy constructors for creating and installing your streambuf
, a destructor and, possibly, an rdbuf
to implementation to process buffers of the correct type. Suppose this is true: the definition of xsputn
in your streambuf
is purely an optimization. The key function that you must define is overflow
. The simplest overflow
implementation simply takes one character and outputs it to the receiver. Everything except this is optimization: you can, for example, configure the buffer with setp
; if you do this, then overflow
will only be called when the buffer is full or flash. In this case you will have to (use pbase
and pptr
to get the addresses). (The base class streambuf
initializes pointers to create a buffer of length 0, so there will be overflow
for each character.) Other functions that you might want to override in (very) specific cases:
imbue
: If you need a locale for some reason. (Remember that the current character encoding is part of the locale.)
setbuf
: For client code to specify a buffer. (IMHO, this is usually not worth the trouble, but you may have special requirements.)
seekoff
: Search support. I have never used this in any of my streambuf
s, so I cannot give any information other than what you can read in the standard.
sync
: called on a flash, should output any characters to the buffer to the shell. If you never call setp
(so there is no buffer), you are always in sync, and this may be non-op. overflow
or uflow
can call this, or both can call some separate function. (The only difference between sync
and uflow
is that uflow
is only called if there is a buffer, and it will never be called if the buffer is empty. sync
will be called if the client code flushes the stream.)
When writing my own threads, if performance does not dictate otherwise, I will keep it simple and only override overflow
. If performance specifies a buffer, I usually put the code in the dump buffer in a separate write(address, length)
function and implement overflow
and sync
along the lines from:
int MyStreambuf::overflow( int ch ) { if ( pbase() == NULL ) { // save one char for next overflow: setp( buffer, buffer + bufferSize - 1 ); if ( ch != EOF ) { ch = sputc( ch ); } else { ch = 0; } } else { char* end = pptr(); if ( ch != EOF ) { *end ++ = ch; } if ( write( pbase(), end - pbase() ) == failed ) { ch = EOF; } else if ( ch == EOF ) { ch = 0; } setp( buffer, buffer + bufferSize - 1 ); } return ch; } int sync() { return (pptr() == pbase() || write( pbase(), pptr() - pbase() ) != failed) ? 0 : -1; }
As a rule, I will not worry about xsputn
, but if your client code prints a lot of long lines, this can be useful. Something like this should do the trick:
streamsize xsputn(char const* p, streamsize n) { streamsize results = 0; if ( pptr() == pbase() || write( pbase(), pptr() - pbase() ) != failed ) { if ( write(p, n) != failed ) { results = n; } } setp( buffer, buffer + bufferSize - 1 ); return results; }