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 <stdint.h>
21 #include "list_base.h"
22 #include "bsl_errno.h"
23 #include "bsl_sal.h"
24 #include "bsl_hash_list.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 typedef struct BslListNodeSt ListNode;
31
BSL_ListInit(BSL_List * list,const ListDupFreeFuncPair * dataFunc)32 int32_t BSL_ListInit(BSL_List *list, const ListDupFreeFuncPair *dataFunc)
33 {
34 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
35
36 if (list != NULL) {
37 ret = ListRawInit(&list->rawList, NULL);
38
39 if (dataFunc == NULL) {
40 list->dataFunc.dupFunc = NULL;
41 list->dataFunc.freeFunc = NULL;
42 } else {
43 list->dataFunc.dupFunc = dataFunc->dupFunc;
44 list->dataFunc.freeFunc = dataFunc->freeFunc;
45 }
46 }
47
48 return ret;
49 }
50
ListRemoveNode(BSL_List * list,ListNode * node)51 static int32_t ListRemoveNode(BSL_List *list, ListNode *node)
52 {
53 int32_t ret;
54
55 if (list->dataFunc.freeFunc != NULL) {
56 (list->dataFunc.freeFunc((void *)(node->userdata)));
57 }
58
59 ret = ListRawRemove(&list->rawList, &node->rawNode);
60 if (ret == BSL_SUCCESS) {
61 BSL_SAL_FREE(node);
62 }
63
64 return ret;
65 }
66
BSL_ListClear(BSL_List * list)67 int32_t BSL_ListClear(BSL_List *list)
68 {
69 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
70 ListNode *node = NULL;
71 const RawList *rawList = NULL;
72 const ListRawNode *head = NULL;
73
74 if (list != NULL) {
75 rawList = &list->rawList;
76 head = &rawList->head;
77 while (!ListRawEmpty(rawList)) {
78 node = BSL_CONTAINER_OF(head->next, ListNode, rawNode);
79 ret = ListRemoveNode(list, node);
80 if (ret != BSL_SUCCESS) {
81 break;
82 }
83 }
84 }
85
86 return ret;
87 }
88
BSL_ListDeinit(BSL_List * list)89 int32_t BSL_ListDeinit(BSL_List *list)
90 {
91 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
92
93 if (list != NULL) {
94 ret = BSL_ListClear(list);
95 list->dataFunc.dupFunc = NULL;
96 list->dataFunc.freeFunc = NULL;
97 }
98
99 return ret;
100 }
101
ListWriteUserdata(const BSL_List * list,ListNode * node,uintptr_t userData,size_t userDataSize)102 static int32_t ListWriteUserdata(const BSL_List *list, ListNode *node, uintptr_t userData, size_t userDataSize)
103 {
104 int32_t ret;
105 const void *copyBuff = NULL;
106
107 if (list->dataFunc.dupFunc == NULL) {
108 node->userdata = userData;
109 ret = BSL_SUCCESS;
110 } else {
111 copyBuff = list->dataFunc.dupFunc((void *)userData, userDataSize);
112 if (copyBuff == NULL) {
113 ret = BSL_INTERNAL_EXCEPTION;
114 } else {
115 node->userdata = (uintptr_t)copyBuff;
116 ret = BSL_SUCCESS;
117 }
118 }
119
120 return ret;
121 }
122
NewNodeCreateByUserData(const BSL_List * list,uintptr_t userData,size_t userDataSize)123 static ListNode *NewNodeCreateByUserData(const BSL_List *list, uintptr_t userData, size_t userDataSize)
124 {
125 ListNode *node = NULL;
126
127 if (list != NULL) {
128 node = (ListNode *)BSL_SAL_Malloc(sizeof(ListNode));
129 if (node != NULL) {
130 if (ListWriteUserdata(list, node, userData, userDataSize) != BSL_SUCCESS) {
131 BSL_SAL_FREE(node);
132 node = NULL;
133 }
134 }
135 }
136
137 return node;
138 }
139
BSL_ListPushFront(BSL_List * list,uintptr_t userData,size_t userDataSize)140 int32_t BSL_ListPushFront(BSL_List *list, uintptr_t userData, size_t userDataSize)
141 {
142 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
143 ListNode *node;
144
145 node = NewNodeCreateByUserData(list, userData, userDataSize);
146 if (node != NULL) {
147 ret = ListRawPushFront(&list->rawList, &node->rawNode);
148 }
149
150 return ret;
151 }
152
BSL_ListPushBack(BSL_List * list,uintptr_t userData,size_t userDataSize)153 int32_t BSL_ListPushBack(BSL_List *list, uintptr_t userData, size_t userDataSize)
154 {
155 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
156 ListNode *node = NULL;
157
158 if (list != NULL) {
159 node = NewNodeCreateByUserData(list, userData, userDataSize);
160 if (node != NULL) {
161 ret = ListRawPushBack(&list->rawList, &node->rawNode);
162 } else {
163 ret = (int32_t)BSL_INTERNAL_EXCEPTION;
164 }
165 }
166
167 return ret;
168 }
169
BSL_ListInsert(BSL_List * list,const BSL_ListIterator it,uintptr_t userData,size_t userDataSize)170 int32_t BSL_ListInsert(BSL_List *list, const BSL_ListIterator it, uintptr_t userData, size_t userDataSize)
171 {
172 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
173 ListNode *node = NULL;
174
175 if ((list != NULL) && (it != NULL)) {
176 node = NewNodeCreateByUserData(list, userData, userDataSize);
177 if (node != NULL) {
178 ret = ListIRawnsert(&it->rawNode, &node->rawNode);
179 if (ret != BSL_SUCCESS) {
180 if (list->dataFunc.freeFunc != NULL) {
181 list->dataFunc.freeFunc((void *)(node->userdata));
182 }
183 BSL_SAL_FREE(node);
184 }
185 } else {
186 ret = (int32_t)BSL_INTERNAL_EXCEPTION;
187 }
188 }
189
190 return ret;
191 }
192
BSL_ListIsEmpty(const BSL_List * list)193 bool BSL_ListIsEmpty(const BSL_List *list)
194 {
195 bool ret = true;
196
197 if (list != NULL) {
198 ret = ListRawEmpty(&list->rawList);
199 }
200
201 return ret;
202 }
203
BSL_ListPopFront(BSL_List * list)204 int32_t BSL_ListPopFront(BSL_List *list)
205 {
206 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
207 ListNode *firstNode = NULL;
208
209 if (!BSL_ListIsEmpty(list)) {
210 firstNode = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
211 ret = ListRemoveNode(list, firstNode);
212 }
213
214 return ret;
215 }
216
BSL_ListPopBack(BSL_List * list)217 int32_t BSL_ListPopBack(BSL_List *list)
218 {
219 int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
220 ListNode *lastNode = NULL;
221
222 if (!BSL_ListIsEmpty(list)) {
223 lastNode = BSL_CONTAINER_OF(list->rawList.head.prev, ListNode, rawNode);
224 ret = ListRemoveNode(list, lastNode);
225 }
226
227 return ret;
228 }
229
BSL_ListIterErase(BSL_List * list,BSL_ListIterator it)230 BSL_ListIterator BSL_ListIterErase(BSL_List *list, BSL_ListIterator it)
231 {
232 int32_t ret = BSL_INTERNAL_EXCEPTION;
233 BSL_ListIterator retIt;
234
235 if (BSL_ListIsEmpty(list) || (it == NULL) || (it == (BSL_ListIterator)(&list->rawList.head))) {
236 retIt = NULL;
237 } else {
238 retIt = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
239 ret = ListRemoveNode(list, it);
240 }
241
242 if (ret != BSL_SUCCESS) {
243 retIt = NULL;
244 }
245
246 return retIt;
247 }
248
BSL_ListFront(const BSL_List * list)249 uintptr_t BSL_ListFront(const BSL_List *list)
250 {
251 uintptr_t frontData = 0;
252 const ListNode *node = NULL;
253
254 if (!BSL_ListIsEmpty(list)) {
255 node = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
256 frontData = node->userdata;
257 }
258
259 return frontData;
260 }
261
BSL_ListBack(const BSL_List * list)262 uintptr_t BSL_ListBack(const BSL_List *list)
263 {
264 uintptr_t backData = 0;
265 const ListNode *node = NULL;
266
267 if (!BSL_ListIsEmpty(list)) {
268 node = BSL_CONTAINER_OF(list->rawList.head.prev, ListNode, rawNode);
269 backData = node->userdata;
270 }
271
272 return backData;
273 }
274
BSL_ListIterBegin(const BSL_List * list)275 BSL_ListIterator BSL_ListIterBegin(const BSL_List *list)
276 {
277 BSL_ListIterator beginIterator = NULL;
278
279 if (list != NULL) {
280 beginIterator = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
281 }
282
283 return beginIterator;
284 }
285
BSL_ListIterEnd(BSL_List * list)286 BSL_ListIterator BSL_ListIterEnd(BSL_List *list)
287 {
288 BSL_ListIterator endIterator = NULL;
289
290 if (list != NULL) {
291 endIterator = (BSL_ListIterator)(&list->rawList.head);
292 }
293
294 return endIterator;
295 }
296
BSL_ListSize(const BSL_List * list)297 size_t BSL_ListSize(const BSL_List *list)
298 {
299 size_t size = 0;
300
301 if (list != NULL) {
302 size = ListRawSize(&list->rawList);
303 }
304
305 return size;
306 }
307
BSL_ListIterPrev(const BSL_List * list,const BSL_ListIterator it)308 BSL_ListIterator BSL_ListIterPrev(const BSL_List *list, const BSL_ListIterator it)
309 {
310 BSL_ListIterator prev = NULL;
311
312 if ((!BSL_ListIsEmpty(list)) && (it != NULL)) {
313 prev = BSL_CONTAINER_OF(it->rawNode.prev, ListNode, rawNode);
314 }
315
316 return prev;
317 }
318
BSL_ListIterNext(const BSL_List * list,const BSL_ListIterator it)319 BSL_ListIterator BSL_ListIterNext(const BSL_List *list, const BSL_ListIterator it)
320 {
321 BSL_ListIterator next = NULL;
322
323 if ((!BSL_ListIsEmpty(list)) && (it != NULL)) {
324 next = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
325 }
326
327 return next;
328 }
329
BSL_ListIterData(const BSL_ListIterator it)330 uintptr_t BSL_ListIterData(const BSL_ListIterator it)
331 {
332 uintptr_t data = 0;
333
334 if (it != NULL) {
335 data = it->userdata;
336 }
337
338 return data;
339 }
340
341 /* Linked list node search function. The type of the first parameter of iterCmpFunc is userdata of each iterator. */
BSL_ListIterFind(BSL_List * list,ListKeyCmpFunc iterCmpFunc,uintptr_t data)342 BSL_ListIterator BSL_ListIterFind(BSL_List *list, ListKeyCmpFunc iterCmpFunc, uintptr_t data)
343 {
344 BSL_ListIterator it = NULL, headIt = NULL;
345 BSL_ListIterator ans = NULL;
346
347 if ((list != NULL) && (iterCmpFunc != NULL)) {
348 headIt = (BSL_ListIterator)BSL_CONTAINER_OF(&list->rawList.head, ListNode, rawNode);
349 it = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
350 while (it != headIt) {
351 if (iterCmpFunc(it->userdata, data) == 0) {
352 ans = it;
353 break;
354 }
355
356 it = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
357 }
358 }
359
360 return ans;
361 }
362
363 #ifdef __cplusplus
364 }
365 #endif
366
367 #endif /* HITLS_BSL_HASH */
368