diff -r c55016431358 -r 0a7b44b10206 symport/e32/euser/us_que.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symport/e32/euser/us_que.cpp Thu Jun 25 15:59:54 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 "Symbian Foundation License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.symbianfoundation.org/legal/sfl-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)); + } +