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   template<typename _CharT, typename _Traits>
00054     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
00055     {
00056     public:
00057       // Types:
00058       typedef _CharT                                char_type;
00059       typedef _Traits                               traits_type;
00060       typedef typename traits_type::int_type        int_type;
00061       typedef typename traits_type::pos_type        pos_type;
00062       typedef typename traits_type::off_type        off_type;
00063 
00064       // Non-standard Types:
00065       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
00066       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00067       typedef __basic_file<char>                __file_type;
00068       typedef typename traits_type::state_type          __state_type;
00069       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
00070       typedef typename __codecvt_type::result           __res_type;
00071       typedef ctype<char_type>                          __ctype_type;
00072 
00073       friend class ios_base; // For sync_with_stdio.
00074 
00075     protected:
00076       // Data Members:
00077       // MT lock inherited from libio or other low-level io library.
00078       __c_lock              _M_lock;
00079 
00080       // External buffer.
00081       __file_type       _M_file;
00082 
00083       // Current and beginning state type for codecvt.
00084       __state_type      _M_state_cur;
00085       __state_type      _M_state_beg;
00086 
00087       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
00088       bool          _M_buf_allocated;
00089       
00090       // XXX Needed?
00091       bool          _M_last_overflowed;
00092 
00093       // The position in the buffer corresponding to the external file
00094       // pointer.
00095       char_type*        _M_filepos;
00096 
00097     public:
00098       // Constructors/destructor:
00099       basic_filebuf();
00100 
00101       virtual
00102       ~basic_filebuf()
00103       {
00104     this->close();
00105     _M_last_overflowed = false;
00106       }
00107 
00108       // Members:
00109       bool
00110       is_open() const { return _M_file.is_open(); }
00111 
00112       __filebuf_type*
00113       open(const char* __s, ios_base::openmode __mode);
00114 
00115       __filebuf_type*
00116       close();
00117 
00118     protected:
00119       void
00120       _M_allocate_internal_buffer();
00121 
00122       void
00123       _M_destroy_internal_buffer();
00124 
00125       // Overridden virtual functions:
00126       virtual streamsize
00127       showmanyc();
00128 
00129       // Stroustrup, 1998, p. 628
00130       // underflow() and uflow() functions are called to get the next
00131       // charater from the real input source when the buffer is empty.
00132       // Buffered input uses underflow()
00133 
00134       // The only difference between underflow() and uflow() is that the
00135       // latter bumps _M_in_cur after the read.  In the sync_with_stdio
00136       // case, this is important, as we need to unget the read character in
00137       // the underflow() case in order to maintain synchronization.  So
00138       // instead of calling underflow() from uflow(), we create a common
00139       // subroutine to do the real work.
00140       int_type
00141       _M_underflow_common(bool __bump);
00142 
00143       virtual int_type
00144       underflow();
00145 
00146       virtual int_type
00147       uflow();
00148 
00149       virtual int_type
00150       pbackfail(int_type __c = _Traits::eof());
00151 
00152       // NB: For what the standard expects of the overflow function,
00153       // see _M_really_overflow(), below. Because basic_streambuf's
00154       // sputc/sputn call overflow directly, and the complications of
00155       // this implementation's setting of the initial pointers all
00156       // equal to _M_buf when initializing, it seems essential to have
00157       // this in actuality be a helper function that checks for the
00158       // eccentricities of this implementation, and then call
00159       // overflow() if indeed the buffer is full.
00160       virtual int_type
00161       overflow(int_type __c = _Traits::eof());
00162 
00163       // Stroustrup, 1998, p 648
00164       // The overflow() function is called to transfer characters to the
00165       // real output destination when the buffer is full. A call to
00166       // overflow(c) outputs the contents of the buffer plus the
00167       // character c.
00168       // 27.5.2.4.5
00169       // Consume some sequence of the characters in the pending sequence.
00170       int_type
00171       _M_really_overflow(int_type __c = _Traits::eof());
00172 
00173       // Convert internal byte sequence to external, char-based
00174       // sequence via codecvt.
00175       void
00176       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
00177 
00178       virtual __streambuf_type*
00179       setbuf(char_type* __s, streamsize __n);
00180 
00181       virtual pos_type
00182       seekoff(off_type __off, ios_base::seekdir __way,
00183           ios_base::openmode __mode = ios_base::in | ios_base::out);
00184 
00185       virtual pos_type
00186       seekpos(pos_type __pos,
00187           ios_base::openmode __mode = ios_base::in | ios_base::out);
00188 
00189       virtual int
00190       sync()
00191       {
00192     bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00193 
00194     // Make sure that the internal buffer resyncs its idea of
00195     // the file position with the external file.
00196     if (__testput)
00197       {
00198         // Need to restore current position after the write.
00199         off_type __off = _M_out_cur - _M_out_end;
00200         _M_really_overflow(); // _M_file.sync() will be called within
00201         if (__off)
00202           _M_file.seekoff(__off, ios_base::cur);
00203       }
00204     else
00205       _M_file.sync();
00206     _M_last_overflowed = false;
00207     return 0;
00208       }
00209 
00210       virtual void
00211       imbue(const locale& __loc);
00212 
00213       virtual streamsize
00214       xsgetn(char_type* __s, streamsize __n)
00215       {
00216     streamsize __ret = 0;
00217     // Clear out pback buffer before going on to the real deal...
00218     if (_M_pback_init)
00219       {
00220         while (__ret < __n && _M_in_cur < _M_in_end)
00221           {
00222         *__s = *_M_in_cur;
00223         ++__ret;
00224         ++__s;
00225         ++_M_in_cur;
00226           }
00227         _M_pback_destroy();
00228       }
00229     if (__ret < __n)
00230       __ret += __streambuf_type::xsgetn(__s, __n - __ret);
00231     return __ret;
00232       }
00233 
00234       virtual streamsize
00235       xsputn(const char_type* __s, streamsize __n)
00236       {
00237     _M_pback_destroy();
00238     return __streambuf_type::xsputn(__s, __n);
00239       }
00240 
00241       void
00242       _M_output_unshift();
00243 
00244       // These three functions are used to clarify internal buffer
00245       // maintenance. After an overflow, or after a seekoff call that
00246       // started at beg or end, or possibly when the stream becomes
00247       // unbuffered, and a myrid other obscure corner cases, the
00248       // internal buffer does not truly reflect the contents of the
00249       // external buffer. At this point, for whatever reason, it is in
00250       // an indeterminate state.
00251       void
00252       _M_set_indeterminate(void)
00253       {
00254     if (_M_mode & ios_base::in)
00255       this->setg(_M_buf, _M_buf, _M_buf);
00256     if (_M_mode & ios_base::out)
00257       this->setp(_M_buf, _M_buf);
00258     _M_filepos = _M_buf;
00259       }
00260 
00261       void
00262       _M_set_determinate(off_type __off)
00263       {
00264     bool __testin = _M_mode & ios_base::in;
00265     bool __testout = _M_mode & ios_base::out;
00266     if (__testin)
00267       this->setg(_M_buf, _M_buf, _M_buf + __off);
00268     if (__testout)
00269       this->setp(_M_buf, _M_buf + __off);
00270     _M_filepos = _M_buf + __off;
00271       }
00272 
00273       bool
00274       _M_is_indeterminate(void)
00275       { 
00276     bool __ret = false;
00277     // Don't return true if unbuffered.
00278     if (_M_buf)
00279       {
00280         if (_M_mode & ios_base::in)
00281           __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
00282         if (_M_mode & ios_base::out)
00283           __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
00284       }
00285     return __ret;
00286       }
00287     };
00288 
00289   // Explicit specializations.
00290   template<> 
00291     basic_filebuf<char>::int_type 
00292     basic_filebuf<char>::_M_underflow_common(bool __bump);
00293 
00294  #ifdef _GLIBCPP_USE_WCHAR_T
00295   template<> 
00296     basic_filebuf<wchar_t>::int_type 
00297     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
00298  #endif
00299 
00300   // Generic definitions.
00301   template <typename _CharT, typename _Traits>
00302     basic_filebuf<_CharT, _Traits>::int_type
00303     basic_filebuf<_CharT, _Traits>::underflow() 
00304     { return _M_underflow_common(false); }
00305 
00306   template <typename _CharT, typename _Traits>
00307     basic_filebuf<_CharT, _Traits>::int_type
00308     basic_filebuf<_CharT, _Traits>::uflow() 
00309     { return _M_underflow_common(true); }
00310 
00311 
00312   // 27.8.1.5  Template class basic_ifstream
00316   template<typename _CharT, typename _Traits>
00317     class basic_ifstream : public basic_istream<_CharT, _Traits>
00318     {
00319     public:
00320       // Types:
00321       typedef _CharT                    char_type;
00322       typedef _Traits                   traits_type;
00323       typedef typename traits_type::int_type        int_type;
00324       typedef typename traits_type::pos_type        pos_type;
00325       typedef typename traits_type::off_type        off_type;
00326 
00327       // Non-standard types:
00328       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00329       typedef basic_istream<char_type, traits_type> __istream_type;
00330 
00331     private:
00332       __filebuf_type    _M_filebuf;
00333 
00334     public:
00335      // Constructors/Destructors:
00337       basic_ifstream()
00338       : __istream_type(NULL), _M_filebuf()
00339       { this->init(&_M_filebuf); }
00340 
00349       explicit
00350       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00351       : __istream_type(NULL), _M_filebuf()
00352       {
00353     this->init(&_M_filebuf);
00354     this->open(__s, __mode);
00355       }
00356 
00357       ~basic_ifstream()
00358       { }
00359 
00360       // Members:
00365       __filebuf_type*
00366       rdbuf() const
00367       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00368 
00369       bool
00370       is_open() { return _M_filebuf.is_open(); }
00371 
00372       void
00373       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00374       {
00375     if (!_M_filebuf.open(__s, __mode | ios_base::in))
00376       this->setstate(ios_base::failbit);
00377       }
00378 
00380       void
00381       close()
00382       {
00383     if (!_M_filebuf.close())
00384       this->setstate(ios_base::failbit);
00385       }
00386     };
00387 
00388 
00389   // 27.8.1.8  Template class basic_ofstream
00393   template<typename _CharT, typename _Traits>
00394     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00395     {
00396     public:
00397       // Types:
00398       typedef _CharT                    char_type;
00399       typedef _Traits                   traits_type;
00400       typedef typename traits_type::int_type        int_type;
00401       typedef typename traits_type::pos_type        pos_type;
00402       typedef typename traits_type::off_type        off_type;
00403 
00404       // Non-standard types:
00405       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00406       typedef basic_ostream<char_type, traits_type> __ostream_type;
00407 
00408     private:
00409       __filebuf_type    _M_filebuf;
00410 
00411     public:
00412       // Constructors:
00414       basic_ofstream()
00415       : __ostream_type(NULL), _M_filebuf()
00416       { this->init(&_M_filebuf); }
00417 
00426       explicit
00427       basic_ofstream(const char* __s,
00428              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00429       : __ostream_type(NULL), _M_filebuf()
00430       {
00431     this->init(&_M_filebuf);
00432     this->open(__s, __mode);
00433       }
00434 
00435       ~basic_ofstream()
00436       { }
00437 
00438       // Members:
00443       __filebuf_type*
00444       rdbuf() const
00445       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00446 
00451       bool
00452       is_open() { return _M_filebuf.is_open(); }
00453 
00462       void
00463       open(const char* __s,
00464        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00465       {
00466     if (!_M_filebuf.open(__s, __mode | ios_base::out))
00467       this->setstate(ios_base::failbit);
00468       }
00469 
00471       void
00472       close()
00473       {
00474     if (!_M_filebuf.close())
00475       this->setstate(ios_base::failbit);
00476       }
00477     };
00478 
00479 
00480   // 27.8.1.11  Template class basic_fstream
00484   template<typename _CharT, typename _Traits>
00485     class basic_fstream : public basic_iostream<_CharT, _Traits>
00486     {
00487     public:
00488       // Types:
00489       typedef _CharT                    char_type;
00490       typedef _Traits                   traits_type;
00491       typedef typename traits_type::int_type        int_type;
00492       typedef typename traits_type::pos_type        pos_type;
00493       typedef typename traits_type::off_type        off_type;
00494 
00495       // Non-standard types:
00496       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00497       typedef basic_ios<char_type, traits_type>     __ios_type;
00498       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00499 
00500     private:
00501       __filebuf_type    _M_filebuf;
00502 
00503     public:
00504       // Constructors/destructor:
00506       basic_fstream()
00507       : __iostream_type(NULL), _M_filebuf()
00508       { this->init(&_M_filebuf); }
00509 
00518       explicit
00519       basic_fstream(const char* __s,
00520             ios_base::openmode __mode = ios_base::in | ios_base::out)
00521       : __iostream_type(NULL), _M_filebuf()
00522       {
00523     this->init(&_M_filebuf);
00524     this->open(__s, __mode);
00525       }
00526 
00527       ~basic_fstream()
00528       { }
00529 
00530       // Members:
00535       __filebuf_type*
00536       rdbuf() const
00537       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00538 
00543       bool
00544       is_open() { return _M_filebuf.is_open(); }
00545 
00554       void
00555       open(const char* __s,
00556        ios_base::openmode __mode = ios_base::in | ios_base::out)
00557       {
00558     if (!_M_filebuf.open(__s, __mode))
00559       setstate(ios_base::failbit);
00560       }
00561 
00563       void
00564       close()
00565       {
00566     if (!_M_filebuf.close())
00567       setstate(ios_base::failbit);
00568       }
00569     };
00570 } // namespace std
00571 
00572 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00573 # define export
00574 #endif
00575 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00576 # include <bits/fstream.tcc>
00577 #endif
00578 
00579 #endif

Generated on Tue Dec 23 12:33:40 2003 for libstdc++-v3 Source by doxygen 1.3.4