Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

std_fstream.h

Go to the documentation of this file.
00001 // File based streams -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 //
00031 // ISO C++ 14882: 27.8  File-based streams
00032 //
00033 
00034 #ifndef _CPP_FSTREAM
00035 #define _CPP_FSTREAM    1
00036 
00037 #pragma GCC system_header
00038 
00039 #include <bits/std_istream.h>
00040 #include <bits/std_ostream.h>
00041 #include <bits/basic_file.h>
00042 #include <bits/std_locale.h>    // For codecvt
00043 #include <bits/c++threads.h>    // For __mutext_type
00044 
00045 namespace std 
00046 {
00047   template<typename _CharT, typename _Traits>
00048     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
00049     {
00050     public:
00051       // Types:
00052       typedef _CharT                                char_type;
00053       typedef _Traits                               traits_type;
00054       typedef typename traits_type::int_type        int_type;
00055       typedef typename traits_type::pos_type        pos_type;
00056       typedef typename traits_type::off_type        off_type;
00057       
00058       // Non-standard Types:
00059       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
00060       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00061       typedef __basic_file<char_type>               __file_type;
00062       typedef typename traits_type::state_type          __state_type;
00063       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
00064       typedef typename __codecvt_type::result           __res_type;
00065       typedef ctype<char_type>                          __ctype_type;
00066 
00067       friend class ios_base; // For sync_with_stdio.
00068 
00069     private:
00070       // Data Members:
00071       // External buffer.
00072       __file_type*      _M_file;
00073 
00074       // Current and beginning state type for codecvt.
00075       __state_type      _M_state_cur;
00076       __state_type      _M_state_beg;   
00077 
00078       // MT lock inherited from libio or other low-level io library.
00079       __c_lock              _M_lock;
00080 
00081       // XXX Needed? 
00082       bool          _M_last_overflowed;  
00083   
00084     public:
00085       // Constructors/destructor:
00086       basic_filebuf();
00087 
00088       // Non-standard ctor:
00089       basic_filebuf(__c_file_type* __f, bool __s, ios_base::openmode __mode);
00090  
00091       virtual 
00092       ~basic_filebuf() 
00093       { 
00094     this->close();
00095     _M_last_overflowed = false;
00096       }
00097 
00098       // Members:
00099       bool 
00100       is_open(void) const { return _M_file ? _M_file->is_open() : false; }
00101     
00102       __filebuf_type* 
00103       open(const char* __s, ios_base::openmode __mode);
00104     
00105       __filebuf_type* 
00106       close(void);
00107 
00108     protected:
00109       // Allocate up pback and internal buffers.
00110       void 
00111       _M_allocate_buffers();
00112 
00113       // Create __file_type object and initialize it properly.
00114       void
00115       _M_filebuf_init();
00116 
00117       // Overridden virtual functions:
00118       virtual streamsize 
00119       showmanyc(void);
00120    
00121       // Stroustrup, 1998, p. 628 
00122       // underflow() and uflow() functions are called to get the next
00123       // charater from the real input source when the buffer is empty.
00124       // Buffered input uses underflow()
00125       virtual int_type 
00126       underflow(void);
00127 
00128       virtual int_type 
00129       pbackfail(int_type __c = _Traits::eof());
00130 
00131       // NB: For what the standard expects of the overflow function,
00132       // see _M_really_overflow(), below. Because basic_streambuf's
00133       // sputc/sputn call overflow directly, and the complications of
00134       // this implementation's setting of the initial pointers all
00135       // equal to _M_buf when initializing, it seems essential to have
00136       // this in actuality be a helper function that checks for the
00137       // eccentricities of this implementation, and then call
00138       // overflow() if indeed the buffer is full.
00139       virtual int_type 
00140       overflow(int_type __c = _Traits::eof());
00141 
00142       // Stroustrup, 1998, p 648
00143       // The overflow() function is called to transfer characters to the
00144       // real output destination when the buffer is full. A call to
00145       // overflow(c) outputs the contents of the buffer plus the
00146       // character c.
00147       // 27.5.2.4.5 
00148       // Consume some sequence of the characters in the pending sequence.
00149       int_type 
00150       _M_really_overflow(int_type __c = _Traits::eof());
00151     
00152       virtual __streambuf_type* 
00153       setbuf(char_type* __s, streamsize __n)
00154       {
00155     if (!this->is_open() && __s == 0 && __n == 0)
00156       {
00157         _M_buf_size = 0;
00158         _M_buf_size_opt = 0;
00159       }
00160     _M_last_overflowed = false; 
00161     return this; 
00162       }
00163     
00164       virtual pos_type 
00165       seekoff(off_type __off, ios_base::seekdir __way,
00166           ios_base::openmode __mode = ios_base::in | ios_base::out);
00167 
00168       virtual pos_type 
00169       seekpos(pos_type __pos,
00170           ios_base::openmode __mode = ios_base::in | ios_base::out);
00171 
00172       virtual int 
00173       sync(void)
00174       {
00175     bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00176     if (__testput)
00177       {
00178             // Make sure that libio resyncs its idea of the file position
00179             // with the external file.
00180             _M_file->sync();
00181 
00182         // Need to restore current position. This interpreted as
00183         // the position of the external byte sequence (_M_file)
00184         // plus the offset in the current internal buffer
00185         // (_M_out_beg - _M_out_cur)
00186         streamoff __cur = _M_file->seekoff(0, ios_base::cur);
00187         off_type __off = _M_out_cur - _M_out_beg;
00188         _M_really_overflow();
00189         _M_file->seekpos(__cur + __off);
00190       }
00191     _M_last_overflowed = false; 
00192     return 0;
00193       }
00194       
00195       virtual void 
00196       imbue(const locale& __loc);
00197 
00198       virtual streamsize 
00199       xsgetn(char_type* __s, streamsize __n)
00200       {
00201     streamsize __ret = 0;
00202     // Clear out pback buffer before going on to the real deal...
00203     if (_M_pback_init)
00204       {
00205         while (__ret < __n && _M_in_cur < _M_in_end)
00206           {
00207         *__s = *_M_in_cur;
00208         ++__ret;
00209         ++__s;
00210         ++_M_in_cur;
00211           }
00212         _M_pback_destroy();
00213       }
00214     if (__ret < __n)
00215       __ret += __streambuf_type::xsgetn(__s, __n - __ret);
00216     return __ret;
00217       }
00218  
00219       virtual streamsize 
00220       xsputn(const char_type* __s, streamsize __n)
00221       {
00222     _M_pback_destroy();
00223     return __streambuf_type::xsputn(__s, __n);
00224       }
00225        
00226       void
00227       _M_output_unshift();
00228     };
00229 
00230 
00231   // 27.8.1.5  Template class basic_ifstream
00232   template<typename _CharT, typename _Traits>
00233     class basic_ifstream : public basic_istream<_CharT, _Traits>
00234     {
00235     public:
00236       // Types:
00237       typedef _CharT                    char_type;
00238       typedef _Traits                   traits_type;
00239       typedef typename traits_type::int_type        int_type;
00240       typedef typename traits_type::pos_type        pos_type;
00241       typedef typename traits_type::off_type        off_type;
00242 
00243       // Non-standard types:
00244       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00245       typedef basic_istream<char_type, traits_type> __istream_type;
00246     
00247       // Constructors/Destructors:
00248       basic_ifstream()
00249       : __istream_type(new __filebuf_type())
00250       { }
00251 
00252       explicit 
00253       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00254       : __istream_type(new __filebuf_type())
00255       { this->open(__s, __mode); }
00256     
00257       ~basic_ifstream()
00258       { 
00259     delete _M_streambuf; 
00260     _M_streambuf = NULL;
00261       }
00262 
00263       // Members:
00264       __filebuf_type* 
00265       rdbuf() const 
00266       { return static_cast<__filebuf_type*>(_M_streambuf); }
00267 
00268       bool 
00269       is_open(void) { return rdbuf()->is_open(); }
00270 
00271       void 
00272       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00273       { 
00274     if (rdbuf()->open(__s, __mode | ios_base::in) == NULL)
00275       this->setstate(ios_base::failbit); 
00276       }
00277 
00278       void 
00279       close(void)
00280       { 
00281     if (!rdbuf()->close())
00282       this->setstate(ios_base::failbit);    
00283       }
00284     };
00285 
00286   
00287   // 27.8.1.8  Template class basic_ofstream
00288   template<typename _CharT, typename _Traits>
00289     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00290     {
00291     public:
00292       // Types:
00293       typedef _CharT                    char_type;
00294       typedef _Traits                   traits_type;
00295       typedef typename traits_type::int_type        int_type;
00296       typedef typename traits_type::pos_type        pos_type;
00297       typedef typename traits_type::off_type        off_type;
00298 
00299       // Non-standard types:
00300       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00301       typedef basic_ostream<char_type, traits_type> __ostream_type;
00302       
00303       // Constructors:
00304       basic_ofstream()
00305       : __ostream_type(new __filebuf_type())
00306       { }
00307       
00308       explicit 
00309       basic_ofstream(const char* __s, 
00310              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00311       : __ostream_type(new __filebuf_type())
00312       { this->open(__s, __mode); }
00313 
00314       ~basic_ofstream()
00315       { 
00316     delete _M_streambuf; 
00317     _M_streambuf = NULL;
00318       }
00319 
00320       // Members:
00321       __filebuf_type* 
00322       rdbuf(void) const
00323       { return static_cast<__filebuf_type*>(_M_streambuf); }
00324  
00325       bool 
00326       is_open(void) { return rdbuf()->is_open(); }
00327 
00328       void 
00329       open(const char* __s, 
00330        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00331       { 
00332     if (!rdbuf()->open(__s, __mode | ios_base::out))
00333       this->setstate(ios_base::failbit); 
00334       }
00335 
00336       void 
00337       close(void)
00338       { 
00339     if (!rdbuf()->close())
00340       setstate(ios_base::failbit); 
00341       }
00342     };
00343 
00344 
00345   // 27.8.1.11  Template class basic_fstream
00346   template<typename _CharT, typename _Traits>
00347     class basic_fstream : public basic_iostream<_CharT, _Traits>
00348     {
00349     public:
00350       // Types:
00351       typedef _CharT                    char_type;
00352       typedef _Traits                   traits_type;
00353       typedef typename traits_type::int_type        int_type;
00354       typedef typename traits_type::pos_type        pos_type;
00355       typedef typename traits_type::off_type        off_type;
00356 
00357       // Non-standard types:
00358       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00359       typedef basic_ios<char_type, traits_type>     __ios_type;
00360       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00361 
00362       // Constructors/destructor:
00363       basic_fstream()
00364       : __iostream_type(new __filebuf_type())
00365       { }
00366 
00367       explicit 
00368       basic_fstream(const char* __s,
00369             ios_base::openmode __mode = ios_base::in | ios_base::out)
00370       : __iostream_type(new __filebuf_type())
00371       { this->open(__s, __mode); }
00372 
00373       ~basic_fstream()
00374       { 
00375     delete _M_streambuf; 
00376     _M_streambuf = NULL;
00377       }
00378     
00379       // Members:
00380       __filebuf_type* 
00381       rdbuf(void) const 
00382       { return static_cast<__filebuf_type*>(_M_streambuf); }
00383 
00384       bool 
00385       is_open(void) { return rdbuf()->is_open(); }
00386 
00387       void 
00388       open(const char* __s, 
00389        ios_base::openmode __mode = ios_base::in | ios_base::out)
00390       { 
00391     if (!rdbuf()->open(__s, __mode))
00392       setstate (ios_base::failbit); 
00393       }
00394 
00395       void 
00396       close(void)
00397       { 
00398     if (!rdbuf()->close())
00399       setstate (ios_base::failbit); 
00400       }
00401     };
00402 } // namespace std
00403 
00404 
00405 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00406 # define export
00407 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00408 # include <bits/fstream.tcc>
00409 #endif
00410 #endif
00411 
00412 #endif  
00413 

Generated at Tue May 1 16:28:38 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001