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