Code Search for Developers
 
 
  

CircularBuffer.c from redshed at Krugle


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

redshed

Code for Mac+WebObjects.

Project homepage: http://sourceforge.net/projects/redshed
Programming language(s): C,Java,Objective C
License: other

  CircularBuffer.xcodeproj/
    project.pbxproj
    wolf.mode1
    wolf.pbxuser
  CircularBuffer.c
  CircularBuffer.h
  TestCircularBuffer.c