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_LIST
18
19 #include <stdlib.h>
20 #include "bsl_list.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "bsl_list_internal.h"
24
25 #define SEC_MAX_QSORT_SIZE (64 * 1024 * 1024)
26 #define SEC_MIN_QSORT_SIZE 10000
27
28 static uint32_t g_maxQsortElem = 100000;
29
BSL_LIST_New(int32_t dataSize)30 BslList *BSL_LIST_New(int32_t dataSize)
31 {
32 BslList *pstList = NULL;
33
34 if (dataSize < 0) {
35 return NULL;
36 }
37 pstList = BSL_SAL_Calloc(1, sizeof(BslList));
38 if (pstList == NULL) {
39 return NULL;
40 }
41
42 pstList->curr = NULL;
43 pstList->last = NULL;
44 pstList->first = NULL;
45 pstList->dataSize = dataSize;
46 pstList->count = 0;
47
48 return pstList;
49 }
50
BSL_LIST_Prev(BslList * pstList)51 void *BSL_LIST_Prev(BslList *pstList)
52 {
53 if (pstList == NULL) {
54 return NULL;
55 }
56
57 if (pstList->curr != NULL) {
58 pstList->curr = pstList->curr->prev;
59 } else {
60 pstList->curr = pstList->last;
61 }
62
63 if (pstList->curr != NULL) {
64 return (void *)&(pstList->curr->data);
65 }
66
67 return NULL;
68 }
69
BSL_LIST_Next(BslList * pstList)70 void *BSL_LIST_Next(BslList *pstList)
71 {
72 if (pstList == NULL) {
73 return NULL;
74 }
75
76 if (pstList->curr != NULL) {
77 pstList->curr = pstList->curr->next;
78 } else {
79 pstList->curr = pstList->first;
80 }
81
82 if (pstList->curr != NULL) {
83 return (void *)&(pstList->curr->data);
84 }
85
86 return NULL;
87 }
88
BSL_LIST_Last(BslList * pstList)89 void *BSL_LIST_Last(BslList *pstList)
90 {
91 if (pstList == NULL) {
92 return NULL;
93 }
94
95 pstList->curr = pstList->last;
96
97 if (pstList->curr != NULL) {
98 return (void *)&(pstList->curr->data);
99 }
100
101 return NULL;
102 }
103
BSL_LIST_First(BslList * pstList)104 void *BSL_LIST_First(BslList *pstList)
105 {
106 if (pstList == NULL) {
107 return NULL;
108 }
109
110 pstList->curr = pstList->first;
111
112 if (pstList->curr != NULL) {
113 return (void *)&(pstList->curr->data);
114 }
115
116 return NULL;
117 }
118
BSL_LIST_Curr(const BslList * pstList)119 void *BSL_LIST_Curr(const BslList *pstList)
120 {
121 if (pstList == NULL || pstList->curr == NULL) {
122 return NULL;
123 }
124
125 return (void *)&(pstList->curr->data);
126 }
127
BSL_LIST_GetElmtIndex(const void * elmt,BslList * pstList)128 int32_t BSL_LIST_GetElmtIndex(const void *elmt, BslList *pstList)
129 {
130 int32_t idx = 0;
131 void *tmpElmt = NULL;
132
133 if (pstList == NULL) {
134 return -1; // -1 means that the corresponding element is not found
135 }
136
137 BslListNode *tmp = (void *)pstList->curr;
138
139 for ((pstList)->curr = (pstList)->first; (pstList)->curr != NULL; (pstList)->curr = (pstList)->curr->next) {
140 tmpElmt = pstList->curr->data;
141 if (tmpElmt == NULL) {
142 break;
143 }
144 if (tmpElmt != elmt) {
145 idx++;
146 continue;
147 }
148
149 pstList->curr = tmp;
150 return idx;
151 }
152
153 pstList->curr = tmp;
154
155 return -1; // -1 means that the corresponding element is not found
156 }
157
BSL_ListSortInternal(BslList * pList,BSL_LIST_PFUNC_CMP cmp)158 int32_t BSL_ListSortInternal(BslList *pList, BSL_LIST_PFUNC_CMP cmp)
159 {
160 void **sortArray = NULL;
161 void *elmt = NULL;
162 int32_t i;
163
164 /* Make sure pList is not NULL */
165 if (pList == NULL || g_maxQsortElem < (uint32_t)pList->count) {
166 BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
167 return BSL_INVALID_ARG;
168 }
169
170 /* Create array of elements so we can qsort the pList */
171 sortArray = BSL_SAL_Calloc((uint32_t)pList->count, sizeof(void *));
172 if (sortArray == NULL) {
173 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
174 return BSL_MALLOC_FAIL;
175 }
176
177 /* Copy the elements from the pList into the sort array */
178 for (pList->curr = pList->first, i = 0; pList->curr; pList->curr = pList->curr->next, i++) {
179 elmt = (void *)pList->curr->data;
180 if (elmt == NULL || i >= pList->count) {
181 break;
182 }
183
184 sortArray[i] = elmt;
185 }
186 /* sort encoded elements */
187 qsort(sortArray, (uint32_t)pList->count, sizeof(void *), cmp);
188
189 for (pList->curr = pList->first, i = 0; pList->curr != NULL; pList->curr = pList->curr->next, i++) {
190 pList->curr->data = sortArray[i];
191 }
192
193 BSL_SAL_FREE(sortArray);
194
195 /* Return the sorted pList */
196 return BSL_SUCCESS;
197 }
198
BSL_LIST_SetMaxQsortCount(uint32_t uiQsortSize)199 int32_t BSL_LIST_SetMaxQsortCount(uint32_t uiQsortSize)
200 {
201 if ((uiQsortSize > SEC_MAX_QSORT_SIZE) || (uiQsortSize < SEC_MIN_QSORT_SIZE)) {
202 BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
203 return BSL_INVALID_ARG;
204 }
205
206 g_maxQsortElem = uiQsortSize;
207 return BSL_SUCCESS;
208 }
209
BSL_LIST_GetMaxQsortCount(void)210 uint32_t BSL_LIST_GetMaxQsortCount(void)
211 {
212 return g_maxQsortElem;
213 }
214 #endif /* HITLS_BSL_LIST */
215