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