diff -r c55016431358 -r 0a7b44b10206 symport/e32/euser/cbase/ub_circ.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symport/e32/euser/cbase/ub_circ.cpp Thu Jun 25 15:59:54 2009 +0100 @@ -0,0 +1,312 @@ +// Copyright (c) 1995-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\cbase\ub_circ.cpp +// +// + +#include "ub_std.h" + +EXPORT_C CCirBufBase::CCirBufBase(TInt aSize) +/** +Constructor taking the size of an object within the buffer. + +@param aSize The size of an object in the buffer. + +@panic E32USER-CBase 72, if aSize is zero or negative. +*/ + : iSize(aSize) + { + + __ASSERT_ALWAYS(iSize>0,Panic(ECircItemSizeNegativeOrZero)); +// iCount=0; +// iLength=0; +// iPtr=NULL; +// iPtrE=NULL; +// iHead=NULL; +// iTail=NULL; + } + +EXPORT_C CCirBufBase::~CCirBufBase() +/** +Destructor. + +This frees the memory allocated to the buffer. +*/ + { + + User::Free(iPtr); + } + +EXPORT_C void CCirBufBase::SetLengthL(TInt aLength) +/** +Sets the maximum capacity of this circular buffer, and resets all +of the buffer pointers. + +The capacity is the maximum number of elements that the buffer can hold. + +The buffer itself is allocated as a result of a call to this function. If +the function has previously been called, then any existing buffer is freed and +any information in it is lost. + +Notes: + +1. This function must be called before attempting to add any objects to + the buffer. + +2. The function can leave if there is insufficient memory available to + allocate the buffer. + +@param aLength The maximum capacity of the circular buffer. + +@panic E32USER-CBase 73, if aLength is zero or negative. +*/ + { + + __ASSERT_ALWAYS(aLength>0,Panic(ECircSetLengthNegativeOrZero)); + iPtr=(TUint8 *)User::ReAllocL(iPtr,aLength*iSize); + iPtrE=iPtr+(aLength*iSize); + iHead=iTail=iPtr; + iLength=aLength; + iCount=0; + } + +EXPORT_C void CCirBufBase::Reset() +/** +Empties the buffer. +*/ + { + + iHead=iTail=iPtr; + iCount=0; +#if defined(_DEBUG) + Mem::FillZ(iPtr,iLength*iSize); +#endif + } + +EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr) +/** +Implementation function for CCirBuf::Add(const T*) + +Adds a single object to the circular buffer, but only if there is +space available. + +@param aPtr A pointer to the object to be added. + +@return 1 if the object is successfully added. 0 if the object cannot be added + because the circular buffer is full. + +@panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been + made before calling this function. + +@see CCirBuf::Add +@see CCirBufBase::SetLengthL +*/ + { + + __ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated)); + if (iCount>=iLength) + return(KErrNone); + Mem::Copy(iHead,aPtr,iSize); + iCount++; + iHead+=iSize; + if (iHead>=iPtrE) + iHead=iPtr; + return(1); + } + +EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr,TInt aCount) +/** +Implementation function for CCirBuf::Add(const T*,TInt) + +Adds multiple objects to the circular buffer, but only if there is +space available. + +@param aPtr A pointer to a set of contiguous objects to be added. + +@param aCount The number of objects to be added. + +@return The number of objects successfully added to the buffer. This value + may be less than the number requested and can range from 0 to aCount. + +@panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been + made before calling this function. +@panic E32USER-CBase 75, if aCount is not a positive value. + +@see CCirBuf::Add +@see CCirBufBase::SetLengthL +*/ + { + + __ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated)); + __ASSERT_ALWAYS(aCount>0,Panic(ECircAddCountNegative)); + TInt rem=iLength-iCount; + if (rem==0) + return(0); + aCount=Min(aCount,rem); + rem=(iPtrE-iHead)/iSize; + if (aCount<=rem) + iHead=Mem::Copy(iHead,aPtr,aCount*iSize); + else + { + TInt len=(rem*iSize); + Mem::Copy(iHead,aPtr,len); + iHead=Mem::Copy(iPtr,aPtr+len,(aCount*iSize)-len); + } + if (iHead>=iPtrE) + iHead=iPtr; + iCount+=aCount; + return(aCount); + } + +EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr) +/** +Implementation function for CCirBuf::Remove(T*) + +Removes a single object from the circular buffer, but only if there are +objects in the buffer. + +A binary copy of the object is made to aPtr. + +@param aPtr A pointer to a location supplied by the caller. + +@return 1 if an object is successfully removed. 0 if an object cannot be removed + because the circular buffer is empty. + +@see CCirBuf::Remove +*/ + { + + if (iCount==0) + return(0); + Mem::Copy(aPtr,iTail,iSize); + iTail+=iSize; + if (iTail>=iPtrE) + iTail=iPtr; + iCount--; + return(1); + } + +EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr,TInt aCount) +/** +Implementation function for CCirBuf::Remove(T*,TInt) + +Attempts to remove aCount objects from the circular buffer, but only if there +are objects in the buffer. + +A binary copy of the objects is made to aPtr. + +@param aPtr A pointer to a location supplied by the caller capable of + holding aCount objects. + +@param aCount The number of objects to be removed from the circular buffer. + +@return The number of objects successfully removed from the buffer. This value + may be less than the number requested, and can range from 0 to aCount. + +@panic E32USER-CBase 76, if aCount is not a positive value. + +@see CCirBuf::Remove +*/ + { + + if (iCount==0) + return(0); + __ASSERT_ALWAYS(aCount>0,Panic(ECircRemoveCountNegative)); + aCount=Min(aCount,iCount); + TInt rem=(iPtrE-iTail)/iSize; + TInt len=rem*iSize; + if (aCount<=rem) + { + Mem::Copy(aPtr,iTail,aCount*iSize); + iTail+=aCount*iSize; + } + else + { + Mem::Copy(aPtr,iTail,len); + rem=(aCount*iSize)-len; + Mem::Copy(aPtr+len,iPtr,rem); + iTail=iPtr+rem; + } + if (iTail>=iPtrE) + iTail=iPtr; + iCount-=aCount; + return(aCount); + } + +EXPORT_C CCirBuffer::CCirBuffer() + : CCirBuf() +/** +Default C++ constructor. +*/ + {} + +EXPORT_C CCirBuffer::~CCirBuffer() +/** +Destructor +*/ + { + } + +EXPORT_C TInt CCirBuffer::Get() +/** +Removes an unsigned 8-bit integer value from the circular buffer and returns +its value. + +The returned TUint8 is promoted to a TInt to allow for negative error codes, +e.g. KErrGeneral. + +@return The unsigned 8-bit integer value removed from the circular buffer. + KErrGeneral, if the circular buffer is empty. +*/ + { + + if (iCount==0) + return(KErrGeneral); + TUint8 *p=iTail++; + if (iTail>=iPtrE) + iTail=iPtr; + iCount--; + return(*p); + } + +EXPORT_C TInt CCirBuffer::Put(TInt aVal) +/** +Adds an unsigned 8-bit integer value in the range 0 to 255 to the circular buffer. + +If the specified integer is outside the range 0 to 255, +this method discards all but the lowest 8 bits and treats those +as the unsigned integer to store. +For example, specifying -2 (or 510, or -258, etc) will result in 254 being stored, +and therefore in 254 being returned by the Get() method +(and not the number passed to Put()). + +@param aVal The unsigned 8-bit integer value to be added. +@return KErrNone, if the unsigned integer is successfully added. + KErrGeneral, if the unsigned integer cannnot be added because + the circular buffer is full. + +@see CCirBuffer::Get() +*/ + { + + __ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated)); + if (iCount>=iLength) + return(KErrGeneral); + *iHead++=(TUint8)aVal; + if (iHead>=iPtrE) + iHead=iPtr; + iCount++; + return(KErrNone); + } +