gwenhywfar/src/base/ringbuffer.c @ 9f7e2793
db6abdf6 | aquamaniac | /***************************************************************************
|
|
$RCSfile$
|
|||
-------------------
|
|||
cvs : $Id$
|
|||
begin : Sun Jan 25 2004
|
|||
copyright : (C) 2004 by Martin Preuss
|
|||
email : martin@libchipcard.de
|
|||
***************************************************************************
|
|||
* *
|
|||
* This library is free software; you can redistribute it and/or *
|
|||
* modify it under the terms of the GNU Lesser General Public *
|
|||
* License as published by the Free Software Foundation; either *
|
|||
* version 2.1 of the License, or (at your option) any later version. *
|
|||
* *
|
|||
* This library is distributed in the hope that it will be useful, *
|
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|||
* Lesser General Public License for more details. *
|
|||
* *
|
|||
* You should have received a copy of the GNU Lesser General Public *
|
|||
* License along with this library; if not, write to the Free Software *
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
|
|||
* MA 02111-1307 USA *
|
|||
* *
|
|||
***************************************************************************/
|
|||
#ifdef HAVE_CONFIG_H
|
|||
# include <config.h>
|
|||
#endif
|
|||
#include "ringbuffer_p.h"
|
|||
#include <gwenhywfar/misc.h>
|
|||
#include <gwenhywfar/debug.h>
|
|||
#include <stdlib.h>
|
|||
GWEN_RINGBUFFER *GWEN_RingBuffer_new(unsigned int size){
|
|||
GWEN_RINGBUFFER *rb;
|
|||
assert(size);
|
|||
GWEN_NEW_OBJECT(GWEN_RINGBUFFER, rb);
|
|||
b2cf2da1 | aquamaniac | DBG_MEM_INC("GWEN_RINGBUFFER", 0);
|
|
db6abdf6 | aquamaniac | rb->ptr=(char*)malloc(size);
|
|
rb->bufferSize=size;
|
|||
return rb;
|
|||
}
|
|||
void GWEN_RingBuffer_free(GWEN_RINGBUFFER *rb){
|
|||
if (rb) {
|
|||
b2cf2da1 | aquamaniac | DBG_MEM_DEC("GWEN_RINGBUFFER");
|
|
db6abdf6 | aquamaniac | free(rb->ptr);
|
|
free(rb);
|
|||
}
|
|||
}
|
|||
dafb784e | aquamaniac | int GWEN_RingBuffer_WriteBytes(GWEN_RINGBUFFER *rb,
|
|
db6abdf6 | aquamaniac | const char *buffer,
|
|
GWEN_TYPE_UINT32 *size){
|
|||
GWEN_TYPE_UINT32 psize;
|
|||
GWEN_TYPE_UINT32 bytesLeft;
|
|||
if ((rb->bufferSize-rb->bytesUsed)==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
|
|
627b5e47 | aquamaniac | rb->fullCounter++;
|
|
db6abdf6 | aquamaniac | return -1;
|
|
}
|
|||
bytesLeft=*size;
|
|||
while(bytesLeft) {
|
|||
if ((rb->bufferSize-rb->bytesUsed)==0)
|
|||
break;
|
|||
if (rb->writePos>=rb->readPos)
|
|||
psize=rb->bufferSize-rb->writePos;
|
|||
else
|
|||
psize=rb->readPos-rb->writePos;
|
|||
dafb784e | aquamaniac | if (psize>bytesLeft)
|
|
psize=bytesLeft;
|
|||
db6abdf6 | aquamaniac | ||
memmove(rb->ptr+rb->writePos, buffer, psize);
|
|||
rb->writePos+=psize;
|
|||
if (rb->writePos>=rb->bufferSize)
|
|||
rb->writePos=0;
|
|||
rb->bytesUsed+=psize;
|
|||
buffer+=psize;
|
|||
bytesLeft-=psize;
|
|||
} /* while */
|
|||
*size-=bytesLeft;
|
|||
627b5e47 | aquamaniac | if (rb->bytesUsed>rb->maxBytesUsed)
|
|
rb->maxBytesUsed=rb->bytesUsed;
|
|||
db6abdf6 | aquamaniac | return 0;
|
|
}
|
|||
dafb784e | aquamaniac | GWEN_TYPE_UINT32
|
|
GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER *rb) {
|
|||
GWEN_TYPE_UINT32 psize;
|
|||
assert(rb);
|
|||
if (rb->bytesUsed==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
|
|
dafb784e | aquamaniac | rb->emptyCounter++;
|
|
return 0;
|
|||
}
|
|||
if (rb->readPos>=rb->writePos)
|
|||
psize=rb->bufferSize-rb->readPos;
|
|||
else
|
|||
psize=rb->writePos-rb->readPos;
|
|||
return psize;
|
|||
}
|
|||
GWEN_TYPE_UINT32
|
|||
GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER *rb) {
|
|||
GWEN_TYPE_UINT32 psize;
|
|||
assert(rb);
|
|||
if ((rb->bufferSize-rb->bytesUsed)==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
|
|
dafb784e | aquamaniac | rb->fullCounter++;
|
|
return 0;
|
|||
}
|
|||
if (rb->writePos>=rb->readPos)
|
|||
psize=rb->bufferSize-rb->writePos;
|
|||
else
|
|||
psize=rb->readPos-rb->writePos;
|
|||
return psize;
|
|||
}
|
|||
void GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER *rb,
|
|||
GWEN_TYPE_UINT32 psize) {
|
|||
assert(rb);
|
|||
if (rb->bytesUsed<psize) {
|
|||
8b7674e6 | aquamaniac | DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than available");
|
|
dafb784e | aquamaniac | abort();
|
|
}
|
|||
rb->readPos+=psize;
|
|||
if (rb->readPos>=rb->bufferSize)
|
|||
rb->readPos=0;
|
|||
rb->bytesUsed-=psize;
|
|||
rb->throughput+=psize;
|
|||
}
|
|||
void GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER *rb,
|
|||
GWEN_TYPE_UINT32 psize) {
|
|||
assert(rb);
|
|||
if ((rb->bufferSize-rb->bytesUsed)<psize) {
|
|||
8b7674e6 | aquamaniac | DBG_ERROR(GWEN_LOGDOMAIN, "Asked to skip more bytes than possible");
|
|
dafb784e | aquamaniac | abort();
|
|
}
|
|||
rb->writePos+=psize;
|
|||
if (rb->writePos>=rb->bufferSize)
|
|||
rb->writePos=0;
|
|||
rb->bytesUsed+=psize;
|
|||
if (rb->bytesUsed>rb->maxBytesUsed)
|
|||
rb->maxBytesUsed=rb->bytesUsed;
|
|||
}
|
|||
int GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER *rb,
|
|||
db6abdf6 | aquamaniac | char *buffer,
|
|
GWEN_TYPE_UINT32 *size){
|
|||
GWEN_TYPE_UINT32 psize;
|
|||
GWEN_TYPE_UINT32 bytesLeft;
|
|||
if (rb->bytesUsed==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
|
|
627b5e47 | aquamaniac | rb->emptyCounter++;
|
|
db6abdf6 | aquamaniac | return -1;
|
|
}
|
|||
bytesLeft=*size;
|
|||
while(bytesLeft) {
|
|||
if (rb->bytesUsed==0)
|
|||
break;
|
|||
if (rb->readPos>=rb->writePos)
|
|||
psize=rb->bufferSize-rb->readPos;
|
|||
else
|
|||
psize=rb->writePos-rb->readPos;
|
|||
dafb784e | aquamaniac | if (psize>bytesLeft)
|
|
psize=bytesLeft;
|
|||
db6abdf6 | aquamaniac | ||
memmove(buffer, rb->ptr+rb->readPos, psize);
|
|||
rb->readPos+=psize;
|
|||
if (rb->readPos>=rb->bufferSize)
|
|||
rb->readPos=0;
|
|||
rb->bytesUsed-=psize;
|
|||
buffer+=psize;
|
|||
bytesLeft-=psize;
|
|||
} /* while */
|
|||
*size-=bytesLeft;
|
|||
627b5e47 | aquamaniac | rb->throughput+=*size;
|
|
db6abdf6 | aquamaniac | return 0;
|
|
}
|
|||
GWEN_TYPE_UINT32 GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER *rb){
|
|||
assert(rb);
|
|||
return rb->bytesUsed;
|
|||
}
|
|||
GWEN_TYPE_UINT32 GWEN_RingBuffer_GetBytesLeft(const GWEN_RINGBUFFER *rb){
|
|||
assert(rb);
|
|||
return rb->bufferSize-rb->bytesUsed;
|
|||
}
|
|||
627b5e47 | aquamaniac | GWEN_TYPE_UINT32 GWEN_RingBuffer_GetBufferSize(const GWEN_RINGBUFFER *rb){
|
|
assert(rb);
|
|||
return rb->bufferSize;
|
|||
}
|
|||
db6abdf6 | aquamaniac | int GWEN_RingBuffer_WriteByte(GWEN_RINGBUFFER *rb,
|
|
char c) {
|
|||
assert(rb);
|
|||
if ((rb->bufferSize-rb->bytesUsed)==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer full");
|
|
627b5e47 | aquamaniac | rb->fullCounter++;
|
|
db6abdf6 | aquamaniac | return -1;
|
|
}
|
|||
rb->ptr[rb->writePos]=c;
|
|||
rb->writePos++;
|
|||
if (rb->writePos>=rb->bufferSize)
|
|||
rb->writePos=0;
|
|||
rb->bytesUsed++;
|
|||
627b5e47 | aquamaniac | if (rb->bytesUsed>rb->maxBytesUsed)
|
|
rb->maxBytesUsed=rb->bytesUsed;
|
|||
db6abdf6 | aquamaniac | return 0;
|
|
}
|
|||
int GWEN_RingBuffer_ReadByte(GWEN_RINGBUFFER *rb) {
|
|||
int c;
|
|||
assert(rb);
|
|||
if (rb->bytesUsed==0) {
|
|||
8b7674e6 | aquamaniac | DBG_DEBUG(GWEN_LOGDOMAIN, "Buffer empty");
|
|
627b5e47 | aquamaniac | rb->emptyCounter++;
|
|
db6abdf6 | aquamaniac | return -1;
|
|
}
|
|||
c=(unsigned char)rb->ptr[rb->readPos];
|
|||
rb->readPos++;
|
|||
if (rb->readPos>=rb->bufferSize)
|
|||
rb->readPos=0;
|
|||
rb->bytesUsed--;
|
|||
627b5e47 | aquamaniac | rb->throughput++;
|
|
db6abdf6 | aquamaniac | return c;
|
|
}
|
|||
627b5e47 | aquamaniac | GWEN_TYPE_UINT32 GWEN_RingBuffer_GetMaxUsedBytes(const GWEN_RINGBUFFER *rb){
|
|
assert(rb);
|
|||
return rb->maxBytesUsed;
|
|||
}
|
|||
void GWEN_RingBuffer_ResetMaxUsedBytes(GWEN_RINGBUFFER *rb) {
|
|||
assert(rb);
|
|||
rb->maxBytesUsed=0;
|
|||
}
|
|||
db6abdf6 | aquamaniac | ||
627b5e47 | aquamaniac | GWEN_TYPE_UINT32 GWEN_RingBuffer_GetThroughput(GWEN_RINGBUFFER *rb) {
|
|
assert(rb);
|
|||
return rb->throughput;
|
|||
}
|
|||
void GWEN_RingBuffer_ResetThroughput(GWEN_RINGBUFFER *rb) {
|
|||
assert(rb);
|
|||
rb->throughput=0;
|
|||
}
|
|||
GWEN_TYPE_UINT32 GWEN_RingBuffer_GetFullCounter(const GWEN_RINGBUFFER *rb){
|
|||
assert(rb);
|
|||
return rb->fullCounter;
|
|||
}
|
|||
void GWEN_RingBuffer_ResetFullCounter(GWEN_RINGBUFFER *rb) {
|
|||
assert(rb);
|
|||
rb->fullCounter=0;
|
|||
}
|
|||
GWEN_TYPE_UINT32 GWEN_RingBuffer_GetEmptyCounter(const GWEN_RINGBUFFER *rb){
|
|||
assert(rb);
|
|||
return rb->emptyCounter;
|
|||
}
|
|||
void GWEN_RingBuffer_ResetEmptyCounter(GWEN_RINGBUFFER *rb) {
|
|||
assert(rb);
|
|||
rb->emptyCounter=0;
|
|||
}
|
|||
db6abdf6 | aquamaniac | ||
dafb784e | aquamaniac | const char *GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER *rb) {
|
|
assert(rb);
|
|||
return rb->ptr+rb->readPos;
|
|||
}
|
|||
char *GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER *rb) {
|
|||
assert(rb);
|
|||
return rb->ptr+rb->writePos;
|
|||
}
|
|||
db6abdf6 | aquamaniac | ||
9f7e2793 | aquamaniac | void GWEN_RingBuffer_Reset(GWEN_RINGBUFFER *rb){
|
|
assert(rb);
|
|||
rb->readPos=0;
|
|||
rb->writePos=0;
|
|||
rb->bytesUsed=0;
|
|||
rb->maxBytesUsed=0;
|
|||
rb->emptyCounter=0;
|
|||
rb->fullCounter=0;
|
|||
rb->throughput=0;
|
|||
}
|
|||