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 _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
00535
00536 const bool __testbinary = _M_mode & ios_base::binary;
00537 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
00538 && __testin && __testbinary && !_M_writing)
00539 #else
00540 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
00541 && __testin && !_M_writing)
00542 #endif
00543 {
00544
00545 const streamsize __avail = this->egptr() - this->gptr();
00546 if (__avail != 0)
00547 {
00548 if (__avail == 1)
00549 *__s = *this->gptr();
00550 else
00551 traits_type::copy(__s, this->gptr(), __avail);
00552 __s += __avail;
00553 this->gbump(__avail);
00554 __ret += __avail;
00555 __n -= __avail;
00556 }
00557
00558 const streamsize __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
00559 __n);
00560 if (__len == -1)
00561 __throw_ios_failure(__N("basic_filebuf::xsgetn "
00562 "error reading the file"));
00563 __ret += __len;
00564 if (__len == __n)
00565 {
00566 _M_set_buffer(0);
00567 _M_reading = true;
00568 }
00569 else if (__len == 0)
00570 {
00571
00572
00573
00574 _M_set_buffer(-1);
00575 _M_reading = false;
00576 }
00577 }
00578 else
00579 __ret += __streambuf_type::xsgetn(__s, __n);
00580
00581 return __ret;
00582 }
00583
00584 template<typename _CharT, typename _Traits>
00585 streamsize
00586 basic_filebuf<_CharT, _Traits>::
00587 xsputn(const _CharT* __s, streamsize __n)
00588 {
00589
00590
00591
00592 streamsize __ret = 0;
00593 const bool __testout = _M_mode & ios_base::out;
00594 if (__check_facet(_M_codecvt).always_noconv()
00595 && __testout && !_M_reading)
00596 {
00597
00598 const streamsize __chunk = 1ul << 10;
00599 streamsize __bufavail = this->epptr() - this->pptr();
00600
00601
00602 if (!_M_writing && _M_buf_size > 1)
00603 __bufavail = _M_buf_size - 1;
00604
00605 const streamsize __limit = std::min(__chunk, __bufavail);
00606 if (__n >= __limit)
00607 {
00608 const streamsize __buffill = this->pptr() - this->pbase();
00609 const char* __buf = reinterpret_cast<const char*>(this->pbase());
00610 __ret = _M_file.xsputn_2(__buf, __buffill,
00611 reinterpret_cast<const char*>(__s),
00612 __n);
00613 if (__ret == __buffill + __n)
00614 {
00615 _M_set_buffer(0);
00616 _M_writing = true;
00617 }
00618 if (__ret > __buffill)
00619 __ret -= __buffill;
00620 else
00621 __ret = 0;
00622 }
00623 else
00624 __ret = __streambuf_type::xsputn(__s, __n);
00625 }
00626 else
00627 __ret = __streambuf_type::xsputn(__s, __n);
00628 return __ret;
00629 }
00630
00631 template<typename _CharT, typename _Traits>
00632 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00633 basic_filebuf<_CharT, _Traits>::
00634 setbuf(char_type* __s, streamsize __n)
00635 {
00636 if (!this->is_open())
00637 if (__s == 0 && __n == 0)
00638 _M_buf_size = 1;
00639 else if (__s && __n > 0)
00640 {
00641
00642
00643
00644
00645
00646
00647
00648
00649 _M_buf = __s;
00650 _M_buf_size = __n;
00651 }
00652 return this;
00653 }
00654
00655
00656
00657
00658 template<typename _CharT, typename _Traits>
00659 typename basic_filebuf<_CharT, _Traits>::pos_type
00660 basic_filebuf<_CharT, _Traits>::
00661 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
00662 {
00663 int __width = 0;
00664 if (_M_codecvt)
00665 __width = _M_codecvt->encoding();
00666 if (__width < 0)
00667 __width = 0;
00668
00669 pos_type __ret = pos_type(off_type(-1));
00670 const bool __testfail = __off != 0 && __width <= 0;
00671 if (this->is_open() && !__testfail)
00672 {
00673
00674 _M_destroy_pback();
00675
00676
00677
00678
00679
00680
00681 __state_type __state = _M_state_beg;
00682 off_type __computed_off = __off * __width;
00683 if (_M_reading && __way == ios_base::cur)
00684 {
00685 if (_M_codecvt->always_noconv())
00686 __computed_off += this->gptr() - this->egptr();
00687 else
00688 {
00689
00690
00691
00692 const int __gptr_off =
00693 _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
00694 this->gptr() - this->eback());
00695 __computed_off += _M_ext_buf + __gptr_off - _M_ext_end;
00696
00697
00698
00699 __state = _M_state_last;
00700 }
00701 }
00702 __ret = _M_seek(__computed_off, __way, __state);
00703 }
00704 return __ret;
00705 }
00706
00707
00708
00709
00710
00711 template<typename _CharT, typename _Traits>
00712 typename basic_filebuf<_CharT, _Traits>::pos_type
00713 basic_filebuf<_CharT, _Traits>::
00714 seekpos(pos_type __pos, ios_base::openmode)
00715 {
00716 pos_type __ret = pos_type(off_type(-1));
00717 if (this->is_open())
00718 {
00719
00720 _M_destroy_pback();
00721 __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
00722 }
00723 return __ret;
00724 }
00725
00726 template<typename _CharT, typename _Traits>
00727 typename basic_filebuf<_CharT, _Traits>::pos_type
00728 basic_filebuf<_CharT, _Traits>::
00729 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
00730 {
00731 pos_type __ret = pos_type(off_type(-1));
00732 if (_M_terminate_output())
00733 {
00734
00735 __ret = pos_type(_M_file.seekoff(__off, __way));
00736 _M_reading = false;
00737 _M_writing = false;
00738 _M_ext_next = _M_ext_end = _M_ext_buf;
00739 _M_set_buffer(-1);
00740 _M_state_cur = __state;
00741 __ret.state(_M_state_cur);
00742 }
00743 return __ret;
00744 }
00745
00746 template<typename _CharT, typename _Traits>
00747 bool
00748 basic_filebuf<_CharT, _Traits>::
00749 _M_terminate_output()
00750 {
00751
00752 bool __testvalid = true;
00753 if (this->pbase() < this->pptr())
00754 {
00755 const int_type __tmp = this->overflow();
00756 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00757 __testvalid = false;
00758 }
00759
00760
00761 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
00762 && __testvalid)
00763 {
00764
00765
00766
00767 const size_t __blen = 128;
00768 char __buf[__blen];
00769 codecvt_base::result __r;
00770 streamsize __ilen = 0;
00771
00772 do
00773 {
00774 char* __next;
00775 __r = _M_codecvt->unshift(_M_state_cur, __buf,
00776 __buf + __blen, __next);
00777 if (__r == codecvt_base::error)
00778 __testvalid = false;
00779 else if (__r == codecvt_base::ok ||
00780 __r == codecvt_base::partial)
00781 {
00782 __ilen = __next - __buf;
00783 if (__ilen > 0)
00784 {
00785 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
00786 if (__elen != __ilen)
00787 __testvalid = false;
00788 }
00789 }
00790 }
00791 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
00792
00793 if (__testvalid)
00794 {
00795
00796
00797
00798
00799 const int_type __tmp = this->overflow();
00800 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00801 __testvalid = false;
00802 }
00803 }
00804 return __testvalid;
00805 }
00806
00807 template<typename _CharT, typename _Traits>
00808 int
00809 basic_filebuf<_CharT, _Traits>::
00810 sync()
00811 {
00812
00813
00814 int __ret = 0;
00815 if (this->pbase() < this->pptr())
00816 {
00817 const int_type __tmp = this->overflow();
00818 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00819 __ret = -1;
00820 }
00821 return __ret;
00822 }
00823
00824 template<typename _CharT, typename _Traits>
00825 void
00826 basic_filebuf<_CharT, _Traits>::
00827 imbue(const locale& __loc)
00828 {
00829 bool __testvalid = true;
00830
00831 const __codecvt_type* _M_codecvt_tmp = 0;
00832 if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
00833 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
00834
00835 if (this->is_open())
00836 {
00837
00838 if ((_M_reading || _M_writing)
00839 && __check_facet(_M_codecvt).encoding() == -1)
00840 __testvalid = false;
00841 else
00842 {
00843 if (_M_reading)
00844 {
00845 if (__check_facet(_M_codecvt).always_noconv())
00846 {
00847 if (_M_codecvt_tmp
00848 && !__check_facet(_M_codecvt_tmp).always_noconv())
00849 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
00850 != pos_type(off_type(-1));
00851 }
00852 else
00853 {
00854
00855 _M_ext_next = _M_ext_buf
00856 + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
00857 this->gptr() - this->eback());
00858 const streamsize __remainder = _M_ext_end - _M_ext_next;
00859 if (__remainder)
00860 std::memmove(_M_ext_buf, _M_ext_next, __remainder);
00861
00862 _M_ext_next = _M_ext_buf;
00863 _M_ext_end = _M_ext_buf + __remainder;
00864 _M_set_buffer(-1);
00865 _M_state_last = _M_state_cur = _M_state_beg;
00866 }
00867 }
00868 else if (_M_writing && (__testvalid = _M_terminate_output()))
00869 _M_set_buffer(-1);
00870 }
00871 }
00872
00873 if (__testvalid)
00874 _M_codecvt = _M_codecvt_tmp;
00875 else
00876 _M_codecvt = 0;
00877 }
00878
00879
00880
00881
00882 #if _GLIBCXX_EXTERN_TEMPLATE
00883 extern template class basic_filebuf<char>;
00884 extern template class basic_ifstream<char>;
00885 extern template class basic_ofstream<char>;
00886 extern template class basic_fstream<char>;
00887
00888 #ifdef _GLIBCXX_USE_WCHAR_T
00889 extern template class basic_filebuf<wchar_t>;
00890 extern template class basic_ifstream<wchar_t>;
00891 extern template class basic_ofstream<wchar_t>;
00892 extern template class basic_fstream<wchar_t>;
00893 #endif
00894 #endif
00895 }
00896
00897 #endif