fstream

Go to the documentation of this file.
00001 // File based streams -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
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 
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
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 
00074 
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 typename __codecvt_type::result           __res_type;
00085       typedef ctype<char_type>                          __ctype_type;
00087 
00088       friend class ios_base; // For sync_with_stdio.
00089 
00090     protected:
00091       // Data Members:
00092       // MT lock inherited from libio or other low-level io library.
00098       __c_lock              _M_lock;
00099 
00100       // External buffer.
00106       __file_type       _M_file;
00107 
00108       // Current and beginning state type for codecvt.
00114       __state_type      _M_state_cur;
00115       __state_type      _M_state_beg;
00116 
00117       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
00123       bool          _M_buf_allocated;
00124       
00125       // XXX Needed?
00126       bool          _M_last_overflowed;
00127 
00128       // The position in the buffer corresponding to the external file
00129       // pointer.
00135       char_type*        _M_filepos;
00136 
00137     public:
00138       // Constructors/destructor:
00145       basic_filebuf();
00146 
00150       virtual
00151       ~basic_filebuf()
00152       {
00153     this->close();
00154     _M_last_overflowed = false;
00155       }
00156 
00157       // Members:
00161       bool
00162       is_open() const { return _M_file.is_open(); }
00163 
00177       __filebuf_type*
00178       open(const char* __s, ios_base::openmode __mode);
00179 
00191       __filebuf_type*
00192       close();
00193 
00194     protected:
00200       void
00201       _M_allocate_internal_buffer();
00202 
00208       void
00209       _M_destroy_internal_buffer();
00210 
00211       // [27.8.1.4] overridden virtual functions
00212       // [documentation is inherited]
00213       virtual streamsize
00214       showmanyc();
00215 
00216       // Stroustrup, 1998, p. 628
00217       // underflow() and uflow() functions are called to get the next
00218       // charater from the real input source when the buffer is empty.
00219       // Buffered input uses underflow()
00220 
00221       // The only difference between underflow() and uflow() is that the
00222       // latter bumps _M_in_cur after the read.  In the sync_with_stdio
00223       // case, this is important, as we need to unget the read character in
00224       // the underflow() case in order to maintain synchronization.  So
00225       // instead of calling underflow() from uflow(), we create a common
00226       // subroutine to do the real work.
00232       int_type
00233       _M_underflow_common(bool __bump);
00234 
00235       // [documentation is inherited]
00236       virtual int_type
00237       underflow() { return _M_underflow_common(false); }
00238 
00239       // [documentation is inherited]
00240       virtual int_type
00241       uflow() { return _M_underflow_common(true); }
00242 
00243       // [documentation is inherited]
00244       virtual int_type
00245       pbackfail(int_type __c = _Traits::eof());
00246 
00247       // NB: For what the standard expects of the overflow function,
00248       // see _M_really_overflow(), below. Because basic_streambuf's
00249       // sputc/sputn call overflow directly, and the complications of
00250       // this implementation's setting of the initial pointers all
00251       // equal to _M_buf when initializing, it seems essential to have
00252       // this in actuality be a helper function that checks for the
00253       // eccentricities of this implementation, and then call
00254       // overflow() if indeed the buffer is full.
00255 
00256       // [documentation is inherited]
00257       virtual int_type
00258       overflow(int_type __c = _Traits::eof());
00259 
00260       // Stroustrup, 1998, p 648
00261       // The overflow() function is called to transfer characters to the
00262       // real output destination when the buffer is full. A call to
00263       // overflow(c) outputs the contents of the buffer plus the
00264       // character c.
00265       // 27.5.2.4.5
00266       // Consume some sequence of the characters in the pending sequence.
00272       int_type
00273       _M_really_overflow(int_type __c = _Traits::eof());
00274 
00275       // Convert internal byte sequence to external, char-based
00276       // sequence via codecvt.
00282       void
00283       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
00284 
00297       virtual __streambuf_type*
00298       setbuf(char_type* __s, streamsize __n);
00299 
00300       // [documentation is inherited]
00301       virtual pos_type
00302       seekoff(off_type __off, ios_base::seekdir __way,
00303           ios_base::openmode __mode = ios_base::in | ios_base::out);
00304 
00305       // [documentation is inherited]
00306       virtual pos_type
00307       seekpos(pos_type __pos,
00308           ios_base::openmode __mode = ios_base::in | ios_base::out);
00309 
00310       // [documentation is inherited]
00311       virtual int
00312       sync()
00313       {
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         _M_really_overflow(); // _M_file.sync() will be called within
00323         if (__off)
00324           _M_file.seekoff(__off, ios_base::cur);
00325       }
00326     else
00327       _M_file.sync();
00328     _M_last_overflowed = false;
00329     return 0;
00330       }
00331 
00332       // [documentation is inherited]
00333       virtual void
00334       imbue(const locale& __loc);
00335 
00336       // [documentation is inherited]
00337       virtual streamsize
00338       xsgetn(char_type* __s, streamsize __n)
00339       {
00340     streamsize __ret = 0;
00341     // Clear out pback buffer before going on to the real deal...
00342     if (_M_pback_init)
00343       {
00344         while (__ret < __n && _M_in_cur < _M_in_end)
00345           {
00346         *__s = *_M_in_cur;
00347         ++__ret;
00348         ++__s;
00349         ++_M_in_cur;
00350           }
00351         _M_pback_destroy();
00352       }
00353     if (__ret < __n)
00354       __ret += __streambuf_type::xsgetn(__s, __n - __ret);
00355     return __ret;
00356       }
00357 
00358       // [documentation is inherited]
00359       virtual streamsize
00360       xsputn(const char_type* __s, streamsize __n)
00361       {
00362     _M_pback_destroy();
00363     return __streambuf_type::xsputn(__s, __n);
00364       }
00365 
00371       void
00372       _M_output_unshift();
00373 
00374       // These three functions are used to clarify internal buffer
00375       // maintenance. After an overflow, or after a seekoff call that
00376       // started at beg or end, or possibly when the stream becomes
00377       // unbuffered, and a myrid other obscure corner cases, the
00378       // internal buffer does not truly reflect the contents of the
00379       // external buffer. At this point, for whatever reason, it is in
00380       // an indeterminate state.
00386       void
00387       _M_set_indeterminate(void)
00388       {
00389     if (_M_mode & ios_base::in)
00390       this->setg(_M_buf, _M_buf, _M_buf);
00391     if (_M_mode & ios_base::out)
00392       this->setp(_M_buf, _M_buf);
00393     _M_filepos = _M_buf;
00394       }
00395 
00401       void
00402       _M_set_determinate(off_type __off)
00403       {
00404     bool __testin = _M_mode & ios_base::in;
00405     bool __testout = _M_mode & ios_base::out;
00406     if (__testin)
00407       this->setg(_M_buf, _M_buf, _M_buf + __off);
00408     if (__testout)
00409       this->setp(_M_buf, _M_buf + __off);
00410     _M_filepos = _M_buf + __off;
00411       }
00412 
00418       bool
00419       _M_is_indeterminate(void)
00420       { 
00421     bool __ret = false;
00422     // Don't return true if unbuffered.
00423     if (_M_buf)
00424       {
00425         if (_M_mode & ios_base::in)
00426           __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
00427         if (_M_mode & ios_base::out)
00428           __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
00429       }
00430     return __ret;
00431       }
00432     };
00433 
00434   // Explicit specializations, defined in src/fstream.cc.
00435   template<> 
00436     basic_filebuf<char>::int_type 
00437     basic_filebuf<char>::_M_underflow_common(bool __bump);
00438 
00439  #ifdef _GLIBCPP_USE_WCHAR_T
00440   template<> 
00441     basic_filebuf<wchar_t>::int_type 
00442     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
00443  #endif
00444 
00445   // [27.8.1.5] Template class basic_ifstream
00454   template<typename _CharT, typename _Traits>
00455     class basic_ifstream : public basic_istream<_CharT, _Traits>
00456     {
00457     public:
00458       // Types:
00459       typedef _CharT                    char_type;
00460       typedef _Traits                   traits_type;
00461       typedef typename traits_type::int_type        int_type;
00462       typedef typename traits_type::pos_type        pos_type;
00463       typedef typename traits_type::off_type        off_type;
00464 
00465       // Non-standard types:
00466       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00467       typedef basic_istream<char_type, traits_type> __istream_type;
00468 
00469     private:
00475       __filebuf_type    _M_filebuf;
00476 
00477     public:
00478       // Constructors/Destructors:
00486       basic_ifstream()
00487       : __istream_type(NULL), _M_filebuf()
00488       { this->init(&_M_filebuf); }
00489 
00500       explicit
00501       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00502       : __istream_type(NULL), _M_filebuf()
00503       {
00504     this->init(&_M_filebuf);
00505     this->open(__s, __mode);
00506       }
00507 
00514       ~basic_ifstream()
00515       { }
00516 
00517       // Members:
00524       __filebuf_type*
00525       rdbuf() const
00526       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00527 
00532       bool
00533       is_open() { return _M_filebuf.is_open(); }
00534 
00546       void
00547       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00548       {
00549     if (!_M_filebuf.open(__s, __mode | ios_base::in))
00550       this->setstate(ios_base::failbit);
00551       }
00552 
00559       void
00560       close()
00561       {
00562     if (!_M_filebuf.close())
00563       this->setstate(ios_base::failbit);
00564       }
00565     };
00566 
00567 
00568   // [27.8.1.8] Template class basic_ofstream
00577   template<typename _CharT, typename _Traits>
00578     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00579     {
00580     public:
00581       // Types:
00582       typedef _CharT                    char_type;
00583       typedef _Traits                   traits_type;
00584       typedef typename traits_type::int_type        int_type;
00585       typedef typename traits_type::pos_type        pos_type;
00586       typedef typename traits_type::off_type        off_type;
00587 
00588       // Non-standard types:
00589       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00590       typedef basic_ostream<char_type, traits_type> __ostream_type;
00591 
00592     private:
00598       __filebuf_type    _M_filebuf;
00599 
00600     public:
00601       // Constructors:
00609       basic_ofstream()
00610       : __ostream_type(NULL), _M_filebuf()
00611       { this->init(&_M_filebuf); }
00612 
00624       explicit
00625       basic_ofstream(const char* __s,
00626              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00627       : __ostream_type(NULL), _M_filebuf()
00628       {
00629     this->init(&_M_filebuf);
00630     this->open(__s, __mode);
00631       }
00632 
00639       ~basic_ofstream()
00640       { }
00641 
00642       // Members:
00649       __filebuf_type*
00650       rdbuf() const
00651       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00652 
00657       bool
00658       is_open() { return _M_filebuf.is_open(); }
00659 
00671       void
00672       open(const char* __s,
00673        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00674       {
00675     if (!_M_filebuf.open(__s, __mode | ios_base::out))
00676       this->setstate(ios_base::failbit);
00677       }
00678 
00685       void
00686       close()
00687       {
00688     if (!_M_filebuf.close())
00689       this->setstate(ios_base::failbit);
00690       }
00691     };
00692 
00693 
00694   // [27.8.1.11] Template class basic_fstream
00703   template<typename _CharT, typename _Traits>
00704     class basic_fstream : public basic_iostream<_CharT, _Traits>
00705     {
00706     public:
00707       // Types:
00708       typedef _CharT                    char_type;
00709       typedef _Traits                   traits_type;
00710       typedef typename traits_type::int_type        int_type;
00711       typedef typename traits_type::pos_type        pos_type;
00712       typedef typename traits_type::off_type        off_type;
00713 
00714       // Non-standard types:
00715       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00716       typedef basic_ios<char_type, traits_type>     __ios_type;
00717       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00718 
00719     private:
00725       __filebuf_type    _M_filebuf;
00726 
00727     public:
00728       // Constructors/destructor:
00736       basic_fstream()
00737       : __iostream_type(NULL), _M_filebuf()
00738       { this->init(&_M_filebuf); }
00739 
00748       explicit
00749       basic_fstream(const char* __s,
00750             ios_base::openmode __mode = ios_base::in | ios_base::out)
00751       : __iostream_type(NULL), _M_filebuf()
00752       {
00753     this->init(&_M_filebuf);
00754     this->open(__s, __mode);
00755       }
00756 
00763       ~basic_fstream()
00764       { }
00765 
00766       // Members:
00773       __filebuf_type*
00774       rdbuf() const
00775       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00776 
00781       bool
00782       is_open() { return _M_filebuf.is_open(); }
00783 
00795       void
00796       open(const char* __s,
00797        ios_base::openmode __mode = ios_base::in | ios_base::out)
00798       {
00799     if (!_M_filebuf.open(__s, __mode))
00800       setstate(ios_base::failbit);
00801       }
00802 
00809       void
00810       close()
00811       {
00812     if (!_M_filebuf.close())
00813       setstate(ios_base::failbit);
00814       }
00815     };
00816 } // namespace std
00817 
00818 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00819 # define export
00820 #endif
00821 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00822 # include <bits/fstream.tcc>
00823 #endif
00824 
00825 #endif

Generated on Thu Nov 21 03:12:47 2002 for libstdc++-v3 Source by doxygen1.2.18-20021030