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 +