fstream.cc

00001 // File based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 { 00054 _M_pback_destroy(); 00055 if (_M_in_cur < _M_in_end) 00056 return traits_type::to_int_type(*_M_in_cur); 00057 } 00058 00059 // Sync internal and external buffers. 00060 // NB: __testget -> __testput as _M_buf_unified here. 00061 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 00062 bool __testinit = _M_is_indeterminate(); 00063 if (__testget) 00064 { 00065 if (__testout) 00066 _M_really_overflow(); 00067 else if (_M_in_cur != _M_filepos) 00068 _M_file.seekoff(_M_in_cur - _M_filepos, 00069 ios_base::cur, ios_base::in); 00070 } 00071 00072 if (__testinit || __testget) 00073 { 00074 streamsize __elen = 0; 00075 streamsize __ilen = 0; 00076 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 00077 _M_buf_size); 00078 __ilen = __elen; 00079 00080 if (0 < __ilen) 00081 { 00082 _M_set_determinate(__ilen); 00083 if (__testout) 00084 _M_out_cur = _M_in_cur; 00085 __ret = traits_type::to_int_type(*_M_in_cur); 00086 if (__bump) 00087 _M_in_cur_move(1); 00088 else if (_M_buf_size == 1) 00089 { 00090 // If we are synced with stdio, we have to unget the 00091 // character we just read so that the file pointer 00092 // doesn't move. 00093 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 00094 _M_set_indeterminate(); 00095 } 00096 } 00097 } 00098 } 00099 _M_last_overflowed = false; 00100 return __ret; 00101 } 00102 00103 #ifdef _GLIBCPP_USE_WCHAR_T 00104 template<> 00105 basic_filebuf<wchar_t>::int_type 00106 basic_filebuf<wchar_t>::_M_underflow_common(bool __bump) 00107 { 00108 int_type __ret = traits_type::eof(); 00109 bool __testin = _M_mode & ios_base::in; 00110 bool __testout = _M_mode & ios_base::out; 00111 00112 if (__testin) 00113 { 00114 // Check for pback madness, and if so swich back to the 00115 // normal buffers and jet outta here before expensive 00116 // fileops happen... 00117 if (_M_pback_init) 00118 { 00119 _M_pback_destroy(); 00120 if (_M_in_cur < _M_in_end) 00121 return traits_type::to_int_type(*_M_in_cur); 00122 } 00123 00124 // Sync internal and external buffers. 00125 // NB: __testget -> __testput as _M_buf_unified here. 00126 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; 00127 bool __testinit = _M_is_indeterminate(); 00128 if (__testget) 00129 { 00130 if (__testout) 00131 _M_really_overflow(); 00132 else if (_M_in_cur != _M_filepos) 00133 _M_file.seekoff(_M_in_cur - _M_filepos, 00134 ios_base::cur, ios_base::in); 00135 } 00136 00137 if (__testinit || __testget) 00138 { 00139 const locale __loc = this->getloc(); 00140 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 00141 00142 streamsize __elen = 0; 00143 streamsize __ilen = 0; 00144 if (__cvt.always_noconv()) 00145 { 00146 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 00147 _M_buf_size); 00148 __ilen = __elen; 00149 } 00150 else 00151 { 00152 char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size)); 00153 __elen = _M_file.xsgetn(__buf, _M_buf_size); 00154 00155 const char* __eend; 00156 char_type* __iend; 00157 __res_type __r = __cvt.in(_M_state_cur, __buf, 00158 __buf + __elen, __eend, _M_in_beg, 00159 _M_in_beg + _M_buf_size, __iend); 00160 if (__r == codecvt_base::ok) 00161 __ilen = __iend - _M_in_beg; 00162 else 00163 { 00164 // Unwind. 00165 __ilen = 0; 00166 _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); 00167 } 00168 } 00169 00170 if (0 < __ilen) 00171 { 00172 _M_set_determinate(__ilen); 00173 if (__testout) 00174 _M_out_cur = _M_in_cur; 00175 __ret = traits_type::to_int_type(*_M_in_cur); 00176 if (__bump) 00177 _M_in_cur_move(1); 00178 else if (_M_buf_size == 1) 00179 { 00180 // If we are synced with stdio, we have to unget the 00181 // character we just read so that the file pointer 00182 // doesn't move. 00183 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur)); 00184 _M_set_indeterminate(); 00185 } 00186 } 00187 } 00188 } 00189 _M_last_overflowed = false; 00190 return __ret; 00191 } 00192 #endif 00193 } // namespace std

Generated on Wed Sep 29 13:54:47 2004 for libstdc++-v3 Source by doxygen 1.3.7