#ifndef __FIFO_H__ #define __FIFO_H__ #define CONCAT3(str1, str2, str3) str1 ## str2 ## str3 #define CONCAT4(str1, str2, str3, str4) str1 ## str2 ## str3 ## str4 #define FIFO_TYPE char #define FIFO_T(type) CONCAT3(fifo_, type, _t) #define FIFO_METHOD(type, name) CONCAT4(fifo_, type, _, name) typedef struct { FIFO_TYPE *buffer; int size; FIFO_TYPE *prius; FIFO_TYPE *follower; } FIFO_T(FIFO_TYPE); /* The mechanizm of the ring buffer. * 1) The "follower" can no reach the "prius" more than overtake it. * 2) The "prius" can reach the "follower", but can't overtake it. */ int FIFO_METHOD(FIFO_TYPE, write) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *values, int size); int FIFO_METHOD(FIFO_TYPE, read) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *buffer, int size); int FIFO_METHOD(FIFO_TYPE, size) (FIFO_T(FIFO_TYPE) *fifo); FIFO_T(FIFO_TYPE) * FIFO_METHOD(FIFO_TYPE,init) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *buffer, int size); #define NULL 0 /** * * * @param fifo * @param buffer * @param size * @return ( FIFO_T(FIFO_TYPE) ) */ FIFO_T(FIFO_TYPE) * FIFO_METHOD(FIFO_TYPE, init) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *buffer, int size){ if(size > 0){ fifo->buffer = buffer; fifo->size = size; fifo->prius = fifo->buffer; fifo->follower = fifo->buffer + size - 1; return fifo; }else{return NULL;} } /** * * * @param fifo * @param data * @param size * @return (int) */ int FIFO_METHOD(FIFO_TYPE, write) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *values, int size){ int _size = 0; if(values != NULL){ while(_size < size){ if(fifo->prius == fifo->buffer + fifo->size){fifo->prius = fifo->buffer;} if(fifo->prius == fifo->follower){break;} *((fifo->prius)++) = *(values + (_size++)); } } return _size; } /** * * * @param fifo * @param buffer * @param size * @return (int) */ int FIFO_METHOD(FIFO_TYPE, read) (FIFO_T(FIFO_TYPE) *fifo, FIFO_TYPE *buffer, int size){ int _size = 0; if(buffer != NULL){ while(_size < size){ if((fifo->follower + 1 - fifo->prius) % fifo->size == 0){break;} if(++fifo->follower == fifo->buffer + fifo->size){fifo->follower = fifo->buffer;} *(buffer + (_size++)) = *(fifo->follower); } } return _size; } /** * * * @param fifo * @return int */ int FIFO_METHOD(FIFO_TYPE, size) (FIFO_T(FIFO_TYPE) *fifo){ return (fifo->prius > fifo->follower ? fifo->prius - fifo->follower - 1: fifo->prius + fifo->size - fifo->follower - 1); } #endif /* __FIFO_H__ */