37 #define _FSTREAM_TCC 1
39 #pragma GCC system_header
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
47 template<
typename _CharT,
typename _Traits>
49 basic_filebuf<_CharT, _Traits>::
50 _M_allocate_internal_buffer()
54 if (!_M_buf_allocated && !_M_buf)
56 _M_buf =
new char_type[_M_buf_size];
57 _M_buf_allocated =
true;
61 template<
typename _CharT,
typename _Traits>
63 basic_filebuf<_CharT, _Traits>::
64 _M_destroy_internal_buffer() throw()
70 _M_buf_allocated =
false;
79 template<
typename _CharT,
typename _Traits>
82 _M_mode(
ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
83 _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ),
84 _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
85 _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
86 _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
93 template<
typename _CharT,
typename _Traits>
96 open(
const char* __s, ios_base::openmode __mode)
101 _M_file.
open(__s, __mode);
104 _M_allocate_internal_buffer();
113 _M_state_last = _M_state_cur = _M_state_beg;
118 == pos_type(off_type(-1)))
127 template<
typename _CharT,
typename _Traits>
132 if (!this->is_open())
135 bool __testfail =
false;
138 struct __close_sentry
145 __fb->_M_pback_init =
false;
146 __fb->_M_destroy_internal_buffer();
147 __fb->_M_reading =
false;
148 __fb->_M_writing =
false;
149 __fb->_M_set_buffer(-1);
150 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
156 if (!_M_terminate_output())
162 __throw_exception_again;
165 { __testfail =
true; }
168 if (!_M_file.close())
177 template<
typename _CharT,
typename _Traits>
184 if (__testin && this->is_open())
188 __ret = this->egptr() - this->gptr();
190 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
193 if (__check_facet(_M_codecvt).encoding() >= 0
196 if (__check_facet(_M_codecvt).encoding() >= 0)
198 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
203 template<
typename _CharT,
typename _Traits>
204 typename basic_filebuf<_CharT, _Traits>::int_type
208 int_type __ret = traits_type::eof();
214 if (overflow() == traits_type::eof())
224 if (this->gptr() < this->egptr())
225 return traits_type::to_int_type(*this->gptr());
228 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
231 bool __got_eof =
false;
234 codecvt_base::result __r = codecvt_base::ok;
235 if (__check_facet(_M_codecvt).always_noconv())
237 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
246 const int __enc = _M_codecvt->encoding();
250 __blen = __rlen = __buflen * __enc;
253 __blen = __buflen + _M_codecvt->max_length() - 1;
256 const streamsize __remainder = _M_ext_end - _M_ext_next;
257 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
261 if (_M_reading && this->egptr() == this->eback() && __remainder)
266 if (_M_ext_buf_size < __blen)
268 char* __buf =
new char[__blen];
270 __builtin_memcpy(__buf, _M_ext_next, __remainder);
272 delete [] _M_ext_buf;
274 _M_ext_buf_size = __blen;
276 else if (__remainder)
277 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
279 _M_ext_next = _M_ext_buf;
280 _M_ext_end = _M_ext_buf + __remainder;
281 _M_state_last = _M_state_cur;
290 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
292 __throw_ios_failure(__N(
"basic_filebuf::underflow "
293 "codecvt::max_length() "
296 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
299 else if (__elen == -1)
301 _M_ext_end += __elen;
304 char_type* __iend = this->eback();
305 if (_M_ext_next < _M_ext_end)
306 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
307 _M_ext_end, _M_ext_next,
309 this->eback() + __buflen, __iend);
310 if (__r == codecvt_base::noconv)
312 size_t __avail = _M_ext_end - _M_ext_buf;
313 __ilen =
std::min(__avail, __buflen);
314 traits_type::copy(this->eback(),
315 reinterpret_cast<char_type*>
316 (_M_ext_buf), __ilen);
317 _M_ext_next = _M_ext_buf + __ilen;
320 __ilen = __iend - this->eback();
325 if (__r == codecvt_base::error)
330 while (__ilen == 0 && !__got_eof);
335 _M_set_buffer(__ilen);
337 __ret = traits_type::to_int_type(*this->gptr());
348 if (__r == codecvt_base::partial)
349 __throw_ios_failure(__N(
"basic_filebuf::underflow "
350 "incomplete character in file"));
352 else if (__r == codecvt_base::error)
353 __throw_ios_failure(__N(
"basic_filebuf::underflow "
354 "invalid byte sequence in file"));
356 __throw_ios_failure(__N(
"basic_filebuf::underflow "
357 "error reading the file"));
362 template<
typename _CharT,
typename _Traits>
363 typename basic_filebuf<_CharT, _Traits>::int_type
367 int_type __ret = traits_type::eof();
373 if (overflow() == traits_type::eof())
380 const bool __testpb = _M_pback_init;
381 const bool __testeof = traits_type::eq_int_type(__i, __ret);
383 if (this->eback() < this->gptr())
386 __tmp = traits_type::to_int_type(*this->gptr());
388 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
390 __tmp = this->underflow();
391 if (traits_type::eq_int_type(__tmp, __ret))
406 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
409 __ret = traits_type::not_eof(__i);
414 *this->gptr() = traits_type::to_char_type(__i);
421 template<
typename _CharT,
typename _Traits>
422 typename basic_filebuf<_CharT, _Traits>::int_type
426 int_type __ret = traits_type::eof();
427 const bool __testeof = traits_type::eq_int_type(__c, __ret);
434 const int __gptr_off = _M_get_ext_pos(_M_state_last);
436 == pos_type(off_type(-1)))
439 if (this->pbase() < this->pptr())
444 *this->pptr() = traits_type::to_char_type(__c);
450 if (_M_convert_to_external(this->pbase(),
451 this->pptr() - this->pbase()))
454 __ret = traits_type::not_eof(__c);
457 else if (_M_buf_size > 1)
466 *this->pptr() = traits_type::to_char_type(__c);
469 __ret = traits_type::not_eof(__c);
474 char_type __conv = traits_type::to_char_type(__c);
475 if (__testeof || _M_convert_to_external(&__conv, 1))
478 __ret = traits_type::not_eof(__c);
485 template<
typename _CharT,
typename _Traits>
493 if (__check_facet(_M_codecvt).always_noconv())
495 __elen = _M_file.
xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
502 streamsize __blen = __ilen * _M_codecvt->max_length();
503 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
506 const char_type* __iend;
507 codecvt_base::result __r;
508 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
509 __iend, __buf, __buf + __blen, __bend);
511 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
512 __blen = __bend - __buf;
513 else if (__r == codecvt_base::noconv)
516 __buf =
reinterpret_cast<char*
>(__ibuf);
520 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
521 "conversion error"));
523 __elen = _M_file.xsputn(__buf, __blen);
527 if (__r == codecvt_base::partial && __elen == __plen)
529 const char_type* __iresume = __iend;
531 __r = _M_codecvt->out(_M_state_cur, __iresume,
532 __iresume + __rlen, __iend, __buf,
533 __buf + __blen, __bend);
534 if (__r != codecvt_base::error)
536 __rlen = __bend - __buf;
537 __elen = _M_file.xsputn(__buf, __rlen);
541 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
542 "conversion error"));
545 return __elen == __plen;
548 template<
typename _CharT,
typename _Traits>
557 if (__n > 0 && this->gptr() == this->eback())
559 *__s++ = *this->gptr();
568 if (overflow() == traits_type::eof())
578 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
580 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
584 const streamsize __avail = this->egptr() - this->gptr();
587 traits_type::copy(__s, this->gptr(), __avail);
589 this->setg(this->eback(), this->gptr() + __avail,
600 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
603 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
604 "error reading the file"));
631 __ret += __streambuf_type::xsgetn(__s, __n);
636 template<
typename _CharT,
typename _Traits>
646 if (__check_facet(_M_codecvt).always_noconv()
647 && __testout && !_M_reading)
651 streamsize __bufavail = this->epptr() - this->pptr();
654 if (!_M_writing && _M_buf_size > 1)
655 __bufavail = _M_buf_size - 1;
660 const streamsize __buffill = this->pptr() - this->pbase();
661 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
662 __ret = _M_file.xsputn_2(__buf, __buffill,
663 reinterpret_cast<const char*>(__s),
665 if (__ret == __buffill + __n)
670 if (__ret > __buffill)
676 __ret = __streambuf_type::xsputn(__s, __n);
679 __ret = __streambuf_type::xsputn(__s, __n);
683 template<
typename _CharT,
typename _Traits>
688 if (!this->is_open())
690 if (__s == 0 && __n == 0)
692 else if (__s && __n > 0)
712 template<
typename _CharT,
typename _Traits>
713 typename basic_filebuf<_CharT, _Traits>::pos_type
715 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
719 __width = _M_codecvt->encoding();
723 pos_type __ret = pos_type(off_type(-1));
724 const bool __testfail = __off != 0 && __width <= 0;
725 if (this->is_open() && !__testfail)
732 && (!_M_writing || _M_codecvt->always_noconv());
743 __state_type __state = _M_state_beg;
744 off_type __computed_off = __off * __width;
747 __state = _M_state_last;
748 __computed_off += _M_get_ext_pos(__state);
751 __ret = _M_seek(__computed_off, __way, __state);
755 __computed_off = this->pptr() - this->pbase();
758 if (__file_off != off_type(-1))
760 __ret = __file_off + __computed_off;
761 __ret.state(__state);
772 template<
typename _CharT,
typename _Traits>
773 typename basic_filebuf<_CharT, _Traits>::pos_type
777 pos_type __ret = pos_type(off_type(-1));
782 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
787 template<
typename _CharT,
typename _Traits>
788 typename basic_filebuf<_CharT, _Traits>::pos_type
790 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
792 pos_type __ret = pos_type(off_type(-1));
793 if (_M_terminate_output())
795 off_type __file_off = _M_file.seekoff(__off, __way);
796 if (__file_off != off_type(-1))
800 _M_ext_next = _M_ext_end = _M_ext_buf;
802 _M_state_cur = __state;
804 __ret.state(_M_state_cur);
813 template<
typename _CharT,
typename _Traits>
814 int basic_filebuf<_CharT, _Traits>::
815 _M_get_ext_pos(__state_type& __state)
817 if (_M_codecvt->always_noconv())
818 return this->gptr() - this->egptr();
824 const int __gptr_off =
825 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
826 this->gptr() - this->eback());
827 return _M_ext_buf + __gptr_off - _M_ext_end;
831 template<
typename _CharT,
typename _Traits>
833 basic_filebuf<_CharT, _Traits>::
834 _M_terminate_output()
837 bool __testvalid =
true;
838 if (this->pbase() < this->pptr())
840 const int_type __tmp = this->overflow();
841 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
846 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
852 const size_t __blen = 128;
854 codecvt_base::result __r;
860 __r = _M_codecvt->unshift(_M_state_cur, __buf,
861 __buf + __blen, __next);
862 if (__r == codecvt_base::error)
864 else if (__r == codecvt_base::ok ||
865 __r == codecvt_base::partial)
867 __ilen = __next - __buf;
870 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
871 if (__elen != __ilen)
876 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
884 const int_type __tmp = this->overflow();
885 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
892 template<
typename _CharT,
typename _Traits>
900 if (this->pbase() < this->pptr())
902 const int_type __tmp = this->overflow();
903 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
909 template<
typename _CharT,
typename _Traits>
914 bool __testvalid =
true;
917 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
918 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
923 if ((_M_reading || _M_writing)
924 && __check_facet(_M_codecvt).encoding() == -1)
930 if (__check_facet(_M_codecvt).always_noconv())
933 && !__check_facet(_M_codecvt_tmp).always_noconv())
935 != pos_type(off_type(-1));
940 _M_ext_next = _M_ext_buf
941 + _M_codecvt->length(_M_state_last, _M_ext_buf,
943 this->gptr() - this->eback());
944 const streamsize __remainder = _M_ext_end - _M_ext_next;
946 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
948 _M_ext_next = _M_ext_buf;
949 _M_ext_end = _M_ext_buf + __remainder;
951 _M_state_last = _M_state_cur = _M_state_beg;
954 else if (_M_writing && (__testvalid = _M_terminate_output()))
960 _M_codecvt = _M_codecvt_tmp;
967 #if _GLIBCXX_EXTERN_TEMPLATE
973 #ifdef _GLIBCXX_USE_WCHAR_T
981 _GLIBCXX_END_NAMESPACE_VERSION