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   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() { return _M_underflow_common(false); }
00145 
00146       virtual int_type
00147       uflow() { return _M_underflow_common(true); }
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 
00290 
00291   // 27.8.1.5  Template class basic_ifstream
00295   template<typename _CharT, typename _Traits>
00296     class basic_ifstream : public basic_istream<_CharT, _Traits>
00297     {
00298     public:
00299       // Types:
00300       typedef _CharT                    char_type;
00301       typedef _Traits                   traits_type;
00302       typedef typename traits_type::int_type        int_type;
00303       typedef typename traits_type::pos_type        pos_type;
00304       typedef typename traits_type::off_type        off_type;
00305 
00306       // Non-standard types:
00307       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00308       typedef basic_istream<char_type, traits_type> __istream_type;
00309 
00310     private:
00311       __filebuf_type    _M_filebuf;
00312 
00313     public:
00314      // Constructors/Destructors:
00316       basic_ifstream()
00317       : __istream_type(NULL), _M_filebuf()
00318       { this->init(&_M_filebuf); }
00319 
00328       explicit
00329       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00330       : __istream_type(NULL), _M_filebuf()
00331       {
00332     this->init(&_M_filebuf);
00333     this->open(__s, __mode);
00334       }
00335 
00336       ~basic_ifstream()
00337       { }
00338 
00339       // Members:
00344       __filebuf_type*
00345       rdbuf() const
00346       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00347 
00348       bool
00349       is_open() { return _M_filebuf.is_open(); }
00350 
00351       void
00352       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00353       {
00354     if (!_M_filebuf.open(__s, __mode | ios_base::in))
00355       this->setstate(ios_base::failbit);
00356       }
00357 
00359       void
00360       close()
00361       {
00362     if (!_M_filebuf.close())
00363       this->setstate(ios_base::failbit);
00364       }
00365     };
00366 
00367 
00368   // 27.8.1.8  Template class basic_ofstream
00372   template<typename _CharT, typename _Traits>
00373     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00374     {
00375     public:
00376       // Types:
00377       typedef _CharT                    char_type;
00378       typedef _Traits                   traits_type;
00379       typedef typename traits_type::int_type        int_type;
00380       typedef typename traits_type::pos_type        pos_type;
00381       typedef typename traits_type::off_type        off_type;
00382 
00383       // Non-standard types:
00384       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00385       typedef basic_ostream<char_type, traits_type> __ostream_type;
00386 
00387     private:
00388       __filebuf_type    _M_filebuf;
00389 
00390     public:
00391       // Constructors:
00393       basic_ofstream()
00394       : __ostream_type(NULL), _M_filebuf()
00395       { this->init(&_M_filebuf); }
00396 
00405       explicit
00406       basic_ofstream(const char* __s,
00407              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00408       : __ostream_type(NULL), _M_filebuf()
00409       {
00410     this->init(&_M_filebuf);
00411     this->open(__s, __mode);
00412       }
00413 
00414       ~basic_ofstream()
00415       { }
00416 
00417       // Members:
00422       __filebuf_type*
00423       rdbuf() const
00424       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00425 
00430       bool
00431       is_open() { return _M_filebuf.is_open(); }
00432 
00441       void
00442       open(const char* __s,
00443        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00444       {
00445     if (!_M_filebuf.open(__s, __mode | ios_base::out))
00446       this->setstate(ios_base::failbit);
00447       }
00448 
00450       void
00451       close()
00452       {
00453     if (!_M_filebuf.close())
00454       this->setstate(ios_base::failbit);
00455       }
00456     };
00457 
00458 
00459   // 27.8.1.11  Template class basic_fstream
00463   template<typename _CharT, typename _Traits>
00464     class basic_fstream : public basic_iostream<_CharT, _Traits>
00465     {
00466     public:
00467       // Types:
00468       typedef _CharT                    char_type;
00469       typedef _Traits                   traits_type;
00470       typedef typename traits_type::int_type        int_type;
00471       typedef typename traits_type::pos_type        pos_type;
00472       typedef typename traits_type::off_type        off_type;
00473 
00474       // Non-standard types:
00475       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00476       typedef basic_ios<char_type, traits_type>     __ios_type;
00477       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00478 
00479     private:
00480       __filebuf_type    _M_filebuf;
00481 
00482     public:
00483       // Constructors/destructor:
00485       basic_fstream()
00486       : __iostream_type(NULL), _M_filebuf()
00487       { this->init(&_M_filebuf); }
00488 
00497       explicit
00498       basic_fstream(const char* __s,
00499             ios_base::openmode __mode = ios_base::in | ios_base::out)
00500       : __iostream_type(NULL), _M_filebuf()
00501       {
00502     this->init(&_M_filebuf);
00503     this->open(__s, __mode);
00504       }
00505 
00506       ~basic_fstream()
00507       { }
00508 
00509       // Members:
00514       __filebuf_type*
00515       rdbuf() const
00516       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00517 
00522       bool
00523       is_open() { return _M_filebuf.is_open(); }
00524 
00533       void
00534       open(const char* __s,
00535        ios_base::openmode __mode = ios_base::in | ios_base::out)
00536       {
00537     if (!_M_filebuf.open(__s, __mode))
00538       setstate(ios_base::failbit);
00539       }
00540 
00542       void
00543       close()
00544       {
00545     if (!_M_filebuf.close())
00546       setstate(ios_base::failbit);
00547       }
00548     };
00549 } // namespace std
00550 
00551 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00552 # define export
00553 #endif
00554 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00555 # include <bits/fstream.tcc>
00556 #endif
00557 
00558 #endif

Generated on Wed May 1 19:19:31 2002 for libstdc++-v3 Source by doxygen1.2.15