Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A custom ostream

Tags:

c++

I need some guidance or pointers understanding how to implement a custom ostream. My requirements are:

  1. A class with a '<<' operator for several data types.
  2. The intention is to send output to database. Each "line" should go to a separate record.
  3. Each record most important field would be the text (or blob), but some other fields such as time, etc. can be mostly deduced automatically
  4. buffering is important, as I don't want to go to database for every record.

First, does it worth deriving from ostream? What do I get by deriving from ostream? What if my class simply implements few operator<< methods (including some custom data types). Which functionality do I get from ostream?

Assuming what I want is a class derived from ostream, I need some guidance understanding the relationship between the ostream and the streambuf classes. Which one do I need to implement? Looking at some samples, it appears that I don't need to derive from ostream at all, and just give the ostream constructor a custom streambuf. Is that true? is that the canonical approach?

Which virtual functions at the custom streambuf do i need to implement? I've seen some samples (including this site: here and here, and few more), some override the sync method, and other override the overflow method. Which one should I override? Also, looking at the stringbuf and filebuf sources (Visual Studio or GCC) both those buffer classes implement many methods of the streambuf.

If a custom class derived from streambuf is required, would there be any benefit deriving from stringbuf (or any other class) instead of directly from streambuf?

As for "lines". I would like at least when my users of the class using the 'endl' manipulator to be a new line (i.e. record in database). Maybe - depends on effort - every '\n' character should be considered as a new record as well. Who do my custom ostream and/or streambuf get notified for each?

like image 629
Uri Avatar asked Dec 04 '12 13:12

Uri


People also ask

What does Ostream mean?

Bazzy (6281) ostream is an output stream, the & is to pass by reference ( the only way to pass streams to functions ) your function should be called like this: print(cout,number); It allows to print to standard output ( cout ) or to any other stream ( like files )

What is Streambuf?

A stream buffer is an object in charge of performing the reading and writing operations of the stream object it is associated with: the stream delegates all such operations to its associated stream buffer object, which is an intermediary between the stream and its controlled input and output sequences.


1 Answers

A custom destination for ostream means implementing your own ostreambuf. If you want your streambuf to actually buffer (i.e. don't connect to the database after each character), the easiest way to do that is by creating a class inheriting from std::stringbuf. The only function that you'll need to override is the sync() method, which is being called whenever the stream is flushed.

class MyBuf : public std::stringbuf { public:     virtual int sync() {         // add this->str() to database here         // (optionally clear buffer afterwards)     } }; 

You can then create a std::ostream using your buffer:

MyBuf buff; std::ostream stream(&buf) 

Most people advised against redirecting the stream to a database, but they ignored my description that the database basically has a single blob field where all text is going to. In rare cases, I might send data to a different field. This can be facilitated with custom attributes understood by my stream. For example:

MyStream << "Some text " << process_id(1234) << "more text" << std::flush 

The code above will create a record in the database with:

blob: 'Some text more text' process_id: 1234 

process_id() is a method returning a structure ProcessID. Then, in the implementation of my ostream, I have an operator<<(ProcessID const& pid), which stores the process ID until it gets written. Works great!

like image 178
Uri Avatar answered Oct 08 '22 23:10

Uri