# 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