# ios.cc

    00001 // Iostreams base classes -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    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.4  Iostreams base classes
    00033 //
    00034
    00035 #include <ios>
    00036 #include <limits>
    00037 #include <bits/atomicity.h>
    00038
    00039 namespace std
    00040 {
    00041   // Definitions for static const data members of __ios_flags.
    00042   const __ios_flags::__int_type __ios_flags::_S_boolalpha;
    00043   const __ios_flags::__int_type __ios_flags::_S_dec;
    00044   const __ios_flags::__int_type __ios_flags::_S_fixed;
    00045   const __ios_flags::__int_type __ios_flags::_S_hex;
    00046   const __ios_flags::__int_type __ios_flags::_S_internal;
    00047   const __ios_flags::__int_type __ios_flags::_S_left;
    00048   const __ios_flags::__int_type __ios_flags::_S_oct;
    00049   const __ios_flags::__int_type __ios_flags::_S_right;
    00050   const __ios_flags::__int_type __ios_flags::_S_scientific;
    00051   const __ios_flags::__int_type __ios_flags::_S_showbase;
    00052   const __ios_flags::__int_type __ios_flags::_S_showpoint;
    00053   const __ios_flags::__int_type __ios_flags::_S_showpos;
    00054   const __ios_flags::__int_type __ios_flags::_S_skipws;
    00055   const __ios_flags::__int_type __ios_flags::_S_unitbuf;
    00056   const __ios_flags::__int_type __ios_flags::_S_uppercase;
    00057   const __ios_flags::__int_type __ios_flags::_S_adjustfield;
    00058   const __ios_flags::__int_type __ios_flags::_S_basefield;
    00059   const __ios_flags::__int_type __ios_flags::_S_floatfield;
    00060
    00061   const __ios_flags::__int_type __ios_flags::_S_badbit;
    00062   const __ios_flags::__int_type __ios_flags::_S_eofbit;
    00063   const __ios_flags::__int_type __ios_flags::_S_failbit;
    00064
    00065   const __ios_flags::__int_type __ios_flags::_S_app;
    00066   const __ios_flags::__int_type __ios_flags::_S_ate;
    00067   const __ios_flags::__int_type __ios_flags::_S_bin;
    00068   const __ios_flags::__int_type __ios_flags::_S_in;
    00069   const __ios_flags::__int_type __ios_flags::_S_out;
    00070   const __ios_flags::__int_type __ios_flags::_S_trunc;
    00071
    00072   // Definitions for static const members of ios_base.
    00073   const ios_base::fmtflags ios_base::boolalpha;
    00074   const ios_base::fmtflags ios_base::dec;
    00075   const ios_base::fmtflags ios_base::fixed;
    00076   const ios_base::fmtflags ios_base::hex;
    00077   const ios_base::fmtflags ios_base::internal;
    00078   const ios_base::fmtflags ios_base::left;
    00079   const ios_base::fmtflags ios_base::oct;
    00080   const ios_base::fmtflags ios_base::right;
    00081   const ios_base::fmtflags ios_base::scientific;
    00082   const ios_base::fmtflags ios_base::showbase;
    00083   const ios_base::fmtflags ios_base::showpoint;
    00084   const ios_base::fmtflags ios_base::showpos;
    00085   const ios_base::fmtflags ios_base::skipws;
    00086   const ios_base::fmtflags ios_base::unitbuf;
    00087   const ios_base::fmtflags ios_base::uppercase;
    00088   const ios_base::fmtflags ios_base::adjustfield;
    00089   const ios_base::fmtflags ios_base::basefield;
    00090   const ios_base::fmtflags ios_base::floatfield;
    00091
    00092   const ios_base::iostate ios_base::badbit;
    00093   const ios_base::iostate ios_base::eofbit;
    00094   const ios_base::iostate ios_base::failbit;
    00095   const ios_base::iostate ios_base::goodbit;
    00096
    00097   const ios_base::openmode ios_base::app;
    00098   const ios_base::openmode ios_base::ate;
    00099   const ios_base::openmode ios_base::binary;
    00100   const ios_base::openmode ios_base::in;
    00101   const ios_base::openmode ios_base::out;
    00102   const ios_base::openmode ios_base::trunc;
    00103
    00104   const ios_base::seekdir ios_base::beg;
    00105   const ios_base::seekdir ios_base::cur;
    00106   const ios_base::seekdir ios_base::end;
    00107
    00108   const int ios_base::_S_local_word_size;
    00109
    00110   _Atomic_word ios_base::Init::_S_refcount;
    00111
    00112   bool ios_base::Init::_S_synced_with_stdio = true;
    00113
    00114   ios_base::ios_base()
    00115   : _M_precision(), _M_width(), _M_flags(), _M_exception(),
    00116   _M_streambuf_state(), _M_callbacks(0), _M_word_zero(),
    00117   _M_word_size(_S_local_word_size), _M_word(_M_local_word), _M_ios_locale()
    00118   {
    00119     // Do nothing: basic_ios::init() does it.
    00120     // NB: _M_callbacks and _M_word must be zero for non-initialized
    00121     // ios_base to go through ~ios_base gracefully.
    00122   }
    00123
    00124   // 27.4.2.7  ios_base constructors/destructors
    00125   ios_base::~ios_base()
    00126   {
    00127     _M_call_callbacks(erase_event);
    00128     _M_dispose_callbacks();
    00129     if (_M_word != _M_local_word)
    00130       {
    00131     delete [] _M_word;
    00132     _M_word = 0;
    00133       }
    00134   }
    00135
    00136   // 27.4.2.5  ios_base storage functions
    00137   int
    00138   ios_base::xalloc() throw()
    00139   {
    00140     // Implementation note: Initialize top to zero to ensure that
    00141     // initialization occurs before main() is started.
    00142     static _Atomic_word _S_top = 0;
    00143     return __gnu_cxx::__exchange_and_add(&_S_top, 1) + 4;
    00144   }
    00145
    00146   void
    00147   ios_base::register_callback(event_callback __fn, int __index)
    00148   { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
    00149
    00150   // 27.4.2.5  iword/pword storage
    00151   ios_base::_Words&
    00152   ios_base::_M_grow_words(int ix, bool iword)
    00153   {
    00154     // Precondition: _M_word_size <= ix
    00155     int newsize = _S_local_word_size;
    00156     _Words* words = _M_local_word;
    00157     if (ix > _S_local_word_size - 1)
    00158       {
    00159     if (ix < numeric_limits<int>::max())
    00160       {
    00161         newsize = ix + 1;
    00162         try
    00163           { words = new _Words[newsize]; }
    00164         catch (...)
    00165           {
    00166         _M_streambuf_state |= badbit;
    00167         if (_M_streambuf_state & _M_exception)
    00168           __throw_ios_failure(__N("ios_base::_M_grow_words "
    00169                       "allocation failed"));
    00170         if (iword)
    00171           _M_word_zero._M_iword = 0;
    00172         else
    00173           _M_word_zero._M_pword = 0;
    00174         return _M_word_zero;
    00175           }
    00176         for (int i = 0; i < _M_word_size; i++)
    00177           words[i] = _M_word[i];
    00178         if (_M_word && _M_word != _M_local_word)
    00179           {
    00180         delete [] _M_word;
    00181         _M_word = 0;
    00182           }
    00183       }
    00184     else
    00185       {
    00186         _M_streambuf_state |= badbit;
    00187         if (_M_streambuf_state & _M_exception)
    00188           __throw_ios_failure(__N("ios_base::_M_grow_words is not valid"));
    00189         if (iword)
    00190           _M_word_zero._M_iword = 0;
    00191         else
    00192           _M_word_zero._M_pword = 0;
    00193         return _M_word_zero;
    00194       }
    00195       }
    00196     _M_word = words;
    00197     _M_word_size = newsize;
    00198     return _M_word[ix];
    00199   }
    00200
    00201   void
    00202   ios_base::_M_call_callbacks(event __e) throw()
    00203   {
    00204     _Callback_list* __p = _M_callbacks;
    00205     while (__p)
    00206       {
    00207     try
    00208       { (*__p->_M_fn) (__e, *this, __p->_M_index); }
    00209     catch (...)
    00210       { }
    00211     __p = __p->_M_next;
    00212       }
    00213   }
    00214
    00215   void
    00216   ios_base::_M_dispose_callbacks(void)
    00217   {
    00218     _Callback_list* __p = _M_callbacks;
    00219     while (__p && __p->_M_remove_reference() == 0)
    00220       {
    00221     _Callback_list* __next = __p->_M_next;
    00222     delete __p;
    00223     __p = __next;
    00224       }
    00225     _M_callbacks = 0;
    00226   }
    00227 } // namespace std