/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * * HDF is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * See the LICENSE file in the root of this repository for complete details. */ #include "hdf_slist.h" #include "hdf_log.h" #define HDF_LOG_TAG utils_slist void HdfSListInit(struct HdfSList *list) { if (list != NULL) { list->root = NULL; } } bool HdfSListIsEmpty(struct HdfSList *list) { return ((list == NULL) || (list->root == NULL)); } struct HdfSListNode *HdfSListSearch(struct HdfSList *list, uint32_t keyValue, HdfSListSearchComparer comparer) { struct HdfSListIterator it; if (comparer == NULL) { return NULL; } HdfSListIteratorInit(&it, list); while (HdfSListIteratorHasNext(&it)) { struct HdfSListNode *listNode = HdfSListIteratorNext(&it); if (comparer(listNode, keyValue)) { return listNode; } } return NULL; } struct HdfSListNode *HdfSListGetLast(struct HdfSList *list) { struct HdfSListNode *last = NULL; struct HdfSListNode *iterator = NULL; if (list == NULL) { return NULL; } for (iterator = list->root; iterator != NULL; iterator = iterator->next) { last = iterator; } return last; } void HdfSListAdd(struct HdfSList *list, struct HdfSListNode *link) { if (list == NULL || link == NULL) { return; } link->next = list->root; list->root = link; } void HdfSListAddTail(struct HdfSList *list, struct HdfSListNode *link) { struct HdfSListNode *iterator = NULL; if (list == NULL || link == NULL) { return; } for (iterator = (struct HdfSListNode *)list; iterator->next; iterator = iterator->next) { if (iterator->next == link) { return; } } link->next = NULL; iterator->next = link; } bool HdfSListAddOrder(struct HdfSList *list, struct HdfSListNode *link, HdfSListAddComparer comparer) { struct HdfSListNode *iterator = NULL; if (list == NULL || link == NULL || comparer == NULL) { HDF_LOGE("input is invalid"); return false; } for (iterator = list->root; iterator; iterator = iterator->next) { if (iterator == link) { HDF_LOGE("link is already in list"); return false; } } if (comparer(link, list->root)) { link->next = list->root; list->root = link; return true; } for (iterator = list->root; iterator && iterator->next; iterator = iterator->next) { if (comparer(iterator, link) && comparer(link, iterator->next)) { link->next = iterator->next; iterator->next = link; return true; } } if ((list->root == NULL) || (iterator == NULL)) { link->next = NULL; list->root = link; } else { link->next = NULL; iterator->next = link; } return true; } void HdfSListRemove(struct HdfSList *list, struct HdfSListNode *link) { struct HdfSListNode *iterator = NULL; if (list == NULL || link == NULL) { return; } for (iterator = (struct HdfSListNode *)list; iterator; iterator = iterator->next) { if (iterator->next == link) { iterator->next = link->next; return; } } } void HdfSListFlush(struct HdfSList *list, HdfSListDeleter deleter) { struct HdfSListIterator iterator; if (list == NULL) { return; } HdfSListIteratorInit(&iterator, list); while (HdfSListIteratorHasNext(&iterator)) { void *listNode = (void *)HdfSListIteratorNext(&iterator); HdfSListIteratorRemove(&iterator); if (deleter != NULL) { deleter(listNode); } } } int HdfSListCount(struct HdfSList *list) { struct HdfSListNode *iterator = NULL; int counter = 0; if (list == NULL) { return counter; } for (iterator = (struct HdfSListNode *)list; iterator->next; iterator = iterator->next) { counter++; } return counter; } struct HdfSListNode *HdfSListPeek(struct HdfSList *list) { if (list == NULL) { return NULL; } return list->root; } struct HdfSListNode *HdfSListNext(struct HdfSListNode *link) { if (link == NULL) { return NULL; } return link->next; } struct HdfSListNode *HdfSListPop(struct HdfSList *list) { if (list == NULL || list->root == NULL) { return NULL; } struct HdfSListNode *first = list->root; list->root = first->next; return first; } void HdfSListIteratorInit(struct HdfSListIterator *iterator, struct HdfSList *list) { if (iterator == NULL || list == NULL) { if (iterator != NULL) { iterator->stepOnNext = 0; iterator->prev = NULL; iterator->curr = NULL; } return; } iterator->stepOnNext = 0; iterator->prev = (struct HdfSListNode *)list; iterator->curr = list->root; } bool HdfSListIteratorHasNext(struct HdfSListIterator *iterator) { if ((iterator == NULL) || (iterator->curr == NULL) || (iterator->prev == NULL)) { return false; } if (!iterator->stepOnNext) { return iterator->curr != NULL; } if (iterator->prev->next != iterator->curr) { // current item has been removed return iterator->prev->next != NULL; } // current items has not been removed return iterator->curr->next != NULL; } struct HdfSListNode *HdfSListIteratorNext(struct HdfSListIterator *iterator) { if ((iterator == NULL) || (iterator->curr == NULL) || (iterator->prev == NULL)) { return NULL; } if (iterator->stepOnNext) { if (iterator->prev->next == iterator->curr) { iterator->prev = iterator->curr; iterator->curr = iterator->curr->next; } else { // curr was removed from the list, set it again but don't advance prev iterator->curr = iterator->prev->next; } } else { iterator->stepOnNext = 1; } return iterator->curr; } void HdfSListIteratorRemove(struct HdfSListIterator *iterator) { if ((iterator == NULL) || (iterator->curr == NULL) || (iterator->prev == NULL)) { return; } iterator->curr = iterator->curr->next; iterator->prev->next = iterator->curr; iterator->stepOnNext = 0; } void HdfSListIteratorInsert(struct HdfSListIterator *iterator, struct HdfSListNode *link) { if (iterator == NULL || link == NULL) { return; } link->next = iterator->curr; iterator->prev->next = link; iterator->prev = link; }