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