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);
432 const int __gptr_off = _M_get_ext_pos(_M_state_last);
434 == pos_type(off_type(-1)))
437 if (this->pbase() < this->pptr())
442 *this->pptr() = traits_type::to_char_type(__c);
448 if (_M_convert_to_external(this->pbase(),
449 this->pptr() - this->pbase()))
452 __ret = traits_type::not_eof(__c);
455 else if (_M_buf_size > 1)
464 *this->pptr() = traits_type::to_char_type(__c);
467 __ret = traits_type::not_eof(__c);
472 char_type __conv = traits_type::to_char_type(__c);
473 if (__testeof || _M_convert_to_external(&__conv, 1))
476 __ret = traits_type::not_eof(__c);
483 template<
typename _CharT,
typename _Traits>
485 basic_filebuf<_CharT, _Traits>::
486 _M_convert_to_external(_CharT* __ibuf,
streamsize __ilen)
491 if (__check_facet(_M_codecvt).always_noconv())
493 __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
500 streamsize __blen = __ilen * _M_codecvt->max_length();
501 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
504 const char_type* __iend;
505 codecvt_base::result __r;
506 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
507 __iend, __buf, __buf + __blen, __bend);
509 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
510 __blen = __bend - __buf;
511 else if (__r == codecvt_base::noconv)
514 __buf =
reinterpret_cast<char*
>(__ibuf);
518 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
519 "conversion error"));
521 __elen = _M_file.xsputn(__buf, __blen);
525 if (__r == codecvt_base::partial && __elen == __plen)
527 const char_type* __iresume = __iend;
529 __r = _M_codecvt->out(_M_state_cur, __iresume,
530 __iresume + __rlen, __iend, __buf,
531 __buf + __blen, __bend);
532 if (__r != codecvt_base::error)
534 __rlen = __bend - __buf;
535 __elen = _M_file.xsputn(__buf, __rlen);
539 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
540 "conversion error"));
543 return __elen == __plen;
546 template<
typename _CharT,
typename _Traits>
555 if (__n > 0 && this->gptr() == this->eback())
557 *__s++ = *this->gptr();
566 if (overflow() == traits_type::eof())
576 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
578 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
582 const streamsize __avail = this->egptr() - this->gptr();
585 traits_type::copy(__s, this->gptr(), __avail);
587 this->setg(this->eback(), this->gptr() + __avail,
598 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
601 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
602 "error reading the file"));
629 __ret += __streambuf_type::xsgetn(__s, __n);
634 template<
typename _CharT,
typename _Traits>
644 if (__check_facet(_M_codecvt).always_noconv()
645 && __testout && !_M_reading)
649 streamsize __bufavail = this->epptr() - this->pptr();
652 if (!_M_writing && _M_buf_size > 1)
653 __bufavail = _M_buf_size - 1;
658 const streamsize __buffill = this->pptr() - this->pbase();
659 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
660 __ret = _M_file.xsputn_2(__buf, __buffill,
661 reinterpret_cast<const char*>(__s),
663 if (__ret == __buffill + __n)
668 if (__ret > __buffill)
674 __ret = __streambuf_type::xsputn(__s, __n);
677 __ret = __streambuf_type::xsputn(__s, __n);
681 template<
typename _CharT,
typename _Traits>
686 if (!this->is_open())
688 if (__s == 0 && __n == 0)
690 else if (__s && __n > 0)
710 template<
typename _CharT,
typename _Traits>
711 typename basic_filebuf<_CharT, _Traits>::pos_type
713 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
717 __width = _M_codecvt->encoding();
721 pos_type __ret = pos_type(off_type(-1));
722 const bool __testfail = __off != 0 && __width <= 0;
723 if (this->is_open() && !__testfail)
730 && (!_M_writing || _M_codecvt->always_noconv());
741 __state_type __state = _M_state_beg;
742 off_type __computed_off = __off * __width;
745 __state = _M_state_last;
746 __computed_off += _M_get_ext_pos(__state);
749 __ret = _M_seek(__computed_off, __way, __state);
753 __computed_off = this->pptr() - this->pbase();
756 if (__file_off != off_type(-1))
758 __ret = __file_off + __computed_off;
759 __ret.state(__state);
770 template<
typename _CharT,
typename _Traits>
771 typename basic_filebuf<_CharT, _Traits>::pos_type
775 pos_type __ret = pos_type(off_type(-1));
780 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
785 template<
typename _CharT,
typename _Traits>
786 typename basic_filebuf<_CharT, _Traits>::pos_type
788 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
790 pos_type __ret = pos_type(off_type(-1));
791 if (_M_terminate_output())
793 off_type __file_off = _M_file.seekoff(__off, __way);
794 if (__file_off != off_type(-1))
798 _M_ext_next = _M_ext_end = _M_ext_buf;
800 _M_state_cur = __state;
802 __ret.state(_M_state_cur);
811 template<
typename _CharT,
typename _Traits>
812 int basic_filebuf<_CharT, _Traits>::
813 _M_get_ext_pos(__state_type& __state)
815 if (_M_codecvt->always_noconv())
816 return this->gptr() - this->egptr();
822 const int __gptr_off =
823 _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
824 this->gptr() - this->eback());
825 return _M_ext_buf + __gptr_off - _M_ext_end;
829 template<
typename _CharT,
typename _Traits>
831 basic_filebuf<_CharT, _Traits>::
832 _M_terminate_output()
835 bool __testvalid =
true;
836 if (this->pbase() < this->pptr())
838 const int_type __tmp = this->overflow();
839 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
844 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
850 const size_t __blen = 128;
852 codecvt_base::result __r;
858 __r = _M_codecvt->unshift(_M_state_cur, __buf,
859 __buf + __blen, __next);
860 if (__r == codecvt_base::error)
862 else if (__r == codecvt_base::ok ||
863 __r == codecvt_base::partial)
865 __ilen = __next - __buf;
868 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
869 if (__elen != __ilen)
874 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
882 const int_type __tmp = this->overflow();
883 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
890 template<
typename _CharT,
typename _Traits>
898 if (this->pbase() < this->pptr())
900 const int_type __tmp = this->overflow();
901 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
907 template<
typename _CharT,
typename _Traits>
912 bool __testvalid =
true;
915 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
916 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
921 if ((_M_reading || _M_writing)
922 && __check_facet(_M_codecvt).encoding() == -1)
928 if (__check_facet(_M_codecvt).always_noconv())
931 && !__check_facet(_M_codecvt_tmp).always_noconv())
933 != pos_type(off_type(-1));
938 _M_ext_next = _M_ext_buf
939 + _M_codecvt->length(_M_state_last, _M_ext_buf,
941 this->gptr() - this->eback());
942 const streamsize __remainder = _M_ext_end - _M_ext_next;
944 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
946 _M_ext_next = _M_ext_buf;
947 _M_ext_end = _M_ext_buf + __remainder;
949 _M_state_last = _M_state_cur = _M_state_beg;
952 else if (_M_writing && (__testvalid = _M_terminate_output()))
958 _M_codecvt = _M_codecvt_tmp;
965 #if _GLIBCXX_EXTERN_TEMPLATE
971 #ifdef _GLIBCXX_USE_WCHAR_T
979 _GLIBCXX_END_NAMESPACE_VERSION
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
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...
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
static const seekdir cur
Request a seek relative to the current position within the sequence.
virtual __streambuf_type * setbuf(char_type *__s, streamsize __n)
Manipulates the buffer.
Controlling input and output for files.
static const seekdir beg
Request a seek relative to the beginning of the stream.
__filebuf_type * close()
Closes the currently associated file.
virtual void imbue(const locale &__loc)
Changes translations.
static const openmode ate
Open and seek to end immediately after opening.
locale _M_buf_locale
Current locale setting.
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
virtual streamsize showmanyc()
Investigating the data available.
Controlling input for files.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
_Ios_Openmode openmode
This is a bitmask type.
Container class for localization functionality.The locale class is first a class wrapper for C librar...
static const seekdir end
Request a seek relative to the current end of the sequence.
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
Controlling output for files.
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.
static const openmode in
Open for input. Default for ifstream and fstream.
The actual work of input and output (interface).
Primary class template codecvt.NB: Generic, mostly useless implementation.
basic_filebuf()
Does not open any files.
virtual int_type underflow()
Fetches more data from the controlled sequence.
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.