Whole document tree std_fstream.hGo 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 ![]() |