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 );
}