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