Topic: Someone deeply understand the C++ streams? Please help
Author: jkontkan@beta.hut.fi (Janne Kontkanen)
Date: 1998/03/18 Raw View
We are developing a library which has several output
streams to display error and log information. These
streams should be easily redictable by the library
user, so I currently do in the library code:
std::ostream libLog(new dummystreambuf);
And user of library is supposed to do (for example):
int main()
{
libLog = std::cout;
...
}
Above should redirect the library log information to
the console (or to whatever std::cout is directed).
However, I am not sure if this is most elegant way to
do these kind of things.
The main problem now is that stream 'redirection'
(copy operator) doesn't seem to have any effect if the
streams original instance lies in dynamically linked library.
(Windows NT).
Value returned by libLog.rdbuf() does not even change - it
keeps pointing to dummystreambuf instance.
What surprises me deeply, is that if the stream instance
(libLog) is in applications code (not in the library), above
works just great.
Also If I directly copy the rdbuf from cout to libLog, the
streams starts to output it's information to console.
This does not solve all the problems though because the old
release of the library that customers are allready using,
does use the copy operator for redirecting those streams.
This works 'because' the older release uses older C++ library
headers (iostream_withassign is obsolete, isn't it?).
Please help, I am out of ideas.
Janne Kontkanen
PS. Anyone knows any book providing deeper dive to C++
standard streams, than for example Stroustrups 3rd edition?
--
* Janne Kontkanen Janne.Kontkanen@hut.fi *
* Albertinkatu 22-24 C 27 http://www.hut.fi/~jkontkan *
* 00120 Helsinki *
* p. 629391 .oOo.) Complex (.oOo. *
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/03/18 Raw View
Janne Kontkanen<jkontkan@beta.hut.fi> wrote:
>Anyone knows any book providing deeper dive to C++
>standard streams, than for example Stroustrups 3rd edition?
If you can read German, Nico Josutti's book on the Standard C++
Library is well-thought-of. (An Englis(c)h translation is due
out "soon". Also, the Langer & Kreft book should be out this
year as well, both from Addison-Wesley.)
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Kevin Jacobs <jacobs@darwin.EPBI.CWRU.Edu>
Date: 1998/03/19 Raw View
Janne Kontkanen <jkontkan@beta.hut.fi> wrote:
> We are developing a library which has several output
> streams to display error and log information. These
> streams should be easily redictable by the library
> user, so I currently do in the library code:
I've done just what you're looking for, but the compiler support isn't quite
there for it to be portable yet. It currently runs under KAI C++ and almost
runs with DeltaLogic's XTL. The streams have copy semantics, have their
own io manipulators and can multiplex themselves. They also include
formatted prefixes, suffixes and word wrapping, plus several other extras.
Here is an example of how they are used:
errorstream<char> errors = cerr;
errorstream<char> warnings = cerr;
errorstream<char> output = cout;
errors << priority(priority_error)
<< prefix("PROGRAM-E (%T): " // %T expands to the current time
<< line_width(80); // set width of line to 80 characters
// for line wrapping
// similar initializations for warnings and output
errormultistream<char> multi;
multi.insert(errors); // Insert errors stream into multistream
// Restrict the range of error messages on the most recently inserted stream
// to items that are of priority error or higher (fatal being the highest)
multi.restrict_range(priority_error, priority_fatal);
multi.insert(warnings);
// restrict the warning stream to only warnings
multi.restrict(r_eq, priority_warnings);
multi.insert(output);
// Restrict the output stream to things that aren't errors
multi.restrict(r_eq,priority_none);
multi can then be passed (and copied) as an errorstream or as an ostream &.
If cast to an ostream & or ostream * it looses the ability to be copied and
use errorstream specific io manipulators (ie. priority, line_width, etc).
Also, there is no memory leak if rdbuf( streambuf *) is called on it when
cast to an ostream. This is a concern since the error stream streambuf must
be dynamically allocated.
> std::ostream libLog(new dummystreambuf);
> And user of library is supposed to do (for example):
> int main()
> {
> libLog = std::cout;
> ...
> }
You have to define a base stream class from basic_ostream<...> that has copy
semantics.
> Above should redirect the library log information to
> the console (or to whatever std::cout is directed).
That requires code in your streambuf class.
> However, I am not sure if this is most elegant way to
> do these kind of things.
To give you a hint as to how I did it, I derive my basic_errorstreambuf
class from basic_stringbuf and flush it on sync().
> PS. Anyone knows any book providing deeper dive to C++
> standard streams, than for example Stroustrups 3rd edition?
I suggest you start reading header files for the iostreams. stringstreams
being the place I started.
-Kevin Jacobs
--
-----------> Kevin Jacobs <-----------|-------> (216) 778-8487 <--------
S.A.G.E. Project Technical Coordinator | Department of Epidemiology
& System Administrator | & Biostatistics
Internet E-mail: jacobs@darwin.cwru.edu | Case Western Reserve University
----------------------------------------------------------------------------
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1998/03/20 Raw View
jkontkan@beta.hut.fi (Janne Kontkanen) wrote:
>We are developing a library which has several output
>streams to display error and log information. These
>streams should be easily redictable by the library
>user, so I currently do in the library code:
>
>std::ostream libLog(new dummystreambuf);
>
>And user of library is supposed to do (for example):
>
>int main()
>{
> libLog = std::cout;
> ...
>}
>
>Above should redirect the library log information to
>the console (or to whatever std::cout is directed).
[ stuff left out ]
>
>This does not solve all the problems though because the old
>release of the library that customers are allready using,
>does use the copy operator for redirecting those streams.
>This works 'because' the older release uses older C++ library
>headers (iostream_withassign is obsolete, isn't it?).
>
>Please help, I am out of ideas.
Yes, ostream_withassign is obsolete.
You should create a class specifically designed for redirection. The
code below is untested, but I think it should work with both older
libraries and newer, standard-conforming libraries.
class redirectable_ostream : public std::ostream
{
public:
redirectable_ostream() : std::ostream((streambuf*) NULL) { }
redirectable_ostream(const std::ostream &rhs)
: std::ostream(rhs.rdbuf()) { }
// the constructor below may seem redundant, but the constructor above
// is not really a copy constructor, so we must create one.
redirectable_ostream(const redirectable_ostream &rhs)
: std::ostream(rhs.rdbuf()) { }
redirectable_ostream& operator=(const std::ostream &rhs)
{ rdbuf(rhs.rdbuf()); return *this; }
redirectable_ostream& operator=(const redirectable_ostream &rhs)
{ rdbuf(rhs.rdbuf()); return *this; }
void release() { rdbuf(NULL); }
};
Then use the above class for your logging:
redirectable_ostream libLog(std::cout);
or
redirectable_ostream libLog;
libLog = cout;
Note that redirectable_ostream never owns its streambuf object. It is
always shared with the stream from which it is copied. Thus, it is
important that the redirectable_ostream object never outlive the stream
from which it was copied.
>
>PS. Anyone knows any book providing deeper dive to C++
>standard streams, than for example Stroustrups 3rd edition?
Stroustrup's 3rd edition does go somewhat into standard streams. Enough
to get a lot done. However, there is at least one book devoted entirely
to the subject (sorry, I don't know the title or author off hand).
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]