xref: /btstack/src/btstack_linked_list.c (revision 8f2a52f4d99b588685740a7150f314f782cdf947)
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 
384fd23d47SMatthias Ringwald /*
394fd23d47SMatthias Ringwald  *  linked_list.c
404fd23d47SMatthias Ringwald  *
414fd23d47SMatthias Ringwald  *  Created by Matthias Ringwald on 7/13/09.
424fd23d47SMatthias Ringwald  */
434fd23d47SMatthias Ringwald 
444fd23d47SMatthias Ringwald #include "btstack_linked_list.h"
454fd23d47SMatthias Ringwald #include <stdlib.h>
464fd23d47SMatthias Ringwald #include <stdio.h>
474fd23d47SMatthias Ringwald 
484fd23d47SMatthias Ringwald /**
494fd23d47SMatthias Ringwald  * tests if list is empty
504fd23d47SMatthias Ringwald  */
51*8f2a52f4SMatthias Ringwald int  btstack_linked_list_empty(btstack_linked_list_t * list){
524fd23d47SMatthias Ringwald     return *list == (void *) 0;
534fd23d47SMatthias Ringwald }
544fd23d47SMatthias Ringwald 
554fd23d47SMatthias Ringwald /**
56665d90f2SMatthias Ringwald  * btstack_linked_list_get_last_item
574fd23d47SMatthias Ringwald  */
58*8f2a52f4SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_get_last_item(btstack_linked_list_t * list){        // <-- find the last item in the list
59665d90f2SMatthias Ringwald     btstack_linked_item_t *lastItem = NULL;
60665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
614fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
624fd23d47SMatthias Ringwald         if (it) {
634fd23d47SMatthias Ringwald             lastItem = it;
644fd23d47SMatthias Ringwald         }
654fd23d47SMatthias Ringwald     }
664fd23d47SMatthias Ringwald     return lastItem;
674fd23d47SMatthias Ringwald }
684fd23d47SMatthias Ringwald 
694fd23d47SMatthias Ringwald 
704fd23d47SMatthias Ringwald /**
71665d90f2SMatthias Ringwald  * btstack_linked_list_add
724fd23d47SMatthias Ringwald  */
73*8f2a52f4SMatthias Ringwald void btstack_linked_list_add(btstack_linked_list_t * list, btstack_linked_item_t *item){        // <-- add item to list
744fd23d47SMatthias Ringwald     // check if already in list
75665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
764fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
774fd23d47SMatthias Ringwald         if (it == item) {
784fd23d47SMatthias Ringwald             return;
794fd23d47SMatthias Ringwald         }
804fd23d47SMatthias Ringwald     }
814fd23d47SMatthias Ringwald     // add first
824fd23d47SMatthias Ringwald     item->next = *list;
834fd23d47SMatthias Ringwald     *list = item;
844fd23d47SMatthias Ringwald }
854fd23d47SMatthias Ringwald 
86*8f2a52f4SMatthias Ringwald void btstack_linked_list_add_tail(btstack_linked_list_t * list, btstack_linked_item_t *item){   // <-- add item to list as last element
874fd23d47SMatthias Ringwald     // check if already in list
88665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
89665d90f2SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it->next ; it = it->next){
904fd23d47SMatthias Ringwald         if (it->next == item) {
914fd23d47SMatthias Ringwald             return;
924fd23d47SMatthias Ringwald         }
934fd23d47SMatthias Ringwald     }
94665d90f2SMatthias Ringwald     item->next = (btstack_linked_item_t*) 0;
954fd23d47SMatthias Ringwald     it->next = item;
964fd23d47SMatthias Ringwald }
974fd23d47SMatthias Ringwald 
984fd23d47SMatthias Ringwald /**
994fd23d47SMatthias Ringwald  * Remove data_source from run loop
1004fd23d47SMatthias Ringwald  *
1014fd23d47SMatthias Ringwald  * @note: assumes that data_source_t.next is first element in data_source
1024fd23d47SMatthias Ringwald  */
103*8f2a52f4SMatthias Ringwald int  btstack_linked_list_remove(btstack_linked_list_t * list, btstack_linked_item_t *item){    // <-- remove item from list
1044fd23d47SMatthias Ringwald     if (!item) return -1;
105665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
106665d90f2SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it ; it = it->next){
1074fd23d47SMatthias Ringwald         if (it->next == item){
1084fd23d47SMatthias Ringwald             it->next =  item->next;
1094fd23d47SMatthias Ringwald             return 0;
1104fd23d47SMatthias Ringwald         }
1114fd23d47SMatthias Ringwald     }
1124fd23d47SMatthias Ringwald     return -1;
1134fd23d47SMatthias Ringwald }
1144fd23d47SMatthias Ringwald 
1154fd23d47SMatthias Ringwald /**
1164fd23d47SMatthias Ringwald  * @returns number of items in list
1174fd23d47SMatthias Ringwald  */
118*8f2a52f4SMatthias Ringwald  int btstack_linked_list_count(btstack_linked_list_t * list){
119665d90f2SMatthias Ringwald     btstack_linked_item_t *it;
1204fd23d47SMatthias Ringwald     int counter = 0;
121665d90f2SMatthias Ringwald     for (it = (btstack_linked_item_t *) list; it ; it = it->next) {
1224fd23d47SMatthias Ringwald         counter++;
1234fd23d47SMatthias Ringwald     }
1244fd23d47SMatthias Ringwald     return counter;
1254fd23d47SMatthias Ringwald }
1264fd23d47SMatthias Ringwald 
1274fd23d47SMatthias Ringwald 
128665d90f2SMatthias Ringwald void btstack_linked_item_set_user(btstack_linked_item_t *item, void *user_data){
129665d90f2SMatthias Ringwald     item->next = (btstack_linked_item_t *) 0;
1304fd23d47SMatthias Ringwald     item->user_data = user_data;
1314fd23d47SMatthias Ringwald }
1324fd23d47SMatthias Ringwald 
133665d90f2SMatthias Ringwald void * btstack_linked_item_get_user(btstack_linked_item_t *item) {
1344fd23d47SMatthias Ringwald     return item->user_data;
1354fd23d47SMatthias Ringwald }
1364fd23d47SMatthias Ringwald 
1374fd23d47SMatthias Ringwald //
1384fd23d47SMatthias Ringwald // Linked List Iterator implementation
1394fd23d47SMatthias Ringwald //
1404fd23d47SMatthias Ringwald 
141*8f2a52f4SMatthias Ringwald void btstack_linked_list_iterator_init(btstack_linked_list_iterator_t * it, btstack_linked_list_t * head){
1424fd23d47SMatthias Ringwald     it->advance_on_next = 0;
143665d90f2SMatthias Ringwald     it->prev = (btstack_linked_item_t*) head;
1444fd23d47SMatthias Ringwald     it->curr = * head;
1454fd23d47SMatthias Ringwald }
1464fd23d47SMatthias Ringwald 
147665d90f2SMatthias Ringwald int btstack_linked_list_iterator_has_next(btstack_linked_list_iterator_t * it){
148665d90f2SMatthias 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);
1494fd23d47SMatthias Ringwald     if (!it->advance_on_next){
1504fd23d47SMatthias Ringwald         return it->curr != NULL;
1514fd23d47SMatthias Ringwald     }
1524fd23d47SMatthias Ringwald     if (it->prev->next != it->curr){
1534fd23d47SMatthias Ringwald         // current item has been removed
1544fd23d47SMatthias Ringwald         return it->prev->next != NULL;
1554fd23d47SMatthias Ringwald     }
1564fd23d47SMatthias Ringwald     // current items has not been removed
1574fd23d47SMatthias Ringwald     return it->curr->next != NULL;
1584fd23d47SMatthias Ringwald }
1594fd23d47SMatthias Ringwald 
160665d90f2SMatthias Ringwald btstack_linked_item_t * btstack_linked_list_iterator_next(btstack_linked_list_iterator_t * it){
1614fd23d47SMatthias Ringwald     if (it->advance_on_next){
1624fd23d47SMatthias Ringwald         if (it->prev->next == it->curr){
1634fd23d47SMatthias Ringwald             it->prev = it->curr;
1644fd23d47SMatthias Ringwald             it->curr = it->curr->next;
1654fd23d47SMatthias Ringwald         } else {
1664fd23d47SMatthias Ringwald             // curr was removed from the list, set it again but don't advance prev
1674fd23d47SMatthias Ringwald             it->curr = it->prev->next;
1684fd23d47SMatthias Ringwald         }
1694fd23d47SMatthias Ringwald     } else {
1704fd23d47SMatthias Ringwald         it->advance_on_next = 1;
1714fd23d47SMatthias Ringwald     }
1724fd23d47SMatthias Ringwald     return it->curr;
1734fd23d47SMatthias Ringwald }
1744fd23d47SMatthias Ringwald 
175665d90f2SMatthias Ringwald void btstack_linked_list_iterator_remove(btstack_linked_list_iterator_t * it){
1764fd23d47SMatthias Ringwald     it->curr = it->curr->next;
1774fd23d47SMatthias Ringwald     it->prev->next = it->curr;
1784fd23d47SMatthias Ringwald     it->advance_on_next = 0;
1794fd23d47SMatthias Ringwald }
180