📄 fstream.tcc
字号:
} _M_last_overflowed = false; // Set in _M_really_overflow, below. return __ret; } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_convert_to_external(_CharT* __ibuf, streamsize __ilen, streamsize& __elen, streamsize& __plen) { const locale __loc = this->getloc(); const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); if (__cvt.always_noconv() && __ilen) { __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); __plen += __ilen; } else { // Worst-case number of external bytes needed. int __ext_multiplier = __cvt.encoding(); if (__ext_multiplier == -1 || __ext_multiplier == 0) __ext_multiplier = sizeof(char_type); streamsize __blen = __ilen * __ext_multiplier; char* __buf = static_cast<char*>(__builtin_alloca(__blen)); char* __bend; const char_type* __iend; codecvt_base::result __r; __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen, __iend, __buf, __buf + __blen, __bend); if (__r == codecvt_base::ok || __r == codecvt_base::partial) __blen = __bend - __buf; else if (__r == codecvt_base::noconv) { // Same as the always_noconv case above. __buf = reinterpret_cast<char*>(__ibuf); __blen = __ilen; } else { // Result == error __blen = 0; } if (__blen) { __elen += _M_file.xsputn(__buf, __blen); __plen += __blen; } // Try once more for partial conversions. if (__r == codecvt_base::partial) { const char_type* __iresume = __iend; streamsize __rlen = _M_out_end - __iend; __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen, __iend, __buf, __buf + __blen, __bend); if (__r != codecvt_base::error) { __rlen = __bend - __buf; __elen += _M_file.xsputn(__buf, __rlen); __plen += __rlen; } } } } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: _M_really_overflow(int_type __c) { int_type __ret = traits_type::eof(); bool __testput = _M_out_cur && _M_out_beg < _M_out_end; bool __testunbuffered = _M_file.is_open() && !_M_buf_size; if (__testput || __testunbuffered) { // Sizes of external and pending output. streamsize __elen = 0; streamsize __plen = 0; // Need to restore current position. The position of the external // byte sequence (_M_file) corresponds to _M_filepos, and we need // to move it to _M_out_beg for the write. if (_M_filepos && _M_filepos != _M_out_beg) { off_type __off = _M_out_beg - _M_filepos; _M_file.seekoff(__off, ios_base::cur); } // Convert internal buffer to external representation, output. // NB: In the unbuffered case, no internal buffer exists. if (!__testunbuffered) _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg, __elen, __plen); // Checks for codecvt.out failures and _M_file.xsputn failures, // respectively, inside _M_convert_to_external. if (__testunbuffered || (__elen && __elen == __plen)) { // Convert pending sequence to external representation, output. // If eof, then just attempt sync. if (!traits_type::eq_int_type(__c, traits_type::eof())) { char_type __pending = traits_type::to_char_type(__c); _M_convert_to_external(&__pending, 1, __elen, __plen); // User code must flush when switching modes (thus // don't sync). if (__elen == __plen && __elen) { _M_set_indeterminate(); __ret = traits_type::not_eof(__c); } } else if (!_M_file.sync()) { _M_set_indeterminate(); __ret = traits_type::not_eof(__c); } } } _M_last_overflowed = true; return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__streambuf_type* basic_filebuf<_CharT, _Traits>:: setbuf(char_type* __s, streamsize __n) { if (!this->is_open() && __s == 0 && __n == 0) _M_buf_size_opt = 0; else if (__s && __n) { // This is implementation-defined behavior, and assumes // that an external char_type array of length (__s + __n) // exists and has been pre-allocated. If this is not the // case, things will quickly blow up. // Step 1: Destroy the current internal array. _M_destroy_internal_buffer(); // Step 2: Use the external array. _M_buf = __s; _M_buf_size_opt = _M_buf_size = __n; _M_set_indeterminate(); } _M_last_overflowed = false; return this; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) { pos_type __ret = pos_type(off_type(-1)); bool __testin = (ios_base::in & _M_mode & __mode) != 0; bool __testout = (ios_base::out & _M_mode & __mode) != 0; int __width = 0; if (has_facet<__codecvt_type>(this->_M_buf_locale)) __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding(); if (__width < 0) __width = 0; bool __testfail = __off != 0 && __width <= 0; if (this->is_open() && !__testfail && (__testin || __testout)) { // Ditch any pback buffers to avoid confusion. _M_pback_destroy(); if (__way != ios_base::cur || __off != 0) { off_type __computed_off = __width * __off; bool __testget = _M_in_cur && _M_in_beg < _M_in_end; bool __testput = _M_out_cur && _M_out_beg < _M_out_end; // Sync the internal and external streams. // out if (__testput || _M_last_overflowed) { // Part one: update the output sequence. this->sync(); // Part two: output unshift sequence. _M_output_unshift(); } //in else if (__testget && __way == ios_base::cur) __computed_off += _M_in_cur - _M_filepos; // Return pos_type(off_type(-1)) in case of failure. __ret = _M_file.seekoff(__computed_off, __way, __mode); _M_set_indeterminate(); } // NB: Need to do this in case _M_file in indeterminate // state, ie _M_file._offset == -1 else { pos_type __tmp = _M_file.seekoff(__off, ios_base::cur, __mode); if (__tmp >= 0) { // Seek successful. __ret = __tmp; __ret += max(_M_out_cur, _M_in_cur) - _M_filepos; } } } _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: seekpos(pos_type __pos, ios_base::openmode __mode) {#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS// 171. Strange seekpos() semantics due to joint position return this->seekoff(off_type(__pos), ios_base::beg, __mode);#endif } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_output_unshift() { } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: imbue(const locale& __loc) { bool __testbeg = gptr() == eback() && pptr() == pbase(); if (__testbeg && _M_buf_locale != __loc) _M_buf_locale = __loc; // NB this may require the reconversion of previously // converted chars. This in turn may cause the reconstruction // of the original file. YIKES!! // XXX The part in the above comment is not done. _M_last_overflowed = false; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension.#if _GLIBCPP_EXTERN_TEMPLATE extern template class basic_filebuf<char>; extern template class basic_ifstream<char>; extern template class basic_ofstream<char>; extern template class basic_fstream<char>;#ifdef _GLIBCPP_USE_WCHAR_T extern template class basic_filebuf<wchar_t>; extern template class basic_ifstream<wchar_t>; extern template class basic_ofstream<wchar_t>; extern template class basic_fstream<wchar_t>;#endif#endif} // namespace std#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -