37 #define _FSTREAM_TCC 1
39 #pragma GCC system_header
41 #include <cxxabi-forced.h>
43 _GLIBCXX_BEGIN_NAMESPACE(std)
45 template<typename _CharT, typename _Traits>
47 basic_filebuf<_CharT, _Traits>::
48 _M_allocate_internal_buffer()
52 if (!_M_buf_allocated && !_M_buf)
54 _M_buf =
new char_type[_M_buf_size];
55 _M_buf_allocated =
true;
59 template<
typename _CharT,
typename _Traits>
61 basic_filebuf<_CharT, _Traits>::
62 _M_destroy_internal_buffer() throw()
68 _M_buf_allocated =
false;
77 template<
typename _CharT,
typename _Traits>
78 basic_filebuf<_CharT, _Traits>::
80 _M_mode(
ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
81 _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ),
82 _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
83 _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
84 _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
91 template<
typename _CharT,
typename _Traits>
94 open(
const char* __s, ios_base::openmode __mode)
99 _M_file.
open(__s, __mode);
102 _M_allocate_internal_buffer();
111 _M_state_last = _M_state_cur = _M_state_beg;
116 == pos_type(off_type(-1)))
125 template<
typename _CharT,
typename _Traits>
130 if (!this->is_open())
133 bool __testfail =
false;
136 struct __close_sentry
142 __fb->_M_mode = ios_base::openmode(0);
143 __fb->_M_pback_init =
false;
144 __fb->_M_destroy_internal_buffer();
145 __fb->_M_reading =
false;
146 __fb->_M_writing =
false;
147 __fb->_M_set_buffer(-1);
148 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
154 if (!_M_terminate_output())
160 __throw_exception_again;
163 { __testfail =
true; }
166 if (!_M_file.close())
175 template<
typename _CharT,
typename _Traits>
182 if (__testin && this->is_open())
186 __ret = this->egptr() - this->gptr();
188 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
191 if (__check_facet(_M_codecvt).encoding() >= 0
194 if (__check_facet(_M_codecvt).encoding() >= 0)
196 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
201 template<
typename _CharT,
typename _Traits>
202 typename basic_filebuf<_CharT, _Traits>::int_type
206 int_type __ret = traits_type::eof();
208 if (__testin && !_M_writing)
215 if (this->gptr() < this->egptr())
216 return traits_type::to_int_type(*this->gptr());
219 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
222 bool __got_eof =
false;
225 codecvt_base::result __r = codecvt_base::ok;
226 if (__check_facet(_M_codecvt).always_noconv())
228 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
237 const int __enc = _M_codecvt->encoding();
241 __blen = __rlen = __buflen * __enc;
244 __blen = __buflen + _M_codecvt->max_length() - 1;
247 const streamsize __remainder = _M_ext_end - _M_ext_next;
248 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
252 if (_M_reading && this->egptr() == this->eback() && __remainder)
257 if (_M_ext_buf_size < __blen)
259 char* __buf =
new char[__blen];
261 __builtin_memcpy(__buf, _M_ext_next, __remainder);
263 delete [] _M_ext_buf;
265 _M_ext_buf_size = __blen;
267 else if (__remainder)
268 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
270 _M_ext_next = _M_ext_buf;
271 _M_ext_end = _M_ext_buf + __remainder;
272 _M_state_last = _M_state_cur;
281 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
283 __throw_ios_failure(__N(
"basic_filebuf::underflow "
284 "codecvt::max_length() "
287 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
290 else if (__elen == -1)
292 _M_ext_end += __elen;
295 char_type* __iend = this->eback();
296 if (_M_ext_next < _M_ext_end)
297 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
298 _M_ext_end, _M_ext_next,
300 this->eback() + __buflen, __iend);
301 if (__r == codecvt_base::noconv)
303 size_t __avail = _M_ext_end - _M_ext_buf;
304 __ilen =
std::min(__avail, __buflen);
305 traits_type::copy(this->eback(),
306 reinterpret_cast<char_type*>
307 (_M_ext_buf), __ilen);
308 _M_ext_next = _M_ext_buf + __ilen;
311 __ilen = __iend - this->eback();
316 if (__r == codecvt_base::error)
321 while (__ilen == 0 && !__got_eof);
326 _M_set_buffer(__ilen);
328 __ret = traits_type::to_int_type(*this->gptr());
339 if (__r == codecvt_base::partial)
340 __throw_ios_failure(__N(
"basic_filebuf::underflow "
341 "incomplete character in file"));
343 else if (__r == codecvt_base::error)
344 __throw_ios_failure(__N(
"basic_filebuf::underflow "
345 "invalid byte sequence in file"));
347 __throw_ios_failure(__N(
"basic_filebuf::underflow "
348 "error reading the file"));
353 template<
typename _CharT,
typename _Traits>
354 typename basic_filebuf<_CharT, _Traits>::int_type
358 int_type __ret = traits_type::eof();
360 if (__testin && !_M_writing)
364 const bool __testpb = _M_pback_init;
365 const bool __testeof = traits_type::eq_int_type(__i, __ret);
367 if (this->eback() < this->gptr())
370 __tmp = traits_type::to_int_type(*this->gptr());
372 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
374 __tmp = this->underflow();
375 if (traits_type::eq_int_type(__tmp, __ret))
390 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
393 __ret = traits_type::not_eof(__i);
398 *this->gptr() = traits_type::to_char_type(__i);
405 template<
typename _CharT,
typename _Traits>
406 typename basic_filebuf<_CharT, _Traits>::int_type
410 int_type __ret = traits_type::eof();
411 const bool __testeof = traits_type::eq_int_type(__c, __ret);
413 if (__testout && !_M_reading)
415 if (this->pbase() < this->pptr())
420 *this->pptr() = traits_type::to_char_type(__c);
426 if (_M_convert_to_external(this->pbase(),
427 this->pptr() - this->pbase()))
430 __ret = traits_type::not_eof(__c);
433 else if (_M_buf_size > 1)
442 *this->pptr() = traits_type::to_char_type(__c);
445 __ret = traits_type::not_eof(__c);
450 char_type __conv = traits_type::to_char_type(__c);
451 if (__testeof || _M_convert_to_external(&__conv, 1))
454 __ret = traits_type::not_eof(__c);
461 template<
typename _CharT,
typename _Traits>
469 if (__check_facet(_M_codecvt).always_noconv())
471 __elen = _M_file.
xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
478 streamsize __blen = __ilen * _M_codecvt->max_length();
479 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
482 const char_type* __iend;
483 codecvt_base::result __r;
484 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
485 __iend, __buf, __buf + __blen, __bend);
487 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
488 __blen = __bend - __buf;
489 else if (__r == codecvt_base::noconv)
492 __buf =
reinterpret_cast<char*
>(__ibuf);
496 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
497 "conversion error"));
499 __elen = _M_file.xsputn(__buf, __blen);
503 if (__r == codecvt_base::partial && __elen == __plen)
505 const char_type* __iresume = __iend;
507 __r = _M_codecvt->out(_M_state_cur, __iresume,
508 __iresume + __rlen, __iend, __buf,
509 __buf + __blen, __bend);
510 if (__r != codecvt_base::error)
512 __rlen = __bend - __buf;
513 __elen = _M_file.xsputn(__buf, __rlen);
517 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
518 "conversion error"));
521 return __elen == __plen;
524 template<
typename _CharT,
typename _Traits>
533 if (__n > 0 && this->gptr() == this->eback())
535 *__s++ = *this->gptr();
547 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
549 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
550 && __testin && !_M_writing)
553 const streamsize __avail = this->egptr() - this->gptr();
557 *__s = *this->gptr();
559 traits_type::copy(__s, this->gptr(), __avail);
561 this->gbump(__avail);
571 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
574 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
575 "error reading the file"));
602 __ret += __streambuf_type::xsgetn(__s, __n);
607 template<
typename _CharT,
typename _Traits>
617 if (__check_facet(_M_codecvt).always_noconv()
618 && __testout && !_M_reading)
622 streamsize __bufavail = this->epptr() - this->pptr();
625 if (!_M_writing && _M_buf_size > 1)
626 __bufavail = _M_buf_size - 1;
631 const streamsize __buffill = this->pptr() - this->pbase();
632 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
633 __ret = _M_file.xsputn_2(__buf, __buffill,
634 reinterpret_cast<const char*>(__s),
636 if (__ret == __buffill + __n)
641 if (__ret > __buffill)
647 __ret = __streambuf_type::xsputn(__s, __n);
650 __ret = __streambuf_type::xsputn(__s, __n);
654 template<
typename _CharT,
typename _Traits>
659 if (!this->is_open())
661 if (__s == 0 && __n == 0)
663 else if (__s && __n > 0)
683 template<
typename _CharT,
typename _Traits>
684 typename basic_filebuf<_CharT, _Traits>::pos_type
686 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
690 __width = _M_codecvt->encoding();
694 pos_type __ret = pos_type(off_type(-1));
695 const bool __testfail = __off != 0 && __width <= 0;
696 if (this->is_open() && !__testfail)
706 __state_type __state = _M_state_beg;
707 off_type __computed_off = __off * __width;
710 if (_M_codecvt->always_noconv())
711 __computed_off += this->gptr() - this->egptr();
717 const int __gptr_off =
718 _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
719 this->gptr() - this->eback());
720 __computed_off += _M_ext_buf + __gptr_off - _M_ext_end;
724 __state = _M_state_last;
727 __ret = _M_seek(__computed_off, __way, __state);
736 template<
typename _CharT,
typename _Traits>
737 typename basic_filebuf<_CharT, _Traits>::pos_type
741 pos_type __ret = pos_type(off_type(-1));
746 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
751 template<
typename _CharT,
typename _Traits>
752 typename basic_filebuf<_CharT, _Traits>::pos_type
754 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
756 pos_type __ret = pos_type(off_type(-1));
757 if (_M_terminate_output())
760 __ret = pos_type(_M_file.seekoff(__off, __way));
761 if (__ret != pos_type(off_type(-1)))
765 _M_ext_next = _M_ext_end = _M_ext_buf;
767 _M_state_cur = __state;
768 __ret.state(_M_state_cur);
774 template<
typename _CharT,
typename _Traits>
776 basic_filebuf<_CharT, _Traits>::
777 _M_terminate_output()
780 bool __testvalid =
true;
781 if (this->pbase() < this->pptr())
783 const int_type __tmp = this->overflow();
784 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
789 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
795 const size_t __blen = 128;
797 codecvt_base::result __r;
803 __r = _M_codecvt->unshift(_M_state_cur, __buf,
804 __buf + __blen, __next);
805 if (__r == codecvt_base::error)
807 else if (__r == codecvt_base::ok ||
808 __r == codecvt_base::partial)
810 __ilen = __next - __buf;
813 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
814 if (__elen != __ilen)
819 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
827 const int_type __tmp = this->overflow();
828 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
835 template<
typename _CharT,
typename _Traits>
843 if (this->pbase() < this->pptr())
845 const int_type __tmp = this->overflow();
846 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
852 template<
typename _CharT,
typename _Traits>
857 bool __testvalid =
true;
860 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
861 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
866 if ((_M_reading || _M_writing)
867 && __check_facet(_M_codecvt).encoding() == -1)
873 if (__check_facet(_M_codecvt).always_noconv())
876 && !__check_facet(_M_codecvt_tmp).always_noconv())
878 != pos_type(off_type(-1));
883 _M_ext_next = _M_ext_buf
884 + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
885 this->gptr() - this->eback());
886 const streamsize __remainder = _M_ext_end - _M_ext_next;
888 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
890 _M_ext_next = _M_ext_buf;
891 _M_ext_end = _M_ext_buf + __remainder;
893 _M_state_last = _M_state_cur = _M_state_beg;
896 else if (_M_writing && (__testvalid = _M_terminate_output()))
902 _M_codecvt = _M_codecvt_tmp;
910 #if _GLIBCXX_EXTERN_TEMPLATE
916 #ifdef _GLIBCXX_USE_WCHAR_T
924 _GLIBCXX_END_NAMESPACE