• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file cstl_rawlist.h
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 cstl_rawlist 对外头文件
17  * @details
18  * Notes: 1、链表遍历过程中删除节点,必须先调 next 函数获取到下一个节点,才能调 erase 删除当前节点。
19  *        2、链表节点在删除时如果用户注册了释放函数,则调用该函数释放资源。用户数据中的句柄、指针等私有资源,需要用户在释放函数中释放。
20  *          若用户不注册释放函数,则仅将该节点从链表中摘除,用户必须自行释放节点内存。
21  *   +-----------------------------------------------------------+
22  *   | +------------------------------------------------------+  |
23  *   | |       head                                           |  |
24  *   | |   +----------+    +----------+    +--------------+   |  |
25  *   | +---|   prev   |<---|   prev   |<---|   prev       |<--+  |
26  *   +---->|   next   |--->|   next   |--->|   next       |------+
27  *         +----------+    +----------+    +--------------+
28  *         | count    |    | userdata |    | userdata1    |
29  *         | freefunc |    |   ...    |    | pointer      |-----------+  用户私有资源
30  *         +----------+    +----------+    | userdata...  |          \|/
31  *                                         +--------------+    +-------------+
32  *                                                             | privatedata |
33  *                                                             +-------------+
34  * @date 2021-04-15
35  * @version v0.1.0
36  * *******************************************************************************************
37  * @par 修改日志:
38  * <table>
39  * <tr><th>Date        <th>Version  <th>Description
40  * <tr><td>2021-04-15  <td>0.1.0    <td>初始化版本
41  * </table>
42  * *******************************************************************************************
43  * @par 修改日志:
44  * <table>
45  * <tr><th>Date        <th>Version  <th>Description
46  * <tr><td>2021-07-20  <td>1.0.0    <td>车规规范整改
47  * </table>
48  * *******************************************************************************************
49  */
50 
51 /**
52  * @defgroup cstl_rawlist Raw双向链表
53  * @ingroup cstl
54  */
55 #ifndef CSTL_RAWLIST_H
56 #define CSTL_RAWLIST_H
57 
58 #include <stdint.h>
59 #include <stddef.h>
60 #include <stdbool.h>
61 
62 #include "cstl_public.h"
63 
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67 
68 /**
69  * @ingroup cstl_rawlist
70  * 该结构被用来保存双向链表中节点的前向指针和后向指针。
71  * 这个链表不包含实质的数据区,一般用于组织(串接)数据节点
72  */
73 struct TagCstlRawListNode {
74     struct TagCstlRawListNode *next;     /**< 指向下一个节点 */
75     struct TagCstlRawListNode *prev;     /**< 指向前一个节点 */
76 };
77 
78 /**
79  * @ingroup cstl_rawlist
80  * 链表头
81  */
82 typedef struct TagCstlRawListNode CstlRawListNode;
83 
84 /**
85  * @ingroup cstl_rawlist
86  * 链表头
87  */
88 typedef struct {
89     CstlRawListNode head;       /**< 链表头 */
90     CstlFreeFunc    freeFunc;   /**< 节点内存释放函数,该函数需要释放节点及节点中的其他私有资源 */
91 } CstlRawList;
92 
93 /**
94  * @ingroup cstl_rawlist
95  * @brief 初始化链表
96  * @par 描述:初始化链表,按需注册用户数据中的私有资源释放函数。本函数不会申请资源。
97  * @attention \n
98  *  1:rawlist模块中的链表节点由用户进行封装并申请内存,rawlist仅做链表的维护,其资源释放应由用户在freeFunc中完成。\n
99  *  2:用户在添加数据时,传递给rawlist的参数为CstlRawListNode节点,因此rawlist传递给用户freeFunc的参数也是CstlRawListNode节点。
100  * @param list        [IN]  链表。
101  * @param freeFunc    [IN]  用户资源释放函数。
102  * @retval #CSTL_OK  0,链表初始化成功。
103  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明链表为NULL,初始化失败。
104  * @li cstl_rawlist.h:该接口声明所在的头文件。
105  */
106 int32_t CstlRawListInit(CstlRawList *list, CstlFreeFunc freeFunc);
107 
108 /**
109  * @ingroup cstl_rawlist
110  * @brief 链表节点清空,删除所有节点
111  * @par 描述:链表节点清空,删除所有节点,调用户注册的free函数释放用户私有资源,回归链表初始化后的状态。
112  * @param list    [IN]  链表
113  * @retval #CSTL_OK  0,链表清空成功。
114  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明链表为NULL,操作失败。
115  * @li cstl_rawlist.h:该接口声明所在的头文件。
116  */
117 int32_t CstlRawListClear(CstlRawList *list);
118 
119 /**
120  * @ingroup cstl_rawlist
121  * @brief 链表去初始化
122  * @par 描述:链表去初始化:删除所有节点,调用户注册的free函数释放用户私有资源,去注册钩子函数。但链表头还在。
123  * @param list    [IN]  链表
124  * @retval #CSTL_OK  0,链表去初始化成功。
125  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明链表为NULL,操作失败。
126  * @li cstl_rawlist.h:该接口声明所在的头文件。
127  */
128 int32_t CstlRawListDeinit(CstlRawList *list);
129 
130 /**
131  * @ingroup cstl_rawlist
132  * @brief 检查链表是否为空
133  * @param list    [IN] 待检查的链表
134  * @retval #true  1,链表为空或者无数据。
135  * @retval #false 0,链表不为空。
136  * @li cstl_rawlist.h:该接口声明所在的头文件。
137  */
138 bool CstlRawListEmpty(const CstlRawList *list);
139 
140 /**
141  * @ingroup cstl_rawlist
142  * @brief 获取链表中节点个数
143  * @param list  [IN] 链表
144  * @retval 链表节点个数
145  * @li cstl_rawlist.h:该接口声明所在的头文件。
146  */
147 size_t CstlRawListSize(const CstlRawList *list);
148 
149 /**
150  * @ingroup cstl_rawlist
151  * @brief 在链表头部插入节点
152  * @param list  [IN] 链表
153  * @param node  [IN] 待插入的节点
154  * @retval #CSTL_OK  0,链表头部插入成功。
155  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。链表为NULL,操作失败。
156  * @li cstl_rawlist.h:该接口声明所在的头文件。
157  */
158 int32_t CstlRawListPushFront(CstlRawList *list, CstlRawListNode *node);
159 
160 /**
161  * @ingroup cstl_rawlist
162  * @brief 在链表尾插入节点
163  * @param list  [IN] 链表
164  * @param node  [IN] 待插入的节点
165  * @retval #CSTL_OK  0,链表尾部插入成功。
166  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明链表是NULL或者node为NULL,操作失败。
167  * @li cstl_rawlist.h:该接口声明所在的头文件。
168  */
169 int32_t CstlRawListPushBack(CstlRawList *list, CstlRawListNode *node);
170 
171 /**
172  * @ingroup cstl_rawlist
173  * @brief 在指定节点前插入节点
174  * @param curNode [IN] 指定的节点
175  * @param newNode [IN] 待插入的节点
176  * @retval #CSTL_OK  0,链表插入成功。
177  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明参数不合法,操作失败。
178  * @li cstl_rawlist.h:该接口声明所在的头文件。
179  */
180 int32_t CstlRawListInsert(const CstlRawListNode *curNode, CstlRawListNode *newNode);
181 
182 /**
183  * @ingroup cstl_rawlist
184  * @brief 从链表头部POP一个节点
185  * @par 描述:从链表中移除头节点。如果在初始化时注册了free函数,还会调该钩子函数释放用户资源。\n
186  * 如果链表为空,则不做任何事情。
187  * @param list [IN]  链表
188  * @retval #CSTL_OK  0,链表头部弹出成功。
189  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明参数不合法,操作失败
190  * @retval #ERRNO_CSTL_ELEMENT_EMPTY,即0xa030001。表明list不是空指针但是无数据,操作失败。
191  * @li cstl_rawlist.h:该接口声明所在的头文件。
192  */
193 int32_t CstlRawListPopFront(CstlRawList *list);
194 
195 /**
196  * @ingroup cstl_rawlist
197  * @brief 从链表中尾部POP一个节点
198  * @par 描述:从链表中移除尾节点。如果在初始化时注册了free函数,还会调该钩子函数释放用户资源。\n
199  * 如果链表为空,则不做任何事情。
200  * @param list [IN]  链表
201  * @retval #CSTL_OK  0,链表尾部弹出成功。
202  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002,表明参数不合法,操作失败
203  * @retval #ERRNO_CSTL_ELEMENT_EMPTY,即0xa030001,表明list不是空指针但是无数据,操作失败。
204  * @li cstl_rawlist.h:该接口声明所在的头文件。
205  */
206 int32_t CstlRawListPopBack(CstlRawList *list);
207 
208 /**
209  * @ingroup cstl_rawlist
210  * @brief 删除链表中指定节点。
211  * @par 描述:\n
212  * 1.list为NULL且node在链表中时,仅将node从链表中摘除。
213  * 2.list非NULL且node在链表中时,从链表中摘除该节点,如果在初始化时注册了free函数,还会调该钩子函数释放用户资源。
214  * @param list [IN] 链表
215  * @param node [IN] 待删除的节点
216  * @retval #CSTL_OK  0,链表删除成功。
217  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明参数不合法,操作失败
218  * @li cstl_rawlist.h:该接口声明所在的头文件。
219  */
220 int32_t CstlRawListErase(CstlRawList *list, CstlRawListNode *node);
221 
222 /**
223  * @ingroup cstl_rawlist
224  * @brief 返回头节点指针
225  * @par 描述:仅用于访问头节点,不会删除该节点;如果链表为NULL,则返回NULL。
226  * @param list  [IN] 链表
227  * @attention 如果用户传入的参数不合理则一定返回NULL,所以用户需要使用正确的参数。
228  * @retval 非NULL 头节点的指针
229  * @retval NULL   链表为NULL
230  * @li cstl_rawlist.h:该接口声明所在的头文件。
231  */
232 CstlRawListNode *CstlRawListFront(const CstlRawList *list);
233 
234 /**
235  * @ingroup cstl_rawlist
236  * @brief 返回尾节点指针。
237  * @par 描述:仅用于访问尾节点,不会删除该节点;如果链表为NULL,则返回NULL。
238  * @param list  [IN] 链表
239  * @attention 如果用户传入的参数不合理则一定返回NULL,所以用户需要使用正确的参数。
240  * @retval 非NULL 尾节点的指针
241  * @retval NULL   链表为NULL
242  * @li cstl_rawlist.h:该接口声明所在的头文件。
243  */
244 CstlRawListNode *CstlRawListBack(const CstlRawList *list);
245 
246 /**
247  * @ingroup cstl_rawlist
248  * @brief 获取当前节点的前一个节点。
249  * @par 描述:获取当前节点的前一个节点指针。如果当前节点是头节点,则返回NULL。
250  * @param list  [IN] 链表
251  * @param node  [IN] 当前节点
252  * @attention 如果用户传入的参数不合理则一定返回NULL,所以用户需要使用正确的参数。
253  * @retval 非NULL 当前节点的前一个节点
254  * @retval NULL   头节点的前一个节点为空
255  * @li cstl_rawlist.h:该接口声明所在的头文件。
256  */
257 CstlRawListNode *CstlRawListPrev(const CstlRawList *list, const CstlRawListNode *node);
258 
259 /**
260  * @ingroup cstl_rawlist
261  * @brief 获取当前节点的后一个节点。
262  * @par 描述:获取当前节点的后一个节点指针。如果当前节点是尾节点,则返回NULL。
263  * @param list  [IN] 链表
264  * @param node  [IN] 当前节点
265  * @attention 如果用户传入的参数不合理则一定返回NULL,所以用户需要使用正确的参数。
266  * @retval 非NULL 当前节点的后一个节点
267  * @retval NULL   尾节点的下一个节点为空
268  * @li cstl_rawlist.h:该接口声明所在的头文件。
269  */
270 CstlRawListNode *CstlRawListNext(const CstlRawList *list, const CstlRawListNode *node);
271 
272 /**
273  * @ingroup cstl_rawlist
274  * @brief 根据用户定义的排序函数,对链表节点进行排序。
275  * @par 描述:根据用户定义的排序函数,对链表节点进行排序,排序顺序按排序函数定义实行。
276  * @attention \n
277  * 1、此处用户输入的排序函数钩子,其两个入参为两个待比较的节点值,入参类型是(CstlRawListNode *)。\n
278  * 2、用户在排序函数内部的实现,需根据节点地址偏移到用户结构体信息再进行排序比较。
279  * @param list      [IN] 链表
280  * @param cmpFunc   [IN] 排序函数钩子
281  * @retval CSTL_OK      排序成功
282  * @retval CSTL_ERROR   排序失败
283  * @retval #ERRNO_CSTL_INPUT_INVALID,即0xa030002。表明参数不合法,操作失败
284  * @li cstl_rawlist.h:该接口声明所在的头文件。
285  */
286 int32_t CstlRawListSort(CstlRawList *list, CstlDataCmpFunc cmpFunc);
287 
288 /**
289  * @ingroup cstl_rawlist
290  * @brief 根据用户定义的节点匹配函数,搜索用户想要的节点。
291  * @par 描述:根据用户定义的节点匹配函数,搜索用户想要的节点。
292  * @attention \n
293  * 1、将从链表头往后遍历,对每个节点依次调用匹配函数,直到找到第一个匹配的节点或者遍历到链表尾部结束。\n
294  * 2、此处用户输入的匹配函数钩子,其第一个入参地址是每个待搜索的节点值,入参类型是(CstlRawListNode *)。\n
295  * 3、用户在匹配钩子内部的实现,需根据节点地址偏移到用户结构体信息再进行匹配比较。
296  * 4、如果用户传入的参数不合理则一定返回NULL,所以用户需要使用正确的参数。
297  * @param list           [IN] 链表
298  * @param nodeMatchFunc  [IN] 匹配函数钩子
299  * @param data           [IN] 关键信息
300  * @retval 非NULL 查询成功,返回节点指针
301  * @retval NULL   查询失败,未找到匹配的节点
302  * @li cstl_rawlist.h:该接口声明所在的头文件。
303  */
304 CstlRawListNode *CstlRawListNodeFind(const CstlRawList *list, CstlMatchFunc nodeMatchFunc, uintptr_t data);
305 
306 #ifdef __cplusplus
307 }
308 #endif
309 
310 #endif /* CSTL_RAWLIST_H */
311