sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #ifndef _MMRCUTIL_H_
sl@0: #define _MMRCUTIL_H_
sl@0: 
sl@0: #include <e32base.h>
sl@0: 
sl@0: template <class T>
sl@0: class RMMRCFifoQueue
sl@0: 	{
sl@0: public:
sl@0: 	RMMRCFifoQueue( );
sl@0: 	~RMMRCFifoQueue( );
sl@0: 
sl@0: 	void Reset( );
sl@0: 	void ResetAndDestroy();
sl@0: 	TBool IsEmpty( ) const;
sl@0: 	TInt Count() const;
sl@0: 	T* PopAndRemove( );
sl@0: 	T* PopAndRemove( TInt aIndex );
sl@0: 	void PushL( T const* const  aElement );
sl@0: 	T* Pop( ) const;
sl@0: 	T* Pop( TInt aIndex ) const;
sl@0: 	T* operator[] ( TInt aIndex ) const;
sl@0: 
sl@0: private:
sl@0: 	RMMRCFifoQueue( const RMMRCFifoQueue & aMMRCFifoQueue ); //not implemented
sl@0: 	const RMMRCFifoQueue & operator= ( const RMMRCFifoQueue & aMMRCFifoQueue );  //not implemented
sl@0: 
sl@0: private:
sl@0: 	struct TListNode
sl@0: 		{
sl@0: 		T const*  iElement;
sl@0: 		TListNode *iNext;
sl@0: 
sl@0: 		TListNode( T const* const aElement )
sl@0: 		: iElement( aElement ), iNext(NULL) { }
sl@0: 		};
sl@0: 
sl@0: 	TListNode *iFirst;
sl@0: 	TListNode *iLast;
sl@0: 	TInt iCount;
sl@0: 	};
sl@0: 	
sl@0: /**
sl@0:  Construct the queue.
sl@0: */
sl@0: template <class T>
sl@0: RMMRCFifoQueue<T>::RMMRCFifoQueue( )
sl@0: 	{
sl@0: 	iFirst = iLast = NULL;
sl@0: 	iCount = 0;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Destructor.
sl@0: */
sl@0: template <class T>
sl@0: RMMRCFifoQueue<T>::~RMMRCFifoQueue( )
sl@0: 	{
sl@0: 	Reset( );
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Delete each node without deleting the elements.
sl@0: */
sl@0: template <class T>
sl@0: void RMMRCFifoQueue<T>::Reset( )
sl@0: 	{
sl@0: 	while( !IsEmpty( ) )
sl@0: 		{
sl@0: 		PopAndRemove( );
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Delete each node and each element.
sl@0: */
sl@0: template <class T>
sl@0: void RMMRCFifoQueue<T>::ResetAndDestroy( )
sl@0: 	{
sl@0: 	while( !IsEmpty( ) )
sl@0: 		{
sl@0: 		T* element = PopAndRemove( );
sl@0: 		delete element;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Return the number of elements.
sl@0: */
sl@0: template <class T>
sl@0: TInt RMMRCFifoQueue<T>::Count( ) const
sl@0: 	{
sl@0: 	return iCount;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Test if the queue is logically empty.
sl@0:  Return TTrue if empty, TFalse, otherwise.
sl@0: */
sl@0: template <class T>
sl@0: TBool RMMRCFifoQueue<T>::IsEmpty( ) const
sl@0: 	{
sl@0: 	return iFirst == NULL;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Return and remove the least recently inserted item from the queue.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoQueue<T>::PopAndRemove( )
sl@0: 	{
sl@0: 	T* element = NULL;
sl@0: 	if( !IsEmpty( ) )
sl@0: 		{
sl@0: 		TListNode* front = iFirst;
sl@0: 		element = const_cast<T*>(iFirst->iElement);
sl@0: 		iFirst = iFirst->iNext;
sl@0: 		if( NULL == iFirst )
sl@0: 			{
sl@0: 			iLast = NULL;
sl@0: 			}
sl@0: 		iCount--;
sl@0: 		delete front;
sl@0: 		front = NULL;
sl@0: 		}
sl@0: 	return element;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Return and remove the least recently inserted item from the queue.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoQueue<T>::PopAndRemove( TInt aIndex )
sl@0: 	{
sl@0: 	T* element = NULL;
sl@0: 	TListNode* PreviousNode = NULL;
sl@0: 	TListNode* node = iFirst;
sl@0: 	TInt i = 0;
sl@0: 	for( ; i<aIndex && i<iCount && node->iNext ; i++)
sl@0: 		{
sl@0: 		PreviousNode = node;
sl@0: 		node = node->iNext;
sl@0: 		}
sl@0: 	
sl@0: 	if(node && i < iCount)
sl@0: 		{
sl@0: 		if(PreviousNode)
sl@0: 			{
sl@0: 			PreviousNode->iNext = node->iNext;
sl@0: 			if( NULL == node->iNext )
sl@0: 				{
sl@0: 				iLast = PreviousNode;
sl@0: 				}
sl@0: 			}
sl@0: 		else 
sl@0: 			{
sl@0: 			iFirst = node->iNext;
sl@0: 			if( NULL == iFirst )
sl@0: 				{
sl@0: 				iLast = NULL;
sl@0: 				} 
sl@0: 			}
sl@0: 		element = const_cast<T*>(node->iElement);
sl@0: 		iCount--;
sl@0: 		delete node;
sl@0: 		}
sl@0: 	return element;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Insert aElement into the queue.
sl@0: */
sl@0: template <class T>
sl@0: void RMMRCFifoQueue<T>::PushL( T const* const aElement )
sl@0: 	{
sl@0: 	if( IsEmpty( ) )
sl@0: 		{
sl@0: 		iLast = iFirst = new(ELeave) TListNode( aElement );
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		iLast = iLast->iNext = new(ELeave) TListNode( aElement );
sl@0: 		}
sl@0: 	iCount++;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Pop a pointer of the aIndex elements.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoQueue<T>::Pop ( ) const
sl@0: 	{
sl@0: 	T* element = NULL;
sl@0: 	TListNode* node = iFirst;
sl@0: 	
sl@0: 	if( node )
sl@0: 		{
sl@0: 		element = const_cast<T*>(node->iElement);
sl@0: 		}
sl@0: 	
sl@0: 	return element;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Pop a pointer of the aIndex elements.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoQueue<T>::Pop ( TInt aIndex ) const
sl@0: 	{
sl@0: 	T* element = NULL;
sl@0: 	TListNode* node = iFirst;
sl@0: 	
sl@0: 	TInt i = 0;
sl@0: 	for( ; (i < aIndex) && (i < iCount) && (node->iNext != NULL) ; i++)
sl@0: 		{
sl@0: 		node = node->iNext;
sl@0: 		}
sl@0: 	
sl@0: 	if(  ( NULL != node ) 
sl@0: 			&& ( i < iCount )  )
sl@0: 		{
sl@0: 		element = const_cast<T*>(node->iElement);
sl@0: 		}
sl@0: 	
sl@0: 	return element;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Pop a pointer of the aIndex elements.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoQueue<T>::operator[] ( TInt aIndex ) const
sl@0: 	{
sl@0: 	return Pop(aIndex);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Class for manage the list of the sessions requesting pause.
sl@0: */
sl@0: template <class T>
sl@0: class RMMRCFifoOrderQueue : private RMMRCFifoQueue <T>
sl@0: 	{
sl@0: 
sl@0: public:
sl@0: 	RMMRCFifoOrderQueue( );
sl@0: 	~RMMRCFifoOrderQueue( );
sl@0: 	void ResetAndDestroy( );
sl@0: 	TInt Count() const;
sl@0: 	void PushL( T const* const  aElement );
sl@0: 	T* PopAndRemoveForPause( TInt aIndex );
sl@0: 	T* operator[] ( TInt aIndex ) const;
sl@0: 
sl@0: 
sl@0: private:
sl@0: 	RPointerArray< T >  iQueue;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Construct the queue.
sl@0: */
sl@0: template <class T>
sl@0: RMMRCFifoOrderQueue<T>::RMMRCFifoOrderQueue( )
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Destructor.
sl@0: */
sl@0: template <class T>
sl@0: RMMRCFifoOrderQueue<T>::~RMMRCFifoOrderQueue( )
sl@0: 	{
sl@0: 	iQueue.Reset();
sl@0: 	iQueue.Close();
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:  Return the number of elements.
sl@0: */
sl@0: template <class T>
sl@0: TInt RMMRCFifoOrderQueue<T>::Count( ) const
sl@0: 	{
sl@0: 	
sl@0: 	TInt iNum = iQueue.Count();
sl@0: 	return iNum;
sl@0: 	}	
sl@0: 
sl@0: /**
sl@0:  Delete each node and each element.
sl@0: */
sl@0: template <class T>
sl@0: void RMMRCFifoOrderQueue<T>::ResetAndDestroy( )
sl@0: 	{
sl@0: 	iQueue.ResetAndDestroy();
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  Insert aElement into the queue and ordered.
sl@0: */
sl@0: template <class T>
sl@0: void RMMRCFifoOrderQueue<T>::PushL( T const* const aElement )
sl@0: 	{
sl@0: 	TInt numElements = iQueue.Count();
sl@0: 	
sl@0: 	if( numElements == 0 )
sl@0: 		{
sl@0: 		iQueue.Append(aElement); //iQueue: We need to check the error here
sl@0: 		return;
sl@0: 		}
sl@0: 	
sl@0: 	for(TInt i(0); i<numElements ; ++i)
sl@0: 		{
sl@0: 		if(aElement->HasMultimediaCapability() && !(iQueue[i]->HasMultimediaCapability()))
sl@0: 			{
sl@0: 			iQueue.Insert(aElement, i);
sl@0: 			return;
sl@0: 			}
sl@0: 		else if(aElement->HasMultimediaCapability() == iQueue[i]->HasMultimediaCapability())	
sl@0: 			{
sl@0: 			if (aElement->GetPriority() > iQueue[i]->GetPriority())
sl@0: 			 	{
sl@0: 				iQueue.Insert(aElement,i);
sl@0: 				return;
sl@0: 			 	}			
sl@0: 			}
sl@0: 		}
sl@0: 	iQueue.Insert(aElement,numElements);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:  Return and remove the inserted item from the queue.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoOrderQueue<T>::PopAndRemoveForPause( TInt aIndex )
sl@0: 	{
sl@0: 	T* aux = NULL;
sl@0: 	aux = iQueue[aIndex];
sl@0: 	iQueue.Remove(aIndex);	
sl@0: 	return aux;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  Pop a pointer of the aIndex elements.
sl@0: */
sl@0: template <class T>
sl@0: T* RMMRCFifoOrderQueue<T>::operator[] ( TInt aIndex ) const
sl@0: 	{
sl@0: 	if(iQueue.Count() != 0)
sl@0: 		{
sl@0: 		return iQueue[aIndex];
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		return NULL;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: #endif /*_MMRCUTIL_H_*/