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