Initial revision
This commit is contained in:
198
sdynar.c
Normal file
198
sdynar.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user