User defined streambuf
Michel Decima
michel.decima@cnet.francetelecom.fr
Sat Apr 1 00:00:00 GMT 2000
Hello everybody,
Last week I downloaded the libstdc++-2.90.7 to play with
standard library features like new streams, and I'm in
trouble now with my own streambufs.. Here is the code:
#include <cstdio>
#include <streambuf>
#include <iostream>
// A black hole streambuf, like /dev/null
// Defined 'by the book' from Nicolai M. Josuttis,
// "The C++ Standard Library", p 668-670
//
template<typename charT, typename traits = std::char_traits<charT> >
class basic_nullbuf : public std::basic_streambuf<charT, traits>
{
protected:
virtual
int_type overflow(int_type c) {
return traits::not_eof(c);
}
};
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
template<typename T>
void print(const T& x) {
nullbuf ob;
std::ostream out(&ob);
out << x << std::endl;
if(!out) std::printf("error\n");
else std::printf("ok\n");
}
int main()
{
print( true );
print( 3.14159 );
print( 10 );
print('x');
print( "pipo");
}
With Sun CC 5.0, the program is doing fine (5 times ok), but with
gcc-2.95.2 and libstdc++-2.90.7, I got 3 ok and 2 error: for
numeric values, my own overflow is called, and the stream state
is ok, but for caracters, overflow is not called (and the stream
become bad). So I added to the class basic_nullbuf the following
function :
virtual
std::streamsize xsputn(const char*, std::streamsize n) {
return n;
}
and it worked (5 ok). But I think I don't have to provide this
hack to have a working streambuf (perhaps I'm wrong, I'm not
yet an ISO-C++-guru), because the default xsputn should call
overflow.
The debugger told me that the default xsputn can't call the
overflow because (see below) because the mode of my nullbuf
is the wrong one :
// g++-v3/include/bits/streambuf.tcc
template<typename _CharT, typename _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsputn(const char_type* __s, streamsize __n)
{
bool __testout = _M_mode & ios_base::out; // here it is !
// _M_mode = 0
streamsize __retval = 0;
if (__n && __testout) { // __testout is false
...
}
Then I removed my own xsputn and added a constructor :
basic_nullbuf() {
_M_mode = std::ios::out;
}
it worked (again 5 ok), but I don't think my code is
standard now...
So I think there is a problem here (or the book and CC are wrong).
Perhaps it is ok in a recent snapshot, and I should update.
--
mailto:michel.decima@cnet.francetelecom.fr
Gates' Law: Every 18 months, the speed of software halves.
More information about the Libstdc++
mailing list