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