mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 06:22:44 +08:00
167 lines
3.8 KiB
C++
167 lines
3.8 KiB
C++
#include "MemoryManager.h"
|
||
|
||
static void *InternalGetMem (unsigned int nSize )
|
||
{
|
||
return malloc( nSize );
|
||
}
|
||
|
||
static void InternalFreeMem(void* pMem)
|
||
{
|
||
free( pMem );
|
||
}
|
||
|
||
|
||
|
||
//MMgrNew
|
||
|
||
//сзодает новые MMgr объект. Если при выделении памяти возникают ошибки,
|
||
//возвращает NULL и создается функци ошибки(error handling function).
|
||
//Если nBufSize не нулевой, MMgr формуируется для выделения памяти
|
||
|
||
MMgr MMgrNew (Error oError, unsigned int nBufSize, AllocFunc pAllocFn, FreeFunc pFreeFn)
|
||
{
|
||
MMgr oMMgr;
|
||
|
||
if ( pAllocFn )
|
||
oMMgr = ( MMgr ) pAllocFn (sizeof( MMgrRec ));
|
||
else
|
||
oMMgr = ( MMgr )InternalGetMem (sizeof( MMgrRec ));
|
||
|
||
if (oMMgr != NULL)
|
||
{
|
||
// инициализируем oMMgr объект
|
||
oMMgr->oError = oError;
|
||
|
||
// Если pAllocFn и pFreeFn определены, тогда используются они.
|
||
// А если нет, используются стандартные функции "malloc" и "free".
|
||
|
||
if ( pAllocFn && pFreeFn )
|
||
{
|
||
oMMgr->pAllocFn = pAllocFn;
|
||
oMMgr->pFreeFn = pFreeFn;
|
||
}
|
||
else
|
||
{
|
||
oMMgr->pAllocFn = InternalGetMem;
|
||
oMMgr->pFreeFn = InternalFreeMem;
|
||
}
|
||
|
||
//Если nBufSize не нулевой, MMgr формурируется для выделения памяти
|
||
|
||
if ( !nBufSize)
|
||
oMMgr->pMPool = NULL;
|
||
else
|
||
{
|
||
MPoolNode pNode;
|
||
|
||
pNode = (MPoolNode)oMMgr->pAllocFn( sizeof(MPoolNodeRec) + nBufSize );
|
||
|
||
if ( NULL == pNode )
|
||
{
|
||
SetError( oError, AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM, NOERROR);
|
||
oMMgr->pFreeFn( oMMgr );
|
||
oMMgr = NULL;
|
||
}
|
||
else
|
||
{
|
||
oMMgr->pMPool = pNode;
|
||
pNode->pBuffer = (BYTE *)pNode + sizeof( MPoolNodeRec );
|
||
pNode->nSize = nBufSize;
|
||
pNode->nUsedSize = 0;
|
||
pNode->pNextNode = NULL;
|
||
}
|
||
}
|
||
|
||
oMMgr->nBufSize = nBufSize;
|
||
oMMgr->pDoc = NULL;
|
||
}
|
||
else
|
||
SetError( oError, AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM, NOERROR);
|
||
|
||
return oMMgr;
|
||
}
|
||
|
||
|
||
void MMgrFree(MMgr oMMgr )
|
||
{
|
||
MPoolNode pNode;
|
||
|
||
if ( oMMgr == NULL )
|
||
return;
|
||
|
||
pNode = oMMgr->pMPool;
|
||
|
||
// удаляем все вершины рекурсивно
|
||
while ( NULL != pNode )
|
||
{
|
||
MPoolNode pTmp = pNode;
|
||
pNode = pTmp->pNextNode;
|
||
|
||
oMMgr->pFreeFn( pTmp );
|
||
}
|
||
oMMgr->pFreeFn( oMMgr );
|
||
}
|
||
|
||
void*GetMem (MMgr oMMgr, unsigned int nSize )
|
||
{
|
||
void *ptr;
|
||
|
||
if ( oMMgr->pMPool )
|
||
{
|
||
MPoolNode pNode = oMMgr->pMPool;
|
||
|
||
#ifdef ALINMENT_SIZ
|
||
nSize = ( nSize + (ALINMENT_SIZ - 1) ) / ALINMENT_SIZ;
|
||
nSize *= ALINMENT_SIZ;
|
||
#endif
|
||
|
||
if ( pNode->nSize - pNode->nUsedSize >= nSize )
|
||
{
|
||
ptr = (BYTE*)pNode->pBuffer + pNode->nUsedSize;
|
||
pNode->nUsedSize += nSize;
|
||
return ptr;
|
||
}
|
||
else
|
||
{
|
||
unsigned int nTmpBufSize = ( oMMgr->nBufSize < nSize) ? nSize : oMMgr->nBufSize;
|
||
|
||
pNode = (MPoolNode)oMMgr->pAllocFn( sizeof(MPoolNodeRec) + nTmpBufSize );
|
||
|
||
if ( !pNode )
|
||
{
|
||
SetError( oMMgr->oError, AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM, NOERROR);
|
||
return NULL;
|
||
}
|
||
|
||
pNode->nSize = nTmpBufSize;
|
||
}
|
||
|
||
pNode->pNextNode = oMMgr->pMPool;
|
||
oMMgr->pMPool = pNode;
|
||
pNode->nUsedSize = nSize;
|
||
pNode->pBuffer = (BYTE*)pNode + sizeof(MPoolNodeRec);
|
||
ptr = pNode->pBuffer;
|
||
}
|
||
else
|
||
{
|
||
ptr = oMMgr->pAllocFn( nSize );
|
||
|
||
if ( NULL == ptr )
|
||
SetError(oMMgr->oError, AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM, NOERROR);
|
||
}
|
||
|
||
return ptr;
|
||
}
|
||
|
||
void FreeMem (MMgr oMMgr, void *aptr)
|
||
{
|
||
if ( !aptr )
|
||
return;
|
||
|
||
if ( !oMMgr->pMPool )
|
||
{
|
||
oMMgr->pFreeFn( aptr );
|
||
}
|
||
return;
|
||
}
|