ringbuffer.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: ringbuffer.c 1393 2007-11-22 18:26:05Z martin $
00005     begin       : Sun Jan 25 2004
00006     copyright   : (C) 2004 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032 
00033 #define DISABLE_DEBUGLOG
00034 
00035 #include "ringbuffer_p.h"
00036 #include <gwenhywfar/misc.h>
00037 #include <gwenhywfar/debug.h>
00038 #include <stdlib.h>
00039 
00040 
00041 
00042 GWEN_RINGBUFFER *GWEN_RingBuffer_new(unsigned int size){
00043   GWEN_RINGBUFFER *rb;
00044 
00045   assert(size);
00046   GWEN_NEW_OBJECT(GWEN_RINGBUFFER, rb);
00047   DBG_MEM_INC("GWEN_RINGBUFFER", 0);
00048   rb->ptr=(char*)malloc(size);
00049   rb->bufferSize=size;
00050   return rb;
00051 }
00052 
00053 
00054 
00055 void GWEN_RingBuffer_free(GWEN_RINGBUFFER *rb){
00056   if (rb) {
00057     DBG_MEM_DEC("GWEN_RINGBUFFER");
00058     free(rb->ptr);
00059     GWEN_FREE_OBJECT(rb);
00060   }
00061 }
00062 
00063 
00064 
00065 int GWEN_RingBuffer_WriteBytes(GWEN_RINGBUFFER *rb,
00066                                const char *buffer,
00067                                uint32_t *size){
00068   uint32_t psize;
00069   uint32_t bytesLeft;
00070 
00071   if ((rb->bufferSize-rb->bytesUsed)==0) {
00072     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
00073     rb->fullCounter++;
00074     return -1;
00075   }
00076 
00077   bytesLeft=*size;
00078   while(bytesLeft) {
00079     if ((rb->bufferSize-rb->bytesUsed)==0)
00080       break;
00081     if (rb->writePos>=rb->readPos)
00082       psize=rb->bufferSize-rb->writePos;
00083     else
00084       psize=rb->readPos-rb->writePos;
00085     if (psize>bytesLeft)
00086       psize=bytesLeft;
00087 
00088     memmove(rb->ptr+rb->writePos, buffer, psize);
00089     rb->writePos+=psize;
00090     if (rb->writePos>=rb->bufferSize)
00091       rb->writePos=0;
00092     rb->bytesUsed+=psize;
00093     buffer+=psize;
00094     bytesLeft-=psize;
00095   } /* while */
00096   *size-=bytesLeft;
00097   if (rb->bytesUsed>rb->maxBytesUsed)
00098     rb->maxBytesUsed=rb->bytesUsed;
00099   return 0;
00100 }
00101 
00102 
00103 
00104 uint32_t
00105 GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER *rb) {
00106   uint32_t psize;
00107 
00108   assert(rb);
00109   if (rb->bytesUsed==0) {
00110     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
00111     rb->emptyCounter++;
00112     return 0;
00113   }
00114 
00115   if (rb->readPos>=rb->writePos)
00116     psize=rb->bufferSize-rb->readPos;
00117   else
00118     psize=rb->writePos-rb->readPos;
00119 
00120   return psize;
00121 }
00122 
00123 
00124 
00125 uint32_t
00126 GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER *rb) {
00127   uint32_t psize;
00128 
00129   assert(rb);
00130   if ((rb->bufferSize-rb->bytesUsed)==0) {
00131     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
00132     rb->fullCounter++;
00133     return 0;
00134   }
00135 
00136   if (rb->writePos>=rb->readPos)
00137     psize=rb->bufferSize-rb->writePos;
00138   else
00139     psize=rb->readPos-rb->writePos;
00140 
00141   return psize;
00142 }
00143 
00144 
00145 
00146 void GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER *rb,
00147                                    uint32_t psize) {
00148   assert(rb);
00149 
00150   if (rb->bytesUsed<psize) {
00151     DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than available");
00152     abort();
00153   }
00154   rb->readPos+=psize;
00155   if (rb->readPos>=rb->bufferSize)
00156     rb->readPos=0;
00157   rb->bytesUsed-=psize;
00158   rb->throughput+=psize;
00159 }
00160 
00161 
00162 
00163 void GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER *rb,
00164                                     uint32_t psize) {
00165   assert(rb);
00166 
00167   if ((rb->bufferSize-rb->bytesUsed)<psize) {
00168     DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than possible");
00169     abort();
00170   }
00171 
00172   rb->writePos+=psize;
00173   if (rb->writePos>=rb->bufferSize)
00174     rb->writePos=0;
00175   rb->bytesUsed+=psize;
00176   if (rb->bytesUsed>rb->maxBytesUsed)
00177     rb->maxBytesUsed=rb->bytesUsed;
00178 }
00179 
00180 
00181 
00182 int GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER *rb,
00183                               char *buffer,
00184                               uint32_t *size){
00185   uint32_t psize;
00186   uint32_t bytesLeft;
00187 
00188   if (rb->bytesUsed==0) {
00189     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
00190     rb->emptyCounter++;
00191     return -1;
00192   }
00193 
00194   bytesLeft=*size;
00195   while(bytesLeft) {
00196     if (rb->bytesUsed==0)
00197       break;
00198     if (rb->readPos>=rb->writePos)
00199       psize=rb->bufferSize-rb->readPos;
00200     else
00201       psize=rb->writePos-rb->readPos;
00202     if (psize>bytesLeft)
00203       psize=bytesLeft;
00204 
00205     memmove(buffer, rb->ptr+rb->readPos, psize);
00206     rb->readPos+=psize;
00207     if (rb->readPos>=rb->bufferSize)
00208       rb->readPos=0;
00209     rb->bytesUsed-=psize;
00210     buffer+=psize;
00211     bytesLeft-=psize;
00212   } /* while */
00213   *size-=bytesLeft;
00214   rb->throughput+=*size;
00215   return 0;
00216 }
00217 
00218 
00219 
00220 uint32_t GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER *rb){
00221   assert(rb);
00222   return rb->bytesUsed;
00223 }
00224 
00225 
00226 
00227 uint32_t GWEN_RingBuffer_GetBytesLeft(const GWEN_RINGBUFFER *rb){
00228   assert(rb);
00229   return rb->bufferSize-rb->bytesUsed;
00230 }
00231 
00232 
00233 
00234 uint32_t GWEN_RingBuffer_GetBufferSize(const GWEN_RINGBUFFER *rb){
00235   assert(rb);
00236   return rb->bufferSize;
00237 }
00238 
00239 
00240 
00241 int GWEN_RingBuffer_WriteByte(GWEN_RINGBUFFER *rb,
00242                               char c) {
00243   assert(rb);
00244   if ((rb->bufferSize-rb->bytesUsed)==0) {
00245     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
00246     rb->fullCounter++;
00247     return -1;
00248   }
00249 
00250   rb->ptr[rb->writePos]=c;
00251   rb->writePos++;
00252   if (rb->writePos>=rb->bufferSize)
00253     rb->writePos=0;
00254   rb->bytesUsed++;
00255   if (rb->bytesUsed>rb->maxBytesUsed)
00256     rb->maxBytesUsed=rb->bytesUsed;
00257   return 0;
00258 }
00259 
00260 
00261 
00262 int GWEN_RingBuffer_ReadByte(GWEN_RINGBUFFER *rb) {
00263   int c;
00264 
00265   assert(rb);
00266   if (rb->bytesUsed==0) {
00267     DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
00268     rb->emptyCounter++;
00269     return -1;
00270   }
00271 
00272   c=(unsigned char)rb->ptr[rb->readPos];
00273   rb->readPos++;
00274   if (rb->readPos>=rb->bufferSize)
00275     rb->readPos=0;
00276   rb->bytesUsed--;
00277   rb->throughput++;
00278   return c;
00279 }
00280 
00281 
00282 
00283 uint32_t GWEN_RingBuffer_GetMaxUsedBytes(const GWEN_RINGBUFFER *rb){
00284   assert(rb);
00285   return rb->maxBytesUsed;
00286 }
00287 
00288 
00289 
00290 void GWEN_RingBuffer_ResetMaxUsedBytes(GWEN_RINGBUFFER *rb) {
00291   assert(rb);
00292   rb->maxBytesUsed=0;
00293 }
00294 
00295 
00296 
00297 uint32_t GWEN_RingBuffer_GetThroughput(GWEN_RINGBUFFER *rb) {
00298   assert(rb);
00299   return rb->throughput;
00300 }
00301 
00302 
00303 
00304 void GWEN_RingBuffer_ResetThroughput(GWEN_RINGBUFFER *rb) {
00305   assert(rb);
00306   rb->throughput=0;
00307 }
00308 
00309 
00310 
00311 uint32_t GWEN_RingBuffer_GetFullCounter(const GWEN_RINGBUFFER *rb){
00312   assert(rb);
00313   return rb->fullCounter;
00314 }
00315 
00316 
00317 
00318 void GWEN_RingBuffer_ResetFullCounter(GWEN_RINGBUFFER *rb) {
00319   assert(rb);
00320   rb->fullCounter=0;
00321 }
00322 
00323 
00324 
00325 uint32_t GWEN_RingBuffer_GetEmptyCounter(const GWEN_RINGBUFFER *rb){
00326   assert(rb);
00327   return rb->emptyCounter;
00328 }
00329 
00330 
00331 
00332 void GWEN_RingBuffer_ResetEmptyCounter(GWEN_RINGBUFFER *rb) {
00333   assert(rb);
00334   rb->emptyCounter=0;
00335 }
00336 
00337 
00338 
00339 const char *GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER *rb) {
00340   assert(rb);
00341   return rb->ptr+rb->readPos;
00342 }
00343 
00344 
00345 
00346 char *GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER *rb) {
00347   assert(rb);
00348   return rb->ptr+rb->writePos;
00349 }
00350 
00351 
00352 
00353 void GWEN_RingBuffer_Reset(GWEN_RINGBUFFER *rb){
00354   assert(rb);
00355 
00356   rb->readPos=0;
00357   rb->writePos=0;
00358   rb->bytesUsed=0;
00359   rb->maxBytesUsed=0;
00360   rb->emptyCounter=0;
00361   rb->fullCounter=0;
00362   rb->throughput=0;
00363 }
00364 
00365 
00366 
00367 
00368 
00369 

Generated on Fri Apr 11 01:53:47 2008 for gwenhywfar by  doxygen 1.5.5