Hi,

sorry for the late answer. I wanted to write something about redirection, but 
wanted to test it first.

There is a class cxxtools::Tee in cxxtools, which is derived from 
std::ostream, which does exactly, what you are trying to do with your macros. 
And with the std::ios::rdbuf-method, you may redirect output to a 
std::ostream. So an elegant way to duplicate the output produced from a 
component is like this:

<%pre>
#include <cxxtools/tee.h>
</%pre>
<%cpp>
cxxtools::Tee tee(reply.out());
reply.out().rdbuf(tee.rdbuf());
</%cpp>
Hi
% tee.flush();


Here a instance of cxxtools::Tee is put on the stack. Cxxtools::Tee fetches 
the underlying streambuf from reply.out() and duplicates output to std::cout. 
You may also use "cxxtools::Tee tee(reply.out(), myofstream)" to duplicate 
into a file.

I don't exactly know, where the output is buffered (cxxtools::Tee has no 
buffer), but it is. Therefore the flush is needed at the end.

The problem what remains is, that the tee-object and its underlying streambuf 
is destroyed before reply.out(), which leads to a crash, when the above 
construct is used as a subcomponent. This can be avoided elegantly, if you 
use a Tee-derived class, which does some cleanup. A more robust version is 
here:

<%pre>
#include <cxxtools/tee.h>

class TempTee : public cxxtools::Tee
{
    std::ostream& s;
    std::streambuf* b;
  public:
    explicit TempTee(std::ostream& s_)
      : s(s_),
        b(s.rdbuf())
      {
        assign(s, std::cout);
        s.rdbuf(rdbuf());
      }

    ~TempTee()
      { flush(); s.rdbuf(b); }
};

</%pre>
<%cpp>
TempTee tee(reply.out());
</%cpp>
Hi


The streambuffer of reply.out() is restored in the desctructor. And now we 
have also a place for our flush(). The class really belongs to a header, but 
for brevity it is put inline here (and also to show you, that it is 
possible ;-) ).

Another debugging tip, I have is to use the logging facility. I use it very 
much. Not also in tntnet, but almost in all my applications. Each component 
has a logging category "component.yourcomponentname", so you may log to the 
same target as tntnet with cxxtools-logging-macros like this:

<%cpp>
log_info("Hi there");
int n = 5;
log_debug("the value of n is " << n);
</%cpp>

The above logs something like:
2008-04-30 20:17:14.09181 [10382.1082132800] INFO component.tee - Hi there

If put into a component tee.ecpp. To see the debug-message, you have to put a 
line "logger.component.tee=DEBUG" (or "logger.component.tee=D") into your 
tntnet.properties. Log messages, which are not enabled, are very cheap. It is 
guaranteed, that the variable n in the above example is not formatted, if 
debug is not enabled.

You may also redirect the messages to a file including automatic file rotate 
or via udp to another host, which is useful e.g. in embedded environments, 
where you don't have a console or a large enough file system.

Tommi

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Tntnet-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tntnet-general

Reply via email to