14fd23d47SMatthias Ringwald /*
24fd23d47SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH
34fd23d47SMatthias Ringwald *
44fd23d47SMatthias Ringwald * Redistribution and use in source and binary forms, with or without
54fd23d47SMatthias Ringwald * modification, are permitted provided that the following conditions
64fd23d47SMatthias Ringwald * are met:
74fd23d47SMatthias Ringwald *
84fd23d47SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright
94fd23d47SMatthias Ringwald * notice, this list of conditions and the following disclaimer.
104fd23d47SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright
114fd23d47SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the
124fd23d47SMatthias Ringwald * documentation and/or other materials provided with the distribution.
134fd23d47SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of
144fd23d47SMatthias Ringwald * contributors may be used to endorse or promote products derived
154fd23d47SMatthias Ringwald * from this software without specific prior written permission.
164fd23d47SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for
174fd23d47SMatthias Ringwald * personal benefit and not for any commercial purpose or for
184fd23d47SMatthias Ringwald * monetary gain.
194fd23d47SMatthias Ringwald *
204fd23d47SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
214fd23d47SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
224fd23d47SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
254fd23d47SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
264fd23d47SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
274fd23d47SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
284fd23d47SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
294fd23d47SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
304fd23d47SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
314fd23d47SMatthias Ringwald * SUCH DAMAGE.
324fd23d47SMatthias Ringwald *
334fd23d47SMatthias Ringwald * Please inquire about commercial licensing options at
344fd23d47SMatthias Ringwald * [email protected]
354fd23d47SMatthias Ringwald *
364fd23d47SMatthias Ringwald */
374fd23d47SMatthias Ringwald
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "btstack_linked_list.c"
39ab2c6ae4SMatthias Ringwald
404fd23d47SMatthias Ringwald /*
414fd23d47SMatthias Ringwald * linked_list.c
424fd23d47SMatthias Ringwald *
434fd23d47SMatthias Ringwald * Created by Matthias Ringwald on 7/13/09.
444fd23d47SMatthias Ringwald */
454fd23d47SMatthias Ringwald
464fd23d47SMatthias Ringwald #include "btstack_linked_list.h"
4786bcddecSMatthias Ringwald #include "btstack_debug.h"
484fd23d47SMatthias Ringwald
493cfa4086SMatthias Ringwald #include <stddef.h>
503cfa4086SMatthias Ringwald
514fd23d47SMatthias Ringwald /**
524fd23d47SMatthias Ringwald * tests if list is empty
534fd23d47SMatthias Ringwald */
btstack_linked_list_empty(btstack_linked_list_t * list)548b2bf72fSMatthias Ringwald bool btstack_linked_list_empty(btstack_linked_list_t * list){
554fd23d47SMatthias Ringwald return *list == (void *) 0;
564fd23d47SMatthias Ringwald }
574fd23d47SMatthias Ringwald
584fd23d47SMatthias Ringwald /**
59665d90f2SMatthias Ringwald * btstack_linked_list_get_last_item
604fd23d47SMatthias Ringwald */
btstack_linked_list_get_last_item(btstack_linked_list_t * list)618f2a52f4SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_last_item(btstack_linked_list_t * list){ // <-- find the last item in the list
62665d90f2SMatthias Ringwald btstack_linked_item_t *lastItem = NULL;
63665d90f2SMatthias Ringwald btstack_linked_item_t *it;
64a0da043fSMatthias Ringwald for (it = *list; it != NULL; it = it->next){
659305033eSMatthias Ringwald if (it != NULL) {
664fd23d47SMatthias Ringwald lastItem = it;
674fd23d47SMatthias Ringwald }
684fd23d47SMatthias Ringwald }
694fd23d47SMatthias Ringwald return lastItem;
704fd23d47SMatthias Ringwald }
714fd23d47SMatthias Ringwald
724fd23d47SMatthias Ringwald
734fd23d47SMatthias Ringwald /**
74665d90f2SMatthias Ringwald * btstack_linked_list_add
754fd23d47SMatthias Ringwald */
btstack_linked_list_add(btstack_linked_list_t * list,btstack_linked_item_t * item)7678d0c67aSMatthias Ringwald bool btstack_linked_list_add(btstack_linked_list_t * list, btstack_linked_item_t *item){ // <-- add item to list
774fd23d47SMatthias Ringwald // check if already in list
78665d90f2SMatthias Ringwald btstack_linked_item_t *it;
79a0da043fSMatthias Ringwald for (it = *list; it != NULL; it = it->next){
804fd23d47SMatthias Ringwald if (it == item) {
8178d0c67aSMatthias Ringwald return false;
824fd23d47SMatthias Ringwald }
834fd23d47SMatthias Ringwald }
844fd23d47SMatthias Ringwald // add first
854fd23d47SMatthias Ringwald item->next = *list;
864fd23d47SMatthias Ringwald *list = item;
8778d0c67aSMatthias Ringwald return true;
884fd23d47SMatthias Ringwald }
894fd23d47SMatthias Ringwald
btstack_linked_list_add_tail(btstack_linked_list_t * list,btstack_linked_item_t * item)9078d0c67aSMatthias Ringwald bool btstack_linked_list_add_tail(btstack_linked_list_t * list, btstack_linked_item_t *item){ // <-- add item to list as last element
914fd23d47SMatthias Ringwald // check if already in list
92665d90f2SMatthias Ringwald btstack_linked_item_t *it;
93a0da043fSMatthias Ringwald for (it = (btstack_linked_item_t *) list; it->next != NULL ; it = it->next){
944fd23d47SMatthias Ringwald if (it->next == item) {
9578d0c67aSMatthias Ringwald return false;
964fd23d47SMatthias Ringwald }
974fd23d47SMatthias Ringwald }
98665d90f2SMatthias Ringwald item->next = (btstack_linked_item_t*) 0;
994fd23d47SMatthias Ringwald it->next = item;
10078d0c67aSMatthias Ringwald return true;
1014fd23d47SMatthias Ringwald }
1024fd23d47SMatthias Ringwald
btstack_linked_list_remove(btstack_linked_list_t * list,btstack_linked_item_t * item)103d58a1b5fSMatthias Ringwald bool btstack_linked_list_remove(btstack_linked_list_t * list, btstack_linked_item_t *item){ // <-- remove item from list
104d58a1b5fSMatthias Ringwald if (!item) return false;
105665d90f2SMatthias Ringwald btstack_linked_item_t *it;
106a0da043fSMatthias Ringwald for (it = (btstack_linked_item_t *) list; it != NULL; it = it->next){
1074fd23d47SMatthias Ringwald if (it->next == item){
1084fd23d47SMatthias Ringwald it->next = item->next;
109d58a1b5fSMatthias Ringwald return true;
1104fd23d47SMatthias Ringwald }
1114fd23d47SMatthias Ringwald }
112d58a1b5fSMatthias Ringwald return false;
1134fd23d47SMatthias Ringwald }
1144fd23d47SMatthias Ringwald
1154fd23d47SMatthias Ringwald /**
1166b65794dSMilanka Ringwald * @return number of items in list
1174fd23d47SMatthias Ringwald */
btstack_linked_list_count(btstack_linked_list_t * list)1188f2a52f4SMatthias Ringwald int btstack_linked_list_count(btstack_linked_list_t * list){
119665d90f2SMatthias Ringwald btstack_linked_item_t *it;
1204fd23d47SMatthias Ringwald int counter = 0;
121a0da043fSMatthias Ringwald for (it = (btstack_linked_item_t *) list; it->next != NULL; it = it->next) {
1224fd23d47SMatthias Ringwald counter++;
1234fd23d47SMatthias Ringwald }
1244fd23d47SMatthias Ringwald return counter;
1254fd23d47SMatthias Ringwald }
1264fd23d47SMatthias Ringwald
12767711d5eSMatthias Ringwald // get first element
btstack_linked_list_get_first_item(btstack_linked_list_t * list)12867711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_first_item(btstack_linked_list_t * list){
12967711d5eSMatthias Ringwald return * list;
13067711d5eSMatthias Ringwald }
13167711d5eSMatthias Ringwald
13267711d5eSMatthias Ringwald // pop (get + remove) first element
btstack_linked_list_pop(btstack_linked_list_t * list)13367711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_pop(btstack_linked_list_t * list){
13467711d5eSMatthias Ringwald btstack_linked_item_t * item = *list;
13567711d5eSMatthias Ringwald if (!item) return NULL;
13667711d5eSMatthias Ringwald *list = item->next;
13767711d5eSMatthias Ringwald return item;
13867711d5eSMatthias Ringwald }
13967711d5eSMatthias Ringwald
14067711d5eSMatthias Ringwald
1414fd23d47SMatthias Ringwald //
1424fd23d47SMatthias Ringwald // Linked List Iterator implementation
1434fd23d47SMatthias Ringwald //
1444fd23d47SMatthias Ringwald
btstack_linked_list_iterator_init(btstack_linked_list_iterator_t * it,btstack_linked_list_t * list)145b45b7749SMilanka Ringwald void btstack_linked_list_iterator_init(btstack_linked_list_iterator_t * it, btstack_linked_list_t * list){
1464fd23d47SMatthias Ringwald it->advance_on_next = 0;
147b45b7749SMilanka Ringwald it->prev = (btstack_linked_item_t*) list;
148b45b7749SMilanka Ringwald it->curr = * list;
1494fd23d47SMatthias Ringwald }
1504fd23d47SMatthias Ringwald
btstack_linked_list_iterator_has_next(btstack_linked_list_iterator_t * it)1518b2bf72fSMatthias Ringwald bool btstack_linked_list_iterator_has_next(btstack_linked_list_iterator_t * it){
152665d90f2SMatthias Ringwald // log_info("btstack_linked_list_iterator_has_next: advance on next %u, it->prev %p, it->curr %p", it->advance_on_next, it->prev, it->curr);
1534fd23d47SMatthias Ringwald if (!it->advance_on_next){
1544fd23d47SMatthias Ringwald return it->curr != NULL;
1554fd23d47SMatthias Ringwald }
1564fd23d47SMatthias Ringwald if (it->prev->next != it->curr){
1574fd23d47SMatthias Ringwald // current item has been removed
1584fd23d47SMatthias Ringwald return it->prev->next != NULL;
1594fd23d47SMatthias Ringwald }
1604fd23d47SMatthias Ringwald // current items has not been removed
1614fd23d47SMatthias Ringwald return it->curr->next != NULL;
1624fd23d47SMatthias Ringwald }
1634fd23d47SMatthias Ringwald
btstack_linked_list_iterator_next(btstack_linked_list_iterator_t * it)164665d90f2SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_iterator_next(btstack_linked_list_iterator_t * it){
1654fd23d47SMatthias Ringwald if (it->advance_on_next){
1664fd23d47SMatthias Ringwald if (it->prev->next == it->curr){
1674fd23d47SMatthias Ringwald it->prev = it->curr;
1684fd23d47SMatthias Ringwald it->curr = it->curr->next;
1694fd23d47SMatthias Ringwald } else {
1704fd23d47SMatthias Ringwald // curr was removed from the list, set it again but don't advance prev
1714fd23d47SMatthias Ringwald it->curr = it->prev->next;
1724fd23d47SMatthias Ringwald }
1734fd23d47SMatthias Ringwald } else {
1744fd23d47SMatthias Ringwald it->advance_on_next = 1;
1754fd23d47SMatthias Ringwald }
1764fd23d47SMatthias Ringwald return it->curr;
1774fd23d47SMatthias Ringwald }
1784fd23d47SMatthias Ringwald
btstack_linked_list_iterator_remove(btstack_linked_list_iterator_t * it)179665d90f2SMatthias Ringwald void btstack_linked_list_iterator_remove(btstack_linked_list_iterator_t * it){
18086167813SMatthias Ringwald btstack_assert(it->prev->next == it->curr);
181f8b1697fSMatthias Ringwald it->curr = it->curr->next;
1824fd23d47SMatthias Ringwald it->prev->next = it->curr;
1834fd23d47SMatthias Ringwald it->advance_on_next = 0;
1844fd23d47SMatthias Ringwald }
185