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 Thu Feb 10 23:22:54 2005 for libstdc++-v3 Source by  doxygen 1.4.0