custom streambuf - not working with >> but works with << and .get()

R

Raf256

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.
 
J

Jim Langston

Raf256 said:
Hello,
my custom streambuf works fine with output via <<
and with input via .get()
but fails to input via >> or getline... any idea why?
// HERE ***********************************
if (!(i--)) break;
char c = in.get(); // THIS WORKS OK
// char c; cin>>c; // THIS FAILS!

Here you say it fails, but later you say it hangs/waits. Are you sure it's
just not waiting for intput? Like type in X and press enter, since you're
waiting for input from cin.
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.

Waiting for input maybe?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top