I am trying to get into C stuff, and I thought it would be a good idea to try and implement a circular buffer.
I have defined my struct like this:
typedef struct
{
int8_t* buffer;
int8_t* buffer_end;
int8_t* data_start;
int8_t* data_end;
int64_t count;
int64_t size;
} ring_buffer;
And the functions:
void RB_init(ring_buffer* rb, int64_t size)
{
rb->buffer = malloc(sizeof(int8_t) * size);
rb->buffer_end = rb->buffer + size;
rb->size = size;
rb->data_start = rb->buffer;
rb->data_end = rb->buffer;
rb->count = 0;
}
void RB_free(ring_buffer* rb)
{
free(rb->buffer);
}
bool RB_push(ring_buffer* rb, int8_t data)
{
if (rb == NULL || rb->buffer == NULL)
return false;
*rb->data_end = data;
rb->data_end++;
if (rb->data_end == rb->buffer_end)
rb->data_end = rb->buffer;
if (RB_full(rb)) {
if ((rb->data_start + 1) == rb->buffer_end)
rb->data_start = rb->buffer;
else
rb->data_start++;
} else {
rb->count++;
}
return true;
}
int8_t RB_pop(ring_buffer* rb)
{
if (rb == NULL || rb->buffer == NULL)
return false;
int8_t data = *rb->data_start;
rb->data_start++;
if (rb->data_start == rb->buffer_end)
rb->data_start = rb->buffer;
rb->count--;
return data;
}
bool RB_full(ring_buffer* rb)
{
return rb->count == rb->size;
}
I did some testing and it seems to work well. Can you suggest some improvements ?
RB_pop
does not check for an empty buffer and has no way of indicating that the buffer is empty. \$\endgroup\$size_t
instead ofint64_t
for all sizes and counts of in-memory objects. \$\endgroup\$