📄 rpool.c
字号:
original size */
while (( !IS_LAST_NODE(location) )&&( count < numOfBlocks ))
{
elem = rpoolGetNode(raH,location);
location = elem->nextBlock;
count ++;
}
/* New size is smaller than at previous allocation */
if ( count == numOfBlocks )
{
/* Fix the next block of the new last element */
elem->nextBlock = SET_LAST_NODE ( (size%elemSize) ? size%elemSize : elemSize );
/* Free the tail and we're done */
rpoolFree(pool, (HRPOOLELEM)location);
return RV_OK;
}
/* New size is bigger than at previous allocation */
if ( IS_LAST_NODE(location) )
{
/* Allocate the additional space needed */
if ((contLocation = (int)rpoolAlloc(pool, (size - count*elemSize)) ) < 0)
return contLocation;
/* Link the new allocation with the old one */
elem->nextBlock = contLocation;
return RV_OK;
}
return RV_ERROR_UNKNOWN;
}
/************************************************************************
* rpoolAppend
* purpose: Append a chunk of memory to an RPOOL element, leaving any old
* bytes with the same value they had previously and setting new
* allocated bytes to zero.
* input : pool - RPOOL handle
* src - Element in RPOOL ot reallocate
* size - Size of append in bytes. If set to RV_INT_MAX then
* the maximum non-fragmented block will be allocated.
* output : lastSize - Last size of the RPOOL element
* appendedDataPtr - Pointer to memory of the appended chunk
* return : Non-negative value on success (which states the size of non-
* fragmented memory that can be accessed with appenedDataPtr,
* other on failure.
************************************************************************/
int rpoolAppend(
IN HRPOOL pool,
IN HRPOOLELEM ptr,
IN int size,
OUT int* lastSize,
OUT RvUint8** appendedDataPtr)
{
HRA raH = (HRA)pool;
int numOfBlocks;
int elemSize, lastNodeSize;
int contLocation, location;
int retSize;
rpoolElem* elem = NULL;
if(( ! pool ) || (! size))
return RV_ERROR_NULLPTR;
location = RPOOL_LOCATION(ptr);
elemSize = RPOOL_ELEM_SIZE(raElemSize(raH));
numOfBlocks = RPOOL_BLOCKS(size,elemSize);
*lastSize = 0;
/* Get to the end of this RPOOL element */
while ( !IS_LAST_NODE(location) )
{
elem = rpoolGetNode(raH,location);
location = elem->nextBlock;
*lastSize += elemSize;
}
/* Get the size of the last node in list and remove from our *lastSize counter */
lastNodeSize = GET_LAST_NODE_SIZE(location);
if (lastNodeSize < elemSize)
*lastSize -= (elemSize - lastNodeSize);
if (size == RV_INT_MAX)
{
/* We want to give the biggest non-fragmented size */
if (lastNodeSize < elemSize)
size = elemSize - lastNodeSize;
else
size = elemSize;
}
retSize = size;
/* Allocate the additional space needed */
size += lastNodeSize;
if (size > elemSize)
{
/* We have to allocate more nodes from RA */
if ((contLocation = (int)rpoolAlloc(pool, (size - elemSize))) < 0)
return contLocation;
if (lastNodeSize == elemSize)
*appendedDataPtr = (RvUint8*)&(rpoolGetNode(raH, contLocation)->data);
else
*appendedDataPtr = ((RvUint8*)&elem->data) + lastNodeSize;
/* Link the new allocation with the old one */
elem->nextBlock = contLocation;
}
else
{
elem->nextBlock = SET_LAST_NODE(size);
*appendedDataPtr = ((RvUint8*)&elem->data) + lastNodeSize;
}
return retSize;
}
/************************************************************************
* rpoolFree
* purpose: Free an element allocation in RPOOL
* input : pool - RPOOL handle
* ptr - Element in RPOOL
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rpoolFree(
IN HRPOOL pool,
IN HRPOOLELEM ptr)
{
HRA raH = (HRA)pool;
int next, location;
rpoolElem *elem;
if ( ! pool ) return RV_ERROR_UNKNOWN;
location = RPOOL_LOCATION(ptr);
if (INVALID_LOCATION(raH,location)) return RV_ERROR_UNKNOWN;
while (!IS_LAST_NODE(location))
{
location=RPOOL_NODE_ID(location);
elem = rpoolGetNode(raH,location);
if (elem != NULL)
next = elem->nextBlock;
else
next = -1;
raDeleteLocation(raH, location);
location = next;
}
return RV_TRUE;
}
/* Internal Operations */
/************************************************************************
* rpoolCopyFromExternal
* purpose: Copy an external memory buffer into an RPOOL element
* input : pool - RPOOL handle
* dest - Element in RPOOL to copy to
* src - Source buffer in memory
* shift - Offset in RPOOL block to copy to
* size - Size of buffer to copy
* output : none
* return : Destination element on success
* NULL on failure
************************************************************************/
HRPOOLELEM rpoolCopyFromExternal(
IN HRPOOL pool,
IN HRPOOLELEM dest,
IN const void* src,
IN int shift,
IN int size)
{
HRA raH = (HRA)pool;
RvSize_t elemSize, tmpSize;
int location, i, shiftBlocks;
rpoolElem *elem;
int srcShift=0;
if(( !pool ) || ( !src ) || ( !size ))return NULL;
location = RPOOL_LOCATION(dest);
if (INVALID_LOCATION(raH,location)) return NULL;
/* Calculate the number of blocks we want to skip */
tmpSize = 0;
elemSize = RPOOL_ELEM_SIZE(raElemSize(raH));
shiftBlocks = RPOOL_BLOCKS(shift,elemSize);
for ( i=0;!IS_LAST_NODE(location) && size>0; i++,location = elem->nextBlock)
{
elem=rpoolGetNode(raH,location);
if (i==shiftBlocks-1 && shift%elemSize)
{
/* First block we copy to */
tmpSize=RvMin(elemSize-shift%elemSize, (RvSize_t)size);
memcpy( (char *)&(elem->data)+(shift%elemSize), (char *)src, tmpSize);
size-=tmpSize;
}
if (i>shiftBlocks-1)
{
/* Copy full blocks */
tmpSize=RvMin(elemSize, (RvSize_t)size);
memcpy( (char *)&(elem->data), (char *)src+srcShift, tmpSize);
size-=tmpSize;
}
srcShift+=tmpSize;
}
return (dest);
}
/************************************************************************
* rpoolCopyToExternal
* purpose: Copy information from an RPOOL element to a memory buffer
* input : pool - RPOOL handle
* dest - Destination buffer in memory
* src - Element in RPOOL to copy from
* shift - Offset in RPOOL block to copy from
* size - Size of buffer to copy
* output : none
* return : Destination memory buffer on success
* NULL on failure
************************************************************************/
void* rpoolCopyToExternal(
IN HRPOOL pool,
IN void* dest,
IN HRPOOLELEM src,
IN int shift,
IN int size)
{
HRA raH = (HRA)pool;
RvSize_t elemSize, tmpSize;
int location, i, shiftBlocks;
rpoolElem *elem;
int destShift=0;
if(( !pool ) || ( !dest ) || ( !size ))return NULL;
location = RPOOL_LOCATION(src);
if (INVALID_LOCATION(raH,location)) return NULL;
/* Calculate the amount of blocks to skip before copying */
tmpSize = 0;
elemSize = RPOOL_ELEM_SIZE(raElemSize(raH));
shiftBlocks = RPOOL_BLOCKS(shift,elemSize);
for ( i=0;!IS_LAST_NODE(location) && size>0; i++,location = elem->nextBlock)
{
elem=rpoolGetNode(raH,location);
if (i==shiftBlocks-1 && shift%elemSize)
{
/* First block we're copying */
tmpSize=RvMin(elemSize-shift%elemSize, (RvSize_t)size);
memcpy( (char *)dest, (char *)&(elem->data)+(shift%elemSize), tmpSize);
size-=tmpSize;
}
if (i>shiftBlocks-1)
{
/* Copy the block */
tmpSize=RvMin(elemSize, (RvSize_t)size);
memcpy( (char *)dest+destShift, (char *)&(elem->data), tmpSize);
size-=tmpSize;
}
destShift+=tmpSize;
}
return (dest);
}
/************************************************************************
* rpoolCopyInternal
* purpose: Copy information from one RPOOL element to another
* input : pool - RPOOL handle
* dest - Element in RPOOL to copy to
* src - Element in RPOOL to copy from
* size - Size of buffer to copy
* output : none
* return : Destination memory buffer on success
* NULL on failure
************************************************************************/
HRPOOLELEM rpoolCopyInternal(
IN HRPOOL pool,
IN HRPOOLELEM dest,
IN const HRPOOLELEM src,
IN int size)
{
HRA raH = (HRA)pool;
RvSize_t elemSize;
int numOfBlocks;
int destLocation, srcLocation, i;
rpoolElem *srcElem, *destElem;
if ((! pool ) || ( ! size ))
return NULL;
srcLocation = RPOOL_LOCATION(src);
destLocation = RPOOL_LOCATION(dest);
if (INVALID_LOCATION(raH,srcLocation)) return NULL;
if (INVALID_LOCATION(raH,destLocation)) return NULL;
/* Calculate the number of blocks to copy */
elemSize = RPOOL_ELEM_SIZE(raElemSize(raH));
numOfBlocks = RPOOL_BLOCKS(size,elemSize);
/* Go through the blocks until we're done or until we don't have any more nodes in dest or src */
for(i = 0; (!IS_LAST_NODE(destLocation) && !IS_LAST_NODE(srcLocation) && (i < numOfBlocks)); i++)
{
/* Get the pointer to the actual data */
srcElem = rpoolGetNode(raH, srcLocation);
destElem = rpoolGetNode(raH, destLocation);
/* Copy */
memcpy((void *)&(destElem->data), (void *)&(srcElem->data), elemSize);
/* Go on the next block */
destLocation = destElem->nextBlock;
srcLocation = srcElem->nextBlock;
}
return (dest);
}
/* Compares allocated element from pool with external block of memory */
/* Returns the same output as memcmp */
int
rpoolCompareExternal(
/* Compare dest to src */
HRPOOL pool,
HRPOOLELEM dest,
void *src,
int size)
{
HRA raH = (HRA)pool;
RvSize_t elemSize, numOfBlocks;
int i, location, res=RV_ERROR_UNKNOWN;
rpoolElem *elem;
if ( (! pool ) || ( ! size) || (! src ))
return RV_ERROR_UNKNOWN;
location = RPOOL_LOCATION(dest);
if (INVALID_LOCATION(raH,location)) return COMPARE_ERROR;
elemSize = RPOOL_ELEM_SIZE(raElemSize(raH));
numOfBlocks = RPOOL_BLOCKS(size,elemSize);
for(i=0;(!IS_LAST_NODE(location)&&(i<((int)numOfBlocks-1)));i++) {
elem=rpoolGetNode(raH,location);
if ((res = memcmp((void *)&(elem->data),(char*)src+i*elemSize , elemSize))) return(res);
location=elem->nextBlock;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -