custom streambuf - not working with >> but works with << and .get()
Hello,
my custom streambuf works fine with output via <<
and with input via .get()
but fails to input via >> or getline... any idea why?
--------------------
A custom stream buffer (for encryption, currently it is doing "nothing")
it almost works, it supports << any_stringable_object
it supports input via .get()
but other inputs - using >> char_variable and getline etc.
fail (program hangs / wait)
Why?
operator>> or getline uses more from underlying streabuf, then .getc()
needs?
PROBLEM is at end of code.
--------------------
#include <streambuf>
#include <istream>
#include <algorithm>
#include <iostream>
#include <fstream>
namespace nUpt {
using namespace std;
// http://www.cplusplus.com/ref/iostream/streambuf/sgetc.html
typedef int uint_type ; // TODO
class decrypting_streambuf : public std::streambuf {
typedef std::streambuf::int_type int_type;
int_type m_key; // this filter (decryption) specyfic
pos_type m_pos; // this filter (decryption) specyfic
std::streambuf *m_sbuf; // underlying streambuf (only-pointed, not owned
but this)
public:
decrypting_streambuf(std::streambuf *buf, uint_type header_key)
: m_key(header_key),
m_sbuf(buf),
m_pos(0)
//m_pos( m_sbuf->pubseekoff(0,std::ios::cur) )
{
cerr<<" "<<__LINE__<<" CTOR! "<<endl;
m_sbuf->pubseekpos( 0 ); // ???
}
// std::streambuf *rdbuf() { return m_sbuf; }
private:
inline char_type decode(char_type c, pos_type const &pos) {
return c;// ^ (pos^m_key);
}
char_type encode(char_type c, pos_type const pos) {
return c;// ^ (pos^m_key);
}
protected:
virtual int_type underflow() { // XXX underfload: READ
cout<<':';
int_type fromUnder = m_sbuf->sbumpc(); // read from underlying buf
if (fromUnder = traits_type::eof()) return fromUnder; // EOF
int_type coded = traits_type::to_int_type(
decode(traits_type::to_char_type( fromUnder ), m_pos)
);
m_pos+=1;
return coded;
}
virtual int_type uflow() { // XXX underflow: READ
cout<<'>';
int_type fromUnder = m_sbuf->sbumpc(); // read from underlying buf
if (fromUnder == traits_type::eof()) return fromUnder; // EOF
int_type coded = traits_type::to_int_type(
decode(traits_type::to_char_type( fromUnder ), m_pos)
);
m_pos+=1;
return coded;
}
virtual int_type overflow(int_type c = traits_type::eof()) { // XXX
WRITE
cout<<'<';
if ( c == traits_type::eof() ) return c; // EOF
c = m_sbuf->sputc(
encode(traits_type::to_char_type(c), m_pos )
);
m_pos+=1;
return c;
}
};
} // NAMESPACE nUpt
void Test() {
using namespace std;
cout << "\nWRITTING...: " << endl;
{
ofstream plik("test.txt");
nUpt::decrypting_streambuf buf( plik.rdbuf() , 1234 ); // underlying
ostream out( &buf );
out << "abc";
if (1) {
out << "def" << ' ' << 2*64*2 << "\n" ;
out << "Hello" << endl;
out << "World!" << endl;
out << "123" << flush << 456;
}
plik.close();
}
cout << "\nFILE: " << endl;
{
ifstream plik("test.txt");
while (!!plik) {
string s;
getline(plik,s);
cout<<s<<endl;
}
}
cout << "\nDECODE: " << endl;
{
ifstream plik("test.txt"); // underlying device
nUpt::decrypting_streambuf buf( plik.rdbuf() , 1234 ); // underlying
buffer/filter
istream in( &buf ); // the stream
int i=30;
while (1) {
cout<<"*";
// HERE ***********************************
if (!(i--)) break;
char c = in.get(); // THIS WORKS OK
// char c; cin>>c; // THIS FAILS!
cout<<c;
}
}
}
int main() { Test(); return 0; }
==================================================
Output (working)
WRITTING...:
31 CTOR!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
FILE:
abcdef 256
Hello
World!
123456
DECODE:
31 CTOR!
*>a*>b*>c*>d*>e*>f*> *>2*>5*>6*>
*>H*>e*>l*>l*>o*>
*>W*>o*>r*>l*>d*>!*>
*>1*>2*>3*>4*>5*>6*
==================================================
Do not work - using operator>> at end of code above
WRITTING...:
31 CTOR!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
FILE:
abcdef 256
Hello
World!
123456
DECODE:
31 CTOR!
*
and program "hangs" waits here.
--
RafaV Maj