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
00036
00037
00038
00039
00040 #ifndef _FSTREAM_TCC
00041 #define _FSTREAM_TCC 1
00042
00043 #pragma GCC system_header
00044
00045 namespace std
00046 {
00047 template<typename _CharT, typename _Traits>
00048 void
00049 basic_filebuf<_CharT, _Traits>::
00050 _M_allocate_internal_buffer()
00051 {
00052
00053
00054 if (!_M_buf_allocated && !_M_buf)
00055 {
00056 _M_buf = new char_type[_M_buf_size];
00057 _M_buf_allocated = true;
00058 }
00059 }
00060
00061 template<typename _CharT, typename _Traits>
00062 void
00063 basic_filebuf<_CharT, _Traits>::
00064 _M_destroy_internal_buffer() throw()
00065 {
00066 if (_M_buf_allocated)
00067 {
00068 delete [] _M_buf;
00069 _M_buf = NULL;
00070 _M_buf_allocated = false;
00071 }
00072 delete [] _M_ext_buf;
00073 _M_ext_buf = NULL;
00074 _M_ext_buf_size = 0;
00075 _M_ext_next = NULL;
00076 _M_ext_end = NULL;
00077 }
00078
00079 template<typename _CharT, typename _Traits>
00080 basic_filebuf<_CharT, _Traits>::
00081 basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock),
00082 _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
00083 _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ),
00084 _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
00085 _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
00086 _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
00087 _M_ext_end(0)
00088 {
00089 if (has_facet<__codecvt_type>(this->_M_buf_locale))
00090 _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
00091 }
00092
00093 template<typename _CharT, typename _Traits>
00094 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00095 basic_filebuf<_CharT, _Traits>::
00096 open(const char* __s, ios_base::openmode __mode)
00097 {
00098 __filebuf_type *__ret = NULL;
00099 if (!this->is_open())
00100 {
00101 _M_file.open(__s, __mode);
00102 if (this->is_open())
00103 {
00104 _M_allocate_internal_buffer();
00105 _M_mode = __mode;
00106
00107
00108 _M_reading = false;
00109 _M_writing = false;
00110 _M_set_buffer(-1);
00111
00112
00113 _M_state_last = _M_state_cur = _M_state_beg;
00114
00115
00116 if ((__mode & ios_base::ate)
00117 && this->seekoff(0, ios_base::end, __mode)
00118 == pos_type(off_type(-1)))
00119 this->close();
00120 else
00121 __ret = this;
00122 }
00123 }
00124 return __ret;
00125 }
00126
00127 template<typename _CharT, typename _Traits>
00128 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00129 basic_filebuf<_CharT, _Traits>::
00130 close() throw()
00131 {
00132 __filebuf_type* __ret = NULL;
00133 if (this->is_open())
00134 {
00135 bool __testfail = false;
00136 try
00137 {
00138 if (!_M_terminate_output())
00139 __testfail = true;
00140 }
00141 catch(...)
00142 { __testfail = true; }
00143
00144
00145 _M_mode = ios_base::openmode(0);
00146 _M_pback_init = false;
00147 _M_destroy_internal_buffer();
00148 _M_reading = false;
00149 _M_writing = false;
00150 _M_set_buffer(-1);
00151 _M_state_last = _M_state_cur = _M_state_beg;
00152
00153 if (!_M_file.close())
00154 __testfail = true;
00155
00156 if (!__testfail)
00157 __ret = this;
00158 }
00159 return __ret;
00160 }
00161
00162 template<typename _CharT, typename _Traits>
00163 streamsize
00164 basic_filebuf<_CharT, _Traits>::
00165 showmanyc()
00166 {
00167 streamsize __ret = -1;
00168 const bool __testin = _M_mode & ios_base::in;
00169 if (__testin && this->is_open())
00170 {
00171
00172
00173 __ret = this->egptr() - this->gptr();
00174
00175 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
00176
00177 const bool __testbinary = _M_mode & ios_base::binary;
00178 if (__check_facet(_M_codecvt).encoding() >= 0
00179 && __testbinary)
00180 #else
00181 if (__check_facet(_M_codecvt).encoding() >= 0)
00182 #endif
00183 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
00184 }
00185 return __ret;
00186 }
00187
00188 template<typename _CharT, typename _Traits>
00189 typename basic_filebuf<_CharT, _Traits>::int_type
00190 basic_filebuf<_CharT, _Traits>::
00191 underflow()
00192 {
00193 int_type __ret = traits_type::eof();
00194 const bool __testin = _M_mode & ios_base::in;
00195 if (__testin && !_M_writing)
00196 {
00197
00198
00199
00200 _M_destroy_pback();
00201
00202 if (this->gptr() < this->egptr())
00203 return traits_type::to_int_type(*this->gptr());
00204
00205
00206 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
00207
00208
00209 bool __got_eof = false;
00210
00211 streamsize __ilen = 0;
00212 codecvt_base::result __r = codecvt_base::ok;
00213 if (__check_facet(_M_codecvt).always_noconv())
00214 {
00215 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
00216 __buflen);
00217 if (__ilen == 0)
00218 __got_eof = true;
00219 }
00220 else
00221 {
00222
00223
00224 const int __enc = _M_codecvt->encoding();
00225 streamsize __blen;
00226 streamsize __rlen;
00227 if (__enc > 0)
00228 __blen = __rlen = __buflen * __enc;
00229 else
00230 {
00231 __blen = __buflen + _M_codecvt->max_length() - 1;
00232 __rlen = __buflen;
00233 }
00234 const streamsize __remainder = _M_ext_end - _M_ext_next;
00235 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
00236
00237
00238
00239 if (_M_reading && this->egptr() == this->eback() && __remainder)
00240 __rlen = 0;
00241
00242
00243
00244 if (_M_ext_buf_size < __blen)
00245 {
00246 char* __buf = new char[__blen];
00247 if (__remainder)
00248 std::memcpy(__buf, _M_ext_next, __remainder);
00249
00250 delete [] _M_ext_buf;
00251 _M_ext_buf = __buf;
00252 _M_ext_buf_size = __blen;
00253 }
00254 else if (__remainder)
00255 std::memmove(_M_ext_buf, _M_ext_next, __remainder);
00256
00257 _M_ext_next = _M_ext_buf;
00258 _M_ext_end = _M_ext_buf + __remainder;
00259 _M_state_last = _M_state_cur;
00260
00261 do
00262 {
00263 if (__rlen > 0)
00264 {
00265
00266
00267
00268 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
00269 {
00270 __throw_ios_failure(__N("basic_filebuf::underflow "
00271 "codecvt::max_length() "
00272 "is not valid"));
00273 }
00274 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
00275 if (__elen == 0)
00276 __got_eof = true;
00277 else if (__elen == -1)
00278 break;
00279 _M_ext_end += __elen;
00280 }
00281
00282 char_type* __iend;
00283 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
00284 _M_ext_end, _M_ext_next, this->eback(),
00285 this->eback() + __buflen, __iend);
00286 if (__r == codecvt_base::noconv)
00287 {
00288 size_t __avail = _M_ext_end - _M_ext_buf;
00289 __ilen = std::min(__avail, __buflen);
00290 traits_type::copy(this->eback(),
00291 reinterpret_cast<char_type*>(_M_ext_buf), __ilen);
00292 _M_ext_next = _M_ext_buf + __ilen;
00293 }
00294 else
00295 __ilen = __iend - this->eback();
00296
00297
00298
00299
00300 if (__r == codecvt_base::error)
00301 break;
00302
00303 __rlen = 1;
00304 }
00305 while (__ilen == 0 && !__got_eof);
00306 }
00307
00308 if (__ilen > 0)
00309 {
00310 _M_set_buffer(__ilen);
00311 _M_reading = true;
00312 __ret = traits_type::to_int_type(*this->gptr());
00313 }
00314 else if (__got_eof)
00315 {
00316
00317
00318
00319 _M_set_buffer(-1);
00320 _M_reading = false;
00321
00322
00323 if (__r == codecvt_base::partial)
00324 __throw_ios_failure(__N("basic_filebuf::underflow "
00325 "incomplete character in file"));
00326 }
00327 else if (__r == codecvt_base::error)
00328 __throw_ios_failure(__N("basic_filebuf::underflow "
00329 "invalid byte sequence in file"));
00330 else
00331 __throw_ios_failure(__N("basic_filebuf::underflow "
00332 "error reading the file"));
00333 }
00334 return __ret;
00335 }
00336
00337 template<typename _CharT, typename _Traits>
00338 typename basic_filebuf<_CharT, _Traits>::int_type
00339 basic_filebuf<_CharT, _Traits>::
00340 pbackfail(int_type __i)
00341 {
00342 int_type __ret = traits_type::eof();
00343 const bool __testin = _M_mode & ios_base::in;
00344 if (__testin && !_M_writing)
00345 {
00346
00347
00348 const bool __testpb = _M_pback_init;
00349 const bool __testeof = traits_type::eq_int_type(__i, __ret);
00350 int_type __tmp;
00351 if (this->eback() < this->gptr())
00352 {
00353 this->gbump(-1);
00354 __tmp = traits_type::to_int_type(*this->gptr());
00355 }
00356 else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1)))
00357 {
00358 __tmp = this->underflow();
00359 if (traits_type::eq_int_type(__tmp, __ret))
00360 return __ret;
00361 }
00362 else
00363 {
00364
00365
00366
00367
00368
00369 return __ret;
00370 }
00371
00372
00373
00374 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
00375 __ret = __i;
00376 else if (__testeof)
00377 __ret = traits_type::not_eof(__i);
00378 else if (!__testpb)
00379 {
00380 _M_create_pback();
00381 _M_reading = true;
00382 *this->gptr() = traits_type::to_char_type(__i);
00383 __ret = __i;
00384 }
00385 }
00386 return __ret;
00387 }
00388
00389 template<typename _CharT, typename _Traits>
00390 typename basic_filebuf<_CharT, _Traits>::int_type
00391 basic_filebuf<_CharT, _Traits>::
00392 overflow(int_type __c)
00393 {
00394 int_type __ret = traits_type::eof();
00395 const bool __testeof = traits_type::eq_int_type(__c, __ret);
00396 const bool __testout = _M_mode & ios_base::out;
00397 if (__testout && !_M_reading)
00398 {
00399 if (this->pbase() < this->pptr())
00400 {
00401
00402 if (!__testeof)
00403 {
00404 *this->pptr() = traits_type::to_char_type(__c);
00405 this->pbump(1);
00406 }
00407
00408
00409
00410 if (_M_convert_to_external(this->pbase(),
00411 this->pptr() - this->pbase()))
00412 {
00413 _M_set_buffer(0);
00414 __ret = traits_type::not_eof(__c);
00415 }
00416 }
00417 else if (_M_buf_size > 1)
00418 {
00419
00420
00421
00422 _M_set_buffer(0);
00423 _M_writing = true;
00424 if (!__testeof)
00425 {
00426 *this->pptr() = traits_type::to_char_type(__c);
00427 this->pbump(1);
00428 }
00429 __ret = traits_type::not_eof(__c);
00430 }
00431 else
00432 {
00433
00434 char_type __conv = traits_type::to_char_type(__c);
00435 if (__testeof || _M_convert_to_external(&__conv, 1))
00436 {
00437 _M_writing = true;
00438 __ret = traits_type::not_eof(__c);
00439 }
00440 }
00441 }
00442 return __ret;
00443 }
00444
00445 template<typename _CharT, typename _Traits>
00446 bool
00447 basic_filebuf<_CharT, _Traits>::
00448 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
00449 {
00450
00451 streamsize __elen;
00452 streamsize __plen;
00453 if (__check_facet(_M_codecvt).always_noconv())
00454 {
00455 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00456 __plen = __ilen;
00457 }
00458 else
00459 {
00460
00461
00462 streamsize __blen = __ilen * _M_codecvt->max_length();
00463 char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00464
00465 char* __bend;
00466 const char_type* __iend;
00467 codecvt_base::result __r;
00468 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
00469 __iend, __buf, __buf + __blen, __bend);
00470
00471 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
00472 __blen = __bend - __buf;
00473 else if (__r == codecvt_base::noconv)
00474 {
00475
00476 __buf = reinterpret_cast<char*>(__ibuf);
00477 __blen = __ilen;
00478 }
00479 else
00480 __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
00481 "conversion error"));
00482
00483 __elen = _M_file.xsputn(__buf, __blen);
00484 __plen = __blen;
00485
00486
00487 if (__r == codecvt_base::partial && __elen == __plen)
00488 {
00489 const char_type* __iresume = __iend;
00490 streamsize __rlen = this->pptr() - __iend;
00491 __r = _M_codecvt->out(_M_state_cur, __iresume,
00492 __iresume + __rlen, __iend, __buf,
00493 __buf + __blen, __bend);
00494 if (__r != codecvt_base::error)
00495 {
00496 __rlen = __bend - __buf;
00497 __elen = _M_file.xsputn(__buf, __rlen);
00498 __plen = __rlen;
00499 }
00500 else
00501 __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
00502 "conversion error"));
00503 }
00504 }
00505 return __elen == __plen;
00506 }
00507
00508 template<typename _CharT, typename _Traits>
00509 streamsize
00510 basic_filebuf<_CharT, _Traits>::
00511 xsgetn(_CharT* __s, streamsize __n)
00512 {
00513
00514 streamsize __ret = 0;
00515 if (_M_pback_init)
00516 {
00517 if (__n > 0 && this->gptr() == this->eback())
00518 {
00519 *__s++ = *this->gptr();
00520 this->gbump(1);
00521 __ret = 1;
00522 --__n;
00523 }
00524 _M_destroy_pback();
00525 }
00526
00527
00528
00529
00530 const bool __testin = _M_mode & ios_base::in;
00531 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
00532
00533 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
00534 && __testin && !_M_writing)
00535 {
00536
00537 const streamsize __avail = this->egptr() - this->gptr();
00538 if (__avail != 0)
00539 {
00540 if (__avail == 1)
00541 *__s = *this->gptr();
00542 else
00543 traits_type::copy(__s, this->gptr(), __avail);
00544 __s += __avail;
00545 this->gbump(__avail);
00546 __ret += __avail;
00547 __n -= __avail;
00548 }
00549
00550
00551
00552 streamsize __len;
00553 for (;;)
00554 {
00555 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
00556 __n);
00557 if (__len == -1)
00558 __throw_ios_failure(__N("basic_filebuf::xsgetn "
00559 "error reading the file"));
00560 if (__len == 0)
00561 break;
00562
00563 __n -= __len;
00564 __ret += __len;
00565 if (__n == 0)
00566 break;
00567
00568 __s += __len;
00569 }
00570
00571 if (__n == 0)
00572 {
00573 _M_set_buffer(0);
00574 _M_reading = true;
00575 }
00576 else if (__len == 0)
00577 {
00578
00579
00580
00581 _M_set_buffer(-1);
00582 _M_reading = false;
00583 }
00584 }
00585 else
00586 __ret += __streambuf_type::xsgetn(__s, __n);
00587
00588 return __ret;
00589 }
00590
00591 template<typename _CharT, typename _Traits>
00592 streamsize
00593 basic_filebuf<_CharT, _Traits>::
00594 xsputn(const _CharT* __s, streamsize __n)
00595 {
00596
00597
00598
00599 streamsize __ret = 0;
00600 const bool __testout = _M_mode & ios_base::out;
00601 if (__check_facet(_M_codecvt).always_noconv()
00602 && __testout && !_M_reading)
00603 {
00604
00605 const streamsize __chunk = 1ul << 10;
00606 streamsize __bufavail = this->epptr() - this->pptr();
00607
00608
00609 if (!_M_writing && _M_buf_size > 1)
00610 __bufavail = _M_buf_size - 1;
00611
00612 const streamsize __limit = std::min(__chunk, __bufavail);
00613 if (__n >= __limit)
00614 {
00615 const streamsize __buffill = this->pptr() - this->pbase();
00616 const char* __buf = reinterpret_cast<const char*>(this->pbase());
00617 __ret = _M_file.xsputn_2(__buf, __buffill,
00618 reinterpret_cast<const char*>(__s),
00619 __n);
00620 if (__ret == __buffill + __n)
00621 {
00622 _M_set_buffer(0);
00623 _M_writing = true;
00624 }
00625 if (__ret > __buffill)
00626 __ret -= __buffill;
00627 else
00628 __ret = 0;
00629 }
00630 else
00631 __ret = __streambuf_type::xsputn(__s, __n);
00632 }
00633 else
00634 __ret = __streambuf_type::xsputn(__s, __n);
00635 return __ret;
00636 }
00637
00638 template<typename _CharT, typename _Traits>
00639 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00640 basic_filebuf<_CharT, _Traits>::
00641 setbuf(char_type* __s, streamsize __n)
00642 {
00643 if (!this->is_open())
00644 if (__s == 0 && __n == 0)
00645 _M_buf_size = 1;
00646 else if (__s && __n > 0)
00647 {
00648
00649
00650
00651
00652
00653
00654
00655
00656 _M_buf = __s;
00657 _M_buf_size = __n;
00658 }
00659 return this;
00660 }
00661
00662
00663
00664
00665 template<typename _CharT, typename _Traits>
00666 typename basic_filebuf<_CharT, _Traits>::pos_type
00667 basic_filebuf<_CharT, _Traits>::
00668 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
00669 {
00670 int __width = 0;
00671 if (_M_codecvt)
00672 __width = _M_codecvt->encoding();
00673 if (__width < 0)
00674 __width = 0;
00675
00676 pos_type __ret = pos_type(off_type(-1));
00677 const bool __testfail = __off != 0 && __width <= 0;
00678 if (this->is_open() && !__testfail)
00679 {
00680
00681 _M_destroy_pback();
00682
00683
00684
00685
00686
00687
00688 __state_type __state = _M_state_beg;
00689 off_type __computed_off = __off * __width;
00690 if (_M_reading && __way == ios_base::cur)
00691 {
00692 if (_M_codecvt->always_noconv())
00693 __computed_off += this->gptr() - this->egptr();
00694 else
00695 {
00696
00697
00698
00699 const int __gptr_off =
00700 _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
00701 this->gptr() - this->eback());
00702 __computed_off += _M_ext_buf + __gptr_off - _M_ext_end;
00703
00704
00705
00706 __state = _M_state_last;
00707 }
00708 }
00709 __ret = _M_seek(__computed_off, __way, __state);
00710 }
00711 return __ret;
00712 }
00713
00714
00715
00716
00717
00718 template<typename _CharT, typename _Traits>
00719 typename basic_filebuf<_CharT, _Traits>::pos_type
00720 basic_filebuf<_CharT, _Traits>::
00721 seekpos(pos_type __pos, ios_base::openmode)
00722 {
00723 pos_type __ret = pos_type(off_type(-1));
00724 if (this->is_open())
00725 {
00726
00727 _M_destroy_pback();
00728 __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
00729 }
00730 return __ret;
00731 }
00732
00733 template<typename _CharT, typename _Traits>
00734 typename basic_filebuf<_CharT, _Traits>::pos_type
00735 basic_filebuf<_CharT, _Traits>::
00736 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
00737 {
00738 pos_type __ret = pos_type(off_type(-1));
00739 if (_M_terminate_output())
00740 {
00741
00742 __ret = pos_type(_M_file.seekoff(__off, __way));
00743 _M_reading = false;
00744 _M_writing = false;
00745 _M_ext_next = _M_ext_end = _M_ext_buf;
00746 _M_set_buffer(-1);
00747 _M_state_cur = __state;
00748 __ret.state(_M_state_cur);
00749 }
00750 return __ret;
00751 }
00752
00753 template<typename _CharT, typename _Traits>
00754 bool
00755 basic_filebuf<_CharT, _Traits>::
00756 _M_terminate_output()
00757 {
00758
00759 bool __testvalid = true;
00760 if (this->pbase() < this->pptr())
00761 {
00762 const int_type __tmp = this->overflow();
00763 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00764 __testvalid = false;
00765 }
00766
00767
00768 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
00769 && __testvalid)
00770 {
00771
00772
00773
00774 const size_t __blen = 128;
00775 char __buf[__blen];
00776 codecvt_base::result __r;
00777 streamsize __ilen = 0;
00778
00779 do
00780 {
00781 char* __next;
00782 __r = _M_codecvt->unshift(_M_state_cur, __buf,
00783 __buf + __blen, __next);
00784 if (__r == codecvt_base::error)
00785 __testvalid = false;
00786 else if (__r == codecvt_base::ok ||
00787 __r == codecvt_base::partial)
00788 {
00789 __ilen = __next - __buf;
00790 if (__ilen > 0)
00791 {
00792 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
00793 if (__elen != __ilen)
00794 __testvalid = false;
00795 }
00796 }
00797 }
00798 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
00799
00800 if (__testvalid)
00801 {
00802
00803
00804
00805
00806 const int_type __tmp = this->overflow();
00807 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00808 __testvalid = false;
00809 }
00810 }
00811 return __testvalid;
00812 }
00813
00814 template<typename _CharT, typename _Traits>
00815 int
00816 basic_filebuf<_CharT, _Traits>::
00817 sync()
00818 {
00819
00820
00821 int __ret = 0;
00822 if (this->pbase() < this->pptr())
00823 {
00824 const int_type __tmp = this->overflow();
00825 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00826 __ret = -1;
00827 }
00828 return __ret;
00829 }
00830
00831 template<typename _CharT, typename _Traits>
00832 void
00833 basic_filebuf<_CharT, _Traits>::
00834 imbue(const locale& __loc)
00835 {
00836 bool __testvalid = true;
00837
00838 const __codecvt_type* _M_codecvt_tmp = 0;
00839 if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
00840 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
00841
00842 if (this->is_open())
00843 {
00844
00845 if ((_M_reading || _M_writing)
00846 && __check_facet(_M_codecvt).encoding() == -1)
00847 __testvalid = false;
00848 else
00849 {
00850 if (_M_reading)
00851 {
00852 if (__check_facet(_M_codecvt).always_noconv())
00853 {
00854 if (_M_codecvt_tmp
00855 && !__check_facet(_M_codecvt_tmp).always_noconv())
00856 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
00857 != pos_type(off_type(-1));
00858 }
00859 else
00860 {
00861
00862 _M_ext_next = _M_ext_buf
00863 + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
00864 this->gptr() - this->eback());
00865 const streamsize __remainder = _M_ext_end - _M_ext_next;
00866 if (__remainder)
00867 std::memmove(_M_ext_buf, _M_ext_next, __remainder);
00868
00869 _M_ext_next = _M_ext_buf;
00870 _M_ext_end = _M_ext_buf + __remainder;
00871 _M_set_buffer(-1);
00872 _M_state_last = _M_state_cur = _M_state_beg;
00873 }
00874 }
00875 else if (_M_writing && (__testvalid = _M_terminate_output()))
00876 _M_set_buffer(-1);
00877 }
00878 }
00879
00880 if (__testvalid)
00881 _M_codecvt = _M_codecvt_tmp;
00882 else
00883 _M_codecvt = 0;
00884 }
00885
00886
00887
00888
00889 #if _GLIBCXX_EXTERN_TEMPLATE
00890 extern template class basic_filebuf<char>;
00891 extern template class basic_ifstream<char>;
00892 extern template class basic_ofstream<char>;
00893 extern template class basic_fstream<char>;
00894
00895 #ifdef _GLIBCXX_USE_WCHAR_T
00896 extern template class basic_filebuf<wchar_t>;
00897 extern template class basic_ifstream<wchar_t>;
00898 extern template class basic_ofstream<wchar_t>;
00899 extern template class basic_fstream<wchar_t>;
00900 #endif
00901 #endif
00902 }
00903
00904 #endif