123 lines
2.9 KiB
C
123 lines
2.9 KiB
C
/*-----------------------------------------------------------------------
|
|
Implementation file for a circular buffer facility.
|
|
|
|
Mark Koennecke, October 1999
|
|
-------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "fortify.h"
|
|
#include "circular.h"
|
|
|
|
/*========================================================================
|
|
Definitions of Structures
|
|
*/
|
|
|
|
typedef struct __CircularItem {
|
|
void *pData;
|
|
struct __CircularItem *next;
|
|
struct __CircularItem *previous;
|
|
} CircularItem, *pCircularItem;
|
|
|
|
|
|
typedef struct __CIRCULAR {
|
|
pCircularItem pPointer;
|
|
CirKillFunc killer;
|
|
} Circular;
|
|
|
|
/*=========================================================================
|
|
Functions for Birth and Death
|
|
*/
|
|
pCircular createCircular(int iSize, CirKillFunc kf)
|
|
{
|
|
pCircular pNew = NULL;
|
|
pCircularItem pItem = NULL, pFirst = NULL;
|
|
int i;
|
|
|
|
|
|
assert(iSize > 0);
|
|
|
|
/* create data structure */
|
|
pNew = (pCircular) malloc(sizeof(Circular));
|
|
if (!pNew)
|
|
return NULL;
|
|
memset(pNew, 0, sizeof(Circular));
|
|
|
|
/* create all the members of the circular buffer */
|
|
pItem = (pCircularItem) malloc(sizeof(CircularItem));
|
|
if (!pItem)
|
|
return NULL;
|
|
memset(pItem, 0, sizeof(CircularItem));
|
|
pNew->pPointer = pItem;
|
|
pFirst = pItem;
|
|
for (i = 1; i < iSize; i++) {
|
|
pItem = (pCircularItem) malloc(sizeof(CircularItem));
|
|
if (!pItem)
|
|
return NULL;
|
|
memset(pItem, 0, sizeof(CircularItem));
|
|
pItem->previous = pNew->pPointer;
|
|
pNew->pPointer->next = pItem;
|
|
pNew->pPointer = pItem;
|
|
}
|
|
pItem->next = pFirst;
|
|
pFirst->previous = pItem;
|
|
pNew->killer = kf;
|
|
return pNew;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
void deleteCircular(pCircular self)
|
|
{
|
|
pCircularItem pNext = NULL, pCurrent = NULL;
|
|
|
|
assert(self);
|
|
|
|
self->pPointer->previous->next = NULL;
|
|
pNext = self->pPointer;
|
|
while (pNext != NULL) {
|
|
pCurrent = pNext;
|
|
pNext = pCurrent->next;
|
|
if (pCurrent->pData && self->killer) {
|
|
self->killer(pCurrent->pData);
|
|
}
|
|
free(pCurrent);
|
|
}
|
|
free(self);
|
|
}
|
|
|
|
/*========================================================================
|
|
Data Manipulation functions
|
|
*/
|
|
void setCircular(pCircular self, void *pData)
|
|
{
|
|
assert(self);
|
|
|
|
/* delete if present */
|
|
if (self->pPointer->pData && self->killer) {
|
|
self->killer(self->pPointer->pData);
|
|
}
|
|
self->pPointer->pData = pData;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void *getCircular(pCircular self)
|
|
{
|
|
assert(self);
|
|
return self->pPointer->pData;
|
|
}
|
|
|
|
/*========================================================================
|
|
Pointer movement
|
|
*/
|
|
void nextCircular(pCircular self)
|
|
{
|
|
assert(self);
|
|
self->pPointer = self->pPointer->next;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
void previousCircular(pCircular self)
|
|
{
|
|
assert(self);
|
|
self->pPointer = self->pPointer->previous;
|
|
}
|