/*----------------------------------------------------------------------- Implementation file for a circular buffer facility. Mark Koennecke, October 1999 -------------------------------------------------------------------------*/ #include #include #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; }