1 /**
2  * @file lv_ll.h
3  * Handle linked lists. The nodes are dynamically allocated by the 'lv_mem' module.
4  */
5 
6 #ifndef LV_LL_H
7 #define LV_LL_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 #include "lv_types.h"
18 
19 /*********************
20  *      DEFINES
21  *********************/
22 
23 /**********************
24  *      TYPEDEFS
25  **********************/
26 
27 /** Dummy type to make handling easier*/
28 typedef uint8_t lv_ll_node_t;
29 
30 /** Description of a linked list*/
31 typedef struct {
32     uint32_t n_size;
33     lv_ll_node_t * head;
34     lv_ll_node_t * tail;
35 } lv_ll_t;
36 
37 /**********************
38  * GLOBAL PROTOTYPES
39  **********************/
40 
41 /**
42  * Initialize linked list
43  * @param ll_p pointer to lv_ll_t variable
44  * @param node_size the size of 1 node in bytes
45  */
46 void lv_ll_init(lv_ll_t * ll_p, uint32_t node_size);
47 
48 /**
49  * Add a new head to a linked list
50  * @param ll_p pointer to linked list
51  * @return pointer to the new head
52  */
53 void * lv_ll_ins_head(lv_ll_t * ll_p);
54 
55 /**
56  * Insert a new node in front of the n_act node
57  * @param ll_p pointer to linked list
58  * @param n_act pointer a node
59  * @return pointer to the new node
60  */
61 void * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act);
62 
63 /**
64  * Add a new tail to a linked list
65  * @param ll_p pointer to linked list
66  * @return pointer to the new tail
67  */
68 void * lv_ll_ins_tail(lv_ll_t * ll_p);
69 
70 /**
71  * Remove the node 'node_p' from 'll_p' linked list.
72  * It does not free the memory of node.
73  * @param ll_p pointer to the linked list of 'node_p'
74  * @param node_p pointer to node in 'll_p' linked list
75  */
76 void lv_ll_remove(lv_ll_t * ll_p, void * node_p);
77 
78 void lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *));
79 
80 /**
81  * Remove and free all elements from a linked list. The list remain valid but become empty.
82  * @param ll_p pointer to linked list
83  */
84 void lv_ll_clear(lv_ll_t * ll_p);
85 
86 /**
87  * Move a node to a new linked list
88  * @param ll_ori_p pointer to the original (old) linked list
89  * @param ll_new_p pointer to the new linked list
90  * @param node pointer to a node
91  * @param head true: be the head in the new list
92  *             false be the tail in the new list
93  */
94 void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head);
95 
96 /**
97  * Return with head node of the linked list
98  * @param ll_p pointer to linked list
99  * @return pointer to the head of 'll_p'
100  */
101 void * lv_ll_get_head(const lv_ll_t * ll_p);
102 
103 /**
104  * Return with tail node of the linked list
105  * @param ll_p pointer to linked list
106  * @return pointer to the tail of 'll_p'
107  */
108 void * lv_ll_get_tail(const lv_ll_t * ll_p);
109 
110 /**
111  * Return with the pointer of the next node after 'n_act'
112  * @param ll_p pointer to linked list
113  * @param n_act pointer a node
114  * @return pointer to the next node
115  */
116 void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act);
117 
118 /**
119  * Return with the pointer of the previous node after 'n_act'
120  * @param ll_p pointer to linked list
121  * @param n_act pointer a node
122  * @return pointer to the previous node
123  */
124 void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act);
125 
126 /**
127  * Return the length of the linked list.
128  * @param ll_p pointer to linked list
129  * @return length of the linked list
130  */
131 uint32_t lv_ll_get_len(const lv_ll_t * ll_p);
132 
133 /*
134  * TODO
135  * @param ll_p
136  * @param n1_p
137  * @param n2_p
138 void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p);
139  */
140 
141 /**
142  * Move a node before another node in the same linked list
143  *
144  * @param ll_p pointer to a linked list
145  * @param n_act pointer to node to move
146  * @param n_after pointer to a node which should be after `n_act`
147  */
148 void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after);
149 
150 /**
151  * Check if a linked list is empty
152  * @param ll_p pointer to a linked list
153  * @return true: the linked list is empty; false: not empty
154  */
155 bool lv_ll_is_empty(lv_ll_t * ll_p);
156 
157 /**********************
158  *      MACROS
159  **********************/
160 
161 #define LV_LL_READ(list, i) for(i = lv_ll_get_head(list); i != NULL; i = lv_ll_get_next(list, i))
162 
163 #define LV_LL_READ_BACK(list, i) for(i = lv_ll_get_tail(list); i != NULL; i = lv_ll_get_prev(list, i))
164 
165 #ifdef __cplusplus
166 } /*extern "C"*/
167 #endif
168 
169 #endif
170