/*************************************************************************
 *
 *  $RCSfile: queue.inl,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000/09/18 15:18:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/


#include <vos/diagnose.hxx>

template<class TELEMENT>
OQueue<TELEMENT>::OQueue(sal_Int32 capacity)
{
	m_Capacity= capacity;

	if(m_Capacity != Infinite)
	{
		// initial state is not full (m_Capacity acquires are possible)
		m_notFull.create(m_Capacity);
	}

	// initial state is empty
	m_notEmpty.create(0);
}


template<class TELEMENT>
inline OQueue<TELEMENT>::~OQueue()
{
	while(!isEmpty())
	{
		removeHead();
	}

}

// returns True is getLength() is 0
template<class TELEMENT>
inline sal_Bool OQueue<TELEMENT>::isEmpty() const
{
	NAMESPACE_VOS(OGuard) Guard(&((OQueue<TELEMENT>*)this)->m_Lock);	// cast const away
	return m_Queue.empty();
}


template<class TELEMENT>
inline sal_Bool  OQueue<TELEMENT>::isFull() const
{
	if(m_Capacity == Infinite)
	{
		return sal_False;
	}

	NAMESPACE_VOS(OGuard) Guard(&((OQueue<TELEMENT>*)this)->m_Lock);
	VOS_ASSERT(m_Capacity >= 0);
	return m_Queue.size() >= (sal_uInt32)m_Capacity;
}


template<class TELEMENT>
inline sal_Int32  OQueue<TELEMENT>::getCapacity() const
{
	return m_Capacity;
}


template<class TELEMENT>
inline sal_uInt32  OQueue<TELEMENT>::getLength() const
{
	NAMESPACE_VOS(OGuard) Guard(&((OQueue<TELEMENT>*)this)->m_Lock);	// cast const away
	return m_Queue.size();
}


template<class TELEMENT>
inline void  OQueue<TELEMENT>::addTail(const TELEMENT& element) 
{

	// wait till queue has room (i.e. is not full)
	if(m_Capacity != Infinite) 
	{
		m_notFull.acquire();
	}

	m_Lock.acquire();

	m_Queue.push_back(element);


	// mark queue as not empty,since it contains at least one element now
	m_notEmpty.release();

	m_Lock.release();
}


template<class TELEMENT>
TELEMENT OQueue<TELEMENT>::getHead() 
{
	TELEMENT element;
		
	// wait till queue contains data (i.e. is not empty)
	m_notEmpty.acquire();

	m_Lock.acquire();
	element= m_Queue.front();
	m_Queue.pop_front();

	// mark queue as not full, since there must be room now for 
	// at least one element
	if(m_Capacity != Infinite) 
	{
		m_notFull.release();
	}


	m_Lock.release();

	return element;
}


template<class TELEMENT>
inline void  OQueue<TELEMENT>::removeHead() 
{

	// try to acquire an element from the queue
	if(!m_notEmpty.tryToAcquire()) 
	{
		// queue empty => nothing to remove
		return;
	}

	m_Lock.acquire();
	sal_uInt32 oldSize= m_Queue.size();

	m_Queue.pop_front();

	if(oldSize == m_Queue.size()+1)  // successful remove
	{
		// mark queue as not full, since there must be room now for at least one element
		if(m_Capacity != Infinite) 
		{
			m_notFull.release();
		}
	}

	m_Lock.release();

}



template<class TELEMENT>
inline void  OQueue<TELEMENT>::remove(const TELEMENT& element) 
{
		
	// try to acquire an element from the queue
	if(!m_notEmpty.tryToAcquire()) 
	{
		// queue empty => nothing to remove
		return;
	}

	m_Lock.acquire();
	sal_uInt32 oldSize= m_Queue.size();

	m_Queue.remove(element);

	if(oldSize == m_Queue.size()+1)  // successful remove
	{
		// mark queue as not full, since there must be room now for at least one element
		if(m_Capacity != Infinite) 
		{
			m_notFull.release();
		}
	}

	m_Lock.release();

}

