# 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