]>
Commit | Line | Data |
---|---|---|
be910ee4 JH |
1 | /** |
2 | * @file linked_list.c | |
79538669 | 3 | * |
51ecb022 | 4 | * @brief Implementation of linked_list_t. |
79538669 | 5 | * |
be910ee4 JH |
6 | */ |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify it | |
13 | * under the terms of the GNU General Public License as published by the | |
14 | * Free Software Foundation; either version 2 of the License, or (at your | |
15 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, but | |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
19 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
20 | * for more details. | |
21 | */ | |
22 | ||
23 | #include <stdlib.h> | |
be910ee4 JH |
24 | |
25 | #include "linked_list.h" | |
79538669 | 26 | |
be910ee4 | 27 | |
d794bcdb | 28 | |
5796aa16 | 29 | typedef struct linked_list_element_t linked_list_element_t; |
7c2228f1 JH |
30 | |
31 | /** | |
d794bcdb | 32 | * @brief Element in a linked list. |
79538669 | 33 | * |
d794bcdb | 34 | * This element holds a pointer to the value it represents. |
7c2228f1 | 35 | */ |
5796aa16 | 36 | struct linked_list_element_t { |
d794bcdb | 37 | |
7c2228f1 | 38 | /** |
e0e554ca | 39 | * Value of a list item. |
7c2228f1 | 40 | */ |
e3dd1393 | 41 | void *value; |
79538669 | 42 | |
7c2228f1 | 43 | /** |
d794bcdb JH |
44 | * Previous list element. |
45 | * | |
46 | * NULL if first element in list. | |
7c2228f1 | 47 | */ |
e3dd1393 | 48 | linked_list_element_t *previous; |
d048df5c | 49 | |
7c2228f1 | 50 | /** |
d794bcdb JH |
51 | * Next list element. |
52 | * | |
53 | * NULL if last element in list. | |
7c2228f1 | 54 | */ |
e3dd1393 | 55 | linked_list_element_t *next; |
d048df5c MW |
56 | |
57 | /** | |
58 | * Destroys a linked_list_element object. | |
59 | * | |
d794bcdb | 60 | * @param linked_list_element_t calling object |
d048df5c MW |
61 | */ |
62 | void (*destroy) (linked_list_element_t *this); | |
7c2228f1 JH |
63 | }; |
64 | ||
be910ee4 | 65 | /** |
e0e554ca | 66 | * Implementation of linked_list_element_t.destroy. |
be910ee4 | 67 | */ |
d048df5c | 68 | static void linked_list_element_destroy(linked_list_element_t *this) |
be910ee4 | 69 | { |
5113680f | 70 | free(this); |
be910ee4 JH |
71 | } |
72 | ||
e3dd1393 | 73 | /** |
e0e554ca | 74 | * @brief Creates an empty linked list object. |
e3dd1393 | 75 | * |
e0e554ca JH |
76 | * @warning Only the pointer to the value is stored. |
77 | * | |
d794bcdb JH |
78 | * @param[in] value value of item to be set |
79 | * @return linked_list_element_t object | |
adca27eb | 80 | */ |
e3dd1393 | 81 | |
be910ee4 JH |
82 | linked_list_element_t *linked_list_element_create(void *value) |
83 | { | |
5113680f | 84 | linked_list_element_t *this = malloc_thing(linked_list_element_t); |
79538669 | 85 | |
623fec54 | 86 | this->destroy = linked_list_element_destroy; |
79538669 | 87 | |
be910ee4 JH |
88 | this->previous=NULL; |
89 | this->next=NULL; | |
e3dd1393 | 90 | this->value = value; |
79538669 | 91 | |
e3dd1393 | 92 | return (this); |
7c2228f1 JH |
93 | } |
94 | ||
e0e554ca JH |
95 | |
96 | typedef struct private_linked_list_t private_linked_list_t; | |
d794bcdb | 97 | |
7c2228f1 | 98 | /** |
d794bcdb | 99 | * Private data of a linked_list_t object. |
79538669 | 100 | * |
7c2228f1 | 101 | */ |
5796aa16 | 102 | struct private_linked_list_t { |
7c2228f1 | 103 | /** |
e0e554ca | 104 | * Public part of linked list. |
7c2228f1 JH |
105 | */ |
106 | linked_list_t public; | |
79538669 | 107 | |
7c2228f1 | 108 | /** |
e0e554ca | 109 | * Number of items in the list. |
7c2228f1 JH |
110 | */ |
111 | int count; | |
79538669 | 112 | |
7c2228f1 | 113 | /** |
e0e554ca JH |
114 | * First element in list. |
115 | * NULL if no elements in list. | |
7c2228f1 | 116 | */ |
e3dd1393 | 117 | linked_list_element_t *first; |
d048df5c | 118 | |
7c2228f1 | 119 | /** |
e0e554ca JH |
120 | * Last element in list. |
121 | * NULL if no elements in list. | |
7c2228f1 | 122 | */ |
e3dd1393 | 123 | linked_list_element_t *last; |
7c2228f1 JH |
124 | }; |
125 | ||
126 | ||
e0e554ca JH |
127 | typedef struct private_iterator_t private_iterator_t; |
128 | ||
7c2228f1 | 129 | /** |
e0e554ca | 130 | * Private variables and functions of linked list iterator. |
7c2228f1 | 131 | */ |
bdb141cb | 132 | struct private_iterator_t { |
7c2228f1 | 133 | /** |
e0e554ca | 134 | * Public part of linked list iterator. |
7c2228f1 | 135 | */ |
bdb141cb | 136 | iterator_t public; |
79538669 | 137 | |
7c2228f1 | 138 | /** |
e0e554ca | 139 | * Associated linked list. |
7c2228f1 JH |
140 | */ |
141 | private_linked_list_t * list; | |
79538669 | 142 | |
7c2228f1 | 143 | /** |
e0e554ca | 144 | * Current element of the iterator. |
7c2228f1 | 145 | */ |
e3dd1393 | 146 | linked_list_element_t *current; |
7c2228f1 JH |
147 | |
148 | /** | |
e0e554ca | 149 | * Direction of iterator. |
7c2228f1 JH |
150 | */ |
151 | bool forward; | |
152 | }; | |
153 | ||
154 | /** | |
e0e554ca | 155 | * Implementation of iterator_t.has_next. |
7c2228f1 | 156 | */ |
dfa6e086 MW |
157 | static bool iterate(private_iterator_t *this, void** value) |
158 | { | |
159 | if (this->list->count == 0) | |
160 | { | |
161 | return FALSE; | |
162 | } | |
163 | if (this->current == NULL) | |
164 | { | |
165 | this->current = (this->forward) ? this->list->first : this->list->last; | |
166 | *value = this->current->value; | |
167 | return TRUE; | |
168 | } | |
169 | if (this->forward) | |
170 | { | |
171 | if (this->current->next == NULL) | |
172 | { | |
173 | return FALSE; | |
174 | } | |
175 | this->current = this->current->next; | |
176 | *value = this->current->value; | |
177 | return TRUE; | |
178 | } | |
179 | /* backward */ | |
180 | if (this->current->previous == NULL) | |
181 | { | |
182 | return FALSE; | |
183 | } | |
184 | this->current = this->current->previous; | |
185 | *value = this->current->value; | |
186 | return TRUE; | |
187 | } | |
188 | ||
189 | /** | |
190 | * Implementation of iterator_t.has_next. | |
191 | */ | |
192 | static bool iterator_has_next(private_iterator_t *this) | |
7c2228f1 JH |
193 | { |
194 | if (this->list->count == 0) | |
195 | { | |
e3dd1393 | 196 | return FALSE; |
7c2228f1 JH |
197 | } |
198 | if (this->current == NULL) | |
199 | { | |
200 | this->current = (this->forward) ? this->list->first : this->list->last; | |
79538669 | 201 | return TRUE; |
7c2228f1 JH |
202 | } |
203 | if (this->forward) | |
204 | { | |
205 | if (this->current->next == NULL) | |
206 | { | |
e3dd1393 | 207 | return FALSE; |
7c2228f1 JH |
208 | } |
209 | this->current = this->current->next; | |
79538669 | 210 | return TRUE; |
7c2228f1 | 211 | } |
79538669 | 212 | /* backward */ |
7c2228f1 JH |
213 | if (this->current->previous == NULL) |
214 | { | |
e3dd1393 | 215 | return FALSE; |
7c2228f1 JH |
216 | } |
217 | this->current = this->current->previous; | |
79538669 | 218 | return TRUE; |
7c2228f1 JH |
219 | } |
220 | ||
221 | /** | |
e0e554ca | 222 | * Implementation of iterator_t.current. |
7c2228f1 | 223 | */ |
bdb141cb | 224 | static status_t iterator_current(private_iterator_t *this, void **value) |
7c2228f1 | 225 | { |
e3dd1393 JH |
226 | if (this->current == NULL) |
227 | { | |
e0e554ca | 228 | return NOT_FOUND; |
e3dd1393 JH |
229 | } |
230 | *value = this->current->value; | |
7c2228f1 JH |
231 | return SUCCESS; |
232 | } | |
233 | ||
234 | /** | |
e0e554ca | 235 | * Implementation of iterator_t.reset. |
7c2228f1 | 236 | */ |
d048df5c | 237 | static void iterator_reset(private_iterator_t *this) |
7c2228f1 | 238 | { |
e0e554ca | 239 | this->current = NULL; |
e0e554ca JH |
240 | } |
241 | ||
242 | /** | |
243 | * Implementation of iterator_t.remove. | |
244 | */ | |
245 | static status_t remove(private_iterator_t *this) | |
246 | { | |
247 | linked_list_element_t *new_current; | |
248 | ||
249 | if (this->current == NULL) | |
e3dd1393 | 250 | { |
e0e554ca | 251 | return NOT_FOUND; |
e3dd1393 | 252 | } |
e0e554ca JH |
253 | |
254 | if (this->list->count == 0) | |
255 | { | |
256 | return NOT_FOUND; | |
257 | } | |
258 | /* find out the new iterator position */ | |
1e54ebfa | 259 | if (this->current->previous != NULL) |
e0e554ca JH |
260 | { |
261 | new_current = this->current->previous; | |
262 | } | |
263 | else if (this->current->next != NULL) | |
264 | { | |
265 | new_current = this->current->next; | |
266 | } | |
267 | else | |
268 | { | |
269 | new_current = NULL; | |
270 | } | |
271 | ||
272 | /* now delete the entry :-) */ | |
273 | if (this->current->previous == NULL) | |
274 | { | |
275 | if (this->current->next == NULL) | |
276 | { | |
277 | this->list->first = NULL; | |
278 | this->list->last = NULL; | |
279 | } | |
280 | else | |
281 | { | |
282 | this->current->next->previous = NULL; | |
283 | this->list->first = this->current->next; | |
284 | } | |
285 | } | |
286 | else if (this->current->next == NULL) | |
287 | { | |
288 | this->current->previous->next = NULL; | |
289 | this->list->last = this->current->previous; | |
290 | } | |
291 | else | |
292 | { | |
293 | this->current->previous->next = this->current->next; | |
294 | this->current->next->previous = this->current->previous; | |
295 | } | |
296 | ||
297 | this->list->count--; | |
298 | this->current->destroy(this->current); | |
299 | /* set the new iterator position */ | |
300 | this->current = new_current; | |
7c2228f1 JH |
301 | return SUCCESS; |
302 | } | |
303 | ||
304 | /** | |
e0e554ca | 305 | * Implementation of iterator_t.insert_before. |
7c2228f1 | 306 | */ |
d048df5c | 307 | static void insert_before(private_iterator_t * iterator, void *item) |
7c2228f1 | 308 | { |
e0e554ca JH |
309 | if (iterator->current == NULL) |
310 | { | |
d048df5c | 311 | iterator->list->public.insert_first(&(iterator->list->public), item); |
e0e554ca JH |
312 | } |
313 | ||
314 | linked_list_element_t *element =(linked_list_element_t *) linked_list_element_create(item); | |
315 | ||
e0e554ca JH |
316 | if (iterator->current->previous == NULL) |
317 | { | |
e0e554ca JH |
318 | iterator->current->previous = element; |
319 | element->next = iterator->current; | |
320 | iterator->list->first = element; | |
321 | } | |
322 | else | |
323 | { | |
324 | iterator->current->previous->next = element; | |
325 | element->previous = iterator->current->previous; | |
326 | iterator->current->previous = element; | |
327 | element->next = iterator->current; | |
328 | } | |
329 | ||
330 | iterator->list->count++; | |
e0e554ca JH |
331 | } |
332 | ||
d440fe6d JH |
333 | /** |
334 | * Implementation of iterator_t.replace. | |
335 | */ | |
68621281 | 336 | static status_t replace (private_iterator_t *this, void **old_item, void *new_item) |
d440fe6d JH |
337 | { |
338 | if (this->current == NULL) | |
339 | { | |
340 | return NOT_FOUND; | |
341 | } | |
342 | if (old_item != NULL) | |
343 | { | |
344 | *old_item = this->current->value; | |
345 | } | |
346 | this->current->value = new_item; | |
347 | ||
348 | return SUCCESS; | |
349 | } | |
350 | ||
e0e554ca JH |
351 | /** |
352 | * Implementation of iterator_t.insert_after. | |
353 | */ | |
d048df5c | 354 | static void insert_after(private_iterator_t * iterator, void *item) |
e0e554ca JH |
355 | { |
356 | if (iterator->current == NULL) | |
357 | { | |
d048df5c | 358 | iterator->list->public.insert_first(&(iterator->list->public),item); |
c6ec246d | 359 | return; |
e0e554ca JH |
360 | } |
361 | ||
362 | linked_list_element_t *element =(linked_list_element_t *) linked_list_element_create(item); | |
363 | ||
e0e554ca JH |
364 | if (iterator->current->next == NULL) |
365 | { | |
e0e554ca JH |
366 | iterator->current->next = element; |
367 | element->previous = iterator->current; | |
368 | iterator->list->last = element; | |
369 | } | |
370 | else | |
371 | { | |
372 | iterator->current->next->previous = element; | |
373 | element->next = iterator->current->next; | |
374 | iterator->current->next = element; | |
375 | element->previous = iterator->current; | |
e3dd1393 | 376 | } |
e0e554ca | 377 | iterator->list->count++; |
e0e554ca JH |
378 | } |
379 | ||
380 | /** | |
381 | * Implementation of iterator_t.destroy. | |
382 | */ | |
d048df5c | 383 | static void iterator_destroy(private_iterator_t *this) |
e0e554ca | 384 | { |
5113680f | 385 | free(this); |
7c2228f1 JH |
386 | } |
387 | ||
388 | /** | |
e0e554ca | 389 | * Implementation of linked_list_t.get_count. |
7c2228f1 | 390 | */ |
1061c878 | 391 | static int get_count(private_linked_list_t *this) |
7c2228f1 | 392 | { |
1061c878 | 393 | return this->count; |
7c2228f1 JH |
394 | } |
395 | ||
c06dbbab MW |
396 | /** |
397 | * Implementation of linked_list_t.call_on_items. | |
398 | */ | |
399 | static void call_on_items(private_linked_list_t *this, void(*func)(void*)) | |
400 | { | |
401 | iterator_t *iterator; | |
402 | void *item; | |
403 | ||
404 | iterator = this->public.create_iterator(&(this->public),TRUE); | |
405 | ||
406 | while (iterator->has_next(iterator)) | |
407 | { | |
408 | iterator->current(iterator, &item); | |
409 | (*func)(item); | |
410 | } | |
411 | iterator->destroy(iterator); | |
412 | } | |
7c2228f1 | 413 | |
be910ee4 | 414 | /** |
e0e554ca | 415 | * Implementation of linked_list_t.insert_first. |
be910ee4 | 416 | */ |
d048df5c | 417 | static void insert_first(private_linked_list_t *this, void *item) |
be910ee4 | 418 | { |
e3dd1393 | 419 | linked_list_element_t *element; |
79538669 | 420 | |
e3dd1393 | 421 | element =(linked_list_element_t *) linked_list_element_create(item); |
79538669 | 422 | |
be910ee4 JH |
423 | if (this->count == 0) |
424 | { | |
425 | /* first entry in list */ | |
426 | this->first = element; | |
427 | this->last = element; | |
428 | element->previous = NULL; | |
429 | element->next = NULL; | |
dc64bed1 JH |
430 | } |
431 | else | |
be910ee4 | 432 | { |
e3dd1393 | 433 | linked_list_element_t *old_first_element = this->first; |
be910ee4 | 434 | element->next = old_first_element; |
7c2228f1 | 435 | element->previous = NULL; |
be910ee4 JH |
436 | old_first_element->previous = element; |
437 | this->first = element; | |
438 | } | |
79538669 | 439 | |
be910ee4 | 440 | this->count++; |
be910ee4 JH |
441 | } |
442 | ||
443 | /** | |
e0e554ca | 444 | * Implementation of linked_list_t.remove_first. |
be910ee4 | 445 | */ |
7c2228f1 | 446 | static status_t remove_first(private_linked_list_t *this, void **item) |
79538669 | 447 | { |
be910ee4 JH |
448 | if (this->count == 0) |
449 | { | |
e0e554ca | 450 | return NOT_FOUND; |
be910ee4 | 451 | } |
79538669 | 452 | |
e3dd1393 | 453 | linked_list_element_t *element = this->first; |
79538669 | 454 | |
be910ee4 JH |
455 | if (element->next != NULL) |
456 | { | |
457 | element->next->previous = NULL; | |
458 | } | |
459 | this->first = element->next; | |
460 | ||
c06dbbab MW |
461 | if (item != NULL) |
462 | { | |
463 | *item = element->value; | |
464 | } | |
be910ee4 JH |
465 | |
466 | this->count--; | |
79538669 | 467 | |
d048df5c MW |
468 | element->destroy(element); |
469 | ||
470 | return SUCCESS; | |
be910ee4 JH |
471 | } |
472 | ||
473 | /** | |
e0e554ca | 474 | * Implementation of linked_list_t.get_first. |
be910ee4 | 475 | */ |
7c2228f1 | 476 | static status_t get_first(private_linked_list_t *this, void **item) |
79538669 | 477 | { |
be910ee4 JH |
478 | if (this->count == 0) |
479 | { | |
e0e554ca | 480 | return NOT_FOUND; |
be910ee4 | 481 | } |
79538669 | 482 | |
e3dd1393 | 483 | *item = this->first->value; |
be910ee4 JH |
484 | |
485 | return SUCCESS; | |
486 | } | |
487 | ||
488 | /** | |
e0e554ca | 489 | * Implementation of linked_list_t.insert_last. |
be910ee4 | 490 | */ |
d048df5c | 491 | static void insert_last(private_linked_list_t *this, void *item) |
be910ee4 | 492 | { |
e3dd1393 | 493 | linked_list_element_t *element = (linked_list_element_t *) linked_list_element_create(item); |
79538669 | 494 | |
be910ee4 JH |
495 | if (this->count == 0) |
496 | { | |
497 | /* first entry in list */ | |
498 | this->first = element; | |
499 | this->last = element; | |
500 | element->previous = NULL; | |
501 | element->next = NULL; | |
d048df5c MW |
502 | } |
503 | else | |
be910ee4 | 504 | { |
d048df5c | 505 | |
e3dd1393 | 506 | linked_list_element_t *old_last_element = this->last; |
be910ee4 | 507 | element->previous = old_last_element; |
7c2228f1 | 508 | element->next = NULL; |
be910ee4 JH |
509 | old_last_element->next = element; |
510 | this->last = element; | |
511 | } | |
79538669 | 512 | |
be910ee4 | 513 | this->count++; |
be910ee4 JH |
514 | } |
515 | ||
516 | /** | |
e0e554ca | 517 | * Implementation of linked_list_t.remove_last. |
be910ee4 | 518 | */ |
7c2228f1 | 519 | static status_t remove_last(private_linked_list_t *this, void **item) |
79538669 | 520 | { |
be910ee4 JH |
521 | if (this->count == 0) |
522 | { | |
e0e554ca | 523 | return NOT_FOUND; |
be910ee4 | 524 | } |
79538669 | 525 | |
e3dd1393 | 526 | linked_list_element_t *element = this->last; |
79538669 | 527 | |
be910ee4 JH |
528 | if (element->previous != NULL) |
529 | { | |
530 | element->previous->next = NULL; | |
531 | } | |
532 | this->last = element->previous; | |
533 | ||
c06dbbab MW |
534 | if (item != NULL) |
535 | { | |
536 | *item = element->value; | |
537 | } | |
be910ee4 JH |
538 | |
539 | this->count--; | |
79538669 | 540 | |
d048df5c MW |
541 | element->destroy(element); |
542 | ||
543 | return SUCCESS; | |
be910ee4 JH |
544 | } |
545 | ||
1e54ebfa JH |
546 | /** |
547 | * Implementation of linked_list_t.insert_at_position. | |
548 | */ | |
549 | static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item) | |
550 | { | |
551 | linked_list_element_t *current_element; | |
552 | int i; | |
553 | ||
554 | if (this->count <= position) | |
555 | { | |
556 | return INVALID_ARG; | |
557 | } | |
558 | ||
559 | current_element = this->first; | |
560 | ||
561 | for (i = 0; i < position;i++) | |
562 | { | |
563 | current_element = current_element->next; | |
564 | } | |
565 | ||
566 | if (current_element == NULL) | |
567 | { | |
568 | this->public.insert_last(&(this->public),item); | |
569 | return SUCCESS; | |
570 | } | |
571 | ||
572 | linked_list_element_t *element =(linked_list_element_t *) linked_list_element_create(item); | |
573 | ||
574 | ||
575 | if (current_element->previous == NULL) | |
576 | { | |
577 | current_element->previous = element; | |
578 | element->next = current_element; | |
579 | this->first = element; | |
580 | } | |
581 | else | |
582 | { | |
583 | current_element->previous->next = element; | |
584 | element->previous = current_element->previous; | |
585 | current_element->previous = element; | |
586 | element->next = current_element; | |
587 | } | |
588 | ||
589 | ||
590 | this->count++; | |
591 | return SUCCESS; | |
592 | } | |
593 | ||
594 | /** | |
595 | * Implementation of linked_list_t.remove_at_position. | |
596 | */ | |
597 | static status_t remove_at_position (private_linked_list_t *this,size_t position, void **item) | |
598 | { | |
599 | iterator_t *iterator; | |
600 | int i; | |
601 | ||
602 | if (this->count <= position) | |
603 | { | |
604 | return INVALID_ARG; | |
605 | } | |
606 | ||
607 | iterator = this->public.create_iterator(&(this->public),TRUE); | |
608 | ||
609 | iterator->has_next(iterator); | |
610 | for (i = 0; i < position;i++) | |
611 | { | |
612 | iterator->has_next(iterator); | |
613 | } | |
614 | iterator->current(iterator,item); | |
615 | iterator->remove(iterator); | |
616 | iterator->destroy(iterator); | |
617 | ||
618 | return SUCCESS; | |
619 | } | |
620 | ||
621 | /** | |
622 | * Implementation of linked_list_t.get_at_position. | |
623 | */ | |
624 | static status_t get_at_position (private_linked_list_t *this,size_t position, void **item) | |
625 | { | |
626 | int i; | |
627 | iterator_t *iterator; | |
628 | status_t status; | |
629 | if (this->count <= position) | |
630 | { | |
631 | return INVALID_ARG; | |
632 | } | |
633 | ||
634 | iterator = this->public.create_iterator(&(this->public),TRUE); | |
635 | ||
636 | iterator->has_next(iterator); | |
637 | for (i = 0; i < position;i++) | |
638 | { | |
639 | iterator->has_next(iterator); | |
640 | } | |
641 | status = iterator->current(iterator,item); | |
642 | iterator->destroy(iterator); | |
643 | return status; | |
644 | } | |
645 | ||
be910ee4 | 646 | /** |
e0e554ca | 647 | * Implementation of linked_list_t.get_last. |
be910ee4 | 648 | */ |
7c2228f1 | 649 | static status_t get_last(private_linked_list_t *this, void **item) |
be910ee4 | 650 | { |
be910ee4 JH |
651 | if (this->count == 0) |
652 | { | |
e0e554ca | 653 | return NOT_FOUND; |
be910ee4 | 654 | } |
79538669 | 655 | |
e3dd1393 | 656 | *item = this->last->value; |
be910ee4 JH |
657 | |
658 | return SUCCESS; | |
659 | } | |
660 | ||
bfdc5c7c | 661 | /** |
e0e554ca | 662 | * Implementation of linked_list_t.create_iterator. |
bfdc5c7c | 663 | */ |
a0753941 | 664 | static iterator_t *create_iterator (private_linked_list_t *linked_list,bool forward) |
12c3e4c8 | 665 | { |
5113680f | 666 | private_iterator_t *this = malloc_thing(private_iterator_t); |
12c3e4c8 | 667 | |
dfa6e086 | 668 | this->public.iterate = (bool (*) (iterator_t *this, void **value)) iterate; |
bdb141cb MW |
669 | this->public.has_next = (bool (*) (iterator_t *this)) iterator_has_next; |
670 | this->public.current = (status_t (*) (iterator_t *this, void **value)) iterator_current; | |
d048df5c MW |
671 | this->public.insert_before = (void (*) (iterator_t *this, void *item)) insert_before; |
672 | this->public.insert_after = (void (*) (iterator_t *this, void *item)) insert_after; | |
d440fe6d | 673 | this->public.replace = (status_t (*) (iterator_t *, void **, void *)) replace; |
bdb141cb | 674 | this->public.remove = (status_t (*) (iterator_t *this)) remove; |
d048df5c MW |
675 | this->public.reset = (void (*) (iterator_t *this)) iterator_reset; |
676 | this->public.destroy = (void (*) (iterator_t *this)) iterator_destroy; | |
12c3e4c8 MW |
677 | |
678 | this->forward = forward; | |
679 | this->current = NULL; | |
680 | this->list = linked_list; | |
681 | ||
a0753941 | 682 | return &(this->public); |
bfdc5c7c JH |
683 | } |
684 | ||
be910ee4 | 685 | /** |
e0e554ca | 686 | * Implementation of linked_list_t.destroy. |
be910ee4 | 687 | */ |
d048df5c | 688 | static void linked_list_destroy(private_linked_list_t *this) |
be910ee4 | 689 | { |
e0e554ca | 690 | void * value; |
dc64bed1 | 691 | /* Remove all list items before destroying list */ |
e0e554ca | 692 | while (this->public.remove_first(&(this->public),&value) != NOT_FOUND) |
be910ee4 | 693 | { |
dc64bed1 JH |
694 | /* values are not destroyed so memory leaks are possible |
695 | * if list is not empty when deleting */ | |
be910ee4 | 696 | } |
5113680f | 697 | free(this); |
be910ee4 | 698 | } |
79538669 | 699 | |
adca27eb | 700 | /* |
d794bcdb | 701 | * Described in header. |
adca27eb | 702 | */ |
79538669 | 703 | linked_list_t *linked_list_create() |
be910ee4 | 704 | { |
5113680f | 705 | private_linked_list_t *this = malloc_thing(private_linked_list_t); |
79538669 | 706 | |
1e54ebfa JH |
707 | this->public.get_count = (int (*) (linked_list_t *)) get_count; |
708 | this->public.create_iterator = (iterator_t * (*) (linked_list_t *,bool )) create_iterator; | |
c06dbbab | 709 | this->public.call_on_items = (void (*) (linked_list_t *, void(*func)(void*)))call_on_items; |
1e54ebfa JH |
710 | this->public.get_first = (status_t (*) (linked_list_t *, void **item)) get_first; |
711 | this->public.get_last = (status_t (*) (linked_list_t *, void **item)) get_last; | |
712 | this->public.insert_first = (void (*) (linked_list_t *, void *item)) insert_first; | |
713 | this->public.insert_last = (void (*) (linked_list_t *, void *item)) insert_last; | |
714 | this->public.remove_first = (status_t (*) (linked_list_t *, void **item)) remove_first; | |
715 | this->public.remove_last = (status_t (*) (linked_list_t *, void **item)) remove_last; | |
716 | this->public.insert_at_position =(status_t (*) (linked_list_t *,size_t, void *)) insert_at_position; | |
717 | this->public.remove_at_position =(status_t (*) (linked_list_t *,size_t, void **)) remove_at_position; | |
718 | this->public.get_at_position =(status_t (*) (linked_list_t *,size_t, void **)) get_at_position; | |
719 | ||
720 | this->public.destroy = (void (*) (linked_list_t *)) linked_list_destroy; | |
79538669 | 721 | |
be910ee4 JH |
722 | this->count = 0; |
723 | this->first = NULL; | |
724 | this->last = NULL; | |
79538669 | 725 | |
7c2228f1 | 726 | return (&(this->public)); |
be910ee4 | 727 | } |