Whole document tree
    

Whole document tree

std_fstream.h Source File
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/gthr.h>
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       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
00082       bool          _M_buf_allocated;
00083 
00084       // XXX Needed? 
00085       bool          _M_last_overflowed;  
00086   
00087     public:
00088       // Constructors/destructor:
00089       basic_filebuf();
00090 
00091       // Non-standard ctor:
00092       basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, 
00093             int_type __s = static_cast<int_type>(BUFSIZ));
00094  
00095       virtual 
00096       ~basic_filebuf() 
00097       { 
00098     this->close();
00099     _M_last_overflowed = false;
00100       }
00101 
00102       // Members:
00103       bool 
00104       is_open(void) const { return _M_file ? _M_file->is_open() : false; }
00105     
00106       __filebuf_type* 
00107       open(const char* __s, ios_base::openmode __mode);
00108     
00109       __filebuf_type* 
00110       close(void);
00111 
00112     protected:
00113       void 
00114       _M_allocate_internal_buffer();
00115 
00116       void 
00117       _M_destroy_internal_buffer();
00118 
00119       void 
00120       _M_allocate_pback_buffer();
00121 
00122       // Create __file_type object and initialize it properly.
00123       void
00124       _M_allocate_file();
00125 
00126       // Overridden virtual functions:
00127       virtual streamsize 
00128       showmanyc(void);
00129    
00130       // Stroustrup, 1998, p. 628 
00131       // underflow() and uflow() functions are called to get the next
00132       // charater from the real input source when the buffer is empty.
00133       // Buffered input uses underflow()
00134       virtual int_type 
00135       underflow(void);
00136 
00137       virtual int_type 
00138       pbackfail(int_type __c = _Traits::eof());
00139 
00140       // NB: For what the standard expects of the overflow function,
00141       // see _M_really_overflow(), below. Because basic_streambuf's
00142       // sputc/sputn call overflow directly, and the complications of
00143       // this implementation's setting of the initial pointers all
00144       // equal to _M_buf when initializing, it seems essential to have
00145       // this in actuality be a helper function that checks for the
00146       // eccentricities of this implementation, and then call
00147       // overflow() if indeed the buffer is full.
00148       virtual int_type 
00149       overflow(int_type __c = _Traits::eof());
00150 
00151       // Stroustrup, 1998, p 648
00152       // The overflow() function is called to transfer characters to the
00153       // real output destination when the buffer is full. A call to
00154       // overflow(c) outputs the contents of the buffer plus the
00155       // character c.
00156       // 27.5.2.4.5 
00157       // Consume some sequence of the characters in the pending sequence.
00158       int_type 
00159       _M_really_overflow(int_type __c = _Traits::eof());
00160     
00161       virtual __streambuf_type* 
00162       setbuf(char_type* __s, streamsize __n);
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     private:
00248       __filebuf_type    _M_filebuf;
00249 
00250     public:
00251      // Constructors/Destructors:
00252       basic_ifstream()
00253       : __istream_type(NULL), _M_filebuf()
00254       { this->init(&_M_filebuf); }
00255 
00256       explicit 
00257       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
00258       : __istream_type(NULL), _M_filebuf()
00259       { 
00260     this->init(&_M_filebuf); 
00261     this->open(__s, __mode); 
00262       }
00263     
00264       ~basic_ifstream()
00265       { }
00266 
00267       // Members:
00268       __filebuf_type* 
00269       rdbuf() const 
00270       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00271 
00272       bool 
00273       is_open(void) { return _M_filebuf.is_open(); }
00274 
00275       void 
00276       open(const char* __s, ios_base::openmode __mode = ios_base::in)
00277       { 
00278     if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
00279       this->setstate(ios_base::failbit); 
00280       }
00281 
00282       void 
00283       close(void)
00284       { 
00285     if (!_M_filebuf.close())
00286       this->setstate(ios_base::failbit);    
00287       }
00288     };
00289 
00290   
00291   // 27.8.1.8  Template class basic_ofstream
00292   template<typename _CharT, typename _Traits>
00293     class basic_ofstream : public basic_ostream<_CharT,_Traits>
00294     {
00295     public:
00296       // Types:
00297       typedef _CharT                    char_type;
00298       typedef _Traits                   traits_type;
00299       typedef typename traits_type::int_type        int_type;
00300       typedef typename traits_type::pos_type        pos_type;
00301       typedef typename traits_type::off_type        off_type;
00302 
00303       // Non-standard types:
00304       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00305       typedef basic_ostream<char_type, traits_type> __ostream_type;
00306       
00307     private:
00308       __filebuf_type    _M_filebuf;
00309 
00310     public:
00311       // Constructors:
00312       basic_ofstream()
00313       : __ostream_type(NULL), _M_filebuf()
00314       { this->init(&_M_filebuf); }
00315       
00316       explicit 
00317       basic_ofstream(const char* __s, 
00318              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
00319       : __ostream_type(NULL), _M_filebuf()
00320       { 
00321     this->init(&_M_filebuf); 
00322     this->open(__s, __mode); 
00323       }
00324 
00325       ~basic_ofstream()
00326       { }
00327 
00328       // Members:
00329       __filebuf_type* 
00330       rdbuf(void) const
00331       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00332  
00333       bool 
00334       is_open(void) { return _M_filebuf.is_open(); }
00335 
00336       void 
00337       open(const char* __s, 
00338        ios_base::openmode __mode = ios_base::out | ios_base::trunc)
00339       { 
00340     if (!_M_filebuf.open(__s, __mode | ios_base::out))
00341       this->setstate(ios_base::failbit); 
00342       }
00343 
00344       void 
00345       close(void)
00346       { 
00347     if (!_M_filebuf.close())
00348       setstate(ios_base::failbit); 
00349       }
00350     };
00351 
00352 
00353   // 27.8.1.11  Template class basic_fstream
00354   template<typename _CharT, typename _Traits>
00355     class basic_fstream : public basic_iostream<_CharT, _Traits>
00356     {
00357     public:
00358       // Types:
00359       typedef _CharT                    char_type;
00360       typedef _Traits                   traits_type;
00361       typedef typename traits_type::int_type        int_type;
00362       typedef typename traits_type::pos_type        pos_type;
00363       typedef typename traits_type::off_type        off_type;
00364 
00365       // Non-standard types:
00366       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
00367       typedef basic_ios<char_type, traits_type>     __ios_type;
00368       typedef basic_iostream<char_type, traits_type>    __iostream_type;
00369 
00370     private:
00371       __filebuf_type    _M_filebuf;
00372       
00373     public:
00374       // Constructors/destructor:
00375       basic_fstream()
00376       : __iostream_type(NULL), _M_filebuf()
00377       { this->init(&_M_filebuf); }
00378 
00379       explicit 
00380       basic_fstream(const char* __s,
00381             ios_base::openmode __mode = ios_base::in | ios_base::out)
00382       : __iostream_type(NULL), _M_filebuf()
00383       { 
00384     this->init(&_M_filebuf); 
00385     this->open(__s, __mode); 
00386       }
00387  
00388       ~basic_fstream()
00389       { }
00390     
00391       // Members:
00392       __filebuf_type* 
00393       rdbuf(void) const 
00394       { return const_cast<__filebuf_type*>(&_M_filebuf); }
00395 
00396       bool 
00397       is_open(void) { return _M_filebuf.is_open(); }
00398 
00399       void 
00400       open(const char* __s, 
00401        ios_base::openmode __mode = ios_base::in | ios_base::out)
00402       { 
00403     if (!_M_filebuf.open(__s, __mode))
00404       setstate(ios_base::failbit); 
00405       }
00406 
00407       void 
00408       close(void)
00409       { 
00410     if (!_M_filebuf.close())
00411       setstate(ios_base::failbit); 
00412       }
00413     };
00414 } // namespace std
00415 
00416 
00417 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
00418 # define export
00419 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
00420 # include <bits/fstream.tcc>
00421 #endif
00422 #endif
00423 
00424 #endif  
00425 

Generated on Mon Apr 8 03:11:33 2002 for libstdc++-v3 Source by doxygen1.2.15