ios.cc revision 169691
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