OSDN Git Service

d7ae5693d33488d4ff676601beae4b88fbe0381e
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / 27_io / streambuf_members.cc
1 // 1999-10-11 bkoz
2
3 // Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 //
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)
9 // any later version.
10
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.
15
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,
19 // USA.
20
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.
29
30 // 27.5.2 template class basic_streambuf
31
32 #include <cstring> // for memset, memcmp
33 #include <streambuf>
34 #include <sstream>
35 #include <ostream>
36 #include <testsuite_hooks.h>
37
38 class testbuf : public std::streambuf
39 {
40 public:
41
42   // Typedefs:
43   typedef std::streambuf::traits_type traits_type;
44   typedef std::streambuf::char_type char_type;
45
46   testbuf(): std::streambuf() 
47   { _M_mode = (std::ios_base::in | std::ios_base::out); }
48
49   bool
50   check_pointers()
51   { 
52     bool test = true;
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 );
59     return test;
60   }
61
62   int_type 
63   pub_uflow() 
64   { return (this->uflow()); }
65
66   int_type 
67   pub_overflow(int_type __c = traits_type::eof()) 
68   { return (this->overflow(__c)); }
69
70   int_type 
71   pub_pbackfail(int_type __c) 
72   { return (this->pbackfail(__c)); }
73
74   void 
75   pub_setg(char* beg, char* cur, char *end) 
76   { this->setg(beg, cur, end); }
77
78   void 
79   pub_setp(char* beg, char* end) 
80   { this->setp(beg, end); }
81
82 protected:
83   int_type 
84   underflow() 
85   { 
86     int_type __retval = traits_type::eof();
87     if (this->gptr() < this->egptr())
88       __retval = traits_type::not_eof(0); 
89     return __retval;
90   }
91 };
92
93 void test01()
94 {
95   typedef testbuf::traits_type traits_type;
96   typedef testbuf::int_type int_type;
97
98   bool test = true;
99   char* lit01 = "chicago underground trio/possible cube on delmark";
100   testbuf buf01;
101
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() );
108
109   // 27.5.2.3.1 get area
110   // 27.5.2.2.3 get area
111   // 27.5.2.4.3 get area
112   int i01 = 3;
113   buf01.pub_setg(lit01, lit01, (lit01 + i01));
114   VERIFY( i01 == buf01.in_avail() );
115
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() );
122
123   // pbackfail
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) );
128
129   // overflow
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]) );
133
134   // sputn/xsputn
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);
139
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 );
152
153 #ifdef DEBUG_ASSERT
154   assert(test);
155 #endif
156 }
157
158 void test02()
159 {
160   typedef testbuf::traits_type traits_type;
161   typedef testbuf::int_type int_type;
162
163   bool test = true;
164   char* lit01 = "chicago underground trio/possible cube on delmark";
165   testbuf buf01;
166
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() );
173
174   // 27.5.2.2.5 Put area
175   size_t i01 = traits_type::length(lit01);
176   char carray01[i01];
177   std::memset(carray01, 0, i01);
178   
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' );
188
189 #ifdef DEBUG_ASSERT
190   assert(test);
191 #endif
192 }
193  
194 // test03
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>
198   {
199   protected:
200     typedef typename
201       std::basic_streambuf<charT, traits>::int_type int_type;
202     virtual int_type 
203     overflow(int_type c) 
204     {  return traits::not_eof(c); }
205   };
206
207 typedef basic_nullbuf<char> nullbuf;
208 typedef basic_nullbuf<wchar_t> wnullbuf;
209
210 template<typename T>
211   char
212   print(const T& x) 
213   {
214    nullbuf ob;
215    std::ostream out(&ob); 
216    out << x << std::endl;
217    return (!out ? '0' : '1');
218  }
219
220 void test03() 
221 {
222   bool test = true;
223   const std::string control01("11111");
224   std::string test01;
225
226   test01 += print(true);
227   test01 += print(3.14159);
228   test01 += print(10);
229   test01 += print('x');
230   test01 += print("pipo");
231
232   VERIFY( test01 == control01 );
233 #ifdef DEBUG_ASSERT
234   assert(test);
235 #endif
236 }
237
238 class setpbuf : public std::streambuf
239 {
240   char          buffer[4];
241   std::string   result;
242
243 public:
244
245   std::string&
246   get_result()
247   { return result; }
248
249   setpbuf()
250   {
251     char foo [32];
252     setp(foo, foo + 32);
253     setp(buffer, buffer + 4);
254   }
255
256   ~setpbuf()
257   { sync(); }
258
259   virtual int_type 
260   overflow(int_type n)
261   {
262     if (sync() != 0)
263       return traits_type::eof();
264     
265     result += traits_type::to_char_type(n);
266     
267     return n;
268   }
269   
270   virtual int 
271   sync()
272   {
273     result.append(pbase(), pptr());
274     setp(buffer, buffer + 4);
275     return 0;
276   }
277 };
278
279 // libstdc++/1057
280 void test04()
281 {
282   bool test = true;
283   std::string text = "abcdefghijklmn";
284   
285   // 01
286   setpbuf sp1;
287   // Here xsputn writes over sp1.result
288   sp1.sputn(text.c_str(), text.length());
289
290   // This crashes when result is accessed
291   sp1.pubsync();
292   VERIFY( sp1.get_result() == text );
293   
294
295   // 02
296   setpbuf sp2;
297   for (std::string::size_type i = 0; i < text.length(); ++i)
298     {
299       // sputc also writes over result
300       sp2.sputc(text[i]);
301     }
302   
303   // Crash here
304   sp2.pubsync();
305   VERIFY( sp2.get_result() == text );
306 }
307
308 class nullsetpbuf : public std::streambuf
309 {
310   char foo[64];
311 public:
312   nullsetpbuf()
313   {
314     setp(foo, foo + 64);
315     setp(NULL, NULL);
316   }
317 };
318
319 // libstdc++/1057
320 void test05()
321 {
322     std::string text1 = "abcdefghijklmn";
323
324     nullsetpbuf nsp;
325     // Immediate crash as xsputn writes to null pointer
326     nsp.sputn(text1.c_str(), text1.length());
327     // ditto
328     nsp.sputc('a');
329 }
330
331 // test06
332 namespace gnu 
333 {
334   class something_derived;
335 }
336
337 class gnu::something_derived : std::streambuf { };
338
339 // libstdc++/3599
340 class testbuf2 : public std::streambuf
341 {
342 public:
343   typedef std::streambuf::traits_type traits_type;
344
345   testbuf2() : std::streambuf() { }
346  
347 protected:
348   int_type 
349   overflow(int_type c = traits_type::eof()) 
350   { return traits_type::not_eof(0); }
351 };
352
353 void
354 test07()
355 {
356   bool test = true;
357   testbuf2 ob;
358   std::ostream out(&ob); 
359
360   out << "gasp";
361   VERIFY(out.good());
362
363   out << std::endl;
364   VERIFY(out.good());
365 }
366
367 // libstdc++/9322
368 void test08()
369 {
370   using std::locale;
371   bool test = true;
372
373   locale loc;
374   testbuf2 ob;
375   VERIFY( ob.getloc() == loc );
376
377   locale::global(locale("en_US"));
378   VERIFY( ob.getloc() == loc );
379
380   locale loc_de ("de_DE");
381   locale ret = ob.pubimbue(loc_de);
382   VERIFY( ob.getloc() == loc_de );
383   VERIFY( ret == loc );
384
385   locale::global(loc);
386   VERIFY( ob.getloc() == loc_de );
387 }
388
389 // libstdc++/9318
390 class Outbuf : public std::streambuf
391 {
392 public:
393   typedef std::streambuf::traits_type traits_type;
394
395   std::string result() const { return str; }
396
397 protected:
398   virtual int_type overflow(int_type c = traits_type::eof())
399   {
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);
403   }
404
405 private:
406   std::string str;
407 };
408
409 // <1>
410 void test09()
411 {
412   bool test = true;
413   
414   std::istringstream stream("Bad Moon Rising");
415   Outbuf buf;
416   stream >> &buf;
417
418   VERIFY( buf.result() == "Bad Moon Rising" );
419 }
420
421 // <2>
422 void test10()
423 {
424   bool test = true;
425
426   std::stringbuf sbuf("Bad Moon Rising", std::ios::in);
427   Outbuf buf;
428   std::ostream stream(&buf);
429   stream << &sbuf;
430
431   VERIFY( buf.result() == "Bad Moon Rising" );
432 }
433
434 // libstdc++/9424
435 class Outbuf_2 : public std::streambuf
436 {
437   char buf[1];
438
439 public:
440   Outbuf_2()
441   {
442     setp(buf, buf + 1);
443   }
444
445   int_type overflow(int_type c)
446   {
447     int_type eof = traits_type::eof();
448     
449     if (pptr() < epptr())
450       {
451         if (traits_type::eq_int_type(c, eof))
452           return traits_type::not_eof(c);
453         
454         *pptr() = traits_type::to_char_type(c);
455         pbump(1);
456         return c;
457       }
458
459     return eof;
460   }
461 };
462
463 class Inbuf_2 : public std::streambuf
464 {
465   static const char buf[];
466   const char* current;
467   int size;
468
469 public:
470   Inbuf_2()
471   {
472     current = buf;
473     size = std::strlen(buf);
474   }
475   
476   int_type underflow()
477   {
478     if (current < buf + size)
479       return traits_type::to_int_type(*current);
480     return traits_type::eof();
481   }
482   
483   int_type uflow()
484   {
485     if (current < buf + size)
486       return traits_type::to_int_type(*current++);
487     return traits_type::eof();
488   }
489 };
490
491 const char Inbuf_2::buf[] = "Atteivlis";
492
493 // <1>
494 void test11()
495 {
496   bool test = true;
497
498   Inbuf_2 inbuf1;
499   std::istream is(&inbuf1);
500   Outbuf_2 outbuf1;
501   is >> &outbuf1;
502   VERIFY( inbuf1.sgetc() == 't' );
503   VERIFY( is.good() );
504 }
505
506 // <2>
507 void test12()
508
509   bool test = true;
510  
511   Outbuf_2 outbuf2;
512   std::ostream os (&outbuf2);
513   Inbuf_2 inbuf2;
514   os << &inbuf2;
515   VERIFY( inbuf2.sgetc() == 't' );
516   VERIFY( os.good() );
517 }
518
519 int main() 
520 {
521   test01();
522   test02();
523   test03();
524
525   test04();
526   test05();
527
528   test07();
529   test08();
530
531   test09();
532   test10();
533   test11();
534   test12();
535   return 0;
536 }