37#pragma GCC system_header
43namespace 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(_GLIBCXX_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),
89 _M_codecvt = std::__try_use_facet<__codecvt_type>(this->
_M_buf_locale);
92#if __cplusplus >= 201103L
93 template<
typename _CharT,
typename _Traits>
96 : __streambuf_type(__rhs),
97 _M_lock(), _M_file(
std::
move(__rhs._M_file), &_M_lock),
98 _M_mode(
std::__exchange(__rhs._M_mode,
ios_base::openmode(0))),
99 _M_state_beg(
std::
move(__rhs._M_state_beg)),
100 _M_state_cur(
std::
move(__rhs._M_state_cur)),
101 _M_state_last(
std::
move(__rhs._M_state_last)),
102 _M_buf(
std::__exchange(__rhs._M_buf, nullptr)),
103 _M_buf_size(
std::__exchange(__rhs._M_buf_size, 1)),
104 _M_buf_allocated(
std::__exchange(__rhs._M_buf_allocated, false)),
105 _M_reading(
std::__exchange(__rhs._M_reading, false)),
106 _M_writing(
std::__exchange(__rhs._M_writing, false)),
107 _M_pback(__rhs._M_pback),
108 _M_pback_cur_save(
std::__exchange(__rhs._M_pback_cur_save, nullptr)),
109 _M_pback_end_save(
std::__exchange(__rhs._M_pback_end_save, nullptr)),
110 _M_pback_init(
std::__exchange(__rhs._M_pback_init, false)),
111 _M_codecvt(__rhs._M_codecvt),
112 _M_ext_buf(
std::__exchange(__rhs._M_ext_buf, nullptr)),
113 _M_ext_buf_size(
std::__exchange(__rhs._M_ext_buf_size, 0)),
114 _M_ext_next(
std::__exchange(__rhs._M_ext_next, nullptr)),
115 _M_ext_end(
std::__exchange(__rhs._M_ext_end, nullptr))
117 __rhs._M_set_buffer(-1);
118 __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg;
121 template<
typename _CharT,
typename _Traits>
122 basic_filebuf<_CharT, _Traits>&
123 basic_filebuf<_CharT, _Traits>::
124 operator=(basic_filebuf&& __rhs)
127 __streambuf_type::operator=(__rhs);
128 _M_file.swap(__rhs._M_file);
130 _M_state_beg =
std::move(__rhs._M_state_beg);
131 _M_state_cur =
std::move(__rhs._M_state_cur);
132 _M_state_last =
std::move(__rhs._M_state_last);
133 _M_buf = std::__exchange(__rhs._M_buf,
nullptr);
134 _M_buf_size = std::__exchange(__rhs._M_buf_size, 1);
135 _M_buf_allocated = std::__exchange(__rhs._M_buf_allocated,
false);
136 _M_ext_buf = std::__exchange(__rhs._M_ext_buf,
nullptr);
137 _M_ext_buf_size = std::__exchange(__rhs._M_ext_buf_size, 0);
138 _M_ext_next = std::__exchange(__rhs._M_ext_next,
nullptr);
139 _M_ext_end = std::__exchange(__rhs._M_ext_end,
nullptr);
140 _M_reading = std::__exchange(__rhs._M_reading,
false);
141 _M_writing = std::__exchange(__rhs._M_writing,
false);
142 _M_pback_cur_save = std::__exchange(__rhs._M_pback_cur_save,
nullptr);
143 _M_pback_end_save = std::__exchange(__rhs._M_pback_end_save,
nullptr);
144 _M_pback_init = std::__exchange(__rhs._M_pback_init,
false);
145 __rhs._M_set_buffer(-1);
146 __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg;
150 template<
typename _CharT,
typename _Traits>
152 basic_filebuf<_CharT, _Traits>::
153 swap(basic_filebuf& __rhs)
155 __streambuf_type::swap(__rhs);
156 _M_file.swap(__rhs._M_file);
158 std::swap(_M_state_beg, __rhs._M_state_beg);
159 std::swap(_M_state_cur, __rhs._M_state_cur);
160 std::swap(_M_state_last, __rhs._M_state_last);
162 std::swap(_M_buf_size, __rhs._M_buf_size);
163 std::swap(_M_buf_allocated, __rhs._M_buf_allocated);
165 std::swap(_M_ext_buf_size, __rhs._M_ext_buf_size);
166 std::swap(_M_ext_next, __rhs._M_ext_next);
170 std::swap(_M_pback_cur_save, __rhs._M_pback_cur_save);
171 std::swap(_M_pback_end_save, __rhs._M_pback_end_save);
172 std::swap(_M_pback_init, __rhs._M_pback_init);
176 template<
typename _CharT,
typename _Traits>
177 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
179 open(
const char* __s, ios_base::openmode __mode)
182 if (!this->is_open())
184 _M_file.
open(__s, __mode);
187 _M_allocate_internal_buffer();
196 _M_state_last = _M_state_cur = _M_state_beg;
201 == pos_type(off_type(-1)))
210#if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
211 template<
typename _CharT,
typename _Traits>
214 open(
const wchar_t* __s, ios_base::openmode __mode)
216 __filebuf_type *__ret = 0;
217 if (!this->is_open())
219 _M_file.
open(__s, __mode);
222 _M_allocate_internal_buffer();
231 _M_state_last = _M_state_cur = _M_state_beg;
236 == pos_type(off_type(-1)))
246 template<
typename _CharT,
typename _Traits>
251 if (!this->is_open())
254 bool __testfail =
false;
257 struct __close_sentry
263 __fb->
_M_mode = ios_base::openmode(0);
265 __fb->_M_destroy_internal_buffer();
267 __fb->_M_writing =
false;
269 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
275 if (!_M_terminate_output())
281 __throw_exception_again;
285 if (!_M_file.close())
294 template<
typename _CharT,
typename _Traits>
301 if (__testin && this->is_open())
305 __ret = this->egptr() - this->gptr();
307#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
310 if (__check_facet(_M_codecvt).encoding() >= 0
313 if (__check_facet(_M_codecvt).encoding() >= 0)
315 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
320 template<
typename _CharT,
typename _Traits>
321 typename basic_filebuf<_CharT, _Traits>::int_type
325 int_type __ret = traits_type::eof();
331 if (overflow() == traits_type::eof())
341 if (this->gptr() < this->egptr())
342 return traits_type::to_int_type(*this->gptr());
345 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
348 bool __got_eof =
false;
351 codecvt_base::result __r = codecvt_base::ok;
352 if (__check_facet(_M_codecvt).always_noconv())
354 __ilen = _M_file.xsgetn(
reinterpret_cast<char*
>(this->eback()),
363 const int __enc = _M_codecvt->encoding();
367 __blen = __rlen = __buflen * __enc;
370 __blen = __buflen + _M_codecvt->max_length() - 1;
373 const streamsize __remainder = _M_ext_end - _M_ext_next;
374 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
378 if (_M_reading && this->egptr() == this->eback() && __remainder)
383 if (_M_ext_buf_size < __blen)
385 char* __buf =
new char[__blen];
387 __builtin_memcpy(__buf, _M_ext_next, __remainder);
389 delete [] _M_ext_buf;
391 _M_ext_buf_size = __blen;
393 else if (__remainder)
394 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
396 _M_ext_next = _M_ext_buf;
397 _M_ext_end = _M_ext_buf + __remainder;
398 _M_state_last = _M_state_cur;
407 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
409 __throw_ios_failure(__N(
"basic_filebuf::underflow "
410 "codecvt::max_length() "
413 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
416 else if (__elen == -1)
418 _M_ext_end += __elen;
421 char_type* __iend = this->eback();
422 if (_M_ext_next < _M_ext_end)
423 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
424 _M_ext_end, _M_ext_next,
426 this->eback() + __buflen, __iend);
427 if (__r == codecvt_base::noconv)
429 size_t __avail = _M_ext_end - _M_ext_buf;
430 __ilen =
std::min(__avail, __buflen);
431 traits_type::copy(this->eback(),
432 reinterpret_cast<char_type*
>
433 (_M_ext_buf), __ilen);
434 _M_ext_next = _M_ext_buf + __ilen;
437 __ilen = __iend - this->eback();
442 if (__r == codecvt_base::error)
447 while (__ilen == 0 && !__got_eof);
452 _M_set_buffer(__ilen);
454 __ret = traits_type::to_int_type(*this->gptr());
465 if (__r == codecvt_base::partial)
466 __throw_ios_failure(__N(
"basic_filebuf::underflow "
467 "incomplete character in file"));
469 else if (__r == codecvt_base::error)
470 __throw_ios_failure(__N(
"basic_filebuf::underflow "
471 "invalid byte sequence in file"));
473 __throw_ios_failure(__N(
"basic_filebuf::underflow "
474 "error reading the file"), errno);
479 template<
typename _CharT,
typename _Traits>
480 typename basic_filebuf<_CharT, _Traits>::int_type
484 int_type __ret = traits_type::eof();
490 if (overflow() == traits_type::eof())
497 const bool __testpb = _M_pback_init;
498 const bool __testeof = traits_type::eq_int_type(__i, __ret);
500 if (this->eback() < this->gptr())
503 __tmp = traits_type::to_int_type(*this->gptr());
505 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
507 __tmp = this->underflow();
508 if (traits_type::eq_int_type(__tmp, __ret))
523 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
526 __ret = traits_type::not_eof(__i);
531 *this->gptr() = traits_type::to_char_type(__i);
538 template<
typename _CharT,
typename _Traits>
539 typename basic_filebuf<_CharT, _Traits>::int_type
543 int_type __ret = traits_type::eof();
544 const bool __testeof = traits_type::eq_int_type(__c, __ret);
552 const int __gptr_off = _M_get_ext_pos(_M_state_last);
554 == pos_type(off_type(-1)))
557 if (this->pbase() < this->pptr())
562 *this->pptr() = traits_type::to_char_type(__c);
568 if (_M_convert_to_external(this->pbase(),
569 this->pptr() - this->pbase()))
572 __ret = traits_type::not_eof(__c);
575 else if (_M_buf_size > 1)
584 *this->pptr() = traits_type::to_char_type(__c);
587 __ret = traits_type::not_eof(__c);
592 char_type __conv = traits_type::to_char_type(__c);
593 if (__testeof || _M_convert_to_external(&__conv, 1))
596 __ret = traits_type::not_eof(__c);
603 template<
typename _CharT,
typename _Traits>
611 if (__check_facet(_M_codecvt).always_noconv())
613 __elen = _M_file.
xsputn(
reinterpret_cast<char*
>(__ibuf), __ilen);
620 streamsize __blen = __ilen * _M_codecvt->max_length();
621 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
624 const char_type* __iend;
625 codecvt_base::result __r;
626 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
627 __iend, __buf, __buf + __blen, __bend);
629 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
630 __blen = __bend - __buf;
631 else if (__r == codecvt_base::noconv)
634 __buf =
reinterpret_cast<char*
>(__ibuf);
638 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
639 "conversion error"));
641 __elen = _M_file.xsputn(__buf, __blen);
645 if (__r == codecvt_base::partial && __elen == __plen)
647 const char_type* __iresume = __iend;
649 __r = _M_codecvt->out(_M_state_cur, __iresume,
650 __iresume + __rlen, __iend, __buf,
651 __buf + __blen, __bend);
652 if (__r != codecvt_base::error)
654 __rlen = __bend - __buf;
655 __elen = _M_file.xsputn(__buf, __rlen);
659 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
660 "conversion error"));
663 return __elen == __plen;
666 template<
typename _CharT,
typename _Traits>
675 if (__n > 0 && this->gptr() == this->eback())
677 *__s++ = *this->gptr();
686 if (overflow() == traits_type::eof())
696 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
698 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
702 const streamsize __avail = this->egptr() - this->gptr();
705 traits_type::copy(__s, this->gptr(), __avail);
707 this->setg(this->eback(), this->gptr() + __avail, this->egptr());
717 __len = _M_file.xsgetn(
reinterpret_cast<char*
>(__s), __n);
719 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
720 "error reading the file"), errno);
747 __ret += __streambuf_type::xsgetn(__s, __n);
752 template<
typename _CharT,
typename _Traits>
763 if (__check_facet(_M_codecvt).always_noconv()
764 && __testout && !_M_reading)
766 streamsize __bufavail = this->epptr() - this->pptr();
769 if (!_M_writing && _M_buf_size > 1)
770 __bufavail = _M_buf_size - 1;
772 if (__n >= __bufavail)
774 const streamsize __buffill = this->pptr() - this->pbase();
775 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
776 __ret = _M_file.xsputn_2(__buf, __buffill,
777 reinterpret_cast<const char*
>(__s),
779 if (__ret == __buffill + __n)
784 if (__ret > __buffill)
790 __ret = __streambuf_type::xsputn(__s, __n);
793 __ret = __streambuf_type::xsputn(__s, __n);
797 template<
typename _CharT,
typename _Traits>
802 if (!this->is_open())
804 if (__s == 0 && __n == 0)
806 else if (__s && __n > 0)
826 template<
typename _CharT,
typename _Traits>
827 typename basic_filebuf<_CharT, _Traits>::pos_type
829 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
833 __width = _M_codecvt->encoding();
837 pos_type __ret = pos_type(off_type(-1));
838 const bool __testfail = __off != 0 && __width <= 0;
839 if (this->is_open() && !__testfail)
846 && (!_M_writing || _M_codecvt->always_noconv());
857 __state_type __state = _M_state_beg;
858 off_type __computed_off = __off * __width;
861 __state = _M_state_last;
862 __computed_off += _M_get_ext_pos(__state);
865 __ret = _M_seek(__computed_off, __way, __state);
869 __computed_off = this->pptr() - this->pbase();
872 if (__file_off != off_type(-1))
874 __ret = __file_off + __computed_off;
875 __ret.state(__state);
886 template<
typename _CharT,
typename _Traits>
887 typename basic_filebuf<_CharT, _Traits>::pos_type
889 seekpos(pos_type __pos, ios_base::openmode)
891 pos_type __ret = pos_type(off_type(-1));
896 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
901 template<
typename _CharT,
typename _Traits>
902 typename basic_filebuf<_CharT, _Traits>::pos_type
904 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
906 pos_type __ret = pos_type(off_type(-1));
907 if (_M_terminate_output())
909 off_type __file_off = _M_file.seekoff(__off, __way);
910 if (__file_off != off_type(-1))
914 _M_ext_next = _M_ext_end = _M_ext_buf;
916 _M_state_cur = __state;
918 __ret.state(_M_state_cur);
927 template<
typename _CharT,
typename _Traits>
928 int basic_filebuf<_CharT, _Traits>::
929 _M_get_ext_pos(__state_type& __state)
931 if (_M_codecvt->always_noconv())
932 return this->gptr() - this->egptr();
938 const int __gptr_off =
939 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
940 this->gptr() - this->eback());
941 return _M_ext_buf + __gptr_off - _M_ext_end;
945 template<
typename _CharT,
typename _Traits>
947 basic_filebuf<_CharT, _Traits>::
948 _M_terminate_output()
951 bool __testvalid =
true;
952 if (this->pbase() < this->pptr())
954 const int_type __tmp = this->overflow();
955 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
960 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
966 const size_t __blen = 128;
968 codecvt_base::result __r;
974 __r = _M_codecvt->unshift(_M_state_cur, __buf,
975 __buf + __blen, __next);
976 if (__r == codecvt_base::error)
978 else if (__r == codecvt_base::ok ||
979 __r == codecvt_base::partial)
981 __ilen = __next - __buf;
984 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
985 if (__elen != __ilen)
990 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
998 const int_type __tmp = this->overflow();
999 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
1000 __testvalid =
false;
1006 template<
typename _CharT,
typename _Traits>
1014 if (this->pbase() < this->pptr())
1016 const int_type __tmp = this->overflow();
1017 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
1023 template<
typename _CharT,
typename _Traits>
1028 bool __testvalid =
true;
1031 = __try_use_facet<__codecvt_type>(__loc);
1033 if (this->is_open())
1036 if ((_M_reading || _M_writing)
1037 && __check_facet(_M_codecvt).encoding() == -1)
1038 __testvalid =
false;
1043 if (__check_facet(_M_codecvt).always_noconv())
1046 && !__check_facet(_M_codecvt_tmp).always_noconv())
1048 != pos_type(off_type(-1));
1053 _M_ext_next = _M_ext_buf
1054 + _M_codecvt->length(_M_state_last, _M_ext_buf,
1056 this->gptr() - this->eback());
1057 const streamsize __remainder = _M_ext_end - _M_ext_next;
1059 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
1061 _M_ext_next = _M_ext_buf;
1062 _M_ext_end = _M_ext_buf + __remainder;
1064 _M_state_last = _M_state_cur = _M_state_beg;
1067 else if (_M_writing && (__testvalid = _M_terminate_output()))
1073 _M_codecvt = _M_codecvt_tmp;
1080#if _GLIBCXX_EXTERN_TEMPLATE
1086#ifdef _GLIBCXX_USE_WCHAR_T
1094_GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
ISO C++ entities toplevel namespace is std.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
The actual work of input and output (for files).
virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
virtual int_type underflow()
Fetches more data from the controlled sequence.
virtual streamsize showmanyc()
Investigating the data available.
ios_base::openmode _M_mode
Place to stash in || out || in | out settings for current filebuf.
virtual void imbue(const locale &__loc)
Changes translations.
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
__filebuf_type * close()
Closes the currently associated file.
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
virtual int_type pbackfail(int_type __c=_Traits::eof())
Tries to back up the input sequence.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.
virtual int_type overflow(int_type __c=_Traits::eof())
Consumes data from the buffer; writes to the controlled sequence.
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
basic_filebuf()
Does not open any files.
void _M_set_buffer(streamsize __off)
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
virtual __streambuf_type * setbuf(char_type *__s, streamsize __n)
Manipulates the buffer.
Controlling input for files.
Controlling output for files.
Controlling input and output for files.
locale _M_buf_locale
Current locale setting.
Primary class template codecvt.
The base of the I/O class hierarchy.
static const seekdir cur
Request a seek relative to the current position within the sequence.
static const seekdir beg
Request a seek relative to the beginning of the stream.
static const seekdir end
Request a seek relative to the current end of the sequence.
static const openmode in
Open for input. Default for ifstream and fstream.
static const openmode out
Open for output. Default for ofstream and fstream.
static const openmode binary
Perform input and output in binary mode (as opposed to text mode). This is probably not what you thin...
_Ios_Openmode openmode
This is a bitmask type.
static const openmode app
Seek to end before each write.
static const openmode ate
Open and seek to end immediately after opening.
Container class for localization functionality.