43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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>::
79 basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock),
80 _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
81 _M_state_last(), _M_buf(0), _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),
87 if (has_facet<__codecvt_type>(this->_M_buf_locale))
88 _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
91 template<
typename _CharT,
typename _Traits>
92 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
93 basic_filebuf<_CharT, _Traits>::
94 open(
const char* __s, ios_base::openmode __mode)
96 __filebuf_type *__ret = 0;
99 _M_file.open(__s, __mode);
102 _M_allocate_internal_buffer();
111 _M_state_last = _M_state_cur = _M_state_beg;
114 if ((__mode & ios_base::ate)
115 && this->seekoff(0, ios_base::end, __mode)
116 == pos_type(off_type(-1)))
125 template<
typename _CharT,
typename _Traits>
126 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
127 basic_filebuf<_CharT, _Traits>::
130 if (!this->is_open())
133 bool __testfail =
false;
136 struct __close_sentry
139 __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { }
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())
157 __catch(__cxxabiv1::__forced_unwind&)
163 { __testfail =
true; }
166 if (!_M_file.close())
175 template<
typename _CharT,
typename _Traits>
177 basic_filebuf<_CharT, _Traits>::
180 streamsize __ret = -1;
181 const bool __testin = _M_mode & ios_base::in;
182 if (__testin && this->is_open())
186 __ret = this->egptr() - this->gptr();
188 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
190 const bool __testbinary = _M_mode & ios_base::binary;
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
203 basic_filebuf<_CharT, _Traits>::
206 int_type __ret = traits_type::eof();
207 const bool __testin = _M_mode & ios_base::in;
212 if (overflow() == traits_type::eof())
222 if (this->gptr() < this->egptr())
223 return traits_type::to_int_type(*this->gptr());
226 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
229 bool __got_eof =
false;
231 streamsize __ilen = 0;
232 codecvt_base::result __r = codecvt_base::ok;
233 if (__check_facet(_M_codecvt).always_noconv())
235 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
244 const int __enc = _M_codecvt->encoding();
248 __blen = __rlen = __buflen * __enc;
251 __blen = __buflen + _M_codecvt->max_length() - 1;
254 const streamsize __remainder = _M_ext_end - _M_ext_next;
255 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
259 if (_M_reading && this->egptr() == this->eback() && __remainder)
264 if (_M_ext_buf_size < __blen)
266 char* __buf =
new char[__blen];
268 __builtin_memcpy(__buf, _M_ext_next, __remainder);
270 delete [] _M_ext_buf;
272 _M_ext_buf_size = __blen;
274 else if (__remainder)
275 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
277 _M_ext_next = _M_ext_buf;
278 _M_ext_end = _M_ext_buf + __remainder;
279 _M_state_last = _M_state_cur;
288 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
290 __throw_ios_failure(__N(
"basic_filebuf::underflow "
291 "codecvt::max_length() "
294 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
297 else if (__elen == -1)
299 _M_ext_end += __elen;
302 char_type* __iend = this->eback();
303 if (_M_ext_next < _M_ext_end)
304 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
305 _M_ext_end, _M_ext_next,
307 this->eback() + __buflen, __iend);
308 if (__r == codecvt_base::noconv)
310 size_t __avail = _M_ext_end - _M_ext_buf;
311 __ilen =
std::min(__avail, __buflen);
312 traits_type::copy(this->eback(),
313 reinterpret_cast<char_type*>
314 (_M_ext_buf), __ilen);
315 _M_ext_next = _M_ext_buf + __ilen;
318 __ilen = __iend - this->eback();
323 if (__r == codecvt_base::error)
328 while (__ilen == 0 && !__got_eof);
333 _M_set_buffer(__ilen);
335 __ret = traits_type::to_int_type(*this->gptr());
346 if (__r == codecvt_base::partial)
347 __throw_ios_failure(__N(
"basic_filebuf::underflow "
348 "incomplete character in file"));
350 else if (__r == codecvt_base::error)
351 __throw_ios_failure(__N(
"basic_filebuf::underflow "
352 "invalid byte sequence in file"));
354 __throw_ios_failure(__N(
"basic_filebuf::underflow "
355 "error reading the file"));
360 template<
typename _CharT,
typename _Traits>
361 typename basic_filebuf<_CharT, _Traits>::int_type
362 basic_filebuf<_CharT, _Traits>::
363 pbackfail(int_type __i)
365 int_type __ret = traits_type::eof();
366 const bool __testin = _M_mode & ios_base::in;
371 if (overflow() == traits_type::eof())
378 const bool __testpb = _M_pback_init;
379 const bool __testeof = traits_type::eq_int_type(__i, __ret);
381 if (this->eback() < this->gptr())
384 __tmp = traits_type::to_int_type(*this->gptr());
386 else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1)))
388 __tmp = this->underflow();
389 if (traits_type::eq_int_type(__tmp, __ret))
404 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
407 __ret = traits_type::not_eof(__i);
412 *this->gptr() = traits_type::to_char_type(__i);
419 template<
typename _CharT,
typename _Traits>
420 typename basic_filebuf<_CharT, _Traits>::int_type
421 basic_filebuf<_CharT, _Traits>::
422 overflow(int_type __c)
424 int_type __ret = traits_type::eof();
425 const bool __testeof = traits_type::eq_int_type(__c, __ret);
426 const bool __testout = _M_mode & ios_base::out;
432 const int __gptr_off = _M_get_ext_pos(_M_state_last);
433 if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
434 == pos_type(off_type(-1)))
437 if (this->pbase() < this->pptr())
442 *this->pptr() = traits_type::to_char_type(__c);
448 if (_M_convert_to_external(this->pbase(),
449 this->pptr() - this->pbase()))
452 __ret = traits_type::not_eof(__c);
455 else if (_M_buf_size > 1)
464 *this->pptr() = traits_type::to_char_type(__c);
467 __ret = traits_type::not_eof(__c);
472 char_type __conv = traits_type::to_char_type(__c);
473 if (__testeof || _M_convert_to_external(&__conv, 1))
476 __ret = traits_type::not_eof(__c);
483 template<
typename _CharT,
typename _Traits>
485 basic_filebuf<_CharT, _Traits>::
486 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
491 if (__check_facet(_M_codecvt).always_noconv())
493 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
500 streamsize __blen = __ilen * _M_codecvt->max_length();
501 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
504 const char_type* __iend;
505 codecvt_base::result __r;
506 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
507 __iend, __buf, __buf + __blen, __bend);
509 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
510 __blen = __bend - __buf;
511 else if (__r == codecvt_base::noconv)
514 __buf =
reinterpret_cast<char*
>(__ibuf);
518 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
519 "conversion error"));
521 __elen = _M_file.xsputn(__buf, __blen);
525 if (__r == codecvt_base::partial && __elen == __plen)
527 const char_type* __iresume = __iend;
528 streamsize __rlen = this->pptr() - __iend;
529 __r = _M_codecvt->out(_M_state_cur, __iresume,
530 __iresume + __rlen, __iend, __buf,
531 __buf + __blen, __bend);
532 if (__r != codecvt_base::error)
534 __rlen = __bend - __buf;
535 __elen = _M_file.xsputn(__buf, __rlen);
539 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
540 "conversion error"));
543 return __elen == __plen;
546 template<
typename _CharT,
typename _Traits>
548 basic_filebuf<_CharT, _Traits>::
549 xsgetn(_CharT* __s, streamsize __n)
552 streamsize __ret = 0;
555 if (__n > 0 && this->gptr() == this->eback())
557 *__s++ = *this->gptr();
566 if (overflow() == traits_type::eof())
575 const bool __testin = _M_mode & ios_base::in;
576 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
578 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
582 const streamsize __avail = this->egptr() - this->gptr();
585 traits_type::copy(__s, this->gptr(), __avail);
587 this->setg(this->eback(), this->gptr() + __avail,
598 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
601 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
602 "error reading the file"));
629 __ret += __streambuf_type::xsgetn(__s, __n);
634 template<
typename _CharT,
typename _Traits>
636 basic_filebuf<_CharT, _Traits>::
637 xsputn(
const _CharT* __s, streamsize __n)
639 streamsize __ret = 0;
643 const bool __testout = _M_mode & ios_base::out;
644 if (__check_facet(_M_codecvt).always_noconv()
645 && __testout && !_M_reading)
648 const streamsize __chunk = 1ul << 10;
649 streamsize __bufavail = this->epptr() - this->pptr();
652 if (!_M_writing && _M_buf_size > 1)
653 __bufavail = _M_buf_size - 1;
655 const streamsize __limit =
std::min(__chunk, __bufavail);
658 const streamsize __buffill = this->pptr() - this->pbase();
659 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
660 __ret = _M_file.xsputn_2(__buf, __buffill,
661 reinterpret_cast<const char*>(__s),
663 if (__ret == __buffill + __n)
668 if (__ret > __buffill)
674 __ret = __streambuf_type::xsputn(__s, __n);
677 __ret = __streambuf_type::xsputn(__s, __n);
681 template<
typename _CharT,
typename _Traits>
682 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
683 basic_filebuf<_CharT, _Traits>::
684 setbuf(char_type* __s, streamsize __n)
686 if (!this->is_open())
688 if (__s == 0 && __n == 0)
690 else if (__s && __n > 0)
710 template<
typename _CharT,
typename _Traits>
711 typename basic_filebuf<_CharT, _Traits>::pos_type
712 basic_filebuf<_CharT, _Traits>::
713 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
717 __width = _M_codecvt->encoding();
721 pos_type __ret = pos_type(off_type(-1));
722 const bool __testfail = __off != 0 && __width <= 0;
723 if (this->is_open() && !__testfail)
729 bool __no_movement = __way == ios_base::cur && __off == 0
730 && (!_M_writing || _M_codecvt->always_noconv());
742 off_type __computed_off = __off * __width;
743 if (_M_reading && __way == ios_base::cur)
745 __state = _M_state_last;
746 __computed_off += _M_get_ext_pos(__state);
749 __ret = _M_seek(__computed_off, __way, __state);
753 __computed_off = this->pptr() - this->pbase();
755 off_type __file_off = _M_file.seekoff(0, ios_base::cur);
756 if (__file_off != off_type(-1))
758 __ret = __file_off + __computed_off;
759 __ret.state(__state);
770 template<
typename _CharT,
typename _Traits>
771 typename basic_filebuf<_CharT, _Traits>::pos_type
772 basic_filebuf<_CharT, _Traits>::
773 seekpos(pos_type __pos, ios_base::openmode)
775 pos_type __ret = pos_type(off_type(-1));
780 __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
785 template<
typename _CharT,
typename _Traits>
786 typename basic_filebuf<_CharT, _Traits>::pos_type
787 basic_filebuf<_CharT, _Traits>::
788 _M_seek(off_type __off, ios_base::seekdir __way,
__state_type __state)
790 pos_type __ret = pos_type(off_type(-1));
791 if (_M_terminate_output())
793 off_type __file_off = _M_file.seekoff(__off, __way);
794 if (__file_off != off_type(-1))
798 _M_ext_next = _M_ext_end = _M_ext_buf;
800 _M_state_cur = __state;
802 __ret.state(_M_state_cur);
811 template<
typename _CharT,
typename _Traits>
812 int basic_filebuf<_CharT, _Traits>::
815 if (_M_codecvt->always_noconv())
816 return this->gptr() - this->egptr();
822 const int __gptr_off =
823 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
824 this->gptr() - this->eback());
825 return _M_ext_buf + __gptr_off - _M_ext_end;
829 template<
typename _CharT,
typename _Traits>
831 basic_filebuf<_CharT, _Traits>::
832 _M_terminate_output()
835 bool __testvalid =
true;
836 if (this->pbase() < this->pptr())
838 const int_type __tmp = this->overflow();
839 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
844 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
850 const size_t __blen = 128;
852 codecvt_base::result __r;
853 streamsize __ilen = 0;
858 __r = _M_codecvt->unshift(_M_state_cur, __buf,
859 __buf + __blen, __next);
860 if (__r == codecvt_base::error)
862 else if (__r == codecvt_base::ok ||
863 __r == codecvt_base::partial)
865 __ilen = __next - __buf;
868 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
869 if (__elen != __ilen)
874 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
882 const int_type __tmp = this->overflow();
883 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
890 template<
typename _CharT,
typename _Traits>
892 basic_filebuf<_CharT, _Traits>::
898 if (this->pbase() < this->pptr())
900 const int_type __tmp = this->overflow();
901 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
907 template<
typename _CharT,
typename _Traits>
909 basic_filebuf<_CharT, _Traits>::
910 imbue(
const locale& __loc)
912 bool __testvalid =
true;
914 const __codecvt_type* _M_codecvt_tmp = 0;
915 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
916 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
921 if ((_M_reading || _M_writing)
922 && __check_facet(_M_codecvt).encoding() == -1)
928 if (__check_facet(_M_codecvt).always_noconv())
931 && !__check_facet(_M_codecvt_tmp).always_noconv())
932 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
933 != pos_type(off_type(-1));
938 _M_ext_next = _M_ext_buf
939 + _M_codecvt->length(_M_state_last, _M_ext_buf,
941 this->gptr() - this->eback());
942 const streamsize __remainder = _M_ext_end - _M_ext_next;
944 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
946 _M_ext_next = _M_ext_buf;
947 _M_ext_end = _M_ext_buf + __remainder;
949 _M_state_last = _M_state_cur = _M_state_beg;
952 else if (_M_writing && (__testvalid = _M_terminate_output()))
958 _M_codecvt = _M_codecvt_tmp;
965 #if _GLIBCXX_EXTERN_TEMPLATE
966 extern template class basic_filebuf<char>;
967 extern template class basic_ifstream<char>;
968 extern template class basic_ofstream<char>;
969 extern template class basic_fstream<char>;
971 #ifdef _GLIBCXX_USE_WCHAR_T
972 extern template class basic_filebuf<wchar_t>;
973 extern template class basic_ifstream<wchar_t>;
974 extern template class basic_ofstream<wchar_t>;
975 extern template class basic_fstream<wchar_t>;
979 _GLIBCXX_END_NAMESPACE_VERSION
#define false
Definition: stdbool.h:35
#define __try
Definition: exception_defines.h:35
#define __throw_exception_again
Definition: exception_defines.h:37
const _Tp & min(const _Tp &__a, const _Tp &__b)
Equivalent to std::min.
Definition: base.h:144
__state_type
Definition: profiler_state.h:35
#define __catch(X)
Definition: exception_defines.h:36