• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file cstl_rawlist.c
3  * @copyright Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 
16  * @brief raw_list 实现
17  * @details raw_list源码
18  * @date 2021-04-15
19  * @version v0.1.0
20  * *******************************************************************************************
21  * @par 修改日志:
22  * <table>
23  * <tr><th>Date        <th>Version  <th>Author    <th>Description
24  * </table>
25  * *******************************************************************************************
26  * @par 修改日志:
27  * <table>
28  * <tr><th>Date        <th>Version  <th>Author    <th>Description
29  * </table>
30  * *******************************************************************************************
31  */
32 
33 #include <stdlib.h>
34 #include "cstl_public_inner.h"
35 #include "cstl_rawlist.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /* 内部函数定义 */
CstlRawListNodeInList(const CstlRawListNode * node)42 CSTL_STATIC inline bool CstlRawListNodeInList(const CstlRawListNode *node)
43 {
44     bool ret = false;
45 
46     if ((node->next != NULL) && (node->prev != NULL) &&
47         ((const CstlRawListNode *)(node->next->prev) == node) &&
48         ((const CstlRawListNode *)(node->prev->next) == node)) {
49         ret = true;
50     }
51 
52     return ret;
53 }
54 
CstlRawListEmptyCheck(const CstlRawList * list)55 CSTL_STATIC inline bool CstlRawListEmptyCheck(const CstlRawList *list)
56 {
57     return (&list->head)->next == &list->head;
58 }
59 
CstlRawListAddAfterNode(CstlRawListNode * node,CstlRawListNode * where)60 CSTL_STATIC inline void CstlRawListAddAfterNode(CstlRawListNode *node, CstlRawListNode *where)
61 {
62     node->next       = (where)->next;
63     node->prev       = (where);
64     where->next      = node;
65     node->next->prev = node;
66 }
67 
CstlRawListAddBeforeNode(CstlRawListNode * node,const CstlRawListNode * where)68 CSTL_STATIC inline void CstlRawListAddBeforeNode(CstlRawListNode *node, const CstlRawListNode *where)
69 {
70     CstlRawListAddAfterNode(node, where->prev);
71 }
72 
CstlRawListIsFirstNode(const CstlRawList * list,const CstlRawListNode * node)73 CSTL_STATIC inline bool CstlRawListIsFirstNode(const CstlRawList *list, const CstlRawListNode *node)
74 {
75     bool ret = false;
76 
77     if ((const CstlRawListNode *)list->head.next == node) {
78         ret = true;
79     }
80 
81     return ret;
82 }
83 
CstlRawListIsLastNode(const CstlRawList * list,const CstlRawListNode * node)84 CSTL_STATIC inline bool CstlRawListIsLastNode(const CstlRawList *list, const CstlRawListNode *node)
85 {
86     bool ret = false;
87 
88     if ((const CstlRawListNode *)list->head.prev == node) {
89         ret = true;
90     }
91 
92     return ret;
93 }
94 
95 /* 删除链表节点,内部函数,不做入参校验 */
CstlRawListRemoveNode(CstlRawList * list,CstlRawListNode * node)96 CSTL_STATIC void CstlRawListRemoveNode(CstlRawList *list, CstlRawListNode *node)
97 {
98     node->prev->next = node->next;
99     node->next->prev = node->prev;
100 
101     if (list->freeFunc != NULL) {
102         list->freeFunc((void *)node);
103     }
104 }
105 
CstlRawListInit(CstlRawList * list,CstlFreeFunc freeFunc)106 __attribute__((visibility("default"))) int32_t CstlRawListInit(
107     CstlRawList *list, CstlFreeFunc freeFunc)
108 {
109     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
110 
111     if (list != NULL) {
112         list->head.next = &list->head;
113         list->head.prev = &list->head;
114         list->freeFunc  = freeFunc;
115         ret = CSTL_OK;
116     }
117 
118     return ret;
119 }
120 
CstlRawListClear(CstlRawList * list)121 __attribute__((visibility("default"))) int32_t CstlRawListClear(
122     CstlRawList *list)
123 {
124     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
125 
126     if (list != NULL) {
127         while (!CstlRawListEmptyCheck(list)) {
128             CstlRawListRemoveNode(list, (CstlRawListNode *)list->head.next);
129         }
130 
131         ret = CSTL_OK;
132     }
133 
134     return ret;
135 }
136 
CstlRawListDeinit(CstlRawList * list)137 __attribute__((visibility("default"))) int32_t CstlRawListDeinit(
138     CstlRawList *list)
139 {
140     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
141 
142     if (list != NULL) {
143         ret = CstlRawListClear(list);
144         list->freeFunc = NULL;
145     }
146 
147     return ret;
148 }
149 
CstlRawListEmpty(const CstlRawList * list)150 __attribute__((visibility("default"))) bool CstlRawListEmpty(
151     const CstlRawList *list)
152 {
153     bool ret = true;
154 
155     if (list != NULL) {
156         ret = CstlRawListEmptyCheck(list);
157     }
158 
159     return ret;
160 }
161 
CstlRawListSizeInner(const CstlRawList * list)162 CSTL_STATIC inline size_t CstlRawListSizeInner(const CstlRawList *list)
163 {
164     size_t size = 0;
165     const CstlRawListNode *node, *head;
166 
167     head = &list->head;
168     for (node = head->next; node != head; node = node->next) {
169         size++;
170     }
171 
172     return size;
173 }
174 
CstlRawListSize(const CstlRawList * list)175 __attribute__((visibility("default"))) size_t CstlRawListSize(
176     const CstlRawList *list)
177 {
178     size_t size = 0;
179 
180     if ((list != NULL) && !CstlRawListEmptyCheck(list)) {
181         size = CstlRawListSizeInner(list);
182     }
183 
184     return size;
185 }
186 
CstlRawListPushFront(CstlRawList * list,CstlRawListNode * node)187 __attribute__((visibility("default"))) int32_t CstlRawListPushFront(
188     CstlRawList *list, CstlRawListNode *node)
189 {
190     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
191 
192     if ((list != NULL) && (node != NULL)) {
193         CstlRawListAddAfterNode(node, &(list->head));
194         ret = CSTL_OK;
195     }
196 
197     return ret;
198 }
199 
CstlRawListPushBack(CstlRawList * list,CstlRawListNode * node)200 __attribute__((visibility("default"))) int32_t CstlRawListPushBack(
201     CstlRawList *list, CstlRawListNode *node)
202 {
203     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
204 
205     if ((list != NULL) && (node != NULL)) {
206         CstlRawListAddBeforeNode(node, &(list->head));
207         ret = CSTL_OK;
208     }
209 
210     return ret;
211 }
212 
CstlRawListInsert(const CstlRawListNode * curNode,CstlRawListNode * newNode)213 __attribute__((visibility("default"))) int32_t CstlRawListInsert(
214     const CstlRawListNode *curNode, CstlRawListNode *newNode)
215 {
216     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
217 
218     if ((curNode != NULL) && (newNode != NULL) && (CstlRawListNodeInList(curNode))) {
219         CstlRawListAddBeforeNode(newNode, curNode);
220         ret = CSTL_OK;
221     }
222 
223     return ret;
224 }
225 
CstlRawListPopFront(CstlRawList * list)226 __attribute__((visibility("default"))) int32_t CstlRawListPopFront(
227     CstlRawList *list)
228 {
229     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
230     CstlRawListNode *firstNode;
231 
232     if ((list != NULL) && (!CstlRawListEmptyCheck(list))) {
233         firstNode = list->head.next;
234         CstlRawListRemoveNode(list, firstNode);
235         ret = CSTL_OK;
236     }
237 
238     return ret;
239 }
240 
CstlRawListPopBack(CstlRawList * list)241 __attribute__((visibility("default"))) int32_t CstlRawListPopBack(
242     CstlRawList *list)
243 {
244     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
245     CstlRawListNode *lastNode;
246 
247     if (list != NULL) {
248         if (!CstlRawListEmptyCheck(list)) {
249             lastNode = list->head.prev;
250             CstlRawListRemoveNode(list, lastNode);
251             ret = CSTL_OK;
252         } else {
253             ret = (int32_t)ERRNO_CSTL_ELEMENT_EMPTY;
254         }
255     }
256 
257     return ret;
258 }
259 
CstlRawListEraseInner(CstlRawList * list,CstlRawListNode * node)260 CSTL_STATIC void CstlRawListEraseInner(CstlRawList *list, CstlRawListNode *node)
261 {
262     node->prev->next = node->next;
263     node->next->prev = node->prev;
264 
265     if ((list != NULL) && !CstlRawListEmptyCheck(list) && (list->freeFunc != NULL)) {
266         list->freeFunc((void *)node);
267     }
268 }
269 
CstlRawListErase(CstlRawList * list,CstlRawListNode * node)270 __attribute__((visibility("default"))) int32_t CstlRawListErase(
271     CstlRawList *list, CstlRawListNode *node)
272 {
273     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
274 
275     if ((node != NULL) && (CstlRawListNodeInList(node))) {
276         CstlRawListEraseInner(list, node);
277         ret = CSTL_OK;
278     }
279 
280     return ret;
281 }
282 
CstlRawListFront(const CstlRawList * list)283 __attribute__((visibility("default"))) CstlRawListNode *CstlRawListFront(
284     const CstlRawList *list)
285 {
286     CstlRawListNode *front = NULL;
287 
288     if ((list != NULL) && (!CstlRawListEmptyCheck(list))) {
289         front = list->head.next;
290     }
291 
292     return front;
293 }
294 
CstlRawListBack(const CstlRawList * list)295 __attribute__((visibility("default"))) CstlRawListNode *CstlRawListBack(
296     const CstlRawList *list)
297 {
298     CstlRawListNode *back = NULL;
299 
300     if ((list != NULL) && (!CstlRawListEmptyCheck(list))) {
301         back = list->head.prev;
302     }
303 
304     return back;
305 }
306 
CstlRawListPrev(const CstlRawList * list,const CstlRawListNode * node)307 __attribute__((visibility("default"))) CstlRawListNode *CstlRawListPrev(
308     const CstlRawList *list, const CstlRawListNode *node)
309 {
310     CstlRawListNode *prev;
311 
312     if ((list == NULL) || (node == NULL) ||
313         (CstlRawListEmptyCheck(list)) || (CstlRawListIsFirstNode(list, node)) || (!CstlRawListNodeInList(node))) {
314         prev = NULL;
315     } else {
316         prev = node->prev;
317     }
318 
319     return prev;
320 }
321 
CstlRawListNext(const CstlRawList * list,const CstlRawListNode * node)322 __attribute__((visibility("default"))) CstlRawListNode *CstlRawListNext(
323     const CstlRawList *list, const CstlRawListNode *node)
324 {
325     CstlRawListNode *next;
326 
327     if ((list == NULL) || (node == NULL) ||
328         (CstlRawListEmptyCheck(list)) || (CstlRawListIsLastNode(list, node)) || (!CstlRawListNodeInList(node))) {
329         next = NULL;
330     } else {
331         next = node->next;
332     }
333 
334     return next;
335 }
336 
CstlRawListSortInner(CstlRawList * list,CstlDataCmpFunc cmpFunc)337 CSTL_STATIC void CstlRawListSortInner(CstlRawList *list, CstlDataCmpFunc cmpFunc)
338 {
339     ssize_t i, j;
340     ssize_t count;
341     int32_t cmpResult;
342     CstlRawListNode *node;
343     CstlRawListNode *nextNode;
344 
345     count = (ssize_t)CstlRawListSizeInner(list);
346     for (i = 0; i < (count - 1); ++i) {
347         node = CstlRawListFront(list);
348         for (j = 0; j < (count - i - 1); ++j) {
349             nextNode = node->next;
350             cmpResult = cmpFunc(node, nextNode);
351             if (cmpResult > 0) {
352                 node->prev->next = nextNode;
353                 nextNode->prev = node->prev;
354 
355                 node->prev = nextNode;
356                 node->next = nextNode->next;
357                 nextNode->next->prev = node;
358                 nextNode->next = node;
359 
360                 continue;
361             }
362             node = node->next;
363         }
364     }
365 }
366 
367 /* 链表排序函数,此处函数钩子cmpFunc的两个入参,类型需由用户保证是(CstlRawListNode *) */
CstlRawListSort(CstlRawList * list,CstlDataCmpFunc cmpFunc)368 __attribute__((visibility("default"))) int32_t CstlRawListSort(
369     CstlRawList *list, CstlDataCmpFunc cmpFunc)
370 {
371     int32_t ret = (int32_t)ERRNO_CSTL_INPUT_INVALID;
372 
373     if ((list != NULL) && (cmpFunc != NULL)) {
374         CstlRawListSortInner(list, cmpFunc);
375         ret = CSTL_OK;
376     }
377 
378     return ret;
379 }
380 
381 /* 链表节点查找函数,此处函数钩子nodeMatchFunc的第一个入参,类型需由用户保证是(CstlRawListNode *) */
CstlRawListNodeFind(const CstlRawList * list,CstlMatchFunc nodeMatchFunc,uintptr_t data)382 __attribute__((visibility("default"))) CstlRawListNode *CstlRawListNodeFind(
383     const CstlRawList *list, CstlMatchFunc nodeMatchFunc, uintptr_t data)
384 {
385     CstlRawListNode *ans = NULL;
386     CstlRawListNode *node;
387     const CstlRawListNode *head;
388 
389     if ((list != NULL) && (nodeMatchFunc != NULL)) {
390         head = (const CstlRawListNode *)(&list->head);
391         node = head->next;
392         while ((const CstlRawListNode *)node != head) {
393             if (nodeMatchFunc((void *)node, data)) {
394                 ans = node;
395                 break;
396             }
397             node = node->next;
398         }
399     }
400 
401     return ans;
402 }
403 
404 #ifdef __cplusplus
405 }
406 #endif
407