xref: /btstack/src/btstack_linked_list.c (revision 9305033e0290a73b79a29900c5b9f35f77d880b1)
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
234fd23d47SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
244fd23d47SMatthias Ringwald  * RINGWALD 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 
494fd23d47SMatthias Ringwald /**
504fd23d47SMatthias Ringwald  * tests if list is empty
514fd23d47SMatthias Ringwald  */
528b2bf72fSMatthias Ringwald bool  btstack_linked_list_empty(btstack_linked_list_t * list){
534fd23d47SMatthias Ringwald     return *list == (void *) 0;
544fd23d47SMatthias Ringwald }
554fd23d47SMatthias Ringwald 
564fd23d47SMatthias Ringwald /**
57665d90f2SMatthias Ringwald  * btstack_linked_list_get_last_item
584fd23d47SMatthias Ringwald  */
598f2a52f4SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_last_item(btstack_linked_list_t * list){        // <-- find the last item in the list
60665d90f2SMatthias Ringwald     btstack_linked_item_t *lastItem = NULL;
61665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
62a0da043fSMatthias Ringwald     for (it = *list; it != NULL; it = it->next){
63*9305033eSMatthias Ringwald         if (it != NULL) {
644fd23d47SMatthias Ringwald             lastItem = it;
654fd23d47SMatthias Ringwald         }
664fd23d47SMatthias Ringwald     }
674fd23d47SMatthias Ringwald     return lastItem;
684fd23d47SMatthias Ringwald }
694fd23d47SMatthias Ringwald 
704fd23d47SMatthias Ringwald 
714fd23d47SMatthias Ringwald /**
72665d90f2SMatthias Ringwald  * btstack_linked_list_add
734fd23d47SMatthias Ringwald  */
7478d0c67aSMatthias Ringwald bool btstack_linked_list_add(btstack_linked_list_t * list, btstack_linked_item_t *item){        // <-- add item to list
754fd23d47SMatthias Ringwald     // check if already in list
76665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
77a0da043fSMatthias Ringwald     for (it = *list; it != NULL; it = it->next){
784fd23d47SMatthias Ringwald         if (it == item) {
7978d0c67aSMatthias Ringwald             return false;
804fd23d47SMatthias Ringwald         }
814fd23d47SMatthias Ringwald     }
824fd23d47SMatthias Ringwald     // add first
834fd23d47SMatthias Ringwald     item->next = *list;
844fd23d47SMatthias Ringwald     *list = item;
8578d0c67aSMatthias Ringwald     return true;
864fd23d47SMatthias Ringwald }
874fd23d47SMatthias Ringwald 
8878d0c67aSMatthias Ringwald bool btstack_linked_list_add_tail(btstack_linked_list_t * list, btstack_linked_item_t *item){   // <-- add item to list as last element
894fd23d47SMatthias Ringwald     // check if already in list
90665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
91a0da043fSMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it->next != NULL ; it = it->next){
924fd23d47SMatthias Ringwald         if (it->next == item) {
9378d0c67aSMatthias Ringwald             return false;
944fd23d47SMatthias Ringwald         }
954fd23d47SMatthias Ringwald     }
96665d90f2SMatthias Ringwald     item->next = (btstack_linked_item_t*) 0;
974fd23d47SMatthias Ringwald     it->next = item;
9878d0c67aSMatthias Ringwald     return true;
994fd23d47SMatthias Ringwald }
1004fd23d47SMatthias Ringwald 
101d58a1b5fSMatthias Ringwald bool  btstack_linked_list_remove(btstack_linked_list_t * list, btstack_linked_item_t *item){    // <-- remove item from list
102d58a1b5fSMatthias Ringwald     if (!item) return false;
103665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
104a0da043fSMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it != NULL; it = it->next){
1054fd23d47SMatthias Ringwald         if (it->next == item){
1064fd23d47SMatthias Ringwald             it->next =  item->next;
107d58a1b5fSMatthias Ringwald             return true;
1084fd23d47SMatthias Ringwald         }
1094fd23d47SMatthias Ringwald     }
110d58a1b5fSMatthias Ringwald     return false;
1114fd23d47SMatthias Ringwald }
1124fd23d47SMatthias Ringwald 
1134fd23d47SMatthias Ringwald /**
1144fd23d47SMatthias Ringwald  * @returns number of items in list
1154fd23d47SMatthias Ringwald  */
1168f2a52f4SMatthias Ringwald  int btstack_linked_list_count(btstack_linked_list_t * list){
117665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
1184fd23d47SMatthias Ringwald     int counter = 0;
119a0da043fSMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it->next != NULL; it = it->next) {
1204fd23d47SMatthias Ringwald         counter++;
1214fd23d47SMatthias Ringwald     }
1224fd23d47SMatthias Ringwald     return counter;
1234fd23d47SMatthias Ringwald }
1244fd23d47SMatthias Ringwald 
12567711d5eSMatthias Ringwald // get first element
12667711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_first_item(btstack_linked_list_t * list){
12767711d5eSMatthias Ringwald     return * list;
12867711d5eSMatthias Ringwald }
12967711d5eSMatthias Ringwald 
13067711d5eSMatthias Ringwald // pop (get + remove) first element
13167711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_pop(btstack_linked_list_t * list){
13267711d5eSMatthias Ringwald     btstack_linked_item_t * item = *list;
13367711d5eSMatthias Ringwald     if (!item) return NULL;
13467711d5eSMatthias Ringwald     *list = item->next;
13567711d5eSMatthias Ringwald     return item;
13667711d5eSMatthias Ringwald }
13767711d5eSMatthias Ringwald 
13867711d5eSMatthias Ringwald 
1394fd23d47SMatthias Ringwald //
1404fd23d47SMatthias Ringwald // Linked List Iterator implementation
1414fd23d47SMatthias Ringwald //
1424fd23d47SMatthias Ringwald 
1438f2a52f4SMatthias Ringwald void btstack_linked_list_iterator_init(btstack_linked_list_iterator_t * it, btstack_linked_list_t * head){
1444fd23d47SMatthias Ringwald     it->advance_on_next = 0;
145665d90f2SMatthias Ringwald     it->prev = (btstack_linked_item_t*) head;
1464fd23d47SMatthias Ringwald     it->curr = * head;
1474fd23d47SMatthias Ringwald }
1484fd23d47SMatthias Ringwald 
1498b2bf72fSMatthias Ringwald bool btstack_linked_list_iterator_has_next(btstack_linked_list_iterator_t * it){
150665d90f2SMatthias 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);
1514fd23d47SMatthias Ringwald     if (!it->advance_on_next){
1524fd23d47SMatthias Ringwald         return it->curr != NULL;
1534fd23d47SMatthias Ringwald     }
1544fd23d47SMatthias Ringwald     if (it->prev->next != it->curr){
1554fd23d47SMatthias Ringwald         // current item has been removed
1564fd23d47SMatthias Ringwald         return it->prev->next != NULL;
1574fd23d47SMatthias Ringwald     }
1584fd23d47SMatthias Ringwald     // current items has not been removed
1594fd23d47SMatthias Ringwald     return it->curr->next != NULL;
1604fd23d47SMatthias Ringwald }
1614fd23d47SMatthias Ringwald 
162665d90f2SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_iterator_next(btstack_linked_list_iterator_t * it){
1634fd23d47SMatthias Ringwald     if (it->advance_on_next){
1644fd23d47SMatthias Ringwald         if (it->prev->next == it->curr){
1654fd23d47SMatthias Ringwald             it->prev = it->curr;
1664fd23d47SMatthias Ringwald             it->curr = it->curr->next;
1674fd23d47SMatthias Ringwald         } else {
1684fd23d47SMatthias Ringwald             // curr was removed from the list, set it again but don't advance prev
1694fd23d47SMatthias Ringwald             it->curr = it->prev->next;
1704fd23d47SMatthias Ringwald         }
1714fd23d47SMatthias Ringwald     } else {
1724fd23d47SMatthias Ringwald         it->advance_on_next = 1;
1734fd23d47SMatthias Ringwald     }
1744fd23d47SMatthias Ringwald     return it->curr;
1754fd23d47SMatthias Ringwald }
1764fd23d47SMatthias Ringwald 
177665d90f2SMatthias Ringwald void btstack_linked_list_iterator_remove(btstack_linked_list_iterator_t * it){
17886167813SMatthias Ringwald     btstack_assert(it->prev->next == it->curr);
179f8b1697fSMatthias Ringwald     it->curr = it->curr->next;
1804fd23d47SMatthias Ringwald     it->prev->next = it->curr;
1814fd23d47SMatthias Ringwald     it->advance_on_next = 0;
1824fd23d47SMatthias Ringwald }
183