103a78d15Sespie // File based streams -*- C++ -*- 203a78d15Sespie 303a78d15Sespie // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 403a78d15Sespie // Free Software Foundation, Inc. 503a78d15Sespie // 603a78d15Sespie // This file is part of the GNU ISO C++ Library. This library is free 703a78d15Sespie // software; you can redistribute it and/or modify it under the 803a78d15Sespie // terms of the GNU General Public License as published by the 903a78d15Sespie // Free Software Foundation; either version 2, or (at your option) 1003a78d15Sespie // any later version. 1103a78d15Sespie 1203a78d15Sespie // This library is distributed in the hope that it will be useful, 1303a78d15Sespie // but WITHOUT ANY WARRANTY; without even the implied warranty of 1403a78d15Sespie // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1503a78d15Sespie // GNU General Public License for more details. 1603a78d15Sespie 1703a78d15Sespie // You should have received a copy of the GNU General Public License along 1803a78d15Sespie // with this library; see the file COPYING. If not, write to the Free 1903a78d15Sespie // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 2003a78d15Sespie // USA. 2103a78d15Sespie 2203a78d15Sespie // As a special exception, you may use this file as part of a free software 2303a78d15Sespie // library without restriction. Specifically, if other files instantiate 2403a78d15Sespie // templates or use macros or inline functions from this file, or you compile 2503a78d15Sespie // this file and link it with other files to produce an executable, this 2603a78d15Sespie // file does not by itself cause the resulting executable to be covered by 2703a78d15Sespie // the GNU General Public License. This exception does not however 2803a78d15Sespie // invalidate any other reasons why the executable file might be covered by 2903a78d15Sespie // the GNU General Public License. 3003a78d15Sespie 3103a78d15Sespie // 3203a78d15Sespie // ISO C++ 14882: 27.8 File-based streams 3303a78d15Sespie // 3403a78d15Sespie 3503a78d15Sespie #include <fstream> 3603a78d15Sespie 3703a78d15Sespie namespace std 3803a78d15Sespie { 3903a78d15Sespie template<> 4003a78d15Sespie basic_filebuf<char>::int_type _M_underflow_common(bool __bump)4103a78d15Sespie basic_filebuf<char>::_M_underflow_common(bool __bump) 4203a78d15Sespie { 4303a78d15Sespie int_type __ret = traits_type::eof(); 4403a78d15Sespie bool __testin = _M_mode & ios_base::in; 4503a78d15Sespie bool __testout = _M_mode & ios_base::out; 4603a78d15Sespie 4703a78d15Sespie if (__testin) 4803a78d15Sespie { 4903a78d15Sespie // Check for pback madness, and if so swich back to the 5003a78d15Sespie // normal buffers and jet outta here before expensive 5103a78d15Sespie // fileops happen... 5203a78d15Sespie if (_M_pback_init) 5303a78d15Sespie _M_pback_destroy(); 5403a78d15Sespie 5503a78d15Sespie if (_M_in_cur && _M_in_cur < _M_in_end) 5603a78d15Sespie { 5703a78d15Sespie __ret = traits_type::to_int_type(*_M_in_cur); 5803a78d15Sespie if (__bump) 5903a78d15Sespie _M_in_cur_move(1); 6003a78d15Sespie return __ret; 6103a78d15Sespie } 6203a78d15Sespie 6303a78d15Sespie // Sync internal and external buffers. 6403a78d15Sespie // NB: __testget -> __testput as _M_buf_unified here. 6503a78d15Sespie bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 6603a78d15Sespie bool __testinit = _M_is_indeterminate(); 6703a78d15Sespie if (__testget) 6803a78d15Sespie { 6903a78d15Sespie if (__testout) 7003a78d15Sespie _M_really_overflow(); 7103a78d15Sespie else if (_M_in_cur != _M_filepos) 7203a78d15Sespie _M_file.seekoff(_M_in_cur - _M_filepos, 7303a78d15Sespie ios_base::cur, ios_base::in); 7403a78d15Sespie } 7503a78d15Sespie 7603a78d15Sespie if (__testinit || __testget) 7703a78d15Sespie { 7803a78d15Sespie streamsize __elen = 0; 7903a78d15Sespie streamsize __ilen = 0; 8003a78d15Sespie __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 8103a78d15Sespie _M_buf_size); 8203a78d15Sespie __ilen = __elen; 8303a78d15Sespie 8403a78d15Sespie if (0 < __ilen) 8503a78d15Sespie { 8603a78d15Sespie _M_set_determinate(__ilen); 8703a78d15Sespie if (__testout) 8803a78d15Sespie _M_out_cur = _M_in_cur; 8903a78d15Sespie __ret = traits_type::to_int_type(*_M_in_cur); 9003a78d15Sespie if (__bump) 9103a78d15Sespie _M_in_cur_move(1); 9203a78d15Sespie else if (_M_buf_size == 1) 9303a78d15Sespie { 9403a78d15Sespie // If we are synced with stdio, we have to unget the 9503a78d15Sespie // character we just read so that the file pointer 9603a78d15Sespie // doesn't move. 9703a78d15Sespie _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 9803a78d15Sespie _M_set_indeterminate(); 9903a78d15Sespie } 10003a78d15Sespie } 10103a78d15Sespie } 10203a78d15Sespie } 10303a78d15Sespie _M_last_overflowed = false; 10403a78d15Sespie return __ret; 10503a78d15Sespie } 10603a78d15Sespie 107*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 10803a78d15Sespie template<> 10903a78d15Sespie basic_filebuf<wchar_t>::int_type _M_underflow_common(bool __bump)11003a78d15Sespie basic_filebuf<wchar_t>::_M_underflow_common(bool __bump) 11103a78d15Sespie { 11203a78d15Sespie int_type __ret = traits_type::eof(); 11303a78d15Sespie bool __testin = _M_mode & ios_base::in; 11403a78d15Sespie bool __testout = _M_mode & ios_base::out; 11503a78d15Sespie 11603a78d15Sespie if (__testin) 11703a78d15Sespie { 11803a78d15Sespie // Check for pback madness, and if so swich back to the 11903a78d15Sespie // normal buffers and jet outta here before expensive 12003a78d15Sespie // fileops happen... 12103a78d15Sespie if (_M_pback_init) 12203a78d15Sespie _M_pback_destroy(); 12303a78d15Sespie 12403a78d15Sespie if (_M_in_cur && _M_in_cur < _M_in_end) 12503a78d15Sespie { 12603a78d15Sespie __ret = traits_type::to_int_type(*_M_in_cur); 12703a78d15Sespie if (__bump) 12803a78d15Sespie _M_in_cur_move(1); 12903a78d15Sespie return __ret; 13003a78d15Sespie } 13103a78d15Sespie 13203a78d15Sespie // Sync internal and external buffers. 13303a78d15Sespie // NB: __testget -> __testput as _M_buf_unified here. 13403a78d15Sespie bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 13503a78d15Sespie bool __testinit = _M_is_indeterminate(); 13603a78d15Sespie if (__testget) 13703a78d15Sespie { 13803a78d15Sespie if (__testout) 13903a78d15Sespie _M_really_overflow(); 14003a78d15Sespie else if (_M_in_cur != _M_filepos) 14103a78d15Sespie _M_file.seekoff(_M_in_cur - _M_filepos, 14203a78d15Sespie ios_base::cur, ios_base::in); 14303a78d15Sespie } 14403a78d15Sespie 14503a78d15Sespie if (__testinit || __testget) 14603a78d15Sespie { 14703a78d15Sespie const locale __loc = this->getloc(); 14803a78d15Sespie const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 14903a78d15Sespie 15003a78d15Sespie streamsize __elen = 0; 15103a78d15Sespie streamsize __ilen = 0; 15203a78d15Sespie if (__cvt.always_noconv()) 15303a78d15Sespie { 15403a78d15Sespie __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 15503a78d15Sespie _M_buf_size); 15603a78d15Sespie __ilen = __elen; 15703a78d15Sespie } 15803a78d15Sespie else 15903a78d15Sespie { 16003a78d15Sespie char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size)); 16103a78d15Sespie __elen = _M_file.xsgetn(__buf, _M_buf_size); 16203a78d15Sespie 16303a78d15Sespie const char* __eend; 16403a78d15Sespie char_type* __iend; 16503a78d15Sespie codecvt_base::result __r; 16603a78d15Sespie __r = __cvt.in(_M_state_cur, __buf, 16703a78d15Sespie __buf + __elen, __eend, _M_in_beg, 16803a78d15Sespie _M_in_beg + _M_buf_size, __iend); 16903a78d15Sespie if (__r == codecvt_base::ok) 17003a78d15Sespie __ilen = __iend - _M_in_beg; 17103a78d15Sespie else 17203a78d15Sespie { 17303a78d15Sespie // Unwind. 17403a78d15Sespie __ilen = 0; 17503a78d15Sespie _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); 17603a78d15Sespie } 17703a78d15Sespie } 17803a78d15Sespie 17903a78d15Sespie if (0 < __ilen) 18003a78d15Sespie { 18103a78d15Sespie _M_set_determinate(__ilen); 18203a78d15Sespie if (__testout) 18303a78d15Sespie _M_out_cur = _M_in_cur; 18403a78d15Sespie __ret = traits_type::to_int_type(*_M_in_cur); 18503a78d15Sespie if (__bump) 18603a78d15Sespie _M_in_cur_move(1); 18703a78d15Sespie else if (_M_buf_size == 1) 18803a78d15Sespie { 18903a78d15Sespie // If we are synced with stdio, we have to unget the 19003a78d15Sespie // character we just read so that the file pointer 19103a78d15Sespie // doesn't move. 19203a78d15Sespie _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 19303a78d15Sespie _M_set_indeterminate(); 19403a78d15Sespie } 19503a78d15Sespie } 19603a78d15Sespie } 19703a78d15Sespie } 19803a78d15Sespie _M_last_overflowed = false; 19903a78d15Sespie return __ret; 20003a78d15Sespie } 20103a78d15Sespie #endif 20203a78d15Sespie } // namespace std 203