📄 lists.c
字号:
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_FUNCTIONSint 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_FUNCTIONSvoid 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -