|
Boost : |
From: Jonathan Turkanis (technews_at_[hidden])
Date: 2005-02-28 19:31:09
Brian Braatz wrote:
>
> I have this sinking feeling this is like when I am standing in front
> of
> the fridge and say "Honey, WHERE IS THE MILK?"
:-)
>> I'm not familiar with the function OutputDebugString,
<snip>
> OutputDebugString() is a win32 function, basically when you build
<snip>
> (I point this out because it is semi-important to note that the
> process OutputDebugString has to go through is SLOW. I.e. just for
> reference, you would NOT want to call OutputDebugString() for each char)
Devices are buffered by default, so unless you specify a buffer of size 0 is
should be called only when you have written a big chunk of text or when you
flush the stream.
> The problem with above, IF I UNDERSTAND iostreams properly, is that I
> just want a filter on the debug_out_sink because it needs the \r\n.
> Everything else needs a \n.
Only data that flows through the newline filter will be affected, so if you put
the newline filter after the tee everything should work in your case.
> Do I need to weave in the filter on the debug_out_sink class? (either
> by "has a" or "is a")?
>
> What I am after is the "user" of debug_out_sink can just "push" it in
> without having to know about \r\n vs \n weirdness.
More generally, if you want the line-ending conversions built in to
debug_out_sink, you could use the class template compose:
struct debug_out_sink_impl { /* as before */ };
debug_out_sink : compose<newline_filter, debug_out_sink_impl > {
// writes to a debug_out_sink_impl , filteed by a newline_filter
};
The only problem is I haven't written compose yet! The reason is that I can't
figure out what the constructor arguments should be, since arguments for both
components may need to be specified.
The only way to merge the line-conversion with the debug_out_sink using existing
library components (rather than by hand) is to use the detail class chain, like
so:
#include <boost/iostreams/detail/chain.hpp>
#include <boost/iostreams/filter/newline_filter.hpp>
struct debug_out_sink_impl : boost::iostreams::sink
{
void write(const char* s, std::streamsize n)
{
std::string str(s, n);
OutputDebugStringA(str.c_str());
}
};
struct debug_out_sink
: boost::iostreams::detail::chain<boost::iostreams::output>
{
debug_out_sink ()
{
using namespace boost::iostreams;
push(newline_filter(newline::windows));
push(debug_out_sink_impl());
}
};
I've included a test program at the end, which executes correctly on my machine.
The class chain is a detail because I was not sure it would be useful to library
users, and by documenting it I would increase the apparent size of the library.
If there is no other good way to solve this sort of problem, I'll make chain
public.
Jonathan
------------------
#include <windows.h>
#include <fstream>
#include <iostream>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/detail/chain.hpp>
#include <boost/iostreams/filter/newline_filter.hpp>
#include <boost/iostreams/filtering_stream.hpp>
struct debug_out_sink_impl : boost::iostreams::sink
{
void write(const char* s, std::streamsize n)
{
std::string str(s, n);
OutputDebugStringA(str.c_str());
}
};
struct debug_out_sink
: boost::iostreams::detail::chain<boost::iostreams::output>
{
debug_out_sink ()
{
using namespace boost::iostreams;
push(newline_filter(newline::windows));
push(debug_out_sink_impl());
}
};
struct tee : boost::iostreams::multichar_output_filter {
tee(std::ostream& dest) : dest(dest) { }
template<typename Sink>
void write(Sink& snk, const char* s, std::streamsize n)
{
// Write to the downstream Sink
boost::iostreams::write(snk, s, n);
// Write to the stored ostream:
dest.write(s, n);
}
std::ostream& dest;
};
int main()
{
using namespace std;
using namespace boost::iostreams;
filtering_ostream out;
std::ofstream log("C:/log.txt");
debug_out_sink dbosink;
out.push(tee(log));
out.push(tee(std::cout));
out.push(dbosink);
out << "LINE ONE" << endl
<< "Next line" << endl
<< "third line" << endl;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk