Pratyush Mallick
/
testing
this is testing
app/noos_mbed/util/list.c@0:3afcd581558d, 2021-01-14 (annotated)
- Committer:
- pmallick
- Date:
- Thu Jan 14 18:54:16 2021 +0530
- Revision:
- 0:3afcd581558d
this is testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pmallick | 0:3afcd581558d | 1 | /***************************************************************************//** |
pmallick | 0:3afcd581558d | 2 | * @file list.c |
pmallick | 0:3afcd581558d | 3 | * @brief List library implementation |
pmallick | 0:3afcd581558d | 4 | * @author Mihail Chindris (mihail.chindris@analog.com) |
pmallick | 0:3afcd581558d | 5 | ******************************************************************************** |
pmallick | 0:3afcd581558d | 6 | * Copyright 2020(c) Analog Devices, Inc. |
pmallick | 0:3afcd581558d | 7 | * |
pmallick | 0:3afcd581558d | 8 | * All rights reserved. |
pmallick | 0:3afcd581558d | 9 | * |
pmallick | 0:3afcd581558d | 10 | * Redistribution and use in source and binary forms, with or without |
pmallick | 0:3afcd581558d | 11 | * modification, are permitted provided that the following conditions are met: |
pmallick | 0:3afcd581558d | 12 | * - Redistributions of source code must retain the above copyright |
pmallick | 0:3afcd581558d | 13 | * notice, this list of conditions and the following disclaimer. |
pmallick | 0:3afcd581558d | 14 | * - Redistributions in binary form must reproduce the above copyright |
pmallick | 0:3afcd581558d | 15 | * notice, this list of conditions and the following disclaimer in |
pmallick | 0:3afcd581558d | 16 | * the documentation and/or other materials provided with the |
pmallick | 0:3afcd581558d | 17 | * distribution. |
pmallick | 0:3afcd581558d | 18 | * - Neither the name of Analog Devices, Inc. nor the names of its |
pmallick | 0:3afcd581558d | 19 | * contributors may be used to endorse or promote products derived |
pmallick | 0:3afcd581558d | 20 | * from this software without specific prior written permission. |
pmallick | 0:3afcd581558d | 21 | * - The use of this software may or may not infringe the patent rights |
pmallick | 0:3afcd581558d | 22 | * of one or more patent holders. This license does not release you |
pmallick | 0:3afcd581558d | 23 | * from the requirement that you obtain separate licenses from these |
pmallick | 0:3afcd581558d | 24 | * patent holders to use this software. |
pmallick | 0:3afcd581558d | 25 | * - Use of the software either in source or binary form, must be run |
pmallick | 0:3afcd581558d | 26 | * on or directly connected to an Analog Devices Inc. component. |
pmallick | 0:3afcd581558d | 27 | * |
pmallick | 0:3afcd581558d | 28 | * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR |
pmallick | 0:3afcd581558d | 29 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, |
pmallick | 0:3afcd581558d | 30 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
pmallick | 0:3afcd581558d | 31 | * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, |
pmallick | 0:3afcd581558d | 32 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
pmallick | 0:3afcd581558d | 33 | * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR |
pmallick | 0:3afcd581558d | 34 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
pmallick | 0:3afcd581558d | 35 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
pmallick | 0:3afcd581558d | 36 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
pmallick | 0:3afcd581558d | 37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
pmallick | 0:3afcd581558d | 38 | *******************************************************************************/ |
pmallick | 0:3afcd581558d | 39 | |
pmallick | 0:3afcd581558d | 40 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 41 | /***************************** Include Files **********************************/ |
pmallick | 0:3afcd581558d | 42 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 43 | |
pmallick | 0:3afcd581558d | 44 | #include "list.h" |
pmallick | 0:3afcd581558d | 45 | #include "error.h" |
pmallick | 0:3afcd581558d | 46 | #include <stdlib.h> |
pmallick | 0:3afcd581558d | 47 | |
pmallick | 0:3afcd581558d | 48 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 49 | /*************************** Types Declarations *******************************/ |
pmallick | 0:3afcd581558d | 50 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 51 | |
pmallick | 0:3afcd581558d | 52 | /** |
pmallick | 0:3afcd581558d | 53 | * @struct list_elem |
pmallick | 0:3afcd581558d | 54 | * @brief Format of each element of the list |
pmallick | 0:3afcd581558d | 55 | */ |
pmallick | 0:3afcd581558d | 56 | struct list_elem { |
pmallick | 0:3afcd581558d | 57 | /** User data */ |
pmallick | 0:3afcd581558d | 58 | void *data; |
pmallick | 0:3afcd581558d | 59 | /** Reference to previous element */ |
pmallick | 0:3afcd581558d | 60 | struct list_elem *prev; |
pmallick | 0:3afcd581558d | 61 | /** Reference to next element */ |
pmallick | 0:3afcd581558d | 62 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 63 | }; |
pmallick | 0:3afcd581558d | 64 | |
pmallick | 0:3afcd581558d | 65 | /** |
pmallick | 0:3afcd581558d | 66 | * @struct list_iterator |
pmallick | 0:3afcd581558d | 67 | * @brief Structure used to iterate through the list |
pmallick | 0:3afcd581558d | 68 | */ |
pmallick | 0:3afcd581558d | 69 | struct iterator { |
pmallick | 0:3afcd581558d | 70 | /** List reference */ |
pmallick | 0:3afcd581558d | 71 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 72 | /** Current element reference */ |
pmallick | 0:3afcd581558d | 73 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 74 | }; |
pmallick | 0:3afcd581558d | 75 | |
pmallick | 0:3afcd581558d | 76 | /** |
pmallick | 0:3afcd581558d | 77 | * @struct _list_desc |
pmallick | 0:3afcd581558d | 78 | * @brief List descriptor |
pmallick | 0:3afcd581558d | 79 | */ |
pmallick | 0:3afcd581558d | 80 | struct _list_desc { |
pmallick | 0:3afcd581558d | 81 | /** Reference to first element in the list */ |
pmallick | 0:3afcd581558d | 82 | struct list_elem *first; |
pmallick | 0:3afcd581558d | 83 | /** Reference to last element in the list*/ |
pmallick | 0:3afcd581558d | 84 | struct list_elem *last; |
pmallick | 0:3afcd581558d | 85 | /** Number of elements in the list */ |
pmallick | 0:3afcd581558d | 86 | uint32_t nb_elements; |
pmallick | 0:3afcd581558d | 87 | /** Function used to compare elements */ |
pmallick | 0:3afcd581558d | 88 | f_cmp comparator; |
pmallick | 0:3afcd581558d | 89 | /** Number of current active iterators */ |
pmallick | 0:3afcd581558d | 90 | uint32_t nb_iterators; |
pmallick | 0:3afcd581558d | 91 | /** Internal list iterator */ |
pmallick | 0:3afcd581558d | 92 | struct iterator l_it; |
pmallick | 0:3afcd581558d | 93 | }; |
pmallick | 0:3afcd581558d | 94 | |
pmallick | 0:3afcd581558d | 95 | /** @brief Default function used to compare element in the list ( \ref f_cmp) */ |
pmallick | 0:3afcd581558d | 96 | static int32_t default_comparator(void *data1, void *data2) |
pmallick | 0:3afcd581558d | 97 | { |
pmallick | 0:3afcd581558d | 98 | return (int32_t)(data1 - data2); |
pmallick | 0:3afcd581558d | 99 | } |
pmallick | 0:3afcd581558d | 100 | |
pmallick | 0:3afcd581558d | 101 | /** |
pmallick | 0:3afcd581558d | 102 | * @brief Creates a new list elements an configure its value |
pmallick | 0:3afcd581558d | 103 | * @param data - To set list_elem.data |
pmallick | 0:3afcd581558d | 104 | * @param prev - To set list_elem.prev |
pmallick | 0:3afcd581558d | 105 | * @param next - To set list_elem.next |
pmallick | 0:3afcd581558d | 106 | * @return Address of the new element or NULL if allocation fails. |
pmallick | 0:3afcd581558d | 107 | */ |
pmallick | 0:3afcd581558d | 108 | static inline struct list_elem *create_element(void *data, |
pmallick | 0:3afcd581558d | 109 | struct list_elem *prev, |
pmallick | 0:3afcd581558d | 110 | struct list_elem *next) |
pmallick | 0:3afcd581558d | 111 | { |
pmallick | 0:3afcd581558d | 112 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 113 | |
pmallick | 0:3afcd581558d | 114 | elem = (struct list_elem *)calloc(1, sizeof(*elem)); |
pmallick | 0:3afcd581558d | 115 | if (!elem) |
pmallick | 0:3afcd581558d | 116 | return NULL; |
pmallick | 0:3afcd581558d | 117 | elem->data = data; |
pmallick | 0:3afcd581558d | 118 | elem->prev = prev; |
pmallick | 0:3afcd581558d | 119 | elem->next = next; |
pmallick | 0:3afcd581558d | 120 | |
pmallick | 0:3afcd581558d | 121 | return (elem); |
pmallick | 0:3afcd581558d | 122 | } |
pmallick | 0:3afcd581558d | 123 | |
pmallick | 0:3afcd581558d | 124 | /** |
pmallick | 0:3afcd581558d | 125 | * @brief Updates the necesary link on the list elements to add or remove one |
pmallick | 0:3afcd581558d | 126 | * @param prev - Low element |
pmallick | 0:3afcd581558d | 127 | * @param elem - Middle element |
pmallick | 0:3afcd581558d | 128 | * @param next - High element |
pmallick | 0:3afcd581558d | 129 | */ |
pmallick | 0:3afcd581558d | 130 | static inline void update_links(struct list_elem *prev, struct list_elem *elem, |
pmallick | 0:3afcd581558d | 131 | struct list_elem *next) |
pmallick | 0:3afcd581558d | 132 | { |
pmallick | 0:3afcd581558d | 133 | if (prev) |
pmallick | 0:3afcd581558d | 134 | prev->next = elem ? elem : next; |
pmallick | 0:3afcd581558d | 135 | if (elem) { |
pmallick | 0:3afcd581558d | 136 | elem->prev = prev; |
pmallick | 0:3afcd581558d | 137 | elem->next = next; |
pmallick | 0:3afcd581558d | 138 | } |
pmallick | 0:3afcd581558d | 139 | if (next) |
pmallick | 0:3afcd581558d | 140 | next->prev = elem ? elem : prev; |
pmallick | 0:3afcd581558d | 141 | } |
pmallick | 0:3afcd581558d | 142 | |
pmallick | 0:3afcd581558d | 143 | /** |
pmallick | 0:3afcd581558d | 144 | * @brief Update according to modification the list descriptor |
pmallick | 0:3afcd581558d | 145 | * @param list - List reference |
pmallick | 0:3afcd581558d | 146 | * @param new_first - New first element |
pmallick | 0:3afcd581558d | 147 | * @param new_last - New last element |
pmallick | 0:3afcd581558d | 148 | */ |
pmallick | 0:3afcd581558d | 149 | static inline void update_desc(struct _list_desc *list, |
pmallick | 0:3afcd581558d | 150 | struct list_elem *new_first, |
pmallick | 0:3afcd581558d | 151 | struct list_elem *new_last) |
pmallick | 0:3afcd581558d | 152 | { |
pmallick | 0:3afcd581558d | 153 | if (new_first == list->first) { |
pmallick | 0:3afcd581558d | 154 | list->last = new_last; |
pmallick | 0:3afcd581558d | 155 | if (new_first == NULL || new_last == NULL) |
pmallick | 0:3afcd581558d | 156 | list->first = new_last; |
pmallick | 0:3afcd581558d | 157 | } else { /* if (new_last == list->last) */ |
pmallick | 0:3afcd581558d | 158 | list->first = new_first; |
pmallick | 0:3afcd581558d | 159 | if (new_last == NULL || new_first == NULL) |
pmallick | 0:3afcd581558d | 160 | list->last = new_first; |
pmallick | 0:3afcd581558d | 161 | } |
pmallick | 0:3afcd581558d | 162 | } |
pmallick | 0:3afcd581558d | 163 | |
pmallick | 0:3afcd581558d | 164 | /** |
pmallick | 0:3afcd581558d | 165 | * @brief Set the adapter functions acording to the adapter type |
pmallick | 0:3afcd581558d | 166 | * @param ad - Reference of the adapter |
pmallick | 0:3afcd581558d | 167 | * @param type - Type of the adapter |
pmallick | 0:3afcd581558d | 168 | */ |
pmallick | 0:3afcd581558d | 169 | static inline void set_adapter(struct list_desc *ad, enum adapter_type type) |
pmallick | 0:3afcd581558d | 170 | { |
pmallick | 0:3afcd581558d | 171 | switch (type) { |
pmallick | 0:3afcd581558d | 172 | case LIST_PRIORITY_LIST: |
pmallick | 0:3afcd581558d | 173 | ad->push = list_add_find; |
pmallick | 0:3afcd581558d | 174 | ad->pop = list_get_first; |
pmallick | 0:3afcd581558d | 175 | ad->top_next = list_read_first; |
pmallick | 0:3afcd581558d | 176 | ad->back = list_read_last; |
pmallick | 0:3afcd581558d | 177 | ad->swap = list_edit_first; |
pmallick | 0:3afcd581558d | 178 | break; |
pmallick | 0:3afcd581558d | 179 | case LIST_QUEUE: |
pmallick | 0:3afcd581558d | 180 | ad->push = list_add_last; |
pmallick | 0:3afcd581558d | 181 | ad->pop = list_get_first; |
pmallick | 0:3afcd581558d | 182 | ad->top_next = list_read_first; |
pmallick | 0:3afcd581558d | 183 | ad->back = list_read_last; |
pmallick | 0:3afcd581558d | 184 | ad->swap = list_edit_first; |
pmallick | 0:3afcd581558d | 185 | break; |
pmallick | 0:3afcd581558d | 186 | case LIST_DEFAULT: |
pmallick | 0:3afcd581558d | 187 | case LIST_STACK: |
pmallick | 0:3afcd581558d | 188 | default: |
pmallick | 0:3afcd581558d | 189 | ad->push = list_add_last; |
pmallick | 0:3afcd581558d | 190 | ad->pop = list_get_last; |
pmallick | 0:3afcd581558d | 191 | ad->top_next = list_read_last; |
pmallick | 0:3afcd581558d | 192 | ad->back = list_read_first; |
pmallick | 0:3afcd581558d | 193 | ad->swap = list_edit_last; |
pmallick | 0:3afcd581558d | 194 | break; |
pmallick | 0:3afcd581558d | 195 | } |
pmallick | 0:3afcd581558d | 196 | } |
pmallick | 0:3afcd581558d | 197 | |
pmallick | 0:3afcd581558d | 198 | /** |
pmallick | 0:3afcd581558d | 199 | * @brief Create a new empty list |
pmallick | 0:3afcd581558d | 200 | * @param list_desc - Where to store the reference of the new created list |
pmallick | 0:3afcd581558d | 201 | * @param type - Type of adapter to use. |
pmallick | 0:3afcd581558d | 202 | * @param comparator - Used to compare item when using an ordered list or when |
pmallick | 0:3afcd581558d | 203 | * using the \em find functions. |
pmallick | 0:3afcd581558d | 204 | * @return |
pmallick | 0:3afcd581558d | 205 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 206 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 207 | */ |
pmallick | 0:3afcd581558d | 208 | int32_t list_init(struct list_desc **list_desc, enum adapter_type type, |
pmallick | 0:3afcd581558d | 209 | f_cmp comparator) |
pmallick | 0:3afcd581558d | 210 | { |
pmallick | 0:3afcd581558d | 211 | struct list_desc *l_desc; |
pmallick | 0:3afcd581558d | 212 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 213 | |
pmallick | 0:3afcd581558d | 214 | |
pmallick | 0:3afcd581558d | 215 | if (!list_desc) |
pmallick | 0:3afcd581558d | 216 | return FAILURE; |
pmallick | 0:3afcd581558d | 217 | l_desc = (struct list_desc *)calloc(1, sizeof(*l_desc)); |
pmallick | 0:3afcd581558d | 218 | if (!l_desc) |
pmallick | 0:3afcd581558d | 219 | return FAILURE; |
pmallick | 0:3afcd581558d | 220 | list = (struct _list_desc *)calloc(1, sizeof(*list)); |
pmallick | 0:3afcd581558d | 221 | if (!list) { |
pmallick | 0:3afcd581558d | 222 | free(l_desc); |
pmallick | 0:3afcd581558d | 223 | return FAILURE; |
pmallick | 0:3afcd581558d | 224 | } |
pmallick | 0:3afcd581558d | 225 | |
pmallick | 0:3afcd581558d | 226 | *list_desc = l_desc; |
pmallick | 0:3afcd581558d | 227 | l_desc->priv_desc = list; |
pmallick | 0:3afcd581558d | 228 | list->comparator = comparator ? comparator : default_comparator; |
pmallick | 0:3afcd581558d | 229 | |
pmallick | 0:3afcd581558d | 230 | /* Configure wrapper */ |
pmallick | 0:3afcd581558d | 231 | set_adapter(l_desc, type); |
pmallick | 0:3afcd581558d | 232 | list->l_it.list = list; |
pmallick | 0:3afcd581558d | 233 | |
pmallick | 0:3afcd581558d | 234 | return SUCCESS; |
pmallick | 0:3afcd581558d | 235 | } |
pmallick | 0:3afcd581558d | 236 | |
pmallick | 0:3afcd581558d | 237 | /** |
pmallick | 0:3afcd581558d | 238 | * @brief Remove the created list. |
pmallick | 0:3afcd581558d | 239 | * |
pmallick | 0:3afcd581558d | 240 | * All its elements will be cleared and the data inside each will be lost. If |
pmallick | 0:3afcd581558d | 241 | * not all iterators have been removed, the list will not be removed. |
pmallick | 0:3afcd581558d | 242 | * @param list_desc - Reference to the list |
pmallick | 0:3afcd581558d | 243 | * @return |
pmallick | 0:3afcd581558d | 244 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 245 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 246 | */ |
pmallick | 0:3afcd581558d | 247 | int32_t list_remove(struct list_desc *list_desc) |
pmallick | 0:3afcd581558d | 248 | { |
pmallick | 0:3afcd581558d | 249 | void *data; |
pmallick | 0:3afcd581558d | 250 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 251 | |
pmallick | 0:3afcd581558d | 252 | if (!list_desc) |
pmallick | 0:3afcd581558d | 253 | return FAILURE; |
pmallick | 0:3afcd581558d | 254 | |
pmallick | 0:3afcd581558d | 255 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 256 | if (list->nb_iterators != 0) |
pmallick | 0:3afcd581558d | 257 | return FAILURE; |
pmallick | 0:3afcd581558d | 258 | |
pmallick | 0:3afcd581558d | 259 | /* Remove all the elements */ |
pmallick | 0:3afcd581558d | 260 | while (SUCCESS == list_get_first(list_desc, &data)) |
pmallick | 0:3afcd581558d | 261 | ; |
pmallick | 0:3afcd581558d | 262 | free(list_desc->priv_desc); |
pmallick | 0:3afcd581558d | 263 | free(list_desc); |
pmallick | 0:3afcd581558d | 264 | |
pmallick | 0:3afcd581558d | 265 | return SUCCESS; |
pmallick | 0:3afcd581558d | 266 | } |
pmallick | 0:3afcd581558d | 267 | |
pmallick | 0:3afcd581558d | 268 | /** |
pmallick | 0:3afcd581558d | 269 | * @brief Get the number of elements inside the list |
pmallick | 0:3afcd581558d | 270 | * @param list_desc - List reference |
pmallick | 0:3afcd581558d | 271 | * @param out_size - Where to store the number of elements |
pmallick | 0:3afcd581558d | 272 | * @return |
pmallick | 0:3afcd581558d | 273 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 274 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 275 | */ |
pmallick | 0:3afcd581558d | 276 | int32_t list_get_size(struct list_desc *list_desc, uint32_t *out_size) |
pmallick | 0:3afcd581558d | 277 | { |
pmallick | 0:3afcd581558d | 278 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 279 | |
pmallick | 0:3afcd581558d | 280 | if (!list_desc || !out_size) |
pmallick | 0:3afcd581558d | 281 | return FAILURE; |
pmallick | 0:3afcd581558d | 282 | |
pmallick | 0:3afcd581558d | 283 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 284 | *out_size = list->nb_elements; |
pmallick | 0:3afcd581558d | 285 | |
pmallick | 0:3afcd581558d | 286 | return SUCCESS; |
pmallick | 0:3afcd581558d | 287 | } |
pmallick | 0:3afcd581558d | 288 | |
pmallick | 0:3afcd581558d | 289 | /** @brief Add element at the begining of the list. Refer to \ref f_add */ |
pmallick | 0:3afcd581558d | 290 | int32_t list_add_first(struct list_desc *list_desc, void *data) |
pmallick | 0:3afcd581558d | 291 | { |
pmallick | 0:3afcd581558d | 292 | struct list_elem *prev; |
pmallick | 0:3afcd581558d | 293 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 294 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 295 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 296 | |
pmallick | 0:3afcd581558d | 297 | if (!list_desc) |
pmallick | 0:3afcd581558d | 298 | return FAILURE; |
pmallick | 0:3afcd581558d | 299 | |
pmallick | 0:3afcd581558d | 300 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 301 | |
pmallick | 0:3afcd581558d | 302 | prev = NULL; |
pmallick | 0:3afcd581558d | 303 | next = list->first; |
pmallick | 0:3afcd581558d | 304 | elem = create_element(data, prev, next); |
pmallick | 0:3afcd581558d | 305 | if (!elem) |
pmallick | 0:3afcd581558d | 306 | return FAILURE; |
pmallick | 0:3afcd581558d | 307 | |
pmallick | 0:3afcd581558d | 308 | update_links(prev, elem, next); |
pmallick | 0:3afcd581558d | 309 | |
pmallick | 0:3afcd581558d | 310 | update_desc(list, elem, list->last); |
pmallick | 0:3afcd581558d | 311 | |
pmallick | 0:3afcd581558d | 312 | list->nb_elements++; |
pmallick | 0:3afcd581558d | 313 | |
pmallick | 0:3afcd581558d | 314 | return SUCCESS; |
pmallick | 0:3afcd581558d | 315 | } |
pmallick | 0:3afcd581558d | 316 | |
pmallick | 0:3afcd581558d | 317 | /** @brief Add element at the end of the list. Refer to \ref f_add */ |
pmallick | 0:3afcd581558d | 318 | int32_t list_add_last(struct list_desc *list_desc, void *data) |
pmallick | 0:3afcd581558d | 319 | { |
pmallick | 0:3afcd581558d | 320 | struct list_elem *prev; |
pmallick | 0:3afcd581558d | 321 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 322 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 323 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 324 | |
pmallick | 0:3afcd581558d | 325 | if (!list_desc) |
pmallick | 0:3afcd581558d | 326 | return FAILURE; |
pmallick | 0:3afcd581558d | 327 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 328 | |
pmallick | 0:3afcd581558d | 329 | prev = list->last; |
pmallick | 0:3afcd581558d | 330 | next = NULL; |
pmallick | 0:3afcd581558d | 331 | elem = create_element(data, prev, next); |
pmallick | 0:3afcd581558d | 332 | if (!elem) |
pmallick | 0:3afcd581558d | 333 | return FAILURE; |
pmallick | 0:3afcd581558d | 334 | |
pmallick | 0:3afcd581558d | 335 | update_links(prev, elem, next); |
pmallick | 0:3afcd581558d | 336 | |
pmallick | 0:3afcd581558d | 337 | update_desc(list, list->first, elem); |
pmallick | 0:3afcd581558d | 338 | |
pmallick | 0:3afcd581558d | 339 | list->nb_elements++; |
pmallick | 0:3afcd581558d | 340 | |
pmallick | 0:3afcd581558d | 341 | return SUCCESS; |
pmallick | 0:3afcd581558d | 342 | } |
pmallick | 0:3afcd581558d | 343 | |
pmallick | 0:3afcd581558d | 344 | /** @brief Add element at the specified idx. Refer to \ref f_add */ |
pmallick | 0:3afcd581558d | 345 | int32_t list_add_idx(struct list_desc *list_desc, void *data, uint32_t idx) |
pmallick | 0:3afcd581558d | 346 | { |
pmallick | 0:3afcd581558d | 347 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 348 | |
pmallick | 0:3afcd581558d | 349 | if (!list_desc) |
pmallick | 0:3afcd581558d | 350 | return FAILURE; |
pmallick | 0:3afcd581558d | 351 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 352 | |
pmallick | 0:3afcd581558d | 353 | /* If there are no elements the creation of an iterator will fail */ |
pmallick | 0:3afcd581558d | 354 | if (list->nb_elements == 0 || idx == 0) |
pmallick | 0:3afcd581558d | 355 | return list_add_first(list_desc, data); |
pmallick | 0:3afcd581558d | 356 | if (list->nb_elements == idx) |
pmallick | 0:3afcd581558d | 357 | return list_add_last(list_desc, data); |
pmallick | 0:3afcd581558d | 358 | |
pmallick | 0:3afcd581558d | 359 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 360 | if (SUCCESS != iterator_move(&(list->l_it), idx)) |
pmallick | 0:3afcd581558d | 361 | return FAILURE; |
pmallick | 0:3afcd581558d | 362 | |
pmallick | 0:3afcd581558d | 363 | return iterator_insert(&(list->l_it), data, 0); |
pmallick | 0:3afcd581558d | 364 | } |
pmallick | 0:3afcd581558d | 365 | |
pmallick | 0:3afcd581558d | 366 | /** @brief Add element in ascending order. Refer to \ref f_add */ |
pmallick | 0:3afcd581558d | 367 | int32_t list_add_find(struct list_desc *list_desc, void *data) |
pmallick | 0:3afcd581558d | 368 | { |
pmallick | 0:3afcd581558d | 369 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 370 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 371 | |
pmallick | 0:3afcd581558d | 372 | if (!list_desc) |
pmallick | 0:3afcd581558d | 373 | return FAILURE; |
pmallick | 0:3afcd581558d | 374 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 375 | |
pmallick | 0:3afcd581558d | 376 | |
pmallick | 0:3afcd581558d | 377 | /* Based on place iterator */ |
pmallick | 0:3afcd581558d | 378 | elem = list->first; |
pmallick | 0:3afcd581558d | 379 | while (elem) { |
pmallick | 0:3afcd581558d | 380 | if (0 < list->comparator(elem->data, data)) |
pmallick | 0:3afcd581558d | 381 | break; |
pmallick | 0:3afcd581558d | 382 | elem = elem->next; |
pmallick | 0:3afcd581558d | 383 | } |
pmallick | 0:3afcd581558d | 384 | if (elem == NULL) { |
pmallick | 0:3afcd581558d | 385 | list->l_it.elem = list->last; |
pmallick | 0:3afcd581558d | 386 | return iterator_insert(&(list->l_it), data, 1); |
pmallick | 0:3afcd581558d | 387 | } else { |
pmallick | 0:3afcd581558d | 388 | list->l_it.elem = elem; |
pmallick | 0:3afcd581558d | 389 | return iterator_insert(&(list->l_it), data, 0); |
pmallick | 0:3afcd581558d | 390 | } |
pmallick | 0:3afcd581558d | 391 | |
pmallick | 0:3afcd581558d | 392 | } |
pmallick | 0:3afcd581558d | 393 | |
pmallick | 0:3afcd581558d | 394 | /** @brief Edit the first element of the list. Refer to \ref f_edit */ |
pmallick | 0:3afcd581558d | 395 | int32_t list_edit_first(struct list_desc *list_desc, void *new_data) |
pmallick | 0:3afcd581558d | 396 | { |
pmallick | 0:3afcd581558d | 397 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 398 | |
pmallick | 0:3afcd581558d | 399 | if (!list_desc) |
pmallick | 0:3afcd581558d | 400 | return FAILURE; |
pmallick | 0:3afcd581558d | 401 | |
pmallick | 0:3afcd581558d | 402 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 403 | list->first->data = new_data; |
pmallick | 0:3afcd581558d | 404 | |
pmallick | 0:3afcd581558d | 405 | return SUCCESS; |
pmallick | 0:3afcd581558d | 406 | } |
pmallick | 0:3afcd581558d | 407 | |
pmallick | 0:3afcd581558d | 408 | /** @brief Edit the last element of the list. Refer to \ref f_edit */ |
pmallick | 0:3afcd581558d | 409 | int32_t list_edit_last(struct list_desc *list_desc, void *new_data) |
pmallick | 0:3afcd581558d | 410 | { |
pmallick | 0:3afcd581558d | 411 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 412 | |
pmallick | 0:3afcd581558d | 413 | if (!list_desc) |
pmallick | 0:3afcd581558d | 414 | return FAILURE; |
pmallick | 0:3afcd581558d | 415 | |
pmallick | 0:3afcd581558d | 416 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 417 | list->last->data = new_data; |
pmallick | 0:3afcd581558d | 418 | |
pmallick | 0:3afcd581558d | 419 | return SUCCESS; |
pmallick | 0:3afcd581558d | 420 | } |
pmallick | 0:3afcd581558d | 421 | |
pmallick | 0:3afcd581558d | 422 | /** @brief Edit the element at the specified idx. Refer to \ref f_edit */ |
pmallick | 0:3afcd581558d | 423 | int32_t list_edit_idx(struct list_desc *list_desc, void *new_data, uint32_t idx) |
pmallick | 0:3afcd581558d | 424 | { |
pmallick | 0:3afcd581558d | 425 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 426 | |
pmallick | 0:3afcd581558d | 427 | if (!list_desc) |
pmallick | 0:3afcd581558d | 428 | return FAILURE; |
pmallick | 0:3afcd581558d | 429 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 430 | |
pmallick | 0:3afcd581558d | 431 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 432 | if (SUCCESS != iterator_move(&(list->l_it), idx)) |
pmallick | 0:3afcd581558d | 433 | return FAILURE; |
pmallick | 0:3afcd581558d | 434 | |
pmallick | 0:3afcd581558d | 435 | return iterator_edit(&(list->l_it), new_data); |
pmallick | 0:3afcd581558d | 436 | } |
pmallick | 0:3afcd581558d | 437 | |
pmallick | 0:3afcd581558d | 438 | /** @brief Edit the element which match with cmp_data. Refer to \ref f_edit */ |
pmallick | 0:3afcd581558d | 439 | int32_t list_edit_find(struct list_desc *list_desc, void *new_data, |
pmallick | 0:3afcd581558d | 440 | void *cmp_data) |
pmallick | 0:3afcd581558d | 441 | { |
pmallick | 0:3afcd581558d | 442 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 443 | |
pmallick | 0:3afcd581558d | 444 | if (!list_desc) |
pmallick | 0:3afcd581558d | 445 | return FAILURE; |
pmallick | 0:3afcd581558d | 446 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 447 | |
pmallick | 0:3afcd581558d | 448 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 449 | if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) |
pmallick | 0:3afcd581558d | 450 | return FAILURE; |
pmallick | 0:3afcd581558d | 451 | |
pmallick | 0:3afcd581558d | 452 | return iterator_edit(&(list->l_it), new_data); |
pmallick | 0:3afcd581558d | 453 | } |
pmallick | 0:3afcd581558d | 454 | |
pmallick | 0:3afcd581558d | 455 | /** @brief Read the first element of the list. Refer to \ref f_read */ |
pmallick | 0:3afcd581558d | 456 | int32_t list_read_first(struct list_desc *list_desc, void **data) |
pmallick | 0:3afcd581558d | 457 | { |
pmallick | 0:3afcd581558d | 458 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 459 | |
pmallick | 0:3afcd581558d | 460 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 461 | return FAILURE; |
pmallick | 0:3afcd581558d | 462 | |
pmallick | 0:3afcd581558d | 463 | *data = NULL; |
pmallick | 0:3afcd581558d | 464 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 465 | if (!list->first) |
pmallick | 0:3afcd581558d | 466 | return FAILURE; |
pmallick | 0:3afcd581558d | 467 | |
pmallick | 0:3afcd581558d | 468 | *data = list->first->data; |
pmallick | 0:3afcd581558d | 469 | |
pmallick | 0:3afcd581558d | 470 | return SUCCESS; |
pmallick | 0:3afcd581558d | 471 | } |
pmallick | 0:3afcd581558d | 472 | |
pmallick | 0:3afcd581558d | 473 | /** @brief Read the last element of the list. Refer to \ref f_read */ |
pmallick | 0:3afcd581558d | 474 | int32_t list_read_last(struct list_desc *list_desc, void **data) |
pmallick | 0:3afcd581558d | 475 | { |
pmallick | 0:3afcd581558d | 476 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 477 | |
pmallick | 0:3afcd581558d | 478 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 479 | return FAILURE; |
pmallick | 0:3afcd581558d | 480 | |
pmallick | 0:3afcd581558d | 481 | *data = NULL; |
pmallick | 0:3afcd581558d | 482 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 483 | if (!list->last) |
pmallick | 0:3afcd581558d | 484 | return FAILURE; |
pmallick | 0:3afcd581558d | 485 | |
pmallick | 0:3afcd581558d | 486 | *data = list->last->data; |
pmallick | 0:3afcd581558d | 487 | |
pmallick | 0:3afcd581558d | 488 | return SUCCESS; |
pmallick | 0:3afcd581558d | 489 | } |
pmallick | 0:3afcd581558d | 490 | |
pmallick | 0:3afcd581558d | 491 | /** @brief Read the element at the specified idx. Refer to \ref f_read */ |
pmallick | 0:3afcd581558d | 492 | int32_t list_read_idx(struct list_desc *list_desc, void **data, uint32_t idx) |
pmallick | 0:3afcd581558d | 493 | { |
pmallick | 0:3afcd581558d | 494 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 495 | |
pmallick | 0:3afcd581558d | 496 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 497 | return FAILURE; |
pmallick | 0:3afcd581558d | 498 | |
pmallick | 0:3afcd581558d | 499 | *data = NULL; |
pmallick | 0:3afcd581558d | 500 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 501 | if (!list) |
pmallick | 0:3afcd581558d | 502 | return FAILURE; |
pmallick | 0:3afcd581558d | 503 | |
pmallick | 0:3afcd581558d | 504 | if (idx >= list->nb_elements) |
pmallick | 0:3afcd581558d | 505 | return FAILURE; |
pmallick | 0:3afcd581558d | 506 | |
pmallick | 0:3afcd581558d | 507 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 508 | if (SUCCESS != iterator_move(&(list->l_it), idx)) |
pmallick | 0:3afcd581558d | 509 | return FAILURE; |
pmallick | 0:3afcd581558d | 510 | |
pmallick | 0:3afcd581558d | 511 | return iterator_read(&(list->l_it), data); |
pmallick | 0:3afcd581558d | 512 | } |
pmallick | 0:3afcd581558d | 513 | |
pmallick | 0:3afcd581558d | 514 | /** @brief Read the element which match with cmp_data. Refer to \ref f_read */ |
pmallick | 0:3afcd581558d | 515 | int32_t list_read_find(struct list_desc *list_desc, void **data, |
pmallick | 0:3afcd581558d | 516 | void *cmp_data) |
pmallick | 0:3afcd581558d | 517 | { |
pmallick | 0:3afcd581558d | 518 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 519 | |
pmallick | 0:3afcd581558d | 520 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 521 | return FAILURE; |
pmallick | 0:3afcd581558d | 522 | |
pmallick | 0:3afcd581558d | 523 | *data = NULL; |
pmallick | 0:3afcd581558d | 524 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 525 | if (!list) |
pmallick | 0:3afcd581558d | 526 | return FAILURE; |
pmallick | 0:3afcd581558d | 527 | |
pmallick | 0:3afcd581558d | 528 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 529 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 530 | if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) |
pmallick | 0:3afcd581558d | 531 | return FAILURE; |
pmallick | 0:3afcd581558d | 532 | |
pmallick | 0:3afcd581558d | 533 | return iterator_read(&(list->l_it), data); |
pmallick | 0:3afcd581558d | 534 | } |
pmallick | 0:3afcd581558d | 535 | |
pmallick | 0:3afcd581558d | 536 | /** @brief Read and delete the first element of the list. Refer to \ref f_get */ |
pmallick | 0:3afcd581558d | 537 | int32_t list_get_first(struct list_desc *list_desc, void **data) |
pmallick | 0:3afcd581558d | 538 | { |
pmallick | 0:3afcd581558d | 539 | struct list_elem *prev; |
pmallick | 0:3afcd581558d | 540 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 541 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 542 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 543 | |
pmallick | 0:3afcd581558d | 544 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 545 | return FAILURE; |
pmallick | 0:3afcd581558d | 546 | |
pmallick | 0:3afcd581558d | 547 | *data = NULL; |
pmallick | 0:3afcd581558d | 548 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 549 | if (!list->nb_elements) |
pmallick | 0:3afcd581558d | 550 | return FAILURE; |
pmallick | 0:3afcd581558d | 551 | |
pmallick | 0:3afcd581558d | 552 | elem = list->first; |
pmallick | 0:3afcd581558d | 553 | prev = elem->prev; |
pmallick | 0:3afcd581558d | 554 | next = elem->next; |
pmallick | 0:3afcd581558d | 555 | |
pmallick | 0:3afcd581558d | 556 | update_links(prev, NULL, next); |
pmallick | 0:3afcd581558d | 557 | update_desc(list, next, list->last); |
pmallick | 0:3afcd581558d | 558 | list->nb_elements--; |
pmallick | 0:3afcd581558d | 559 | |
pmallick | 0:3afcd581558d | 560 | *data = elem->data; |
pmallick | 0:3afcd581558d | 561 | free(elem); |
pmallick | 0:3afcd581558d | 562 | |
pmallick | 0:3afcd581558d | 563 | return SUCCESS; |
pmallick | 0:3afcd581558d | 564 | } |
pmallick | 0:3afcd581558d | 565 | |
pmallick | 0:3afcd581558d | 566 | /** @brief Read and delete the last element of the list. Refer to \ref f_get */ |
pmallick | 0:3afcd581558d | 567 | int32_t list_get_last(struct list_desc *list_desc, void **data) |
pmallick | 0:3afcd581558d | 568 | { |
pmallick | 0:3afcd581558d | 569 | struct list_elem *prev; |
pmallick | 0:3afcd581558d | 570 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 571 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 572 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 573 | |
pmallick | 0:3afcd581558d | 574 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 575 | return FAILURE; |
pmallick | 0:3afcd581558d | 576 | |
pmallick | 0:3afcd581558d | 577 | *data = NULL; |
pmallick | 0:3afcd581558d | 578 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 579 | if (!list->nb_elements) |
pmallick | 0:3afcd581558d | 580 | return FAILURE; |
pmallick | 0:3afcd581558d | 581 | |
pmallick | 0:3afcd581558d | 582 | elem = list->last; |
pmallick | 0:3afcd581558d | 583 | prev = elem->prev; |
pmallick | 0:3afcd581558d | 584 | next = elem->next; |
pmallick | 0:3afcd581558d | 585 | |
pmallick | 0:3afcd581558d | 586 | update_links(prev, NULL, next); |
pmallick | 0:3afcd581558d | 587 | update_desc(list, list->first, prev); |
pmallick | 0:3afcd581558d | 588 | list->nb_elements--; |
pmallick | 0:3afcd581558d | 589 | |
pmallick | 0:3afcd581558d | 590 | *data = elem->data; |
pmallick | 0:3afcd581558d | 591 | free(elem); |
pmallick | 0:3afcd581558d | 592 | |
pmallick | 0:3afcd581558d | 593 | return SUCCESS; |
pmallick | 0:3afcd581558d | 594 | } |
pmallick | 0:3afcd581558d | 595 | |
pmallick | 0:3afcd581558d | 596 | /** @brief Read and delete the element at idx. Refer to \ref f_get */ |
pmallick | 0:3afcd581558d | 597 | int32_t list_get_idx(struct list_desc *list_desc, void **data, uint32_t idx) |
pmallick | 0:3afcd581558d | 598 | { |
pmallick | 0:3afcd581558d | 599 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 600 | |
pmallick | 0:3afcd581558d | 601 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 602 | return FAILURE; |
pmallick | 0:3afcd581558d | 603 | |
pmallick | 0:3afcd581558d | 604 | *data = NULL; |
pmallick | 0:3afcd581558d | 605 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 606 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 607 | if (SUCCESS != iterator_move(&(list->l_it), idx)) |
pmallick | 0:3afcd581558d | 608 | return FAILURE; |
pmallick | 0:3afcd581558d | 609 | |
pmallick | 0:3afcd581558d | 610 | return iterator_get(&(list->l_it), data); |
pmallick | 0:3afcd581558d | 611 | } |
pmallick | 0:3afcd581558d | 612 | |
pmallick | 0:3afcd581558d | 613 | /** |
pmallick | 0:3afcd581558d | 614 | * @brief Read and delete the element which match with cmp_data. |
pmallick | 0:3afcd581558d | 615 | * Refer to \ref f_get |
pmallick | 0:3afcd581558d | 616 | */ |
pmallick | 0:3afcd581558d | 617 | int32_t list_get_find(struct list_desc *list_desc, void **data, void *cmp_data) |
pmallick | 0:3afcd581558d | 618 | { |
pmallick | 0:3afcd581558d | 619 | struct _list_desc *list; |
pmallick | 0:3afcd581558d | 620 | |
pmallick | 0:3afcd581558d | 621 | if (!list_desc || !data) |
pmallick | 0:3afcd581558d | 622 | return FAILURE; |
pmallick | 0:3afcd581558d | 623 | |
pmallick | 0:3afcd581558d | 624 | *data = NULL; |
pmallick | 0:3afcd581558d | 625 | list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 626 | list->l_it.elem = list->first; |
pmallick | 0:3afcd581558d | 627 | if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) |
pmallick | 0:3afcd581558d | 628 | return FAILURE; |
pmallick | 0:3afcd581558d | 629 | |
pmallick | 0:3afcd581558d | 630 | return iterator_get(&(list->l_it), data); |
pmallick | 0:3afcd581558d | 631 | } |
pmallick | 0:3afcd581558d | 632 | |
pmallick | 0:3afcd581558d | 633 | /** |
pmallick | 0:3afcd581558d | 634 | * @brief Create a new iterator |
pmallick | 0:3afcd581558d | 635 | * @param iter - Where to store the reference for the new iterator |
pmallick | 0:3afcd581558d | 636 | * @param list_desc - Reference of the list the iterator will be used for |
pmallick | 0:3afcd581558d | 637 | * @param start - If it is true the iterator will be positioned at the first |
pmallick | 0:3afcd581558d | 638 | * element of the list, else it will be positioned at the last. |
pmallick | 0:3afcd581558d | 639 | * @return |
pmallick | 0:3afcd581558d | 640 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 641 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 642 | */ |
pmallick | 0:3afcd581558d | 643 | int32_t iterator_init(struct iterator **iter, struct list_desc *list_desc, |
pmallick | 0:3afcd581558d | 644 | bool start) |
pmallick | 0:3afcd581558d | 645 | { |
pmallick | 0:3afcd581558d | 646 | struct iterator *it; |
pmallick | 0:3afcd581558d | 647 | |
pmallick | 0:3afcd581558d | 648 | if (!list_desc) |
pmallick | 0:3afcd581558d | 649 | return FAILURE; |
pmallick | 0:3afcd581558d | 650 | |
pmallick | 0:3afcd581558d | 651 | it = (struct iterator *)calloc(1, sizeof(*it)); |
pmallick | 0:3afcd581558d | 652 | if (!it) |
pmallick | 0:3afcd581558d | 653 | return FAILURE; |
pmallick | 0:3afcd581558d | 654 | it->list = list_desc->priv_desc; |
pmallick | 0:3afcd581558d | 655 | it->list->nb_iterators++; |
pmallick | 0:3afcd581558d | 656 | it->elem = start ? it->list->first : it->list->last; |
pmallick | 0:3afcd581558d | 657 | *iter = it; |
pmallick | 0:3afcd581558d | 658 | |
pmallick | 0:3afcd581558d | 659 | return SUCCESS; |
pmallick | 0:3afcd581558d | 660 | } |
pmallick | 0:3afcd581558d | 661 | |
pmallick | 0:3afcd581558d | 662 | /** |
pmallick | 0:3afcd581558d | 663 | * @brief Remove the created iterator |
pmallick | 0:3afcd581558d | 664 | * @param iter - Reference of the iterator |
pmallick | 0:3afcd581558d | 665 | * @return |
pmallick | 0:3afcd581558d | 666 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 667 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 668 | */ |
pmallick | 0:3afcd581558d | 669 | int32_t iterator_remove(struct iterator *iter) |
pmallick | 0:3afcd581558d | 670 | { |
pmallick | 0:3afcd581558d | 671 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 672 | |
pmallick | 0:3afcd581558d | 673 | if (!it) |
pmallick | 0:3afcd581558d | 674 | return FAILURE; |
pmallick | 0:3afcd581558d | 675 | |
pmallick | 0:3afcd581558d | 676 | it->list->nb_iterators--; |
pmallick | 0:3afcd581558d | 677 | free(it); |
pmallick | 0:3afcd581558d | 678 | |
pmallick | 0:3afcd581558d | 679 | return SUCCESS; |
pmallick | 0:3afcd581558d | 680 | } |
pmallick | 0:3afcd581558d | 681 | |
pmallick | 0:3afcd581558d | 682 | /** |
pmallick | 0:3afcd581558d | 683 | * @brief Move the position of the iteration through the list. |
pmallick | 0:3afcd581558d | 684 | * |
pmallick | 0:3afcd581558d | 685 | * If the required position is outside the list, the call will fail and the |
pmallick | 0:3afcd581558d | 686 | * iterator will keep its position. |
pmallick | 0:3afcd581558d | 687 | * @param iter - Reference of the iterator |
pmallick | 0:3afcd581558d | 688 | * @param idx - Number of positions to be move. If positive, it will be moved |
pmallick | 0:3afcd581558d | 689 | * forward, otherwise backwords. |
pmallick | 0:3afcd581558d | 690 | * @return |
pmallick | 0:3afcd581558d | 691 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 692 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 693 | */ |
pmallick | 0:3afcd581558d | 694 | int32_t iterator_move(struct iterator *iter, int32_t idx) |
pmallick | 0:3afcd581558d | 695 | { |
pmallick | 0:3afcd581558d | 696 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 697 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 698 | int32_t dir = (idx < 0) ? -1 : 1; |
pmallick | 0:3afcd581558d | 699 | |
pmallick | 0:3afcd581558d | 700 | if (!it) |
pmallick | 0:3afcd581558d | 701 | return FAILURE; |
pmallick | 0:3afcd581558d | 702 | |
pmallick | 0:3afcd581558d | 703 | idx = abs(idx); |
pmallick | 0:3afcd581558d | 704 | elem = it->elem; |
pmallick | 0:3afcd581558d | 705 | while (idx > 0 && elem) { |
pmallick | 0:3afcd581558d | 706 | elem = dir > 0 ? elem->next : elem->prev; |
pmallick | 0:3afcd581558d | 707 | idx--; |
pmallick | 0:3afcd581558d | 708 | } |
pmallick | 0:3afcd581558d | 709 | if (!elem) |
pmallick | 0:3afcd581558d | 710 | return FAILURE; |
pmallick | 0:3afcd581558d | 711 | |
pmallick | 0:3afcd581558d | 712 | it->elem = elem; |
pmallick | 0:3afcd581558d | 713 | |
pmallick | 0:3afcd581558d | 714 | return SUCCESS; |
pmallick | 0:3afcd581558d | 715 | } |
pmallick | 0:3afcd581558d | 716 | |
pmallick | 0:3afcd581558d | 717 | /** |
pmallick | 0:3afcd581558d | 718 | * @brief Place the iterator where cmp_data if found. |
pmallick | 0:3afcd581558d | 719 | * @param iter - Reference to the iterator |
pmallick | 0:3afcd581558d | 720 | * @param cmp_data - Data to be found |
pmallick | 0:3afcd581558d | 721 | * @return |
pmallick | 0:3afcd581558d | 722 | * - \ref SUCCESS : On success |
pmallick | 0:3afcd581558d | 723 | * - \ref FAILURE : Otherwise |
pmallick | 0:3afcd581558d | 724 | */ |
pmallick | 0:3afcd581558d | 725 | int32_t iterator_find(struct iterator *iter, void *cmp_data) |
pmallick | 0:3afcd581558d | 726 | { |
pmallick | 0:3afcd581558d | 727 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 728 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 729 | |
pmallick | 0:3afcd581558d | 730 | if (!it) |
pmallick | 0:3afcd581558d | 731 | return FAILURE; |
pmallick | 0:3afcd581558d | 732 | |
pmallick | 0:3afcd581558d | 733 | elem = it->list->first; |
pmallick | 0:3afcd581558d | 734 | while (elem) { |
pmallick | 0:3afcd581558d | 735 | if (0 == it->list->comparator(elem->data, cmp_data)) { |
pmallick | 0:3afcd581558d | 736 | it->elem = elem; |
pmallick | 0:3afcd581558d | 737 | return SUCCESS; |
pmallick | 0:3afcd581558d | 738 | } |
pmallick | 0:3afcd581558d | 739 | elem = elem->next; |
pmallick | 0:3afcd581558d | 740 | } |
pmallick | 0:3afcd581558d | 741 | |
pmallick | 0:3afcd581558d | 742 | return FAILURE; |
pmallick | 0:3afcd581558d | 743 | } |
pmallick | 0:3afcd581558d | 744 | |
pmallick | 0:3afcd581558d | 745 | /** |
pmallick | 0:3afcd581558d | 746 | * @brief Replace the data at the current position. Refer to \ref f_edit |
pmallick | 0:3afcd581558d | 747 | */ |
pmallick | 0:3afcd581558d | 748 | int32_t iterator_edit(struct iterator *iter, void *new_data) |
pmallick | 0:3afcd581558d | 749 | { |
pmallick | 0:3afcd581558d | 750 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 751 | |
pmallick | 0:3afcd581558d | 752 | if (!it) |
pmallick | 0:3afcd581558d | 753 | return FAILURE; |
pmallick | 0:3afcd581558d | 754 | |
pmallick | 0:3afcd581558d | 755 | it->elem->data = new_data; |
pmallick | 0:3afcd581558d | 756 | |
pmallick | 0:3afcd581558d | 757 | return SUCCESS; |
pmallick | 0:3afcd581558d | 758 | } |
pmallick | 0:3afcd581558d | 759 | |
pmallick | 0:3afcd581558d | 760 | /** |
pmallick | 0:3afcd581558d | 761 | * @brief Read and remove the data at the current position. Refer to \ref f_get. |
pmallick | 0:3afcd581558d | 762 | * |
pmallick | 0:3afcd581558d | 763 | * If the current item is the last one, the iterator will be moved to the |
pmallick | 0:3afcd581558d | 764 | * previous one. |
pmallick | 0:3afcd581558d | 765 | */ |
pmallick | 0:3afcd581558d | 766 | int32_t iterator_get(struct iterator *iter, void **data) |
pmallick | 0:3afcd581558d | 767 | { |
pmallick | 0:3afcd581558d | 768 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 769 | struct list_elem *next; |
pmallick | 0:3afcd581558d | 770 | |
pmallick | 0:3afcd581558d | 771 | |
pmallick | 0:3afcd581558d | 772 | if (!it || !it->elem || !data) |
pmallick | 0:3afcd581558d | 773 | return FAILURE; |
pmallick | 0:3afcd581558d | 774 | |
pmallick | 0:3afcd581558d | 775 | update_links(it->elem->prev, NULL, it->elem->next); |
pmallick | 0:3afcd581558d | 776 | if (it->elem == it->list->first) |
pmallick | 0:3afcd581558d | 777 | update_desc(it->list, it->elem->next, it->list->last); |
pmallick | 0:3afcd581558d | 778 | else if (it->elem == it->list->last) |
pmallick | 0:3afcd581558d | 779 | update_desc(it->list, it->list->first, it->elem->prev); |
pmallick | 0:3afcd581558d | 780 | it->list->nb_elements--; |
pmallick | 0:3afcd581558d | 781 | |
pmallick | 0:3afcd581558d | 782 | *data = it->elem->data; |
pmallick | 0:3afcd581558d | 783 | if (it->elem == it->list->last) |
pmallick | 0:3afcd581558d | 784 | next = it->elem->prev; |
pmallick | 0:3afcd581558d | 785 | else |
pmallick | 0:3afcd581558d | 786 | next = it->elem->next; |
pmallick | 0:3afcd581558d | 787 | free(it->elem); |
pmallick | 0:3afcd581558d | 788 | it->elem = next; |
pmallick | 0:3afcd581558d | 789 | |
pmallick | 0:3afcd581558d | 790 | return SUCCESS; |
pmallick | 0:3afcd581558d | 791 | } |
pmallick | 0:3afcd581558d | 792 | |
pmallick | 0:3afcd581558d | 793 | /** |
pmallick | 0:3afcd581558d | 794 | * @brief Read the data at the current position. Refer to \ref f_read |
pmallick | 0:3afcd581558d | 795 | */ |
pmallick | 0:3afcd581558d | 796 | int32_t iterator_read(struct iterator *iter, void **data) |
pmallick | 0:3afcd581558d | 797 | { |
pmallick | 0:3afcd581558d | 798 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 799 | |
pmallick | 0:3afcd581558d | 800 | if (!it || !it->elem || !data) |
pmallick | 0:3afcd581558d | 801 | return FAILURE; |
pmallick | 0:3afcd581558d | 802 | |
pmallick | 0:3afcd581558d | 803 | *data = it->elem->data; |
pmallick | 0:3afcd581558d | 804 | |
pmallick | 0:3afcd581558d | 805 | return SUCCESS; |
pmallick | 0:3afcd581558d | 806 | } |
pmallick | 0:3afcd581558d | 807 | |
pmallick | 0:3afcd581558d | 808 | /** |
pmallick | 0:3afcd581558d | 809 | * @brief Insert an item in the list. Refer to \ref f_add |
pmallick | 0:3afcd581558d | 810 | * @param iter |
pmallick | 0:3afcd581558d | 811 | * @param data |
pmallick | 0:3afcd581558d | 812 | * @param after - If true, the item will be inserted after the current position. |
pmallick | 0:3afcd581558d | 813 | * Otherwise it will be inserted before. |
pmallick | 0:3afcd581558d | 814 | */ |
pmallick | 0:3afcd581558d | 815 | int32_t iterator_insert(struct iterator *iter, void *data, bool after) |
pmallick | 0:3afcd581558d | 816 | { |
pmallick | 0:3afcd581558d | 817 | struct iterator *it = iter; |
pmallick | 0:3afcd581558d | 818 | struct list_elem *elem; |
pmallick | 0:3afcd581558d | 819 | struct list_desc list_desc; |
pmallick | 0:3afcd581558d | 820 | |
pmallick | 0:3afcd581558d | 821 | if (!it) |
pmallick | 0:3afcd581558d | 822 | return FAILURE; |
pmallick | 0:3afcd581558d | 823 | |
pmallick | 0:3afcd581558d | 824 | list_desc.priv_desc = iter->list; |
pmallick | 0:3afcd581558d | 825 | if (after && it->elem == it->list->last) |
pmallick | 0:3afcd581558d | 826 | return list_add_last(&list_desc, data); |
pmallick | 0:3afcd581558d | 827 | if (!after && it->elem == it->list->first) |
pmallick | 0:3afcd581558d | 828 | return list_add_first(&list_desc, data); |
pmallick | 0:3afcd581558d | 829 | |
pmallick | 0:3afcd581558d | 830 | if (after) |
pmallick | 0:3afcd581558d | 831 | elem = create_element(data, it->elem, it->elem->next); |
pmallick | 0:3afcd581558d | 832 | else |
pmallick | 0:3afcd581558d | 833 | elem = create_element(data, it->elem->prev, it->elem); |
pmallick | 0:3afcd581558d | 834 | if (!elem) |
pmallick | 0:3afcd581558d | 835 | return FAILURE; |
pmallick | 0:3afcd581558d | 836 | |
pmallick | 0:3afcd581558d | 837 | update_links(elem->prev, elem, elem->next); |
pmallick | 0:3afcd581558d | 838 | |
pmallick | 0:3afcd581558d | 839 | it->list->nb_elements++; |
pmallick | 0:3afcd581558d | 840 | |
pmallick | 0:3afcd581558d | 841 | return SUCCESS; |
pmallick | 0:3afcd581558d | 842 | } |