Files
sics/sdynar.c
koennecke 91d4af0541 - Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
2009-02-13 09:00:03 +00:00

186 lines
4.2 KiB
C

/*---------------------------------------------------------------------------
D Y N A M I C A R R A Y
Implementation file for a dynamically resizing array of void pointers.
Mark Koennecke, September 1997
copyright: see copyright.h
-----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "fortify.h"
#include "sdynar.h"
#include "sdynar.i"
/*---------------------------------------------------------------------------*/
pDynar CreateDynar(int iStart, int iEnd, int iGrain,
void (*DataFree) (void *pData))
{
pDynar pNew = NULL;
int iSize;
pNew = (pDynar) malloc(sizeof(Dynar));
if (!pNew) {
return NULL;
}
memset(pNew, 0, sizeof(Dynar));
pNew->iStart = iStart;
pNew->iEnd = iEnd;
pNew->iGrain = iGrain;
pNew->DataFree = DataFree;
iSize = iEnd - iStart;
assert(iSize > 0);
pNew->pArray = (void **) malloc(iSize * sizeof(void *));
if (!pNew->pArray) {
free(pNew);
return NULL;
}
memset(pNew->pArray, 0, iSize * sizeof(void *));
return pNew;
}
/*----------------------------------------------------------------------------*/
void DeleteDynar(pDynar self)
{
int i, iSize;
assert(self);
iSize = self->iEnd - self->iStart;
for (i = 0; i < iSize; i++) {
if (self->pArray[i]) {
if (self->DataFree) {
self->DataFree(self->pArray[i]);
}
}
}
free(self->pArray);
free(self);
}
/*---------------------------------------------------------------------------*/
static int DynarResize(pDynar self, int iRequest)
{
void **pNew = NULL;
int i, iNewStart, iNewEnd, iOldSize, iNewSize, iOffset;
assert(self);
iOldSize = self->iEnd - self->iStart;
iNewStart = self->iStart;
iNewEnd = self->iEnd;
if (iRequest <= self->iStart) {
iNewStart -= self->iGrain;
}
if (iRequest >= (self->iEnd - 1)) {
iNewEnd += self->iGrain;
}
iNewSize = iNewEnd - iNewStart;
pNew = (void **) malloc(iNewSize * sizeof(void *));
if (!pNew) {
return 0;
}
memset(pNew, 0, iNewSize * sizeof(void *));
iOffset = self->iStart - iNewStart;
if (iOffset < 0) {
iOffset = -iOffset;
}
for (i = 0; i < iOldSize; i++) {
pNew[i + iOffset] = self->pArray[i];
}
self->iStart = iNewStart;
self->iEnd = iNewEnd;
free(self->pArray);
self->pArray = pNew;
return 1;
}
/*----------------------------------------------------------------------------*/
int DynarPut(pDynar self, int iIndex, void *pData)
{
int iReal, iRet;
assert(self);
if ((iIndex < self->iStart) || (iIndex > self->iEnd - 1)) {
iRet = DynarResize(self, iIndex);
if (!iRet) {
return 0;
}
}
iReal = iIndex - self->iStart;
if (self->pArray[iReal]) {
if (self->DataFree) {
self->DataFree(self->pArray[iReal]);
}
}
self->pArray[iReal] = pData;
return 1;
}
/*-------------------------------------------------------------------------*/
int DynarPutCopy(pDynar self, int iIndex, void *pBuffer, int iDataLen)
{
char *pPtr = NULL;
pPtr = (char *) malloc(iDataLen);
if (!pPtr) {
return 0;
}
memcpy(pPtr, pBuffer, iDataLen);
return DynarPut(self, iIndex, pPtr);
}
/*--------------------------------------------------------------------------*/
int DynarReplace(pDynar self, int iIndex, void *pData, int iDataLen)
{
int iReal, iRet;
assert(self);
if ((iIndex < self->iStart) || (iIndex >= self->iEnd - 1)) {
iRet = DynarResize(self, iIndex);
if (!iRet) {
return 0;
}
}
iReal = iIndex - self->iStart;
if (self->pArray[iReal]) {
memcpy(self->pArray[iReal], pData, iDataLen);
return 1;
} else {
return DynarPutCopy(self, iIndex, pData, iDataLen);
}
}
/*---------------------------------------------------------------------------*/
int DynarGet(pDynar self, int iIndex, void **pData)
{
int iReal;
assert(self);
iReal = iIndex - self->iStart;
*pData = self->pArray[iReal];
return 1;
}
/*-------------------------------------------------------------------------*/
int DynarGetCopy(pDynar self, int iIndex, void *pData, int iDataLen)
{
int iReal;
assert(self);
iReal = iIndex - self->iStart;
memcpy(pData, self->pArray[iReal], iDataLen);
return 1;
}