/**************************************************************************
 *
 * iostore.cpp - source of the C++ Standard Library 
 *               ios_base storage functions [lib.ios.base.storage]
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <string.h>        // memcpy(), memset()
#include <rw/_rawiter.h>   // get_temporary_buffer()

#include "iosdata.h"

#include <rw/_defs.h>


_RWSTD_NAMESPACE (__rw) {


// will grow an array of POD elements, never shrinks
static void*
__rw_realloc (void *array, _RWSTD_SIZE_T size, _RWSTD_SIZE_T &n, int inx)
{
    if (inx < 0)
        return 0;   // bad index

    if (_RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < n)
        return array;   // no need to reallocate

    void *tmp;

    _TRY {
        // make sure index is dereferencable (cast prevents HP aCC warnings)
        tmp = operator new (_RWSTD_STATIC_CAST (_RWSTD_SIZE_T, ++inx) * size);
    }
    _CATCH (...) {
        return 0;
    }

    _RWSTD_ASSERT (0 != tmp);

    // copy elements from array to tmp
    if (array)
        memcpy (tmp, array, n * size);

    // zero out newly allocated storage
    memset (_RWSTD_STATIC_CAST (char*, tmp) + n * size, 0, (inx - n) * size);

    // modify passed-in size
    n = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx);

    operator delete (array);

    return tmp;
}


}   // namespace __rw


_RWSTD_NAMESPACE (std) {


/* static */ int ios_base::xalloc ()
{
    // outlined to hide implementation details

    static int inx /* = 0 */;

    return _RWSTD_ATOMIC_PREINCREMENT (inx, false) - 1;
}


void ios_base::_C_fire_event (event ev, bool reentrant)
{
    if (!_C_usr)
        return;

    _C_usr_data::_C_event_cb *cba    = _C_usr->_C_cbarray;
    _RWSTD_SIZE_T             cbsize = _C_usr->_C_cbsize;

    // verify consistency (either both are 0 or neither is)
    _RWSTD_ASSERT (!!cba == !!cbsize);

    if (!cba)
        return;

    // caller expected to lock if necessary

    _TRY {
        // protect `cba' from an exception (copy only necessary
        // when `reentrant' is non-zero in which case we unlock
        // the mutex and allow registered callbacks to call the
        // stream member functions recursively)
        if (reentrant) {
            // never throws
            cba = _GET_TEMP_BUFFER (_C_usr_data::_C_event_cb, cbsize).first;

            if (!cba) {
                // clear may throw...
                _C_set (_C_state | badbit, _C_except | _RW::__rw_nolock,
                        _C_rdbuf);
                return;
            }

            // verify consistency (neither must be 0 at this point)
            _RWSTD_ASSERT (_C_usr->_C_cbarray && _C_usr->_C_cbsize);

            // copy into temporary buffer
            memcpy (cba, _C_usr->_C_cbarray, cbsize * sizeof *cba);

            // unlock only if stream state allows it
            if (!(flags () & _RW::__rw_nolock))
                _C_unlock ();
        }

        // 27.4.2.6, p1 - call callbacks in opposite order of registration
        for (_RWSTD_SIZE_T i = cbsize; i-- > 0; ) {

            _RWSTD_ASSERT (cba && cba [i]._C_fn);

            // ok if callback calls locking functions, we're unlocked
            // and working with a local copy of callack array
            cba [i]._C_fn (ev, *this, cba [i]._C_index);
        }

        if (reentrant) {
            return_temporary_buffer (cba);

            // lock only if stream state allows it (stream state
            // may have been modified by one of the callbacks)
            if (!(flags () & _RW::__rw_nolock))
                _C_lock ();
        }
    }
    _CATCH (...) {
        if (reentrant) {
            return_temporary_buffer (cba);

            // lock only if `cba' was successfully allocated (or copied)
            // and the stream state allows it (stream state may have been
            // modified by one of the callbacks)
            if (cba && !(flags () & _RW::__rw_nolock))
                _C_lock ();
        }
        _RETHROW;
    }
}


