1 /***************************************************************************
2 $RCSfile$
3 -------------------
4 cvs : $Id$
5 begin : Sun Jan 25 2004
6 copyright : (C) 2004 by Martin Preuss
7 email : martin@libchipcard.de
8
9 ***************************************************************************
10 * *
11 * This library is free software; you can redistribute it and/or *
12 * modify it under the terms of the GNU Lesser General Public *
13 * License as published by the Free Software Foundation; either *
14 * version 2.1 of the License, or (at your option) any later version. *
15 * *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19 * Lesser General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU Lesser General Public *
22 * License along with this library; if not, write to the Free Software *
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24 * MA 02111-1307 USA *
25 * *
26 ***************************************************************************/
27
28
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33 #define DISABLE_DEBUGLOG
34
35 #include "ringbuffer_p.h"
36 #include <gwenhywfar/misc.h>
37 #include <gwenhywfar/debug.h>
38 #include <stdlib.h>
39
40
41
GWEN_RingBuffer_new(unsigned int size)42 GWEN_RINGBUFFER *GWEN_RingBuffer_new(unsigned int size)
43 {
44 GWEN_RINGBUFFER *rb;
45
46 assert(size);
47 GWEN_NEW_OBJECT(GWEN_RINGBUFFER, rb);
48 DBG_MEM_INC("GWEN_RINGBUFFER", 0);
49 rb->ptr=(char *)malloc(size);
50 rb->bufferSize=size;
51 return rb;
52 }
53
54
55
GWEN_RingBuffer_free(GWEN_RINGBUFFER * rb)56 void GWEN_RingBuffer_free(GWEN_RINGBUFFER *rb)
57 {
58 if (rb) {
59 DBG_MEM_DEC("GWEN_RINGBUFFER");
60 free(rb->ptr);
61 GWEN_FREE_OBJECT(rb);
62 }
63 }
64
65
66
GWEN_RingBuffer_WriteBytes(GWEN_RINGBUFFER * rb,const char * buffer,uint32_t * size)67 int GWEN_RingBuffer_WriteBytes(GWEN_RINGBUFFER *rb,
68 const char *buffer,
69 uint32_t *size)
70 {
71 uint32_t psize;
72 uint32_t bytesLeft;
73
74 if ((rb->bufferSize-rb->bytesUsed)==0) {
75 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
76 rb->fullCounter++;
77 return -1;
78 }
79
80 bytesLeft=*size;
81 while (bytesLeft) {
82 if ((rb->bufferSize-rb->bytesUsed)==0)
83 break;
84 if (rb->writePos>=rb->readPos)
85 psize=rb->bufferSize-rb->writePos;
86 else
87 psize=rb->readPos-rb->writePos;
88 if (psize>bytesLeft)
89 psize=bytesLeft;
90
91 memmove(rb->ptr+rb->writePos, buffer, psize);
92 rb->writePos+=psize;
93 if (rb->writePos>=rb->bufferSize)
94 rb->writePos=0;
95 rb->bytesUsed+=psize;
96 buffer+=psize;
97 bytesLeft-=psize;
98 } /* while */
99 *size-=bytesLeft;
100 if (rb->bytesUsed>rb->maxBytesUsed)
101 rb->maxBytesUsed=rb->bytesUsed;
102 return 0;
103 }
104
105
106
GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER * rb)107 uint32_t GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER *rb)
108 {
109 uint32_t psize;
110
111 assert(rb);
112 if (rb->bytesUsed==0) {
113 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
114 rb->emptyCounter++;
115 return 0;
116 }
117
118 if (rb->readPos>=rb->writePos)
119 psize=rb->bufferSize-rb->readPos;
120 else
121 psize=rb->writePos-rb->readPos;
122
123 return psize;
124 }
125
126
127
GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER * rb)128 uint32_t GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER *rb)
129 {
130 uint32_t psize;
131
132 assert(rb);
133 if ((rb->bufferSize-rb->bytesUsed)==0) {
134 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
135 rb->fullCounter++;
136 return 0;
137 }
138
139 if (rb->writePos>=rb->readPos)
140 psize=rb->bufferSize-rb->writePos;
141 else
142 psize=rb->readPos-rb->writePos;
143
144 return psize;
145 }
146
147
148
GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER * rb,uint32_t psize)149 void GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER *rb,
150 uint32_t psize)
151 {
152 assert(rb);
153
154 if (rb->bytesUsed<psize) {
155 DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than available");
156 abort();
157 }
158 rb->readPos+=psize;
159 if (rb->readPos>=rb->bufferSize)
160 rb->readPos=0;
161 rb->bytesUsed-=psize;
162 rb->throughput+=psize;
163 }
164
165
166
GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER * rb,uint32_t psize)167 void GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER *rb,
168 uint32_t psize)
169 {
170 assert(rb);
171
172 if ((rb->bufferSize-rb->bytesUsed)<psize) {
173 DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than possible");
174 abort();
175 }
176
177 rb->writePos+=psize;
178 if (rb->writePos>=rb->bufferSize)
179 rb->writePos=0;
180 rb->bytesUsed+=psize;
181 if (rb->bytesUsed>rb->maxBytesUsed)
182 rb->maxBytesUsed=rb->bytesUsed;
183 }
184
185
186
GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER * rb,char * buffer,uint32_t * size)187 int GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER *rb,
188 char *buffer,
189 uint32_t *size)
190 {
191 uint32_t psize;
192 uint32_t bytesLeft;
193
194 if (rb->bytesUsed==0) {
195 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
196 rb->emptyCounter++;
197 return -1;
198 }
199
200 bytesLeft=*size;
201 while (bytesLeft) {
202 if (rb->bytesUsed==0)
203 break;
204 if (rb->readPos>=rb->writePos)
205 psize=rb->bufferSize-rb->readPos;
206 else
207 psize=rb->writePos-rb->readPos;
208 if (psize>bytesLeft)
209 psize=bytesLeft;
210
211 memmove(buffer, rb->ptr+rb->readPos, psize);
212 rb->readPos+=psize;
213 if (rb->readPos>=rb->bufferSize)
214 rb->readPos=0;
215 rb->bytesUsed-=psize;
216 buffer+=psize;
217 bytesLeft-=psize;
218 } /* while */
219 *size-=bytesLeft;
220 rb->throughput+=*size;
221 return 0;
222 }
223
224
225
GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER * rb)226 uint32_t GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER *rb)
227 {
228 assert(rb);
229 return rb->bytesUsed;
230 }
231
232
233
GWEN_RingBuffer_GetBytesLeft(const GWEN_RINGBUFFER * rb)234 uint32_t GWEN_RingBuffer_GetBytesLeft(const GWEN_RINGBUFFER *rb)
235 {
236 assert(rb);
237 return rb->bufferSize-rb->bytesUsed;
238 }
239
240
241
GWEN_RingBuffer_GetBufferSize(const GWEN_RINGBUFFER * rb)242 uint32_t GWEN_RingBuffer_GetBufferSize(const GWEN_RINGBUFFER *rb)
243 {
244 assert(rb);
245 return rb->bufferSize;
246 }
247
248
249
GWEN_RingBuffer_WriteByte(GWEN_RINGBUFFER * rb,char c)250 int GWEN_RingBuffer_WriteByte(GWEN_RINGBUFFER *rb,
251 char c)
252 {
253 assert(rb);
254 if ((rb->bufferSize-rb->bytesUsed)==0) {
255 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
256 rb->fullCounter++;
257 return -1;
258 }
259
260 rb->ptr[rb->writePos]=c;
261 rb->writePos++;
262 if (rb->writePos>=rb->bufferSize)
263 rb->writePos=0;
264 rb->bytesUsed++;
265 if (rb->bytesUsed>rb->maxBytesUsed)
266 rb->maxBytesUsed=rb->bytesUsed;
267 return 0;
268 }
269
270
271
GWEN_RingBuffer_ReadByte(GWEN_RINGBUFFER * rb)272 int GWEN_RingBuffer_ReadByte(GWEN_RINGBUFFER *rb)
273 {
274 int c;
275
276 assert(rb);
277 if (rb->bytesUsed==0) {
278 DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
279 rb->emptyCounter++;
280 return -1;
281 }
282
283 c=(unsigned char)rb->ptr[rb->readPos];
284 rb->readPos++;
285 if (rb->readPos>=rb->bufferSize)
286 rb->readPos=0;
287 rb->bytesUsed--;
288 rb->throughput++;
289 return c;
290 }
291
292
293
GWEN_RingBuffer_GetMaxUsedBytes(const GWEN_RINGBUFFER * rb)294 uint32_t GWEN_RingBuffer_GetMaxUsedBytes(const GWEN_RINGBUFFER *rb)
295 {
296 assert(rb);
297 return rb->maxBytesUsed;
298 }
299
300
301
GWEN_RingBuffer_ResetMaxUsedBytes(GWEN_RINGBUFFER * rb)302 void GWEN_RingBuffer_ResetMaxUsedBytes(GWEN_RINGBUFFER *rb)
303 {
304 assert(rb);
305 rb->maxBytesUsed=0;
306 }
307
308
309
GWEN_RingBuffer_GetThroughput(GWEN_RINGBUFFER * rb)310 uint32_t GWEN_RingBuffer_GetThroughput(GWEN_RINGBUFFER *rb)
311 {
312 assert(rb);
313 return rb->throughput;
314 }
315
316
317
GWEN_RingBuffer_ResetThroughput(GWEN_RINGBUFFER * rb)318 void GWEN_RingBuffer_ResetThroughput(GWEN_RINGBUFFER *rb)
319 {
320 assert(rb);
321 rb->throughput=0;
322 }
323
324
325
GWEN_RingBuffer_GetFullCounter(const GWEN_RINGBUFFER * rb)326 uint32_t GWEN_RingBuffer_GetFullCounter(const GWEN_RINGBUFFER *rb)
327 {
328 assert(rb);
329 return rb->fullCounter;
330 }
331
332
333
GWEN_RingBuffer_ResetFullCounter(GWEN_RINGBUFFER * rb)334 void GWEN_RingBuffer_ResetFullCounter(GWEN_RINGBUFFER *rb)
335 {
336 assert(rb);
337 rb->fullCounter=0;
338 }
339
340
341
GWEN_RingBuffer_GetEmptyCounter(const GWEN_RINGBUFFER * rb)342 uint32_t GWEN_RingBuffer_GetEmptyCounter(const GWEN_RINGBUFFER *rb)
343 {
344 assert(rb);
345 return rb->emptyCounter;
346 }
347
348
349
GWEN_RingBuffer_ResetEmptyCounter(GWEN_RINGBUFFER * rb)350 void GWEN_RingBuffer_ResetEmptyCounter(GWEN_RINGBUFFER *rb)
351 {
352 assert(rb);
353 rb->emptyCounter=0;
354 }
355
356
357
GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER * rb)358 const char *GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER *rb)
359 {
360 assert(rb);
361 return rb->ptr+rb->readPos;
362 }
363
364
365
GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER * rb)366 char *GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER *rb)
367 {
368 assert(rb);
369 return rb->ptr+rb->writePos;
370 }
371
372
373
GWEN_RingBuffer_Reset(GWEN_RINGBUFFER * rb)374 void GWEN_RingBuffer_Reset(GWEN_RINGBUFFER *rb)
375 {
376 assert(rb);
377
378 rb->readPos=0;
379 rb->writePos=0;
380 rb->bytesUsed=0;
381 rb->maxBytesUsed=0;
382 rb->emptyCounter=0;
383 rb->fullCounter=0;
384 rb->throughput=0;
385 }
386
387
388
389
390
391
392