kernel/eka/euser/cbase/ub_circ.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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