1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#ifndef BASE_STARTUP_INITLITE_LIST_H 17d9f0492fSopenharmony_ci#define BASE_STARTUP_INITLITE_LIST_H 18d9f0492fSopenharmony_ci#include <stddef.h> 19d9f0492fSopenharmony_ci 20d9f0492fSopenharmony_ci#ifdef __cplusplus 21d9f0492fSopenharmony_ci#if __cplusplus 22d9f0492fSopenharmony_ciextern "C" { 23d9f0492fSopenharmony_ci#endif 24d9f0492fSopenharmony_ci#endif 25d9f0492fSopenharmony_ci 26d9f0492fSopenharmony_ci/** 27d9f0492fSopenharmony_ci * @brief Double linked list structure is show as below: 28d9f0492fSopenharmony_ci * 29d9f0492fSopenharmony_ci * | ̄ ̄ ̄ ̄ ̄|-----------------------------------------------| 30d9f0492fSopenharmony_ci * |->| head | | 31d9f0492fSopenharmony_ci * | |________|<-------------------------------------------| | 32d9f0492fSopenharmony_ci * | | | | 33d9f0492fSopenharmony_ci * | └-next->|▔▔▔▔▔▔|-next->|▔▔▔▔▔▔|-next->|▔▔▔▔▔▔|-next--| | 34d9f0492fSopenharmony_ci * └------prev-| node |<-prev-| node |<-prev-| node |<-prev----| 35d9f0492fSopenharmony_ci * |------| |------| |------| 36d9f0492fSopenharmony_ci * | extra| | extra| | extra| 37d9f0492fSopenharmony_ci * |______| |______| |______| 38d9f0492fSopenharmony_ci * 39d9f0492fSopenharmony_ci * Usage Example: 40d9f0492fSopenharmony_ci * 1. Define structure for each item in the list 41d9f0492fSopenharmony_ci * typedef struct tagTEST_LIST_ITEM { 42d9f0492fSopenharmony_ci * ListNode node; 43d9f0492fSopenharmony_ci * int value; 44d9f0492fSopenharmony_ci * } TEST_LIST_ITEM; 45d9f0492fSopenharmony_ci * 46d9f0492fSopenharmony_ci * 2. Define a list and init list by OH_ListAddTail 47d9f0492fSopenharmony_ci * ListNode testList; 48d9f0492fSopenharmony_ci * c(&testList); 49d9f0492fSopenharmony_ci * 50d9f0492fSopenharmony_ci * 3. Define a list item instance 51d9f0492fSopenharmony_ci * TEST_LIST_ITEM item; 52d9f0492fSopenharmony_ci * item.value = 0; 53d9f0492fSopenharmony_ci * 54d9f0492fSopenharmony_ci * 4. Add list item to list 55d9f0492fSopenharmony_ci * OH_ListAddTail(&testList, (ListNode *)(&item)); 56d9f0492fSopenharmony_ci * 57d9f0492fSopenharmony_ci * 5. Advanced usage: add with order 58d9f0492fSopenharmony_ci * // Ordering compare function 59d9f0492fSopenharmony_ci * static int TestListItemCompareProc(ListNode *node, ListNode *newNode) 60d9f0492fSopenharmony_ci * { 61d9f0492fSopenharmony_ci * TEST_LIST_ITEM *left = (TEST_LIST_ITEM *)node; 62d9f0492fSopenharmony_ci * TEST_LIST_ITEM *right = (TEST_LIST_ITEM *)newNode; 63d9f0492fSopenharmony_ci * return left->value - right->value; 64d9f0492fSopenharmony_ci * } 65d9f0492fSopenharmony_ci * OH_ListAddWithOrder(&testList, (ListNode *)(&item)) 66d9f0492fSopenharmony_ci */ 67d9f0492fSopenharmony_ci 68d9f0492fSopenharmony_ci/** 69d9f0492fSopenharmony_ci * @brief Double linked list node 70d9f0492fSopenharmony_ci */ 71d9f0492fSopenharmony_citypedef struct ListNode { 72d9f0492fSopenharmony_ci struct ListNode *next; 73d9f0492fSopenharmony_ci struct ListNode *prev; 74d9f0492fSopenharmony_ci} ListNode, ListHead; 75d9f0492fSopenharmony_ci 76d9f0492fSopenharmony_ci#define ListEmpty(node) ((node).next == &(node) && (node).prev == &(node)) 77d9f0492fSopenharmony_ci#define ListEntry(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) 78d9f0492fSopenharmony_ci#define ForEachListEntry(list, node) for (node = (list)->next; node != (list); node = node->next) 79d9f0492fSopenharmony_ci 80d9f0492fSopenharmony_ci/** 81d9f0492fSopenharmony_ci * @brief Initialize a double-linked list head 82d9f0492fSopenharmony_ci * 83d9f0492fSopenharmony_ci * All other list API should be initialized by this function.\n 84d9f0492fSopenharmony_ci * 85d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer 86d9f0492fSopenharmony_ci * @return None 87d9f0492fSopenharmony_ci */ 88d9f0492fSopenharmony_civoid OH_ListInit(struct ListNode *list); 89d9f0492fSopenharmony_ci 90d9f0492fSopenharmony_ci/** 91d9f0492fSopenharmony_ci * @brief Add a node to the end of the list 92d9f0492fSopenharmony_ci * 93d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer 94d9f0492fSopenharmony_ci * @param item new node to be added 95d9f0492fSopenharmony_ci * @return None 96d9f0492fSopenharmony_ci */ 97d9f0492fSopenharmony_civoid OH_ListAddTail(struct ListNode *list, struct ListNode *item); 98d9f0492fSopenharmony_ci 99d9f0492fSopenharmony_ci/** 100d9f0492fSopenharmony_ci * @brief Remove a node from the list 101d9f0492fSopenharmony_ci * 102d9f0492fSopenharmony_ci * @param item the node to be removed from the list. 103d9f0492fSopenharmony_ci * This function does not free any memory within item. 104d9f0492fSopenharmony_ci * @return None 105d9f0492fSopenharmony_ci */ 106d9f0492fSopenharmony_civoid OH_ListRemove(struct ListNode *item); 107d9f0492fSopenharmony_ci 108d9f0492fSopenharmony_ci/** 109d9f0492fSopenharmony_ci * @brief ListNode comparison function prototype 110d9f0492fSopenharmony_ci * 111d9f0492fSopenharmony_ci * @param node ListNode to be compared. 112d9f0492fSopenharmony_ci * @param newNode new ListNode to be compared. 113d9f0492fSopenharmony_ci * @return 114d9f0492fSopenharmony_ci * <0 if node < newNode 115d9f0492fSopenharmony_ci * =0 if node = newNode 116d9f0492fSopenharmony_ci * >0 if Node > newNode 117d9f0492fSopenharmony_ci */ 118d9f0492fSopenharmony_citypedef int (*ListCompareProc)(ListNode *node, ListNode *newNode); 119d9f0492fSopenharmony_ci 120d9f0492fSopenharmony_ci/** 121d9f0492fSopenharmony_ci * @brief Add a node to the list with order 122d9f0492fSopenharmony_ci * 123d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer 124d9f0492fSopenharmony_ci * @param item new node to be added 125d9f0492fSopenharmony_ci * @param compareProc comparison function for adding node 126d9f0492fSopenharmony_ci * if it is ascending order, this function should return an integer less than, 127d9f0492fSopenharmony_ci * equal to, or greater than zero if the first argument is considered to be 128d9f0492fSopenharmony_ci * respectively less than, equal to, or greater than the second. 129d9f0492fSopenharmony_ci * @return None 130d9f0492fSopenharmony_ci */ 131d9f0492fSopenharmony_civoid OH_ListAddWithOrder(struct ListNode *head, struct ListNode *item, ListCompareProc compareProc); 132d9f0492fSopenharmony_ci 133d9f0492fSopenharmony_ci/** 134d9f0492fSopenharmony_ci * @brief ListNode traversing and find function prototype 135d9f0492fSopenharmony_ci * 136d9f0492fSopenharmony_ci * @param node ListNode to be compared. 137d9f0492fSopenharmony_ci * @param data value for traversing 138d9f0492fSopenharmony_ci * @return 139d9f0492fSopenharmony_ci * return 0 if node value equals data for OH_ListFind 140d9f0492fSopenharmony_ci */ 141d9f0492fSopenharmony_citypedef int (*ListTraversalProc)(ListNode *node, void *data); 142d9f0492fSopenharmony_ci 143d9f0492fSopenharmony_ci/** 144d9f0492fSopenharmony_ci * @brief Find a node by traversing the list 145d9f0492fSopenharmony_ci * 146d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer. 147d9f0492fSopenharmony_ci * @param data comparing data. 148d9f0492fSopenharmony_ci * @param compareProc comparing function, return 0 if matched. 149d9f0492fSopenharmony_ci * @return the found node; return NULL if none is found. 150d9f0492fSopenharmony_ci */ 151d9f0492fSopenharmony_ciListNode *OH_ListFind(const ListNode *head, void *data, ListTraversalProc compareProc); 152d9f0492fSopenharmony_ci 153d9f0492fSopenharmony_ci/* Traversing from end to start */ 154d9f0492fSopenharmony_ci#define TRAVERSE_REVERSE_ORDER 0x1 155d9f0492fSopenharmony_ci/* Stop traversing when error returned */ 156d9f0492fSopenharmony_ci#define TRAVERSE_STOP_WHEN_ERROR 0x2 157d9f0492fSopenharmony_ci 158d9f0492fSopenharmony_ci/** 159d9f0492fSopenharmony_ci * @brief Traversal the list with specified function 160d9f0492fSopenharmony_ci * 161d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer. 162d9f0492fSopenharmony_ci * @param cookie optional traversing data. 163d9f0492fSopenharmony_ci * @param traversalProc comparing function, return 0 if matched. 164d9f0492fSopenharmony_ci * @param flags optional traversing flags: 165d9f0492fSopenharmony_ci * TRAVERSE_REVERSE_ORDER: traversing from last node to first node; 166d9f0492fSopenharmony_ci * default behaviour is from first node to last node 167d9f0492fSopenharmony_ci * TRAVERSE_STOP_WHEN_ERROR: stop traversing if traversalProc return non-zero 168d9f0492fSopenharmony_ci * default behaviour will ignore traversalProc return values 169d9f0492fSopenharmony_ci * @return return -1 for invalid input arguments. 170d9f0492fSopenharmony_ci * when TRAVERSE_STOP_WHEN_ERROR is specified, it will return errors from traversalProc 171d9f0492fSopenharmony_ci */ 172d9f0492fSopenharmony_ciint OH_ListTraversal(ListNode *head, void *data, ListTraversalProc traversalProc, unsigned int flags); 173d9f0492fSopenharmony_ci 174d9f0492fSopenharmony_ci/** 175d9f0492fSopenharmony_ci * @brief ListNode destroy function prototype 176d9f0492fSopenharmony_ci * 177d9f0492fSopenharmony_ci * @param node ListNode to be destroyed. 178d9f0492fSopenharmony_ci * @return None 179d9f0492fSopenharmony_ci */ 180d9f0492fSopenharmony_citypedef void (*ListDestroyProc)(ListNode *node); 181d9f0492fSopenharmony_ci 182d9f0492fSopenharmony_ci/** 183d9f0492fSopenharmony_ci * @brief Find a node by traversing the list 184d9f0492fSopenharmony_ci * 185d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer. 186d9f0492fSopenharmony_ci * @param destroyProc destroy function; if NULL, it will free each node by default. 187d9f0492fSopenharmony_ci * @return None 188d9f0492fSopenharmony_ci */ 189d9f0492fSopenharmony_civoid OH_ListRemoveAll(ListNode *head, ListDestroyProc destroyProc); 190d9f0492fSopenharmony_ci 191d9f0492fSopenharmony_ci/** 192d9f0492fSopenharmony_ci * @brief Get list count 193d9f0492fSopenharmony_ci * 194d9f0492fSopenharmony_ci * @param head list head, make sure head is valid pointer. 195d9f0492fSopenharmony_ci * @return the count of nodes in the list; return 0 if error 196d9f0492fSopenharmony_ci */ 197d9f0492fSopenharmony_ciint OH_ListGetCnt(const ListNode *head); 198d9f0492fSopenharmony_ci 199d9f0492fSopenharmony_ci#ifdef __cplusplus 200d9f0492fSopenharmony_ci#if __cplusplus 201d9f0492fSopenharmony_ci} 202d9f0492fSopenharmony_ci#endif 203d9f0492fSopenharmony_ci#endif 204d9f0492fSopenharmony_ci 205d9f0492fSopenharmony_ci#endif // BASE_STARTUP_INITLITE_LIST_H 206