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 _GLIBCXX_BEGIN_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 if (__ret != pos_type(off_type(-1)))
00744 {
00745 _M_reading = false;
00746 _M_writing = false;
00747 _M_ext_next = _M_ext_end = _M_ext_buf;
00748 _M_set_buffer(-1);
00749 _M_state_cur = __state;
00750 __ret.state(_M_state_cur);
00751 }
00752 }
00753 return __ret;
00754 }
00755
00756 template<typename _CharT, typename _Traits>
00757 bool
00758 basic_filebuf<_CharT, _Traits>::
00759 _M_terminate_output()
00760 {
00761
00762 bool __testvalid = true;
00763 if (this->pbase() < this->pptr())
00764 {
00765 const int_type __tmp = this->overflow();
00766 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00767 __testvalid = false;
00768 }
00769
00770
00771 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
00772 && __testvalid)
00773 {
00774
00775
00776
00777 const size_t __blen = 128;
00778 char __buf[__blen];
00779 codecvt_base::result __r;
00780 streamsize __ilen = 0;
00781
00782 do
00783 {
00784 char* __next;
00785 __r = _M_codecvt->unshift(_M_state_cur, __buf,
00786 __buf + __blen, __next);
00787 if (__r == codecvt_base::error)
00788 __testvalid = false;
00789 else if (__r == codecvt_base::ok ||
00790 __r == codecvt_base::partial)
00791 {
00792 __ilen = __next - __buf;
00793 if (__ilen > 0)
00794 {
00795 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
00796 if (__elen != __ilen)
00797 __testvalid = false;
00798 }
00799 }
00800 }
00801 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
00802
00803 if (__testvalid)
00804 {
00805
00806
00807
00808
00809 const int_type __tmp = this->overflow();
00810 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00811 __testvalid = false;
00812 }
00813 }
00814 return __testvalid;
00815 }
00816
00817 template<typename _CharT, typename _Traits>
00818 int
00819 basic_filebuf<_CharT, _Traits>::
00820 sync()
00821 {
00822
00823
00824 int __ret = 0;
00825 if (this->pbase() < this->pptr())
00826 {
00827 const int_type __tmp = this->overflow();
00828 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00829 __ret = -1;
00830 }
00831 return __ret;
00832 }
00833
00834 template<typename _CharT, typename _Traits>
00835 void
00836 basic_filebuf<_CharT, _Traits>::
00837 imbue(const locale& __loc)
00838 {
00839 bool __testvalid = true;
00840
00841 const __codecvt_type* _M_codecvt_tmp = 0;
00842 if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
00843 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
00844
00845 if (this->is_open())
00846 {
00847
00848 if ((_M_reading || _M_writing)
00849 && __check_facet(_M_codecvt).encoding() == -1)
00850 __testvalid = false;
00851 else
00852 {
00853 if (_M_reading)
00854 {
00855 if (__check_facet(_M_codecvt).always_noconv())
00856 {
00857 if (_M_codecvt_tmp
00858 && !__check_facet(_M_codecvt_tmp).always_noconv())
00859 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
00860 != pos_type(off_type(-1));
00861 }
00862 else
00863 {
00864
00865 _M_ext_next = _M_ext_buf
00866 + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
00867 this->gptr() - this->eback());
00868 const streamsize __remainder = _M_ext_end - _M_ext_next;
00869 if (__remainder)
00870 std::memmove(_M_ext_buf, _M_ext_next, __remainder);
00871
00872 _M_ext_next = _M_ext_buf;
00873 _M_ext_end = _M_ext_buf + __remainder;
00874 _M_set_buffer(-1);
00875 _M_state_last = _M_state_cur = _M_state_beg;
00876 }
00877 }
00878 else if (_M_writing && (__testvalid = _M_terminate_output()))
00879 _M_set_buffer(-1);
00880 }
00881 }
00882
00883 if (__testvalid)
00884 _M_codecvt = _M_codecvt_tmp;
00885 else
00886 _M_codecvt = 0;
00887 }
00888
00889
00890
00891
00892 #if _GLIBCXX_EXTERN_TEMPLATE
00893 extern template class basic_filebuf<char>;
00894 extern template class basic_ifstream<char>;
00895 extern template class basic_ofstream<char>;
00896 extern template class basic_fstream<char>;
00897
00898 #ifdef _GLIBCXX_USE_WCHAR_T
00899 extern template class basic_filebuf<wchar_t>;
00900 extern template class basic_ifstream<wchar_t>;
00901 extern template class basic_ofstream<wchar_t>;
00902 extern template class basic_fstream<wchar_t>;
00903 #endif
00904 #endif
00905
00906 _GLIBCXX_END_NAMESPACE
00907
00908 #endif