00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _CPP_BITS_FSTREAM_TCC
00036 #define _CPP_BITS_FSTREAM_TCC 1
00037
00038 #pragma GCC system_header
00039
00040 namespace std
00041 {
00042 template<typename _CharT, typename _Traits>
00043 void
00044 basic_filebuf<_CharT, _Traits>::
00045 _M_allocate_internal_buffer()
00046 {
00047 if (!_M_buf && _M_buf_size_opt)
00048 {
00049 _M_buf_size = _M_buf_size_opt;
00050
00051
00052 _M_buf = new char_type[_M_buf_size];
00053 _M_buf_allocated = true;
00054 }
00055 }
00056
00057
00058 template<typename _CharT, typename _Traits>
00059 void
00060 basic_filebuf<_CharT, _Traits>::
00061 _M_destroy_internal_buffer()
00062 {
00063 if (_M_buf_allocated)
00064 {
00065 delete [] _M_buf;
00066 _M_buf = NULL;
00067 _M_buf_allocated = false;
00068 this->setg(NULL, NULL, NULL);
00069 this->setp(NULL, NULL);
00070 }
00071 }
00072
00073 template<typename _CharT, typename _Traits>
00074 basic_filebuf<_CharT, _Traits>::
00075 basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
00076 _M_state_cur(__state_type()), _M_state_beg(__state_type()),
00077 _M_buf_allocated(false), _M_last_overflowed(false)
00078 { _M_buf_unified = true; }
00079
00080 template<typename _CharT, typename _Traits>
00081 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00082 basic_filebuf<_CharT, _Traits>::
00083 open(const char* __s, ios_base::openmode __mode)
00084 {
00085 __filebuf_type *__ret = NULL;
00086 if (!this->is_open())
00087 {
00088 _M_file.open(__s, __mode);
00089 if (this->is_open())
00090 {
00091 _M_allocate_internal_buffer();
00092 _M_mode = __mode;
00093 _M_set_indeterminate();
00094
00095 if ((__mode & ios_base::ate)
00096 && this->seekoff(0, ios_base::end, __mode) < 0)
00097 {
00098
00099 this->close();
00100 return __ret;
00101 }
00102
00103 __ret = this;
00104 }
00105 }
00106 return __ret;
00107 }
00108
00109 template<typename _CharT, typename _Traits>
00110 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00111 basic_filebuf<_CharT, _Traits>::
00112 close()
00113 {
00114 __filebuf_type *__ret = NULL;
00115 if (this->is_open())
00116 {
00117 const int_type __eof = traits_type::eof();
00118 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00119 if (__testput
00120 && traits_type::eq_int_type(_M_really_overflow(__eof), __eof))
00121 return __ret;
00122
00123
00124 _M_mode = ios_base::openmode(0);
00125 _M_destroy_internal_buffer();
00126 _M_pback_destroy();
00127
00128 #if 0
00129
00130 if (_M_last_overflowed)
00131 {
00132 _M_output_unshift();
00133 _M_really_overflow(__eof);
00134 }
00135 #endif
00136
00137 if (_M_file.close())
00138 __ret = this;
00139 }
00140
00141 _M_last_overflowed = false;
00142 return __ret;
00143 }
00144
00145 template<typename _CharT, typename _Traits>
00146 streamsize
00147 basic_filebuf<_CharT, _Traits>::
00148 showmanyc()
00149 {
00150 streamsize __ret = -1;
00151 bool __testin = _M_mode & ios_base::in;
00152
00153 if (__testin && this->is_open())
00154 __ret = _M_in_end - _M_in_cur;
00155 _M_last_overflowed = false;
00156 return __ret;
00157 }
00158
00159 template<typename _CharT, typename _Traits>
00160 typename basic_filebuf<_CharT, _Traits>::int_type
00161 basic_filebuf<_CharT, _Traits>::
00162 pbackfail(int_type __i)
00163 {
00164 int_type __ret = traits_type::eof();
00165 bool __testin = _M_mode & ios_base::in;
00166
00167 if (__testin)
00168 {
00169 bool __testpb = _M_in_beg < _M_in_cur;
00170 char_type __c = traits_type::to_char_type(__i);
00171 bool __testeof = traits_type::eq_int_type(__i, __ret);
00172
00173 if (__testpb)
00174 {
00175 bool __testout = _M_mode & ios_base::out;
00176 bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
00177
00178
00179
00180 if (!__testeof && __testeq)
00181 {
00182 --_M_in_cur;
00183 if (__testout)
00184 --_M_out_cur;
00185 __ret = __i;
00186 }
00187 else if (__testeof)
00188 {
00189 --_M_in_cur;
00190 if (__testout)
00191 --_M_out_cur;
00192 __ret = traits_type::not_eof(__i);
00193 }
00194 else if (!__testeof)
00195 {
00196 --_M_in_cur;
00197 if (__testout)
00198 --_M_out_cur;
00199 _M_pback_create();
00200 *_M_in_cur = __c;
00201 __ret = __i;
00202 }
00203 }
00204 else
00205 {
00206
00207
00208 this->seekoff(-1, ios_base::cur);
00209 this->underflow();
00210 if (!__testeof)
00211 {
00212 if (!traits_type::eq(__c, *_M_in_cur))
00213 {
00214 _M_pback_create();
00215 *_M_in_cur = __c;
00216 }
00217 __ret = __i;
00218 }
00219 else
00220 __ret = traits_type::not_eof(__i);
00221 }
00222 }
00223 _M_last_overflowed = false;
00224 return __ret;
00225 }
00226
00227 template<typename _CharT, typename _Traits>
00228 typename basic_filebuf<_CharT, _Traits>::int_type
00229 basic_filebuf<_CharT, _Traits>::
00230 overflow(int_type __c)
00231 {
00232 int_type __ret = traits_type::eof();
00233 bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
00234 bool __testout = _M_mode & ios_base::out;
00235
00236 if (__testout)
00237 {
00238 if (__testput)
00239 {
00240 *_M_out_cur = traits_type::to_char_type(__c);
00241 _M_out_cur_move(1);
00242 __ret = traits_type::not_eof(__c);
00243 }
00244 else
00245 __ret = this->_M_really_overflow(__c);
00246 }
00247
00248 _M_last_overflowed = false;
00249 return __ret;
00250 }
00251
00252 template<typename _CharT, typename _Traits>
00253 void
00254 basic_filebuf<_CharT, _Traits>::
00255 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
00256 streamsize& __elen, streamsize& __plen)
00257 {
00258 const locale __loc = this->getloc();
00259 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00260
00261 if (__cvt.always_noconv() && __ilen)
00262 {
00263 __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00264 __plen += __ilen;
00265 }
00266 else
00267 {
00268
00269 int __ext_multiplier = __cvt.encoding();
00270 if (__ext_multiplier == -1 || __ext_multiplier == 0)
00271 __ext_multiplier = sizeof(char_type);
00272 streamsize __blen = __ilen * __ext_multiplier;
00273 char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00274 char* __bend;
00275 const char_type* __iend;
00276 __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
00277 __iend, __buf, __buf + __blen, __bend);
00278
00279 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
00280 __blen = __bend - __buf;
00281
00282 else if (__r == codecvt_base::noconv)
00283 {
00284 __buf = reinterpret_cast<char*>(__ibuf);
00285 __blen = __ilen;
00286 }
00287
00288 else
00289 __blen = 0;
00290
00291 if (__blen)
00292 {
00293 __elen += _M_file.xsputn(__buf, __blen);
00294 __plen += __blen;
00295 }
00296
00297
00298 if (__r == codecvt_base::partial)
00299 {
00300 const char_type* __iresume = __iend;
00301 streamsize __rlen = _M_out_end - __iend;
00302 __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
00303 __iend, __buf, __buf + __blen, __bend);
00304 if (__r != codecvt_base::error)
00305 __rlen = __bend - __buf;
00306 else
00307 __rlen = 0;
00308 if (__rlen)
00309 {
00310 __elen += _M_file.xsputn(__buf, __rlen);
00311 __plen += __rlen;
00312 }
00313 }
00314 }
00315 }
00316
00317 template<typename _CharT, typename _Traits>
00318 typename basic_filebuf<_CharT, _Traits>::int_type
00319 basic_filebuf<_CharT, _Traits>::
00320 _M_really_overflow(int_type __c)
00321 {
00322 int_type __ret = traits_type::eof();
00323 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00324 bool __testunbuffered = _M_file.is_open() && !_M_buf_size_opt;
00325
00326 if (__testput || __testunbuffered)
00327 {
00328
00329 streamsize __elen = 0;
00330 streamsize __plen = 0;
00331
00332
00333
00334
00335 if (_M_filepos && _M_filepos != _M_out_beg)
00336 {
00337 off_type __off = _M_out_beg - _M_filepos;
00338 _M_file.seekoff(__off, ios_base::cur);
00339 }
00340
00341
00342
00343 if (!__testunbuffered)
00344 _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg,
00345 __elen, __plen);
00346
00347
00348
00349 if (!traits_type::eq_int_type(__c, traits_type::eof()))
00350 {
00351 char_type __pending = traits_type::to_char_type(__c);
00352 _M_convert_to_external(&__pending, 1, __elen, __plen);
00353
00354
00355 if (__elen == __plen)
00356 {
00357 _M_set_indeterminate();
00358 __ret = traits_type::not_eof(__c);
00359 }
00360 }
00361 else if (!_M_file.sync())
00362 {
00363 _M_set_indeterminate();
00364 __ret = traits_type::not_eof(__c);
00365 }
00366 }
00367 _M_last_overflowed = true;
00368 return __ret;
00369 }
00370
00371 template<typename _CharT, typename _Traits>
00372 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00373 basic_filebuf<_CharT, _Traits>::
00374 setbuf(char_type* __s, streamsize __n)
00375 {
00376 if (!this->is_open() && __s == 0 && __n == 0)
00377 _M_buf_size_opt = 0;
00378 else if (__s && __n)
00379 {
00380
00381
00382
00383
00384
00385 _M_destroy_internal_buffer();
00386
00387
00388 _M_buf = __s;
00389 _M_buf_size_opt = _M_buf_size = __n;
00390 _M_set_indeterminate();
00391 }
00392 _M_last_overflowed = false;
00393 return this;
00394 }
00395
00396 template<typename _CharT, typename _Traits>
00397 typename basic_filebuf<_CharT, _Traits>::pos_type
00398 basic_filebuf<_CharT, _Traits>::
00399 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
00400 {
00401 pos_type __ret = pos_type(off_type(-1));
00402 bool __testin = (ios_base::in & _M_mode & __mode) != 0;
00403 bool __testout = (ios_base::out & _M_mode & __mode) != 0;
00404
00405
00406 int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
00407 if (__width < 0)
00408 __width = 0;
00409 bool __testfail = __off != 0 && __width <= 0;
00410
00411 if (this->is_open() && !__testfail && (__testin || __testout))
00412 {
00413
00414 _M_pback_destroy();
00415
00416 if (__way != ios_base::cur || __off != 0)
00417 {
00418 off_type __computed_off = __width * __off;
00419
00420 bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
00421 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00422
00423
00424 if (__testput || _M_last_overflowed)
00425 {
00426
00427 this->sync();
00428
00429 _M_output_unshift();
00430 }
00431
00432 else if (__testget && __way == ios_base::cur)
00433 __computed_off += _M_in_cur - _M_filepos;
00434
00435 __ret = _M_file.seekoff(__computed_off, __way, __mode);
00436 _M_set_indeterminate();
00437 }
00438
00439
00440 else
00441 {
00442 __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
00443 __ret += max(_M_out_cur, _M_in_cur) - _M_filepos;
00444 }
00445 }
00446 _M_last_overflowed = false;
00447 return __ret;
00448 }
00449
00450 template<typename _CharT, typename _Traits>
00451 typename basic_filebuf<_CharT, _Traits>::pos_type
00452 basic_filebuf<_CharT, _Traits>::
00453 seekpos(pos_type __pos, ios_base::openmode __mode)
00454 {
00455 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00456
00457 return this->seekoff(off_type(__pos), ios_base::beg, __mode);
00458 #endif
00459 }
00460
00461 template<typename _CharT, typename _Traits>
00462 void
00463 basic_filebuf<_CharT, _Traits>::
00464 _M_output_unshift()
00465 { }
00466
00467 template<typename _CharT, typename _Traits>
00468 void
00469 basic_filebuf<_CharT, _Traits>::
00470 imbue(const locale& __loc)
00471 {
00472 bool __testbeg = gptr() == eback() && pptr() == pbase();
00473
00474 if (__testbeg && _M_buf_locale != __loc)
00475 _M_buf_locale = __loc;
00476
00477
00478
00479
00480
00481 _M_last_overflowed = false;
00482 }
00483
00484
00485
00486
00487 extern template class basic_filebuf<char>;
00488 extern template class basic_ifstream<char>;
00489 extern template class basic_ofstream<char>;
00490 extern template class basic_fstream<char>;
00491
00492 #ifdef _GLIBCPP_USE_WCHAR_T
00493 extern template class basic_filebuf<wchar_t>;
00494 extern template class basic_ifstream<wchar_t>;
00495 extern template class basic_ofstream<wchar_t>;
00496 extern template class basic_fstream<wchar_t>;
00497 #endif
00498 }
00499
00500 #endif