// succeeds irrespective of rdstate()
void ios_base::
_C_copyfmt (const ios_base &rhs,
            void *dst, const void *src, _RWSTD_SIZE_T size)
{
    if (this == &rhs)
        return;

    typedef _C_usr_data::_C_event_cb EventCB;

    // allocate sufficient storage
    long    *ia  = 0;
    void*   *pa  = 0;
    EventCB *cba = 0;

    _RWSTD_SIZE_T a_size [3];    // sizes of arrays above

    unsigned   fmtfl;    // formatting flags
    streamsize prec;     // new precision
    streamsize wide;     // new width
    unsigned   except;   // new exceptions

    char srcbuf [16];    // buffer to copy `src' to

    // flags to copy from `rhs'
    const fmtflags flagmask = ~(_RW::__rw_nolock | _RW::__rw_nolockbuf);

    _TRY {
        // lock `rhs', *this not locked yet
        _RWSTD_MT_GUARD (rhs.flags () & _RW::__rw_nolock
                         ? 0 : &_RWSTD_CONST_CAST (ios_base&, rhs)._C_mutex);

        if (rhs._C_usr) {

            // for convenience
            const _C_usr_data* const rusr = rhs._C_usr;

            // verify that either both are 0 or neither is
            _RWSTD_ASSERT (!!rusr->_C_iarray == !!rusr->_C_isize);
            _RWSTD_ASSERT (!!rusr->_C_parray == !!rusr->_C_psize);
            _RWSTD_ASSERT (!!rusr->_C_cbarray == !!rusr->_C_cbsize);

            a_size [0] = rusr->_C_isize;
            a_size [1] = rusr->_C_psize;
            a_size [2] = rusr->_C_cbsize;
                
            ia = _RWSTD_STATIC_CAST (long*,
                     a_size [0] ? operator new (a_size [0] * sizeof *ia) : 0);

            pa = _RWSTD_STATIC_CAST (void**,
                     a_size [1] ? operator new (a_size [1] * sizeof *pa) : 0);

            cba = _RWSTD_STATIC_CAST (EventCB*,
                     a_size [2] ? operator new (a_size [2] * sizeof *cba) : 0);

            // copy rhs into allocated storage and assign (27.4.4.2, p15)
            memcpy (ia,  rusr->_C_iarray,  a_size [0] * sizeof *ia);
            memcpy (pa,  rusr->_C_parray,  a_size [1] * sizeof *pa);
            memcpy (cba, rusr->_C_cbarray, a_size [2] * sizeof *cba);
        }
        else {
            // zero out array to prevent (bogus) gcc warnings
            // about the variable being used uninitialized
            memset (a_size, 0, sizeof a_size);
        }

        // copy the rest of rhs state (save for exceptions)
        // while it's locked to guarantee atomicity
        fmtfl  = rhs._C_fmtfl;
        prec   = rhs._C_prec;
        wide   = rhs._C_wide;
        except = rhs._C_except;

        // copy additional data (rhs's fill char) to the small
        // temporary buffer only if it fits
        if (size <= sizeof srcbuf)
            src = memcpy (srcbuf, src, size);
    }
    _CATCH (...) {
        // *this is unmodified
        operator delete (ia);
        operator delete (pa);
        operator delete (cba);

        _RETHROW;
    }

    // `rhs' unlocked, lock *this
    _RWSTD_MT_GUARD (flags () & _RW::__rw_nolock ? 0 : &_C_mutex);

    _TRY {
        if (_C_usr) {
            // fire erase events (27.4.4.2, p17) - may throw
            if (_C_usr->_C_fire)
                (this->*_C_usr->_C_fire)(erase_event, true /* reentrant */);

            // delete existing arrays, if any; _C_usr will only be deleted
            // if `rhs' contains no user data (see below)
            operator delete (_C_usr->_C_iarray);
            operator delete (_C_usr->_C_parray);
            operator delete (_C_usr->_C_cbarray);
        }
        else if (ia || pa || cba) {
            // allocation may throw
            _C_usr = new _C_usr_data ();

#ifdef _RWSTD_NO_POD_ZERO_INIT

#  ifdef _RWSTD_NO_NEW_THROWS

            if (!_C_usr)
                _RW::__rw_throw (_RWSTD_ERROR_FIRST + 3 /* BAD_ALLOC */);

#  endif   // _RWSTD_NO_NEW_THROWS

            _RWSTD_ASSERT (0 != _C_usr);
            memset (_C_usr, 0, sizeof *_C_usr);

#endif   // _RWSTD_NO_POD_ZERO_INIT

        }
    }
    _CATCH (...) {
        // *this is unmodified
        operator delete (ia);
        operator delete (pa);
        operator delete (cba);

        _RETHROW;
    }

    if (ia || pa || cba) {

        // assing allocated and copied arrays and their sizes
        _C_usr->_C_iarray  = ia;
        _C_usr->_C_parray  = pa;
        _C_usr->_C_cbarray = cba;

        _C_usr->_C_isize   = a_size [0];
        _C_usr->_C_psize   = a_size [1];
        _C_usr->_C_cbsize  = a_size [2];

        _C_usr->_C_fire    = &ios_base::_C_fire_event;
    }
    else {
        // `rhs' contains no user data, delete _C_usr
        _C_usr_data::_C_dealloc (_C_usr);
        _C_usr = 0;
    }

    // copy all but masked flags(), leave masked flags alone
    _C_fmtfl = fmtfl & flagmask | _C_fmtfl & ~flagmask;
    _C_prec  = prec;
    _C_wide  = wide;

    // copy additional data (fill character) -- will be atomic
    // only if size is sufficiently small; since this is used
    // for the fill character represented in derived classes
    // as int_type this will be true for all standard iostreams
    memcpy (dst, src, size);

    if (_C_usr && _C_usr->_C_fire) {
        _TRY {
            // fire copy events (27.4.4.2, p17), may temporarily unlock
            // or throw
            (this->*_C_usr->_C_fire)(copyfmt_event, true /* reentrant */);
        }
        _CATCH (...) {
            // must still assign exceptions
            _C_except = except;

            // just rethrow caught exception (don't call clear())
            _RETHROW;
        }
    }

    // assign exceptions last (27.4.4.2, p15, bullet 2)
    _C_except = except;

    // leave state alone but throw an exception if necessary
    _C_set (_C_state, _C_except | _RW::__rw_nolock, _C_rdbuf);
}


