I don't know if this is correct solution, but I inherited it this way. It uses buffer and gets 64 bytes (or less if flushed) and sends them to generic putChars() method where the actual handling of data is done. It also demonstrates how to give user data.
I haven't checked if this compiles or not, but I think you get the point.
class MyBuffer : public std::basic_streambuf< char, std::char_traits< char > >
{
public:
inline MyBuffer(MyData data) :
data(data)
{
setp(buf, buf + BUF_SIZE);
}
protected:
// This is called when buffer becomes full. If
// buffer is not used, then this is called every
// time when characters are put to stream.
inline virtual int overflow(int c = Traits::eof())
{
// Handle output
putChars(pbase(), pptr());
if (c != Traits::eof()) {
char c2 = c;
// Handle the one character that didn't fit to buffer
putChars(&c2, &c2 + 1);
}
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE);
// I'm not sure about this return value!
return 0;
}
// This function is called when stream is flushed,
// for example when std::endl is put to stream.
inline virtual int sync(void)
{
// Handle output
putChars(pbase(), pptr());
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE);
return 0;
}
private:
// For EOF detection
typedef std::char_traits< char > Traits;
// Work in buffer mode. It is also possible to work without buffer.
static size_t const BUF_SIZE = 64;
char buf[BUF_SIZE];
// This is example about userdata
MyData data;
// In this function, the characters are parsed.
void putChars(char const* begin, char const* end);
};
class MyOStream : public std::basic_ostream< char, std::char_traits< char > >
{
public:
inline MyOStream(MyData data) :
std::basic_ostream< char, std::char_traits< char > >(&buf),
buf(data)
{
}
private:
MyBuffer buf;
};