/*--------------------------------------------------------------------------- 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 #include #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; }