Re: Redirecting cout to a TextBuffer
- From: "Søren Hauberg" <hauberg gmail com>
- To: "Charles McLachlan" <cim20 metropolis-data co uk>
- Cc: gtkmm-list <gtkmm-list gnome org>
- Subject: Re: Redirecting cout to a TextBuffer
- Date: Sun, 29 Jun 2008 19:05:19 +0200
2008/5/12 Charles McLachlan <cim20 metropolis-data co uk>:
> On Sat, 10 May 2008, Søren Hauberg wrote:
>
>> Hi all,
>> I'm using gtksourceviewmm as terminal-like widget, and I want to
>> redirect std::cout to this widget. Currently I'm doing something like
>> this in my constructor:
>>
>> std::ostringstream outs;
>> std::cout.rdbuf (outs.rdbuf ());
>
> Caveat: I don't know much about gtksourcemm but I do know something about
> STL streambufs.
>
> If the above code works (its an interesting idea that I have not seen
> before), then my advice would be subclass your own streambuf. You'll need to
> overload the the sync and overflow members. These have slightly weird
> actions and (on first viewing) appear non trivial.
>
> The advantage of this appreoach is that the source view will only be updated
> when 1) the buffer runs out, 2) the stream explicitly asks for it, usually
> via stream.sync() being called. This (correctly) puts the control of the
> updates in the hands of the user of the stream, rather than having to wait
> for timeouts.
So, I finally got my act together and implemented your idea, so I
thought I'd report back. Basically, your idea works great. Some
modifications were necessary, so I thought I'd post the code in case
anybody wanted something similar:
class ogsbuf : public std::streambuf
{
private:
const static int kZBufferSize = 2048;
Glib::RefPtr<Gtk::TextBuffer> destination;
char *buffer;
public:
explicit ogsbuf (Glib::RefPtr<Gtk::TextBuffer> &_destination)
: destination (_destination)
{
buffer = (char*)malloc (sizeof (char) * kZBufferSize);
setp (buffer, buffer + kZBufferSize);
}
~ogsbuf ()
{
sync ();
clear ();
}
void clear ()
{
free (buffer);
}
protected:
inline int sync()
{
// pbase () is an unsigned char * pointing to the data to be
written to the destination
// pptr () is an end pointer for the data.
destination->insert (destination->end (), pbase (), pptr ());
setp (buffer, buffer + kZBufferSize);
return 0;
}
inline int overflow (int ch = traits_type::eof ())
{
const int ret = sync ();
*pptr () = ch;
pbump (1);
return ret;
}
};
Thanks,
Søren
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]