I want to have a simple way to replace a istream or ostream in order to do on-line filtering of the content (for instance: add 1 to each character when reading, remove 1 when writing). It has to support operations like unget and putback
I think the easiest way might be to overload streambuf
I thought this would be something very easy, but it seems most of the code I'm doing results in error when code tries to do a unget
Could someone show me how to subclass a streambuf to do online filtering (char by char) which I can then put in a istream or ostrea?
Here is some code I'm using
Code:
class FilteringBuf : public std::streambuf
{
char readBuf_; // current char
std::streambuf* pExternBuf_; // source buffer
int_type underflow()
{
if (gptr() == &readBuf_)
return traits_type::to_int_type(readBuf_);
int_type nextChar = pExternBuf_->sbumpc();
if (nextChar == traits_type::eof())
return traits_type::eof();
readBuf_ = traits_type::to_char_type(nextChar);
// replace character
readBuf_ += 1;
setg(&readBuf_, &readBuf_, &readBuf_ + 1);
return traits_type::to_int_type(readBuf_);
}
int_type overflow(int_type ch) {
// replace character
ch = ch - 1;
return pExternBuf_->sputc(ch);
}
int sync() {
return pExternBuf_->pubsync();
}
public:
FilteringBuf(std::streambuf* pExternBuf)
: pExternBuf_(pExternBuf)
{
reset();
}
~FilteringBuf() {
sync();
}
void reset() {
setg(0, 0, 0);
setp(0, 0);
}
};