xref: /btstack/src/btstack_linked_list.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
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