fstream.cc

00001 // File based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // 00032 // ISO C++ 14882: 27.8 File-based streams 00033 // 00034 00035 #include <fstream> 00036 00037 namespace std 00038 { 00039 template<> 00040 basic_filebuf<char>::int_type 00041 basic_filebuf<char>::_M_underflow_common(bool __bump) 00042 { 00043 int_type __ret = traits_type::eof(); 00044 bool __testin = _M_mode & ios_base::in; 00045 bool __testout = _M_mode & ios_base::out; 00046 00047 if (__testin) 00048 { 00049 // Check for pback madness, and if so swich back to the 00050 // normal buffers and jet outta here before expensive 00051 // fileops happen... 00052 if (_M_pback_init) 00053 _M_pback_destroy(); 00054 00055 if (_M_in_cur && _M_in_cur < _M_in_end) 00056 { 00057 __ret = traits_type::to_int_type(*_M_in_cur); 00058 if (__bump) 00059 _M_in_cur_move(1); 00060 return __ret; 00061 } 00062 00063 // Sync internal and external buffers. 00064 // NB: __testget -> __testput as _M_buf_unified here. 00065 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 00066 bool __testinit = _M_is_indeterminate(); 00067 if (__testget) 00068 { 00069 if (__testout) 00070 _M_really_overflow(); 00071 else if (_M_in_cur != _M_filepos) 00072 _M_file.seekoff(_M_in_cur - _M_filepos, 00073 ios_base::cur, ios_base::in); 00074 } 00075 00076 if (__testinit || __testget) 00077 { 00078 streamsize __elen = 0; 00079 streamsize __ilen = 0; 00080 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 00081 _M_buf_size); 00082 __ilen = __elen; 00083 00084 if (0 < __ilen) 00085 { 00086 _M_set_determinate(__ilen); 00087 if (__testout) 00088 _M_out_cur = _M_in_cur; 00089 __ret = traits_type::to_int_type(*_M_in_cur); 00090 if (__bump) 00091 _M_in_cur_move(1); 00092 else if (_M_buf_size == 1) 00093 { 00094 // If we are synced with stdio, we have to unget the 00095 // character we just read so that the file pointer 00096 // doesn't move. 00097 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 00098 _M_set_indeterminate(); 00099 } 00100 } 00101 } 00102 } 00103 _M_last_overflowed = false; 00104 return __ret; 00105 } 00106 00107 #ifdef _GLIBCPP_USE_WCHAR_T 00108 template<> 00109 basic_filebuf<wchar_t>::int_type 00110 basic_filebuf<wchar_t>::_M_underflow_common(bool __bump) 00111 { 00112 int_type __ret = traits_type::eof(); 00113 bool __testin = _M_mode & ios_base::in; 00114 bool __testout = _M_mode & ios_base::out; 00115 00116 if (__testin) 00117 { 00118 // Check for pback madness, and if so swich back to the 00119 // normal buffers and jet outta here before expensive 00120 // fileops happen... 00121 if (_M_pback_init) 00122 _M_pback_destroy(); 00123 00124 if (_M_in_cur && _M_in_cur < _M_in_end) 00125 { 00126 __ret = traits_type::to_int_type(*_M_in_cur); 00127 if (__bump) 00128 _M_in_cur_move(1); 00129 return __ret; 00130 } 00131 00132 // Sync internal and external buffers. 00133 // NB: __testget -> __testput as _M_buf_unified here. 00134 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 00135 bool __testinit = _M_is_indeterminate(); 00136 if (__testget) 00137 { 00138 if (__testout) 00139 _M_really_overflow(); 00140 else if (_M_in_cur != _M_filepos) 00141 _M_file.seekoff(_M_in_cur - _M_filepos, 00142 ios_base::cur, ios_base::in); 00143 } 00144 00145 if (__testinit || __testget) 00146 { 00147 const locale __loc = this->getloc(); 00148 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 00149 00150 streamsize __elen = 0; 00151 streamsize __ilen = 0; 00152 if (__cvt.always_noconv()) 00153 { 00154 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 00155 _M_buf_size); 00156 __ilen = __elen; 00157 } 00158 else 00159 { 00160 char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size)); 00161 __elen = _M_file.xsgetn(__buf, _M_buf_size); 00162 00163 const char* __eend; 00164 char_type* __iend; 00165 codecvt_base::result __r; 00166 __r = __cvt.in(_M_state_cur, __buf, 00167 __buf + __elen, __eend, _M_in_beg, 00168 _M_in_beg + _M_buf_size, __iend); 00169 if (__r == codecvt_base::ok) 00170 __ilen = __iend - _M_in_beg; 00171 else 00172 { 00173 // Unwind. 00174 __ilen = 0; 00175 _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); 00176 } 00177 } 00178 00179 if (0 < __ilen) 00180 { 00181 _M_set_determinate(__ilen); 00182 if (__testout) 00183 _M_out_cur = _M_in_cur; 00184 __ret = traits_type::to_int_type(*_M_in_cur); 00185 if (__bump) 00186 _M_in_cur_move(1); 00187 else if (_M_buf_size == 1) 00188 { 00189 // If we are synced with stdio, we have to unget the 00190 // character we just read so that the file pointer 00191 // doesn't move. 00192 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 00193 _M_set_indeterminate(); 00194 } 00195 } 00196 } 00197 } 00198 _M_last_overflowed = false; 00199 return __ret; 00200 } 00201 #endif 00202 } // namespace std

Generated on Wed Aug 4 21:43:10 2004 for libstdc++-v3 Source by doxygen 1.3.8