//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.3.0, Copyright (C) Peter A. Buhr 2005
// 
// ostream.h -- 
// 
// Author           : Peter A. Buhr
// Created On       : Thu Jul 28 14:42:29 2005
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue Sep 13 11:29:11 2005
// Update Count     : 39
// 
//
// This  library is free  software; you  can redistribute  it and/or  modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
// option) any later version.
// 
// This library is distributed in the  hope that it will be useful, but WITHOUT
// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
// for more details.
// 
// You should  have received a  copy of the  GNU Lesser General  Public License
// along  with this library.
// 


#include_next <ostream>

#ifndef __OSTREAM_H__
#define __OSTREAM_H__

#include <uFilebuf.h>


namespace std {

//######################### new stream manipulators/routines #########################


    template<class streamtype>
    class basic_acquire {
	typedef typename streamtype::char_type char_type;
	typedef typename streamtype::traits_type traits_type;

	streamtype &lockedStream;

	basic_acquire( const basic_acquire & );
	basic_acquire &operator=( const basic_acquire & );
      public:
	basic_acquire( streamtype &ios ) : lockedStream( ios ) {
#ifdef __U_DEBUG__
	    filebuf *buf = dynamic_cast<filebuf *>( ios.rdbuf() );
	    if ( buf == NULL ) {
		uAbort( "Attempt to acquire mutual exclusion for a non-concurrent stream." );
	    } // if
#else
	    filebuf *buf = (filebuf *)ios.rdbuf();
#endif // __U_DEBUG__
	    buf->ownerlock.acquire();
	} // basic_acquire

	~basic_acquire() {
	    ((filebuf *)lockedStream.rdbuf())->ownerlock.release();
	} // ~basic_acquire

	template< class datatype >
	streamtype &operator<<( const datatype &data ) {
	    return lockedStream << data;
	} // operator<<

	template< class datatype >
	streamtype &operator>>( const datatype &data ) {
	    return lockedStream >> data;
	} // operator>>

	template< class datatype >
	streamtype &operator<<( datatype &data ) {
	    return lockedStream << data;
	} // operator<<

	template< class datatype >
	streamtype &operator>>( datatype &data ) {
	    return lockedStream >> data;
	} // operator>>

	streamtype &operator<<( streamtype &(*__pf)(streamtype & ) ) {
	    return lockedStream << __pf;
	} // operator<<

	streamtype &operator>>( streamtype &(*__pf)(streamtype & ) ) {
	    return lockedStream >> __pf;
	} // operator>>

	streamtype &operator<<( basic_ios<char_type, traits_type> &(*__pf)(basic_ios<char_type, traits_type> & ) ) {
	    return lockedStream << __pf;
	} // operator<<

	streamtype &operator>>( basic_ios<char_type, traits_type> &(*__pf)(basic_ios<char_type, traits_type> & ) ) {
	    return lockedStream >> __pf;
	} // operator>>

	streamtype &operator<<( ios_base &(*__pf)(ios_base & ) ) {
	    return lockedStream << __pf;
	} // operator<<

	streamtype &operator>>( ios_base &(*__pf)(ios_base & ) ) {
	    return lockedStream >> __pf;
	} // operator>>
    }; // basic_acquire


    typedef basic_acquire<std::ostream> osacquire;
    typedef basic_acquire<std::istream> isacquire;


    template<class Ch, class Tr>
    basic_ios<Ch, Tr> &acquire( basic_ios<Ch, Tr> &os ) __attribute__((deprecated));

    template<class Ch, class Tr>
    basic_ios<Ch, Tr> &acquire( basic_ios<Ch, Tr> &os ) {
#ifdef __U_DEBUG__
	basic_filebuf<Ch, Tr> *buf = dynamic_cast<basic_filebuf<Ch, Tr> *>( os.rdbuf() );
	if ( buf == NULL ) {
	    uAbort( "Attempt to use acquire with non-concurrent stream." );
	} // if
#else
	basic_filebuf<Ch, Tr> *buf = (basic_filebuf<Ch, Tr> *)os.rdbuf();
#endif // __U_DEBUG__
	buf->ownerlock.acquire();
	return os;
    } // acquire


    template<class Ch, class Tr>
    basic_ios<Ch, Tr> &release( basic_ios<Ch, Tr> &os ) __attribute__((deprecated));

    template<class Ch, class Tr>
    basic_ios<Ch, Tr> &release( basic_ios<Ch, Tr> &os ) {
#ifdef __U_DEBUG__
	basic_filebuf<Ch, Tr> *buf = dynamic_cast<basic_filebuf<Ch, Tr> *>( os.rdbuf() );
	if ( buf == NULL ) {
	    uAbort( "Attempt to use release with non-concurrent stream." );
	} // if
#else
	basic_filebuf<Ch, Tr> *buf = (basic_filebuf<Ch, Tr> *)os.rdbuf();
#endif // __U_DEBUG__
	buf->ownerlock.release();
	return os;
    } // release


    template<class Ch, class Tr>
    uBaseTask *owner( basic_ios<Ch, Tr> &os ) __attribute__((deprecated));

    template<class Ch, class Tr>
    uBaseTask *owner( basic_ios<Ch, Tr> &os ) {
#ifdef __U_DEBUG__
	basic_filebuf<Ch, Tr> *buf = dynamic_cast<basic_filebuf<Ch, Tr> *>( os.rdbuf() );
	if ( buf == NULL ) {
	    uAbort( "Attempt to use owner with non-concurrent stream." );
	} // if
#else
	basic_filebuf<Ch, Tr> *buf = (basic_filebuf<Ch, Tr> *)os.rdbuf();
#endif // __U_DEBUG__
	return buf->ownerlock.owner();
    } // owner

} // namespace std


#endif // __OSTREAM_H__


// Local Variables: //
// compile-command: "gmake install" //
// End: //
