Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>master
parent
ef0255fc75
commit
c1de7a6daf
@ -1,734 +0,0 @@ |
||||
#include <common.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) |
||||
|
||||
/* increase list size by 10% every time it is full */ |
||||
#define kDefaultAllocationPercentIncrease 10 |
||||
|
||||
/* always increase list size by 4 items when it is full */ |
||||
#define kDefaultAllocationminNumItemsIncrease 4 |
||||
|
||||
/*
|
||||
* 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 */ |
||||
|
||||
/*******************************************************************************/ |
||||
|
||||
/*
|
||||
* 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); |
||||
} |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* keeps memory, resets the number of items to 0 |
||||
*/ |
||||
void ListClear (list_t list) |
||||
{ |
||||
if (!list) |
||||
return; |
||||
(*list)->numItems = 0; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* copy is only as large as necessary |
||||
*/ |
||||
list_t ListCopy (list_t originalList) |
||||
{ |
||||
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; |
||||
} |
||||
|
||||
/********************************/ |
||||
|
||||
/*
|
||||
* list1 = list1 + list2 |
||||
*/ |
||||
int ListAppend (list_t list1, list_t 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) |
||||
return 0; |
||||
|
||||
if ((*list)->numItems >= (*list)->listSize) { |
||||
if (!ExpandListSpace (list, -numItemsToInsert)) |
||||
return 0; |
||||
} |
||||
|
||||
if (firstItemPosition == LIST_START) { |
||||
if (numItems == 0) { |
||||
/* special case for empty list */ |
||||
firstItemPosition = LIST_END; |
||||
} else { |
||||
firstItemPosition = 1; |
||||
} |
||||
} |
||||
|
||||
if (firstItemPosition == LIST_END) { /* add at the end of the list */ |
||||
if (ptrToItems) |
||||
memcpy (ITEMPTR (list, numItems), ptrToItems, |
||||
(*list)->itemSize * numItemsToInsert); |
||||
else |
||||
memset (ITEMPTR (list, numItems), 0, |
||||
(*list)->itemSize * numItemsToInsert); |
||||
|
||||
(*list)->numItems += numItemsToInsert; |
||||
} else { /* move part of list up to make room for new item */ |
||||
memmove (ITEMPTR (list, firstItemPosition - 1 + numItemsToInsert), |
||||
ITEMPTR (list, firstItemPosition - 1), |
||||
(numItems + 1 - firstItemPosition) * (*list)->itemSize); |
||||
|
||||
if (ptrToItems) |
||||
memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems, |
||||
(*list)->itemSize * numItemsToInsert); |
||||
else |
||||
memset (ITEMPTR (list, firstItemPosition - 1), 0, |
||||
(*list)->itemSize * numItemsToInsert); |
||||
|
||||
(*list)->numItems += numItemsToInsert; |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
#ifdef CFG_ALL_LIST_FUNCTIONS |
||||
|
||||
/*******************************/ |
||||
|
||||
int ListEqual (list_t list1, list_t list2) |
||||
{ |
||||
if (list1 == list2) |
||||
return 1; |
||||
|
||||
if (list1 == NULL || list2 == NULL) |
||||
return 0; |
||||
|
||||
if ((*list1)->itemSize == (*list1)->itemSize) { |
||||
if ((*list1)->numItems == (*list2)->numItems) { |
||||
return (memcmp (ITEMPTR (list1, 0), ITEMPTR (list2, 0), |
||||
(*list1)->itemSize * (*list1)->numItems) == 0); |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* The item pointed to by ptrToItem is copied over the current item |
||||
* at itemPosition |
||||
*/ |
||||
void ListReplaceItem (list_t list, void *ptrToItem, int itemPosition) |
||||
{ |
||||
ListReplaceItems (list, ptrToItem, itemPosition, 1); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* The item pointed to by ptrToItems is copied over the current item |
||||
* at itemPosition |
||||
*/ |
||||
void ListReplaceItems ( list_t list, void *ptrToItems, |
||||
int firstItemPosition, int numItemsToReplace) |
||||
{ |
||||
|
||||
if (firstItemPosition == LIST_END) |
||||
firstItemPosition = (*list)->numItems; |
||||
else if (firstItemPosition == LIST_START) |
||||
firstItemPosition = 1; |
||||
|
||||
memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems, |
||||
(*list)->itemSize * numItemsToReplace); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
void ListGetItem (list_t list, void *itemDestination, int itemPosition) |
||||
{ |
||||
ListGetItems (list, itemDestination, itemPosition, 1); |
||||
} |
||||
|
||||
#endif /* CFG_ALL_LIST_FUNCTIONS */ |
||||
|
||||
/*******************************/ |
||||
|
||||
#if defined(CFG_ALL_LIST_FUNCTIONS) || defined(CFG_DEVICE_DEREGISTER) |
||||
|
||||
void ListRemoveItem (list_t list, void *itemDestination, int itemPosition) |
||||
{ |
||||
ListRemoveItems (list, itemDestination, itemPosition, 1); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
void ListRemoveItems (list_t list, void *itemsDestination, |
||||
int firstItemPosition, int numItemsToRemove) |
||||
{ |
||||
int firstItemAfterChunk, numToMove; |
||||
|
||||
if (firstItemPosition == LIST_START) |
||||
firstItemPosition = 1; |
||||
else if (firstItemPosition == LIST_END) |
||||
firstItemPosition = (*list)->numItems; |
||||
|
||||
if (itemsDestination != NULL) |
||||
memcpy (itemsDestination, ITEMPTR (list, firstItemPosition - 1), |
||||
(*list)->itemSize * numItemsToRemove); |
||||
|
||||
firstItemAfterChunk = firstItemPosition + numItemsToRemove; |
||||
numToMove = (*list)->numItems - (firstItemAfterChunk - 1); |
||||
|
||||
if (numToMove > 0) { |
||||
/*
|
||||
* move part of list down to cover hole left by removed item |
||||
*/ |
||||
memmove (ITEMPTR (list, firstItemPosition - 1), |
||||
ITEMPTR (list, firstItemAfterChunk - 1), |
||||
(*list)->itemSize * numToMove); |
||||
} |
||||
|
||||
(*list)->numItems -= numItemsToRemove; |
||||
} |
||||
#endif /* CFG_ALL_LIST_FUNCTIONS || CFG_DEVICE_DEREGISTER */ |
||||
|
||||
/*******************************/ |
||||
|
||||
void ListGetItems (list_t list, void *itemsDestination, |
||||
int firstItemPosition, int numItemsToGet) |
||||
{ |
||||
|
||||
if (firstItemPosition == LIST_START) |
||||
firstItemPosition = 1; |
||||
else if (firstItemPosition == LIST_END) |
||||
firstItemPosition = (*list)->numItems; |
||||
|
||||
memcpy (itemsDestination, |
||||
ITEMPTR (list, firstItemPosition - 1), |
||||
(*list)->itemSize * numItemsToGet); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* Returns a pointer to the item at itemPosition. returns null if an |
||||
* errors occurred. |
||||
*/ |
||||
void *ListGetPtrToItem (list_t list, int itemPosition) |
||||
{ |
||||
if (itemPosition == LIST_START) |
||||
itemPosition = 1; |
||||
else if (itemPosition == LIST_END) |
||||
itemPosition = (*list)->numItems; |
||||
|
||||
return ITEMPTR (list, itemPosition - 1); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
/*
|
||||
* returns a pointer the lists data (abstraction violation for |
||||
* optimization) |
||||
*/ |
||||
void *ListGetDataPtr (list_t list) |
||||
{ |
||||
return &((*list)->itemList[0]); |
||||
} |
||||
|
||||
/********************************/ |
||||
|
||||
#ifdef CFG_ALL_LIST_FUNCTIONS |
||||
|
||||
int ListApplyToEach (list_t list, int ascending, |
||||
ListApplicationFunc funcToApply, |
||||
void *callbackData) |
||||
{ |
||||
int result = 0, index; |
||||
|
||||
if (!list || !funcToApply) |
||||
goto Error; |
||||
|
||||
if (ascending) { |
||||
for (index = 1; index <= ListNumItems (list); index++) { |
||||
result = funcToApply (index, |
||||
ListGetPtrToItem (list, index), |
||||
callbackData); |
||||
if (result < 0) |
||||
goto Error; |
||||
} |
||||
} else { |
||||
for (index = ListNumItems (list); |
||||
index > 0 && index <= ListNumItems (list); |
||||
index--) { |
||||
result = funcToApply (index, |
||||
ListGetPtrToItem (list, index), |
||||
callbackData); |
||||
if (result < 0) |
||||
goto Error; |
||||
} |
||||
} |
||||
|
||||
Error: |
||||
return result; |
||||
} |
||||
|
||||
#endif /* CFG_ALL_LIST_FUNCTIONS */ |
||||
|
||||
/********************************/ |
||||
|
||||
int ListGetItemSize (list_t list) |
||||
{ |
||||
return (*list)->itemSize; |
||||
} |
||||
|
||||
/********************************/ |
||||
|
||||
int ListNumItems (list_t list) |
||||
{ |
||||
return (*list)->numItems; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
#ifdef CFG_ALL_LIST_FUNCTIONS |
||||
|
||||
void ListRemoveDuplicates (list_t list, CompareFunction compareFunction) |
||||
{ |
||||
int numItems, index, startIndexForFind, duplicatesIndex; |
||||
|
||||
numItems = ListNumItems (list); |
||||
|
||||
for (index = 1; index < numItems; index++) { |
||||
startIndexForFind = index + 1; |
||||
while (startIndexForFind <= numItems) { |
||||
duplicatesIndex = |
||||
ListFindItem (list, |
||||
ListGetPtrToItem (list, index), |
||||
startIndexForFind, |
||||
compareFunction); |
||||
if (duplicatesIndex > 0) { |
||||
ListRemoveItem (list, NULL, duplicatesIndex); |
||||
numItems--; |
||||
startIndexForFind = duplicatesIndex; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
|
||||
/*******************************/ |
||||
|
||||
int ListFindItem (list_t list, void *ptrToItem, int startingPosition, |
||||
CompareFunction compareFunction) |
||||
{ |
||||
int numItems, size, index, cmp; |
||||
void *listItemPtr; |
||||
|
||||
if ((numItems = (*list)->numItems) == 0) |
||||
return 0; |
||||
|
||||
size = (*list)->itemSize; |
||||
|
||||
if (startingPosition == LIST_START) |
||||
startingPosition = 1; |
||||
else if (startingPosition == LIST_END) |
||||
startingPosition = numItems; |
||||
|
||||
for (index = startingPosition; index <= numItems; index++) { |
||||
listItemPtr = ITEMPTR (list, index - 1); |
||||
cmp = compareFunction |
||||
? compareFunction (ptrToItem, listItemPtr) |
||||
: ListMemBlockCmp (ptrToItem, listItemPtr, size); |
||||
if (cmp == 0) |
||||
return index; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
int ShortCompare (void *a, void *b) |
||||
{ |
||||
if (*(short *) a < *(short *) b) |
||||
return -1; |
||||
if (*(short *) a > *(short *) b) |
||||
return 1; |
||||
return 0; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
int IntCompare (void *a, void *b) |
||||
{ |
||||
if (*(int *) a < *(int *) b) |
||||
return -1; |
||||
if (*(int *) a > *(int *) b) |
||||
return 1; |
||||
return 0; |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
int CStringCompare (void *a, void *b) |
||||
{ |
||||
return strcmp (*(char **) a, *(char **) b); |
||||
} |
||||
|
||||
/*******************************/ |
||||
|
||||
|
||||
int ListBinSearch (list_t list, void *ptrToItem, |
||||
CompareFunction compareFunction) |
||||
{ |
||||
int index; |
||||
|
||||
index = BinSearch (ITEMPTR (list, 0), |
||||
(int) (*list)->numItems, |
||||
(int) (*list)->itemSize, ptrToItem, |
||||
compareFunction); |
||||
|
||||
if (index >= 0) |
||||
index++; /* lists start from 1 */ |
||||
else |
||||
index = 0; /* item not found */ |
||||
|
||||
return index; |
||||
} |
||||
|
||||
/**************************************************************************/ |
||||
|
||||
/*
|
||||
* Reserves memory for numItems in the list. If it succeeds then |
||||
* numItems items can be inserted without possibility of an out of |
||||
* memory error (useful to simplify error recovery in complex |
||||
* functions). Returns 1 if success, 0 if out of memory. |
||||
*/ |
||||
int ListPreAllocate (list_t list, int numItems) |
||||
{ |
||||
if ((*list)->listSize - (*list)->numItems < numItems) { |
||||
return ExpandListSpace (list, |
||||
numItems - ((*list)->listSize - |
||||
(*list)->numItems)); |
||||
} else { |
||||
return 1; /* enough items are already pre-allocated */ |
||||
} |
||||
} |
||||
|
||||
#endif /* CFG_ALL_LIST_FUNCTIONS */ |
@ -1,77 +0,0 @@ |
||||
#ifndef _LISTS_H_ |
||||
#define _LISTS_H_ |
||||
|
||||
#define LIST_START -1 /* Handy Constants that substitute for item positions */ |
||||
#define LIST_END 0 /* END_OF_LIST means one past current length of list when */ |
||||
/* inserting. Otherwise it refers the last item in the list. */ |
||||
|
||||
typedef struct |
||||
{ |
||||
void *ptr; |
||||
unsigned int size; |
||||
} HandleRecord; |
||||
|
||||
typedef void **Handle; |
||||
|
||||
typedef int (*CompareFunction)(void *data1, void *data2) ; |
||||
|
||||
typedef struct ListStructTag |
||||
{ |
||||
int signature; /* debugging aid */ |
||||
int percentIncrease; /* %of current size to increase by when list is out of space */ |
||||
int minNumItemsIncrease; /* fixed number of items to increase by when list is out of space */ |
||||
int listSize; /* number of items than can fit in the currently allocated memory */ |
||||
int itemSize; /* the size of each item in the list (same for every item) */ |
||||
int numItems; /* number of items currently in the list */ |
||||
unsigned char itemList[1]; /* resizable array of list elements */ |
||||
} ListStruct; |
||||
|
||||
typedef struct ListStructTag **list_t; /* The list abstract data type */ |
||||
typedef int ( * ListApplicationFunc)(int index, void *ptrToItem, void *callbackData); |
||||
|
||||
/* Basic List Operations */ |
||||
list_t ListCreate(int elementSize); |
||||
int ListNumItems(list_t list); |
||||
int ListInsertItem(list_t list, void *ptrToItem, int itemPosition); |
||||
int ListInsertItems(list_t list, void *ptrToItems, int firstItemPosition, int numItemsToInsert); |
||||
void ListDispose(list_t list); |
||||
void *ListGetPtrToItem(list_t list, int itemPosition); |
||||
void ListRemoveItem(list_t list, void *itemDestination, int itemPosition); |
||||
void ListRemoveItems(list_t list, void *itemsDestination, int firstItemPosition, int numItemsToRemove); |
||||
|
||||
#if 0 /* rarely ever used; kept here for reference just in case ... */
|
||||
void ListDisposePtrList(list_t list); |
||||
void ListGetItem(list_t list, void *itemDestination, int itemPosition); |
||||
void ListReplaceItem(list_t list, void *ptrToItem, int itemPosition); |
||||
void ListRemoveItem(list_t list, void *itemDestination, int itemPosition); |
||||
void ListGetItems(list_t list, void *itemsDestination, int firstItemPosition, int numItemsToGet); |
||||
void ListReplaceItems(list_t list, void *ptrToItems, int firstItemPosition, int numItemsToReplace); |
||||
void ListRemoveItems(list_t list, void *itemsDestination, int firstItemPosition, int numItemsToRemove); |
||||
list_t ListCopy(list_t originalList); |
||||
int ListAppend(list_t list1, list_t list2); |
||||
void ListClear(list_t list); |
||||
int ListEqual(list_t list1, list_t list2); |
||||
int ListInsertInOrder(list_t list, void *ptrToItem, CompareFunction compareFunction); |
||||
void *ListGetDataPtr(list_t list); |
||||
int ListApplyToEach(list_t list, int ascending, ListApplicationFunc funcToApply, void *callbackData); |
||||
|
||||
/* List Searching and Sorting */ |
||||
int ListFindItem(list_t list, void *ptrToItem, int startingPosition, CompareFunction compareFunction); |
||||
void ListRemoveDuplicates(list_t list, CompareFunction compareFunction); |
||||
int ListBinSearch(list_t list, void *itemPtr, CompareFunction compareFunction); |
||||
void ListQuickSort(list_t list, CompareFunction compareFunction); |
||||
void ListHeapSort(list_t list, CompareFunction compareFunction); |
||||
void ListInsertionSort(list_t list, CompareFunction compareFunction); |
||||
int ListIsSorted(list_t list, CompareFunction compareFunction); |
||||
|
||||
/* Advanced List Functions */ |
||||
void ListSetAllocationPolicy(list_t list, int minItemsPerAlloc, int percentIncreasePerAlloc); |
||||
void ListCompact(list_t list); |
||||
int ListPreAllocate(list_t list, int numItems); |
||||
int ListGetItemSize(list_t list); |
||||
int GetIntListFromParmInfo(va_list parmInfo, int numIntegers, list_t *integerList); |
||||
int ListInsertAfterItem(list_t list, void *ptrToItem, void *ptrToItemToInsertAfter, CompareFunction compareFunction); |
||||
int ListInsertBeforeItem(list_t list, void *ptrToItem, void *ptrToItemToInsertBefore, CompareFunction compareFunction); |
||||
#endif /* 0 */ |
||||
|
||||
#endif /* _LISTS_H_ */ |
Loading…
Reference in new issue