std_fstream.h revision 132720
197403Sobrien// File based streams -*- C++ -*-
297403Sobrien
3110614Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
1997403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien//
3297403Sobrien// ISO C++ 14882: 27.8  File-based streams
3397403Sobrien//
3497403Sobrien
3597403Sobrien/** @file fstream
3697403Sobrien *  This is a Standard C++ Library header.  You should @c #include this header
3797403Sobrien *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
3897403Sobrien */
3997403Sobrien
40132720Skan#ifndef _GLIBCXX_FSTREAM
41132720Skan#define _GLIBCXX_FSTREAM 1
4297403Sobrien
4397403Sobrien#pragma GCC system_header
4497403Sobrien
4597403Sobrien#include <istream>
4697403Sobrien#include <ostream>
4797403Sobrien#include <locale>	// For codecvt
48132720Skan#include <cstdio>       // For SEEK_SET, SEEK_CUR, SEEK_END, BUFSIZ
4997403Sobrien#include <bits/basic_file.h>
5097403Sobrien#include <bits/gthr.h>
5197403Sobrien
5297403Sobriennamespace std
5397403Sobrien{
54117397Skan  // [27.8.1.1] template class basic_filebuf
55117397Skan  /**
56117397Skan   *  @brief  The actual work of input and output (for files).
57117397Skan   *
58117397Skan   *  This class associates both its input and output sequence with an
59117397Skan   *  external disk file, and maintains a joint file position for both
60117397Skan   *  sequences.  Many of its sematics are described in terms of similar
61117397Skan   *  behavior in the Standard C Library's @c FILE streams.
62117397Skan  */
63132720Skan  // Requirements on traits_type, specific to this class:
64132720Skan  // traits_type::pos_type must be fpos<traits_type::state_type>
65132720Skan  // traits_type::off_type must be streamoff
66132720Skan  // traits_type::state_type must be Assignable and DefaultConstructable,
67132720Skan  // and traits_type::state_type() must be the initial state for codecvt.
6897403Sobrien  template<typename _CharT, typename _Traits>
6997403Sobrien    class basic_filebuf : public basic_streambuf<_CharT, _Traits>
7097403Sobrien    {
7197403Sobrien    public:
7297403Sobrien      // Types:
7397403Sobrien      typedef _CharT                     	        char_type;
7497403Sobrien      typedef _Traits                    	        traits_type;
7597403Sobrien      typedef typename traits_type::int_type 		int_type;
7697403Sobrien      typedef typename traits_type::pos_type 		pos_type;
7797403Sobrien      typedef typename traits_type::off_type 		off_type;
7897403Sobrien
79117397Skan      //@{
80117397Skan      /**
81117397Skan       *  @if maint
82117397Skan       *  @doctodo
83117397Skan       *  @endif
84117397Skan      */
8597403Sobrien      typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
8697403Sobrien      typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
8797403Sobrien      typedef __basic_file<char>		        __file_type;
8897403Sobrien      typedef typename traits_type::state_type          __state_type;
8997403Sobrien      typedef codecvt<char_type, char, __state_type>    __codecvt_type;
90117397Skan      //@}
9197403Sobrien
9297403Sobrien      friend class ios_base; // For sync_with_stdio.
9397403Sobrien
9497403Sobrien    protected:
9597403Sobrien      // Data Members:
9697403Sobrien      // MT lock inherited from libio or other low-level io library.
97117397Skan      /**
98117397Skan       *  @if maint
99117397Skan       *  @doctodo
100117397Skan       *  @endif
101117397Skan      */
10297403Sobrien      __c_lock          	_M_lock;
10397403Sobrien
10497403Sobrien      // External buffer.
105117397Skan      /**
106117397Skan       *  @if maint
107117397Skan       *  @doctodo
108117397Skan       *  @endif
109117397Skan      */
11097403Sobrien      __file_type 		_M_file;
11197403Sobrien
112117397Skan      /**
113117397Skan       *  @if maint
114132720Skan       *  Place to stash in || out || in | out settings for current filebuf.
115132720Skan       *  @endif
116132720Skan      */
117132720Skan      ios_base::openmode 	_M_mode;
118132720Skan
119132720Skan      // Beginning state type for codecvt.
120132720Skan      /**
121132720Skan       *  @if maint
122117397Skan       *  @doctodo
123117397Skan       *  @endif
124117397Skan      */
12597403Sobrien      __state_type 		_M_state_beg;
12697403Sobrien
127132720Skan      // During output, the state that corresponds to pptr(),
128132720Skan      // during input, the state that corresponds to egptr() and
129132720Skan      // _M_ext_next.
130132720Skan      /**
131132720Skan       *  @if maint
132132720Skan       *  @doctodo
133132720Skan       *  @endif
134132720Skan      */
135132720Skan      __state_type		_M_state_cur;
136132720Skan
137132720Skan      // Not used for output. During input, the state that corresponds
138132720Skan      // to eback() and _M_ext_buf.
139132720Skan      /**
140132720Skan       *  @if maint
141132720Skan       *  @doctodo
142132720Skan       *  @endif
143132720Skan      */
144132720Skan      __state_type		_M_state_last;
145132720Skan
146132720Skan      /**
147132720Skan       *  @if maint
148132720Skan       *  Pointer to the beginning of internal buffer.
149132720Skan       *  @endif
150132720Skan      */
151132720Skan      char_type*		_M_buf;
152132720Skan
153132720Skan      /**
154132720Skan       *  @if maint
155132720Skan       *  Actual size of internal buffer. This number is equal to the size
156132720Skan       *  of the put area + 1 position, reserved for the overflow char of
157132720Skan       *  a full area.
158132720Skan       *  @endif
159132720Skan      */
160132720Skan      size_t			_M_buf_size;
161132720Skan
16297403Sobrien      // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
163117397Skan      /**
164117397Skan       *  @if maint
165117397Skan       *  @doctodo
166117397Skan       *  @endif
167117397Skan      */
16897403Sobrien      bool			_M_buf_allocated;
16997403Sobrien
170117397Skan      /**
171117397Skan       *  @if maint
172132720Skan       *  _M_reading == false && _M_writing == false for 'uncommitted' mode;
173132720Skan       *  _M_reading == true for 'read' mode;
174132720Skan       *  _M_writing == true for 'write' mode;
175132720Skan       *
176132720Skan       *  NB: _M_reading == true && _M_writing == true is unused.
177117397Skan       *  @endif
178132720Skan      */
179132720Skan      bool                      _M_reading;
180132720Skan      bool                      _M_writing;
181132720Skan
182132720Skan      //@{
183132720Skan      /**
184132720Skan       *  @if maint
185132720Skan       *  Necessary bits for putback buffer management.
186132720Skan       *
187132720Skan       *  @note pbacks of over one character are not currently supported.
188132720Skan       *  @endif
189117397Skan      */
190132720Skan      char_type			_M_pback;
191132720Skan      char_type*		_M_pback_cur_save;
192132720Skan      char_type*		_M_pback_end_save;
193132720Skan      bool			_M_pback_init;
194132720Skan      //@}
19597403Sobrien
196132720Skan      // Cached codecvt facet.
197132720Skan      const __codecvt_type* 	_M_codecvt;
198132720Skan
199132720Skan      /**
200132720Skan       *  @if maint
201132720Skan       *  Buffer for external characters. Used for input when
202132720Skan       *  codecvt::always_noconv() == false. When valid, this corresponds
203132720Skan       *  to eback().
204132720Skan       *  @endif
205132720Skan      */
206132720Skan      char*			_M_ext_buf;
207132720Skan
208132720Skan      /**
209132720Skan       *  @if maint
210132720Skan       *  Size of buffer held by _M_ext_buf.
211132720Skan       *  @endif
212132720Skan      */
213132720Skan      streamsize		_M_ext_buf_size;
214132720Skan
215132720Skan      /**
216132720Skan       *  @if maint
217132720Skan       *  Pointers into the buffer held by _M_ext_buf that delimit a
218132720Skan       *  subsequence of bytes that have been read but not yet converted.
219132720Skan       *  When valid, _M_ext_next corresponds to egptr().
220132720Skan       *  @endif
221132720Skan      */
222132720Skan      const char*		_M_ext_next;
223132720Skan      char*			_M_ext_end;
224132720Skan
225132720Skan      /**
226132720Skan       *  @if maint
227132720Skan       *  Initializes pback buffers, and moves normal buffers to safety.
228132720Skan       *  Assumptions:
229132720Skan       *  _M_in_cur has already been moved back
230132720Skan       *  @endif
231132720Skan      */
232132720Skan      void
233132720Skan      _M_create_pback()
234132720Skan      {
235132720Skan	if (!_M_pback_init)
236132720Skan	  {
237132720Skan	    _M_pback_cur_save = this->gptr();
238132720Skan	    _M_pback_end_save = this->egptr();
239132720Skan	    this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
240132720Skan	    _M_pback_init = true;
241132720Skan	  }
242132720Skan      }
243132720Skan
244132720Skan      /**
245132720Skan       *  @if maint
246132720Skan       *  Deactivates pback buffer contents, and restores normal buffer.
247132720Skan       *  Assumptions:
248132720Skan       *  The pback buffer has only moved forward.
249132720Skan       *  @endif
250132720Skan      */
251132720Skan      void
252132720Skan      _M_destroy_pback() throw()
253132720Skan      {
254132720Skan	if (_M_pback_init)
255132720Skan	  {
256132720Skan	    // Length _M_in_cur moved in the pback buffer.
257132720Skan	    _M_pback_cur_save += this->gptr() != this->eback();
258132720Skan	    this->setg(this->_M_buf, _M_pback_cur_save, _M_pback_end_save);
259132720Skan	    _M_pback_init = false;
260132720Skan	  }
261132720Skan      }
262132720Skan
26397403Sobrien    public:
26497403Sobrien      // Constructors/destructor:
265117397Skan      /**
266117397Skan       *  @brief  Does not open any files.
267117397Skan       *
268117397Skan       *  The default constructor initializes the parent class using its
269117397Skan       *  own default ctor.
270117397Skan      */
27197403Sobrien      basic_filebuf();
27297403Sobrien
273117397Skan      /**
274117397Skan       *  @brief  The destructor closes the file first.
275117397Skan      */
27697403Sobrien      virtual
27797403Sobrien      ~basic_filebuf()
278132720Skan      { this->close(); }
27997403Sobrien
28097403Sobrien      // Members:
281117397Skan      /**
282117397Skan       *  @brief  Returns true if the external file is open.
283117397Skan      */
28497403Sobrien      bool
285117397Skan      is_open() const throw() { return _M_file.is_open(); }
28697403Sobrien
287117397Skan      /**
288117397Skan       *  @brief  Opens an external file.
289117397Skan       *  @param  s  The name of the file.
290117397Skan       *  @param  mode  The open mode flags.
291117397Skan       *  @return  @c this on success, NULL on failure
292117397Skan       *
293117397Skan       *  If a file is already open, this function immediately fails.
294117397Skan       *  Otherwise it tries to open the file named @a s using the flags
295117397Skan       *  given in @a mode.
296117397Skan       *
297117397Skan       *  [Table 92 gives the relation between openmode combinations and the
298117397Skan       *  equivalent fopen() flags, but the table has not been copied yet.]
299117397Skan      */
30097403Sobrien      __filebuf_type*
30197403Sobrien      open(const char* __s, ios_base::openmode __mode);
30297403Sobrien
303117397Skan      /**
304117397Skan       *  @brief  Closes the currently associated file.
305117397Skan       *  @return  @c this on success, NULL on failure
306117397Skan       *
307117397Skan       *  If no file is currently open, this function immediately fails.
308117397Skan       *
309117397Skan       *  If a "put buffer area" exists, @c overflow(eof) is called to flush
310117397Skan       *  all the characters.  The file is then closed.
311117397Skan       *
312117397Skan       *  If any operations fail, this function also fails.
313117397Skan      */
31497403Sobrien      __filebuf_type*
315117397Skan      close() throw();
31697403Sobrien
31797403Sobrien    protected:
318117397Skan      /**
319117397Skan       *  @if maint
320117397Skan       *  @doctodo
321117397Skan       *  @endif
322117397Skan      */
32397403Sobrien      void
32497403Sobrien      _M_allocate_internal_buffer();
32597403Sobrien
326117397Skan      /**
327117397Skan       *  @if maint
328117397Skan       *  @doctodo
329117397Skan       *  @endif
330117397Skan      */
33197403Sobrien      void
332117397Skan      _M_destroy_internal_buffer() throw();
33397403Sobrien
334117397Skan      // [27.8.1.4] overridden virtual functions
335117397Skan      // [documentation is inherited]
33697403Sobrien      virtual streamsize
33797403Sobrien      showmanyc();
33897403Sobrien
33997403Sobrien      // Stroustrup, 1998, p. 628
34097403Sobrien      // underflow() and uflow() functions are called to get the next
34197403Sobrien      // charater from the real input source when the buffer is empty.
34297403Sobrien      // Buffered input uses underflow()
34397403Sobrien
344117397Skan      // [documentation is inherited]
34597403Sobrien      virtual int_type
346110614Skan      underflow();
34797403Sobrien
348117397Skan      // [documentation is inherited]
34997403Sobrien      virtual int_type
35097403Sobrien      pbackfail(int_type __c = _Traits::eof());
35197403Sobrien
35297403Sobrien      // Stroustrup, 1998, p 648
35397403Sobrien      // The overflow() function is called to transfer characters to the
35497403Sobrien      // real output destination when the buffer is full. A call to
35597403Sobrien      // overflow(c) outputs the contents of the buffer plus the
35697403Sobrien      // character c.
35797403Sobrien      // 27.5.2.4.5
35897403Sobrien      // Consume some sequence of the characters in the pending sequence.
359117397Skan      /**
360117397Skan       *  @if maint
361117397Skan       *  @doctodo
362117397Skan       *  @endif
363117397Skan      */
364132720Skan      virtual int_type
365132720Skan      overflow(int_type __c = _Traits::eof());
36697403Sobrien
36797403Sobrien      // Convert internal byte sequence to external, char-based
36897403Sobrien      // sequence via codecvt.
369117397Skan      /**
370117397Skan       *  @if maint
371117397Skan       *  @doctodo
372117397Skan       *  @endif
373117397Skan      */
374132720Skan      bool
375132720Skan      _M_convert_to_external(char_type*, streamsize);
37697403Sobrien
377117397Skan      /**
378117397Skan       *  @brief  Manipulates the buffer.
379117397Skan       *  @param  s  Pointer to a buffer area.
380117397Skan       *  @param  n  Size of @a s.
381117397Skan       *  @return  @c this
382117397Skan       *
383117397Skan       *  If no file has been opened, and both @a s and @a n are zero, then
384117397Skan       *  the stream becomes unbuffered.  Otherwise, @c s is used as a
385117397Skan       *  buffer; see
386117397Skan       *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
387117397Skan       *  for more.
388117397Skan      */
38997403Sobrien      virtual __streambuf_type*
39097403Sobrien      setbuf(char_type* __s, streamsize __n);
39197403Sobrien
392117397Skan      // [documentation is inherited]
39397403Sobrien      virtual pos_type
39497403Sobrien      seekoff(off_type __off, ios_base::seekdir __way,
39597403Sobrien	      ios_base::openmode __mode = ios_base::in | ios_base::out);
39697403Sobrien
397117397Skan      // [documentation is inherited]
39897403Sobrien      virtual pos_type
39997403Sobrien      seekpos(pos_type __pos,
40097403Sobrien	      ios_base::openmode __mode = ios_base::in | ios_base::out);
40197403Sobrien
402132720Skan      // Common code for seekoff and seekpos
403132720Skan      /**
404132720Skan       *  @if maint
405132720Skan       *  @doctodo
406132720Skan       *  @endif
407132720Skan      */
408132720Skan      pos_type
409132720Skan      _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
410132720Skan
411117397Skan      // [documentation is inherited]
41297403Sobrien      virtual int
413132720Skan      sync();
41497403Sobrien
415117397Skan      // [documentation is inherited]
41697403Sobrien      virtual void
41797403Sobrien      imbue(const locale& __loc);
41897403Sobrien
419117397Skan      // [documentation is inherited]
42097403Sobrien      virtual streamsize
42197403Sobrien      xsgetn(char_type* __s, streamsize __n)
42297403Sobrien      {
423132720Skan	// Clear out pback buffer before going on to the real deal...
42497403Sobrien	streamsize __ret = 0;
425132720Skan	if (this->_M_pback_init)
42697403Sobrien	  {
427132720Skan	    if (__n && this->gptr() == this->eback())
42897403Sobrien	      {
429132720Skan		*__s++ = *this->gptr();
430132720Skan		this->gbump(1);
431132720Skan		__ret = 1;
43297403Sobrien	      }
433132720Skan	    _M_destroy_pback();
43497403Sobrien	  }
43597403Sobrien	if (__ret < __n)
43697403Sobrien	  __ret += __streambuf_type::xsgetn(__s, __n - __ret);
43797403Sobrien	return __ret;
43897403Sobrien      }
43997403Sobrien
440117397Skan      // [documentation is inherited]
44197403Sobrien      virtual streamsize
442132720Skan      xsputn(const char_type* __s, streamsize __n);
44397403Sobrien
444132720Skan      // Flushes output buffer, then writes unshift sequence.
445117397Skan      /**
446117397Skan       *  @if maint
447117397Skan       *  @doctodo
448117397Skan       *  @endif
449117397Skan      */
450132720Skan      bool
451132720Skan      _M_terminate_output();
45297403Sobrien
453117397Skan      /**
454132720Skan       *  @if maint
455132720Skan       *  This function sets the pointers of the internal buffer, both get
456132720Skan       *  and put areas. Typically:
457132720Skan       *
458132720Skan       *   __off == egptr() - eback() upon underflow/uflow ('read' mode);
459132720Skan       *   __off == 0 upon overflow ('write' mode);
460132720Skan       *   __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode).
461132720Skan       *
462132720Skan       *  NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
463132720Skan       *  reflects the actual allocated memory and the last cell is reserved
464132720Skan       *  for the overflow char of a full put area.
465117397Skan       *  @endif
466117397Skan      */
46797403Sobrien      void
468132720Skan      _M_set_buffer(streamsize __off)
46997403Sobrien      {
470132720Skan 	const bool __testin = this->_M_mode & ios_base::in;
471132720Skan 	const bool __testout = this->_M_mode & ios_base::out;
472132720Skan
473132720Skan	if (__testin && __off > 0)
474132720Skan	  this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
475132720Skan	else
476132720Skan	  this->setg(this->_M_buf, this->_M_buf, this->_M_buf);
47797403Sobrien
478132720Skan	if (__testout && __off == 0 && this->_M_buf_size > 1 )
479132720Skan	  this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1);
480132720Skan	else
481132720Skan	  this->setp(NULL, NULL);
48297403Sobrien      }
48397403Sobrien    };
48497403Sobrien
485117397Skan  // [27.8.1.5] Template class basic_ifstream
48697403Sobrien  /**
487117397Skan   *  @brief  Controlling input for files.
488117397Skan   *
489117397Skan   *  This class supports reading from named files, using the inherited
490117397Skan   *  functions from std::basic_istream.  To control the associated
491117397Skan   *  sequence, an instance of std::basic_filebuf is used, which this page
492117397Skan   *  refers to as @c sb.
49397403Sobrien  */
49497403Sobrien  template<typename _CharT, typename _Traits>
49597403Sobrien    class basic_ifstream : public basic_istream<_CharT, _Traits>
49697403Sobrien    {
49797403Sobrien    public:
49897403Sobrien      // Types:
49997403Sobrien      typedef _CharT 					char_type;
50097403Sobrien      typedef _Traits 					traits_type;
50197403Sobrien      typedef typename traits_type::int_type 		int_type;
50297403Sobrien      typedef typename traits_type::pos_type 		pos_type;
50397403Sobrien      typedef typename traits_type::off_type 		off_type;
50497403Sobrien
50597403Sobrien      // Non-standard types:
50697403Sobrien      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
50797403Sobrien      typedef basic_istream<char_type, traits_type>	__istream_type;
50897403Sobrien
50997403Sobrien    private:
510117397Skan      /**
511117397Skan       *  @if maint
512117397Skan       *  @doctodo
513117397Skan       *  @endif
514117397Skan      */
51597403Sobrien      __filebuf_type	_M_filebuf;
51697403Sobrien
51797403Sobrien    public:
518117397Skan      // Constructors/Destructors:
519117397Skan      /**
520117397Skan       *  @brief  Default constructor.
521117397Skan       *
522117397Skan       *  Initializes @c sb using its default constructor, and passes
523117397Skan       *  @c &sb to the base class initializer.  Does not open any files
524117397Skan       *  (you haven't given it a filename to open).
525117397Skan      */
526132720Skan      basic_ifstream() : __istream_type(), _M_filebuf()
52797403Sobrien      { this->init(&_M_filebuf); }
52897403Sobrien
52997403Sobrien      /**
530117397Skan       *  @brief  Create an input file stream.
531117397Skan       *  @param  s  Null terminated string specifying the filename.
53297403Sobrien       *  @param  mode  Open file in specified mode (see std::ios_base).
53397403Sobrien       *
534117397Skan       *  @c ios_base::in is automatically included in @a mode.
535117397Skan       *
53697403Sobrien       *  Tip:  When using std::string to hold the filename, you must use
53797403Sobrien       *  .c_str() before passing it to this constructor.
53897403Sobrien      */
53997403Sobrien      explicit
54097403Sobrien      basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
541132720Skan      : __istream_type(), _M_filebuf()
54297403Sobrien      {
54397403Sobrien	this->init(&_M_filebuf);
54497403Sobrien	this->open(__s, __mode);
54597403Sobrien      }
54697403Sobrien
547117397Skan      /**
548117397Skan       *  @brief  The destructor does nothing.
549117397Skan       *
550117397Skan       *  The file is closed by the filebuf object, not the formatting
551117397Skan       *  stream.
552117397Skan      */
55397403Sobrien      ~basic_ifstream()
55497403Sobrien      { }
55597403Sobrien
55697403Sobrien      // Members:
55797403Sobrien      /**
558117397Skan       *  @brief  Accessing the underlying buffer.
559117397Skan       *  @return  The current basic_filebuf buffer.
560117397Skan       *
561117397Skan       *  This hides both signatures of std::basic_ios::rdbuf().
56297403Sobrien      */
56397403Sobrien      __filebuf_type*
56497403Sobrien      rdbuf() const
56597403Sobrien      { return const_cast<__filebuf_type*>(&_M_filebuf); }
56697403Sobrien
567117397Skan      /**
568117397Skan       *  @brief  Wrapper to test for an open file.
569117397Skan       *  @return  @c rdbuf()->is_open()
570117397Skan      */
57197403Sobrien      bool
57297403Sobrien      is_open() { return _M_filebuf.is_open(); }
57397403Sobrien
574117397Skan      /**
575117397Skan       *  @brief  Opens an external file.
576117397Skan       *  @param  s  The name of the file.
577117397Skan       *  @param  mode  The open mode flags.
578117397Skan       *
579117397Skan       *  Calls @c std::basic_filebuf::open(s,mode|in).  If that function
580117397Skan       *  fails, @c failbit is set in the stream's error state.
581117397Skan       *
582117397Skan       *  Tip:  When using std::string to hold the filename, you must use
583117397Skan       *  .c_str() before passing it to this constructor.
584117397Skan      */
58597403Sobrien      void
58697403Sobrien      open(const char* __s, ios_base::openmode __mode = ios_base::in)
58797403Sobrien      {
58897403Sobrien	if (!_M_filebuf.open(__s, __mode | ios_base::in))
58997403Sobrien	  this->setstate(ios_base::failbit);
59097403Sobrien      }
59197403Sobrien
592117397Skan      /**
593117397Skan       *  @brief  Close the file.
594117397Skan       *
595117397Skan       *  Calls @c std::basic_filebuf::close().  If that function
596117397Skan       *  fails, @c failbit is set in the stream's error state.
597117397Skan      */
59897403Sobrien      void
59997403Sobrien      close()
60097403Sobrien      {
60197403Sobrien	if (!_M_filebuf.close())
60297403Sobrien	  this->setstate(ios_base::failbit);
60397403Sobrien      }
60497403Sobrien    };
60597403Sobrien
60697403Sobrien
607117397Skan  // [27.8.1.8] Template class basic_ofstream
60897403Sobrien  /**
609117397Skan   *  @brief  Controlling output for files.
610117397Skan   *
611117397Skan   *  This class supports reading from named files, using the inherited
612117397Skan   *  functions from std::basic_ostream.  To control the associated
613117397Skan   *  sequence, an instance of std::basic_filebuf is used, which this page
614117397Skan   *  refers to as @c sb.
61597403Sobrien  */
61697403Sobrien  template<typename _CharT, typename _Traits>
61797403Sobrien    class basic_ofstream : public basic_ostream<_CharT,_Traits>
61897403Sobrien    {
61997403Sobrien    public:
62097403Sobrien      // Types:
62197403Sobrien      typedef _CharT 					char_type;
62297403Sobrien      typedef _Traits 					traits_type;
62397403Sobrien      typedef typename traits_type::int_type 		int_type;
62497403Sobrien      typedef typename traits_type::pos_type 		pos_type;
62597403Sobrien      typedef typename traits_type::off_type 		off_type;
62697403Sobrien
62797403Sobrien      // Non-standard types:
62897403Sobrien      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
62997403Sobrien      typedef basic_ostream<char_type, traits_type>	__ostream_type;
63097403Sobrien
63197403Sobrien    private:
632117397Skan      /**
633117397Skan       *  @if maint
634117397Skan       *  @doctodo
635117397Skan       *  @endif
636117397Skan      */
63797403Sobrien      __filebuf_type	_M_filebuf;
63897403Sobrien
63997403Sobrien    public:
64097403Sobrien      // Constructors:
641117397Skan      /**
642117397Skan       *  @brief  Default constructor.
643117397Skan       *
644117397Skan       *  Initializes @c sb using its default constructor, and passes
645117397Skan       *  @c &sb to the base class initializer.  Does not open any files
646117397Skan       *  (you haven't given it a filename to open).
647117397Skan      */
648132720Skan      basic_ofstream(): __ostream_type(), _M_filebuf()
64997403Sobrien      { this->init(&_M_filebuf); }
65097403Sobrien
65197403Sobrien      /**
652117397Skan       *  @brief  Create an output file stream.
653117397Skan       *  @param  s  Null terminated string specifying the filename.
65497403Sobrien       *  @param  mode  Open file in specified mode (see std::ios_base).
65597403Sobrien       *
656117397Skan       *  @c ios_base::out|ios_base::trunc is automatically included in
657117397Skan       *  @a mode.
658117397Skan       *
65997403Sobrien       *  Tip:  When using std::string to hold the filename, you must use
66097403Sobrien       *  .c_str() before passing it to this constructor.
66197403Sobrien      */
66297403Sobrien      explicit
66397403Sobrien      basic_ofstream(const char* __s,
66497403Sobrien		     ios_base::openmode __mode = ios_base::out|ios_base::trunc)
665132720Skan      : __ostream_type(), _M_filebuf()
66697403Sobrien      {
66797403Sobrien	this->init(&_M_filebuf);
66897403Sobrien	this->open(__s, __mode);
66997403Sobrien      }
67097403Sobrien
671117397Skan      /**
672117397Skan       *  @brief  The destructor does nothing.
673117397Skan       *
674117397Skan       *  The file is closed by the filebuf object, not the formatting
675117397Skan       *  stream.
676117397Skan      */
67797403Sobrien      ~basic_ofstream()
67897403Sobrien      { }
67997403Sobrien
68097403Sobrien      // Members:
68197403Sobrien      /**
682117397Skan       *  @brief  Accessing the underlying buffer.
683117397Skan       *  @return  The current basic_filebuf buffer.
684117397Skan       *
685117397Skan       *  This hides both signatures of std::basic_ios::rdbuf().
68697403Sobrien      */
68797403Sobrien      __filebuf_type*
68897403Sobrien      rdbuf() const
68997403Sobrien      { return const_cast<__filebuf_type*>(&_M_filebuf); }
69097403Sobrien
69197403Sobrien      /**
692117397Skan       *  @brief  Wrapper to test for an open file.
693117397Skan       *  @return  @c rdbuf()->is_open()
69497403Sobrien      */
69597403Sobrien      bool
69697403Sobrien      is_open() { return _M_filebuf.is_open(); }
69797403Sobrien
69897403Sobrien      /**
699117397Skan       *  @brief  Opens an external file.
700117397Skan       *  @param  s  The name of the file.
701117397Skan       *  @param  mode  The open mode flags.
70297403Sobrien       *
703117397Skan       *  Calls @c std::basic_filebuf::open(s,mode|out|trunc).  If that
704117397Skan       *  function fails, @c failbit is set in the stream's error state.
705117397Skan       *
70697403Sobrien       *  Tip:  When using std::string to hold the filename, you must use
70797403Sobrien       *  .c_str() before passing it to this constructor.
70897403Sobrien      */
70997403Sobrien      void
71097403Sobrien      open(const char* __s,
71197403Sobrien	   ios_base::openmode __mode = ios_base::out | ios_base::trunc)
71297403Sobrien      {
71397403Sobrien	if (!_M_filebuf.open(__s, __mode | ios_base::out))
71497403Sobrien	  this->setstate(ios_base::failbit);
71597403Sobrien      }
71697403Sobrien
717117397Skan      /**
718117397Skan       *  @brief  Close the file.
719117397Skan       *
720117397Skan       *  Calls @c std::basic_filebuf::close().  If that function
721117397Skan       *  fails, @c failbit is set in the stream's error state.
722117397Skan      */
72397403Sobrien      void
72497403Sobrien      close()
72597403Sobrien      {
72697403Sobrien	if (!_M_filebuf.close())
72797403Sobrien	  this->setstate(ios_base::failbit);
72897403Sobrien      }
72997403Sobrien    };
73097403Sobrien
73197403Sobrien
732117397Skan  // [27.8.1.11] Template class basic_fstream
73397403Sobrien  /**
734117397Skan   *  @brief  Controlling intput and output for files.
735117397Skan   *
736117397Skan   *  This class supports reading from and writing to named files, using
737117397Skan   *  the inherited functions from std::basic_iostream.  To control the
738117397Skan   *  associated sequence, an instance of std::basic_filebuf is used, which
739117397Skan   *  this page refers to as @c sb.
74097403Sobrien  */
74197403Sobrien  template<typename _CharT, typename _Traits>
74297403Sobrien    class basic_fstream : public basic_iostream<_CharT, _Traits>
74397403Sobrien    {
74497403Sobrien    public:
74597403Sobrien      // Types:
74697403Sobrien      typedef _CharT 					char_type;
74797403Sobrien      typedef _Traits 					traits_type;
74897403Sobrien      typedef typename traits_type::int_type 		int_type;
74997403Sobrien      typedef typename traits_type::pos_type 		pos_type;
75097403Sobrien      typedef typename traits_type::off_type 		off_type;
75197403Sobrien
75297403Sobrien      // Non-standard types:
75397403Sobrien      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
75497403Sobrien      typedef basic_ios<char_type, traits_type>		__ios_type;
75597403Sobrien      typedef basic_iostream<char_type, traits_type>	__iostream_type;
75697403Sobrien
75797403Sobrien    private:
758117397Skan      /**
759117397Skan       *  @if maint
760117397Skan       *  @doctodo
761117397Skan       *  @endif
762117397Skan      */
76397403Sobrien      __filebuf_type	_M_filebuf;
76497403Sobrien
76597403Sobrien    public:
76697403Sobrien      // Constructors/destructor:
767117397Skan      /**
768117397Skan       *  @brief  Default constructor.
769117397Skan       *
770117397Skan       *  Initializes @c sb using its default constructor, and passes
771117397Skan       *  @c &sb to the base class initializer.  Does not open any files
772117397Skan       *  (you haven't given it a filename to open).
773117397Skan      */
77497403Sobrien      basic_fstream()
775132720Skan      : __iostream_type(), _M_filebuf()
77697403Sobrien      { this->init(&_M_filebuf); }
77797403Sobrien
77897403Sobrien      /**
779117397Skan       *  @brief  Create an input/output file stream.
780117397Skan       *  @param  s  Null terminated string specifying the filename.
78197403Sobrien       *  @param  mode  Open file in specified mode (see std::ios_base).
78297403Sobrien       *
78397403Sobrien       *  Tip:  When using std::string to hold the filename, you must use
78497403Sobrien       *  .c_str() before passing it to this constructor.
78597403Sobrien      */
78697403Sobrien      explicit
78797403Sobrien      basic_fstream(const char* __s,
78897403Sobrien		    ios_base::openmode __mode = ios_base::in | ios_base::out)
78997403Sobrien      : __iostream_type(NULL), _M_filebuf()
79097403Sobrien      {
79197403Sobrien	this->init(&_M_filebuf);
79297403Sobrien	this->open(__s, __mode);
79397403Sobrien      }
79497403Sobrien
795117397Skan      /**
796117397Skan       *  @brief  The destructor does nothing.
797117397Skan       *
798117397Skan       *  The file is closed by the filebuf object, not the formatting
799117397Skan       *  stream.
800117397Skan      */
80197403Sobrien      ~basic_fstream()
80297403Sobrien      { }
80397403Sobrien
80497403Sobrien      // Members:
80597403Sobrien      /**
806117397Skan       *  @brief  Accessing the underlying buffer.
807117397Skan       *  @return  The current basic_filebuf buffer.
808117397Skan       *
809117397Skan       *  This hides both signatures of std::basic_ios::rdbuf().
81097403Sobrien      */
81197403Sobrien      __filebuf_type*
81297403Sobrien      rdbuf() const
81397403Sobrien      { return const_cast<__filebuf_type*>(&_M_filebuf); }
81497403Sobrien
81597403Sobrien      /**
816117397Skan       *  @brief  Wrapper to test for an open file.
817117397Skan       *  @return  @c rdbuf()->is_open()
81897403Sobrien      */
81997403Sobrien      bool
82097403Sobrien      is_open() { return _M_filebuf.is_open(); }
82197403Sobrien
82297403Sobrien      /**
823117397Skan       *  @brief  Opens an external file.
824117397Skan       *  @param  s  The name of the file.
825117397Skan       *  @param  mode  The open mode flags.
82697403Sobrien       *
827117397Skan       *  Calls @c std::basic_filebuf::open(s,mode).  If that
828117397Skan       *  function fails, @c failbit is set in the stream's error state.
829117397Skan       *
83097403Sobrien       *  Tip:  When using std::string to hold the filename, you must use
83197403Sobrien       *  .c_str() before passing it to this constructor.
83297403Sobrien      */
83397403Sobrien      void
83497403Sobrien      open(const char* __s,
83597403Sobrien	   ios_base::openmode __mode = ios_base::in | ios_base::out)
83697403Sobrien      {
83797403Sobrien	if (!_M_filebuf.open(__s, __mode))
838132720Skan	  this->setstate(ios_base::failbit);
83997403Sobrien      }
84097403Sobrien
841117397Skan      /**
842117397Skan       *  @brief  Close the file.
843117397Skan       *
844117397Skan       *  Calls @c std::basic_filebuf::close().  If that function
845117397Skan       *  fails, @c failbit is set in the stream's error state.
846117397Skan      */
84797403Sobrien      void
84897403Sobrien      close()
84997403Sobrien      {
85097403Sobrien	if (!_M_filebuf.close())
851132720Skan	  this->setstate(ios_base::failbit);
85297403Sobrien      }
85397403Sobrien    };
85497403Sobrien} // namespace std
85597403Sobrien
856132720Skan#ifndef _GLIBCXX_EXPORT_TEMPLATE
85797403Sobrien# include <bits/fstream.tcc>
85897403Sobrien#endif
85997403Sobrien
860132720Skan#endif /* _GLIBCXX_FSTREAM */
861