this is testing

Committer:
pmallick
Date:
Thu Jan 14 19:12:57 2021 +0530
Revision:
0:e8a1ba50c46b
this is testing

Who changed what in which revision?

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