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; }