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