xref: /btstack/src/btstack_linked_list.c (revision ab2c6ae4b737d5e801d3defe4117331eb244ebb7)
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 
38*ab2c6ae4SMatthias Ringwald #define __BTSTACK_FILE__ "btstack_linked_list.c"
39*ab2c6ae4SMatthias 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"
474fd23d47SMatthias Ringwald #include <stdlib.h>
484fd23d47SMatthias Ringwald #include <stdio.h>
494fd23d47SMatthias Ringwald 
504fd23d47SMatthias Ringwald /**
514fd23d47SMatthias Ringwald  * tests if list is empty
524fd23d47SMatthias Ringwald  */
538f2a52f4SMatthias Ringwald int  btstack_linked_list_empty(btstack_linked_list_t * list){
544fd23d47SMatthias Ringwald     return *list == (void *) 0;
554fd23d47SMatthias Ringwald }
564fd23d47SMatthias Ringwald 
574fd23d47SMatthias Ringwald /**
58665d90f2SMatthias Ringwald  * btstack_linked_list_get_last_item
594fd23d47SMatthias Ringwald  */
608f2a52f4SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_last_item(btstack_linked_list_t * list){        // <-- find the last item in the list
61665d90f2SMatthias Ringwald     btstack_linked_item_t *lastItem = NULL;
62665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
634fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
644fd23d47SMatthias Ringwald         if (it) {
654fd23d47SMatthias Ringwald             lastItem = it;
664fd23d47SMatthias Ringwald         }
674fd23d47SMatthias Ringwald     }
684fd23d47SMatthias Ringwald     return lastItem;
694fd23d47SMatthias Ringwald }
704fd23d47SMatthias Ringwald 
714fd23d47SMatthias Ringwald 
724fd23d47SMatthias Ringwald /**
73665d90f2SMatthias Ringwald  * btstack_linked_list_add
744fd23d47SMatthias Ringwald  */
758f2a52f4SMatthias Ringwald void btstack_linked_list_add(btstack_linked_list_t * list, btstack_linked_item_t *item){        // <-- add item to list
764fd23d47SMatthias Ringwald     // check if already in list
77665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
784fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
794fd23d47SMatthias Ringwald         if (it == item) {
804fd23d47SMatthias Ringwald             return;
814fd23d47SMatthias Ringwald         }
824fd23d47SMatthias Ringwald     }
834fd23d47SMatthias Ringwald     // add first
844fd23d47SMatthias Ringwald     item->next = *list;
854fd23d47SMatthias Ringwald     *list = item;
864fd23d47SMatthias Ringwald }
874fd23d47SMatthias Ringwald 
888f2a52f4SMatthias Ringwald void 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;
91665d90f2SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it->next ; it = it->next){
924fd23d47SMatthias Ringwald         if (it->next == item) {
934fd23d47SMatthias Ringwald             return;
944fd23d47SMatthias Ringwald         }
954fd23d47SMatthias Ringwald     }
96665d90f2SMatthias Ringwald     item->next = (btstack_linked_item_t*) 0;
974fd23d47SMatthias Ringwald     it->next = item;
984fd23d47SMatthias Ringwald }
994fd23d47SMatthias Ringwald 
1008f2a52f4SMatthias Ringwald int  btstack_linked_list_remove(btstack_linked_list_t * list, btstack_linked_item_t *item){    // <-- remove item from list
1014fd23d47SMatthias Ringwald     if (!item) return -1;
102665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
103665d90f2SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it ; it = it->next){
1044fd23d47SMatthias Ringwald         if (it->next == item){
1054fd23d47SMatthias Ringwald             it->next =  item->next;
1064fd23d47SMatthias Ringwald             return 0;
1074fd23d47SMatthias Ringwald         }
1084fd23d47SMatthias Ringwald     }
1094fd23d47SMatthias Ringwald     return -1;
1104fd23d47SMatthias Ringwald }
1114fd23d47SMatthias Ringwald 
1124fd23d47SMatthias Ringwald /**
1134fd23d47SMatthias Ringwald  * @returns number of items in list
1144fd23d47SMatthias Ringwald  */
1158f2a52f4SMatthias Ringwald  int btstack_linked_list_count(btstack_linked_list_t * list){
116665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
1174fd23d47SMatthias Ringwald     int counter = 0;
118a2908aa0SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it->next ; it = it->next) {
1194fd23d47SMatthias Ringwald         counter++;
1204fd23d47SMatthias Ringwald     }
1214fd23d47SMatthias Ringwald     return counter;
1224fd23d47SMatthias Ringwald }
1234fd23d47SMatthias Ringwald 
12467711d5eSMatthias Ringwald // get first element
12567711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_first_item(btstack_linked_list_t * list){
12667711d5eSMatthias Ringwald     return * list;
12767711d5eSMatthias Ringwald }
12867711d5eSMatthias Ringwald 
12967711d5eSMatthias Ringwald // pop (get + remove) first element
13067711d5eSMatthias Ringwald btstack_linked_item_t * btstack_linked_list_pop(btstack_linked_list_t * list){
13167711d5eSMatthias Ringwald     btstack_linked_item_t * item = *list;
13267711d5eSMatthias Ringwald     if (!item) return NULL;
13367711d5eSMatthias Ringwald     *list = item->next;
13467711d5eSMatthias Ringwald     return item;
13567711d5eSMatthias Ringwald }
13667711d5eSMatthias Ringwald 
13767711d5eSMatthias Ringwald 
1384fd23d47SMatthias Ringwald //
1394fd23d47SMatthias Ringwald // Linked List Iterator implementation
1404fd23d47SMatthias Ringwald //
1414fd23d47SMatthias Ringwald 
1428f2a52f4SMatthias Ringwald void btstack_linked_list_iterator_init(btstack_linked_list_iterator_t * it, btstack_linked_list_t * head){
1434fd23d47SMatthias Ringwald     it->advance_on_next = 0;
144665d90f2SMatthias Ringwald     it->prev = (btstack_linked_item_t*) head;
1454fd23d47SMatthias Ringwald     it->curr = * head;
1464fd23d47SMatthias Ringwald }
1474fd23d47SMatthias Ringwald 
148665d90f2SMatthias Ringwald int btstack_linked_list_iterator_has_next(btstack_linked_list_iterator_t * it){
149665d90f2SMatthias 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);
1504fd23d47SMatthias Ringwald     if (!it->advance_on_next){
1514fd23d47SMatthias Ringwald         return it->curr != NULL;
1524fd23d47SMatthias Ringwald     }
1534fd23d47SMatthias Ringwald     if (it->prev->next != it->curr){
1544fd23d47SMatthias Ringwald         // current item has been removed
1554fd23d47SMatthias Ringwald         return it->prev->next != NULL;
1564fd23d47SMatthias Ringwald     }
1574fd23d47SMatthias Ringwald     // current items has not been removed
1584fd23d47SMatthias Ringwald     return it->curr->next != NULL;
1594fd23d47SMatthias Ringwald }
1604fd23d47SMatthias Ringwald 
161665d90f2SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_iterator_next(btstack_linked_list_iterator_t * it){
1624fd23d47SMatthias Ringwald     if (it->advance_on_next){
1634fd23d47SMatthias Ringwald         if (it->prev->next == it->curr){
1644fd23d47SMatthias Ringwald             it->prev = it->curr;
1654fd23d47SMatthias Ringwald             it->curr = it->curr->next;
1664fd23d47SMatthias Ringwald         } else {
1674fd23d47SMatthias Ringwald             // curr was removed from the list, set it again but don't advance prev
1684fd23d47SMatthias Ringwald             it->curr = it->prev->next;
1694fd23d47SMatthias Ringwald         }
1704fd23d47SMatthias Ringwald     } else {
1714fd23d47SMatthias Ringwald         it->advance_on_next = 1;
1724fd23d47SMatthias Ringwald     }
1734fd23d47SMatthias Ringwald     return it->curr;
1744fd23d47SMatthias Ringwald }
1754fd23d47SMatthias Ringwald 
176665d90f2SMatthias Ringwald void btstack_linked_list_iterator_remove(btstack_linked_list_iterator_t * it){
1774fd23d47SMatthias Ringwald     it->curr = it->curr->next;
1784fd23d47SMatthias Ringwald     it->prev->next = it->curr;
1794fd23d47SMatthias Ringwald     it->advance_on_next = 0;
1804fd23d47SMatthias Ringwald }
181