Writing my own stream class
-
For a module I want to write my own stream class. Although not identical the following example illustrates what I want to do: suppose you have a class representing a printer:
class Printer { ...};
I want the user of this class to send data to this class using the << operator, so that any data type/class, for which << is defined on streams, e.g.
Printer myPrinter (printerName); PrinterStream &printStr = myPrinter.getStream(); printStr << "Hello world" << 123 << std::endl;
So, how can I write my own stream class so that I can intercept the data send to printStr? I probably need to inherit from some STL stream class, but I don't know where to start. Is this something that can be done easily, or is this almost impossible? Another alternative (although I don't really like it) is to let my getStream() method to return a stringstream. My class then simply needs a kind of flush method to get the data from the stringstream, send it to the output where I want it and then empty the stringstream. I don't like this alternative because it exposes the fact that's a stringstream to the caller. Also I cannot add my own output manipulators (e.g. to set the font or color) to the stream. Does anybody know a simple solution, or point me to an article that explains how to write your own stream class? Thanks in advance. Enjoy life, this is not a rehearsal !!! My Articles: - Implementing a Subject/Observer pattern with templates - Different ways of writing class factories - AutoRunner: a template class to automatically run start- and cleanup-code in code blocks
-
For a module I want to write my own stream class. Although not identical the following example illustrates what I want to do: suppose you have a class representing a printer:
class Printer { ...};
I want the user of this class to send data to this class using the << operator, so that any data type/class, for which << is defined on streams, e.g.
Printer myPrinter (printerName); PrinterStream &printStr = myPrinter.getStream(); printStr << "Hello world" << 123 << std::endl;
So, how can I write my own stream class so that I can intercept the data send to printStr? I probably need to inherit from some STL stream class, but I don't know where to start. Is this something that can be done easily, or is this almost impossible? Another alternative (although I don't really like it) is to let my getStream() method to return a stringstream. My class then simply needs a kind of flush method to get the data from the stringstream, send it to the output where I want it and then empty the stringstream. I don't like this alternative because it exposes the fact that's a stringstream to the caller. Also I cannot add my own output manipulators (e.g. to set the font or color) to the stream. Does anybody know a simple solution, or point me to an article that explains how to write your own stream class? Thanks in advance. Enjoy life, this is not a rehearsal !!! My Articles: - Implementing a Subject/Observer pattern with templates - Different ways of writing class factories - AutoRunner: a template class to automatically run start- and cleanup-code in code blocks
-
For a module I want to write my own stream class. Although not identical the following example illustrates what I want to do: suppose you have a class representing a printer:
class Printer { ...};
I want the user of this class to send data to this class using the << operator, so that any data type/class, for which << is defined on streams, e.g.
Printer myPrinter (printerName); PrinterStream &printStr = myPrinter.getStream(); printStr << "Hello world" << 123 << std::endl;
So, how can I write my own stream class so that I can intercept the data send to printStr? I probably need to inherit from some STL stream class, but I don't know where to start. Is this something that can be done easily, or is this almost impossible? Another alternative (although I don't really like it) is to let my getStream() method to return a stringstream. My class then simply needs a kind of flush method to get the data from the stringstream, send it to the output where I want it and then empty the stringstream. I don't like this alternative because it exposes the fact that's a stringstream to the caller. Also I cannot add my own output manipulators (e.g. to set the font or color) to the stream. Does anybody know a simple solution, or point me to an article that explains how to write your own stream class? Thanks in advance. Enjoy life, this is not a rehearsal !!! My Articles: - Implementing a Subject/Observer pattern with templates - Different ways of writing class factories - AutoRunner: a template class to automatically run start- and cleanup-code in code blocks
Writing your iostream class is not hard, but it's not trivial either. Basically you have to make
CPrinter
derive fromstd::ostream
and provide a specialstd::streambuf
class:class CPrinter: public std::ostream
{
typedef std::ostream super;
CPrinterStreambuf sbuf; // more on this later
public:
CPrinter():super(&buf){}...
};
Now,
std::ostream
handles all the IO via the providedCPrinterStreambuf
object, which derives from the virtual base classstd::streambuf
. Depending on where you want the bytes to be sent, you might consider writingCPrinterStreambuf
from scratch or deriving from saystd::filebuf
orstd::stringbuf
. Now you can intercept outgoing data by overridingoverflow
andsync
. Here[^] is an example provided by MS that might be useful. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
Writing your iostream class is not hard, but it's not trivial either. Basically you have to make
CPrinter
derive fromstd::ostream
and provide a specialstd::streambuf
class:class CPrinter: public std::ostream
{
typedef std::ostream super;
CPrinterStreambuf sbuf; // more on this later
public:
CPrinter():super(&buf){}...
};
Now,
std::ostream
handles all the IO via the providedCPrinterStreambuf
object, which derives from the virtual base classstd::streambuf
. Depending on where you want the bytes to be sent, you might consider writingCPrinterStreambuf
from scratch or deriving from saystd::filebuf
orstd::stringbuf
. Now you can intercept outgoing data by overridingoverflow
andsync
. Here[^] is an example provided by MS that might be useful. Joaquín M López Muñoz Telefónica, Investigación y DesarrolloThank you Joaquin, I finally found some time to experiment with this. I started from the Microsoft article you referenced but that did not work because there seems to be something like an old STL and a new STL. The article only worked for the old STL, and not for the new one. But after some digging into the documentation, I finally found the solution. Thanks for your help. Maybe I write an article on this. Enjoy life, this is not a rehearsal !!! My Articles: - Implementing a Subject/Observer pattern with templates - Different ways of writing class factories - AutoRunner: a template class to automatically run start- and cleanup-code in code blocks