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),
93#if __cplusplus >= 201103L
94 template<
typename _CharT,
typename _Traits>
97 : __streambuf_type(__rhs),
98 _M_lock(), _M_file(
std::
move(__rhs._M_file), &_M_lock),
99 _M_mode(
std::__exchange(__rhs._M_mode,
ios_base::openmode(0))),
100 _M_state_beg(
std::
move(__rhs._M_state_beg)),
101 _M_state_cur(
std::
move(__rhs._M_state_cur)),
102 _M_state_last(
std::
move(__rhs._M_state_last)),
103 _M_buf(
std::__exchange(__rhs._M_buf, nullptr)),
104 _M_buf_size(
std::__exchange(__rhs._M_buf_size, 1)),
105 _M_buf_allocated(
std::__exchange(__rhs._M_buf_allocated, false)),
106 _M_reading(
std::__exchange(__rhs._M_reading, false)),
107 _M_writing(
std::__exchange(__rhs._M_writing, false)),
108 _M_pback(__rhs._M_pback),
109 _M_pback_cur_save(
std::__exchange(__rhs._M_pback_cur_save, nullptr)),
110 _M_pback_end_save(
std::__exchange(__rhs._M_pback_end_save, nullptr)),
111 _M_pback_init(
std::__exchange(__rhs._M_pback_init, false)),
112 _M_codecvt(__rhs._M_codecvt),
113 _M_ext_buf(
std::__exchange(__rhs._M_ext_buf, nullptr)),
114 _M_ext_buf_size(
std::__exchange(__rhs._M_ext_buf_size, 0)),
115 _M_ext_next(
std::__exchange(__rhs._M_ext_next, nullptr)),
116 _M_ext_end(
std::__exchange(__rhs._M_ext_end, nullptr))
118 __rhs._M_set_buffer(-1);
119 __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg;
122 template<
typename _CharT,
typename _Traits>
123 basic_filebuf<_CharT, _Traits>&
124 basic_filebuf<_CharT, _Traits>::
125 operator=(basic_filebuf&& __rhs)
128 __streambuf_type::operator=(__rhs);
129 _M_file.swap(__rhs._M_file);
131 _M_state_beg =
std::move(__rhs._M_state_beg);
132 _M_state_cur =
std::move(__rhs._M_state_cur);
133 _M_state_last =
std::move(__rhs._M_state_last);
134 _M_buf = std::__exchange(__rhs._M_buf,
nullptr);
135 _M_buf_size = std::__exchange(__rhs._M_buf_size, 1);
136 _M_buf_allocated = std::__exchange(__rhs._M_buf_allocated,
false);
137 _M_ext_buf = std::__exchange(__rhs._M_ext_buf,
nullptr);
138 _M_ext_buf_size = std::__exchange(__rhs._M_ext_buf_size, 0);
139 _M_ext_next = std::__exchange(__rhs._M_ext_next,
nullptr);
140 _M_ext_end = std::__exchange(__rhs._M_ext_end,
nullptr);
141 _M_reading = std::__exchange(__rhs._M_reading,
false);
142 _M_writing = std::__exchange(__rhs._M_writing,
false);
143 _M_pback_cur_save = std::__exchange(__rhs._M_pback_cur_save,
nullptr);
144 _M_pback_end_save = std::__exchange(__rhs._M_pback_end_save,
nullptr);
145 _M_pback_init = std::__exchange(__rhs._M_pback_init,
false);
146 __rhs._M_set_buffer(-1);
147 __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg;
151 template<
typename _CharT,
typename _Traits>
153 basic_filebuf<_CharT, _Traits>::
154 swap(basic_filebuf& __rhs)
156 __streambuf_type::swap(__rhs);
157 _M_file.swap(__rhs._M_file);
159 std::swap(_M_state_beg, __rhs._M_state_beg);
160 std::swap(_M_state_cur, __rhs._M_state_cur);
161 std::swap(_M_state_last, __rhs._M_state_last);
163 std::swap(_M_buf_size, __rhs._M_buf_size);
164 std::swap(_M_buf_allocated, __rhs._M_buf_allocated);
166 std::swap(_M_ext_buf_size, __rhs._M_ext_buf_size);
167 std::swap(_M_ext_next, __rhs._M_ext_next);
171 std::swap(_M_pback_cur_save, __rhs._M_pback_cur_save);
172 std::swap(_M_pback_end_save, __rhs._M_pback_end_save);
173 std::swap(_M_pback_init, __rhs._M_pback_init);
177 template<
typename _CharT,
typename _Traits>
178 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
180 open(
const char* __s, ios_base::openmode __mode)
183 if (!this->is_open())
185 _M_file.
open(__s, __mode);
188 _M_allocate_internal_buffer();
197 _M_state_last = _M_state_cur = _M_state_beg;
202 == pos_type(off_type(-1)))
211#if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
212 template<
typename _CharT,
typename _Traits>
215 open(
const wchar_t* __s, ios_base::openmode __mode)
217 __filebuf_type *__ret = 0;
218 if (!this->is_open())
220 _M_file.
open(__s, __mode);
223 _M_allocate_internal_buffer();
232 _M_state_last = _M_state_cur = _M_state_beg;
237 == pos_type(off_type(-1)))
247 template<
typename _CharT,
typename _Traits>
248 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
252 if (!this->is_open())
255 bool __testfail =
false;
258 struct __close_sentry
264 __fb->
_M_mode = ios_base::openmode(0);
266 __fb->_M_destroy_internal_buffer();
268 __fb->_M_writing =
false;
270 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
276 if (!_M_terminate_output())
282 __throw_exception_again;
286 if (!_M_file.close())
295 template<
typename _CharT,
typename _Traits>
302 if (__testin && this->is_open())
306 __ret = this->egptr() - this->gptr();
308#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
311 if (__check_facet(_M_codecvt).encoding() >= 0
314 if (__check_facet(_M_codecvt).encoding() >= 0)
316 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
321 template<
typename _CharT,
typename _Traits>
322 typename basic_filebuf<_CharT, _Traits>::int_type
326 int_type __ret = traits_type::eof();
332 if (overflow() == traits_type::eof())
342 if (this->gptr() < this->egptr())
343 return traits_type::to_int_type(*this->gptr());
346 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
349 bool __got_eof =
false;
352 codecvt_base::result __r = codecvt_base::ok;
353 if (__check_facet(_M_codecvt).always_noconv())
355 __ilen = _M_file.xsgetn(
reinterpret_cast<char*
>(this->eback()),
364 const int __enc = _M_codecvt->encoding();
368 __blen = __rlen = __buflen * __enc;
371 __blen = __buflen + _M_codecvt->max_length() - 1;
374 const streamsize __remainder = _M_ext_end - _M_ext_next;
375 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
379 if (_M_reading && this->egptr() == this->eback() && __remainder)
384 if (_M_ext_buf_size < __blen)
386 char* __buf =
new char[__blen];
388 __builtin_memcpy(__buf, _M_ext_next, __remainder);
390 delete [] _M_ext_buf;
392 _M_ext_buf_size = __blen;
394 else if (__remainder)
395 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
397 _M_ext_next = _M_ext_buf;
398 _M_ext_end = _M_ext_buf + __remainder;
399 _M_state_last = _M_state_cur;
408 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
410 __throw_ios_failure(__N(
"basic_filebuf::underflow "
411 "codecvt::max_length() "
414 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
417 else if (__elen == -1)
419 _M_ext_end += __elen;
422 char_type* __iend = this->eback();
423 if (_M_ext_next < _M_ext_end)
424 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
425 _M_ext_end, _M_ext_next,
427 this->eback() + __buflen, __iend);
428 if (__r == codecvt_base::noconv)
430 size_t __avail = _M_ext_end - _M_ext_buf;
431 __ilen =
std::min(__avail, __buflen);
432 traits_type::copy(this->eback(),
433 reinterpret_cast<char_type*
>
434 (_M_ext_buf), __ilen);
435 _M_ext_next = _M_ext_buf + __ilen;
438 __ilen = __iend - this->eback();
443 if (__r == codecvt_base::error)
448 while (__ilen == 0 && !__got_eof);
453 _M_set_buffer(__ilen);
455 __ret = traits_type::to_int_type(*this->gptr());
466 if (__r == codecvt_base::partial)
467 __throw_ios_failure(__N(
"basic_filebuf::underflow "
468 "incomplete character in file"));
470 else if (__r == codecvt_base::error)
471 __throw_ios_failure(__N(
"basic_filebuf::underflow "
472 "invalid byte sequence in file"));
474 __throw_ios_failure(__N(
"basic_filebuf::underflow "
475 "error reading the file"), errno);
480 template<
typename _CharT,
typename _Traits>
481 typename basic_filebuf<_CharT, _Traits>::int_type
485 int_type __ret = traits_type::eof();
491 if (overflow() == traits_type::eof())
498 const bool __testpb = _M_pback_init;
499 const bool __testeof = traits_type::eq_int_type(__i, __ret);
501 if (this->eback() < this->gptr())
504 __tmp = traits_type::to_int_type(*this->gptr());
506 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
508 __tmp = this->underflow();
509 if (traits_type::eq_int_type(__tmp, __ret))
524 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
527 __ret = traits_type::not_eof(__i);
532 *this->gptr() = traits_type::to_char_type(__i);
539 template<
typename _CharT,
typename _Traits>
540 typename basic_filebuf<_CharT, _Traits>::int_type
544 int_type __ret = traits_type::eof();
545 const bool __testeof = traits_type::eq_int_type(__c, __ret);
553 const int __gptr_off = _M_get_ext_pos(_M_state_last);
555 == pos_type(off_type(-1)))
558 if (this->pbase() < this->pptr())
563 *this->pptr() = traits_type::to_char_type(__c);
569 if (_M_convert_to_external(this->pbase(),
570 this->pptr() - this->pbase()))
573 __ret = traits_type::not_eof(__c);
576 else if (_M_buf_size > 1)
585 *this->pptr() = traits_type::to_char_type(__c);
588 __ret = traits_type::not_eof(__c);
593 char_type __conv = traits_type::to_char_type(__c);
594 if (__testeof || _M_convert_to_external(&__conv, 1))
597 __ret = traits_type::not_eof(__c);
604 template<
typename _CharT,
typename _Traits>
612 if (__check_facet(_M_codecvt).always_noconv())
614 __elen = _M_file.
xsputn(
reinterpret_cast<char*
>(__ibuf), __ilen);
621 streamsize __blen = __ilen * _M_codecvt->max_length();
622 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
625 const char_type* __iend;
626 codecvt_base::result __r;
627 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
628 __iend, __buf, __buf + __blen, __bend);
630 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
631 __blen = __bend - __buf;
632 else if (__r == codecvt_base::noconv)
635 __buf =
reinterpret_cast<char*
>(__ibuf);
639 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
640 "conversion error"));
642 __elen = _M_file.xsputn(__buf, __blen);
646 if (__r == codecvt_base::partial && __elen == __plen)
648 const char_type* __iresume = __iend;
650 __r = _M_codecvt->out(_M_state_cur, __iresume,
651 __iresume + __rlen, __iend, __buf,
652 __buf + __blen, __bend);
653 if (__r != codecvt_base::error)
655 __rlen = __bend - __buf;
656 __elen = _M_file.xsputn(__buf, __rlen);
660 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
661 "conversion error"));
664 return __elen == __plen;
667 template<
typename _CharT,
typename _Traits>
676 if (__n > 0 && this->gptr() == this->eback())
678 *__s++ = *this->gptr();
687 if (overflow() == traits_type::eof())
697 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
699 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
703 const streamsize __avail = this->egptr() - this->gptr();
706 traits_type::copy(__s, this->gptr(), __avail);
708 this->setg(this->eback(), this->gptr() + __avail, this->egptr());
718 __len = _M_file.xsgetn(
reinterpret_cast<char*
>(__s), __n);
720 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
721 "error reading the file"), errno);
748 __ret += __streambuf_type::xsgetn(__s, __n);
753 template<
typename _CharT,
typename _Traits>
764 if (__check_facet(_M_codecvt).always_noconv()
765 && __testout && !_M_reading)
769 streamsize __bufavail = this->epptr() - this->pptr();
772 if (!_M_writing && _M_buf_size > 1)
773 __bufavail = _M_buf_size - 1;
778 const streamsize __buffill = this->pptr() - this->pbase();
779 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
780 __ret = _M_file.xsputn_2(__buf, __buffill,
781 reinterpret_cast<const char*
>(__s),
783 if (__ret == __buffill + __n)
788 if (__ret > __buffill)
794 __ret = __streambuf_type::xsputn(__s, __n);
797 __ret = __streambuf_type::xsputn(__s, __n);
801 template<
typename _CharT,
typename _Traits>
806 if (!this->is_open())
808 if (__s == 0 && __n == 0)
810 else if (__s && __n > 0)
830 template<
typename _CharT,
typename _Traits>
831 typename basic_filebuf<_CharT, _Traits>::pos_type
833 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
837 __width = _M_codecvt->encoding();
841 pos_type __ret = pos_type(off_type(-1));
842 const bool __testfail = __off != 0 && __width <= 0;
843 if (this->is_open() && !__testfail)
850 && (!_M_writing || _M_codecvt->always_noconv());
861 __state_type __state = _M_state_beg;
862 off_type __computed_off = __off * __width;
865 __state = _M_state_last;
866 __computed_off += _M_get_ext_pos(__state);
869 __ret = _M_seek(__computed_off, __way, __state);
873 __computed_off = this->pptr() - this->pbase();
876 if (__file_off != off_type(-1))
878 __ret = __file_off + __computed_off;
879 __ret.state(__state);
890 template<
typename _CharT,
typename _Traits>
891 typename basic_filebuf<_CharT, _Traits>::pos_type
893 seekpos(pos_type __pos, ios_base::openmode)
895 pos_type __ret = pos_type(off_type(-1));
900 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
905 template<
typename _CharT,
typename _Traits>
906 typename basic_filebuf<_CharT, _Traits>::pos_type
908 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
910 pos_type __ret = pos_type(off_type(-1));
911 if (_M_terminate_output())
913 off_type __file_off = _M_file.seekoff(__off, __way);
914 if (__file_off != off_type(-1))
918 _M_ext_next = _M_ext_end = _M_ext_buf;
920 _M_state_cur = __state;
922 __ret.state(_M_state_cur);
931 template<
typename _CharT,
typename _Traits>
932 int basic_filebuf<_CharT, _Traits>::
933 _M_get_ext_pos(__state_type& __state)
935 if (_M_codecvt->always_noconv())
936 return this->gptr() - this->egptr();
942 const int __gptr_off =
943 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
944 this->gptr() - this->eback());
945 return _M_ext_buf + __gptr_off - _M_ext_end;
949 template<
typename _CharT,
typename _Traits>
951 basic_filebuf<_CharT, _Traits>::
952 _M_terminate_output()
955 bool __testvalid =
true;
956 if (this->pbase() < this->pptr())
958 const int_type __tmp = this->overflow();
959 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
964 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
970 const size_t __blen = 128;
972 codecvt_base::result __r;
978 __r = _M_codecvt->unshift(_M_state_cur, __buf,
979 __buf + __blen, __next);
980 if (__r == codecvt_base::error)
982 else if (__r == codecvt_base::ok ||
983 __r == codecvt_base::partial)
985 __ilen = __next - __buf;
988 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
989 if (__elen != __ilen)
994 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
1002 const int_type __tmp = this->overflow();
1003 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
1004 __testvalid =
false;
1010 template<
typename _CharT,
typename _Traits>
1018 if (this->pbase() < this->pptr())
1020 const int_type __tmp = this->overflow();
1021 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
1027 template<
typename _CharT,
typename _Traits>
1032 bool __testvalid =
true;
1035 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
1036 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
1038 if (this->is_open())
1041 if ((_M_reading || _M_writing)
1042 && __check_facet(_M_codecvt).encoding() == -1)
1043 __testvalid =
false;
1048 if (__check_facet(_M_codecvt).always_noconv())
1051 && !__check_facet(_M_codecvt_tmp).always_noconv())
1053 != pos_type(off_type(-1));
1058 _M_ext_next = _M_ext_buf
1059 + _M_codecvt->length(_M_state_last, _M_ext_buf,
1061 this->gptr() - this->eback());
1062 const streamsize __remainder = _M_ext_end - _M_ext_next;
1064 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
1066 _M_ext_next = _M_ext_buf;
1067 _M_ext_end = _M_ext_buf + __remainder;
1069 _M_state_last = _M_state_cur = _M_state_beg;
1072 else if (_M_writing && (__testvalid = _M_terminate_output()))
1078 _M_codecvt = _M_codecvt_tmp;
1085#if _GLIBCXX_EXTERN_TEMPLATE
1091#ifdef _GLIBCXX_USE_WCHAR_T
1099_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.