37 #define _FSTREAM_TCC 1
39 #pragma GCC system_header
41 #include <cxxabi-forced.h>
43 _GLIBCXX_BEGIN_NAMESPACE(std)
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>
78 basic_filebuf<_CharT, _Traits>::
80 _M_mode(
ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
81 _M_state_last(), _M_buf(NULL), _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();
208 if (__testin && !_M_writing)
215 if (this->gptr() < this->egptr())
216 return traits_type::to_int_type(*this->gptr());
219 const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
222 bool __got_eof =
false;
225 codecvt_base::result __r = codecvt_base::ok;
226 if (__check_facet(_M_codecvt).always_noconv())
228 __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
237 const int __enc = _M_codecvt->encoding();
241 __blen = __rlen = __buflen * __enc;
244 __blen = __buflen + _M_codecvt->max_length() - 1;
247 const streamsize __remainder = _M_ext_end - _M_ext_next;
248 __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
252 if (_M_reading && this->egptr() == this->eback() && __remainder)
257 if (_M_ext_buf_size < __blen)
259 char* __buf =
new char[__blen];
261 __builtin_memcpy(__buf, _M_ext_next, __remainder);
263 delete [] _M_ext_buf;
265 _M_ext_buf_size = __blen;
267 else if (__remainder)
268 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
270 _M_ext_next = _M_ext_buf;
271 _M_ext_end = _M_ext_buf + __remainder;
272 _M_state_last = _M_state_cur;
281 if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
283 __throw_ios_failure(__N(
"basic_filebuf::underflow "
284 "codecvt::max_length() "
287 streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
290 else if (__elen == -1)
292 _M_ext_end += __elen;
295 char_type* __iend = this->eback();
296 if (_M_ext_next < _M_ext_end)
297 __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
298 _M_ext_end, _M_ext_next,
300 this->eback() + __buflen, __iend);
301 if (__r == codecvt_base::noconv)
303 size_t __avail = _M_ext_end - _M_ext_buf;
304 __ilen =
std::min(__avail, __buflen);
305 traits_type::copy(this->eback(),
306 reinterpret_cast<char_type*>
307 (_M_ext_buf), __ilen);
308 _M_ext_next = _M_ext_buf + __ilen;
311 __ilen = __iend - this->eback();
316 if (__r == codecvt_base::error)
321 while (__ilen == 0 && !__got_eof);
326 _M_set_buffer(__ilen);
328 __ret = traits_type::to_int_type(*this->gptr());
339 if (__r == codecvt_base::partial)
340 __throw_ios_failure(__N(
"basic_filebuf::underflow "
341 "incomplete character in file"));
343 else if (__r == codecvt_base::error)
344 __throw_ios_failure(__N(
"basic_filebuf::underflow "
345 "invalid byte sequence in file"));
347 __throw_ios_failure(__N(
"basic_filebuf::underflow "
348 "error reading the file"));
353 template<
typename _CharT,
typename _Traits>
354 typename basic_filebuf<_CharT, _Traits>::int_type
358 int_type __ret = traits_type::eof();
360 if (__testin && !_M_writing)
364 const bool __testpb = _M_pback_init;
365 const bool __testeof = traits_type::eq_int_type(__i, __ret);
367 if (this->eback() < this->gptr())
370 __tmp = traits_type::to_int_type(*this->gptr());
372 else if (this->seekoff(-1,
ios_base::cur) != pos_type(off_type(-1)))
374 __tmp = this->underflow();
375 if (traits_type::eq_int_type(__tmp, __ret))
390 if (!__testeof && traits_type::eq_int_type(__i, __tmp))
393 __ret = traits_type::not_eof(__i);
398 *this->gptr() = traits_type::to_char_type(__i);
405 template<
typename _CharT,
typename _Traits>
406 typename basic_filebuf<_CharT, _Traits>::int_type
410 int_type __ret = traits_type::eof();
411 const bool __testeof = traits_type::eq_int_type(__c, __ret);
413 if (__testout && !_M_reading)
415 if (this->pbase() < this->pptr())
420 *this->pptr() = traits_type::to_char_type(__c);
426 if (_M_convert_to_external(this->pbase(),
427 this->pptr() - this->pbase()))
430 __ret = traits_type::not_eof(__c);
433 else if (_M_buf_size > 1)
442 *this->pptr() = traits_type::to_char_type(__c);
445 __ret = traits_type::not_eof(__c);
450 char_type __conv = traits_type::to_char_type(__c);
451 if (__testeof || _M_convert_to_external(&__conv, 1))
454 __ret = traits_type::not_eof(__c);
461 template<
typename _CharT,
typename _Traits>
469 if (__check_facet(_M_codecvt).always_noconv())
471 __elen = _M_file.
xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
478 streamsize __blen = __ilen * _M_codecvt->max_length();
479 char* __buf =
static_cast<char*
>(__builtin_alloca(__blen));
482 const char_type* __iend;
483 codecvt_base::result __r;
484 __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
485 __iend, __buf, __buf + __blen, __bend);
487 if (__r == codecvt_base::ok || __r == codecvt_base::partial)
488 __blen = __bend - __buf;
489 else if (__r == codecvt_base::noconv)
492 __buf =
reinterpret_cast<char*
>(__ibuf);
496 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
497 "conversion error"));
499 __elen = _M_file.xsputn(__buf, __blen);
503 if (__r == codecvt_base::partial && __elen == __plen)
505 const char_type* __iresume = __iend;
507 __r = _M_codecvt->out(_M_state_cur, __iresume,
508 __iresume + __rlen, __iend, __buf,
509 __buf + __blen, __bend);
510 if (__r != codecvt_base::error)
512 __rlen = __bend - __buf;
513 __elen = _M_file.xsputn(__buf, __rlen);
517 __throw_ios_failure(__N(
"basic_filebuf::_M_convert_to_external "
518 "conversion error"));
521 return __elen == __plen;
524 template<
typename _CharT,
typename _Traits>
533 if (__n > 0 && this->gptr() == this->eback())
535 *__s++ = *this->gptr();
547 const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
549 if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
550 && __testin && !_M_writing)
553 const streamsize __avail = this->egptr() - this->gptr();
557 *__s = *this->gptr();
559 traits_type::copy(__s, this->gptr(), __avail);
561 this->gbump(__avail);
571 __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
574 __throw_ios_failure(__N(
"basic_filebuf::xsgetn "
575 "error reading the file"));
602 __ret += __streambuf_type::xsgetn(__s, __n);
607 template<
typename _CharT,
typename _Traits>
617 if (__check_facet(_M_codecvt).always_noconv()
618 && __testout && !_M_reading)
622 streamsize __bufavail = this->epptr() - this->pptr();
625 if (!_M_writing && _M_buf_size > 1)
626 __bufavail = _M_buf_size - 1;
631 const streamsize __buffill = this->pptr() - this->pbase();
632 const char* __buf =
reinterpret_cast<const char*
>(this->pbase());
633 __ret = _M_file.xsputn_2(__buf, __buffill,
634 reinterpret_cast<const char*>(__s),
636 if (__ret == __buffill + __n)
641 if (__ret > __buffill)
647 __ret = __streambuf_type::xsputn(__s, __n);
650 __ret = __streambuf_type::xsputn(__s, __n);
654 template<
typename _CharT,
typename _Traits>
659 if (!this->is_open())
661 if (__s == 0 && __n == 0)
663 else if (__s && __n > 0)
683 template<
typename _CharT,
typename _Traits>
684 typename basic_filebuf<_CharT, _Traits>::pos_type
686 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
690 __width = _M_codecvt->encoding();
694 pos_type __ret = pos_type(off_type(-1));
695 const bool __testfail = __off != 0 && __width <= 0;
696 if (this->is_open() && !__testfail)
706 __state_type __state = _M_state_beg;
707 off_type __computed_off = __off * __width;
710 if (_M_codecvt->always_noconv())
711 __computed_off += this->gptr() - this->egptr();
717 const int __gptr_off =
718 _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
719 this->gptr() - this->eback());
720 __computed_off += _M_ext_buf + __gptr_off - _M_ext_end;
724 __state = _M_state_last;
727 __ret = _M_seek(__computed_off, __way, __state);
736 template<
typename _CharT,
typename _Traits>
737 typename basic_filebuf<_CharT, _Traits>::pos_type
741 pos_type __ret = pos_type(off_type(-1));
746 __ret = _M_seek(off_type(__pos),
ios_base::beg, __pos.state());
751 template<
typename _CharT,
typename _Traits>
752 typename basic_filebuf<_CharT, _Traits>::pos_type
754 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
756 pos_type __ret = pos_type(off_type(-1));
757 if (_M_terminate_output())
760 __ret = pos_type(_M_file.seekoff(__off, __way));
761 if (__ret != pos_type(off_type(-1)))
765 _M_ext_next = _M_ext_end = _M_ext_buf;
767 _M_state_cur = __state;
768 __ret.state(_M_state_cur);
774 template<
typename _CharT,
typename _Traits>
776 basic_filebuf<_CharT, _Traits>::
777 _M_terminate_output()
780 bool __testvalid =
true;
781 if (this->pbase() < this->pptr())
783 const int_type __tmp = this->overflow();
784 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
789 if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
795 const size_t __blen = 128;
797 codecvt_base::result __r;
803 __r = _M_codecvt->unshift(_M_state_cur, __buf,
804 __buf + __blen, __next);
805 if (__r == codecvt_base::error)
807 else if (__r == codecvt_base::ok ||
808 __r == codecvt_base::partial)
810 __ilen = __next - __buf;
813 const streamsize __elen = _M_file.xsputn(__buf, __ilen);
814 if (__elen != __ilen)
819 while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
827 const int_type __tmp = this->overflow();
828 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
835 template<
typename _CharT,
typename _Traits>
843 if (this->pbase() < this->pptr())
845 const int_type __tmp = this->overflow();
846 if (traits_type::eq_int_type(__tmp, traits_type::eof()))
852 template<
typename _CharT,
typename _Traits>
857 bool __testvalid =
true;
860 if (__builtin_expect(has_facet<__codecvt_type>(__loc),
true))
861 _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
866 if ((_M_reading || _M_writing)
867 && __check_facet(_M_codecvt).encoding() == -1)
873 if (__check_facet(_M_codecvt).always_noconv())
876 && !__check_facet(_M_codecvt_tmp).always_noconv())
878 != pos_type(off_type(-1));
883 _M_ext_next = _M_ext_buf
884 + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
885 this->gptr() - this->eback());
886 const streamsize __remainder = _M_ext_end - _M_ext_next;
888 __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
890 _M_ext_next = _M_ext_buf;
891 _M_ext_end = _M_ext_buf + __remainder;
893 _M_state_last = _M_state_cur = _M_state_beg;
896 else if (_M_writing && (__testvalid = _M_terminate_output()))
902 _M_codecvt = _M_codecvt_tmp;
910 #if _GLIBCXX_EXTERN_TEMPLATE
916 #ifdef _GLIBCXX_USE_WCHAR_T
924 _GLIBCXX_END_NAMESPACE
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.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
static const openmode ate
Open and seek to end immediately after opening.
__filebuf_type * open(const char *__s, ios_base::openmode __mode)
Opens an external file.
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...
Controlling output for files.This class supports reading from named files, using the inherited functi...
_Ios_Openmode openmode
This is a bitmask type.
The actual work of input and output (interface).
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
static const seekdir cur
Request a seek relative to the current position within the sequence.
virtual streamsize xsputn(const char_type *__s, streamsize __n)
Multiple character insertion.
virtual __streambuf_type * setbuf(char_type *__s, streamsize __n)
Manipulates the buffer.
static const seekdir beg
Request a seek relative to the beginning of the stream.
static const openmode in
Open for input. Default for ifstream and fstream.
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode=ios_base::in|ios_base::out)
Alters the stream positions.
virtual streamsize xsgetn(char_type *__s, streamsize __n)
Multiple character extraction.
virtual streamsize showmanyc()
Investigating the data available.
virtual int_type overflow(int_type __c=_Traits::eof())
Consumes data from the buffer; writes to the controlled sequence.
Controlling input for files.This class supports reading from named files, using the inherited functio...
__filebuf_type * close()
Closes the currently associated file.
Container class for localization functionality.
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
virtual void imbue(const locale &__loc)
Changes translations.
virtual int sync()
Synchronizes the buffer arrays with the controlled sequences.
virtual int_type pbackfail(int_type __c=_Traits::eof())
Tries to back up the input sequence.
class codecvt [22.2.1.5]. NB: Generic, mostly useless implementation.
locale _M_buf_locale
Current locale setting.
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.
Controlling input and output for files.This class supports reading from and writing to named files...