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 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(); 00145 00146 virtual int_type 00147 uflow(); 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 // Explicit specializations. 00290 template<> 00291 basic_filebuf<char>::int_type 00292 basic_filebuf<char>::_M_underflow_common(bool __bump); 00293 00294 #ifdef _GLIBCPP_USE_WCHAR_T 00295 template<> 00296 basic_filebuf<wchar_t>::int_type 00297 basic_filebuf<wchar_t>::_M_underflow_common(bool __bump); 00298 #endif 00299 00300 // Generic definitions. 00301 template <typename _CharT, typename _Traits> 00302 basic_filebuf<_CharT, _Traits>::int_type 00303 basic_filebuf<_CharT, _Traits>::underflow() 00304 { return _M_underflow_common(false); } 00305 00306 template <typename _CharT, typename _Traits> 00307 basic_filebuf<_CharT, _Traits>::int_type 00308 basic_filebuf<_CharT, _Traits>::uflow() 00309 { return _M_underflow_common(true); } 00310 00311 00312 // 27.8.1.5 Template class basic_ifstream 00316 template<typename _CharT, typename _Traits> 00317 class basic_ifstream : public basic_istream<_CharT, _Traits> 00318 { 00319 public: 00320 // Types: 00321 typedef _CharT char_type; 00322 typedef _Traits traits_type; 00323 typedef typename traits_type::int_type int_type; 00324 typedef typename traits_type::pos_type pos_type; 00325 typedef typename traits_type::off_type off_type; 00326 00327 // Non-standard types: 00328 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00329 typedef basic_istream<char_type, traits_type> __istream_type; 00330 00331 private: 00332 __filebuf_type _M_filebuf; 00333 00334 public: 00335 // Constructors/Destructors: 00337 basic_ifstream() 00338 : __istream_type(NULL), _M_filebuf() 00339 { this->init(&_M_filebuf); } 00340 00349 explicit 00350 basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 00351 : __istream_type(NULL), _M_filebuf() 00352 { 00353 this->init(&_M_filebuf); 00354 this->open(__s, __mode); 00355 } 00356 00357 ~basic_ifstream() 00358 { } 00359 00360 // Members: 00365 __filebuf_type* 00366 rdbuf() const 00367 { return const_cast<__filebuf_type*>(&_M_filebuf); } 00368 00369 bool 00370 is_open() { return _M_filebuf.is_open(); } 00371 00372 void 00373 open(const char* __s, ios_base::openmode __mode = ios_base::in) 00374 { 00375 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 00376 this->setstate(ios_base::failbit); 00377 } 00378 00380 void 00381 close() 00382 { 00383 if (!_M_filebuf.close()) 00384 this->setstate(ios_base::failbit); 00385 } 00386 }; 00387 00388 00389 // 27.8.1.8 Template class basic_ofstream 00393 template<typename _CharT, typename _Traits> 00394 class basic_ofstream : public basic_ostream<_CharT,_Traits> 00395 { 00396 public: 00397 // Types: 00398 typedef _CharT char_type; 00399 typedef _Traits traits_type; 00400 typedef typename traits_type::int_type int_type; 00401 typedef typename traits_type::pos_type pos_type; 00402 typedef typename traits_type::off_type off_type; 00403 00404 // Non-standard types: 00405 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00406 typedef basic_ostream<char_type, traits_type> __ostream_type; 00407 00408 private: 00409 __filebuf_type _M_filebuf; 00410 00411 public: 00412 // Constructors: 00414 basic_ofstream() 00415 : __ostream_type(NULL), _M_filebuf() 00416 { this->init(&_M_filebuf); } 00417 00426 explicit 00427 basic_ofstream(const char* __s, 00428 ios_base::openmode __mode = ios_base::out|ios_base::trunc) 00429 : __ostream_type(NULL), _M_filebuf() 00430 { 00431 this->init(&_M_filebuf); 00432 this->open(__s, __mode); 00433 } 00434 00435 ~basic_ofstream() 00436 { } 00437 00438 // Members: 00443 __filebuf_type* 00444 rdbuf() const 00445 { return const_cast<__filebuf_type*>(&_M_filebuf); } 00446 00451 bool 00452 is_open() { return _M_filebuf.is_open(); } 00453 00462 void 00463 open(const char* __s, 00464 ios_base::openmode __mode = ios_base::out | ios_base::trunc) 00465 { 00466 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 00467 this->setstate(ios_base::failbit); 00468 } 00469 00471 void 00472 close() 00473 { 00474 if (!_M_filebuf.close()) 00475 this->setstate(ios_base::failbit); 00476 } 00477 }; 00478 00479 00480 // 27.8.1.11 Template class basic_fstream 00484 template<typename _CharT, typename _Traits> 00485 class basic_fstream : public basic_iostream<_CharT, _Traits> 00486 { 00487 public: 00488 // Types: 00489 typedef _CharT char_type; 00490 typedef _Traits traits_type; 00491 typedef typename traits_type::int_type int_type; 00492 typedef typename traits_type::pos_type pos_type; 00493 typedef typename traits_type::off_type off_type; 00494 00495 // Non-standard types: 00496 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00497 typedef basic_ios<char_type, traits_type> __ios_type; 00498 typedef basic_iostream<char_type, traits_type> __iostream_type; 00499 00500 private: 00501 __filebuf_type _M_filebuf; 00502 00503 public: 00504 // Constructors/destructor: 00506 basic_fstream() 00507 : __iostream_type(NULL), _M_filebuf() 00508 { this->init(&_M_filebuf); } 00509 00518 explicit 00519 basic_fstream(const char* __s, 00520 ios_base::openmode __mode = ios_base::in | ios_base::out) 00521 : __iostream_type(NULL), _M_filebuf() 00522 { 00523 this->init(&_M_filebuf); 00524 this->open(__s, __mode); 00525 } 00526 00527 ~basic_fstream() 00528 { } 00529 00530 // Members: 00535 __filebuf_type* 00536 rdbuf() const 00537 { return const_cast<__filebuf_type*>(&_M_filebuf); } 00538 00543 bool 00544 is_open() { return _M_filebuf.is_open(); } 00545 00554 void 00555 open(const char* __s, 00556 ios_base::openmode __mode = ios_base::in | ios_base::out) 00557 { 00558 if (!_M_filebuf.open(__s, __mode)) 00559 setstate(ios_base::failbit); 00560 } 00561 00563 void 00564 close() 00565 { 00566 if (!_M_filebuf.close()) 00567 setstate(ios_base::failbit); 00568 } 00569 }; 00570 } // namespace std 00571 00572 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 00573 # define export 00574 #endif 00575 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS 00576 # include <bits/fstream.tcc> 00577 #endif 00578 00579 #endif

Generated on Wed Sep 29 13:54:47 2004 for libstdc++-v3 Source by doxygen 1.3.7