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

📄 lists.c

📁 嵌入式ARM的一些源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <ppcboot.h>
#include <malloc.h>
#include "lists.h"

#define MAX(a,b) 	(((a)>(b)) ? (a) : (b))
#define MIN(a,b) 	(((a)<(b)) ? (a) : (b))
#define CAT4CHARS(a,b,c,d)	((a<<24) | (b<<16) | (c<<8) | d)

#define kDefaultAllocationPercentIncrease   10  /* increase list size by 10% every time it is full */
#define kDefaultAllocationminNumItemsIncrease   4   /* always increase list size by 4 items when it is full */

 /* how many items to expand the list by when it becomes full = current listSize (in items) + (hiword percent of list size) +   loword */
#define NUMITEMSPERALLOC(list) MAX(((*list)->listSize * ((*list)->percentIncrease + 100)) / 100 , (*list)->minNumItemsIncrease)

#define ITEMPTR(list, item)     &(((char *)&(*list)->itemList)[ (*(list))->itemSize * (item)])

#define LIST_SIGNATURE          CAT4CHARS('L', 'I', 'S', 'T');

#define calloc(size,num)	malloc(size*num)

/********************************************************************/

Handle NewHandle(unsigned int numBytes)
{
    void            *memPtr;
    HandleRecord    *hanPtr;

    memPtr = calloc(numBytes, 1);
    hanPtr = (HandleRecord*)calloc(sizeof(HandleRecord), 1);
    if (hanPtr && (memPtr || numBytes == 0))
        {
        hanPtr->ptr = memPtr;
        hanPtr->size = numBytes;
        return (Handle)hanPtr;
        }
    else
        {
        free(memPtr);
        free(hanPtr);
        return NULL;
        }
}

/********************************************************************/

void  DisposeHandle(Handle handle)
{
    if (handle)
        {
        free(*handle);
        free((void *)handle);
        }
}

/********************************************************************/

unsigned int  GetHandleSize(Handle handle)
{
    return ((HandleRecord *)handle)->size;
}

/********************************************************************/

int  SetHandleSize(Handle handle, unsigned int newSize)
{
    HandleRecord    *hanRecPtr = (HandleRecord *)handle;
    void            *newPtr, *oldPtr;
    unsigned int    oldSize;


    oldPtr = hanRecPtr->ptr;
    oldSize = hanRecPtr->size;

    if (oldSize == newSize)
         return 1;

    if (oldPtr == NULL)
    {
        newPtr = malloc(newSize);
    }
    else
    {
        newPtr = realloc(oldPtr, newSize);
    }
    if (newPtr || (newSize == 0))
        {
        hanRecPtr->ptr = newPtr;
        hanRecPtr->size = newSize;
        if (newSize > oldSize)
            memset ((char *)newPtr+oldSize, 0, newSize-oldSize);
        return 1;
        }
    else
        return 0;
}

#ifdef	CFG_ALL_LIST_FUNCTIONS

    /*  Used to compare list elements by their raw data contents */
static int  ListMemBlockCmp(void *a, void *b, int size)
{
    return memcmp(a, b, size);
}


/***************************************************************************/

    /*  Binary search numElements of size elementSize in array for a match
        to the. item. Return the index of the element that matches (0 - numElements - 1).
        If no match is found return the -i-1 where i is the index (0 - numElements)
        where the item should be placed. (*theCmp)(a,b) should return  <0 if a<b,
        0 if a==b, >0 if a>b.

        This function is like the C-Library function bsearch() except that this
        function returns the index where the item should be placed if it is not
        found.
    */
int BinSearch(void *array, int numElements, int elementSize, void *itemPtr, CompareFunction compareFunction)
{
    int low, high, mid, cmp;
    void *arrayItemPtr;

    for(low=0, high= numElements-1, mid=0, cmp= -1; low <= high; )
        {
        mid = (low + high) >> 1;

        arrayItemPtr = (void *) (((char *)array) + (mid*elementSize));
        cmp = compareFunction ? compareFunction(itemPtr, arrayItemPtr)
                              : ListMemBlockCmp(itemPtr, arrayItemPtr, elementSize);
        if (cmp == 0)
            return mid;
        else
        if (cmp < 0)
            high= mid - 1;
        else
            low= mid + 1;
        }
    if (cmp > 0)
        mid++;

    return -mid-1;
}

#endif	/* CFG_ALL_LIST_FUNCTIONS */

/*******************************************************************************/

    /* BEGIN PATCH to 4.0.1 - jag 8-29-96 */
    /*  If numNewItems == 0 then expand the list by the number of items
	indicated by its allocation policy.
        If numNewItems > 0 then expand the list by exactly the number of
	items indicated.
        If numNewItems < 0 then expand the list by the absolute value of
	numNewItems plus the number of items indicated by its allocation
	policy.
        Returns 1 for success, 0 if out of memory
    */
