quickdev16/poc/fastlz/ringbuffer.h
2016-05-22 15:15:04 +02:00

81 lines
1.9 KiB
C

/* Philip Thrasher's Crazy Awesome Ring Buffer Macros!
*
* Below you will find some naughty macros for easy owning and manipulating
* generic ring buffers. Yes, they are slightly evil in readability, but they
* are really fast, and they work great.
*
* Example usage:
*
* #include <stdio.h>
*
* // So we can use this in any method, this gives us a typedef
* // named 'intBuffer'.
* ringBuffer_typedef(int, intBuffer);
*
* int main() {
* // Declare vars.
* intBuffer myBuffer;
*
* bufferInit(myBuffer,1024,int);
*
* // We must have the pointer. All of the macros deal with the pointer.
* // (except for init.)
* intBuffer* myBuffer_ptr;
* myBuffer_ptr = &myBuffer;
*
* // Write two values.
* bufferWrite(myBuffer_ptr,37);
* bufferWrite(myBuffer_ptr,72);
*
* // Read a value into a local variable.
* int first;
* bufferRead(myBuffer_ptr,first);
* assert(first == 37); // true
*
* int second;
* bufferRead(myBuffer_ptr,second);
* assert(second == 72); // true
*
* return 0;
* }
*
*/
#ifndef _ringbuffer_h
#define _ringbuffer_h
#define ringBuffer_typedef(T, NAME) \
typedef struct { \
int size; \
int start; \
int end; \
T* elems; \
} NAME
#define bufferInit(BUF, S, T) \
BUF.size = S+1; \
BUF.start = 0; \
BUF.end = 0; \
BUF.elems = (T*)calloc(BUF.size, sizeof(T))
#define bufferDestroy(BUF) free(BUF->elems)
#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size)
#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size)
#define isBufferEmpty(BUF) (BUF->end == BUF->start)
#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start)
#define bufferWrite(BUF, ELEM) \
BUF->elems[BUF->end] = ELEM; \
BUF->end = (BUF->end + 1) % BUF->size; \
if (isBufferEmpty(BUF)) { \
BUF->start = nextStartIndex(BUF); \
}
#define bufferRead(BUF, ELEM) \
ELEM = BUF->elems[BUF->start]; \
BUF->start = nextStartIndex(BUF);
#endif