• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /**
17  * @defgroup bsl_list
18  * @ingroup bsl
19  * @brief linked list
20  */
21 
22 #ifndef BSL_LIST_H
23 #define BSL_LIST_H
24 
25 #include <stdint.h>
26 #include "bsl_errno.h"
27 #include "bsl_sal.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /* for handling ASN.1 SET OF type */
34 
35 /**
36  * @ingroup bsl_list
37  *
38  */
39 typedef struct BslListNode {
40     struct BslListNode *prev; /**< The previous node in the list */
41     struct BslListNode *next; /**< The next node in the list */
42     void *data;               /**< This must be the last field of this structure */
43 } BslListNode;
44 
45 /**
46  * @ingroup bsl_list
47  *
48  */
49 typedef struct BslList {
50     BslListNode *first;     /**< The first node in the list */
51     BslListNode *last;      /**< The last node in the list */
52     BslListNode *curr;      /**< The current node in the list */
53     int32_t count;          /**< count of elements */
54     int32_t dataSize;       /**< Memory needed for each node data */
55 } BslList;
56 
57 /**
58  * @ingroup bsl_list
59  *
60  * the enum for specifying whether to add the element before/after the
61  * current element.  It is used in BSL_LIST_AddElement()
62  * @datastruct BSL_LIST_POS_BEFORE Indication to to add the element before the current element.
63  * @datastruct BSL_LIST_POS_AFTER Indication to to add the element after the current element.
64  * @datastruct BSL_LIST_POS_BEGIN Indication to to add the element at the beginning of the list.
65  * @datastruct BSL_LIST_POS_END Indication to to add the element at the end of the list.
66  */
67 typedef enum {
68     BSL_LIST_POS_BEFORE, /**< Indication to to add the element before the current element */
69     BSL_LIST_POS_AFTER,  /**< Indication to to add the element after the current element */
70     BSL_LIST_POS_BEGIN,  /**< Indication to to add the element at the beginning of the list */
71     BSL_LIST_POS_END     /**< Indication to to add the element at the end of the list */
72 } BslListPosition;
73 
74 /**
75  * @ingroup bsl_list
76  *
77  * This is a pointer to the list comparison function used in BSL_LIST_Search function.
78  * It takes two pointers and compares them based on a criteria. If the two are equal a zero is returned.
79  * If the first should preceed the second, a negative is returned. Else a positive value is returned.
80  */
81 typedef int32_t (*BSL_LIST_PFUNC_CMP)(const void *, const void *);
82 
83 /**
84  * @ingroup bsl_list
85  *
86  * This is a pointer to the free function.
87  * The free function takes a pointer to data structure to be freed and must return void.
88  */
89 typedef void (*BSL_LIST_PFUNC_FREE)(void *);
90 
91 /**
92  * @ingroup bsl_list
93  *
94  * This is a pointer to the Copy function.
95  * The copy function takes a pointer to data structure to be freed and must return void.
96  */
97 typedef void *(*BSL_LIST_PFUNC_DUP)(const void *);
98 
99 /*
100   The following macros return the specified element of the list.  They do
101   not change the current list pointer.
102  */
103 /* returns the current element */
104 #define BSL_LIST_CURR_ELMT(pList) ((pList) ? ((pList)->curr ? ((pList)->curr->data) : NULL) : NULL)
105 
106 /* returns the next element */
107 #define BSL_LIST_NEXT_ELMT(pList) \
108     ((pList) ? ((pList)->curr ? ((pList)->curr->next ? ((pList)->curr->next->data) : NULL) : NULL) : NULL)
109 
110 /* returns the previous element */
111 #define BSL_LIST_PREV_ELMT(pList) \
112     ((pList) ? ((pList)->curr ? ((pList)->curr->prev ? ((pList)->curr->prev->data) : NULL) : NULL) : NULL)
113 
114 /* returns the last element */
115 #define BSL_LIST_LAST_ELMT(pList) ((pList) ? ((pList)->last ? ((pList)->last->data) : NULL) : NULL)
116 
117 /* returns the first element */
118 #define BSL_LIST_FIRST_ELMT(pList) ((pList) ? ((pList)->first ? ((pList)->first->data) : NULL) : NULL)
119 
120 /* checks if the list is NULL */
121 #define BSL_LIST_EMPTY(pList) (((pList) != NULL) ? ((pList)->count == 0) : 0)
122 
123 /* returns the number of nodes in the list */
124 #define BSL_LIST_COUNT(pList) ((pList) ? ((pList)->count) : 0)
125 
126 /* checks if current node is the end */
127 #define BSL_LIST_IS_END(pList) ((pList) ? (NULL == (pList)->curr) : 0)
128 
129 /* checks if current node is the first one */
130 #define BSL_LIST_IS_START(pList) ((pList) ? ((pList)->first == (pList)->curr) : 0)
131 
132 /* Get the next element */
133 #define BSL_LIST_GET_NEXT(pList) ((pList) ? (BSL_LIST_Next(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL)
134 
135 /* Get the previous element */
136 #define BSL_LIST_GET_PREV(pList) ((pList) ? (BSL_LIST_Prev(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL)
137 
138 /* Get the first element */
139 #define BSL_LIST_GET_FIRST(pList) ((pList) ? (BSL_LIST_First(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL)
140 
141 /* Get the last element */
142 #define BSL_LIST_GET_LAST(pList) ((pList) ? (BSL_LIST_Last(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL)
143 
144 /**
145  * @ingroup bsl_list
146  *
147  * Delete all the nodes in the list and then frees the header
148  */
149 #define BSL_LIST_FREE(pList, pFreeFunc)        \
150     do {                                       \
151         BSL_LIST_DeleteAll((pList), pFreeFunc); \
152         if (NULL != (pList)) {             \
153             BSL_SAL_Free(pList);                  \
154             (pList) = NULL;                       \
155         }                                      \
156     } while (0)
157 
158 
159 #define SEC_INT_ERROR (-2)
160 
161 /**
162  * @ingroup bsl_list
163  *
164  * This function sets the max element in BSL_LIST.Default value is 10000000 (10 Million).
165  *
166  * @param iMaxElements [IN] Max allowed element in BSL_LIST. It should be in range[0xffff, 0xfffffff]
167  * @retval #BSL_INVALID_ARG If input falls outside the range.
168  * @retval #BSL_SUCCESS If successful.
169  */
170 int32_t BSL_LIST_SetMaxElements(int32_t iMaxElements);
171 
172 /**
173  * @ingroup bsl_list
174  *
175  * This function returns the max allowed elements in BSL_LIST.
176  *
177  * @retval int32_t Max configured elements in BSL_LIST
178  */
179 int32_t BSL_LIST_GetMaxElements(void);
180 
181 /**
182  * @ingroup bsl_list
183  *
184  * This function creates a new node before, after or at the begining or end of the current node. If the list was already
185  * NULL, the node will be added as the only node.The current pointer is changed to point to the newly added node in the
186  * list. If the current pointer is NULL then this operation fails.
187  *
188  * @param pList [IN] The list
189  * @param pData [IN] The element to be added
190  * @param enPosition [IN] Whether the element is to be added before or after the list
191  * @retval The error code.
192  * @retval #BSL_SUCCESS If successful.
193  */
194 int32_t BSL_LIST_AddElement(BslList *pList, void *pData, BslListPosition enPosition);
195 
196 /**
197  * @ingroup bsl_list
198  *
199  * This function deletes all the nodes of the list but does not delete the list header.
200  *
201  * @param pList [IN] The list
202  * @param pfFreeFunc [IN] The freefunction to free the data pointer in each node
203  */
204 void BSL_LIST_DeleteAll(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc);
205 
206 /**
207  * @ingroup bsl_list
208  *
209  * This function deletes the current element of list.
210  *
211  * @param pList [IN] The list
212  * @param pfFreeFunc [IN] The pointer to the free function of data
213  */
214 void BSL_LIST_DeleteCurrent(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc);
215 
216 /**
217  * @ingroup bsl_list
218  *
219  * This function detaches the current element from the list, the current node will be freed, but the data contained
220  * in the current node will not be freed.Also the pList->first, pList->curr and pList->last will be appropriately
221  * updated. If the current node is the last node, then pList->curr will point to its previous node after detachment,
222  * else it will point to its next node.
223  *
224  * @param pList [IN] The list
225  */
226 void BSL_LIST_DetachCurrent(BslList *pList);
227 
228 /**
229  * @ingroup bsl_list
230  *
231  * This function searches a list based on the comparator function
232  * supplied (3rd param). The second param is given to the
233  * comparator as its second param and each data item on the
234  * list is given as its first param while searching. The
235  * comparator must return 0 to indicate a match.
236  *
237  * @param pList [IN] The list
238  * @param pSearchFor [IN] The element to be searched
239  * @param pSearcher [IN] The pointer to the comparison function of data
240  * @retval Void* The element which was found [Void*]
241  * @retval Void* If none found [NULL]
242  */
243 void *BSL_LIST_Search(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher, int32_t *pstErr);
244 
245 /**
246  * @ingroup bsl_list
247  *
248  * This function returns the node at the given index in the list, starting at 0.
249  *
250  * @param pList [IN] The list
251  * @param ulIndex [IN] The index in the list
252  * @retval Void* The element which was found [Void*]
253  * @retval Void* If none found [NULL]
254  */
255 void *BSL_LIST_GetIndexNode(uint32_t ulIndex, BslList *pList);
256 
257 /**
258  * @ingroup bsl_list
259  *
260  * This function dups a list by copying the list by creating a copy of list
261  * and returns the destinaton list pointer.
262  *
263  * @param pSrcList [IN] The list
264  * @param pFuncCpy [IN] The dup function for the data in the node
265  * @param pfFreeFunc [IN] The pointer to the free function for the data in the node of data
266  * @retval BslList* The duplicated List pointer [BslList*]
267  * @retval BslList* If dup failed or memory allocation fails.[NULL]
268  */
269 BslList *BSL_LIST_Copy(BslList *pSrcList, BSL_LIST_PFUNC_DUP pFuncCpy, BSL_LIST_PFUNC_FREE pfFreeFunc);
270 
271 /**
272  * @ingroup bsl_list
273  *
274  * This function sorts the list using the comparison function provided.
275  *
276  * @param pList [IN] The list
277  * @param pfCmp [IN] The comparison function
278  * @retval BslList* If unsuccessful [NULL]
279  * @retval BslList* If successful [The destination sorted list]
280  */
281 BslList *BSL_LIST_Sort(BslList *pList, BSL_LIST_PFUNC_CMP pfCmp);
282 
283 /**
284  * @ingroup bsl_list
285  *
286  * This function is used to create a new list.
287  *
288  * @param dataSize [IN] Size of the data inside the list node
289  * @retval BslList* An NULL list [BslList*]
290  */
291 BslList *BSL_LIST_New(int32_t dataSize);
292 
293 /**
294  * @ingroup bsl_list
295  *
296  * This function returns the data of the current element in the list.
297  *
298  * @param pstList [IN] Input list
299  * @retval void* Data at the current element in the list [void*]
300  * @retval void* If the current element does not exist in the list [NULL]
301  * @retval void* If memory allocation fails. [NULL]
302  */
303 void *BSL_LIST_Curr(const BslList *pstList);
304 
305 /**
306  * @ingroup bsl_list
307  *
308  * This function returns the data at the first element of the list.
309  *
310  * @param pstList [IN] the list
311  * @retval void* Data at the first element of the list [void*]
312  * @retval void* If the first element does not exist [NULL]
313  */
314 void *BSL_LIST_First(BslList *pstList);
315 
316 /**
317  * @ingroup bsl_list
318  *
319  * This function returns the data at the last element of the list.
320  *
321  * @param pstList [IN] The list
322  * @retval void* Data at the last element of the list [void*]
323  * @retval void* If the last element does not exist [NULL]
324  */
325 void *BSL_LIST_Last(BslList *pstList);
326 
327 /**
328  * @ingroup bsl_list
329  *
330  * This function advances the current pointer by one and returns the data address of the new
331  * current node. If the current pointer is off the list, the new current node
332  * will be the first node of the list (unless the list is NULL).
333  *
334  * @param pstList [IN] The list
335  * @retval void* Pointer to the next element in the list [void*]
336  * @retval void* If the next element does not exist [NULL]
337  */
338 void *BSL_LIST_Next(BslList *pstList);
339 
340 /**
341  * @ingroup bsl_list
342  *
343  * backs up the current pointer by one and returns the data address of the new
344  * current node. If the current pointer is off the list, the new current node
345  * will be the last node of the list (unless the list is NULL).
346  *
347  * @param pstList [IN] The list
348  * @retval void* Pointer to the previous element in the list [void*]
349  * @retval void* If the previous element does not exist[NULL]
350  */
351 void *BSL_LIST_Prev(BslList *pstList);
352 
353 /**
354  * @ingroup bsl_list
355  *
356  * This function returns the index (starting a 0 for the first element)
357  * of the given element in the given list.
358  * Returns -1, if the element is not in the list.
359  * Assumes that the list node contains a single pointer.
360  *
361  * @param elmt [IN] The element whose index is to be retrieved
362  * @param pstList [IN] The list to which the element belongs to
363  * @retval int32_t The index of the specified element in the given list [int32_t]
364  * @retval int32_t If the element is not found in the list [-1]
365  */
366 int32_t BSL_LIST_GetElmtIndex(const void *elmt, BslList *pstList);
367 
368 /**
369  * @ingroup bsl_list
370  *
371  * This function is used to concatenate list 2 to list 1.
372  *
373  * @param pDestList [IN] The list to which the 2nd list is to be concatenated to.
374  * @param pSrcList [IN] The list which is to be concatenated.
375  * @retval BslList* The concatenated list. [BslList*]
376  */
377 BslList *BSL_LIST_Concat(BslList *pDestList, const BslList *pSrcList);
378 
379 /**
380  * @ingroup bsl_list
381  *
382  * This function is used to free the Asn list.
383  *
384  * @param pstList [IN] list Pointer to the Asn list which has to be freed
385  * @retval void This function does not return any value.
386  */
387 void BSL_LIST_FreeWithoutData(BslList *pstList);
388 
389 /**
390  * @ingroup bsl_list
391  *
392  * This function is used to  reverse the linked list.
393  *
394  * @param pstList [IN] Pointer to the list which has to be reversed
395  * @retval void This function does not return any value.
396  */
397 void BSL_LIST_RevList(BslList *pstList);
398 
399 /**
400  * @ingroup bsl_list
401  *
402  * This function set the max qsort Size.Default value is 100000
403  *
404  * @param uiQsortSize [IN] Max Buff Size. it should in range of [10000, 67108864] Default value is 100000
405  * @retval int32_t BSL_SUCCESS on success BSL_INVALID_ARG on Failure.
406  */
407 int32_t BSL_LIST_SetMaxQsortCount(uint32_t uiQsortSize);
408 
409 /**
410  * @ingroup bsl_list
411  *
412  * This function returns the MAX qsort Size
413  *
414  * @retval uint32_t Returns the max qsort Size.
415  */
416 uint32_t BSL_LIST_GetMaxQsortCount(void);
417 
418 /**
419  * @ingroup bsl_list
420  *
421  * Delete all the nodes in the list.
422  * But it does not delete the data pointers inside the list nodes.
423  * It is used only after sort to delete the input list to the sort function.
424  *
425  * @param pList [IN] The list.
426  */
427 void BSL_LIST_DeleteAllAfterSort(BslList *pList);
428 
429 /**
430  * @ingroup bsl_list
431  *
432  * This function returns the first element of the list.
433  *
434  * @param list [IN] The list.
435  * @retval BslListNode* first element of the list [BslListNode*]
436  * @retval BslListNode* If the first element does not exist [NULL]
437  */
438 BslListNode *BSL_LIST_FirstNode(const BslList *list);
439 
440 /**
441  * @ingroup bsl_list
442  *
443  * This function returns the data of the passed list node.
444  *
445  * @param pstNode [IN] The node.
446  * @retval void* Data of the passed list node. [void*]
447  * @retval void* If the data is not present in the list node. [NULL]
448  */
449 void *BSL_LIST_GetData(const BslListNode *pstNode);
450 
451 /**
452  * @ingroup bsl_list
453  *
454  * This function advances the current reference pointer by one and returns the
455  * new current node. If the current reference pointer is off the list,
456  * the new current node will be the first node of the list
457  * (unless the list is NULL).
458  *
459  * @param pstList [IN] The list.
460  * @param pstListNode [IN] The list node.
461  * @retval BslListNode* Pointer to next element in the list. [void*]
462  * @retval BslListNode* If the next element does not exist. [NULL]
463  */
464 BslListNode *BSL_LIST_GetNextNode(const BslList *pstList, const BslListNode *pstListNode);
465 
466 /**
467  * @ingroup bsl_list
468  *
469  * This function backs up the current reference pointer by one and returns the
470  * new current node.
471  *
472  * @param pstListNode [IN] The list node.
473  * @retval BslListNode* Pointer to the previous element in the list
474  * @retval BslListNode* If the previous element does not exist[NULL]
475  */
476 BslListNode *BSL_LIST_GetPrevNode(const BslListNode *pstListNode);
477 
478 /**
479  * @ingroup bsl_list
480  *
481  * This function deletes the matching input node from the input list.
482  *
483  * @param pstList [IN] The list.
484  * @param pstListNode [IN] The current reference node.
485  * @param pfFreeFunc [IN] The pointer to the free function of data.
486  */
487 void BSL_LIST_DeleteNode(BslList *pstList, const BslListNode *pstListNode, BSL_LIST_PFUNC_FREE pfFreeFunc);
488 
489 /**
490  * @ingroup bsl_list
491  *
492  * This function detaches the matching input node from the input list.
493  * The node will be freed but, the data contained in the
494  * node will not be freed, and also the pList->first, pList->curr,
495  * and pList->last will be appropriately updated. If the matching node
496  * is the last node, then pList->curr will point to its previous node
497  * after detachment, else it will point to its next node.
498  *
499  * @param pstList [IN] The list.
500  * @param pstListNode [in/out] when it is input parameter, it is the list node to be detached.
501  */
502 void BSL_LIST_DetachNode(BslList *pstList, BslListNode **pstListNode);
503 
504 #ifdef __cplusplus
505 }
506 #endif /* __cplusplus */
507 
508 #endif // BSL_LIST_H
509