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