⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpool.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
       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 + -