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 
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 ctype<char_type>                          __ctype_type;
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.
00097       __c_lock              _M_lock;
00098 
00099       // External buffer.
00105       __file_type       _M_file;
00106 
00107       // Current and beginning state type for codecvt.
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.
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.
00134       char_type*        _M_filepos;
00135 
00136     public:
00137       // Constructors/destructor:
00144       basic_filebuf();
00145 
00149       virtual
00150       ~basic_filebuf()
00151       {
00152     this->close();
00153     _M_last_overflowed = false;
00154       }
00155 
00156       // Members:
00160       bool
00161       is_open() const throw() { return _M_file.is_open(); }
00162 
00176       __filebuf_type*
00177       open(const char* __s, ios_base::openmode __mode);
00178 
00190       __filebuf_type*
00191       close() throw();
00192 
00193     protected:
00199       void
00200       _M_allocate_internal_buffer();
00201 
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.
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.
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.
00281       void
00282       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
00283 
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 
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.
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 
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 
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
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:
00492       __filebuf_type    _M_filebuf;
00493 
00494     public:
00495       // Constructors/Destructors:
00503       basic_ifstream()
00504       : __istream_type(NULL), _M_filebuf()
00505       { this->init(&_M_filebuf); }
00506 
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 
00531       ~basic_ifstream()
00532       { }
00533 
00534       // Members:
00541       __filebuf_type*
00542       rdbuf() const
00543       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00544 
00549       bool
00550       is_open() { return _M_filebuf.is_open(); }
00551 
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 
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
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:
00615       __filebuf_type    _M_filebuf;
00616 
00617     public:
00618       // Constructors:
00626       basic_ofstream()
00627       : __ostream_type(NULL), _M_filebuf()
00628       { this->init(&_M_filebuf); }
00629 
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 
00656       ~basic_ofstream()
00657       { }
00658 
00659       // Members:
00666       __filebuf_type*
00667       rdbuf() const
00668       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00669 
00674       bool
00675       is_open() { return _M_filebuf.is_open(); }
00676 
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 
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
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:
00742       __filebuf_type    _M_filebuf;
00743 
00744     public:
00745       // Constructors/destructor:
00753       basic_fstream()
00754       : __iostream_type(NULL), _M_filebuf()
00755       { this->init(&_M_filebuf); }
00756 
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 
00780       ~basic_fstream()
00781       { }
00782 
00783       // Members:
00790       __filebuf_type*
00791       rdbuf() const
00792       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00793 
00798       bool
00799       is_open() { return _M_filebuf.is_open(); }
00800 
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 
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 Tue Apr 29 20:16:21 2003 for libstdc++-v3 Source by doxygen1.3