streambuf not flushing, apparently

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

Yes, it's me again, with my dear, dear friends std::streambuf and
std::eek:stream... On the bright side, the code compiles. On the gloomy
side, I can't seem to get overflow() or xsputn() called...

class TWFileBuf : public std::streambuf
{
private:
bool Open( name ) {/* debug printf - does show up */}

protected:
TLSFile lsf;
virtual int_type overflow(int_type c)
{
// debug printf omitted - it does NOT show up
if( lsf.Write(c) ) {
return c;
}
return EOF;
}
virtual std::streamsize xsputn(const char *s, std::streamsize num)
{
// debug printf omitted - it does NOT show up
lsf.Write(s);
return(strlen(s));
}

public:
TWFileBuf( const char* name ) {Open(name);}
};

class
TLogBuf : public TWFileBuf
{
protected:
virtual std::streamsize xsputn(const char *s, std::streamsize num)
{ /* do complicated stuff - printf here doesn't show up */ }

public:
TLogBuf( name ) : TWFileBuf(name) {}
};

template <class buftype>
class TWFileStreamBase : public std::eek:stream
{
protected:
buftype buf;

public:
TWFileStreamBase( const char* name ) :
buf(name),std::eek:stream(&buf) {}
};

typedef TWFileStream<TLogBuf> TDebugLogFile;

Any ideas on what's still wrong with this code.................?
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
typedef TWFileStream<TLogBuf> TDebugLogFile;

I should add that I'm using a TDebugLogFile like so:

dbglog << "Hello, world!" << flush; // is flush what I want?
 
A

Alf P. Steinbach

* Christopher Benson-Manica said:
I should add that I'm using a TDebugLogFile like so:

dbglog << "Hello, world!" << flush; // is flush what I want?


I don't know, but I do know that the prudent thing to do if you find
yourself concerned with the innards of streams, is to _avoid_ streams.

Streams are extremely inefficient and ugly as hell (as evidenced by your
confusion over some detail or other) and not even as type safe as advertised.

Forget them.
 
C

Christopher Benson-Manica

Alf P. Steinbach said:
Streams are extremely inefficient and ugly as hell (as evidenced by your
confusion over some detail or other) and not even as type safe as advertised.

Uglier than the alternative, which is

TLSFile f;

f.Print( "The number of ways I like printf is %u", 0 );

? Or better yet, the other class I want to be like a stream...

Socket s;

s.Send( bprf("Wow, I hate this function in %d ways!",666) );

where bprf() is like printf() but gives you a temporary buffer that
times out after a finite amount of time. Trust me, streams are
looking like a nice alternative, if I can get them to work.
 
J

John Harrison

Christopher Benson-Manica said:
Yes, it's me again, with my dear, dear friends std::streambuf and
std::eek:stream... On the bright side, the code compiles. On the gloomy
side, I can't seem to get overflow() or xsputn() called...

class TWFileBuf : public std::streambuf
{
private:
bool Open( name ) {/* debug printf - does show up */}

protected:
TLSFile lsf;
virtual int_type overflow(int_type c)
{
// debug printf omitted - it does NOT show up
if( lsf.Write(c) ) {
return c;
}
return EOF;
}
virtual std::streamsize xsputn(const char *s, std::streamsize num)
{
// debug printf omitted - it does NOT show up
lsf.Write(s);
return(strlen(s));

This is wrong, you're assuming that s is a null terminated string, which
isn't necessarily the case.

Doesn;t explain why this function isn't called at all however.
}

public:
TWFileBuf( const char* name ) {Open(name);}
};

class
TLogBuf : public TWFileBuf
{
protected:
virtual std::streamsize xsputn(const char *s, std::streamsize num)
{ /* do complicated stuff - printf here doesn't show up */ }

public:
TLogBuf( name ) : TWFileBuf(name) {}
};

template <class buftype>
class TWFileStreamBase : public std::eek:stream
{
protected:
buftype buf;

public:
TWFileStreamBase( const char* name ) :
buf(name),std::eek:stream(&buf) {}
};

typedef TWFileStream<TLogBuf> TDebugLogFile;

Any ideas on what's still wrong with this code.................?

Can't see anything wrong with it.

I would use a debugger to step in the code when you do << to see what is
really happening. Because you are doing unbuffered I/O you shouldn't need to
use flush, output should happen immediately.

Not all compilers implement the standard library correctly, some things you
might check are.

That the stream error state isn't set, try calling clear() in the
TWFileStreamBase constructor.

You are using unbuffered output, try saying so explicitly by calling
buf.setp(0,0) in TWFileStreamBase constructor.

Try checking that your overirides really are overriding the streambuf
function, check the streambuf header file to see if the argument types for
overflow and xsputn match the ones you are using.

But I think a good debugger is your main tool.

Actually the code above cannot be the correct code, TWFileStream<TLogBuf>
does not have a default constructor. That makes me think that the problem is
that you've got the stream into an error state, when that happens no I/O
will occur until you call clear().

john
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top