37 #define _FSTREAM_TCC 1
39 #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(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 template<
typename _CharT,
typename _Traits>
96 open(
const char* __s, ios_base::openmode __mode)
101 _M_file.
open(__s, __mode);
104 _M_allocate_internal_buffer();
113 _M_state_last = _M_state_cur = _M_state_beg;
118 == pos_type(off_type(-1)))
127 template<
typename _CharT,
typename _Traits>
132 if (!this->is_open())
135 bool __testfail =
false;
138 struct __close_sentry
145 __fb->_M_pback_init =
false;
146 __fb->_M_destroy_internal_buffer();
147 __fb->_M_reading =
false;
148 __fb->_M_writing =
false;
149 __fb->_M_set_buffer(-1);
150 __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
156 if (!_M_terminate_output())
162 __throw_exception_again;
165 { __testfail =
true; }
168 if (!_M_file.close())
177 template<
typename _CharT,
typename _Traits>
184 if (__testin && this->is_open())
188 __ret = this->egptr() - this->gptr();
190 #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
193 if (__check_facet(_M_codecvt).encoding() >= 0
196 if (__check_facet(_M_codecvt).encoding() >= 0)
198 __ret += _M_file.showmanyc() / _M_codecvt->max_length();
203 template<
typename _CharT,
typename _Traits>
204 typename basic_filebuf<_CharT, _Traits>::int_type
208 int_type __ret = traits_type::eof();
214 if (overflow() == traits_type::eof())
224 if (this->gptr() < this->egptr())
225 return traits_type::to_int_type(*this->gptr());
228 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
231 bool __got_eof =
false;
234 codecvt_base::result __r = codecvt_base::ok;
235 if (__check_facet(_M_codecvt).always_noconv())
237 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
246 const int __enc = _M_codecvt->encoding();
250 __blen = __rlen = __buflen * __enc;
253 __blen = __buflen + _M_codecvt->max_length() - 1;
256 const streamsize __remainder = _M_ext_end - _M_ext_next;
257 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
261 if (_M_reading && this->egptr() == this->eback() && __remainder)
266 if (_M_ext_buf_size < __blen)
268 char* __buf =
new char[__blen];
270 __builtin_memcpy(__buf, _M_ext_next, __remainder);
272 delete [] _M_ext_buf;
274 _M_ext_buf_size = __blen;
276 else if (__remainder)
277 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
279 _M_ext_next = _M_ext_buf;
280 _M_ext_end = _M_ext_buf + __remainder;
281 _M_state_last = _M_state_cur;
290 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
292 __throw_ios_failure(__N(
"basic_filebuf::underflow "
293 "codecvt::max_length() "
296 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
299 else if (__elen == -1)
301 _M_ext_end += __elen;
304 char_type* __iend = this->eback();
305 if (_M_ext_next < _M_ext_end)
306 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
307 _M_ext_end, _M_ext_next,
309 this->eback() + __buflen, __iend);
310 if (__r == codecvt_base::noconv)
312 size_t __avail = _M_ext_end - _M_ext_buf;
313 __ilen =
std::min(__avail, __buflen);
314 traits_type::copy(this->eback(),
315 reinterpret_cast<char_type*>
316 (_M_ext_buf), __ilen);
317 _M_ext_next = _M_ext_buf + __ilen;
320 __ilen = __iend - this->eback();
325 if (__r == codecvt_base::error)
330 while (__ilen == 0 && !__got_eof);
335 _M_set_buffer(__ilen);
337 __ret = traits_type::to_int_type(*this->gptr());
348 if (__r == codecvt_base::partial)
349 __throw_ios_failure(__N(
"basic_filebuf::underflow "
350 "incomplete character in file"));
352 else if (__r == codecvt_base::error)
353 __throw_ios_failure(__N(
"basic_filebuf::underflow "
354 "invalid byte sequence in file"));
356 __throw_ios_failure(__N(
"basic_filebuf::underflow "
357 "error reading the file"));
362 template<
typename _CharT,
typename _Traits>
363 typename basic_filebuf<_CharT, _Traits>::int_type
367 int_type __ret = traits_type::eof();
373 if (overflow() == traits_type::eof())
380 const bool __testpb = _M_pback_init;
381 const bool __testeof = traits_type::eq_int_type(__i, __ret);
383 if (this->eback() < this->gptr())
386 __tmp = traits_type::to_int_type(*this->gptr());
388 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
390 __tmp = this->underflow();
391 if (traits_type::eq_int_type(__tmp, __ret))
406 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
409 __ret = traits_type::not_eof(__i);
414 *this->gptr() = traits_type::to_char_type(__i);
421 template<
typename _CharT,
typename _Traits>
422 typename basic_filebuf<_CharT, _Traits>::int_type
426 int_type __ret = traits_type::eof();
427 const bool __testeof = traits_type::eq_int_type(__c, __ret);
434 const int __gptr_off = _M_get_ext_pos(_M_state_last);
436 == pos_type(off_type(-1)))
439 if (this->pbase() < this->pptr())
444 *this->pptr() = traits_type::to_char_type(__c);
450 if (_M_convert_to_external(this->pbase(),
451 this->pptr() - this->pbase()))
454 __ret = traits_type::not_eof(__c);
457 else if (_M_buf_size > 1)
466 *this->pptr() = traits_type::to_char_type(__c);
469 __ret = traits_type::not_eof(__c);
474 char_type __conv = traits_type::to_char_type(__c);
475 if (__testeof || _M_convert_to_external(&__conv, 1))
478 __ret = traits_type::not_eof(__c);
485 template<
typename _CharT,
typename _Traits>
493 if (__check_facet(_M_codecvt).always_noconv())
495 __elen = _M_file.
xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
502 streamsize __blen = __ilen * _M_codecvt->max_length();
503 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
506 const char_type* __iend;
507 codecvt_base::result __r;
508 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
509 __iend, __buf, __buf + __blen, __bend);
511 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
512 __blen = __bend - __buf;
513 else if (__r == codecvt_base::noconv)
516 __buf =
reinterpret_cast<char*
>(__ibuf);
520 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
521 "conversion error"));
523 __elen = _M_file.xsputn(__buf, __blen);
527 if (__r == codecvt_base::partial && __elen == __plen)
529 const char_type* __iresume = __iend;
531 __r = _M_codecvt->out(_M_state_cur, __iresume,
532 __iresume + __rlen, __iend, __buf,
533 __buf + __blen, __bend);
534 if (__r != codecvt_base::error)
536 __rlen = __bend - __buf;
537 __elen = _M_file.xsputn(__buf, __rlen);
541 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
542 "conversion error"));
545 return __elen == __plen;
548 template<
typename _CharT,
typename _Traits>
557 if (__n > 0 && this->gptr() == this->eback())
559 *__s++ = *this->gptr();
568 if (overflow() == traits_type::eof())
578 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
580 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
584 const streamsize __avail = this->egptr() - this->gptr();
587 traits_type::copy(__s, this->gptr(), __avail);
589 this->setg(this->eback(), this->gptr() + __avail,
600 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
603 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
604 "error reading the file"));
631 __ret += __streambuf_type::xsgetn(__s, __n);
636 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
virtual int_type pbackfail(int_type __c=_Traits::eof())
Tries to back up the input sequence.
Primary class template codecvt.NB: Generic, mostly useless implementation.
basic_filebuf()
Does not open any files.
virtual void imbue(const locale &__loc)
Changes translations.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.
Controlling input and output for files.This class supports reading from and writing to named files...
virtual __streambuf_type * setbuf(char_type *__s, streamsize __n)
Manipulates the buffer.
locale _M_buf_locale
Current locale setting.
_Ios_Openmode openmode
This is a bitmask type.
static const openmode ate
Open and seek to end immediately after opening.
static const seekdir beg
Request a seek relative to the beginning of the stream.
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
static const seekdir end
Request a seek relative to the current end of the sequence.
virtual int_type underflow()
Fetches more data from the controlled sequence.
Container class for localization functionality.The locale class is first a class wrapper for C librar...
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.
__filebuf_type * close()
Closes the currently associated file.
Controlling output for files.This class supports reading from named files, using the inherited functi...
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
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.
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
static const openmode in
Open for input. Default for ifstream and fstream.
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
virtual int_type overflow(int_type __c=_Traits::eof())
Consumes data from the buffer; writes to the controlled sequence.
static const openmode binary
Perform input and output in binary mode (as opposed to text mode). This is probably not what you thin...
Controlling input for files.This class supports reading from named files, using the inherited functio...
The actual work of input and output (interface).This is a base class. Derived stream buffers each con...
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
virtual streamsize showmanyc()
Investigating the data available.
static const seekdir cur
Request a seek relative to the current position within the sequence.