os/kernelhwsrv/kernel/eka/euser/cbase/ub_circ.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/euser/cbase/ub_circ.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,312 @@
     1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32\euser\cbase\ub_circ.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "ub_std.h"
    1.22 +
    1.23 +EXPORT_C CCirBufBase::CCirBufBase(TInt aSize)
    1.24 +/**
    1.25 +Constructor taking the size of an object within the buffer.
    1.26 +
    1.27 +@param aSize The size of an object in the buffer.
    1.28 +
    1.29 +@panic E32USER-CBase 72, if aSize is zero or negative. 
    1.30 +*/
    1.31 +	: iSize(aSize)
    1.32 +	{
    1.33 +
    1.34 +	__ASSERT_ALWAYS(iSize>0,Panic(ECircItemSizeNegativeOrZero));
    1.35 +//	iCount=0;
    1.36 +//	iLength=0;
    1.37 +//	iPtr=NULL;
    1.38 +//	iPtrE=NULL;
    1.39 +//	iHead=NULL;
    1.40 +//	iTail=NULL;
    1.41 +	}
    1.42 +
    1.43 +EXPORT_C CCirBufBase::~CCirBufBase()
    1.44 +/**
    1.45 +Destructor.
    1.46 +
    1.47 +This frees the memory allocated to the buffer.
    1.48 +*/
    1.49 +	{
    1.50 +
    1.51 +	User::Free(iPtr);
    1.52 +	}
    1.53 +
    1.54 +EXPORT_C void CCirBufBase::SetLengthL(TInt aLength)
    1.55 +/**
    1.56 +Sets the maximum capacity of this circular buffer, and resets all
    1.57 +of the buffer pointers.
    1.58 +
    1.59 +The capacity is the maximum number of elements that the buffer can hold.
    1.60 +
    1.61 +The buffer itself is allocated as a result of a call to this function. If 
    1.62 +the function has previously been called, then any existing buffer is freed and 
    1.63 +any information in it is lost.
    1.64 +
    1.65 +Notes:
    1.66 +
    1.67 +1. This function must be called before attempting to add any objects to
    1.68 +   the buffer.
    1.69 +
    1.70 +2. The function can leave if there is insufficient memory available to
    1.71 +   allocate the buffer.
    1.72 +
    1.73 +@param aLength The maximum capacity of the circular buffer.
    1.74 +
    1.75 +@panic E32USER-CBase 73, if aLength is zero or negative. 
    1.76 +*/
    1.77 +	{
    1.78 +
    1.79 +	__ASSERT_ALWAYS(aLength>0,Panic(ECircSetLengthNegativeOrZero));
    1.80 +	iPtr=(TUint8 *)User::ReAllocL(iPtr,aLength*iSize);
    1.81 +	iPtrE=iPtr+(aLength*iSize);
    1.82 +	iHead=iTail=iPtr;
    1.83 +	iLength=aLength;
    1.84 +	iCount=0;
    1.85 +	}
    1.86 +
    1.87 +EXPORT_C void CCirBufBase::Reset()
    1.88 +/**
    1.89 +Empties the buffer.
    1.90 +*/
    1.91 +	{
    1.92 +
    1.93 +	iHead=iTail=iPtr;
    1.94 +	iCount=0;
    1.95 +#if defined(_DEBUG)
    1.96 +	Mem::FillZ(iPtr,iLength*iSize);
    1.97 +#endif
    1.98 +	}
    1.99 +
   1.100 +EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr)
   1.101 +/**
   1.102 +Implementation function for CCirBuf::Add(const T*)
   1.103 +
   1.104 +Adds a single object to the circular buffer, but only if there is
   1.105 +space available.
   1.106 +
   1.107 +@param aPtr A pointer to the object to be added.
   1.108 +
   1.109 +@return 1 if the object is successfully added. 0 if the object cannot be added 
   1.110 +        because the circular buffer is full.
   1.111 +
   1.112 +@panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been
   1.113 +                         made before calling this function.
   1.114 +
   1.115 +@see CCirBuf::Add
   1.116 +@see CCirBufBase::SetLengthL
   1.117 +*/
   1.118 +	{
   1.119 +
   1.120 +	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   1.121 +	if (iCount>=iLength)
   1.122 +		return(KErrNone);
   1.123 +	Mem::Copy(iHead,aPtr,iSize);
   1.124 +	iCount++;
   1.125 +	iHead+=iSize;
   1.126 +	if (iHead>=iPtrE)
   1.127 +		iHead=iPtr;
   1.128 +	return(1);
   1.129 +	}
   1.130 +
   1.131 +EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr,TInt aCount)
   1.132 +/**
   1.133 +Implementation function for CCirBuf::Add(const T*,TInt)
   1.134 +
   1.135 +Adds multiple objects to the circular buffer, but only if there is
   1.136 +space available.
   1.137 +
   1.138 +@param aPtr   A pointer to a set of contiguous objects to be added.
   1.139 +
   1.140 +@param aCount The number of objects to be added.
   1.141 +
   1.142 +@return The number of objects successfully added to the buffer. This value 
   1.143 +        may be less than the number requested and can range from 0 to aCount. 
   1.144 +
   1.145 +@panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been
   1.146 +                         made before calling this function.
   1.147 +@panic E32USER-CBase 75, if aCount is not a positive value. 
   1.148 +
   1.149 +@see CCirBuf::Add
   1.150 +@see CCirBufBase::SetLengthL
   1.151 +*/
   1.152 +	{
   1.153 +
   1.154 +	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   1.155 +	__ASSERT_ALWAYS(aCount>0,Panic(ECircAddCountNegative));
   1.156 +	TInt rem=iLength-iCount;
   1.157 +	if (rem==0)
   1.158 +		return(0);
   1.159 +	aCount=Min(aCount,rem);
   1.160 +	rem=(iPtrE-iHead)/iSize;
   1.161 +	if (aCount<=rem)
   1.162 +		iHead=Mem::Copy(iHead,aPtr,aCount*iSize);
   1.163 +	else
   1.164 +		{
   1.165 +		TInt len=(rem*iSize);
   1.166 +		Mem::Copy(iHead,aPtr,len);
   1.167 +		iHead=Mem::Copy(iPtr,aPtr+len,(aCount*iSize)-len);
   1.168 +		}
   1.169 +	if (iHead>=iPtrE)
   1.170 +		iHead=iPtr;
   1.171 +	iCount+=aCount;
   1.172 +	return(aCount);
   1.173 +	}
   1.174 +
   1.175 +EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr)
   1.176 +/**
   1.177 +Implementation function for CCirBuf::Remove(T*)
   1.178 +
   1.179 +Removes a single object from the circular buffer, but only if there are
   1.180 +objects in the buffer.
   1.181 +
   1.182 +A binary copy of the object is made to aPtr.
   1.183 +
   1.184 +@param aPtr A pointer to a location supplied by the caller.
   1.185 +
   1.186 +@return 1 if an object is successfully removed. 0 if an object cannot be removed 
   1.187 +        because the circular buffer is empty.
   1.188 +
   1.189 +@see CCirBuf::Remove
   1.190 +*/
   1.191 +	{
   1.192 +
   1.193 +	if (iCount==0)
   1.194 +		return(0);
   1.195 +	Mem::Copy(aPtr,iTail,iSize);
   1.196 +	iTail+=iSize;
   1.197 +	if (iTail>=iPtrE)
   1.198 +		iTail=iPtr;
   1.199 +	iCount--;
   1.200 +	return(1);
   1.201 +	}
   1.202 +
   1.203 +EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr,TInt aCount)
   1.204 +/**
   1.205 +Implementation function for CCirBuf::Remove(T*,TInt)
   1.206 +
   1.207 +Attempts to remove aCount objects from the circular buffer, but only if there
   1.208 +are objects in the buffer.
   1.209 +
   1.210 +A binary copy of the objects is made to aPtr.
   1.211 +
   1.212 +@param aPtr   A pointer to a location supplied by the caller capable of
   1.213 +              holding aCount objects.
   1.214 +
   1.215 +@param aCount The number of objects to be removed from the circular buffer.
   1.216 +
   1.217 +@return The number of objects successfully removed from the buffer. This value
   1.218 +        may be less than the number requested, and can range from 0 to aCount.
   1.219 +
   1.220 +@panic E32USER-CBase 76, if aCount is not a positive value.
   1.221 +
   1.222 +@see CCirBuf::Remove
   1.223 +*/
   1.224 +	{
   1.225 +
   1.226 +	if (iCount==0)
   1.227 +		return(0);
   1.228 +	__ASSERT_ALWAYS(aCount>0,Panic(ECircRemoveCountNegative));
   1.229 +	aCount=Min(aCount,iCount);
   1.230 +	TInt rem=(iPtrE-iTail)/iSize;
   1.231 +	TInt len=rem*iSize;
   1.232 +	if (aCount<=rem)
   1.233 +		{
   1.234 +		Mem::Copy(aPtr,iTail,aCount*iSize);
   1.235 +		iTail+=aCount*iSize;
   1.236 +		}
   1.237 +	else
   1.238 +		{
   1.239 +		Mem::Copy(aPtr,iTail,len);
   1.240 +		rem=(aCount*iSize)-len;
   1.241 +		Mem::Copy(aPtr+len,iPtr,rem);
   1.242 +		iTail=iPtr+rem;
   1.243 +		}
   1.244 +	if (iTail>=iPtrE)
   1.245 +		iTail=iPtr;
   1.246 +	iCount-=aCount;
   1.247 +	return(aCount);
   1.248 +	}
   1.249 +
   1.250 +EXPORT_C CCirBuffer::CCirBuffer()
   1.251 +	: CCirBuf<TUint8>()
   1.252 +/**
   1.253 +Default C++ constructor.
   1.254 +*/
   1.255 +	{}
   1.256 +
   1.257 +EXPORT_C CCirBuffer::~CCirBuffer()
   1.258 +/**
   1.259 +Destructor
   1.260 +*/
   1.261 +	{
   1.262 +	}
   1.263 +
   1.264 +EXPORT_C TInt CCirBuffer::Get()
   1.265 +/**
   1.266 +Removes an unsigned 8-bit integer value from the circular buffer and returns
   1.267 +its value. 
   1.268 +
   1.269 +The returned TUint8 is promoted to a TInt to allow for negative error codes, 
   1.270 +e.g. KErrGeneral.
   1.271 +
   1.272 +@return The unsigned 8-bit integer value removed from the circular buffer.
   1.273 +        KErrGeneral, if the circular buffer is empty.
   1.274 +*/
   1.275 +	{
   1.276 +
   1.277 +	if (iCount==0)
   1.278 +		return(KErrGeneral);
   1.279 +	TUint8 *p=iTail++;
   1.280 +	if (iTail>=iPtrE)
   1.281 +		iTail=iPtr;
   1.282 +	iCount--;
   1.283 +	return(*p);
   1.284 +	}
   1.285 +
   1.286 +EXPORT_C TInt CCirBuffer::Put(TInt aVal)
   1.287 +/**
   1.288 +Adds an unsigned 8-bit integer value in the range 0 to 255 to the circular buffer.
   1.289 +
   1.290 +If the specified integer is outside the range 0 to 255,
   1.291 +this method discards all but the lowest 8 bits and treats those
   1.292 +as the unsigned integer to store.
   1.293 +For example, specifying -2 (or 510, or -258, etc) will result in 254 being stored,
   1.294 +and therefore in 254 being returned by the Get() method
   1.295 +(and not the number passed to Put()).
   1.296 +
   1.297 +@param aVal The unsigned 8-bit integer value to be added.
   1.298 +@return KErrNone, if the unsigned integer is successfully added.
   1.299 +        KErrGeneral, if the unsigned integer cannnot be added because
   1.300 +        the circular buffer is full.
   1.301 +
   1.302 +@see CCirBuffer::Get()
   1.303 +*/
   1.304 +	{
   1.305 +
   1.306 +	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   1.307 +	if (iCount>=iLength)
   1.308 +		return(KErrGeneral);
   1.309 +	*iHead++=(TUint8)aVal;
   1.310 +	if (iHead>=iPtrE)
   1.311 +		iHead=iPtr;
   1.312 +	iCount++;
   1.313 +	return(KErrNone);
   1.314 +	}
   1.315 +