197403Sobrien// Iostreams base classes -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien//
3297403Sobrien// ISO C++ 14882: 27.4  Iostreams base classes
3397403Sobrien//
3497403Sobrien
3597403Sobrien#include <ios>
36132720Skan#include <limits>
3797403Sobrien
38169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
3997403Sobrien
4097403Sobrien  // Definitions for static const members of ios_base.
4197403Sobrien  const ios_base::fmtflags ios_base::boolalpha;
4297403Sobrien  const ios_base::fmtflags ios_base::dec;
4397403Sobrien  const ios_base::fmtflags ios_base::fixed;
4497403Sobrien  const ios_base::fmtflags ios_base::hex;
4597403Sobrien  const ios_base::fmtflags ios_base::internal;
4697403Sobrien  const ios_base::fmtflags ios_base::left;
4797403Sobrien  const ios_base::fmtflags ios_base::oct;
4897403Sobrien  const ios_base::fmtflags ios_base::right;
4997403Sobrien  const ios_base::fmtflags ios_base::scientific;
5097403Sobrien  const ios_base::fmtflags ios_base::showbase;
5197403Sobrien  const ios_base::fmtflags ios_base::showpoint;
5297403Sobrien  const ios_base::fmtflags ios_base::showpos;
5397403Sobrien  const ios_base::fmtflags ios_base::skipws;
5497403Sobrien  const ios_base::fmtflags ios_base::unitbuf;
5597403Sobrien  const ios_base::fmtflags ios_base::uppercase;
5697403Sobrien  const ios_base::fmtflags ios_base::adjustfield;
5797403Sobrien  const ios_base::fmtflags ios_base::basefield;
5897403Sobrien  const ios_base::fmtflags ios_base::floatfield;
5997403Sobrien
6097403Sobrien  const ios_base::iostate ios_base::badbit;
6197403Sobrien  const ios_base::iostate ios_base::eofbit;
6297403Sobrien  const ios_base::iostate ios_base::failbit;
6397403Sobrien  const ios_base::iostate ios_base::goodbit;
6497403Sobrien
6597403Sobrien  const ios_base::openmode ios_base::app;
6697403Sobrien  const ios_base::openmode ios_base::ate;
6797403Sobrien  const ios_base::openmode ios_base::binary;
6897403Sobrien  const ios_base::openmode ios_base::in;
6997403Sobrien  const ios_base::openmode ios_base::out;
7097403Sobrien  const ios_base::openmode ios_base::trunc;
7197403Sobrien
7297403Sobrien  const ios_base::seekdir ios_base::beg;
7397403Sobrien  const ios_base::seekdir ios_base::cur;
7497403Sobrien  const ios_base::seekdir ios_base::end;
7597403Sobrien
76132720Skan  _Atomic_word ios_base::Init::_S_refcount;
7797403Sobrien
78132720Skan  bool ios_base::Init::_S_synced_with_stdio = true;
7997403Sobrien
80132720Skan  ios_base::ios_base()
81132720Skan  : _M_precision(), _M_width(), _M_flags(), _M_exception(),
82132720Skan  _M_streambuf_state(), _M_callbacks(0), _M_word_zero(),
83132720Skan  _M_word_size(_S_local_word_size), _M_word(_M_local_word), _M_ios_locale()
8497403Sobrien  {
85132720Skan    // Do nothing: basic_ios::init() does it.
86132720Skan    // NB: _M_callbacks and _M_word must be zero for non-initialized
87132720Skan    // ios_base to go through ~ios_base gracefully.
8897403Sobrien  }
89132720Skan
90132720Skan  // 27.4.2.7  ios_base constructors/destructors
91132720Skan  ios_base::~ios_base()
9297403Sobrien  {
93132720Skan    _M_call_callbacks(erase_event);
94132720Skan    _M_dispose_callbacks();
95132720Skan    if (_M_word != _M_local_word)
9697403Sobrien      {
97132720Skan	delete [] _M_word;
98132720Skan	_M_word = 0;
9997403Sobrien      }
10097403Sobrien  }
10197403Sobrien
10297403Sobrien  // 27.4.2.5  ios_base storage functions
10397403Sobrien  int
10497403Sobrien  ios_base::xalloc() throw()
10597403Sobrien  {
10697403Sobrien    // Implementation note: Initialize top to zero to ensure that
10797403Sobrien    // initialization occurs before main() is started.
10897403Sobrien    static _Atomic_word _S_top = 0;
109169691Skan    return __gnu_cxx::__exchange_and_add_dispatch(&_S_top, 1) + 4;
11097403Sobrien  }
11197403Sobrien
112132720Skan  void
113132720Skan  ios_base::register_callback(event_callback __fn, int __index)
114132720Skan  { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
115132720Skan
11697403Sobrien  // 27.4.2.5  iword/pword storage
11797403Sobrien  ios_base::_Words&
118169691Skan  ios_base::_M_grow_words(int __ix, bool __iword)
11997403Sobrien  {
120169691Skan    // Precondition: _M_word_size <= __ix
121169691Skan    int __newsize = _S_local_word_size;
122169691Skan    _Words* __words = _M_local_word;
123169691Skan    if (__ix > _S_local_word_size - 1)
12497403Sobrien      {
125169691Skan	if (__ix < numeric_limits<int>::max())
12697403Sobrien	  {
127169691Skan	    __newsize = __ix + 1;
12897403Sobrien	    try
129169691Skan	      { __words = new _Words[__newsize]; }
13097403Sobrien	    catch (...)
13197403Sobrien	      {
13297403Sobrien		_M_streambuf_state |= badbit;
13397403Sobrien		if (_M_streambuf_state & _M_exception)
134132720Skan		  __throw_ios_failure(__N("ios_base::_M_grow_words "
135132720Skan				      "allocation failed"));
136169691Skan		if (__iword)
137132720Skan		  _M_word_zero._M_iword = 0;
138132720Skan		else
139132720Skan		  _M_word_zero._M_pword = 0;
14097403Sobrien		return _M_word_zero;
14197403Sobrien	      }
142169691Skan	    for (int __i = 0; __i < _M_word_size; __i++)
143169691Skan	      __words[__i] = _M_word[__i];
14497403Sobrien	    if (_M_word && _M_word != _M_local_word)
14597403Sobrien	      {
14697403Sobrien		delete [] _M_word;
14797403Sobrien		_M_word = 0;
14897403Sobrien	      }
14997403Sobrien	  }
15097403Sobrien	else
15197403Sobrien	  {
15297403Sobrien	    _M_streambuf_state |= badbit;
153117397Skan	    if (_M_streambuf_state & _M_exception)
154132720Skan	      __throw_ios_failure(__N("ios_base::_M_grow_words is not valid"));
155169691Skan	    if (__iword)
156132720Skan	      _M_word_zero._M_iword = 0;
157132720Skan	    else
158132720Skan	      _M_word_zero._M_pword = 0;
15997403Sobrien	    return _M_word_zero;
16097403Sobrien	  }
16197403Sobrien      }
162169691Skan    _M_word = __words;
163169691Skan    _M_word_size = __newsize;
164169691Skan    return _M_word[__ix];
16597403Sobrien  }
16697403Sobrien
16797403Sobrien  void
16897403Sobrien  ios_base::_M_call_callbacks(event __e) throw()
16997403Sobrien  {
17097403Sobrien    _Callback_list* __p = _M_callbacks;
17197403Sobrien    while (__p)
17297403Sobrien      {
17397403Sobrien	try
17497403Sobrien	  { (*__p->_M_fn) (__e, *this, __p->_M_index); }
17597403Sobrien	catch (...)
17697403Sobrien	  { }
17797403Sobrien	__p = __p->_M_next;
17897403Sobrien      }
17997403Sobrien  }
18097403Sobrien
18197403Sobrien  void
18297403Sobrien  ios_base::_M_dispose_callbacks(void)
18397403Sobrien  {
18497403Sobrien    _Callback_list* __p = _M_callbacks;
18597403Sobrien    while (__p && __p->_M_remove_reference() == 0)
18697403Sobrien      {
18797403Sobrien	_Callback_list* __next = __p->_M_next;
18897403Sobrien	delete __p;
18997403Sobrien	__p = __next;
19097403Sobrien      }
19197403Sobrien    _M_callbacks = 0;
19297403Sobrien  }
193169691Skan
194169691Skan_GLIBCXX_END_NAMESPACE
195