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 if (__avail == 1)
00588 *__s = *this->gptr();
00589 else
00590 traits_type::copy(__s, this->gptr(), __avail);
00591 __s += __avail;
00592 this->gbump(__avail);
00593 __ret += __avail;
00594 __n -= __avail;
00595 }
00596
00597
00598
00599 streamsize __len;
00600 for (;;)
00601 {
00602 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
00603 __n);
00604 if (__len == -1)
00605 __throw_ios_failure(__N("basic_filebuf::xsgetn "
00606 "error reading the file"));
00607 if (__len == 0)
00608 break;
00609
00610 __n -= __len;
00611 __ret += __len;
00612 if (__n == 0)
00613 break;
00614
00615 __s += __len;
00616 }
00617
00618 if (__n == 0)
00619 {
00620 _M_set_buffer(0);
00621 _M_reading = true;
00622 }
00623 else if (__len == 0)
00624 {
00625
00626
00627
00628 _M_set_buffer(-1);
00629 _M_reading = false;
00630 }
00631 }
00632 else
00633 __ret += __streambuf_type::xsgetn(__s, __n);
00634
00635 return __ret;
00636 }
00637
00638 template<typename _CharT, typename _Traits>
00639 streamsize
00640 basic_filebuf<_CharT, _Traits>::
00641 xsputn(const _CharT* __s, streamsize __n)
00642 {
00643 streamsize __ret = 0;
00644
00645
00646
00647 const bool __testout = _M_mode & ios_base::out;
00648 if (__check_facet(_M_codecvt).always_noconv()
00649 && __testout && !_M_reading)
00650 {
00651
00652 const streamsize __chunk = 1ul << 10;
00653 streamsize __bufavail = this->epptr() - this->pptr();
00654
00655
00656 if (!_M_writing && _M_buf_size > 1)
00657 __bufavail = _M_buf_size - 1;
00658
00659 const streamsize __limit = std::min(__chunk, __bufavail);
00660 if (__n >= __limit)
00661 {
00662 const streamsize __buffill = this->pptr() - this->pbase();
00663 const char* __buf = reinterpret_cast<const char*>(this->pbase());
00664 __ret = _M_file.xsputn_2(__buf, __buffill,
00665 reinterpret_cast<const char*>(__s),
00666 __n);
00667 if (__ret == __buffill + __n)
00668 {
00669 _M_set_buffer(0);
00670 _M_writing = true;
00671 }
00672 if (__ret > __buffill)
00673 __ret -= __buffill;
00674 else
00675 __ret = 0;
00676 }
00677 else
00678 __ret = __streambuf_type::xsputn(__s, __n);
00679 }
00680 else
00681 __ret = __streambuf_type::xsputn(__s, __n);
00682 return __ret;
00683 }
00684
00685 template<typename _CharT, typename _Traits>
00686 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00687 basic_filebuf<_CharT, _Traits>::
00688 setbuf(char_type* __s, streamsize __n)
00689 {
00690 if (!this->is_open())
00691 {
00692 if (__s == 0 && __n == 0)
00693 _M_buf_size = 1;
00694 else if (__s && __n > 0)
00695 {
00696
00697
00698
00699
00700
00701
00702
00703
00704 _M_buf = __s;
00705 _M_buf_size = __n;
00706 }
00707 }
00708 return this;
00709 }
00710
00711
00712
00713
00714 template<typename _CharT, typename _Traits>
00715 typename basic_filebuf<_CharT, _Traits>::pos_type
00716 basic_filebuf<_CharT, _Traits>::
00717 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
00718 {
00719 int __width = 0;
00720 if (_M_codecvt)
00721 __width = _M_codecvt->encoding();
00722 if (__width < 0)
00723 __width = 0;
00724
00725 pos_type __ret = pos_type(off_type(-1));
00726 const bool __testfail = __off != 0 && __width <= 0;
00727 if (this->is_open() && !__testfail)
00728 {
00729
00730
00731
00732
00733 bool __no_movement = __way == ios_base::cur && __off == 0
00734 && (!_M_writing || _M_codecvt->always_noconv());
00735
00736
00737 if (!__no_movement)
00738 _M_destroy_pback();
00739
00740
00741
00742
00743
00744
00745 __state_type __state = _M_state_beg;
00746 off_type __computed_off = __off * __width;
00747 if (_M_reading && __way == ios_base::cur)
00748 {
00749 __state = _M_state_last;
00750 __computed_off += _M_get_ext_pos(__state);
00751 }
00752 if (!__no_movement)
00753 __ret = _M_seek(__computed_off, __way, __state);
00754 else
00755 {
00756 if (_M_writing)
00757 __computed_off = this->pptr() - this->pbase();
00758
00759 off_type __file_off = _M_file.seekoff(0, ios_base::cur);
00760 if (__file_off != off_type(-1))
00761 {
00762 __ret = __file_off + __computed_off;
00763 __ret.state(__state);
00764 }
00765 }
00766 }
00767 return __ret;
00768 }
00769
00770
00771
00772
00773
00774 template<typename _CharT, typename _Traits>
00775 typename basic_filebuf<_CharT, _Traits>::pos_type
00776 basic_filebuf<_CharT, _Traits>::
00777 seekpos(pos_type __pos, ios_base::openmode)
00778 {
00779 pos_type __ret = pos_type(off_type(-1));
00780 if (this->is_open())
00781 {
00782
00783 _M_destroy_pback();
00784 __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
00785 }
00786 return __ret;
00787 }
00788
00789 template<typename _CharT, typename _Traits>
00790 typename basic_filebuf<_CharT, _Traits>::pos_type
00791 basic_filebuf<_CharT, _Traits>::
00792 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
00793 {
00794 pos_type __ret = pos_type(off_type(-1));
00795 if (_M_terminate_output())
00796 {
00797 off_type __file_off = _M_file.seekoff(__off, __way);
00798 if (__file_off != off_type(-1))
00799 {
00800 _M_reading = false;
00801 _M_writing = false;
00802 _M_ext_next = _M_ext_end = _M_ext_buf;
00803 _M_set_buffer(-1);
00804 _M_state_cur = __state;
00805 __ret = __file_off;
00806 __ret.state(_M_state_cur);
00807 }
00808 }
00809 return __ret;
00810 }
00811
00812
00813
00814
00815 template<typename _CharT, typename _Traits>
00816 int basic_filebuf<_CharT, _Traits>::
00817 _M_get_ext_pos(__state_type& __state)
00818 {
00819 if (_M_codecvt->always_noconv())
00820 return this->gptr() - this->egptr();
00821 else
00822 {
00823
00824
00825
00826 const int __gptr_off =
00827 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
00828 this->gptr() - this->eback());
00829 return _M_ext_buf + __gptr_off - _M_ext_end;
00830 }
00831 }
00832
00833 template<typename _CharT, typename _Traits>
00834 bool
00835 basic_filebuf<_CharT, _Traits>::
00836 _M_terminate_output()
00837 {
00838
00839 bool __testvalid = true;
00840 if (this->pbase() < this->pptr())
00841 {
00842 const int_type __tmp = this->overflow();
00843 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00844 __testvalid = false;
00845 }
00846
00847
00848 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
00849 && __testvalid)
00850 {
00851
00852
00853
00854 const size_t __blen = 128;
00855 char __buf[__blen];
00856 codecvt_base::result __r;
00857 streamsize __ilen = 0;
00858
00859 do
00860 {
00861 char* __next;
00862 __r = _M_codecvt->unshift(_M_state_cur, __buf,
00863 __buf + __blen, __next);
00864 if (__r == codecvt_base::error)
00865 __testvalid = false;
00866 else if (__r == codecvt_base::ok ||
00867 __r == codecvt_base::partial)
00868 {
00869 __ilen = __next - __buf;
00870 if (__ilen > 0)
00871 {
00872 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
00873 if (__elen != __ilen)
00874 __testvalid = false;
00875 }
00876 }
00877 }
00878 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
00879
00880 if (__testvalid)
00881 {
00882
00883
00884
00885
00886 const int_type __tmp = this->overflow();
00887 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00888 __testvalid = false;
00889 }
00890 }
00891 return __testvalid;
00892 }
00893
00894 template<typename _CharT, typename _Traits>
00895 int
00896 basic_filebuf<_CharT, _Traits>::
00897 sync()
00898 {
00899
00900
00901 int __ret = 0;
00902 if (this->pbase() < this->pptr())
00903 {
00904 const int_type __tmp = this->overflow();
00905 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
00906 __ret = -1;
00907 }
00908 return __ret;
00909 }
00910
00911 template<typename _CharT, typename _Traits>
00912 void
00913 basic_filebuf<_CharT, _Traits>::
00914 imbue(const locale& __loc)
00915 {
00916 bool __testvalid = true;
00917
00918 const __codecvt_type* _M_codecvt_tmp = 0;
00919 if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
00920 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
00921
00922 if (this->is_open())
00923 {
00924
00925 if ((_M_reading || _M_writing)
00926 && __check_facet(_M_codecvt).encoding() == -1)
00927 __testvalid = false;
00928 else
00929 {
00930 if (_M_reading)
00931 {
00932 if (__check_facet(_M_codecvt).always_noconv())
00933 {
00934 if (_M_codecvt_tmp
00935 && !__check_facet(_M_codecvt_tmp).always_noconv())
00936 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
00937 != pos_type(off_type(-1));
00938 }
00939 else
00940 {
00941
00942 _M_ext_next = _M_ext_buf
00943 + _M_codecvt->length(_M_state_last, _M_ext_buf,
00944 _M_ext_next,
00945 this->gptr() - this->eback());
00946 const streamsize __remainder = _M_ext_end - _M_ext_next;
00947 if (__remainder)
00948 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
00949
00950 _M_ext_next = _M_ext_buf;
00951 _M_ext_end = _M_ext_buf + __remainder;
00952 _M_set_buffer(-1);
00953 _M_state_last = _M_state_cur = _M_state_beg;
00954 }
00955 }
00956 else if (_M_writing && (__testvalid = _M_terminate_output()))
00957 _M_set_buffer(-1);
00958 }
00959 }
00960
00961 if (__testvalid)
00962 _M_codecvt = _M_codecvt_tmp;
00963 else
00964 _M_codecvt = 0;
00965 }
00966
00967
00968
00969
00970 #if _GLIBCXX_EXTERN_TEMPLATE
00971 extern template class basic_filebuf<char>;
00972 extern template class basic_ifstream<char>;
00973 extern template class basic_ofstream<char>;
00974 extern template class basic_fstream<char>;
00975
00976 #ifdef _GLIBCXX_USE_WCHAR_T
00977 extern template class basic_filebuf<wchar_t>;
00978 extern template class basic_ifstream<wchar_t>;
00979 extern template class basic_ofstream<wchar_t>;
00980 extern template class basic_fstream<wchar_t>;
00981 #endif
00982 #endif
00983
00984 _GLIBCXX_END_NAMESPACE_VERSION
00985 }
00986
00987 #endif