#ifndef __RING_BUFFER_H__#define __RING_BUFFER_H__//------------------------------------------------------------------------------// External functions//------------------------------------------------------------------------------void BSP_Lock( void );void BSP_Unlock( void );typedef struct{ unsigned char * buffer; unsigned int capacity; unsigned int pointer; unsigned int count;} ring_buffer_t;ring_buffer_t *ring_buffer_create( unsigned int size );void ring_buffer_delete( ring_buffer_t *ring_buffer );void ring_buffer_init( ring_buffer_t *ring_buffer, unsigned char * buffer, unsigned int capacity );void ring_buffer_clear( ring_buffer_t *ring_buffer );unsigned int ring_buffer_readable( ring_buffer_t *ring_buffer );unsigned int ring_buffer_writable( ring_buffer_t *ring_buffer );void ring_buffer_flush( ring_buffer_t *ring_buffer, unsigned int bytes );unsigned int ring_buffer_read( ring_buffer_t *ring_buffer, unsigned char *data, unsigned int length );unsigned int ring_buffer_write( ring_buffer_t *ring_buffer, const unsigned char *data, unsigned int length );unsigned int ring_buffer_full( ring_buffer_t *ring_buffer );unsigned int ring_buffer_empty( ring_buffer_t *ring_buffer );#endif /* __RING_BUFFER_H__ */
#include "ring_buffer.h"#include#include unsigned int ring_buffer_readable( ring_buffer_t *ring_buffer ){ return ring_buffer->count;}unsigned int ring_buffer_writable( ring_buffer_t *ring_buffer ){ return ring_buffer->capacity - ring_buffer->count;}unsigned int ring_buffer_full( ring_buffer_t *ring_buffer ){ return ring_buffer->count == ring_buffer->capacity;}unsigned int ring_buffer_empty( ring_buffer_t *ring_buffer ){ return ring_buffer->count == 0;}unsigned int ring_buffer_read( ring_buffer_t *ring_buffer, unsigned char *data, unsigned int length ){ unsigned int buffer_readable = ring_buffer_readable( ring_buffer ); unsigned int bytes_read = length; if ( bytes_read > buffer_readable ) bytes_read = buffer_readable; if ( bytes_read == 0 ) return 0; // -----------RRRRRRRRRRRR if ( ring_buffer->pointer + bytes_read <= ring_buffer->capacity ) memcpy( data, ring_buffer->buffer + ring_buffer->pointer, bytes_read ); else // RRRRRR--------------RRRRR { unsigned int upper = ring_buffer->capacity - ring_buffer->pointer; unsigned int lower = bytes_read - upper; memcpy( data, ring_buffer->buffer + ring_buffer->pointer, upper ); memcpy( data + upper, ring_buffer->buffer, lower ); } BSP_Lock( ); ring_buffer->pointer = ( ring_buffer->pointer + bytes_read ) % ring_buffer->capacity; ring_buffer->count -= bytes_read; BSP_Unlock( ); return bytes_read;}unsigned int ring_buffer_write( ring_buffer_t *ring_buffer, const unsigned char *data, unsigned int length ){ unsigned int bytes_written = length; unsigned int buffer_writable = ring_buffer_writable( ring_buffer ); if ( bytes_written > buffer_writable ) bytes_written = buffer_writable; if ( bytes_written == 0 ) return 0; unsigned int write_position = ( ring_buffer->pointer + ring_buffer->count ) % ring_buffer->capacity; // --------WWWWWWWW--- if ( write_position + bytes_written <= ring_buffer->capacity ) memcpy( ring_buffer->buffer + write_position, data, bytes_written ); else // WWWWWWW-------WWWW { unsigned int upper = ring_buffer->capacity - write_position; unsigned int lower = bytes_written - upper; memcpy( ring_buffer->buffer + write_position, data, upper ); memcpy( ring_buffer->buffer, data + upper, lower ); } BSP_Lock( ); ring_buffer->count += bytes_written; BSP_Unlock( ); return bytes_written;}void ring_buffer_flush( ring_buffer_t *ring_buffer, unsigned int length ){ // we can't flush more bytes than there are BSP_Lock( ); if ( length > (unsigned int) ring_buffer->count ) length = ring_buffer->count; ring_buffer->count -= length; ring_buffer->pointer = ( ring_buffer->pointer + length ); ring_buffer->pointer %= ring_buffer->capacity; BSP_Unlock( );}void ring_buffer_clear( ring_buffer_t *ring_buffer ){ BSP_Lock( ); ring_buffer->count = 0; ring_buffer->pointer = 0; BSP_Unlock( );}void ring_buffer_init( ring_buffer_t *ring_buffer, unsigned char * buffer, unsigned int capacity ){ ring_buffer->buffer = buffer; ring_buffer->capacity = capacity; ring_buffer_clear( ring_buffer );}ring_buffer_t * ring_buffer_create( unsigned int size ){ void * p = malloc( sizeof(ring_buffer_t) + size ); ring_buffer_t *ring_buffer = (ring_buffer_t *) p; if ( ring_buffer == NULL ) return NULL; ring_buffer->capacity = size; ring_buffer_clear( ring_buffer ); return ring_buffer;}void ring_buffer_delete( ring_buffer_t *ring_buffer ){ free( ring_buffer );}