typedef struct RingBuffer RingBuffer;
RingBuffer* RingBufferCreate(int sizeOf,int length);
void RingBufferDestroy(RingBuffer* ring);
int RingBufferWrite(RingBuffer* ring,const char* data,int len);
int RingBufferRead(RingBuffer* ring,char* data,int len);
struct RingBuffer
{
char* mem;
int sizeOf;
int length;
int writePos;
int full;
};
RingBuffer* RingBufferCreate(int sizeOf,int length)
{
RingBuffer *ring = (RingBuffer*)calloc(1,sizeof(*ring));
if(ring)
{
ring->sizeOf = sizeOf;
ring->length = length;
ring->writePos = 0;
ring->full = 0;
ring->mem = (char*)malloc(ring->length * ring->sizeOf);
if(!ring->mem)
{
free(ring);
ring = 0;
}
}
return ring;
}
void RingBufferDestroy(RingBuffer* ring)
{
if(ring)
{
free(ring->mem);
free(ring);
}
}
int RingBufferRead(RingBuffer* ring,char* data,int len)
{
if(ring->full == 1)
{
if(len > ring->length)
len = ring->length;
memcpy(data,ring->mem,len*ring->sizeOf);
ring->full = 0;
}
if(ring->writePos < len)
{
ring->full = 0;
int ret = ring->writePos;
ring->writePos = 0;
memcpy(data,ring->mem,ring->writePos*ring->sizeOf);
return ret;
}
else
{
ring->full = 0;
memcpy(data,ring->mem,len*ring->sizeOf);
ring->writePos -= len;
memcpy(ring->mem,ring->mem + len*ring->sizeOf,ring->writePos*ring->sizeOf);
return len;
}
}
int RingBufferWrite(RingBuffer* ring,const char* data,int len)
{
if(len + ring->writePos > ring->length)
ring->full = 1;
int ret = len >= ring->length ? ring->length : len;
if(len >= ring->length)
{
memcpy(ring->mem,data + (ring->length-ring->length%len)*ring->sizeOf,ring->length*ring->sizeOf);
ring->writePos = ring->length;
}
else if(len + ring->writePos <= ring->length)
{
memcpy(ring->mem + ring->writePos*ring->sizeOf,data,len*ring->sizeOf);
ring->writePos += len;
}
else
{
memcpy(ring->mem,ring->mem + (len + ring->writePos - ring->length)*ring->sizeOf,(len + ring->writePos - ring->length)*ring->sizeOf);
memcpy(ring->mem + (len + ring->writePos - ring->length)*ring->sizeOf,data,len*ring->sizeOf);
ring->writePos = ring->length;
}
return ret;
}