1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_HASH
18
19 #include <stdlib.h>
20 #include "bsl_errno.h"
21 #include "list_base.h"
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 /* internal function definition */
ListRawNodeInList(const ListRawNode * node)28 static inline bool ListRawNodeInList(const ListRawNode *node)
29 {
30 bool ret = false;
31
32 if ((node->next != NULL) && (node->prev != NULL) &&
33 ((const ListRawNode *)(node->next->prev) == node) &&
34 ((const ListRawNode *)(node->prev->next) == node)) {
35 ret = true;
36 }
37
38 return ret;
39 }
40
IsListRawEmptyCheck(const RawList * list)41 static inline bool IsListRawEmptyCheck(const RawList *list)
42 {
43 return (&list->head)->next == &list->head;
44 }
45
ListRawAddAfterNode(ListRawNode * node,ListRawNode * where)46 static inline void ListRawAddAfterNode(ListRawNode *node, ListRawNode *where)
47 {
48 node->next = (where)->next;
49 node->prev = (where);
50 where->next = node;
51 node->next->prev = node;
52 }
53
ListRawAddBeforeNode(ListRawNode * node,const ListRawNode * where)54 static inline void ListRawAddBeforeNode(ListRawNode *node, const ListRawNode *where)
55 {
56 ListRawAddAfterNode(node, where->prev);
57 }
58
IsListRawFirstNode(const RawList * list,const ListRawNode * node)59 static inline bool IsListRawFirstNode(const RawList *list, const ListRawNode *node)
60 {
61 bool ret = false;
62
63 if ((const ListRawNode *)list->head.next == node) {
64 ret = true;
65 }
66
67 return ret;
68 }
69
IsListRawLastNode(const RawList * list,const ListRawNode * node)70 static inline bool IsListRawLastNode(const RawList *list, const ListRawNode *node)
71 {
72 bool ret = false;
73
74 if ((const ListRawNode *)list->head.prev == node) {
75 ret = true;
76 }
77
78 return ret;
79 }
80
81 /* Deleting the list node, internal function, input parameter validation is not required. */
ListRawRemoveNode(const RawList * list,ListRawNode * node)82 static void ListRawRemoveNode(const RawList *list, ListRawNode *node)
83 {
84 node->prev->next = node->next;
85 node->next->prev = node->prev;
86
87 if (list->freeFunc != NULL) {
88 list->freeFunc((void *)node);
89 }
90 }
91
ListRawInit(RawList * list,ListFreeFunc freeFunc)92 int32_t ListRawInit(RawList *list, ListFreeFunc freeFunc)
93 {
94 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
95
96 if (list != NULL) {
97 list->head.next = &list->head;
98 list->head.prev = &list->head;
99 list->freeFunc = freeFunc;
100 ret = BSL_SUCCESS;
101 }
102
103 return ret;
104 }
105
ListRawClear(RawList * list)106 int32_t ListRawClear(RawList *list)
107 {
108 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
109
110 if (list != NULL) {
111 while (!IsListRawEmptyCheck(list)) {
112 ListRawRemoveNode(list, (ListRawNode *)list->head.next);
113 }
114
115 ret = BSL_SUCCESS;
116 }
117
118 return ret;
119 }
120
ListRawDeinit(RawList * list)121 int32_t ListRawDeinit(RawList *list)
122 {
123 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
124
125 if (list != NULL) {
126 ret = ListRawClear(list);
127 list->freeFunc = NULL;
128 }
129
130 return ret;
131 }
132
ListRawEmpty(const RawList * list)133 bool ListRawEmpty(const RawList *list)
134 {
135 bool ret = true;
136
137 if (list != NULL) {
138 ret = IsListRawEmptyCheck(list);
139 }
140
141 return ret;
142 }
143
ListRawSizeInner(const RawList * list)144 static inline size_t ListRawSizeInner(const RawList *list)
145 {
146 size_t size = 0;
147 const ListRawNode *node = NULL, *head = NULL;
148
149 head = &list->head;
150 for (node = head->next; node != head; node = node->next) {
151 size++;
152 }
153
154 return size;
155 }
156
ListRawSize(const RawList * list)157 size_t ListRawSize(const RawList *list)
158 {
159 size_t size = 0;
160
161 if ((list != NULL) && !IsListRawEmptyCheck(list)) {
162 size = ListRawSizeInner(list);
163 }
164
165 return size;
166 }
167
ListRawPushFront(RawList * list,ListRawNode * node)168 int32_t ListRawPushFront(RawList *list, ListRawNode *node)
169 {
170 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
171
172 if ((list != NULL) && (node != NULL)) {
173 ListRawAddAfterNode(node, &(list->head));
174 ret = BSL_SUCCESS;
175 }
176
177 return ret;
178 }
179
ListRawPushBack(RawList * list,ListRawNode * node)180 int32_t ListRawPushBack(RawList *list, ListRawNode *node)
181 {
182 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
183
184 if ((list != NULL) && (node != NULL)) {
185 ListRawAddBeforeNode(node, &(list->head));
186 ret = BSL_SUCCESS;
187 }
188
189 return ret;
190 }
191
ListIRawnsert(const ListRawNode * curNode,ListRawNode * newNode)192 int32_t ListIRawnsert(const ListRawNode *curNode, ListRawNode *newNode)
193 {
194 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
195
196 if ((curNode != NULL) && (newNode != NULL) && (ListRawNodeInList(curNode))) {
197 ListRawAddBeforeNode(newNode, curNode);
198 ret = BSL_SUCCESS;
199 }
200
201 return ret;
202 }
203
ListRawPopFront(RawList * list)204 int32_t ListRawPopFront(RawList *list)
205 {
206 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
207 ListRawNode *firstNode = NULL;
208
209 if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
210 firstNode = list->head.next;
211 ListRawRemoveNode(list, firstNode);
212 ret = BSL_SUCCESS;
213 }
214
215 return ret;
216 }
217
ListRawPopBack(RawList * list)218 int32_t ListRawPopBack(RawList *list)
219 {
220 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
221 ListRawNode *lastNode = NULL;
222
223 if (list != NULL) {
224 if (!IsListRawEmptyCheck(list)) {
225 lastNode = list->head.prev;
226 ListRawRemoveNode(list, lastNode);
227 ret = BSL_SUCCESS;
228 } else {
229 ret = (int32_t)BSL_INTERNAL_EXCEPTION;
230 }
231 }
232
233 return ret;
234 }
235
ListRawRemoveInner(RawList * list,ListRawNode * node)236 static void ListRawRemoveInner(RawList *list, ListRawNode *node)
237 {
238 node->prev->next = node->next;
239 node->next->prev = node->prev;
240
241 if ((list != NULL) && !IsListRawEmptyCheck(list) && (list->freeFunc != NULL)) {
242 list->freeFunc((void *)node);
243 }
244 }
245
ListRawRemove(RawList * list,ListRawNode * node)246 int32_t ListRawRemove(RawList *list, ListRawNode *node)
247 {
248 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
249
250 if ((node != NULL) && (ListRawNodeInList(node))) {
251 ListRawRemoveInner(list, node);
252 ret = BSL_SUCCESS;
253 }
254
255 return ret;
256 }
257
ListRawFront(const RawList * list)258 ListRawNode *ListRawFront(const RawList *list)
259 {
260 ListRawNode *front = NULL;
261
262 if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
263 front = list->head.next;
264 }
265
266 return front;
267 }
268
ListRawBack(const RawList * list)269 ListRawNode *ListRawBack(const RawList *list)
270 {
271 ListRawNode *back = NULL;
272
273 if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
274 back = list->head.prev;
275 }
276
277 return back;
278 }
279
ListRawGetPrev(const RawList * list,const ListRawNode * node)280 ListRawNode *ListRawGetPrev(const RawList *list, const ListRawNode *node)
281 {
282 ListRawNode *prev = NULL;
283
284 if ((list == NULL) || (node == NULL) ||
285 (IsListRawEmptyCheck(list)) || (IsListRawFirstNode(list, node)) || (!ListRawNodeInList(node))) {
286 prev = NULL;
287 } else {
288 prev = node->prev;
289 }
290
291 return prev;
292 }
293
ListRawGetNext(const RawList * list,const ListRawNode * node)294 ListRawNode *ListRawGetNext(const RawList *list, const ListRawNode *node)
295 {
296 ListRawNode *next = NULL;
297
298 if ((list == NULL) || (node == NULL) ||
299 (IsListRawEmptyCheck(list)) || (IsListRawLastNode(list, node)) || (!ListRawNodeInList(node))) {
300 next = NULL;
301 } else {
302 next = node->next;
303 }
304
305 return next;
306 }
307
308 /* Linked list node search function. The type of the first parameter of nodeMatchFunc must be (ListRawNode *) */
ListRawFindNode(const RawList * list,ListMatchFunc nodeMatchFunc,uintptr_t data)309 ListRawNode *ListRawFindNode(const RawList *list, ListMatchFunc nodeMatchFunc, uintptr_t data)
310 {
311 ListRawNode *ans = NULL;
312 ListRawNode *node = NULL;
313 const ListRawNode *head = NULL;
314
315 if ((list != NULL) && (nodeMatchFunc != NULL)) {
316 head = (const ListRawNode *)(&list->head);
317 node = head->next;
318 while ((const ListRawNode *)node != head) {
319 if (nodeMatchFunc((void *)node, data)) {
320 ans = node;
321 break;
322 }
323 node = node->next;
324 }
325 }
326
327 return ans;
328 }
329
330 #ifdef __cplusplus
331 }
332 #endif
333
334 #endif /* HITLS_BSL_HASH */
335