1 // File based streams -*- C++ -*-
2 
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21 
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30 
31 //
32 // ISO C++ 14882: 27.8  File-based streams
33 //
34 
35 /** @file fstream
36  *  This is a Standard C++ Library header.  You should @c #include this header
37  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
38  */
39 
40 #ifndef _CPP_FSTREAM
41 #define _CPP_FSTREAM	1
42 
43 #pragma GCC system_header
44 
45 #include <istream>
46 #include <ostream>
47 #include <locale>	// For codecvt
48 #include <bits/basic_file.h>
49 #include <bits/gthr.h>
50 
51 namespace std
52 {
53   // [27.8.1.1] template class basic_filebuf
54   /**
55    *  @brief  The actual work of input and output (for files).
56    *
57    *  This class associates both its input and output sequence with an
58    *  external disk file, and maintains a joint file position for both
59    *  sequences.  Many of its sematics are described in terms of similar
60    *  behavior in the Standard C Library's @c FILE streams.
61   */
62   template<typename _CharT, typename _Traits>
63     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
64     {
65     public:
66       // Types:
67       typedef _CharT                     	        char_type;
68       typedef _Traits                    	        traits_type;
69       typedef typename traits_type::int_type 		int_type;
70       typedef typename traits_type::pos_type 		pos_type;
71       typedef typename traits_type::off_type 		off_type;
72 
73       //@{
74       /**
75        *  @if maint
76        *  @doctodo
77        *  @endif
78       */
79       typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
80       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
81       typedef __basic_file<char>		        __file_type;
82       typedef typename traits_type::state_type          __state_type;
83       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
84       typedef ctype<char_type>                          __ctype_type;
85       //@}
86 
87       friend class ios_base; // For sync_with_stdio.
88 
89     protected:
90       // Data Members:
91       // MT lock inherited from libio or other low-level io library.
92       /**
93        *  @if maint
94        *  @doctodo
95        *  @endif
96       */
97       __c_lock          	_M_lock;
98 
99       // External buffer.
100       /**
101        *  @if maint
102        *  @doctodo
103        *  @endif
104       */
105       __file_type 		_M_file;
106 
107       // Current and beginning state type for codecvt.
108       /**
109        *  @if maint
110        *  @doctodo
111        *  @endif
112       */
113       __state_type		_M_state_cur;
114       __state_type 		_M_state_beg;
115 
116       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
117       /**
118        *  @if maint
119        *  @doctodo
120        *  @endif
121       */
122       bool			_M_buf_allocated;
123 
124       // XXX Needed?
125       bool			_M_last_overflowed;
126 
127       // The position in the buffer corresponding to the external file
128       // pointer.
129       /**
130        *  @if maint
131        *  @doctodo
132        *  @endif
133       */
134       char_type*		_M_filepos;
135 
136     public:
137       // Constructors/destructor:
138       /**
139        *  @brief  Does not open any files.
140        *
141        *  The default constructor initializes the parent class using its
142        *  own default ctor.
143       */
144       basic_filebuf();
145 
146       /**
147        *  @brief  The destructor closes the file first.
148       */
149       virtual
150       ~basic_filebuf()
151       {
152 	this->close();
153 	_M_last_overflowed = false;
154       }
155 
156       // Members:
157       /**
158        *  @brief  Returns true if the external file is open.
159       */
160       bool
161       is_open() const throw() { return _M_file.is_open(); }
162 
163       /**
164        *  @brief  Opens an external file.
165        *  @param  s  The name of the file.
166        *  @param  mode  The open mode flags.
167        *  @return  @c this on success, NULL on failure
168        *
169        *  If a file is already open, this function immediately fails.
170        *  Otherwise it tries to open the file named @a s using the flags
171        *  given in @a mode.
172        *
173        *  [Table 92 gives the relation between openmode combinations and the
174        *  equivalent fopen() flags, but the table has not been copied yet.]
175       */
176       __filebuf_type*
177       open(const char* __s, ios_base::openmode __mode);
178 
179       /**
180        *  @brief  Closes the currently associated file.
181        *  @return  @c this on success, NULL on failure
182        *
183        *  If no file is currently open, this function immediately fails.
184        *
185        *  If a "put buffer area" exists, @c overflow(eof) is called to flush
186        *  all the characters.  The file is then closed.
187        *
188        *  If any operations fail, this function also fails.
189       */
190       __filebuf_type*
191       close() throw();
192 
193     protected:
194       /**
195        *  @if maint
196        *  @doctodo
197        *  @endif
198       */
199       void
200       _M_allocate_internal_buffer();
201 
202       /**
203        *  @if maint
204        *  @doctodo
205        *  @endif
206       */
207       void
208       _M_destroy_internal_buffer() throw();
209 
210       // [27.8.1.4] overridden virtual functions
211       // [documentation is inherited]
212       virtual streamsize
213       showmanyc();
214 
215       // Stroustrup, 1998, p. 628
216       // underflow() and uflow() functions are called to get the next
217       // charater from the real input source when the buffer is empty.
218       // Buffered input uses underflow()
219 
220       // The only difference between underflow() and uflow() is that the
221       // latter bumps _M_in_cur after the read.  In the sync_with_stdio
222       // case, this is important, as we need to unget the read character in
223       // the underflow() case in order to maintain synchronization.  So
224       // instead of calling underflow() from uflow(), we create a common
225       // subroutine to do the real work.
226       /**
227        *  @if maint
228        *  @doctodo
229        *  @endif
230       */
231       int_type
232       _M_underflow_common(bool __bump);
233 
234       // [documentation is inherited]
235       virtual int_type
236       underflow();
237 
238       // [documentation is inherited]
239       virtual int_type
240       uflow();
241 
242       // [documentation is inherited]
243       virtual int_type
244       pbackfail(int_type __c = _Traits::eof());
245 
246       // NB: For what the standard expects of the overflow function,
247       // see _M_really_overflow(), below. Because basic_streambuf's
248       // sputc/sputn call overflow directly, and the complications of
249       // this implementation's setting of the initial pointers all
250       // equal to _M_buf when initializing, it seems essential to have
251       // this in actuality be a helper function that checks for the
252       // eccentricities of this implementation, and then call
253       // overflow() if indeed the buffer is full.
254 
255       // [documentation is inherited]
256       virtual int_type
257       overflow(int_type __c = _Traits::eof());
258 
259       // Stroustrup, 1998, p 648
260       // The overflow() function is called to transfer characters to the
261       // real output destination when the buffer is full. A call to
262       // overflow(c) outputs the contents of the buffer plus the
263       // character c.
264       // 27.5.2.4.5
265       // Consume some sequence of the characters in the pending sequence.
266       /**
267        *  @if maint
268        *  @doctodo
269        *  @endif
270       */
271       int_type
272       _M_really_overflow(int_type __c = _Traits::eof());
273 
274       // Convert internal byte sequence to external, char-based
275       // sequence via codecvt.
276       /**
277        *  @if maint
278        *  @doctodo
279        *  @endif
280       */
281       void
282       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
283 
284       /**
285        *  @brief  Manipulates the buffer.
286        *  @param  s  Pointer to a buffer area.
287        *  @param  n  Size of @a s.
288        *  @return  @c this
289        *
290        *  If no file has been opened, and both @a s and @a n are zero, then
291        *  the stream becomes unbuffered.  Otherwise, @c s is used as a
292        *  buffer; see
293        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
294        *  for more.
295       */
296       virtual __streambuf_type*
297       setbuf(char_type* __s, streamsize __n);
298 
299       // [documentation is inherited]
300       virtual pos_type
301       seekoff(off_type __off, ios_base::seekdir __way,
302 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
303 
304       // [documentation is inherited]
305       virtual pos_type
306       seekpos(pos_type __pos,
307 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
308 
309       // [documentation is inherited]
310       virtual int
311       sync()
312       {
313 	int __ret = 0;
314 	bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
315 
316 	// Make sure that the internal buffer resyncs its idea of
317 	// the file position with the external file.
318 	if (__testput)
319 	  {
320 	    // Need to restore current position after the write.
321 	    off_type __off = _M_out_cur - _M_out_end;
322 
323 	    // _M_file.sync() will be called within
324 	    if (traits_type::eq_int_type(_M_really_overflow(),
325 					 traits_type::eof()))
326 	      __ret = -1;
327 	    else if (__off)
328 	      _M_file.seekoff(__off, ios_base::cur);
329 	  }
330 	else
331 	  _M_file.sync();
332 
333 	_M_last_overflowed = false;
334 	return __ret;
335       }
336 
337       // [documentation is inherited]
338       virtual void
339       imbue(const locale& __loc);
340 
341       // [documentation is inherited]
342       virtual streamsize
343       xsgetn(char_type* __s, streamsize __n)
344       {
345 	streamsize __ret = 0;
346 	// Clear out pback buffer before going on to the real deal...
347 	if (_M_pback_init)
348 	  {
349 	    while (__ret < __n && _M_in_cur < _M_in_end)
350 	      {
351 		*__s = *_M_in_cur;
352 		++__ret;
353 		++__s;
354 		++_M_in_cur;
355 	      }
356 	    _M_pback_destroy();
357 	  }
358 	if (__ret < __n)
359 	  __ret += __streambuf_type::xsgetn(__s, __n - __ret);
360 	return __ret;
361       }
362 
363       // [documentation is inherited]
364       virtual streamsize
365       xsputn(const char_type* __s, streamsize __n)
366       {
367 	_M_pback_destroy();
368 	return __streambuf_type::xsputn(__s, __n);
369       }
370 
371       /**
372        *  @if maint
373        *  @doctodo
374        *  @endif
375       */
376       void
377       _M_output_unshift();
378 
379       // These three functions are used to clarify internal buffer
380       // maintenance. After an overflow, or after a seekoff call that
381       // started at beg or end, or possibly when the stream becomes
382       // unbuffered, and a myrid other obscure corner cases, the
383       // internal buffer does not truly reflect the contents of the
384       // external buffer. At this point, for whatever reason, it is in
385       // an indeterminate state.
386       /**
387        *  @if maint
388        *  @doctodo
389        *  @endif
390       */
391       void
392       _M_set_indeterminate(void)
393       {
394 	if (_M_mode & ios_base::in)
395 	  this->setg(_M_buf, _M_buf, _M_buf);
396 	if (_M_mode & ios_base::out)
397 	  this->setp(_M_buf, _M_buf);
398 	_M_filepos = _M_buf;
399       }
400 
401       /**
402        *  @if maint
403        *  @doctodo
404        *  @endif
405       */
406       void
407       _M_set_determinate(off_type __off)
408       {
409 	bool __testin = _M_mode & ios_base::in;
410 	bool __testout = _M_mode & ios_base::out;
411 	if (__testin)
412 	  this->setg(_M_buf, _M_buf, _M_buf + __off);
413 	if (__testout)
414 	  this->setp(_M_buf, _M_buf + __off);
415 	_M_filepos = _M_buf + __off;
416       }
417 
418       /**
419        *  @if maint
420        *  @doctodo
421        *  @endif
422       */
423       bool
424       _M_is_indeterminate(void)
425       {
426 	bool __ret = false;
427 	// Don't return true if unbuffered.
428 	if (_M_buf)
429 	  {
430 	    if (_M_mode & ios_base::in)
431 	      __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
432 	    if (_M_mode & ios_base::out)
433 	      __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
434 	  }
435 	return __ret;
436       }
437     };
438 
439   // Explicit specialization declarations, defined in src/fstream.cc.
440   template<>
441     basic_filebuf<char>::int_type
442     basic_filebuf<char>::_M_underflow_common(bool __bump);
443 
444  #ifdef _GLIBCPP_USE_WCHAR_T
445   template<>
446     basic_filebuf<wchar_t>::int_type
447     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
448  #endif
449 
450   // Generic definitions.
451   template <typename _CharT, typename _Traits>
452     typename basic_filebuf<_CharT, _Traits>::int_type
453     basic_filebuf<_CharT, _Traits>::underflow()
454     { return _M_underflow_common(false); }
455 
456   template <typename _CharT, typename _Traits>
457     typename basic_filebuf<_CharT, _Traits>::int_type
458     basic_filebuf<_CharT, _Traits>::uflow()
459     { return _M_underflow_common(true); }
460 
461 
462   // [27.8.1.5] Template class basic_ifstream
463   /**
464    *  @brief  Controlling input for files.
465    *
466    *  This class supports reading from named files, using the inherited
467    *  functions from std::basic_istream.  To control the associated
468    *  sequence, an instance of std::basic_filebuf is used, which this page
469    *  refers to as @c sb.
470   */
471   template<typename _CharT, typename _Traits>
472     class basic_ifstream : public basic_istream<_CharT, _Traits>
473     {
474     public:
475       // Types:
476       typedef _CharT 					char_type;
477       typedef _Traits 					traits_type;
478       typedef typename traits_type::int_type 		int_type;
479       typedef typename traits_type::pos_type 		pos_type;
480       typedef typename traits_type::off_type 		off_type;
481 
482       // Non-standard types:
483       typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
484       typedef basic_istream<char_type, traits_type>	__istream_type;
485 
486     private:
487       /**
488        *  @if maint
489        *  @doctodo
490        *  @endif
491       */
492       __filebuf_type	_M_filebuf;
493 
494     public:
495       // Constructors/Destructors:
496       /**
497        *  @brief  Default constructor.
498        *
499        *  Initializes @c sb using its default constructor, and passes
500        *  @c &sb to the base class initializer.  Does not open any files
501        *  (you haven't given it a filename to open).
502       */
503       basic_ifstream()
504       : __istream_type(NULL), _M_filebuf()
505       { this->init(&_M_filebuf); }
506 
507       /**
508        *  @brief  Create an input file stream.
509        *  @param  s  Null terminated string specifying the filename.
510        *  @param  mode  Open file in specified mode (see std::ios_base).
511        *
512        *  @c ios_base::in is automatically included in @a mode.
513        *
514        *  Tip:  When using std::string to hold the filename, you must use
515        *  .c_str() before passing it to this constructor.
516       */
517       explicit
518       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
519       : __istream_type(NULL), _M_filebuf()
520       {
521 	this->init(&_M_filebuf);
522 	this->open(__s, __mode);
523       }
524 
525       /**
526        *  @brief  The destructor does nothing.
527        *
528        *  The file is closed by the filebuf object, not the formatting
529        *  stream.
530       */
531       ~basic_ifstream()
532       { }
533 
534       // Members:
535       /**
536        *  @brief  Accessing the underlying buffer.
537        *  @return  The current basic_filebuf buffer.
538        *
539        *  This hides both signatures of std::basic_ios::rdbuf().
540       */
541       __filebuf_type*
542       rdbuf() const
543       { return const_cast<__filebuf_type*>(&_M_filebuf); }
544 
545       /**
546        *  @brief  Wrapper to test for an open file.
547        *  @return  @c rdbuf()->is_open()
548       */
549       bool
550       is_open() { return _M_filebuf.is_open(); }
551 
552       /**
553        *  @brief  Opens an external file.
554        *  @param  s  The name of the file.
555        *  @param  mode  The open mode flags.
556        *
557        *  Calls @c std::basic_filebuf::open(s,mode|in).  If that function
558        *  fails, @c failbit is set in the stream's error state.
559        *
560        *  Tip:  When using std::string to hold the filename, you must use
561        *  .c_str() before passing it to this constructor.
562       */
563       void
564       open(const char* __s, ios_base::openmode __mode = ios_base::in)
565       {
566 	if (!_M_filebuf.open(__s, __mode | ios_base::in))
567 	  this->setstate(ios_base::failbit);
568       }
569 
570       /**
571        *  @brief  Close the file.
572        *
573        *  Calls @c std::basic_filebuf::close().  If that function
574        *  fails, @c failbit is set in the stream's error state.
575       */
576       void
577       close()
578       {
579 	if (!_M_filebuf.close())
580 	  this->setstate(ios_base::failbit);
581       }
582     };
583 
584 
585   // [27.8.1.8] Template class basic_ofstream
586   /**
587    *  @brief  Controlling output for files.
588    *
589    *  This class supports reading from named files, using the inherited
590    *  functions from std::basic_ostream.  To control the associated
591    *  sequence, an instance of std::basic_filebuf is used, which this page
592    *  refers to as @c sb.
593   */
594   template<typename _CharT, typename _Traits>
595     class basic_ofstream : public basic_ostream<_CharT,_Traits>
596     {
597     public:
598       // Types:
599       typedef _CharT 					char_type;
600       typedef _Traits 					traits_type;
601       typedef typename traits_type::int_type 		int_type;
602       typedef typename traits_type::pos_type 		pos_type;
603       typedef typename traits_type::off_type 		off_type;
604 
605       // Non-standard types:
606       typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
607       typedef basic_ostream<char_type, traits_type>	__ostream_type;
608 
609     private:
610       /**
611        *  @if maint
612        *  @doctodo
613        *  @endif
614       */
615       __filebuf_type	_M_filebuf;
616 
617     public:
618       // Constructors:
619       /**
620        *  @brief  Default constructor.
621        *
622        *  Initializes @c sb using its default constructor, and passes
623        *  @c &sb to the base class initializer.  Does not open any files
624        *  (you haven't given it a filename to open).
625       */
626       basic_ofstream()
627       : __ostream_type(NULL), _M_filebuf()
628       { this->init(&_M_filebuf); }
629 
630       /**
631        *  @brief  Create an output file stream.
632        *  @param  s  Null terminated string specifying the filename.
633        *  @param  mode  Open file in specified mode (see std::ios_base).
634        *
635        *  @c ios_base::out|ios_base::trunc is automatically included in
636        *  @a mode.
637        *
638        *  Tip:  When using std::string to hold the filename, you must use
639        *  .c_str() before passing it to this constructor.
640       */
641       explicit
642       basic_ofstream(const char* __s,
643 		     ios_base::openmode __mode = ios_base::out|ios_base::trunc)
644       : __ostream_type(NULL), _M_filebuf()
645       {
646 	this->init(&_M_filebuf);
647 	this->open(__s, __mode);
648       }
649 
650       /**
651        *  @brief  The destructor does nothing.
652        *
653        *  The file is closed by the filebuf object, not the formatting
654        *  stream.
655       */
656       ~basic_ofstream()
657       { }
658 
659       // Members:
660       /**
661        *  @brief  Accessing the underlying buffer.
662        *  @return  The current basic_filebuf buffer.
663        *
664        *  This hides both signatures of std::basic_ios::rdbuf().
665       */
666       __filebuf_type*
667       rdbuf() const
668       { return const_cast<__filebuf_type*>(&_M_filebuf); }
669 
670       /**
671        *  @brief  Wrapper to test for an open file.
672        *  @return  @c rdbuf()->is_open()
673       */
674       bool
675       is_open() { return _M_filebuf.is_open(); }
676 
677       /**
678        *  @brief  Opens an external file.
679        *  @param  s  The name of the file.
680        *  @param  mode  The open mode flags.
681        *
682        *  Calls @c std::basic_filebuf::open(s,mode|out|trunc).  If that
683        *  function fails, @c failbit is set in the stream's error state.
684        *
685        *  Tip:  When using std::string to hold the filename, you must use
686        *  .c_str() before passing it to this constructor.
687       */
688       void
689       open(const char* __s,
690 	   ios_base::openmode __mode = ios_base::out | ios_base::trunc)
691       {
692 	if (!_M_filebuf.open(__s, __mode | ios_base::out))
693 	  this->setstate(ios_base::failbit);
694       }
695 
696       /**
697        *  @brief  Close the file.
698        *
699        *  Calls @c std::basic_filebuf::close().  If that function
700        *  fails, @c failbit is set in the stream's error state.
701       */
702       void
703       close()
704       {
705 	if (!_M_filebuf.close())
706 	  this->setstate(ios_base::failbit);
707       }
708     };
709 
710 
711   // [27.8.1.11] Template class basic_fstream
712   /**
713    *  @brief  Controlling intput and output for files.
714    *
715    *  This class supports reading from and writing to named files, using
716    *  the inherited functions from std::basic_iostream.  To control the
717    *  associated sequence, an instance of std::basic_filebuf is used, which
718    *  this page refers to as @c sb.
719   */
720   template<typename _CharT, typename _Traits>
721     class basic_fstream : public basic_iostream<_CharT, _Traits>
722     {
723     public:
724       // Types:
725       typedef _CharT 					char_type;
726       typedef _Traits 					traits_type;
727       typedef typename traits_type::int_type 		int_type;
728       typedef typename traits_type::pos_type 		pos_type;
729       typedef typename traits_type::off_type 		off_type;
730 
731       // Non-standard types:
732       typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
733       typedef basic_ios<char_type, traits_type>		__ios_type;
734       typedef basic_iostream<char_type, traits_type>	__iostream_type;
735 
736     private:
737       /**
738        *  @if maint
739        *  @doctodo
740        *  @endif
741       */
742       __filebuf_type	_M_filebuf;
743 
744     public:
745       // Constructors/destructor:
746       /**
747        *  @brief  Default constructor.
748        *
749        *  Initializes @c sb using its default constructor, and passes
750        *  @c &sb to the base class initializer.  Does not open any files
751        *  (you haven't given it a filename to open).
752       */
753       basic_fstream()
754       : __iostream_type(NULL), _M_filebuf()
755       { this->init(&_M_filebuf); }
756 
757       /**
758        *  @brief  Create an input/output file stream.
759        *  @param  s  Null terminated string specifying the filename.
760        *  @param  mode  Open file in specified mode (see std::ios_base).
761        *
762        *  Tip:  When using std::string to hold the filename, you must use
763        *  .c_str() before passing it to this constructor.
764       */
765       explicit
766       basic_fstream(const char* __s,
767 		    ios_base::openmode __mode = ios_base::in | ios_base::out)
768       : __iostream_type(NULL), _M_filebuf()
769       {
770 	this->init(&_M_filebuf);
771 	this->open(__s, __mode);
772       }
773 
774       /**
775        *  @brief  The destructor does nothing.
776        *
777        *  The file is closed by the filebuf object, not the formatting
778        *  stream.
779       */
780       ~basic_fstream()
781       { }
782 
783       // Members:
784       /**
785        *  @brief  Accessing the underlying buffer.
786        *  @return  The current basic_filebuf buffer.
787        *
788        *  This hides both signatures of std::basic_ios::rdbuf().
789       */
790       __filebuf_type*
791       rdbuf() const
792       { return const_cast<__filebuf_type*>(&_M_filebuf); }
793 
794       /**
795        *  @brief  Wrapper to test for an open file.
796        *  @return  @c rdbuf()->is_open()
797       */
798       bool
799       is_open() { return _M_filebuf.is_open(); }
800 
801       /**
802        *  @brief  Opens an external file.
803        *  @param  s  The name of the file.
804        *  @param  mode  The open mode flags.
805        *
806        *  Calls @c std::basic_filebuf::open(s,mode).  If that
807        *  function fails, @c failbit is set in the stream's error state.
808        *
809        *  Tip:  When using std::string to hold the filename, you must use
810        *  .c_str() before passing it to this constructor.
811       */
812       void
813       open(const char* __s,
814 	   ios_base::openmode __mode = ios_base::in | ios_base::out)
815       {
816 	if (!_M_filebuf.open(__s, __mode))
817 	  setstate(ios_base::failbit);
818       }
819 
820       /**
821        *  @brief  Close the file.
822        *
823        *  Calls @c std::basic_filebuf::close().  If that function
824        *  fails, @c failbit is set in the stream's error state.
825       */
826       void
827       close()
828       {
829 	if (!_M_filebuf.close())
830 	  setstate(ios_base::failbit);
831       }
832     };
833 } // namespace std
834 
835 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
836 # define export
837 #endif
838 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
839 # include <bits/fstream.tcc>
840 #endif
841 
842 #endif
843