Created
August 23, 2010 07:36
-
-
Save zdxerr/545010 to your computer and use it in GitHub Desktop.
Circular Buffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /****************************************************************************** | |
| * 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 *)); | |
| }*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /****************************************************************************** | |
| * 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