queues.c

#include <stdio.h>
#include <stdlib.h>

typedef struct _tagQUE {
	char *Body;	/* Body points to the base of where the data elements will be stored */
	unsigned int Head, /* Head is where data is added */
		Tail, 	/* Tail is where data is removed */
		Size;	/* Size indicates how many elements (minus 1) the Queue can hold */
	} QUE;

enum ErrCode { ERR_OK, ERR_FULL, ERR_EMPTY };

/*********************************************************************************
** Name:	QueIsFull
** Descr:	Determines if Que is full
** Params:	q = The QUE to check
** Returns:	1(true) if the que is full, 0(false) if not
*********************************************************************************/
#define QueIsFull(q) (QueNextHead(q)==q->Tail)
/*********************************************************************************
** Name:	QueIsEmpty
** Descr:	Determines if Que is empty
** Params:	q = The QUE to check
** Returns:	1(true) if the que is empty, 0(false) if not
*********************************************************************************/
#define QueIsEmpty(q) ((q)->Head==(q)->Tail)

/*********************************************************************************
** Name:	QueNextTail
** Descr:	Returns the value of the next Tail position for a que
** Params:	q = The QUE to get the next tail position for
** Returns:	The next tail position for q
*********************************************************************************/
#define QueNextTail(q) (((q)->Tail+1)%(q)->Size)
/*********************************************************************************
** Name:	QueNextHead
** Descr:	Returns the value of the next Head position for a que
** Params:	q = The QUE to get the next head position for
** Returns:	The head tail position for q
*********************************************************************************/
#define QueNextHead(q) (((q)->Head+1)%(q)->Size)

/*********************************************************************************
** Name:	QueConstruct
** Descr:	Constructs a new QUE structure
** Params:	Size = Number of elements the new should be able to hold
** Returns:	NULL upon failure, or the pointer to a new QUE structure
*********************************************************************************/
QUE *QueConstruct( int Size )
{
	QUE *Que;
	if( (Que=calloc(1,sizeof(QUE))) != NULL )
	{
		if( (Que->Body=calloc(Size+1, sizeof( char ))) != NULL )
			Que->Size=(unsigned int)Size+1; /* +1 because one element is always unavailable */
		else
		{
			free( Que );	/* Cleanup if error */
			return(NULL);
		}
	}
	return( Que );
}

/*********************************************************************************
** Name:	QueDestruct
** Descr:	Removes a QUE from memory
** Params:	Que = The QUE to be removed
** Returns:	Nothing
*********************************************************************************/
void QueDestruct( QUE *Que )
{
	free( Que->Body );	/* Free body, then controling structure */
	free( Que );
}

/*********************************************************************************
** Name:	QueAdd
** Descr:	Adds a value to a QUE structure
** Params:	Que = The QUE to receive the data
** 			Value: The value to add to 'Que'
** Returns:	ERR_OK upon success, an error code upon failure
*********************************************************************************/
int QueAdd( QUE *Que, int Value )
{
	if( QueIsFull( Que ) )
		return(ERR_FULL);
	Que->Body[Que->Head]=Value;
	Que->Head = QueNextHead(Que);
	return(ERR_OK);
}

/*********************************************************************************
** Name:	QueRemove
** Descr:	Removes a value from a QUE structure
** Params:	Que = The QUE to get the data from
** 			Dest: Pointer to where to store the retrieved value
** Returns:	ERR_OK upon success, an error code upon failure
*********************************************************************************/
int QueRemove(QUE *Que, char *Dest)
{
	if( QueIsEmpty( Que ) )
		return(ERR_EMPTY);
	*Dest=Que->Body[Que->Tail];
	Que->Tail = QueNextTail(Que);
	return(ERR_OK);
}

/*********************************************************************************
** Name:	main
** Descr:	Test program for the QUE structure and code
** Params:	Nothing
** Returns:	Nothing
*********************************************************************************/
void main( void )
{
	QUE *Q;
	char Ch;
	Q=QueConstruct(2);
	printf("%d\n", QueAdd(Q,'A') );
	printf("%d\n", QueAdd(Q,'B') );
	printf("%d\n", QueAdd(Q,'C') );
	printf("%d ", QueRemove(Q,&Ch) );
	printf("%c\n", Ch);
	printf("%d ", QueRemove(Q,&Ch) );
	printf("%c\n", Ch);
	printf("%d ", QueRemove(Q,&Ch) );
	printf("%c\n", Ch);
	QueDestruct( Q );
}