kernel/eka/euser/us_que.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_que.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,852 @@
+// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\euser\us_que.cpp
+// 
+//
+
+#include "us_std.h"
+
+EXPORT_C void TSglQueLink::Enque(TSglQueLink* aLink)
+//
+// Enque this after aLink.
+//
+	{
+
+	iNext=aLink->iNext;
+	aLink->iNext=this;
+	}
+
+
+
+
+EXPORT_C void TDblQueLinkBase::Enque(TDblQueLinkBase* aLink)
+/** 
+Inserts this link object after the specified link object.
+
+The specified link object must already be in the doubly linked list.
+
+The function cannot be used to insert a list element into the beginning or 
+end of a doubly linked list; this is handled by the TDblQue::AddFirst() 
+and TDblQue::AddLast() functions.
+
+@param aLink A pointer to the link object embedded within the list element 
+             to which this link object is to be connected. It must not be NULL.
+              
+@see TDblQue
+*/
+	{
+
+	iNext=aLink->iNext;
+	iPrev=aLink;
+	aLink->iNext->iPrev=this;
+	aLink->iNext=this;
+	}
+
+
+
+
+EXPORT_C void TDblQueLinkBase::AddBefore(TDblQueLinkBase* aLink)
+/**
+Inserts this link object before the specified link object.
+
+The specified link object must already be in the doubly linked list.
+
+The function cannot be used to insert a list element into the beginning or 
+end of a doubly linked list; this is handled by the TDblQue::AddFirst() 
+and TDblQue::AddLast() functions.
+
+@param aLink A pointer to the link object embedded within the list element 
+             to which this link object is to be connected. It must not be NULL.
+              
+@see TDblQue
+*/
+	{
+
+	iNext=aLink;
+	iPrev=aLink->iPrev;
+	aLink->iPrev->iNext=this;
+	aLink->iPrev=this;
+	}
+
+
+
+
+EXPORT_C void TDblQueLink::Deque()
+/**
+Removes this link object from the doubly linked list.
+
+In effect, this removes the list element that acts as host to this link object
+from the doubly linked list.
+
+The link object can be any in the doubly linked list.
+
+It is safe to use this method on an object which has already been removed from the list.
+
+@post iNext member is set to NULL
+*/
+	{
+
+	if (iNext)
+		{
+	    iPrev->iNext=iNext;
+		iNext->iPrev=iPrev;
+		iNext=NULL;
+		}
+	}
+
+
+
+
+EXPORT_C TSglQueBase::TSglQueBase()
+	: iHead(NULL),iLast((TSglQueLink*)&iHead),iOffset(0)
+/**
+Default constructor.
+
+It sets:
+
+1. iHead to Null.
+
+2. iLast to point to the head  of queue.
+
+3. iOffset to zero.
+
+@see iHead
+@see iLast
+@see iOffset
+*/
+	{}
+
+
+
+
+EXPORT_C TSglQueBase::TSglQueBase(TInt aOffset)
+	: iHead(NULL),iLast((TSglQueLink*)&iHead),iOffset(aOffset)
+/**
+Constructor with specified offset.
+
+It sets:
+
+1. iHead to Null
+
+2. iLast to point to the head of queue.
+
+3. iOffset to the specified value.
+
+@param aOffset The offset of a link object within an element.
+
+@panic USER 75, if aOffset is not divisible by four
+
+@see iHead
+@see iLast
+@see iOffset
+*/
+	{
+
+	__ASSERT_ALWAYS(iOffset%4==0,Panic(ESQueOffsetNotAligned));
+	}
+
+
+
+
+EXPORT_C TBool TSglQueBase::IsEmpty() const
+/**
+Tests whether the singly linked list is empty, i.e. has no list elements.
+
+@return True, if the singly linked list is empty; false, otherwise.
+*/
+	{
+
+	return(iHead==NULL);
+	}
+
+
+
+
+EXPORT_C void TSglQueBase::SetOffset(TInt aOffset)
+/**
+Sets the offset of the link object from the start of a singly linked
+list element.
+
+@param aOffset The offset of the link object from the start of a singly linked 
+               list element.
+               
+@panic USER 75, if aOffset is not divisible by four.              
+
+@see TSglQue
+*/
+	{
+
+	__ASSERT_ALWAYS(iOffset%4==0,Panic(ESQueOffsetNotAligned));
+	iOffset=aOffset;
+	}
+
+
+
+
+
+EXPORT_C void TSglQueBase::Reset()
+/**
+Empties the singly linked list.
+
+After a call to this function, there are no elements queued from the header; 
+the elements are orphaned. Special care must be taken when list elements are 
+CBase derived objects, i.e. are allocated on the heap.
+*/
+	{
+	
+	iHead=NULL;
+	iLast=(TSglQueLink*)&iHead;
+	}
+
+
+
+
+
+EXPORT_C void TSglQueBase::DoAddFirst(TAny* aPtr)
+/**
+Implements the insertion of a list element at the front of the singly linked 
+list.
+
+This function is called by TSglQue::AddFirst().
+
+@param aPtr An untyped pointer to the element to be inserted.
+
+@see TSglQue::AddFirst
+*/
+	{
+
+	TSglQueLink* pL=PtrAdd((TSglQueLink*)aPtr,iOffset);
+	pL->Enque((TSglQueLink*)&iHead);
+	if (iLast==(TSglQueLink*)(&iHead))
+		iLast=pL;
+	}
+
+
+
+
+EXPORT_C void TSglQueBase::DoAddLast(TAny* aPtr)
+/**
+Implements the insertion of a list element at the back of the singly linked 
+list.
+
+This function is called by TSglQue::AddLast().
+
+@param aPtr An untyped pointer to the element to be inserted.
+
+@see TSglQue::AddLast
+*/
+	{
+
+	TSglQueLink* pL=PtrAdd((TSglQueLink*)aPtr,iOffset);
+	pL->Enque(iLast);
+	iLast=pL;
+	}
+
+
+
+
+EXPORT_C void TSglQueBase::DoRemove(TAny* aPtr)
+/**
+Implements the removal of a list element from the singly linked list.
+
+This function is called by TSglQue::Remove().
+
+@param aPtr An untyped pointer to the element to be removed.
+
+@see TSglQue::Remove
+*/
+	{
+
+	TSglQueLink* pP=(TSglQueLink*)(&iHead);
+	TSglQueLink* pL=PtrAdd((TSglQueLink*)aPtr,iOffset);
+	TSglQueLink* pN=pP->iNext;
+	while (pN)
+		{
+		if (pN==pL)
+			{
+			pP->iNext=pN->iNext;
+			if (iLast==pL)
+				{
+				iLast=pP;
+				if (iLast==NULL)
+					iLast=(TSglQueLink*)(&iHead);
+				}
+			return;
+			}
+		pP=pN;
+		pN=pP->iNext;
+		}
+	Panic(ESQueLinkNotQueued);
+	}
+
+
+
+
+#pragma warning( disable : 4705 )	// statement has no effect
+EXPORT_C TDblQueBase::TDblQueBase()
+	: iOffset(0)
+/**
+Default constructor.
+
+It sets: 
+
+1. iHead to point to this object in both the forwards and backwards direction.
+
+2. iOffset to zero.
+
+@see iHead
+@see iOffset
+*/
+	{
+
+	iHead.iNext=iHead.iPrev=(&iHead);
+	}
+
+
+
+
+EXPORT_C TDblQueBase::TDblQueBase(TInt aOffset)
+	: iOffset(aOffset)
+/**
+Constructor with specified offset.
+
+It sets:
+
+1. iHead to point to this object in both the forwards and backwards direction.
+
+2. iOffset to the specified value.
+
+@param aOffset The offset of a link object within an element.
+
+@panic USER 78, if aOffset is not divisible by four
+
+@see iHead
+@see iOffset
+*/
+	{
+
+	__ASSERT_ALWAYS(iOffset%4==0,Panic(ETQueOffsetNotAligned));
+	iHead.iNext=iHead.iPrev=(&iHead);
+	}
+#pragma warning( default : 4705 )
+
+
+
+
+EXPORT_C TBool TDblQueBase::IsEmpty() const
+/**
+Tests whether the doubly linked list is empty, i.e. has no list elements.
+
+@return True, if the doubly linked list is empty; false, otherwise.
+*/
+	{
+
+	return((const TDblQueLinkBase*)iHead.iNext==(&iHead));
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::SetOffset(TInt aOffset)
+/**
+Sets the offset of the link object from the start of a doubly linked list element.
+
+@param aOffset The offset of the link object from the start of a doubly linked 
+               list element.
+               
+@panic USER 78, if aOffset is not divisible by four.               
+               
+@see TDblQue
+*/
+	{
+
+	__ASSERT_ALWAYS(iOffset%4==0,Panic(ETQueOffsetNotAligned));
+	iOffset=aOffset;
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::Reset()
+/**
+Empties the doubly linked list.
+
+After a call to this function, there are no elements queued from the header; 
+the elements are orphaned. Special care must be taken when list elements are 
+CBase derived objects, i.e. are allocated on the heap.
+*/
+	{
+	
+	iHead.iNext=iHead.iPrev=(&iHead);
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::DoAddFirst(TAny* aPtr)
+/**
+Implements the insertion of the specified list element at the front of the
+doubly linked list.
+
+This function is called by TDblQue::AddFirst().
+
+@param aPtr An untyped pointer to the element to be inserted.
+
+@see TDblQue::AddFirst
+*/
+	{
+
+	PtrAdd((TDblQueLinkBase*)aPtr,iOffset)->Enque(&iHead);
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::DoAddLast(TAny* aPtr)
+/**
+Implements the insertion of the specified list element at the back of the
+doubly linked list.
+
+This function is called by TDblQue::AddLast().
+
+@param aPtr An untyped pointer to the element to be inserted.
+
+@see TDblQue::AddLast*/
+	{
+
+	PtrAdd((TDblQueLinkBase*)aPtr,iOffset)->Enque(iHead.iPrev);
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::DoAddPriority(TAny* aPtr)
+/**
+Implements the insertion of the specified list element in priority order.
+
+This function is called by TPriQue::Add().
+
+@param aPtr An untyped pointer to the element to be inserted.
+
+@see TPriQue::Add
+*/
+	{
+
+	TPriQueLink* pN=(TPriQueLink*)iHead.iNext;
+	TPriQueLink* pI=PtrAdd((TPriQueLink*)aPtr,iOffset);
+	TInt p=pI->iPriority;
+	while (pN!=(TPriQueLink*)&iHead && p<=pN->iPriority)
+		pN=(TPriQueLink*)pN->iNext;
+	pI->Enque(pN->iPrev);
+	}
+
+
+
+
+EXPORT_C TDeltaQueBase::TDeltaQueBase()
+	: iFirstDelta(NULL)
+/**
+Default constructor.
+
+It sets iFirstDelta to NULL.
+
+@see TDeltaQueBase::iFirstDelta
+*/
+	{
+	}
+
+
+
+
+EXPORT_C TDeltaQueBase::TDeltaQueBase(TInt aOffset)
+	: TDblQueBase(aOffset),iFirstDelta(NULL)
+/**
+Constructor with specified offset.
+
+It sets:
+
+1. iFirstDelta to NULL
+
+2. TDblQueBase::iOffset to the specified value, through a call to the
+   base class  constructor.
+
+@param aOffset The offset of a link object within an element.
+
+@see TDeltaQueBase::iFirstDelta
+@see TDblQueBase::iOffset
+*/
+	{
+	}
+
+
+
+
+EXPORT_C void TDeltaQueBase::Reset()
+/**
+Empties the doubly linked list, and resets the first delta pointer.
+*/
+	{
+	
+	TDblQueBase::Reset();
+	iFirstDelta=NULL;
+	}
+
+
+
+
+EXPORT_C TBool TDeltaQueBase::FirstDelta(TInt& aValue)
+/**
+Gets the delta value of the first list element.
+
+@param aValue On return, contsins the delta value of the first element.
+              Note that this remains unchanged if there is no first element.
+              
+@return True, if there is a first element; false, otherwise.
+*/
+    {
+    if (iFirstDelta)
+        {
+        aValue=*iFirstDelta;
+        return(ETrue);
+        }
+    return(EFalse);
+    }
+
+
+
+
+EXPORT_C TBool TDeltaQueBase::CountDown()
+/**
+Decrements the delta value of the first element by one, and returns true if 
+the result is negative or zero.
+
+@return True, if the resulting delta value is negative or zero; false, if 
+        the value is positive, or there is no first element.
+*/
+	{
+
+    return(CountDown(1));
+	}
+
+
+
+
+EXPORT_C TBool TDeltaQueBase::CountDown(TInt aValue)
+/**
+Decrements the delta value of the first element by the specified value, and 
+returns true if the result is negative or zero.
+
+@param aValue The amount by which the delta value is to be reduced.
+
+@return True, if the resulting delta value is negative or zero; false, if the 
+        value is positive, or there is no first element.
+*/
+	{
+
+	if (iFirstDelta)
+		{
+		(*iFirstDelta)-=aValue;
+		if (*iFirstDelta<=0)
+			return(ETrue);
+		}
+	return(EFalse);
+	}
+
+
+
+
+EXPORT_C void TDeltaQueBase::DoAddDelta(TAny* aPtr,TInt aDelta)
+/**
+Implements the addition of the specified list element into the list.
+
+This function is called by TDeltaQue::Add().
+
+@param aPtr   Pointer to the list element to be inserted.
+@param aDelta The 'distance' from the nominal zero point.
+
+@see TDeltaQue::Add
+*/
+	{
+
+	TDeltaQueLink* pD=(TDeltaQueLink*)iHead.iNext;
+	TDeltaQueLink* pI=PtrAdd((TDeltaQueLink*)aPtr,iOffset);
+	while (pD!=(TDeltaQueLink*)&iHead && aDelta>=pD->iDelta)
+		{
+		aDelta-=pD->iDelta;
+		pD=(TDeltaQueLink*)pD->iNext;
+		}
+	pI->iDelta=aDelta;
+	pI->Enque(pD->iPrev);
+	if (pI->iNext!=&iHead)
+		pD->iDelta-=aDelta;
+	iFirstDelta=(&((TDeltaQueLink*)iHead.iNext)->iDelta);
+	}
+
+
+
+
+EXPORT_C void TDeltaQueBase::DoRemove(TAny* aPtr)
+/**
+Implements the removal of the specified list element from the list.
+
+This function is called by TDeltaQue::Remove().
+
+@param aPtr Pointer to the list element to be removed.
+
+@see TDeltaQue::Remove
+*/
+	{
+
+	TDeltaQueLink* pI=PtrAdd((TDeltaQueLink*)aPtr,iOffset);
+	TDeltaQueLink* pN=(TDeltaQueLink*)pI->iNext;
+	if (pN!=(TDeltaQueLink*)&iHead)
+		pN->iDelta+=pI->iDelta;
+	((TDblQueLink*)pI)->Deque();
+	iFirstDelta=(iHead.iNext!=(&iHead) ? &((TDeltaQueLink*)iHead.iNext)->iDelta : NULL);
+	}
+
+
+
+
+EXPORT_C TAny* TDeltaQueBase::DoRemoveFirst()
+/**
+Implements the removal of the first list element from the linked list if its 
+delta value is zero or negative.
+
+This function is called by TDeltaQue::RemoveFirst().
+
+@return A pointer to the element removed from the linked list. This is NULL, 
+        if the first element has a positive delta value.
+
+@see TDeltaQue::RemoveFirst
+*/
+	{
+
+	TDeltaQueLink* pN=(TDeltaQueLink*)iHead.iNext;
+	if (pN!=(TDeltaQueLink*)&iHead && pN->iDelta<=0)
+		{
+		pN=PtrSub(pN,iOffset);
+		DoRemove(pN);
+		return(pN);
+		}
+	return(NULL);
+	}
+
+
+
+
+EXPORT_C TSglQueIterBase::TSglQueIterBase(TSglQueBase& aQue)
+//
+// Cosntructor.
+//
+	: iOffset(aQue.iOffset),iHead((TSglQueLink*)&aQue.iHead),iNext(aQue.iHead)
+	{}
+
+
+
+
+EXPORT_C void TSglQueIterBase::SetToFirst()
+/**
+Sets the iterator to point to the first element in the singly linked list. 
+
+The function can be called to re-set the pointer at any time during the iterator's 
+existence.
+
+The function can be called even if the list has no elements.
+*/
+	{
+
+	iNext=iHead->iNext;
+	}
+
+
+
+
+EXPORT_C void TSglQueIterBase::DoSet(TAny* aLink)
+//
+// Start the iterator at aLink.
+//
+	{
+
+	iNext=PtrAdd((TSglQueLink*)aLink,iOffset);
+	}
+
+EXPORT_C TAny* TSglQueIterBase::DoPostInc()
+//
+// Return the current pointer and increment.
+//
+	{
+
+	TAny* pN=iNext;
+	if (pN==NULL)
+		return NULL;
+	iNext=iNext->iNext;
+	return(PtrSub(pN,iOffset));
+	}
+
+EXPORT_C TAny* TSglQueIterBase::DoCurrent()
+//
+// Return the current pointer.
+//
+	{
+
+	return(iNext==NULL ? NULL : PtrSub((TAny*)iNext,iOffset));
+	}
+
+
+
+
+EXPORT_C TDblQueIterBase::TDblQueIterBase(TDblQueBase& aQue)
+	: iOffset(aQue.iOffset),iHead(&aQue.iHead),iNext(aQue.iHead.iNext)
+/**
+Constructs the iterator for the specified doubly linked list.
+
+@param aQue A reference to a doubly linked list header.
+*/
+	{}
+
+
+
+
+EXPORT_C void TDblQueIterBase::SetToFirst()
+/**
+Sets the iterator to point to the first element in the doubly linked list. 
+
+The function can be called to re-set the pointer at any time during the
+iterator's  existence.
+
+The function can be called even if the list has no elements.
+*/
+	{
+
+	iNext=iHead->iNext;
+	}
+
+
+
+
+EXPORT_C void TDblQueIterBase::SetToLast()
+/**
+Sets the iterator to point to the last element in the doubly linked list. The 
+function can be called to re-set the pointer at any time during the
+iterator's existence.
+
+The function can be called even if the list has no elements.
+*/
+	{
+
+	iNext=iHead->iPrev;
+	}
+
+
+
+
+EXPORT_C void TDblQueIterBase::DoSet(TAny* aLink)
+/**
+Sets the iterator to point to a specific element in the list.
+
+The function is an implementation for TDblQueIter::Set().
+
+@param aLink A pointer to the current list element.
+
+@see TDblQueIter::Set
+*/
+	{
+
+	iNext=PtrAdd((TDblQueLinkBase*)aLink,iOffset);
+	}
+
+
+
+
+EXPORT_C TAny* TDblQueIterBase::DoPostInc()
+/**
+Gets the current item and then moves to the next item.
+
+The function is an implementation for TDblQueIter::operator++().
+
+@return A pointer to the current list element.
+
+@see TDblQueIter::operator++
+*/
+	{
+
+	if (iNext==iHead)
+		return(NULL);
+	__ASSERT_DEBUG((iNext->iNext!=NULL)&&(iNext->iPrev!=NULL),Panic(ETQueLinkHasBeenRemoved));
+	TAny* p=PtrSub(iNext,iOffset);
+	iNext=iNext->iNext;
+	return(p);
+	}
+
+
+
+
+EXPORT_C TAny* TDblQueIterBase::DoPostDec()
+/**
+Gets the current item and then moves to the previous item.
+
+The function is an implementation for TDblQueIter::operator--().
+
+@return A pointer to the current list element.
+
+@see TDblQueIter::operator--
+*/
+	{
+
+	if (iNext==iHead)
+		return(NULL);
+	__ASSERT_DEBUG((iNext->iNext!=NULL)&&(iNext->iPrev!=NULL),Panic(ETQueLinkHasBeenRemoved));
+	TAny* p=PtrSub(iNext,iOffset);
+	iNext=iNext->iPrev;
+	return(p);
+	}
+
+
+
+
+EXPORT_C TAny* TDblQueIterBase::DoCurrent()
+/**
+Gets the current item in the queue.
+
+The function is an implementation for TDblQueIter::operator T*().
+
+@return A pointer to the current list element.
+
+@see TDblQueIter::operator T*
+*/
+	{
+
+	if (iNext==iHead)
+		return(NULL);
+	__ASSERT_DEBUG((iNext->iNext!=NULL)&&(iNext->iPrev!=NULL),Panic(ETQueLinkHasBeenRemoved));
+	return(PtrSub(iNext,iOffset));
+	}
+
+
+
+
+EXPORT_C void TDblQueBase::__DbgTestEmpty() const
+/**
+Tests whether the queue is empty.
+
+The function is implemented as an __ASSERT_DEBUG.
+
+@panic USER 79, if the assertion fails.
+*/
+	{
+
+	__ASSERT_DEBUG((((TDblQueLink*)iHead.iNext)!=&iHead)&&(((TDblQueLink*)iHead.iPrev)!=&iHead),Panic(ETQueQueueEmpty));
+	}
+