35 #define _FSTREAM_TCC 1
37 #pragma GCC system_header
41 namespace std _GLIBCXX_VISIBILITY(default)
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>
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),
91 template<
typename _CharT,
typename _Traits>
94 open(
const char* __s, ios_base::openmode __mode)
99 _M_file.
open(__s, __mode);
102 _M_allocate_internal_buffer();
111 _M_state_last = _M_state_cur = _M_state_beg;
116 == pos_type(off_type(-1)))
125 template<
typename _CharT,
typename _Traits>
130 if (!this->is_open())
133 bool __testfail =
false;
136 struct __close_sentry
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())
160 __throw_exception_again;
163 { __testfail =
true; }
166 if (!_M_file.close())
175 template<
typename _CharT,
typename _Traits>
182 if (__testin && this->is_open())
186 __ret = this->egptr() - this->gptr();
188 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
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
206 int_type __ret = traits_type::eof();
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;
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
365 int_type __ret = traits_type::eof();
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);
433 const int __gptr_off = _M_get_ext_pos(_M_state_last);
435 == pos_type(off_type(-1)))
438 if (this->pbase() < this->pptr())
443 *this->pptr() = traits_type::to_char_type(__c);
449 if (_M_convert_to_external(this->pbase(),
450 this->pptr() - this->pbase()))
453 __ret = traits_type::not_eof(__c);
456 else if (_M_buf_size > 1)
465 *this->pptr() = traits_type::to_char_type(__c);
468 __ret = traits_type::not_eof(__c);
473 char_type __conv = traits_type::to_char_type(__c);
474 if (__testeof || _M_convert_to_external(&__conv, 1))
477 __ret = traits_type::not_eof(__c);
484 template<
typename _CharT,
typename _Traits>
486 basic_filebuf<_CharT, _Traits>::
487 _M_convert_to_external(_CharT* __ibuf,
streamsize __ilen)
492 if (__check_facet(_M_codecvt).always_noconv())
494 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
501 streamsize __blen = __ilen * _M_codecvt->max_length();
502 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
505 const char_type* __iend;
506 codecvt_base::result __r;
507 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
508 __iend, __buf, __buf + __blen, __bend);
510 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
511 __blen = __bend - __buf;
512 else if (__r == codecvt_base::noconv)
515 __buf =
reinterpret_cast<char*
>(__ibuf);
519 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
520 "conversion error"));
522 __elen = _M_file.xsputn(__buf, __blen);
526 if (__r == codecvt_base::partial && __elen == __plen)
528 const char_type* __iresume = __iend;
530 __r = _M_codecvt->out(_M_state_cur, __iresume,
531 __iresume + __rlen, __iend, __buf,
532 __buf + __blen, __bend);
533 if (__r != codecvt_base::error)
535 __rlen = __bend - __buf;
536 __elen = _M_file.xsputn(__buf, __rlen);
540 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
541 "conversion error"));
544 return __elen == __plen;
547 template<
typename _CharT,
typename _Traits>
556 if (__n > 0 && this->gptr() == this->eback())
558 *__s++ = *this->gptr();
567 if (overflow() == traits_type::eof())
577 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
579 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
583 const streamsize __avail = this->egptr() - this->gptr();
586 traits_type::copy(__s, this->gptr(), __avail);
588 this->setg(this->eback(), this->gptr() + __avail,
599 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
602 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
603 "error reading the file"));
630 __ret += __streambuf_type::xsgetn(__s, __n);
635 template<
typename _CharT,
typename _Traits>
646 if (__check_facet(_M_codecvt).always_noconv()
647 && __testout && !_M_reading)
651 streamsize __bufavail = this->epptr() - this->pptr();
654 if (!_M_writing && _M_buf_size > 1)
655 __bufavail = _M_buf_size - 1;
660 const streamsize __buffill = this->pptr() - this->pbase();
661 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
662 __ret = _M_file.xsputn_2(__buf, __buffill,
663 reinterpret_cast<const char*>(__s),
665 if (__ret == __buffill + __n)
670 if (__ret > __buffill)
676 __ret = __streambuf_type::xsputn(__s, __n);
679 __ret = __streambuf_type::xsputn(__s, __n);
683 template<
typename _CharT,
typename _Traits>
688 if (!this->is_open())
690 if (__s == 0 && __n == 0)
692 else if (__s && __n > 0)
712 template<
typename _CharT,
typename _Traits>
713 typename basic_filebuf<_CharT, _Traits>::pos_type
715 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
719 __width = _M_codecvt->encoding();
723 pos_type __ret = pos_type(off_type(-1));
724 const bool __testfail = __off != 0 && __width <= 0;
725 if (this->is_open() && !__testfail)
732 && (!_M_writing || _M_codecvt->always_noconv());
743 __state_type __state = _M_state_beg;
744 off_type __computed_off = __off * __width;
747 __state = _M_state_last;
748 __computed_off += _M_get_ext_pos(__state);
751 __ret = _M_seek(__computed_off, __way, __state);
755 __computed_off = this->pptr() - this->pbase();
758 if (__file_off != off_type(-1))
760 __ret = __file_off + __computed_off;
761 __ret.state(__state);
772 template<
typename _CharT,
typename _Traits>
773 typename basic_filebuf<_CharT, _Traits>::pos_type
777 pos_type __ret = pos_type(off_type(-1));
782 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
787 template<
typename _CharT,
typename _Traits>
788 typename basic_filebuf<_CharT, _Traits>::pos_type
790 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
792 pos_type __ret = pos_type(off_type(-1));
793 if (_M_terminate_output())
795 off_type __file_off = _M_file.seekoff(__off, __way);
796 if (__file_off != off_type(-1))
800 _M_ext_next = _M_ext_end = _M_ext_buf;
802 _M_state_cur = __state;
804 __ret.state(_M_state_cur);
813 template<
typename _CharT,
typename _Traits>
814 int basic_filebuf<_CharT, _Traits>::
815 _M_get_ext_pos(__state_type& __state)
817 if (_M_codecvt->always_noconv())
818 return this->gptr() - this->egptr();
824 const int __gptr_off =
825 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
826 this->gptr() - this->eback());
827 return _M_ext_buf + __gptr_off - _M_ext_end;
831 template<
typename _CharT,
typename _Traits>
833 basic_filebuf<_CharT, _Traits>::
834 _M_terminate_output()
837 bool __testvalid =
true;
838 if (this->pbase() < this->pptr())
840 const int_type __tmp = this->overflow();
841 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
846 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
852 const size_t __blen = 128;
854 codecvt_base::result __r;
860 __r = _M_codecvt->unshift(_M_state_cur, __buf,
861 __buf + __blen, __next);
862 if (__r == codecvt_base::error)
864 else if (__r == codecvt_base::ok ||
865 __r == codecvt_base::partial)
867 __ilen = __next - __buf;
870 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
871 if (__elen != __ilen)
876 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
884 const int_type __tmp = this->overflow();
885 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
892 template<
typename _CharT,
typename _Traits>
900 if (this->pbase() < this->pptr())
902 const int_type __tmp = this->overflow();
903 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
909 template<
typename _CharT,
typename _Traits>
914 bool __testvalid =
true;
917 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
918 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
923 if ((_M_reading || _M_writing)
924 && __check_facet(_M_codecvt).encoding() == -1)
930 if (__check_facet(_M_codecvt).always_noconv())
933 && !__check_facet(_M_codecvt_tmp).always_noconv())
935 != pos_type(off_type(-1));
940 _M_ext_next = _M_ext_buf
941 + _M_codecvt->length(_M_state_last, _M_ext_buf,
943 this->gptr() - this->eback());
944 const streamsize __remainder = _M_ext_end - _M_ext_next;
946 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
948 _M_ext_next = _M_ext_buf;
949 _M_ext_end = _M_ext_buf + __remainder;
951 _M_state_last = _M_state_cur = _M_state_beg;
954 else if (_M_writing && (__testvalid = _M_terminate_output()))
960 _M_codecvt = _M_codecvt_tmp;
967 #if _GLIBCXX_EXTERN_TEMPLATE
973 #ifdef _GLIBCXX_USE_WCHAR_T
981 _GLIBCXX_END_NAMESPACE_VERSION
static const openmode app
Seek to end before each write.
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.
__filebuf_type * close()
Closes the currently associated file.
virtual void imbue(const locale &__loc)
Changes translations.
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
locale _M_buf_locale
Current locale setting.
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
static const openmode in
Open for input. Default for ifstream and fstream.
virtual streamsize showmanyc()
Investigating the data available.
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 seekdir cur
Request a seek relative to the current position within the sequence.
Controlling input for files.
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
Controlling output for files.
Container class for localization functionality.The locale class is first a class wrapper for C librar...
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
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.
static const seekdir beg
Request a seek relative to the beginning of the stream.
Controlling input and output for files.
The actual work of input and output (interface).
static const openmode ate
Open and seek to end immediately after opening.
_Ios_Openmode openmode
This is a bitmask type.
Primary class template codecvt.NB: Generic, mostly useless implementation.
static const openmode out
Open for output. Default for ofstream and fstream.
static const seekdir end
Request a seek relative to the current end of the sequence.
basic_filebuf()
Does not open any files.
virtual int_type underflow()
Fetches more data from the controlled sequence.
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
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.