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 try { _M_buf = new char_type[_M_buf_size]; }
00053 catch(...)
00054 {
00055 delete [] _M_buf;
00056 __throw_exception_again;
00057 }
00058 _M_buf_allocated = true;
00059 }
00060 }
00061
00062
00063 template<typename _CharT, typename _Traits>
00064 void
00065 basic_filebuf<_CharT, _Traits>::
00066 _M_destroy_internal_buffer()
00067 {
00068 if (_M_buf_allocated)
00069 {
00070 delete [] _M_buf;
00071 _M_buf = NULL;
00072 _M_buf_allocated = false;
00073 this->setg(NULL, NULL, NULL);
00074 this->setp(NULL, NULL);
00075 }
00076 }
00077
00078 template<typename _CharT, typename _Traits>
00079 basic_filebuf<_CharT, _Traits>::
00080 basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
00081 _M_state_cur(__state_type()), _M_state_beg(__state_type()),
00082 _M_buf_allocated(false), _M_last_overflowed(false)
00083 { _M_buf_unified = true; }
00084
00085 template<typename _CharT, typename _Traits>
00086 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00087 basic_filebuf<_CharT, _Traits>::
00088 open(const char* __s, ios_base::openmode __mode)
00089 {
00090 __filebuf_type *__ret = NULL;
00091 if (!this->is_open())
00092 {
00093 _M_file.open(__s, __mode);
00094 if (this->is_open())
00095 {
00096 _M_allocate_internal_buffer();
00097 _M_mode = __mode;
00098
00099
00100 _M_set_indeterminate();
00101 if ((__mode & ios_base::ate)
00102 && this->seekoff(0, ios_base::end, __mode) < 0)
00103 this->close();
00104 __ret = this;
00105 }
00106 }
00107 return __ret;
00108 }
00109
00110 template<typename _CharT, typename _Traits>
00111 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00112 basic_filebuf<_CharT, _Traits>::
00113 close()
00114 {
00115 __filebuf_type *__ret = NULL;
00116 if (this->is_open())
00117 {
00118 const int_type __eof = traits_type::eof();
00119 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00120 if (__testput && _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 {
00155 if (_M_in_cur < _M_in_end)
00156 __ret = _M_in_end - _M_in_cur;
00157 else
00158 __ret = 0;
00159 }
00160 _M_last_overflowed = false;
00161 return __ret;
00162 }
00163
00164 template<typename _CharT, typename _Traits>
00165 typename basic_filebuf<_CharT, _Traits>::int_type
00166 basic_filebuf<_CharT, _Traits>::
00167 _M_underflow_common(bool __bump)
00168 {
00169 int_type __ret = traits_type::eof();
00170 bool __testin = _M_mode & ios_base::in;
00171 bool __testout = _M_mode & ios_base::out;
00172
00173 if (__testin)
00174 {
00175
00176
00177
00178 if (_M_pback_init)
00179 {
00180 _M_pback_destroy();
00181 if (_M_in_cur < _M_in_end)
00182 return traits_type::to_int_type(*_M_in_cur);
00183 }
00184
00185
00186 if (_M_buf_size == 1)
00187 {
00188 int_type __c = _M_file.sys_getc();
00189 if (__c != __ret)
00190 {
00191 __ret = __c;
00192 *_M_in_cur = traits_type::to_char_type(__c);
00193 _M_set_determinate(1);
00194 if (__testout)
00195 _M_out_cur = _M_in_cur;
00196 }
00197 return __ret;
00198 }
00199
00200
00201
00202 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
00203 bool __testinit = _M_is_indeterminate();
00204 if (__testget)
00205 {
00206 if (__testout)
00207 _M_really_overflow();
00208 else if (_M_in_cur != _M_filepos)
00209 _M_file.seekoff(_M_in_cur - _M_filepos,
00210 ios_base::cur, ios_base::in);
00211 }
00212
00213 if (__testinit || __testget)
00214 {
00215 const locale __loc = this->getloc();
00216 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00217
00218 streamsize __elen = 0;
00219 streamsize __ilen = 0;
00220 if (__cvt.always_noconv())
00221 {
00222 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
00223 _M_buf_size);
00224 __ilen = __elen;
00225 }
00226 else
00227 {
00228 char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
00229 __elen = _M_file.xsgetn(__buf, _M_buf_size);
00230
00231 const char* __eend;
00232 char_type* __iend;
00233 __res_type __r = __cvt.in(_M_state_cur, __buf,
00234 __buf + __elen, __eend, _M_in_beg,
00235 _M_in_beg + _M_buf_size, __iend);
00236 if (__r == codecvt_base::ok)
00237 __ilen = __iend - _M_in_beg;
00238 else
00239 {
00240
00241 __ilen = 0;
00242 _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
00243 }
00244 }
00245
00246 if (0 < __ilen)
00247 {
00248 _M_set_determinate(__ilen);
00249 if (__testout)
00250 _M_out_cur = _M_in_cur;
00251 __ret = traits_type::to_int_type(*_M_in_cur);
00252 if (__bump)
00253 _M_in_cur_move(1);
00254 }
00255 }
00256 }
00257 _M_last_overflowed = false;
00258 return __ret;
00259 }
00260
00261 template<typename _CharT, typename _Traits>
00262 typename basic_filebuf<_CharT, _Traits>::int_type
00263 basic_filebuf<_CharT, _Traits>::
00264 pbackfail(int_type __i)
00265 {
00266 int_type __ret = traits_type::eof();
00267 bool __testin = _M_mode & ios_base::in;
00268
00269 if (__testin)
00270 {
00271 bool __testpb = _M_in_beg < _M_in_cur;
00272 char_type __c = traits_type::to_char_type(__i);
00273 bool __testeof = traits_type::eq_int_type(__i, __ret);
00274
00275 if (__testpb)
00276 {
00277 bool __testout = _M_mode & ios_base::out;
00278 bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
00279
00280
00281
00282 if (!__testeof && __testeq)
00283 {
00284 --_M_in_cur;
00285 if (__testout)
00286 --_M_out_cur;
00287 __ret = __i;
00288 }
00289 else if (__testeof)
00290 {
00291 --_M_in_cur;
00292 if (__testout)
00293 --_M_out_cur;
00294 __ret = traits_type::not_eof(__i);
00295 }
00296 else if (!__testeof)
00297 {
00298 --_M_in_cur;
00299 if (__testout)
00300 --_M_out_cur;
00301 _M_pback_create();
00302 *_M_in_cur = __c;
00303 __ret = __i;
00304 }
00305 }
00306 else
00307 {
00308
00309
00310 this->seekoff(-1, ios_base::cur);
00311 this->underflow();
00312 if (!__testeof)
00313 {
00314 if (!traits_type::eq(__c, *_M_in_cur))
00315 {
00316 _M_pback_create();
00317 *_M_in_cur = __c;
00318 }
00319 __ret = __i;
00320 }
00321 else
00322 __ret = traits_type::not_eof(__i);
00323 }
00324 }
00325 _M_last_overflowed = false;
00326 return __ret;
00327 }
00328
00329 template<typename _CharT, typename _Traits>
00330 typename basic_filebuf<_CharT, _Traits>::int_type
00331 basic_filebuf<_CharT, _Traits>::
00332 overflow(int_type __c)
00333 {
00334 int_type __ret = traits_type::eof();
00335 bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
00336 bool __testout = _M_mode & ios_base::out;
00337
00338 if (__testout)
00339 {
00340 if (__testput)
00341 {
00342 *_M_out_cur = traits_type::to_char_type(__c);
00343 _M_out_cur_move(1);
00344 __ret = traits_type::not_eof(__c);
00345 }
00346 else
00347 __ret = this->_M_really_overflow(__c);
00348 }
00349
00350 _M_last_overflowed = false;
00351 return __ret;
00352 }
00353
00354 template<typename _CharT, typename _Traits>
00355 void
00356 basic_filebuf<_CharT, _Traits>::
00357 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
00358 streamsize& __elen, streamsize& __plen)
00359 {
00360 const locale __loc = this->getloc();
00361 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00362
00363 if (__cvt.always_noconv() && __ilen)
00364 {
00365 __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00366 __plen += __ilen;
00367 }
00368 else
00369 {
00370
00371 int __ext_multiplier = __cvt.encoding();
00372 if (__ext_multiplier == -1 || __ext_multiplier == 0)
00373 __ext_multiplier = sizeof(char_type);
00374 streamsize __blen = __ilen * __ext_multiplier;
00375 char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00376 char* __bend;
00377 const char_type* __iend;
00378 __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
00379 __iend, __buf, __buf + __blen, __bend);
00380
00381 if (__r != codecvt_base::error)
00382 __blen = __bend - __buf;
00383
00384 else
00385 __blen = 0;
00386
00387 if (__blen)
00388 {
00389 __elen += _M_file.xsputn(__buf, __blen);
00390 __plen += __blen;
00391 }
00392
00393
00394 if (__r == codecvt_base::partial)
00395 {
00396 const char_type* __iresume = __iend;
00397 streamsize __rlen = _M_out_end - __iend;
00398 __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
00399 __iend, __buf, __buf + __blen, __bend);
00400 if (__r != codecvt_base::error)
00401 __rlen = __bend - __buf;
00402 else
00403 __rlen = 0;
00404 if (__rlen)
00405 {
00406 __elen += _M_file.xsputn(__buf, __rlen);
00407 __plen += __rlen;
00408 }
00409 }
00410 }
00411 }
00412
00413 template<typename _CharT, typename _Traits>
00414 typename basic_filebuf<_CharT, _Traits>::int_type
00415 basic_filebuf<_CharT, _Traits>::
00416 _M_really_overflow(int_type __c)
00417 {
00418 int_type __ret = traits_type::eof();
00419 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00420 bool __testunbuffered = _M_file.is_open() && !_M_buf_size;
00421
00422 if (__testput || __testunbuffered)
00423 {
00424
00425 streamsize __elen = 0;
00426 streamsize __plen = 0;
00427
00428
00429
00430
00431 if (_M_filepos && _M_filepos != _M_out_beg)
00432 {
00433 off_type __off = _M_out_beg - _M_filepos;
00434 _M_file.seekoff(__off, ios_base::cur);
00435 }
00436
00437
00438
00439 if (!__testunbuffered)
00440 _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg,
00441 __elen, __plen);
00442
00443
00444
00445 if (!traits_type::eq_int_type(__c, traits_type::eof()))
00446 {
00447 char_type __pending = traits_type::to_char_type(__c);
00448 _M_convert_to_external(&__pending, 1, __elen, __plen);
00449
00450
00451 if (__elen == __plen)
00452 {
00453 _M_set_indeterminate();
00454 __ret = traits_type::not_eof(__c);
00455 }
00456 }
00457 else if (!_M_file.sync())
00458 {
00459 _M_set_indeterminate();
00460 __ret = traits_type::not_eof(__c);
00461 }
00462 }
00463 _M_last_overflowed = true;
00464 return __ret;
00465 }
00466
00467 template<typename _CharT, typename _Traits>
00468 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00469 basic_filebuf<_CharT, _Traits>::
00470 setbuf(char_type* __s, streamsize __n)
00471 {
00472 if (!this->is_open() && __s == 0 && __n == 0)
00473 _M_buf_size_opt = 0;
00474 else if (__s && __n)
00475 {
00476
00477
00478
00479
00480
00481 _M_destroy_internal_buffer();
00482
00483
00484 _M_buf = __s;
00485 _M_buf_size_opt = _M_buf_size = __n;
00486 _M_set_indeterminate();
00487 }
00488 _M_last_overflowed = false;
00489 return this;
00490 }
00491
00492 template<typename _CharT, typename _Traits>
00493 typename basic_filebuf<_CharT, _Traits>::pos_type
00494 basic_filebuf<_CharT, _Traits>::
00495 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
00496 {
00497 pos_type __ret = pos_type(off_type(-1));
00498 bool __testin = (ios_base::in & _M_mode & __mode) != 0;
00499 bool __testout = (ios_base::out & _M_mode & __mode) != 0;
00500
00501
00502 int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
00503 if (__width < 0)
00504 __width = 0;
00505 bool __testfail = __off != 0 && __width <= 0;
00506
00507 if (this->is_open() && !__testfail && (__testin || __testout))
00508 {
00509
00510 _M_pback_destroy();
00511
00512 if (__way != ios_base::cur || __off != 0)
00513 {
00514 off_type __computed_off = __width * __off;
00515
00516 bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
00517 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00518
00519
00520 if (__testput || _M_last_overflowed)
00521 {
00522
00523 this->sync();
00524
00525 _M_output_unshift();
00526 }
00527
00528 else if (__testget && __way == ios_base::cur)
00529 __computed_off += _M_in_cur - _M_filepos;
00530
00531 __ret = _M_file.seekoff(__computed_off, __way, __mode);
00532 _M_set_indeterminate();
00533 }
00534
00535
00536 else
00537 {
00538 __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
00539 __ret += max(_M_out_cur, _M_in_cur) - _M_filepos;
00540 }
00541 }
00542 _M_last_overflowed = false;
00543 return __ret;
00544 }
00545
00546 template<typename _CharT, typename _Traits>
00547 typename basic_filebuf<_CharT, _Traits>::pos_type
00548 basic_filebuf<_CharT, _Traits>::
00549 seekpos(pos_type __pos, ios_base::openmode __mode)
00550 {
00551 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00552
00553 return this->seekoff(off_type(__pos), ios_base::beg, __mode);
00554 #endif
00555 }
00556
00557 template<typename _CharT, typename _Traits>
00558 void
00559 basic_filebuf<_CharT, _Traits>::
00560 _M_output_unshift()
00561 { }
00562
00563 template<typename _CharT, typename _Traits>
00564 void
00565 basic_filebuf<_CharT, _Traits>::
00566 imbue(const locale& __loc)
00567 {
00568 bool __testbeg = gptr() == eback() && pptr() == pbase();
00569
00570 if (__testbeg && _M_buf_locale != __loc)
00571 {
00572 _M_buf_locale = __loc;
00573 _M_buf_locale_init = true;
00574 }
00575
00576
00577
00578
00579
00580 _M_last_overflowed = false;
00581 }
00582
00583
00584
00585
00586 extern template class basic_filebuf<char>;
00587 extern template class basic_filebuf<wchar_t>;
00588 extern template class basic_ifstream<char>;
00589 extern template class basic_ifstream<wchar_t>;
00590 extern template class basic_ofstream<char>;
00591 extern template class basic_ofstream<wchar_t>;
00592 extern template class basic_fstream<char>;
00593 extern template class basic_fstream<wchar_t>;
00594 }
00595
00596 #endif