35 #define _FSTREAM_TCC 1 37 #pragma GCC system_header 43 namespace 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);
129 _M_mode = std::__exchange(__rhs._M_mode, ios_base::openmode(0));
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*
178 basic_filebuf<_CharT, _Traits>::
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;
199 if ((__mode & ios_base::ate)
200 && this->seekoff(0, ios_base::end, __mode)
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;
234 if ((__mode & ios_base::ate)
235 && this->seekoff(0, ios_base::end, __mode)
236 == pos_type(off_type(-1)))
244 #endif // HAVE__WFOPEN && USE_WCHAR_T 246 template<
typename _CharT,
typename _Traits>
247 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
248 basic_filebuf<_CharT, _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>
300 const bool __testin = _M_mode & ios_base::in;
301 if (__testin && this->is_open())
305 __ret = this->egptr() - this->gptr();
307 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 309 const bool __testbinary = _M_mode & ios_base::binary;
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();
326 const bool __testin = _M_mode & ios_base::in;
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;
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();
485 const bool __testin = _M_mode & ios_base::in;
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());
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);
545 const bool __testout = (_M_mode & ios_base::out
546 || _M_mode & ios_base::app);
552 const int __gptr_off = _M_get_ext_pos(_M_state_last);
553 if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
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>
668 basic_filebuf<_CharT, _Traits>::
675 if (__n > 0 && this->gptr() == this->eback())
677 *__s++ = *this->gptr();
686 if (overflow() == traits_type::eof())
695 const bool __testin = _M_mode & ios_base::in;
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>
761 const bool __testout = (_M_mode & ios_base::out
762 || _M_mode & ios_base::app);
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
833 __width = _M_codecvt->encoding();
838 const bool __testfail = __off != 0 && __width <= 0;
839 if (this->is_open() && !__testfail)
845 bool __no_movement = __way == ios_base::cur && __off == 0
846 && (!_M_writing || _M_codecvt->always_noconv());
857 __state_type __state = _M_state_beg;
858 off_type __computed_off = __off * __width;
859 if (_M_reading && __way == ios_base::cur)
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();
871 off_type __file_off = _M_file.seekoff(0, ios_base::cur);
874 __ret = __file_off + __computed_off;
875 __ret.state(__state);
886 template<
typename _CharT,
typename _Traits>
887 typename basic_filebuf<_CharT, _Traits>::pos_type
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>
1008 basic_filebuf<_CharT, _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())
1047 __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
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
Controlling input and output for files.
The actual work of input and output (for files).
basic_filebuf()
Does not open any files.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.
Controlling output for files.
void _M_set_buffer(streamsize __off)
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Primary class template codecvt.NB: Generic, mostly useless implementation.
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
Container class for localization functionality.The locale class is first a class wrapper for C librar...
ISO C++ entities toplevel namespace is std.
traits_type::pos_type pos_type
ios_base::openmode _M_mode
Place to stash in || out || in | out settings for current filebuf.
traits_type::int_type int_type
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
traits_type::off_type off_type
The actual work of input and output (interface).
Controlling input for files.