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