fstream

Go to the documentation of this file.
00001 // File based streams -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 //
00032 // ISO C++ 14882: 27.8  File-based streams
00033 //
00034 
00035 /** @file fstream
00036  *  This is a Standard C++ Library header.  You should @c #include this header
00037  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
00038  */
00039 
00040 #ifndef _CPP_FSTREAM
00041 #define _CPP_FSTREAM    1
00042 
00043 #pragma GCC system_header
00044 
00045 #include <istream>
00046 #include <ostream>
00047 #include <locale>   // For codecvt
00048 #include <bits/basic_file.h>
00049 #include <bits/gthr.h>
00050 
00051 namespace std
00052 {
00053   // [27.8.1.1] template class basic_filebuf
00054   /**
00055    *  @brief  The actual work of input and output (for files).
00056    *
00057    *  This class associates both its input and output sequence with an
00058    *  external disk file, and maintains a joint file position for both
00059    *  sequences.  Many of its sematics are described in terms of similar
00060    *  behavior in the Standard C Library's @c FILE streams.
00061   */
00062   template<typename _CharT, typename _Traits>
00063     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
00064     {
00065     public:
00066       // Types:
00067       typedef _CharT                                char_type;
00068       typedef _Traits                               traits_type;
00069       typedef typename traits_type::int_type        int_type;
00070       typedef typename traits_type::pos_type        pos_type;
00071       typedef typename traits_type::off_type        off_type;
00072 
00073       //@{
00074       /**
00075        *  @if maint
00076        *  @doctodo
00077        *  @endif
00078       */
00079       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
00080       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00081       typedef __basic_file<char>                __file_type;
00082       typedef typename traits_type::state_type          __state_type;
00083       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
00084       typedef ctype<char_type>                          __ctype_type;
00085       //@}
00086 
00087       friend class ios_base; // For sync_with_stdio.
00088 
00089     protected:
00090       // Data Members:
00091       // MT lock inherited from libio or other low-level io library.
00092       /**
00093        *  @if maint
00094        *  @doctodo
00095        *  @endif
00096       */
00097       __c_lock              _M_lock;
00098 
00099       // External buffer.
00100       /**
00101        *  @if maint
00102        *  @doctodo
00103        *  @endif
00104       */
00105       __file_type       _M_file;
00106 
00107       // Current and beginning state type for codecvt.
00108       /**
00109        *  @if maint
00110        *  @doctodo
00111        *  @endif
00112       */
00113       __state_type      _M_state_cur;
00114       __state_type      _M_state_beg;
00115 
00116       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
00117       /**
00118        *  @if maint
00119        *  @doctodo
00120        *  @endif
00121       */
00122       bool          _M_buf_allocated;
00123       
00124       // XXX Needed?
00125       bool          _M_last_overflowed;
00126 
00127       // The position in the buffer corresponding to the external file
00128       // pointer.
00129       /**
00130        *  @if maint
00131        *  @doctodo
00132        *  @endif
00133       */
00134       char_type*        _M_filepos;
00135 
00136     public:
00137       // Constructors/destructor:
00138       /**
00139        *  @brief  Does not open any files.
00140        *
00141        *  The default constructor initializes the parent class using its
00142        *  own default ctor.
00143       */
00144       basic_filebuf();
00145 
00146       /**
00147        *  @brief  The destructor closes the file first.
00148       */
00149       virtual
00150       ~basic_filebuf()
00151       {
00152     this->close();
00153     _M_last_overflowed = false;
00154       }
00155 
00156       // Members:
00157       /**
00158        *  @brief  Returns true if the external file is open.
00159       */
00160       bool
00161       is_open() const throw() { return _M_file.is_open(); }
00162 
00163       /**
00164        *  @brief  Opens an external file.
00165        *  @param  s  The name of the file.
00166        *  @param  mode  The open mode flags.
00167        *  @return  @c this on success, NULL on failure
00168        *
00169        *  If a file is already open, this function immediately fails.
00170        *  Otherwise it tries to open the file named @a s using the flags
00171        *  given in @a mode.
00172        *
00173        *  [Table 92 gives the relation between openmode combinations and the
00174        *  equivalent fopen() flags, but the table has not been copied yet.]
00175       */
00176       __filebuf_type*
00177       open(const char* __s, ios_base::openmode __mode);
00178 
00179       /**
00180        *  @brief  Closes the currently associated file.
00181        *  @return  @c this on success, NULL on failure
00182        *
00183        *  If no file is currently open, this function immediately fails.
00184        *
00185        *  If a "put buffer area" exists, @c overflow(eof) is called to flush
00186        *  all the characters.  The file is then closed.
00187        *
00188        *  If any operations fail, this function also fails.
00189       */
00190       __filebuf_type*
00191       close() throw();
00192 
00193     protected:
00194       /**
00195        *  @if maint
00196        *  @doctodo
00197        *  @endif
00198       */
00199       void
00200       _M_allocate_internal_buffer();
00201 
00202       /**
00203        *  @if maint
00204        *  @doctodo
00205        *  @endif
00206       */
00207       void
00208       _M_destroy_internal_buffer() throw();
00209 
00210       // [27.8.1.4] overridden virtual functions
00211       // [documentation is inherited]
00212       virtual streamsize
00213       showmanyc();
00214 
00215       // Stroustrup, 1998, p. 628
00216       // underflow() and uflow() functions are called to get the next
00217       // charater from the real input source when the buffer is empty.
00218       // Buffered input uses underflow()
00219 
00220       // The only difference between underflow() and uflow() is that the
00221       // latter bumps _M_in_cur after the read.  In the sync_with_stdio
00222       // case, this is important, as we need to unget the read character in
00223       // the underflow() case in order to maintain synchronization.  So
00224       // instead of calling underflow() from uflow(), we create a common
00225       // subroutine to do the real work.
00226       /**
00227        *  @if maint
00228        *  @doctodo
00229        *  @endif
00230       */
00231       int_type
00232       _M_underflow_common(bool __bump);
00233 
00234       // [documentation is inherited]
00235       virtual int_type
00236       underflow();
00237 
00238       // [documentation is inherited]
00239       virtual int_type
00240       uflow();
00241 
00242       // [documentation is inherited]
00243       virtual int_type
00244       pbackfail(int_type __c = _Traits::eof());
00245 
00246       // NB: For what the standard expects of the overflow function,
00247       // see _M_really_overflow(), below. Because basic_streambuf's
00248       // sputc/sputn call overflow directly, and the complications of
00249       // this implementation's setting of the initial pointers all
00250       // equal to _M_buf when initializing, it seems essential to have
00251       // this in actuality be a helper function that checks for the
00252       // eccentricities of this implementation, and then call
00253       // overflow() if indeed the buffer is full.
00254 
00255       // [documentation is inherited]
00256       virtual int_type
00257       overflow(int_type __c = _Traits::eof());
00258 
00259       // Stroustrup, 1998, p 648
00260       // The overflow() function is called to transfer characters to the
00261       // real output destination when the buffer is full. A call to
00262       // overflow(c) outputs the contents of the buffer plus the
00263       // character c.
00264       // 27.5.2.4.5
00265       // Consume some sequence of the characters in the pending sequence.
00266       /**
00267        *  @if maint
00268        *  @doctodo
00269        *  @endif
00270       */
00271       int_type
00272       _M_really_overflow(int_type __c = _Traits::eof());
00273 
00274       // Convert internal byte sequence to external, char-based
00275       // sequence via codecvt.
00276       /**
00277        *  @if maint
00278        *  @doctodo
00279        *  @endif
00280       */
00281       void
00282       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
00283 
00284       /**
00285        *  @brief  Manipulates the buffer.
00286        *  @param  s  Pointer to a buffer area.
00287        *  @param  n  Size of @a s.
00288        *  @return  @c this
00289        *
00290        *  If no file has been opened, and both @a s and @a n are zero, then
00291        *  the stream becomes unbuffered.  Otherwise, @c s is used as a
00292        *  buffer; see
00293        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
00294        *  for more.
00295       */
00296       virtual __streambuf_type*
00297       setbuf(char_type* __s, streamsize __n);
00298 
00299       // [documentation is inherited]
00300       virtual pos_type
00301       seekoff(off_type __off, ios_base::seekdir __way,
00302           ios_base::openmode __mode = ios_base::in | ios_base::out);
00303 
00304       // [documentation is inherited]
00305       virtual pos_type
00306       seekpos(pos_type __pos,
00307           ios_base::openmode __mode = ios_base::in | ios_base::out);
00308 
00309       // [documentation is inherited]
00310       virtual int
00311       sync()
00312       {
00313     int __ret = 0;
00314     bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00315 
00316     // Make sure that the internal buffer resyncs its idea of
00317     // the file position with the external file.
00318     if (__testput)
00319       {
00320         // Need to restore current position after the write.
00321         off_type __off = _M_out_cur - _M_out_end;
00322 
00323         // _M_file.sync() will be called within
00324         if (traits_type::eq_int_type(_M_really_overflow(),
00325                      traits_type::eof()))
00326           __ret = -1;
00327         else if (__off)
00328           _M_file.seekoff(__off, ios_base::cur);
00329       }
00330     else
00331       _M_file.sync();
00332 
00333     _M_last_overflowed = false;
00334     return __ret;
00335       }
00336 
00337       // [documentation is inherited]
00338       virtual void
00339       imbue(const locale& __loc);
00340 
00341       // [documentation is inherited]
00342       virtual streamsize
00343       xsgetn(char_type* __s, streamsize __n)
00344       {
00345     streamsize __ret = 0;
00346     // Clear out pback buffer before going on to the real deal...
00347     if (_M_pback_init)
00348       {
00349         while (__ret < __n && _M_in_cur < _M_in_end)
00350           {
00351         *__s = *_M_in_cur;
00352         ++__ret;
00353         ++__s;
00354         ++_M_in_cur;
00355           }
00356         _M_pback_destroy();
00357       }
00358     if (__ret < __n)
00359       __ret += __streambuf_type::xsgetn(__s, __n - __ret);
00360     return __ret;
00361       }
00362 
00363       // [documentation is inherited]
00364       virtual streamsize
00365       xsputn(const char_type* __s, streamsize __n)
00366       {
00367     _M_pback_destroy();
00368     return __streambuf_type::xsputn(__s, __n);
00369       }
00370 
00371       /**
00372        *  @if maint
00373        *  @doctodo
00374        *  @endif
00375       */
00376       void
00377       _M_output_unshift();
00378 
00379       // These three functions are used to clarify internal buffer
00380       // maintenance. After an overflow, or after a seekoff call that
00381       // started at beg or end, or possibly when the stream becomes
00382       // unbuffered, and a myrid other obscure corner cases, the
00383       // internal buffer does not truly reflect the contents of the
00384       // external buffer. At this point, for whatever reason, it is in
00385       // an indeterminate state.
00386       /**
00387        *  @if maint
00388        *  @doctodo
00389        *  @endif
00390       */
00391       void
00392       _M_set_indeterminate(void)
00393       {
00394     if (_M_mode & ios_base::in)
00395       this->setg(_M_buf, _M_buf, _M_buf);
00396     if (_M_mode & ios_base::out)
00397       this->setp(_M_buf, _M_buf);
00398     _M_filepos = _M_buf;
00399       }
00400 
00401       /**
00402        *  @if maint
00403        *  @doctodo
00404        *  @endif
00405       */
00406       void
00407       _M_set_determinate(off_type __off)
00408       {
00409     bool __testin = _M_mode & ios_base::in;
00410     bool __testout = _M_mode & ios_base::out;
00411     if (__testin)
00412       this->setg(_M_buf, _M_buf, _M_buf + __off);
00413     if (__testout)
00414       this->setp(_M_buf, _M_buf + __off);
00415     _M_filepos = _M_buf + __off;
00416       }
00417 
00418       /**
00419        *  @if maint
00420        *  @doctodo
00421        *  @endif
00422       */
00423       bool
00424       _M_is_indeterminate(void)
00425       { 
00426     bool __ret = false;
00427     // Don't return true if unbuffered.
00428     if (_M_buf)
00429       {
00430         if (_M_mode & ios_base::in)
00431           __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
00432         if (_M_mode & ios_base::out)
00433           __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
00434       }
00435     return __ret;
00436       }
00437     };
00438 
00439   // Explicit specialization declarations, defined in src/fstream.cc.
00440   template<> 
00441     basic_filebuf<char>::int_type 
00442     basic_filebuf<char>::_M_underflow_common(bool __bump);
00443 
00444  #ifdef _GLIBCPP_USE_WCHAR_T
00445   template<> 
00446     basic_filebuf<wchar_t>::int_type 
00447     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
00448  #endif
00449 
00450   // Generic definitions.
00451   template <typename _CharT, typename _Traits>
00452     typename basic_filebuf<_CharT, _Traits>::int_type
00453     basic_filebuf<_CharT, _Traits>::underflow() 
00454     { return _M_underflow_common(false); }
00455 
00456   template <typename _CharT, typename _Traits>
00457     typename basic_filebuf<_CharT, _Traits>::int_type
00458     basic_filebuf<_CharT, _Traits>::uflow() 
00459     { return _M_underflow_common(true); }
00460 
00461 
00462   // [27.8.1.5] Template class basic_ifstream
00463   /**
00464    *  @brief  Controlling input for files.
00465    *
00466    *  This class supports reading from named files, using the inherited
00467    *  functions from std::basic_istream.  To control the associated
00468    *  sequence, an instance of std::basic_filebuf is used, which this page
00469    *  refers to as @c sb.
00470   */
00471   template<typename _CharT, typename _Traits>
00472     class basic_ifstream : public basic_istream<_CharT, _Traits>
00473     {
00474     public:
00475       // Types:
00476       typedef _CharT                    char_type;
00477       typedef _Traits                   traits_type;
00478       typedef typename traits_type::int_type        int_type;
00479       typedef typename traits_type::pos_type        pos_type;
00480       typedef typename traits_type::off_type        off_type;
00481 
00482       // Non-standard types:
00483       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00484       typedef basic_istream<char_type, traits_type> __istream_type;
00485 
00486     private:
00487       /**
00488        *  @if maint
00489        *  @doctodo
00490        *  @endif
00491       */
00492       __filebuf_type    _M_filebuf;
00493 
00494     public:
00495       // Constructors/Destructors:
00496       /**
00497        *  @brief  Default constructor.
00498        *
00499        *  Initializes @c sb using its default constructor, and passes
00500        *  @c &sb to the base class initializer.  Does not open any files
00501        *  (you haven't given it a filename to open).
00502       */
00503       basic_ifstream()
00504       : __istream_type(NULL), _M_filebuf()
00505       { this->init(&_M_filebuf); }
00506 
00507       /**
00508        *  @brief  Create an input file stream.
00509        *  @param  s  Null terminated string specifying the filename.
00510        *  @param  mode  Open file in specified mode (see std::ios_base).
00511        *
00512        *  @c ios_base::in is automatically included in @a mode.
00513        *
00514        *  Tip:  When using std::string to hold the filename, you must use
00515        *  .c_str() before passing it to this constructor.
00516       */
00517       explicit
00518       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00519       : __istream_type(NULL), _M_filebuf()
00520       {
00521     this->init(&_M_filebuf);
00522     this->open(__s, __mode);
00523       }
00524 
00525       /**
00526        *  @brief  The destructor does nothing.
00527        *
00528        *  The file is closed by the filebuf object, not the formatting
00529        *  stream.
00530       */
00531       ~basic_ifstream()
00532       { }
00533 
00534       // Members:
00535       /**
00536        *  @brief  Accessing the underlying buffer.
00537        *  @return  The current basic_filebuf buffer.
00538        *
00539        *  This hides both signatures of std::basic_ios::rdbuf().
00540       */
00541       __filebuf_type*
00542       rdbuf() const
00543       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00544 
00545       /**
00546        *  @brief  Wrapper to test for an open file.
00547        *  @return  @c rdbuf()->is_open()
00548       */
00549       bool
00550       is_open() { return _M_filebuf.is_open(); }
00551 
00552       /**
00553        *  @brief  Opens an external file.
00554        *  @param  s  The name of the file.
00555        *  @param  mode  The open mode flags.
00556        *
00557        *  Calls @c std::basic_filebuf::open(s,mode|in).  If that function
00558        *  fails, @c failbit is set in the stream's error state.
00559        *
00560        *  Tip:  When using std::string to hold the filename, you must use
00561        *  .c_str() before passing it to this constructor.
00562       */
00563       void
00564       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00565       {
00566     if (!_M_filebuf.open(__s, __mode | ios_base::in))
00567       this->setstate(ios_base::failbit);
00568       }
00569 
00570       /**
00571        *  @brief  Close the file.
00572        *
00573        *  Calls @c std::basic_filebuf::close().  If that function
00574        *  fails, @c failbit is set in the stream's error state.
00575       */
00576       void
00577       close()
00578       {
00579     if (!_M_filebuf.close())
00580       this->setstate(ios_base::failbit);
00581       }
00582     };
00583 
00584 
00585   // [27.8.1.8] Template class basic_ofstream
00586   /**
00587    *  @brief  Controlling output for files.
00588    *
00589    *  This class supports reading from named files, using the inherited
00590    *  functions from std::basic_ostream.  To control the associated
00591    *  sequence, an instance of std::basic_filebuf is used, which this page
00592    *  refers to as @c sb.
00593   */
00594   template<typename _CharT, typename _Traits>
00595     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00596     {
00597     public:
00598       // Types:
00599       typedef _CharT                    char_type;
00600       typedef _Traits                   traits_type;
00601       typedef typename traits_type::int_type        int_type;
00602       typedef typename traits_type::pos_type        pos_type;
00603       typedef typename traits_type::off_type        off_type;
00604 
00605       // Non-standard types:
00606       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00607       typedef basic_ostream<char_type, traits_type> __ostream_type;
00608 
00609     private:
00610       /**
00611        *  @if maint
00612        *  @doctodo
00613        *  @endif
00614       */
00615       __filebuf_type    _M_filebuf;
00616 
00617     public:
00618       // Constructors:
00619       /**
00620        *  @brief  Default constructor.
00621        *
00622        *  Initializes @c sb using its default constructor, and passes
00623        *  @c &sb to the base class initializer.  Does not open any files
00624        *  (you haven't given it a filename to open).
00625       */
00626       basic_ofstream()
00627       : __ostream_type(NULL), _M_filebuf()
00628       { this->init(&_M_filebuf); }
00629 
00630       /**
00631        *  @brief  Create an output file stream.
00632        *  @param  s  Null terminated string specifying the filename.
00633        *  @param  mode  Open file in specified mode (see std::ios_base).
00634        *
00635        *  @c ios_base::out|ios_base::trunc is automatically included in
00636        *  @a mode.
00637        *
00638        *  Tip:  When using std::string to hold the filename, you must use
00639        *  .c_str() before passing it to this constructor.
00640       */
00641       explicit
00642       basic_ofstream(const char* __s,
00643              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00644       : __ostream_type(NULL), _M_filebuf()
00645       {
00646     this->init(&_M_filebuf);
00647     this->open(__s, __mode);
00648       }
00649 
00650       /**
00651        *  @brief  The destructor does nothing.
00652        *
00653        *  The file is closed by the filebuf object, not the formatting
00654        *  stream.
00655       */
00656       ~basic_ofstream()
00657       { }
00658 
00659       // Members:
00660       /**
00661        *  @brief  Accessing the underlying buffer.
00662        *  @return  The current basic_filebuf buffer.
00663        *
00664        *  This hides both signatures of std::basic_ios::rdbuf().
00665       */
00666       __filebuf_type*
00667       rdbuf() const
00668       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00669 
00670       /**
00671        *  @brief  Wrapper to test for an open file.
00672        *  @return  @c rdbuf()->is_open()
00673       */
00674       bool
00675       is_open() { return _M_filebuf.is_open(); }
00676 
00677       /**
00678        *  @brief  Opens an external file.
00679        *  @param  s  The name of the file.
00680        *  @param  mode  The open mode flags.
00681        *
00682        *  Calls @c std::basic_filebuf::open(s,mode|out|trunc).  If that
00683        *  function fails, @c failbit is set in the stream's error state.
00684        *
00685        *  Tip:  When using std::string to hold the filename, you must use
00686        *  .c_str() before passing it to this constructor.
00687       */
00688       void
00689       open(const char* __s,
00690        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00691       {
00692     if (!_M_filebuf.open(__s, __mode | ios_base::out))
00693       this->setstate(ios_base::failbit);
00694       }
00695 
00696       /**
00697        *  @brief  Close the file.
00698        *
00699        *  Calls @c std::basic_filebuf::close().  If that function
00700        *  fails, @c failbit is set in the stream's error state.
00701       */
00702       void
00703       close()
00704       {
00705     if (!_M_filebuf.close())
00706       this->setstate(ios_base::failbit);
00707       }
00708     };
00709 
00710 
00711   // [27.8.1.11] Template class basic_fstream
00712   /**
00713    *  @brief  Controlling intput and output for files.
00714    *
00715    *  This class supports reading from and writing to named files, using
00716    *  the inherited functions from std::basic_iostream.  To control the
00717    *  associated sequence, an instance of std::basic_filebuf is used, which
00718    *  this page refers to as @c sb.
00719   */
00720   template<typename _CharT, typename _Traits>
00721     class basic_fstream : public basic_iostream<_CharT, _Traits>
00722     {
00723     public:
00724       // Types:
00725       typedef _CharT                    char_type;
00726       typedef _Traits                   traits_type;
00727       typedef typename traits_type::int_type        int_type;
00728       typedef typename traits_type::pos_type        pos_type;
00729       typedef typename traits_type::off_type        off_type;
00730 
00731       // Non-standard types:
00732       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00733       typedef basic_ios<char_type, traits_type>     __ios_type;
00734       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00735 
00736     private:
00737       /**
00738        *  @if maint
00739        *  @doctodo
00740        *  @endif
00741       */
00742       __filebuf_type    _M_filebuf;
00743 
00744     public:
00745       // Constructors/destructor:
00746       /**
00747        *  @brief  Default constructor.
00748        *
00749        *  Initializes @c sb using its default constructor, and passes
00750        *  @c &sb to the base class initializer.  Does not open any files
00751        *  (you haven't given it a filename to open).
00752       */
00753       basic_fstream()
00754       : __iostream_type(NULL), _M_filebuf()
00755       { this->init(&_M_filebuf); }
00756 
00757       /**
00758        *  @brief  Create an input/output file stream.
00759        *  @param  s  Null terminated string specifying the filename.
00760        *  @param  mode  Open file in specified mode (see std::ios_base).
00761        *
00762        *  Tip:  When using std::string to hold the filename, you must use
00763        *  .c_str() before passing it to this constructor.
00764       */
00765       explicit
00766       basic_fstream(const char* __s,
00767             ios_base::openmode __mode = ios_base::in | ios_base::out)
00768       : __iostream_type(NULL), _M_filebuf()
00769       {
00770     this->init(&_M_filebuf);
00771     this->open(__s, __mode);
00772       }
00773 
00774       /**
00775        *  @brief  The destructor does nothing.
00776        *
00777        *  The file is closed by the filebuf object, not the formatting
00778        *  stream.
00779       */
00780       ~basic_fstream()
00781       { }
00782 
00783       // Members:
00784       /**
00785        *  @brief  Accessing the underlying buffer.
00786        *  @return  The current basic_filebuf buffer.
00787        *
00788        *  This hides both signatures of std::basic_ios::rdbuf().
00789       */
00790       __filebuf_type*
00791       rdbuf() const
00792       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00793 
00794       /**
00795        *  @brief  Wrapper to test for an open file.
00796        *  @return  @c rdbuf()->is_open()
00797       */
00798       bool
00799       is_open() { return _M_filebuf.is_open(); }
00800 
00801       /**
00802        *  @brief  Opens an external file.
00803        *  @param  s  The name of the file.
00804        *  @param  mode  The open mode flags.
00805        *
00806        *  Calls @c std::basic_filebuf::open(s,mode).  If that
00807        *  function fails, @c failbit is set in the stream's error state.
00808        *
00809        *  Tip:  When using std::string to hold the filename, you must use
00810        *  .c_str() before passing it to this constructor.
00811       */
00812       void
00813       open(const char* __s,
00814        ios_base::openmode __mode = ios_base::in | ios_base::out)
00815       {
00816     if (!_M_filebuf.open(__s, __mode))
00817       setstate(ios_base::failbit);
00818       }
00819 
00820       /**
00821        *  @brief  Close the file.
00822        *
00823        *  Calls @c std::basic_filebuf::close().  If that function
00824        *  fails, @c failbit is set in the stream's error state.
00825       */
00826       void
00827       close()
00828       {
00829     if (!_M_filebuf.close())
00830       setstate(ios_base::failbit);
00831       }
00832     };
00833 } // namespace std
00834 
00835 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00836 # define export
00837 #endif
00838 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00839 # include <bits/fstream.tcc>
00840 #endif
00841 
00842 #endif

Generated on Thu Feb 10 23:22:54 2005 for libstdc++-v3 Source by  doxygen 1.4.0