3 // Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 // 27.5.2 template class basic_streambuf
32 #include <cstring> // for memset, memcmp
36 #include <testsuite_hooks.h>
38 class testbuf : public std::streambuf
43 typedef std::streambuf::traits_type traits_type;
44 typedef std::streambuf::char_type char_type;
46 testbuf(): std::streambuf()
47 { _M_mode = (std::ios_base::in | std::ios_base::out); }
53 VERIFY( this->eback() == NULL );
54 VERIFY( this->gptr() == NULL );
55 VERIFY( this->egptr() == NULL );
56 VERIFY( this->pbase() == NULL );
57 VERIFY( this->pptr() == NULL );
58 VERIFY( this->epptr() == NULL );
64 { return (this->uflow()); }
67 pub_overflow(int_type __c = traits_type::eof())
68 { return (this->overflow(__c)); }
71 pub_pbackfail(int_type __c)
72 { return (this->pbackfail(__c)); }
75 pub_setg(char* beg, char* cur, char *end)
76 { this->setg(beg, cur, end); }
79 pub_setp(char* beg, char* end)
80 { this->setp(beg, end); }
86 int_type __retval = traits_type::eof();
87 if (this->gptr() < this->egptr())
88 __retval = traits_type::not_eof(0);
95 typedef testbuf::traits_type traits_type;
96 typedef testbuf::int_type int_type;
99 char* lit01 = "chicago underground trio/possible cube on delmark";
102 // 27.5.2.1 basic_streambuf ctors
103 // default ctor initializes
104 // - all pointer members to null pointers
105 // - locale to current global locale
106 VERIFY( buf01.check_pointers() );
107 VERIFY( buf01.getloc() == std::locale() );
109 // 27.5.2.3.1 get area
110 // 27.5.2.2.3 get area
111 // 27.5.2.4.3 get area
113 buf01.pub_setg(lit01, lit01, (lit01 + i01));
114 VERIFY( i01 == buf01.in_avail() );
116 VERIFY( buf01.pub_uflow() == lit01[0] );
117 VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[1]) );
118 VERIFY( buf01.pub_uflow() == lit01[1] );
119 VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[2]) );
120 VERIFY( buf01.pub_uflow() == lit01[2] );
121 VERIFY( buf01.sgetc() == traits_type::eof() );
124 buf01.pub_setg(lit01, lit01, (lit01 + i01));
125 VERIFY( i01 == buf01.in_avail() );
126 int_type intt01 = traits_type::to_int_type('b');
127 VERIFY( traits_type::eof() == buf01.pub_pbackfail(intt01) );
130 VERIFY( traits_type::eof() == buf01.pub_overflow(intt01) );
131 VERIFY( traits_type::eof() == buf01.pub_overflow() );
132 VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[0]) );
135 char* lit02 = "isotope 217: the unstable molecule on thrill jockey";
136 int i02 = std::strlen(lit02);
137 char carray[i02 + 1];
138 std::memset(carray, 0, i02 + 1);
140 buf01.pub_setp(carray, (carray + i02));
141 buf01.sputn(lit02, 0);
142 VERIFY( carray[0] == 0 );
143 VERIFY( lit02[0] == 'i' );
144 buf01.sputn(lit02, 1);
145 VERIFY( lit02[0] == carray[0] );
146 VERIFY( lit02[1] == 's' );
147 VERIFY( carray[1] == 0 );
148 buf01.sputn(lit02 + 1, 10);
149 VERIFY( std::memcmp(lit02, carray, 10) == 0 );
150 buf01.sputn(lit02 + 11, 20);
151 VERIFY( std::memcmp(lit02, carray, 30) == 0 );
160 typedef testbuf::traits_type traits_type;
161 typedef testbuf::int_type int_type;
164 char* lit01 = "chicago underground trio/possible cube on delmark";
167 // 27.5.2.1 basic_streambuf ctors
168 // default ctor initializes
169 // - all pointer members to null pointers
170 // - locale to current global locale
171 VERIFY( buf01.check_pointers() );
172 VERIFY( buf01.getloc() == std::locale() );
174 // 27.5.2.2.5 Put area
175 size_t i01 = traits_type::length(lit01);
177 std::memset(carray01, 0, i01);
179 buf01.pub_setg(lit01, lit01, lit01 + i01);
180 buf01.sgetn(carray01, 0);
181 VERIFY( carray01[0] == 0 );
182 buf01.sgetn(carray01, 1);
183 VERIFY( carray01[0] == 'c' );
184 buf01.sgetn(carray01 + 1, i01 - 1);
185 VERIFY( carray01[0] == 'c' );
186 VERIFY( carray01[1] == 'h' );
187 VERIFY( carray01[i01 - 1] == 'k' );
195 // http://gcc.gnu.org/ml/libstdc++/2000-q1/msg00151.html
196 template<typename charT, typename traits = std::char_traits<charT> >
197 class basic_nullbuf : public std::basic_streambuf<charT, traits>
201 std::basic_streambuf<charT, traits>::int_type int_type;
204 { return traits::not_eof(c); }
207 typedef basic_nullbuf<char> nullbuf;
208 typedef basic_nullbuf<wchar_t> wnullbuf;
215 std::ostream out(&ob);
216 out << x << std::endl;
217 return (!out ? '0' : '1');
223 const std::string control01("11111");
226 test01 += print(true);
227 test01 += print(3.14159);
229 test01 += print('x');
230 test01 += print("pipo");
232 VERIFY( test01 == control01 );
238 class setpbuf : public std::streambuf
253 setp(buffer, buffer + 4);
263 return traits_type::eof();
265 result += traits_type::to_char_type(n);
273 result.append(pbase(), pptr());
274 setp(buffer, buffer + 4);
283 std::string text = "abcdefghijklmn";
287 // Here xsputn writes over sp1.result
288 sp1.sputn(text.c_str(), text.length());
290 // This crashes when result is accessed
292 VERIFY( sp1.get_result() == text );
297 for (std::string::size_type i = 0; i < text.length(); ++i)
299 // sputc also writes over result
305 VERIFY( sp2.get_result() == text );
308 class nullsetpbuf : public std::streambuf
322 std::string text1 = "abcdefghijklmn";
325 // Immediate crash as xsputn writes to null pointer
326 nsp.sputn(text1.c_str(), text1.length());
334 class something_derived;
337 class gnu::something_derived : std::streambuf { };
340 class testbuf2 : public std::streambuf
343 typedef std::streambuf::traits_type traits_type;
345 testbuf2() : std::streambuf() { }
349 overflow(int_type c = traits_type::eof())
350 { return traits_type::not_eof(0); }
358 std::ostream out(&ob);
375 VERIFY( ob.getloc() == loc );
377 locale::global(locale("en_US"));
378 VERIFY( ob.getloc() == loc );
380 locale loc_de ("de_DE");
381 locale ret = ob.pubimbue(loc_de);
382 VERIFY( ob.getloc() == loc_de );
383 VERIFY( ret == loc );
386 VERIFY( ob.getloc() == loc_de );
390 class Outbuf : public std::streambuf
393 typedef std::streambuf::traits_type traits_type;
395 std::string result() const { return str; }
398 virtual int_type overflow(int_type c = traits_type::eof())
400 if (!traits_type::eq_int_type(c, traits_type::eof()))
401 str.push_back(traits_type::to_char_type(c));
402 return traits_type::not_eof(c);
414 std::istringstream stream("Bad Moon Rising");
418 VERIFY( buf.result() == "Bad Moon Rising" );
426 std::stringbuf sbuf("Bad Moon Rising", std::ios::in);
428 std::ostream stream(&buf);
431 VERIFY( buf.result() == "Bad Moon Rising" );
435 class Outbuf_2 : public std::streambuf
445 int_type overflow(int_type c)
447 int_type eof = traits_type::eof();
449 if (pptr() < epptr())
451 if (traits_type::eq_int_type(c, eof))
452 return traits_type::not_eof(c);
454 *pptr() = traits_type::to_char_type(c);
463 class Inbuf_2 : public std::streambuf
465 static const char buf[];
473 size = std::strlen(buf);
478 if (current < buf + size)
479 return traits_type::to_int_type(*current);
480 return traits_type::eof();
485 if (current < buf + size)
486 return traits_type::to_int_type(*current++);
487 return traits_type::eof();
491 const char Inbuf_2::buf[] = "Atteivlis";
499 std::istream is(&inbuf1);
502 VERIFY( inbuf1.sgetc() == 't' );
512 std::ostream os (&outbuf2);
515 VERIFY( inbuf2.sgetc() == 't' );