#ifndef __RING_BUFFER_H_
#define __RING_BUFFER_H_
struct ring_buffer
{
unsigned int in;
unsigned int out;
unsigned int size;
unsigned char *buffer;
};
struct ring_buffer *ring_buffer_init(unsigned int buffer_size);
void ring_buffer_exit(struct ring_buffer *rb);
unsigned int ring_buffer_avail(struct ring_buffer *rb);
void ring_buffer_discard(struct ring_buffer *rb, unsigned int length);
unsigned int ring_buffer_read(struct ring_buffer *rb, unsigned char *buffer, unsigned int length);
unsigned int ring_buffer_write(struct ring_buffer *rb, const unsigned char *buffer, unsigned int length);
unsigned int ring_buffer_overwrite(struct ring_buffer *rb, const unsigned char *buffer, unsigned int length);
#endif
#include "ring_buffer.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
struct ring_buffer *ring_buffer_init(unsigned int buffer_size)
{
int i;
struct ring_buffer *rb = NULL;
rb = (struct ring_buffer *) malloc(sizeof(struct ring_buffer));
if (NULL == rb)
{
printf("malloc struct ring_buffer failed! \n");
return rb;
}
for (i=0; ; i++)
{
if (((1<<i) < buffer_size) && (buffer_size <= (1<<i+1)))
break;
}
rb->buffer = (unsigned char *) malloc((1 << (i + 1)) * sizeof(unsigned char));
if (NULL == rb->buffer)
{
printf("malloc buffer failed! \n");
free(rb);
rb = NULL;
return rb;
}
printf("The ring buffer alloced is %d bytes. \n", 1 << (i + 1));
rb->in = 0;
rb->out = 0;
rb->size = 1 << (i + 1);
return rb;
}
void ring_buffer_exit(struct ring_buffer *rb)
{
if (NULL == rb)
return ;
if (NULL != rb->buffer)
free(rb->buffer);
free(rb);
}
unsigned int ring_buffer_avail(struct ring_buffer *rb)
{
return (rb->in - rb->out);
}
void ring_buffer_discard(struct ring_buffer *rb, unsigned int length)
{
length = MIN(length, rb->in - rb->out);
rb->out += length;
}
unsigned int ring_buffer_read(struct ring_buffer *rb, unsigned char *buffer, unsigned int length)
{
unsigned int len;
length = MIN(length, rb->in - rb->out);
len = MIN(length, rb->size - (rb->out & (rb->size - 1)));
memcpy(buffer, rb->buffer + (rb->out & (rb->size - 1)), len);
memcpy(buffer + len, rb->buffer, length - len);
rb->out += length;
return length;
}
unsigned int ring_buffer_write(struct ring_buffer *rb, const unsigned char *buffer, unsigned int length)
{
unsigned int len;
length = MIN(length, rb->size - rb->in + rb->out);
len = MIN(length, rb->size - (rb->in & (rb->size - 1)));
memcpy(rb->buffer + (rb->in & (rb->size - 1)), buffer, len);
memcpy(rb->buffer, buffer + len, length - len);
rb->in += length;
return length;
}
unsigned int ring_buffer_overwrite(struct ring_buffer *rb, const unsigned char *buffer, unsigned int length)
{
unsigned int len;
unsigned int unavail;
unavail = rb->size - rb->in + rb->out;
if (length < rb->size)
{
if (unavail < length)
{
ring_buffer_discard(rb, length - unavail);
}
len = MIN(length, rb->size - (rb->in & (rb->size - 1)));
memcpy(rb->buffer + (rb->in & (rb->size - 1)), buffer, len);
memcpy(rb->buffer, buffer + len, length - len);
rb->in += length;
}
else
{
memcpy(rb->buffer, buffer + length - rb->size, rb->size);
rb->in = rb->size;
rb->out = 0;
}
return length;
}
#include "ring_buffer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* arg[])
{
unsigned int i = 0;
unsigned int n, ret;
char exit_q;
unsigned char buff[100];
printf("Please enter the size of ring buffer that you want to alloc: ");
scanf("%d", &i);
struct ring_buffer *ring_buffer_st = ring_buffer_init(i);
if (NULL == ring_buffer_st)
return -1;
printf("\n");
while (1)
{
memset(buff, 0, 100);
i = 0;
printf("Please enter the number of data you want to write: ");
scanf("%d", &i);
printf("Please input the data that you want to write: ");
for (n = 0; n < i; n++)
scanf("%d", &buff[n]);
ret = ring_buffer_overwrite(ring_buffer_st, buff, i);
printf("\t ring_buffer_overwrite return value = %d \n", ret);
printf("\t ------------------------\n");
printf("\t | ");
for (i = 0; i < ring_buffer_st->size; i++)
printf("%u ", ring_buffer_st->buffer[i]);
printf("\n");
printf("\t | out=%u, in=%u, \n", ring_buffer_st->out, ring_buffer_st->in);
printf("\t ------------------------\n");
ret = ring_buffer_avail(ring_buffer_st);
printf("\t ring_buffer_avail return value = %d \n\n", ret);
memset(buff, 0, 100);
i = 0;
printf("Please enter the number of data you want to read: ");
scanf("%d", &i);
ret = ring_buffer_read(ring_buffer_st, buff, i);
printf("The dats is: ");
for (n = 0; n < ret; n++)
printf("%d ", buff[n]);
printf("\n");
printf("\t ring_buffer_read return value = %d \n", ret);
printf("\t ------------------------\n");
printf("\t | ");
for (i = 0; i < ring_buffer_st->size; i++)
printf("%u ", ring_buffer_st->buffer[i]);
printf("\n");
printf("\t | out=%u, in=%u, \n", ring_buffer_st->out, ring_buffer_st->in);
printf("\t ------------------------\n");
ret = ring_buffer_avail(ring_buffer_st);
printf("\t ring_buffer_avail return value = %d \n\n", ret);
printf("You can enter Q to exit the program ...\n");
setbuf(stdin, NULL);
exit_q = getchar();
if (exit_q == 'q' || exit_q == 'Q')
break;
}
ring_buffer_exit(ring_buffer_st);
ring_buffer_st = NULL;
}
|