5 // Copyright (c) 2020 Apple Inc. All rights reserved.
11 #pragma mark - Includes
14 #include <AssertMacros.h> // for require_* macro
15 #include "mDNSEmbeddedAPI.h" // for mStatus
16 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
18 #pragma mark - Structures
22 #pragma mark list_node_t
25 * A node in the list_t.
27 typedef struct list_node list_node_t
;
29 list_node_t
* _Nullable prev
;
30 list_node_t
* _Nullable next
;
31 mDNSu8 data
[0]; // the actual data will be stored starting from data, so list_node_t->data can access it
37 * A structure that represents a generic doublely linked list.
39 typedef struct list list_t
;
41 mDNSu32 data_size
; // to check if the data put into the list matches the size of actual structure
42 list_node_t
* _Nullable head_ptr
;
43 list_node_t
* _Nullable tail_ptr
;
44 list_node_t head
; // dummy head will be pointed by head_ptr
45 list_node_t tail
; // dummy tail will be pointed by tail_ptr
48 #pragma mark - Functions
52 #pragma mark list_init
55 * Initializes list_t, must be called before using the list
58 * The pointer to the unintialized list
60 * @param new_data_size
61 * the size of the data that will be put into the list
64 * After the list is initialized with "new_data_size", we could only put the same data structure that has the same "data_size" into the list
67 list_init(list_t
* const _Nonnull list_to_init
, const mDNSu32 new_data_size
);
69 #pragma mark list_append_uinitialized
72 * Appends a node at the end of the list, and return a memory pointer that can be used to store the data structure.
75 * The pointer to the list.
77 * @param new_data_size
78 * The size of the data structure that will be appended into the list.
81 * The output pointer to the memory location that can be used to save the data structure.
84 * mStatus_NoError if everything works fine, or other error codes defined in mStatus.
87 * The returned memory pointer can be used to initialize a data structure which will stored in the list.
90 list_append_uinitialized(list_t
* const _Nonnull list_ptr
, const mDNSu32 new_data_size
, void * _Nullable
* _Nonnull out_data_ptr
);
92 #pragma mark list_prepend_uinitialized
95 * Prepends a node at the start of the list, and return a memory pointer that can be used to store the data structure.
98 * The pointer to the list.
100 * @param new_data_size
101 * The size of the data structure that will be appended into the list.
103 * @param out_data_ptr
104 * The output pointer to the memory location that can be used to save the data structure.
107 * mStatus_NoError if everything works fine, or other error codes defined in mStatus.
110 * The returned memory pointer can be used to initialize a data structure which will be stored in the list.
113 list_prepend_uinitialized(list_t
* const _Nonnull list_ptr
, const mDNSu32 new_data_size
, void * _Nullable
* _Nonnull out_data_ptr
);
115 #pragma mark list_append_node
118 * Given a list_node_t structure, insert it in the end of the list.
120 * The pointer to the list.
122 * The list_node_t structure to be inserted.
125 list_append_node(list_t
* const _Nonnull list_ptr
, list_node_t
* const _Nonnull node_ptr
);
129 * Given a list_node_t structure, insert it in the start of the list.
131 * The pointer to the list.
133 * The list_node_t structure to be inserted.
135 #pragma mark list_prepend_node
137 list_prepend_node(list_t
* const _Nonnull list_ptr
, list_node_t
* const _Nonnull node_ptr
);
139 #pragma mark list_append_node_at_node
142 * Append the list_node_t after the given node in the list
143 * @param original_node
144 * The node to be appended after.
146 * The node to append.
149 list_append_node_at_node(list_node_t
* const _Nonnull original_node
, list_node_t
* const _Nonnull added_node
);
151 #pragma mark list_prepend_node_at_node
154 * Prepend the list_node_t before the given node in the list
155 * @param original_node
156 * The node to be appended after.
158 * The node to prepend.
161 list_prepend_node_at_node(list_node_t
* const _Nonnull original_node
, list_node_t
* const _Nonnull added_node
);
163 #pragma mark list_concatenate
166 * Concatenate two lists together.
168 * The list to concatenate with.
170 * The list to concatenate with.
172 * The concatenation result is the dst_list.
175 list_concatenate(list_t
* const _Nonnull dst_list
, list_t
* const _Nonnull src_list
);
177 #pragma mark list_sort_comparator_t
180 * The sort comparator for the list.
182 * The list_node_t to be compared.
184 * The list_node_t to be compared.
186 * If the comparator returns -1, 0 and 1, -1 means left is less than right, 0 means left is equal to right, 1 means left is greater than right
188 typedef mDNSs8 (* _Nonnull list_sort_comparator_t
)(const list_node_t
* _Nonnull
const left
, const list_node_t
* _Nonnull
const right
);
190 #pragma mark list_sort
193 * Sort the node in the list according to the comparator.
195 * The list to be sorted.
197 * The list_sort_comparator_t that defines the sort order.
199 * If the comparator returns -1, 0 and 1, -1 means left is less than right, 0 means left is equal to right, 1 means left is greater than right
202 list_sort(list_t
* const _Nonnull list_ptr
, list_sort_comparator_t comparator
);
204 #pragma mark list_node_detach
207 * Detach the list_node_t from the list
209 * The node to be detached
211 * It will only seperate the node from the list, the node itself still exists.
214 list_node_detach(list_node_t
* const _Nonnull node
);
216 #pragma mark list_node_delete
219 * Delete the current node that is in the list.
221 * The pointer of the node to be deleted.
223 * This function must be used for the node that is in the list.
226 list_node_delete(list_node_t
* const _Nonnull node_ptr
);
228 #pragma mark list_node_delete_all
231 * Delete all nodes in the list
233 * The pointer to the list.
236 list_node_delete_all(list_t
* const _Nonnull list_ptr
);
238 #pragma mark list_delete_node_with_data_ptr
241 * Delete the node in the list that contains the data.
243 * The pointer to the list that will delete the node.
245 * The pointer to the data that one node in list contains.
247 * return mStatus_NoError if the node is found and deleted from the list, return mStatus_NoSuchKey if the node does not exist.
249 * The function will scan through the list, compare the data field of node with the "data" parameter.
252 list_delete_node_with_data_ptr(list_t
* const _Nonnull list_ptr
, void * const _Nonnull data
);
254 #pragma mark list_empty
257 * Test if the list is empty or not.
261 * Returns true if the lis is empty, returns false if the list has nodes inside.
264 list_empty(const list_t
* const _Nonnull list_ptr
);
266 #pragma mark list_count_node
269 * Get the number of nodes in the list.
271 * The list to count node.
273 * The number of nodes.
276 list_count_node(const list_t
*const _Nonnull list_ptr
);
278 #pragma mark list_get_first
281 * Get the first node in the list.
283 * The pointer to the list.
285 * The first list_node_t in the list, if the list is empty, NULL is returned.
287 mDNSexport list_node_t
* _Nullable
288 list_get_first(const list_t
* const _Nonnull list_ptr
);
290 #pragma mark list_get_last
293 * Get the last node in the list.
295 * The pointer to the list.
297 * The last list_node_t in the list, if the list is empty, NULL is returned.
299 mDNSexport list_node_t
* _Nullable
300 list_get_last(const list_t
* const _Nonnull list_ptr
);
302 #pragma mark list_next
305 * Get the next node of the current node in the list.
307 * The pointer to the current node.
311 mDNSexport list_node_t
* _Nonnull
312 list_next(const list_node_t
* const _Nonnull node_ptr
);
314 #pragma mark list_has_ended
317 * Test if the current node has reached the end of the list.
319 * The pointer to the list.
321 * The pointer to the node.
323 * Returns true if the node_ptr points to the end of the list, returns false if it has more nodes coming next.
326 list_has_ended(const list_t
* const _Nonnull list_ptr
, const list_node_t
* const _Nullable node_ptr
);
328 #pragma mark list_uninit
331 * Delete all the existing nodes in the list, and untialize the list structure.
333 * The pointer to the list that will be uninitialized.
336 list_uninit(list_t
* const _Nonnull list_ptr
);
338 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)