Skip to content

Instantly share code, notes, and snippets.

@zdxerr
Created August 23, 2010 07:36
Show Gist options
  • Select an option

  • Save zdxerr/545010 to your computer and use it in GitHub Desktop.

Select an option

Save zdxerr/545010 to your computer and use it in GitHub Desktop.
Circular Buffer
/******************************************************************************
* FILE circular_buffer.c
*
* DESCRIPTION
*
*
* AUTHOR(S)
* C. Schniedermeier
******************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "circular_buffer.h"
circular_buffer *cb_init(size_t capacity, size_t size)
{
circular_buffer * cb;
cb = (circular_buffer *)malloc(sizeof(circular_buffer));
if(cb != 0)
{
cb->buffer = malloc(capacity * size);
cb->head = 0;
cb->tail = 0;
cb->capacity = capacity;
cb->size = size;
cb->count = 0;
}
return cb;
}
unsigned int cb_enqueue(circular_buffer *cb, void *item)
{
if(cb->count) cb->tail = (cb->tail + 1) & (cb->capacity - 1);
if((cb->count > 1) & (cb->head == cb->tail))
cb->head = (cb->head + 1) & (cb->capacity - 1);
memcpy(cb->buffer + cb->tail * cb->size, item, cb->size);
if(cb->count < cb->capacity) cb->count++;
return cb->count;
}
unsigned int cb_dequeue(circular_buffer *cb, void *item)
{
if(cb->count <= 0)
{
return 0;
}
memcpy(item, cb->buffer + cb->head * cb->size, cb->size);
cb->head = (cb->head + 1) & (cb->capacity - 1);
cb->count--;
return cb->count;
}
unsigned int cb_pop_front(circular_buffer *cb, void *item)
{
if(cb->count <= 0)
{
return 0;
}
memcpy(item, cb->buffer + cb->tail * cb->size, cb->size);
cb->tail = (cb->tail - 1) & (cb->capacity - 1);
cb->count--;
return cb->count;
}
/* clones circular buffer, but not the items in it! */
void cb_clone(circular_buffer *dst, circular_buffer *src)
{
memcpy(dst, src, sizeof(circular_buffer));
}
int cb_empty(circular_buffer * cb)
{
return cb->count <= 0;
}
int cb_full(circular_buffer *cb)
{
return cb->count >= cb->capacity;
}
void *cb_head(circular_buffer * cb)
{
return cb->buffer + cb->head * cb->size;
}
void *cb_tail(circular_buffer *cb)
{
return cb->buffer + cb->tail * cb->size;
}
circular_buffer_iterator *cb_head_iterator(circular_buffer * cb)
{
if(cb->count == 0)
{
return 0x0;
}
circular_buffer_iterator *cbi;
cbi = malloc(sizeof(circular_buffer_iterator));
cbi->cb = cb;
cbi->pos = cb->head;
return cbi;
}
circular_buffer_iterator *cb_tail_iterator(circular_buffer *cb)
{
if(cb->count == 0)
{
return 0x0;
}
circular_buffer_iterator *cbi;
cbi = malloc(sizeof(circular_buffer_iterator));
cbi->cb = cb;
cbi->pos = cb->tail;
return cbi;
}
void *cbi_get(circular_buffer_iterator *cbi)
{
return cbi->cb->buffer + cbi->pos * cbi->cb->size;
}
void *cbi_next(circular_buffer_iterator *cbi)
{
void *item;
item = cbi->cb->buffer + cbi->pos * cbi->cb->size;
cbi->pos = (cbi->pos + 1) & (cbi->cb->capacity - 1);
return item;
}
void *cbi_prev(circular_buffer_iterator *cbi)
{
void *item;
item = cbi->cb->buffer + cbi->pos * cbi->cb->size;
cbi->pos = (cbi->pos - 1) & (cbi->cb->capacity - 1);
return item;
}
int cbi_is_head(circular_buffer_iterator *cbi)
{
return cbi->pos == cbi->cb->head;
}
int cbi_is_tail(circular_buffer_iterator *cbi)
{
return cbi->pos == cbi->cb->tail;
}
void cb_free(circular_buffer *cb)
{
free(cb->buffer);
free(cb);
}
/*
circular_buffer *cb_bsearch(circular_buffer *cb,
const void *key,
int (*compare)(const void *, const void *))
{
void *bsearch(const void *key,
const void *base,
size_t nmemb,
size_t size,
int (*compare)(const void *, const void *));
}*/
/******************************************************************************
* FILE circular_buffer.h
*
* DESCRIPTION
*
*
* AUTHOR(S)
* C. Schniedermeier
******************************************************************************/
#ifndef _CIRCULAR_BUFFER_H
#define _CIRCULAR_BUFFER_H
typedef struct _circular_buffer circular_buffer;
typedef struct _circular_buffer_iterator circular_buffer_iterator;
struct _circular_buffer
{
void *buffer;
unsigned int head;
unsigned int tail;
size_t capacity; // maximum number of items in the buffer
size_t size; // size of each item in the buffer
size_t count; // number of items in the buffer
};
struct _circular_buffer_iterator
{
circular_buffer *cb;
unsigned int pos;
};
struct _circular_buffer_range
{
circular_buffer *cb;
unsigned int head;
unsigned int tail;
};
circular_buffer *cb_init(size_t capacity, size_t size);
unsigned int cb_enqueue(circular_buffer *cb, void *item);
unsigned int cb_dequeue(circular_buffer *cb, void *item);
unsigned int cb_pop_front(circular_buffer * cb, void * item);
void cb_clone(circular_buffer *dst, circular_buffer *src);
int cb_empty(circular_buffer *cb);
int cb_full(circular_buffer *cb);
void *cb_head(circular_buffer *cb);
void *cb_tail(circular_buffer *cb);
circular_buffer_iterator *cb_head_iterator(circular_buffer * cb);
circular_buffer_iterator *cb_tail_iterator(circular_buffer *cb);
void *cbi_get(circular_buffer_iterator *cbi);
void *cbi_next(circular_buffer_iterator *cbi);
void *cbi_prev(circular_buffer_iterator *cbi);
int cbi_is_head(circular_buffer_iterator *cbi);
int cbi_is_tail(circular_buffer_iterator *cbi);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment