0
|
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 |
|