• 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 #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