os/kernelhwsrv/kernel/eka/euser/cbase/ub_circ.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\cbase\ub_circ.cpp
    15 // 
    16 //
    17 
    18 #include "ub_std.h"
    19 
    20 EXPORT_C CCirBufBase::CCirBufBase(TInt aSize)
    21 /**
    22 Constructor taking the size of an object within the buffer.
    23 
    24 @param aSize The size of an object in the buffer.
    25 
    26 @panic E32USER-CBase 72, if aSize is zero or negative. 
    27 */
    28 	: iSize(aSize)
    29 	{
    30 
    31 	__ASSERT_ALWAYS(iSize>0,Panic(ECircItemSizeNegativeOrZero));
    32 //	iCount=0;
    33 //	iLength=0;
    34 //	iPtr=NULL;
    35 //	iPtrE=NULL;
    36 //	iHead=NULL;
    37 //	iTail=NULL;
    38 	}
    39 
    40 EXPORT_C CCirBufBase::~CCirBufBase()
    41 /**
    42 Destructor.
    43 
    44 This frees the memory allocated to the buffer.
    45 */
    46 	{
    47 
    48 	User::Free(iPtr);
    49 	}
    50 
    51 EXPORT_C void CCirBufBase::SetLengthL(TInt aLength)
    52 /**
    53 Sets the maximum capacity of this circular buffer, and resets all
    54 of the buffer pointers.
    55 
    56 The capacity is the maximum number of elements that the buffer can hold.
    57 
    58 The buffer itself is allocated as a result of a call to this function. If 
    59 the function has previously been called, then any existing buffer is freed and 
    60 any information in it is lost.
    61 
    62 Notes:
    63 
    64 1. This function must be called before attempting to add any objects to
    65    the buffer.
    66 
    67 2. The function can leave if there is insufficient memory available to
    68    allocate the buffer.
    69 
    70 @param aLength The maximum capacity of the circular buffer.
    71 
    72 @panic E32USER-CBase 73, if aLength is zero or negative. 
    73 */
    74 	{
    75 
    76 	__ASSERT_ALWAYS(aLength>0,Panic(ECircSetLengthNegativeOrZero));
    77 	iPtr=(TUint8 *)User::ReAllocL(iPtr,aLength*iSize);
    78 	iPtrE=iPtr+(aLength*iSize);
    79 	iHead=iTail=iPtr;
    80 	iLength=aLength;
    81 	iCount=0;
    82 	}
    83 
    84 EXPORT_C void CCirBufBase::Reset()
    85 /**
    86 Empties the buffer.
    87 */
    88 	{
    89 
    90 	iHead=iTail=iPtr;
    91 	iCount=0;
    92 #if defined(_DEBUG)
    93 	Mem::FillZ(iPtr,iLength*iSize);
    94 #endif
    95 	}
    96 
    97 EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr)
    98 /**
    99 Implementation function for CCirBuf::Add(const T*)
   100 
   101 Adds a single object to the circular buffer, but only if there is
   102 space available.
   103 
   104 @param aPtr A pointer to the object to be added.
   105 
   106 @return 1 if the object is successfully added. 0 if the object cannot be added 
   107         because the circular buffer is full.
   108 
   109 @panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been
   110                          made before calling this function.
   111 
   112 @see CCirBuf::Add
   113 @see CCirBufBase::SetLengthL
   114 */
   115 	{
   116 
   117 	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   118 	if (iCount>=iLength)
   119 		return(KErrNone);
   120 	Mem::Copy(iHead,aPtr,iSize);
   121 	iCount++;
   122 	iHead+=iSize;
   123 	if (iHead>=iPtrE)
   124 		iHead=iPtr;
   125 	return(1);
   126 	}
   127 
   128 EXPORT_C TInt CCirBufBase::DoAdd(const TUint8 *aPtr,TInt aCount)
   129 /**
   130 Implementation function for CCirBuf::Add(const T*,TInt)
   131 
   132 Adds multiple objects to the circular buffer, but only if there is
   133 space available.
   134 
   135 @param aPtr   A pointer to a set of contiguous objects to be added.
   136 
   137 @param aCount The number of objects to be added.
   138 
   139 @return The number of objects successfully added to the buffer. This value 
   140         may be less than the number requested and can range from 0 to aCount. 
   141 
   142 @panic E32USER-CBase 74, if a call to CCirBufBase::SetLengthL() has not been
   143                          made before calling this function.
   144 @panic E32USER-CBase 75, if aCount is not a positive value. 
   145 
   146 @see CCirBuf::Add
   147 @see CCirBufBase::SetLengthL
   148 */
   149 	{
   150 
   151 	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   152 	__ASSERT_ALWAYS(aCount>0,Panic(ECircAddCountNegative));
   153 	TInt rem=iLength-iCount;
   154 	if (rem==0)
   155 		return(0);
   156 	aCount=Min(aCount,rem);
   157 	rem=(iPtrE-iHead)/iSize;
   158 	if (aCount<=rem)
   159 		iHead=Mem::Copy(iHead,aPtr,aCount*iSize);
   160 	else
   161 		{
   162 		TInt len=(rem*iSize);
   163 		Mem::Copy(iHead,aPtr,len);
   164 		iHead=Mem::Copy(iPtr,aPtr+len,(aCount*iSize)-len);
   165 		}
   166 	if (iHead>=iPtrE)
   167 		iHead=iPtr;
   168 	iCount+=aCount;
   169 	return(aCount);
   170 	}
   171 
   172 EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr)
   173 /**
   174 Implementation function for CCirBuf::Remove(T*)
   175 
   176 Removes a single object from the circular buffer, but only if there are
   177 objects in the buffer.
   178 
   179 A binary copy of the object is made to aPtr.
   180 
   181 @param aPtr A pointer to a location supplied by the caller.
   182 
   183 @return 1 if an object is successfully removed. 0 if an object cannot be removed 
   184         because the circular buffer is empty.
   185 
   186 @see CCirBuf::Remove
   187 */
   188 	{
   189 
   190 	if (iCount==0)
   191 		return(0);
   192 	Mem::Copy(aPtr,iTail,iSize);
   193 	iTail+=iSize;
   194 	if (iTail>=iPtrE)
   195 		iTail=iPtr;
   196 	iCount--;
   197 	return(1);
   198 	}
   199 
   200 EXPORT_C TInt CCirBufBase::DoRemove(TUint8 *aPtr,TInt aCount)
   201 /**
   202 Implementation function for CCirBuf::Remove(T*,TInt)
   203 
   204 Attempts to remove aCount objects from the circular buffer, but only if there
   205 are objects in the buffer.
   206 
   207 A binary copy of the objects is made to aPtr.
   208 
   209 @param aPtr   A pointer to a location supplied by the caller capable of
   210               holding aCount objects.
   211 
   212 @param aCount The number of objects to be removed from the circular buffer.
   213 
   214 @return The number of objects successfully removed from the buffer. This value
   215         may be less than the number requested, and can range from 0 to aCount.
   216 
   217 @panic E32USER-CBase 76, if aCount is not a positive value.
   218 
   219 @see CCirBuf::Remove
   220 */
   221 	{
   222 
   223 	if (iCount==0)
   224 		return(0);
   225 	__ASSERT_ALWAYS(aCount>0,Panic(ECircRemoveCountNegative));
   226 	aCount=Min(aCount,iCount);
   227 	TInt rem=(iPtrE-iTail)/iSize;
   228 	TInt len=rem*iSize;
   229 	if (aCount<=rem)
   230 		{
   231 		Mem::Copy(aPtr,iTail,aCount*iSize);
   232 		iTail+=aCount*iSize;
   233 		}
   234 	else
   235 		{
   236 		Mem::Copy(aPtr,iTail,len);
   237 		rem=(aCount*iSize)-len;
   238 		Mem::Copy(aPtr+len,iPtr,rem);
   239 		iTail=iPtr+rem;
   240 		}
   241 	if (iTail>=iPtrE)
   242 		iTail=iPtr;
   243 	iCount-=aCount;
   244 	return(aCount);
   245 	}
   246 
   247 EXPORT_C CCirBuffer::CCirBuffer()
   248 	: CCirBuf<TUint8>()
   249 /**
   250 Default C++ constructor.
   251 */
   252 	{}
   253 
   254 EXPORT_C CCirBuffer::~CCirBuffer()
   255 /**
   256 Destructor
   257 */
   258 	{
   259 	}
   260 
   261 EXPORT_C TInt CCirBuffer::Get()
   262 /**
   263 Removes an unsigned 8-bit integer value from the circular buffer and returns
   264 its value. 
   265 
   266 The returned TUint8 is promoted to a TInt to allow for negative error codes, 
   267 e.g. KErrGeneral.
   268 
   269 @return The unsigned 8-bit integer value removed from the circular buffer.
   270         KErrGeneral, if the circular buffer is empty.
   271 */
   272 	{
   273 
   274 	if (iCount==0)
   275 		return(KErrGeneral);
   276 	TUint8 *p=iTail++;
   277 	if (iTail>=iPtrE)
   278 		iTail=iPtr;
   279 	iCount--;
   280 	return(*p);
   281 	}
   282 
   283 EXPORT_C TInt CCirBuffer::Put(TInt aVal)
   284 /**
   285 Adds an unsigned 8-bit integer value in the range 0 to 255 to the circular buffer.
   286 
   287 If the specified integer is outside the range 0 to 255,
   288 this method discards all but the lowest 8 bits and treats those
   289 as the unsigned integer to store.
   290 For example, specifying -2 (or 510, or -258, etc) will result in 254 being stored,
   291 and therefore in 254 being returned by the Get() method
   292 (and not the number passed to Put()).
   293 
   294 @param aVal The unsigned 8-bit integer value to be added.
   295 @return KErrNone, if the unsigned integer is successfully added.
   296         KErrGeneral, if the unsigned integer cannnot be added because
   297         the circular buffer is full.
   298 
   299 @see CCirBuffer::Get()
   300 */
   301 	{
   302 
   303 	__ASSERT_ALWAYS(iPtr!=NULL,Panic(ECircNoBufferAllocated));
   304 	if (iCount>=iLength)
   305 		return(KErrGeneral);
   306 	*iHead++=(TUint8)aVal;
   307 	if (iHead>=iPtrE)
   308 		iHead=iPtr;
   309 	iCount++;
   310 	return(KErrNone);
   311 	}
   312