static int  ExpandListSpace (list_t list, int numNewItems)
{
    if (numNewItems == 0)
        numNewItems = NUMITEMSPERALLOC(list);
    else
    if (numNewItems < 0)
        numNewItems = (-numNewItems) + NUMITEMSPERALLOC(list);

    if (SetHandleSize ((Handle)list,
        sizeof(ListStruct) +
	((*list)->listSize + numNewItems) * (*list)->itemSize))
	{
    	    (*list)->listSize += numNewItems;
    	    return 1;
        }
    else
    {
        return 0;
    }
}

/*******************************/

#ifdef	CFG_ALL_LIST_FUNCTIONS

     /* This function reallocate the list, minus any currently unused portion of its allotted memory. */
void  ListCompact (list_t list)
{

    if (!SetHandleSize ((Handle)list,
        sizeof (ListStruct) + (*list)->numItems * (*list)->itemSize))
        return;

    (*list)->listSize = (*list)->numItems;
}

#endif	/* CFG_ALL_LIST_FUNCTIONS */

/*******************************/

list_t  ListCreate (int elementSize)
{
    list_t    list;

    list = (list_t)(NewHandle (sizeof(ListStruct)));   /* create empty list */
    if (list)
        {
        (*list)->signature = LIST_SIGNATURE;
        (*list)->numItems = 0;
        (*list)->listSize = 0;
        (*list)->itemSize = elementSize;
        (*list)->percentIncrease = kDefaultAllocationPercentIncrease;
        (*list)->minNumItemsIncrease = kDefaultAllocationminNumItemsIncrease;
        }

    return list;
}

/*******************************/

void  ListSetAllocationPolicy (list_t list, int minItemsPerAlloc, int percentIncreasePerAlloc)
{

    (*list)->percentIncrease = percentIncreasePerAlloc;
    (*list)->minNumItemsIncrease = minItemsPerAlloc;
}

/*******************************/

void  ListDispose (list_t list)
{
    DisposeHandle ((Handle)list);
}

/*******************************/

#ifdef	CFG_ALL_LIST_FUNCTIONS

void  ListDisposePtrList(list_t list)
{
    int index;
    int numItems;

    if (list)
        {
        numItems = ListNumItems(list);

        for (index = 1; index <= numItems; index++)
            free(*(void **)ListGetPtrToItem(list, index));

        ListDispose(list);
        }
}

/*******************************/

void   ListClear (list_t list)  /* keeps memory, resets the number of items to 0 */
{
    if (!list)
        return;
    (*list)->numItems = 0;
}

/*******************************/

list_t  ListCopy (list_t originalList)   /* copy is only as large as necessary */
{
    list_t    tempList = NULL;
    int         numItems;

    if (!originalList)
        return NULL;

    tempList = ListCreate ((*originalList)->itemSize);
    if (tempList) {
        numItems = ListNumItems (originalList);

        if (!SetHandleSize ((Handle)tempList,
            sizeof (ListStruct) + numItems * (*tempList)->itemSize)) {
            ListDispose (tempList);
            return NULL;
            }

        (*tempList)->numItems = (*originalList)->numItems;
        (*tempList)->listSize = (*originalList)->numItems;
        (*tempList)->itemSize = (*originalList)->itemSize;
        (*tempList)->percentIncrease = (*originalList)->percentIncrease;
        (*tempList)->minNumItemsIncrease = (*originalList)->minNumItemsIncrease;

        memcpy (ITEMPTR(tempList,0), ITEMPTR(originalList,0),
            numItems * (*tempList)->itemSize);
        }

    return tempList;
}

/********************************/

int  ListAppend (list_t list1, list_t list2)  /* list1 = list1 + list2 */
{
    int numItemsL1, numItemsL2;

    if (!list2)
        return 1;

    if (!list1)
        return 0;
    if ((*list1)->itemSize != (*list2)->itemSize)
        return 0;

    numItemsL1 = ListNumItems (list1);
    numItemsL2 = ListNumItems (list2);

    if (numItemsL2 == 0)
        return 1;

    if (!SetHandleSize ((Handle)list1,
        sizeof (ListStruct) + (numItemsL1 + numItemsL2) * (*list1)->itemSize))
        return 0;

    (*list1)->numItems = numItemsL1 + numItemsL2;
    (*list1)->listSize = numItemsL1 + numItemsL2;

    memmove (ITEMPTR(list1,numItemsL1), ITEMPTR(list2,0),
        numItemsL2 * (*list2)->itemSize);

    return 1;
}

#endif	/* CFG_ALL_LIST_FUNCTIONS */

/*******************************/

    /*  returns 1 if the item is inserted, returns 0 if out of memory or
        bad arguments were passed.
    */
int  ListInsertItem (list_t list, void *ptrToItem, int itemPosition)
{
    return ListInsertItems (list, ptrToItem, itemPosition, 1);
}

/*******************************/

int  ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition, int numItemsToInsert)
{
    int numItems = (*list)->numItems;

    if (firstItemPosition == numItems + 1)
        firstItemPosition = LIST_END;
    else
    if (firstItemPosition > numItems)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -