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