#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
struct ringbuf {
int begin;
int end;
int full;
int size;
char *buf;
};
struct ringbuf *ringbuf_alloc(int size)
{
struct ringbuf *rb = calloc(1,sizeof(struct ringbuf));
if(!rb)
return NULL;
rb->buf = calloc(1,size);
if(!rb->buf)
{
free(rb);
return NULL;
}
rb->size = size;
return rb;
}
void ringbuf_free(struct ringbuf *rb)
{
if(rb)
{
if(rb->buf)
free(rb->buf);
free(rb);
}
}
int ringbuf_count(struct ringbuf *rb)
{
if(!rb)
return -1;
if(rb->end == rb->begin)
return (rb->full)? rb->size:0;
if(rb->end > rb->begin)
return rb->end - rb->begin;
else
return (rb->size + rb->end - rb->begin);
}
int ringbuf_getfree(struct ringbuf *rb)
{
if(!rb)
return -1;
return rb->size - ringbuf_count(rb);
}
int ringbuf_write(struct ringbuf *rb,const char *data,int len)
{
int i,freelen,pos;
if(!rb)
return -1;
freelen = ringbuf_getfree(rb);
pos = rb->end;
if(freelen < len)
return -1;
for(i = 0;i < len; i++)
{
pos = (i + rb->end + rb->size) % rb->size;
rb->buf[pos] = data[i];
}
rb->end = (i + rb->end + rb->size) % rb->size;
if(rb->begin == rb->end)
rb->full = 1;
return len;
}
int ringbuf_read(struct ringbuf *rb,char *buf,int len)
{
int cur_cnt,i,pos,readlen;
if(!rb)
return -1;
cur_cnt = ringbuf_count(rb);
pos = rb->begin;
readlen = (len<cur_cnt)? len:cur_cnt;
for(i = 0;i < readlen; i++)
{
pos = (i + rb->begin + rb->size) % rb->size;
buf[i] = rb->buf[pos];
}
rb->begin = (i + rb->begin +rb->size) % rb->size;
if(rb->full)
rb->full = 0;
return readlen;
}
int ringbuf_posvalud(struct ringbuf *rb,char value)
{
int cur_cnt,i,pos;
cur_cnt = ringbuf_count(rb);
pos = rb->begin;
for(i=0;i<cur_cnt;i++)
{
pos = (i + rb->begin + rb->size) % rb->size;
if(rb->buf[pos] == value)
return pos;
}
return -1;
}
int main()
{
struct ringbuf *rb = ringbuf_alloc(32);
char buf[50] = {"hello world,I am ring buffer.123"};
char tmp[100] = {0};
int ret;
if(!rb)
return 1;
ringbuf_write(rb,buf,strlen(buf));
printf("ret = %d\n",ringbuf_write(rb,buf,10));
ret = ringbuf_read(rb,tmp,sizeof(tmp));
printf("ret = %d,%s\n",ret,tmp);
printf("free len: %d\n",ringbuf_getfree(rb));
printf("==================================\n");
memset(tmp,0,sizeof(tmp));
ringbuf_write(rb,buf,29);
ret = ringbuf_read(rb,tmp,12);
printf("ret = %d,%s\n",ret,tmp);
printf("==================================\n");
ringbuf_write(rb,buf,12);
memset(tmp,0,sizeof(tmp));
printf("free len: %d\n",ringbuf_count(rb));
ret = ringbuf_read(rb,tmp,50);
printf("ret = %d,%s\n",ret,tmp);
ringbuf_free(rb);
return 0;
}