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 <cxxabi-forced.h>
00042
00043 _GLIBCXX_BEGIN_NAMESPACE(std)
00044
00045 template<typename _CharT, typename _Traits>
00046 void
00047 basic_filebuf<_CharT, _Traits>::
00048 _M_allocate_internal_buffer()
00049 {
00050
00051
00052 if (!_M_buf_allocated && !_M_buf)
00053 {
00054 _M_buf = new char_type[_M_buf_size];
00055 _M_buf_allocated = true;
00056 }
00057 }
00058
00059 template<typename _CharT, typename _Traits>
00060 void
00061 basic_filebuf<_CharT, _Traits>::
00062 _M_destroy_internal_buffer() throw()
00063 {
00064 if (_M_buf_allocated)
00065 {
00066 delete [] _M_buf;
00067 _M_buf = 0;
00068 _M_buf_allocated = false;
00069 }
00070 delete [] _M_ext_buf;
00071 _M_ext_buf = 0;
00072 _M_ext_buf_size = 0;
00073 _M_ext_next = 0;
00074 _M_ext_end = 0;
00075 }
00076
00077 template<typename _CharT, typename _Traits>
00078 basic_filebuf<_CharT, _Traits>::
00079 basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock),
00080 _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
00081 _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ),
00082 _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
00083 _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
00084 _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
00085 _M_ext_end(0)
00086 {
00087 if (has_facet<__codecvt_type>(this->_M_buf_locale))
00088 _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
00089 }
00090
00091 template<typename _CharT, typename _Traits>
00092 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00093 basic_filebuf<_CharT, _Traits>::
00094 open(const char* __s, ios_base::openmode __mode)
00095 {
00096 __filebuf_type *__ret = 0;
00097 if (!this->is_open())
00098 {
00099 _M_file.open(__s, __mode);
00100 if (this->is_open())
00101 {
00102 _M_allocate_internal_buffer();
00103 _M_mode = __mode;
00104
00105
00106 _M_reading = false;
00107 _M_writing = false;
00108 _M_set_buffer(-1);
00109
00110
00111 _M_state_last = _M_state_cur = _M_state_beg;
00112
00113
00114 if ((__mode & ios_base::ate)
00115 && this->seekoff(0, ios_base::end, __mode)
00116 == pos_type(off_type(-1)))
00117 this->close();
00118 else
00119 __ret = this;
00120 }
00121 }
00122 return __ret;
00123 }
00124
00125 template<typename _CharT, typename _Traits>
00126 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00127 basic_filebuf<_CharT, _Traits>::
00128 close()
00129 {
00130 if (!this->is_open())
00131 return 0;
00132
00133 bool __testfail = false;
00134 {
00135
00136 struct __close_sentry
00137 {
00138 basic_filebuf *__fb;
00139 __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { }
00140 ~__close_sentry ()
00141 {
00142 __fb->_M_mode = ios_base::openmode(0);
00143 __fb->_M_pback_init = false;
00144 __fb->_M_destroy_internal_buffer();
00145 __fb->_M_reading = false;
00146 __fb->_M_writing = false;
00147 __fb->_M_set_buffer(-1);
00148 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
00149 }
00150 } __cs (this);
00151
00152 __try
00153 {
00154 if (!_M_terminate_output())
00155 __testfail = true;
00156 }
00157 __catch(__cxxabiv1::__forced_unwind&)
00158 {
00159 _M_file.close();
00160 __throw_exception_again;
00161 }
00162 __catch(...)
00163 { __testfail = true; }
00164 }
00165
00166 if (!_M_file.close())
00167 __testfail = true;
00168
00169 if (__testfail)
00170 return 0;
00171 else
00172 return this;
00173 }
00174
00175 template<typename _CharT, typename _Traits>
00176 streamsize
00177 basic_filebuf<_CharT, _Traits>::
00178 showmanyc()
00179 {
00180 streamsize __ret = -1;
00181 const bool __testin = _M_mode & ios_base::in;
00182 if (__testin && this->is_open())
00183 {
00184
00185
00186 __ret = this->egptr() - this->gptr();
00187
00188 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
00189
00190 const bool __testbinary = _M_mode & ios_base::binary;
00191 if (__check_facet(_M_codecvt).encoding() >= 0
00192 && __testbinary)
00193 #else
00194 if (__check_facet(_M_codecvt).encoding() >= 0)
00195 #endif
00196 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
00197 }
00198 return __ret;
00199 }
00200
00201 template<typename _CharT, typename _Traits>
00202 typename basic_filebuf<_CharT, _Traits>::int_type
00203 basic_filebuf<_CharT, _Traits>::
00204 underflow()
00205 {
00206 int_type __ret = traits_type::eof();
00207 const bool __testin = _M_mode & ios_base::in;
00208 if (__testin)
00209 {
00210 if (_M_writing)
00211 {
00212 if (overflow() == traits_type::eof())
00213 return __ret;
00214 _M_set_buffer(-1);
00215 _M_writing = false;
00216 }
00217
00218
00219
00220 _M_destroy_pback();
00221
00222 if (this->gptr() < this->egptr())
00223 return traits_type::to_int_type(*this->gptr());
00224
00225
00226 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
00227
00228
00229 bool __got_eof = false;
00230
00231 streamsize __ilen = 0;
00232 codecvt_base::result __r = codecvt_base::ok;
00233 if (__check_facet(_M_codecvt).always_noconv())
00234 {
00235 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
00236 __buflen);
00237 if (__ilen == 0)
00238 __got_eof = true;
00239 }
00240 else
00241 {
00242
00243
00244 const int __enc = _M_codecvt->encoding();
00245 streamsize __blen;
00246 streamsize __rlen;
00247 if (__enc > 0)
00248 __blen = __rlen = __buflen * __enc;
00249 else
00250 {
00251 __blen = __buflen + _M_codecvt->max_length() - 1;
00252 __rlen = __buflen;
00253 }
00254 const streamsize __remainder = _M_ext_end - _M_ext_next;
00255 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
00256
00257
00258
00259 if (_M_reading && this->egptr() == this->eback() && __remainder)
00260 __rlen = 0;
00261
00262
00263
00264 if (_M_ext_buf_size < __blen)
00265 {
00266 char* __buf = new char[__blen];
00267 if (__remainder)
00268 __builtin_memcpy(__buf, _M_ext_next, __remainder);
00269
00270 delete [] _M_ext_buf;
00271 _M_ext_buf = __buf;
00272 _M_ext_buf_size = __blen;
00273 }
00274 else if (__remainder)
00275 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
00276
00277 _M_ext_next = _M_ext_buf;
00278 _M_ext_end = _M_ext_buf + __remainder;
00279 _M_state_last = _M_state_cur;
00280
00281 do
00282 {
00283 if (__rlen > 0)
00284 {
00285
00286
00287
00288 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
00289 {
00290 __throw_ios_failure(__N("basic_filebuf::underflow "
00291 "codecvt::max_length() "
00292 "is not valid"));
00293 }
00294 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
00295 if (__elen == 0)
00296 __got_eof = true;
00297 else if (__elen == -1)
00298 break;
00299 _M_ext_end += __elen;
00300 }
00301
00302 char_type* __iend = this->eback();
00303 if (_M_ext_next < _M_ext_end)
00304 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
00305 _M_ext_end, _M_ext_next,
00306 this->eback(),
00307 this->eback() + __buflen, __iend);
00308 if (__r == codecvt_base::noconv)
00309 {
00310 size_t __avail = _M_ext_end - _M_ext_buf;
00311 __ilen = std::min(__avail, __buflen);
00312 traits_type::copy(this->eback(),
00313 reinterpret_cast<char_type*>
00314 (_M_ext_buf), __ilen);
00315 _M_ext_next = _M_ext_buf + __ilen;
00316 }
00317 else
00318 __ilen = __iend - this->eback();
00319
00320
00321
00322
00323 if (__r == codecvt_base::error)
00324 break;
00325
00326 __rlen = 1;
00327 }
00328 while (__ilen == 0 && !__got_eof);
00329 }
00330
00331 if (__ilen > 0)
00332 {
00333 _M_set_buffer(__ilen);
00334 _M_reading = true;
00335 __ret = traits_type::to_int_type(*this->gptr());
00336 }
00337 else if (__got_eof)
00338 {
00339
00340
00341
00342 _M_set_buffer(-1);
00343 _M_reading = false;
00344
00345
00346 if (__r == codecvt_base::partial)
00347 __throw_ios_failure(__N("basic_filebuf::underflow "
00348 "incomplete character in file"));
00349 }
00350 else if (__r == codecvt_base::error)
00351 __throw_ios_failure(__N("basic_filebuf::underflow "
00352 "invalid byte sequence in file"));
00353 else
00354 __throw_ios_failure(__N("basic_filebuf::underflow "
00355 "error reading the file"));
00356 }
00357 return __ret;
00358 }
00359
00360 template<typename _CharT, typename _Traits>
00361 typename basic_filebuf<_CharT, _Traits>::int_type
00362 basic_filebuf<_CharT, _Traits>::
00363 pbackfail(int_type __i)
00364 {
00365 int_type __ret = traits_type::eof();
00366 const bool __testin = _M_mode & ios_base::in;
00367 if (__testin)
00368 {
00369 if (_M_writing)
00370 {
00371 if (overflow() == traits_type::eof())
00372 return __ret;
00373 _M_set_buffer(-1);
00374 _M_writing = false;
00375 }
00376
00377
00378 const bool __testpb = _M_pback_init;
00379 const bool __testeof = traits_type::eq_int_type(__i, __ret);
00380 int_type __tmp;
00381 if (this->eback() < this->gptr())
00382 {
00383 this->gbump(-1);
00384 __tmp = traits_type::to_int_type(*this->gptr());
00385 }
00386 else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1)))
00387 {
00388 __tmp = this->underflow();
00389 if (traits_type::eq_int_type(__tmp, __ret))
00390 return __ret;
00391 }
00392 else
00393 {
00394
00395
00396
00397
00398
00399 return __ret;
00400 }
00401
00402
00403
00404 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
00405 __ret = __i;
00406 else if (__testeof)
00407 __ret = traits_type::not_eof(__i);
00408 else if (!__testpb)
00409 {
00410 _M_create_pback();
00411 _M_reading = true;
00412 *this->gptr() = traits_type::to_char_type(__i);
00413 __ret = __i;
00414 }
00415 }
00416 return __ret;
00417 }
00418
00419 template<typename _CharT, typename _Traits>
00420 typename basic_filebuf<_CharT, _Traits>::int_type
00421 basic_filebuf<_CharT, _Traits>::
00422 overflow(int_type __c)
00423 {
00424 int_type __ret = traits_type::eof();
00425 const bool __testeof = traits_type::eq_int_type(__c, __ret);
00426 const bool __testout = _M_mode & ios_base::out;
00427 if (__testout)
00428 {
00429 if (_M_reading)
00430 {
00431 _M_destroy_pback();
00432 const int __gptr_off = _M_get_ext_pos(_M_state_last);
00433 if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
00434 == pos_type(off_type(-1)))
00435 return __ret;
00436 }
00437 if (this->pbase() < this->pptr())
00438 {
00439
00440 if (!__testeof)
00441 {
00442 *this->pptr() = traits_type::to_char_type(__c);
00443 this->pbump(1);
00444 }
00445
00446
00447
00448 if (_M_convert_to_external(this->pbase(),
00449 this->pptr() - this->pbase()))
00450 {
00451 _M_set_buffer(0);
00452 __ret = traits_type::not_eof(__c);
00453 }
00454 }
00455 else if (_M_buf_size > 1)
00456 {
00457
00458
00459
00460 _M_set_buffer(0);
00461 _M_writing = true;
00462 if (!__testeof)
00463 {
00464 *this->pptr() = traits_type::to_char_type(__c);
00465 this->pbump(1);
00466 }
00467 __ret = traits_type::not_eof(__c);
00468 }
00469 else
00470 {
00471
00472 char_type __conv = traits_type::to_char_type(__c);
00473 if (__testeof || _M_convert_to_external(&__conv, 1))
00474 {
00475 _M_writing = true;
00476 __ret = traits_type::not_eof(__c);
00477 }
00478 }
00479 }
00480 return __ret;
00481 }
00482
00483 template<typename _CharT, typename _Traits>
00484 bool
00485 basic_filebuf<_CharT, _Traits>::
00486 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
00487 {
00488
00489 streamsize __elen;
00490 streamsize __plen;
00491 if (__check_facet(_M_codecvt).always_noconv())
00492 {
00493 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00494 __plen = __ilen;
00495 }
00496 else
00497 {
00498
00499
00500 streamsize __blen = __ilen * _M_codecvt->max_length();
00501 char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00502
00503 char* __bend;
00504 const char_type* __iend;
00505 codecvt_base::result __r;
00506 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
00507 __iend, __buf, __buf + __blen, __bend);
00508
00509 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
00510 __blen = __bend - __buf;
00511 else if (__r == codecvt_base::noconv)
00512 {
00513
00514 __buf = reinterpret_cast<char*>(__ibuf);
00515 __blen = __ilen;
00516 }
00517 else
00518 __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
00519 "conversion error"));
00520
00521 __elen = _M_file.xsputn(__buf, __blen);
00522 __plen = __blen;
00523
00524
00525 if (__r == codecvt_base::partial && __elen == __plen)
00526 {
00527 const char_type* __iresume = __iend;
00528 streamsize __rlen = this->pptr() - __iend;
00529 __r = _M_codecvt->out(_M_state_cur, __iresume,
00530 __iresume + __rlen, __iend, __buf,
00531 __buf + __blen, __bend);
00532 if (__r != codecvt_base::error)
00533 {
00534 __rlen = __bend - __buf;
00535 __elen = _M_file.xsputn(__buf, __rlen);
00536 __plen = __rlen;
00537 }
00538 else
00539 __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
00540 "conversion error"));
00541 }
00542 }
00543 return __elen == __plen;
00544 }
00545
00546 template<typename _CharT, typename _Traits>
00547 streamsize
00548 basic_filebuf<_CharT, _Traits>::
00549 xsgetn(_CharT* __s, streamsize __n)
00550 {
00551
00552 streamsize __ret = 0;
00553 if (_M_pback_init)
00554 {
00555 if (__n > 0 && this->gptr() == this->eback())
00556 {
00557 *__s++ = *this->gptr();
00558 this->gbump(1);
00559 __ret = 1;
00560 --__n;
00561 }
00562 _M_destroy_pback();
00563 }
00564 else if (_M_writing)
00565 {
00566 if (overflow() == traits_type::eof())
00567 return __ret;
00568 _M_set_buffer(-1);
00569 _M_writing = false;
00570 }
00571
00572
00573
00574
00575 const bool __testin = _M_mode & ios_base::in;
00576 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
00577
00578 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
00579 && __testin)
00580 {
00581
00582 const streamsize __avail = this->egptr() - this->gptr();
00583 if (__avail != 0)
00584 {
00585 if (__avail == 1)
00586 *__s = *this->gptr();
00587 else
00588 traits_type::copy(__s, this->gptr(), __avail);
00589 __s += __avail;
00590 this->gbump(__avail);
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
00983
00984 #endif