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