📄 fstream.tcc
字号:
// File based streams -*- C++ -*-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003// Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// ISO C++ 14882: 27.8 File-based streams//#ifndef _CPP_BITS_FSTREAM_TCC#define _CPP_BITS_FSTREAM_TCC 1#pragma GCC system_headernamespace std{ template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_allocate_internal_buffer() { if (!_M_buf && _M_buf_size_opt) { _M_buf_size = _M_buf_size_opt; // Allocate internal buffer. _M_buf = new char_type[_M_buf_size]; _M_buf_allocated = true; } } // Both close and setbuf need to deallocate internal buffers, if it exists. template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_destroy_internal_buffer() throw() { if (_M_buf_allocated) { delete [] _M_buf; _M_buf = NULL; _M_buf_allocated = false; this->setg(NULL, NULL, NULL); this->setp(NULL, NULL); } } template<typename _CharT, typename _Traits> basic_filebuf<_CharT, _Traits>:: basic_filebuf() : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf_allocated(false), _M_last_overflowed(false) { _M_buf_unified = true; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: open(const char* __s, ios_base::openmode __mode) { __filebuf_type *__ret = NULL; if (!this->is_open()) { _M_file.open(__s, __mode); if (this->is_open()) { _M_allocate_internal_buffer(); _M_mode = __mode; // Setup initial position of buffer. _M_set_indeterminate(); if ((__mode & ios_base::ate) && this->seekoff(0, ios_base::end, __mode) < 0) { // 27.8.1.3,4 this->close(); return __ret; } __ret = this; } } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: close() throw() { __filebuf_type* __ret = NULL; if (this->is_open()) { bool __testfail = false; try { const int_type __eof = traits_type::eof(); bool __testput = _M_out_cur && _M_out_beg < _M_out_end; if (__testput && traits_type::eq_int_type(_M_really_overflow(__eof), __eof)) __testfail = true; #if 0 // XXX not done if (_M_last_overflowed) { _M_output_unshift(); _M_really_overflow(__eof); }#endif } catch(...) { __testfail = true; } // NB: Do this here so that re-opened filebufs will be cool... this->_M_mode = ios_base::openmode(0); _M_destroy_internal_buffer(); _M_pback_destroy(); if (!_M_file.close()) __testfail = true; if (!__testfail) __ret = this; } _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> streamsize basic_filebuf<_CharT, _Traits>:: showmanyc() { streamsize __ret = -1; bool __testin = _M_mode & ios_base::in; const locale __loc = this->getloc(); const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); if (__testin && this->is_open()) { __ret = _M_in_end - _M_in_cur; if (__cvt.always_noconv()) __ret += _M_file.showmanyc_helper(); } _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: pbackfail(int_type __i) { int_type __ret = traits_type::eof(); bool __testin = _M_mode & ios_base::in; if (__testin) { bool __testpb = _M_in_beg < _M_in_cur; char_type __c = traits_type::to_char_type(__i); bool __testeof = traits_type::eq_int_type(__i, __ret); if (__testpb) { bool __testout = _M_mode & ios_base::out; bool __testeq = traits_type::eq(__c, this->gptr()[-1]); // Try to put back __c into input sequence in one of three ways. // Order these tests done in is unspecified by the standard. if (!__testeof && __testeq) { --_M_in_cur; if (__testout) --_M_out_cur; __ret = __i; } else if (__testeof) { --_M_in_cur; if (__testout) --_M_out_cur; __ret = traits_type::not_eof(__i); } else if (!__testeof) { --_M_in_cur; if (__testout) --_M_out_cur; _M_pback_create(); *_M_in_cur = __c; __ret = __i; } } else { // At the beginning of the buffer, need to make a // putback position available. // But the seek may fail (f.i., at the beginning of // a file, see libstdc++/9439) and in that case // we return traits_type::eof() if (this->seekoff(-1, ios_base::cur) >= 0) { this->underflow(); if (!__testeof) { if (!traits_type::eq(__c, *_M_in_cur)) { _M_pback_create(); *_M_in_cur = __c; } __ret = __i; } else __ret = traits_type::not_eof(__i); } } } _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: overflow(int_type __c) { int_type __ret = traits_type::eof(); bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size; bool __testout = _M_mode & ios_base::out; if (__testout) { if (traits_type::eq_int_type(__c, traits_type::eof())) __ret = traits_type::not_eof(__c); else if (__testput) { *_M_out_cur = traits_type::to_char_type(__c); _M_out_cur_move(1); __ret = traits_type::not_eof(__c); } else __ret = this->_M_really_overflow(__c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -