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 Tue Dec 23 12:33:40 2003 for libstdc++-v3 Source by doxygen 1.3.4