long& ios_base::iword (int inx)
{
    _RWSTD_MT_GUARD (flags () & _RW::__rw_nolock ? 0 : &_C_mutex);

    if (!_C_usr)
        _C_usr = _C_usr_data::_C_alloc (&ios_base::_C_fire_event);

    long* const ia = _C_usr
        ? _RWSTD_STATIC_CAST (long*, _RW::__rw_realloc (_C_usr->_C_iarray,
                                                        sizeof (long),
                                                        _C_usr->_C_isize,
                                                        inx))
        : 0;

    if (ia) {
        _RWSTD_ASSERT (  _C_usr->_C_isize
                       > _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx));

        return (_C_usr->_C_iarray = ia)[inx];
    }

    _C_set (_C_state | badbit, _C_except | _RW::__rw_nolock, _C_rdbuf);

    // returns a reference to a dummy object on failure (27.4.2.5, p3)
    static long dummy_iword;

    return dummy_iword = 0;
}


void*& ios_base::pword (int inx)
{ 
    _RWSTD_MT_GUARD (flags () & _RW::__rw_nolock ? 0 : &_C_mutex);

    if (!_C_usr)
        _C_usr = _C_usr_data::_C_alloc (&ios_base::_C_fire_event);

    void** const pa = _C_usr
        ? _RWSTD_STATIC_CAST (void**, _RW::__rw_realloc (_C_usr->_C_parray,
                                                         sizeof (void*),
                                                         _C_usr->_C_psize,
                                                         inx))
        : 0;

    if (pa) {
        _RWSTD_ASSERT (  _C_usr->_C_psize
                       > _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx));

        return (_C_usr->_C_parray = pa)[inx];
    }

    _C_set (_C_state | badbit, _C_except | _RW::__rw_nolock, _C_rdbuf);

    // returns a reference to a dummy object on failure (27.4.2.5, p3)
    static void *dummy_pword;

    return dummy_pword = 0;
}


void ios_base::
register_callback (event_callback fun, int inx)
{
    _RWSTD_ASSERT (0 != fun);

    _RWSTD_MT_GUARD (flags () & _RW::__rw_nolock ? 0 : &_C_mutex);

    if (!_C_usr)
        _C_usr = _C_usr_data::_C_alloc (&ios_base::_C_fire_event);

    typedef _C_usr_data::_C_event_cb EventCB;

    _RWSTD_SIZE_T  sz  = 0;
    EventCB       *cba = 0;

    if (_C_usr) {
        sz  = _C_usr->_C_cbsize;
        cba = _RWSTD_STATIC_CAST (EventCB*,
                                  _RW::__rw_realloc (_C_usr->_C_cbarray,
                                                     sizeof (EventCB),
                                                     _C_usr->_C_cbsize,
                                                     int (sz)));
    }

    if (cba) {
        // array must have grown by at least one element
        _RWSTD_ASSERT (sz < _C_usr->_C_cbsize);

        _C_usr->_C_cbarray = cba;

        _C_usr->_C_cbarray [sz]._C_index = inx;
        _C_usr->_C_cbarray [sz]._C_fn    = fun;
    }
    else {
        // not required by 27.4.2.6
        _C_set (_C_state | badbit, _C_except | _RW::__rw_nolock, _C_rdbuf);
    }
}


}   // namespace std
