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 #include <stdlib.h> 494fd23d47SMatthias Ringwald #include <stdio.h> 504fd23d47SMatthias Ringwald 514fd23d47SMatthias Ringwald /** 524fd23d47SMatthias Ringwald * tests if list is empty 534fd23d47SMatthias Ringwald */ 54*8b2bf72fSMatthias 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 */ 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; 644fd23d47SMatthias Ringwald for (it = *list; it ; it = it->next){ 654fd23d47SMatthias Ringwald if (it) { 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 */ 768f2a52f4SMatthias Ringwald void 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; 794fd23d47SMatthias Ringwald for (it = *list; it ; it = it->next){ 804fd23d47SMatthias Ringwald if (it == item) { 814fd23d47SMatthias Ringwald return; 824fd23d47SMatthias Ringwald } 834fd23d47SMatthias Ringwald } 844fd23d47SMatthias Ringwald // add first 854fd23d47SMatthias Ringwald item->next = *list; 864fd23d47SMatthias Ringwald *list = item; 874fd23d47SMatthias Ringwald } 884fd23d47SMatthias Ringwald 898f2a52f4SMatthias Ringwald void btstack_linked_list_add_tail(btstack_linked_list_t * list, btstack_linked_item_t *item){ // <-- add item to list as last element 904fd23d47SMatthias Ringwald // check if already in list 91665d90f2SMatthias Ringwald btstack_linked_item_t *it; 92665d90f2SMatthias Ringwald for (it = (btstack_linked_item_t *) list; it->next ; it = it->next){ 934fd23d47SMatthias Ringwald if (it->next == item) { 944fd23d47SMatthias Ringwald return; 954fd23d47SMatthias Ringwald } 964fd23d47SMatthias Ringwald } 97665d90f2SMatthias Ringwald item->next = (btstack_linked_item_t*) 0; 984fd23d47SMatthias Ringwald it->next = item; 994fd23d47SMatthias Ringwald } 1004fd23d47SMatthias Ringwald 1018f2a52f4SMatthias Ringwald int btstack_linked_list_remove(btstack_linked_list_t * list, btstack_linked_item_t *item){ // <-- remove item from list 1024fd23d47SMatthias Ringwald if (!item) return -1; 103665d90f2SMatthias Ringwald btstack_linked_item_t *it; 104665d90f2SMatthias Ringwald for (it = (btstack_linked_item_t *) list; it ; it = it->next){ 1054fd23d47SMatthias Ringwald if (it->next == item){ 1064fd23d47SMatthias Ringwald it->next = item->next; 1074fd23d47SMatthias Ringwald return 0; 1084fd23d47SMatthias Ringwald } 1094fd23d47SMatthias Ringwald } 1104fd23d47SMatthias Ringwald return -1; 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; 119a2908aa0SMatthias Ringwald for (it = (btstack_linked_item_t *) list; it->next ; 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 149*8b2bf72fSMatthias 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){ 17886bcddecSMatthias Ringwald if (it->prev->next != it->curr){ 17986bcddecSMatthias Ringwald log_error("prev item %p does not point to curr %p", it->prev, it->curr); 18086bcddecSMatthias Ringwald } 181f8b1697fSMatthias Ringwald it->curr = it->curr->next; 1824fd23d47SMatthias Ringwald it->prev->next = it->curr; 1834fd23d47SMatthias Ringwald it->advance_on_next = 0; 1844fd23d47SMatthias Ringwald } 185