35 #define _FSTREAM_TCC 1
37 #pragma GCC system_header
42 namespace std _GLIBCXX_VISIBILITY(default)
44 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 template<
typename _CharT,
typename _Traits>
48 basic_filebuf<_CharT, _Traits>::
49 _M_allocate_internal_buffer()
53 if (!_M_buf_allocated && !_M_buf)
55 _M_buf =
new char_type[_M_buf_size];
56 _M_buf_allocated =
true;
60 template<
typename _CharT,
typename _Traits>
62 basic_filebuf<_CharT, _Traits>::
63 _M_destroy_internal_buffer() throw()
69 _M_buf_allocated =
false;
78 template<
typename _CharT,
typename _Traits>
81 _M_mode(
ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
82 _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ),
83 _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
84 _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
85 _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
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);
157 std::swap(_M_mode, __rhs._M_mode);
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);
161 std::swap(_M_buf, __rhs._M_buf);
162 std::swap(_M_buf_size, __rhs._M_buf_size);
163 std::swap(_M_buf_allocated, __rhs._M_buf_allocated);
164 std::swap(_M_ext_buf, __rhs._M_ext_buf);
165 std::swap(_M_ext_buf_size, __rhs._M_ext_buf_size);
166 std::swap(_M_ext_next, __rhs._M_ext_next);
167 std::swap(_M_ext_end, __rhs._M_ext_end);
168 std::swap(_M_reading, __rhs._M_reading);
169 std::swap(_M_writing, __rhs._M_writing);
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 template<
typename _CharT,
typename _Traits>
215 if (!this->is_open())
218 bool __testfail =
false;
221 struct __close_sentry
228 __fb->_M_pback_init =
false;
229 __fb->_M_destroy_internal_buffer();
230 __fb->_M_reading =
false;
231 __fb->_M_writing =
false;
232 __fb->_M_set_buffer(-1);
233 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
239 if (!_M_terminate_output())
245 __throw_exception_again;
248 { __testfail =
true; }
251 if (!_M_file.close())
260 template<
typename _CharT,
typename _Traits>
267 if (__testin && this->is_open())
271 __ret = this->egptr() - this->gptr();
273 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
276 if (__check_facet(_M_codecvt).encoding() >= 0
279 if (__check_facet(_M_codecvt).encoding() >= 0)
281 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
286 template<
typename _CharT,
typename _Traits>
287 typename basic_filebuf<_CharT, _Traits>::int_type
291 int_type __ret = traits_type::eof();
297 if (overflow() == traits_type::eof())
307 if (this->gptr() < this->egptr())
308 return traits_type::to_int_type(*this->gptr());
311 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
314 bool __got_eof =
false;
317 codecvt_base::result __r = codecvt_base::ok;
318 if (__check_facet(_M_codecvt).always_noconv())
320 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
329 const int __enc = _M_codecvt->encoding();
333 __blen = __rlen = __buflen * __enc;
336 __blen = __buflen + _M_codecvt->max_length() - 1;
339 const streamsize __remainder = _M_ext_end - _M_ext_next;
340 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
344 if (_M_reading && this->egptr() == this->eback() && __remainder)
349 if (_M_ext_buf_size < __blen)
351 char* __buf =
new char[__blen];
353 __builtin_memcpy(__buf, _M_ext_next, __remainder);
355 delete [] _M_ext_buf;
357 _M_ext_buf_size = __blen;
359 else if (__remainder)
360 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
362 _M_ext_next = _M_ext_buf;
363 _M_ext_end = _M_ext_buf + __remainder;
364 _M_state_last = _M_state_cur;
373 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
375 __throw_ios_failure(__N(
"basic_filebuf::underflow "
376 "codecvt::max_length() "
379 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
382 else if (__elen == -1)
384 _M_ext_end += __elen;
387 char_type* __iend = this->eback();
388 if (_M_ext_next < _M_ext_end)
389 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
390 _M_ext_end, _M_ext_next,
392 this->eback() + __buflen, __iend);
393 if (__r == codecvt_base::noconv)
395 size_t __avail = _M_ext_end - _M_ext_buf;
396 __ilen =
std::min(__avail, __buflen);
397 traits_type::copy(this->eback(),
398 reinterpret_cast<char_type*>
399 (_M_ext_buf), __ilen);
400 _M_ext_next = _M_ext_buf + __ilen;
403 __ilen = __iend - this->eback();
408 if (__r == codecvt_base::error)
413 while (__ilen == 0 && !__got_eof);
418 _M_set_buffer(__ilen);
420 __ret = traits_type::to_int_type(*this->gptr());
431 if (__r == codecvt_base::partial)
432 __throw_ios_failure(__N(
"basic_filebuf::underflow "
433 "incomplete character in file"));
435 else if (__r == codecvt_base::error)
436 __throw_ios_failure(__N(
"basic_filebuf::underflow "
437 "invalid byte sequence in file"));
439 __throw_ios_failure(__N(
"basic_filebuf::underflow "
440 "error reading the file"));
445 template<
typename _CharT,
typename _Traits>
446 typename basic_filebuf<_CharT, _Traits>::int_type
450 int_type __ret = traits_type::eof();
456 if (overflow() == traits_type::eof())
463 const bool __testpb = _M_pback_init;
464 const bool __testeof = traits_type::eq_int_type(__i, __ret);
466 if (this->eback() < this->gptr())
469 __tmp = traits_type::to_int_type(*this->gptr());
471 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
473 __tmp = this->underflow();
474 if (traits_type::eq_int_type(__tmp, __ret))
489 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
492 __ret = traits_type::not_eof(__i);
497 *this->gptr() = traits_type::to_char_type(__i);
504 template<
typename _CharT,
typename _Traits>
505 typename basic_filebuf<_CharT, _Traits>::int_type
506 basic_filebuf<_CharT, _Traits>::
507 overflow(int_type __c)
509 int_type __ret = traits_type::eof();
510 const bool __testeof = traits_type::eq_int_type(__c, __ret);
518 const int __gptr_off = _M_get_ext_pos(_M_state_last);
520 == pos_type(off_type(-1)))
523 if (this->pbase() < this->pptr())
528 *this->pptr() = traits_type::to_char_type(__c);
534 if (_M_convert_to_external(this->pbase(),
535 this->pptr() - this->pbase()))
538 __ret = traits_type::not_eof(__c);
541 else if (_M_buf_size > 1)
550 *this->pptr() = traits_type::to_char_type(__c);
553 __ret = traits_type::not_eof(__c);
558 char_type __conv = traits_type::to_char_type(__c);
559 if (__testeof || _M_convert_to_external(&__conv, 1))
562 __ret = traits_type::not_eof(__c);
569 template<
typename _CharT,
typename _Traits>
571 basic_filebuf<_CharT, _Traits>::
572 _M_convert_to_external(_CharT* __ibuf,
streamsize __ilen)
577 if (__check_facet(_M_codecvt).always_noconv())
579 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
586 streamsize __blen = __ilen * _M_codecvt->max_length();
587 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
590 const char_type* __iend;
591 codecvt_base::result __r;
592 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
593 __iend, __buf, __buf + __blen, __bend);
595 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
596 __blen = __bend - __buf;
597 else if (__r == codecvt_base::noconv)
600 __buf =
reinterpret_cast<char*
>(__ibuf);
604 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
605 "conversion error"));
607 __elen = _M_file.xsputn(__buf, __blen);
611 if (__r == codecvt_base::partial && __elen == __plen)
613 const char_type* __iresume = __iend;
615 __r = _M_codecvt->out(_M_state_cur, __iresume,
616 __iresume + __rlen, __iend, __buf,
617 __buf + __blen, __bend);
618 if (__r != codecvt_base::error)
620 __rlen = __bend - __buf;
621 __elen = _M_file.xsputn(__buf, __rlen);
625 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
626 "conversion error"));
629 return __elen == __plen;
632 template<
typename _CharT,
typename _Traits>
641 if (__n > 0 && this->gptr() == this->eback())
643 *__s++ = *this->gptr();
652 if (overflow() == traits_type::eof())
662 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
664 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
668 const streamsize __avail = this->egptr() - this->gptr();
671 traits_type::copy(__s, this->gptr(), __avail);
673 this->setg(this->eback(), this->gptr() + __avail, this->egptr());
683 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
685 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
686 "error reading the file"));
713 __ret += __streambuf_type::xsgetn(__s, __n);
718 template<
typename _CharT,
typename _Traits>
729 if (__check_facet(_M_codecvt).always_noconv()
730 && __testout && !_M_reading)
734 streamsize __bufavail = this->epptr() - this->pptr();
737 if (!_M_writing && _M_buf_size > 1)
738 __bufavail = _M_buf_size - 1;
743 const streamsize __buffill = this->pptr() - this->pbase();
744 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
745 __ret = _M_file.xsputn_2(__buf, __buffill,
746 reinterpret_cast<const char*>(__s),
748 if (__ret == __buffill + __n)
753 if (__ret > __buffill)
759 __ret = __streambuf_type::xsputn(__s, __n);
762 __ret = __streambuf_type::xsputn(__s, __n);
766 template<
typename _CharT,
typename _Traits>
771 if (!this->is_open())
773 if (__s == 0 && __n == 0)
775 else if (__s && __n > 0)
795 template<
typename _CharT,
typename _Traits>
796 typename basic_filebuf<_CharT, _Traits>::pos_type
798 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
802 __width = _M_codecvt->encoding();
806 pos_type __ret = pos_type(off_type(-1));
807 const bool __testfail = __off != 0 && __width <= 0;
808 if (this->is_open() && !__testfail)
815 && (!_M_writing || _M_codecvt->always_noconv());
826 __state_type __state = _M_state_beg;
827 off_type __computed_off = __off * __width;
830 __state = _M_state_last;
831 __computed_off += _M_get_ext_pos(__state);
834 __ret = _M_seek(__computed_off, __way, __state);
838 __computed_off = this->pptr() - this->pbase();
841 if (__file_off != off_type(-1))
843 __ret = __file_off + __computed_off;
844 __ret.state(__state);
855 template<
typename _CharT,
typename _Traits>
856 typename basic_filebuf<_CharT, _Traits>::pos_type
860 pos_type __ret = pos_type(off_type(-1));
865 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
870 template<
typename _CharT,
typename _Traits>
871 typename basic_filebuf<_CharT, _Traits>::pos_type
873 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
875 pos_type __ret = pos_type(off_type(-1));
876 if (_M_terminate_output())
878 off_type __file_off = _M_file.seekoff(__off, __way);
879 if (__file_off != off_type(-1))
883 _M_ext_next = _M_ext_end = _M_ext_buf;
885 _M_state_cur = __state;
887 __ret.state(_M_state_cur);
896 template<
typename _CharT,
typename _Traits>
897 int basic_filebuf<_CharT, _Traits>::
898 _M_get_ext_pos(__state_type& __state)
900 if (_M_codecvt->always_noconv())
901 return this->gptr() - this->egptr();
907 const int __gptr_off =
908 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
909 this->gptr() - this->eback());
910 return _M_ext_buf + __gptr_off - _M_ext_end;
914 template<
typename _CharT,
typename _Traits>
916 basic_filebuf<_CharT, _Traits>::
917 _M_terminate_output()
920 bool __testvalid =
true;
921 if (this->pbase() < this->pptr())
923 const int_type __tmp = this->overflow();
924 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
929 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
935 const size_t __blen = 128;
937 codecvt_base::result __r;
943 __r = _M_codecvt->unshift(_M_state_cur, __buf,
944 __buf + __blen, __next);
945 if (__r == codecvt_base::error)
947 else if (__r == codecvt_base::ok ||
948 __r == codecvt_base::partial)
950 __ilen = __next - __buf;
953 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
954 if (__elen != __ilen)
959 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
967 const int_type __tmp = this->overflow();
968 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
975 template<
typename _CharT,
typename _Traits>
983 if (this->pbase() < this->pptr())
985 const int_type __tmp = this->overflow();
986 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
992 template<
typename _CharT,
typename _Traits>
997 bool __testvalid =
true;
999 const __codecvt_type* _M_codecvt_tmp = 0;
1000 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
1001 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
1003 if (this->is_open())
1006 if ((_M_reading || _M_writing)
1007 && __check_facet(_M_codecvt).encoding() == -1)
1008 __testvalid =
false;
1013 if (__check_facet(_M_codecvt).always_noconv())
1016 && !__check_facet(_M_codecvt_tmp).always_noconv())
1018 != pos_type(off_type(-1));
1023 _M_ext_next = _M_ext_buf
1024 + _M_codecvt->length(_M_state_last, _M_ext_buf,
1026 this->gptr() - this->eback());
1027 const streamsize __remainder = _M_ext_end - _M_ext_next;
1029 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
1031 _M_ext_next = _M_ext_buf;
1032 _M_ext_end = _M_ext_buf + __remainder;
1034 _M_state_last = _M_state_cur = _M_state_beg;
1037 else if (_M_writing && (__testvalid = _M_terminate_output()))
1043 _M_codecvt = _M_codecvt_tmp;
1050 #if _GLIBCXX_EXTERN_TEMPLATE
1051 extern template class basic_filebuf<char>;
1052 extern template class basic_ifstream<char>;
1053 extern template class basic_ofstream<char>;
1054 extern template class basic_fstream<char>;
1056 #ifdef _GLIBCXX_USE_WCHAR_T
1057 extern template class basic_filebuf<wchar_t>;
1058 extern template class basic_ifstream<wchar_t>;
1059 extern template class basic_ofstream<wchar_t>;
1060 extern template class basic_fstream<wchar_t>;
1064 _GLIBCXX_END_NAMESPACE_VERSION
static const seekdir cur
Request a seek relative to the current position within the sequence.
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
__filebuf_type * close()
Closes the currently associated file.
The actual work of input and output (interface).
virtual int_type underflow()
Fetches more data from the controlled sequence.
static const openmode ate
Open and seek to end immediately after opening.
_Ios_Openmode openmode
This is a bitmask type.
Container class for localization functionality.The locale class is first a class wrapper for C librar...
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
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.
basic_filebuf()
Does not open any files.
static const seekdir end
Request a seek relative to the current end of the sequence.
virtual streamsize showmanyc()
Investigating the data available.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
The actual work of input and output (for files).
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
static const openmode binary
Perform input and output in binary mode (as opposed to text mode). This is probably not what you thin...
static const openmode app
Seek to end before each write.
static const openmode out
Open for output. Default for ofstream and fstream.
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
locale _M_buf_locale
Current locale setting.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.
static const openmode in
Open for input. Default for ifstream and fstream.
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
static const seekdir beg
Request a seek relative to the beginning of the stream.
_GLIBCXX14_CONSTEXPR const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
virtual __streambuf_type * setbuf(char_type *__s, streamsize __n)
Manipulates the buffer.