I am trying to write a custom std::ostream
that invokes a function for every line written to it. That is, I would like the following code to work as documented in comments:
my_output_stream s([] (const std::string& line) {
WriteLineToSomeOutput(line);
});
s << "Hello world"; // do not invoke anything. The line has not ended yet!
s << ", from Alex" << std::endl; // here we invoke WriteLineToSomeOutput("hello world, from Alex")
s << "What's up"; // do not invoke anything. The line has not ended yet.
s << ", doc?!\nHow u doing?\n"; // Now we have two lines. We invoke WriteLineToSomeOutput("What's up, doc?!) and WriteLineToSomeOutput("How u doing?")
Note that the data is not written anywhere and not stored anywhere. The only thing that I need the stream to store is the current line that is being aggregated, until we encounter an end of line.
I did not find any easy way of doing so, even when using the boost.Iostreams library. Can I avoid writing my own line tokenizer here by using some built-in facilities of STL and Boost?
Background
The my_output_stream
class will be used to adapt between an external library and a logging library used in my application. The external library requires that I provide an std::ostream. And I want to log each line that is logged by the external library using my application's logging framework.
If I understand correctly, you want to unconditionally flush at
end of line, and only at end of line. To do this, you must
implement your own streambuf; it could be based on
std::stringbuf
, but if you're only concerned with output,
and not worried about seeking, it's probably just as easy to do
it yourself.
Something like the following should do the trick:
class LineBufferedOutput : public std::streambuf
{
std::vector<char> myBuffer;
protected:
int overflow( int ch ) override
{
myBuffer.push_back( ch );
if ( ch == '\n' ) {
// whatever you have to do...
}
// return traits::eof() for failure...
}
};
I'm not sure what you mean by implementing your own tokenizer;
there's no tokenization involved. You do have to look at each
character, in order to compare it to '\n'
, but that's all.
And you ignore any explicit requests to sync()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With