Show CircularBuffer.c syntax highlighted
#include "CircularBuffer.h"
#include <strings.h>
#include <assert.h>
#define assertPtr(PTR) assert(PTR)
#define GenerateAssertions 1
#if GenerateAssertions
static void AssertCircularBuffer( CircularBuffer *circularBuffer ) {
assertPtr( circularBuffer );
assertPtr( circularBuffer->head );
assertPtr( circularBuffer->tail );
assertPtr( circularBuffer->read );
assertPtr( circularBuffer->write );
assert( circularBuffer->tail > circularBuffer->head );
assert( circularBuffer->read >= circularBuffer->head );
assert( circularBuffer->read <= circularBuffer->tail );
assert( circularBuffer->write >= circularBuffer->head );
assert( circularBuffer->write <= circularBuffer->tail );
}
#else
#define AssertCircularBuffer( circularBuffer )
#endif
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Oct 18, 2002 Created.
************************************************************************************/
void
CircularBufferInit(
CircularBuffer *circularBuffer,
void *buffer,
size_t bufferSize )
{
assertPtr( circularBuffer );
assertPtr( buffer );
assert( bufferSize > 2 );
circularBuffer->head = (int8_t*) buffer;
circularBuffer->tail = ((int8_t*) buffer) + bufferSize;
circularBuffer->read = (int8_t*) buffer;
circularBuffer->write = (int8_t*) buffer;
circularBuffer->refcon = NULL;
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Oct 18, 2002 Created.
************************************************************************************/
size_t
CircularBufferDataSize(
CircularBuffer *circularBuffer )
{
size_t result;
AssertCircularBuffer( circularBuffer );
if( circularBuffer->read < circularBuffer->write ) {
// Read pointer is below write pointer: nonfragmented state.
result = circularBuffer->write - circularBuffer->read;
} else if( circularBuffer->read > circularBuffer->write ) {
// Read pointer is above write pointer: fragmented state.
result = (circularBuffer->tail - circularBuffer->read) + (circularBuffer->write - circularBuffer->head);
} else {
// They're equal.
result = 0;
}
assert( result >= 0 );
//assert( result < 20 * 1024 * 1024 );
return result;
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Oct 18, 2002 Created.
************************************************************************************/
size_t
CircularBufferSpaceSize(
CircularBuffer *circularBuffer )
{
size_t result;
AssertCircularBuffer( circularBuffer );
if( circularBuffer->read < circularBuffer->write ) {
// Read pointer is below write pointer: nonfragmented state.
result = (circularBuffer->tail - circularBuffer->write) + (circularBuffer->read - circularBuffer->head);
} else if( circularBuffer->read > circularBuffer->write ) {
// Read pointer is above write pointer: fragmented state.
result = circularBuffer->read - circularBuffer->write;
} else {
// They're equal.
result = circularBuffer->tail - circularBuffer->head;
}
assert( result >= 0 );
//assert( result < 20 * 1024 * 1024 );
return result;
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Oct 18, 2002 Created.
************************************************************************************/
#define CircularBufferMin( X, Y ) ((X) < (Y)) ? (X) : (Y)
int // boolean (success)
CircularBufferWrite(
CircularBuffer *circularBuffer,
const void *buffer,
size_t bufferSize )
{
size_t upperSpaceSize, firstCopySize, secondCopySize;
AssertCircularBuffer( circularBuffer );
assertPtr( buffer );
if( bufferSize > CircularBufferSpaceSize( circularBuffer ) )
return 0;
if( circularBuffer->read <= circularBuffer->write ) {
// Read pointer is below or equal to write pointer: nonfragmented state.
upperSpaceSize = circularBuffer->tail - circularBuffer->write;
firstCopySize = CircularBufferMin( bufferSize, upperSpaceSize );
secondCopySize = bufferSize - firstCopySize;
bcopy( buffer, circularBuffer->write, firstCopySize );
if( secondCopySize ) {
bcopy( ((int8_t*) buffer) + firstCopySize, circularBuffer->head, secondCopySize );
circularBuffer->write = circularBuffer->head + secondCopySize;
} else {
circularBuffer->write += firstCopySize;
}
} else {
// Read pointer is above write pointer: fragmented state.
bcopy( buffer, circularBuffer->write, bufferSize );
circularBuffer->write += bufferSize;
}
return 1;
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Oct 18, 2002 Created.
************************************************************************************/
size_t
CircularBufferRead(
CircularBuffer *circularBuffer,
void *buffer,
size_t readSize )
{
size_t dataSize, actualReadSize, upperDataSize, firstCopySize, secondCopySize;
AssertCircularBuffer( circularBuffer );
dataSize = CircularBufferDataSize( circularBuffer );
actualReadSize = CircularBufferMin( dataSize, readSize );
if( circularBuffer->read <= circularBuffer->write ) {
// Read pointer is below or equal to write pointer: nonfragmented state.
bcopy( circularBuffer->read, buffer, actualReadSize );
circularBuffer->read += actualReadSize;
} else {
// Read pointer is above write pointer: fragmented state.
upperDataSize = circularBuffer->tail - circularBuffer->read;
firstCopySize = CircularBufferMin( actualReadSize, upperDataSize );
secondCopySize = actualReadSize - firstCopySize;
bcopy( circularBuffer->read, buffer, firstCopySize );
if( secondCopySize ) {
bcopy( circularBuffer->head, ((int8_t*) buffer) + firstCopySize, secondCopySize );
circularBuffer->read = circularBuffer->head + secondCopySize;
} else {
circularBuffer->read += firstCopySize;
}
}
return actualReadSize;
}
See more files for this project here