xref: /btstack/src/btstack_linked_list.c (revision 4fd23d473838d04835bc511e0b2828d1d21a6b1e)
1*4fd23d47SMatthias Ringwald /*
2*4fd23d47SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*4fd23d47SMatthias Ringwald  *
4*4fd23d47SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*4fd23d47SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*4fd23d47SMatthias Ringwald  * are met:
7*4fd23d47SMatthias Ringwald  *
8*4fd23d47SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*4fd23d47SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*4fd23d47SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*4fd23d47SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*4fd23d47SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*4fd23d47SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*4fd23d47SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*4fd23d47SMatthias Ringwald  *    from this software without specific prior written permission.
16*4fd23d47SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*4fd23d47SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*4fd23d47SMatthias Ringwald  *    monetary gain.
19*4fd23d47SMatthias Ringwald  *
20*4fd23d47SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*4fd23d47SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*4fd23d47SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*4fd23d47SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*4fd23d47SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*4fd23d47SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*4fd23d47SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*4fd23d47SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*4fd23d47SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*4fd23d47SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*4fd23d47SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*4fd23d47SMatthias Ringwald  * SUCH DAMAGE.
32*4fd23d47SMatthias Ringwald  *
33*4fd23d47SMatthias Ringwald  * Please inquire about commercial licensing options at
34*4fd23d47SMatthias Ringwald  * [email protected]
35*4fd23d47SMatthias Ringwald  *
36*4fd23d47SMatthias Ringwald  */
37*4fd23d47SMatthias Ringwald 
38*4fd23d47SMatthias Ringwald /*
39*4fd23d47SMatthias Ringwald  *  linked_list.c
40*4fd23d47SMatthias Ringwald  *
41*4fd23d47SMatthias Ringwald  *  Created by Matthias Ringwald on 7/13/09.
42*4fd23d47SMatthias Ringwald  */
43*4fd23d47SMatthias Ringwald 
44*4fd23d47SMatthias Ringwald #include "btstack_linked_list.h"
45*4fd23d47SMatthias Ringwald #include <stdlib.h>
46*4fd23d47SMatthias Ringwald #include <stdio.h>
47*4fd23d47SMatthias Ringwald 
48*4fd23d47SMatthias Ringwald /**
49*4fd23d47SMatthias Ringwald  * tests if list is empty
50*4fd23d47SMatthias Ringwald  */
51*4fd23d47SMatthias Ringwald int  linked_list_empty(bk_linked_list_t * list){
52*4fd23d47SMatthias Ringwald     return *list == (void *) 0;
53*4fd23d47SMatthias Ringwald }
54*4fd23d47SMatthias Ringwald 
55*4fd23d47SMatthias Ringwald /**
56*4fd23d47SMatthias Ringwald  * linked_list_get_last_item
57*4fd23d47SMatthias Ringwald  */
58*4fd23d47SMatthias Ringwald linked_item_t * linked_list_get_last_item(bk_linked_list_t * list){        // <-- find the last item in the list
59*4fd23d47SMatthias Ringwald     linked_item_t *lastItem = NULL;
60*4fd23d47SMatthias Ringwald     linked_item_t *it;
61*4fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
62*4fd23d47SMatthias Ringwald         if (it) {
63*4fd23d47SMatthias Ringwald             lastItem = it;
64*4fd23d47SMatthias Ringwald         }
65*4fd23d47SMatthias Ringwald     }
66*4fd23d47SMatthias Ringwald     return lastItem;
67*4fd23d47SMatthias Ringwald }
68*4fd23d47SMatthias Ringwald 
69*4fd23d47SMatthias Ringwald 
70*4fd23d47SMatthias Ringwald /**
71*4fd23d47SMatthias Ringwald  * linked_list_add
72*4fd23d47SMatthias Ringwald  */
73*4fd23d47SMatthias Ringwald void linked_list_add(bk_linked_list_t * list, linked_item_t *item){        // <-- add item to list
74*4fd23d47SMatthias Ringwald     // check if already in list
75*4fd23d47SMatthias Ringwald     linked_item_t *it;
76*4fd23d47SMatthias Ringwald     for (it = *list; it ; it = it->next){
77*4fd23d47SMatthias Ringwald         if (it == item) {
78*4fd23d47SMatthias Ringwald             return;
79*4fd23d47SMatthias Ringwald         }
80*4fd23d47SMatthias Ringwald     }
81*4fd23d47SMatthias Ringwald     // add first
82*4fd23d47SMatthias Ringwald     item->next = *list;
83*4fd23d47SMatthias Ringwald     *list = item;
84*4fd23d47SMatthias Ringwald }
85*4fd23d47SMatthias Ringwald 
86*4fd23d47SMatthias Ringwald void linked_list_add_tail(bk_linked_list_t * list, linked_item_t *item){   // <-- add item to list as last element
87*4fd23d47SMatthias Ringwald     // check if already in list
88*4fd23d47SMatthias Ringwald     linked_item_t *it;
89*4fd23d47SMatthias Ringwald     for (it = (linked_item_t *) list; it->next ; it = it->next){
90*4fd23d47SMatthias Ringwald         if (it->next == item) {
91*4fd23d47SMatthias Ringwald             return;
92*4fd23d47SMatthias Ringwald         }
93*4fd23d47SMatthias Ringwald     }
94*4fd23d47SMatthias Ringwald     item->next = (linked_item_t*) 0;
95*4fd23d47SMatthias Ringwald     it->next = item;
96*4fd23d47SMatthias Ringwald }
97*4fd23d47SMatthias Ringwald 
98*4fd23d47SMatthias Ringwald /**
99*4fd23d47SMatthias Ringwald  * Remove data_source from run loop
100*4fd23d47SMatthias Ringwald  *
101*4fd23d47SMatthias Ringwald  * @note: assumes that data_source_t.next is first element in data_source
102*4fd23d47SMatthias Ringwald  */
103*4fd23d47SMatthias Ringwald int  linked_list_remove(bk_linked_list_t * list, linked_item_t *item){    // <-- remove item from list
104*4fd23d47SMatthias Ringwald     if (!item) return -1;
105*4fd23d47SMatthias Ringwald     linked_item_t *it;
106*4fd23d47SMatthias Ringwald     for (it = (linked_item_t *) list; it ; it = it->next){
107*4fd23d47SMatthias Ringwald         if (it->next == item){
108*4fd23d47SMatthias Ringwald             it->next =  item->next;
109*4fd23d47SMatthias Ringwald             return 0;
110*4fd23d47SMatthias Ringwald         }
111*4fd23d47SMatthias Ringwald     }
112*4fd23d47SMatthias Ringwald     return -1;
113*4fd23d47SMatthias Ringwald }
114*4fd23d47SMatthias Ringwald 
115*4fd23d47SMatthias Ringwald /**
116*4fd23d47SMatthias Ringwald  * @returns number of items in list
117*4fd23d47SMatthias Ringwald  */
118*4fd23d47SMatthias Ringwald  int linked_list_count(bk_linked_list_t * list){
119*4fd23d47SMatthias Ringwald     linked_item_t *it;
120*4fd23d47SMatthias Ringwald     int counter = 0;
121*4fd23d47SMatthias Ringwald     for (it = (linked_item_t *) list; it ; it = it->next) {
122*4fd23d47SMatthias Ringwald         counter++;
123*4fd23d47SMatthias Ringwald     }
124*4fd23d47SMatthias Ringwald     return counter;
125*4fd23d47SMatthias Ringwald }
126*4fd23d47SMatthias Ringwald 
127*4fd23d47SMatthias Ringwald 
128*4fd23d47SMatthias Ringwald void linked_item_set_user(linked_item_t *item, void *user_data){
129*4fd23d47SMatthias Ringwald     item->next = (linked_item_t *) 0;
130*4fd23d47SMatthias Ringwald     item->user_data = user_data;
131*4fd23d47SMatthias Ringwald }
132*4fd23d47SMatthias Ringwald 
133*4fd23d47SMatthias Ringwald void * linked_item_get_user(linked_item_t *item) {
134*4fd23d47SMatthias Ringwald     return item->user_data;
135*4fd23d47SMatthias Ringwald }
136*4fd23d47SMatthias Ringwald 
137*4fd23d47SMatthias Ringwald //
138*4fd23d47SMatthias Ringwald // Linked List Iterator implementation
139*4fd23d47SMatthias Ringwald //
140*4fd23d47SMatthias Ringwald 
141*4fd23d47SMatthias Ringwald void linked_list_iterator_init(linked_list_iterator_t * it, bk_linked_list_t * head){
142*4fd23d47SMatthias Ringwald     it->advance_on_next = 0;
143*4fd23d47SMatthias Ringwald     it->prev = (linked_item_t*) head;
144*4fd23d47SMatthias Ringwald     it->curr = * head;
145*4fd23d47SMatthias Ringwald }
146*4fd23d47SMatthias Ringwald 
147*4fd23d47SMatthias Ringwald int linked_list_iterator_has_next(linked_list_iterator_t * it){
148*4fd23d47SMatthias Ringwald     // log_info("linked_list_iterator_has_next: advance on next %u, it->prev %p, it->curr %p", it->advance_on_next, it->prev, it->curr);
149*4fd23d47SMatthias Ringwald     if (!it->advance_on_next){
150*4fd23d47SMatthias Ringwald         return it->curr != NULL;
151*4fd23d47SMatthias Ringwald     }
152*4fd23d47SMatthias Ringwald     if (it->prev->next != it->curr){
153*4fd23d47SMatthias Ringwald         // current item has been removed
154*4fd23d47SMatthias Ringwald         return it->prev->next != NULL;
155*4fd23d47SMatthias Ringwald     }
156*4fd23d47SMatthias Ringwald     // current items has not been removed
157*4fd23d47SMatthias Ringwald     return it->curr->next != NULL;
158*4fd23d47SMatthias Ringwald }
159*4fd23d47SMatthias Ringwald 
160*4fd23d47SMatthias Ringwald linked_item_t * linked_list_iterator_next(linked_list_iterator_t * it){
161*4fd23d47SMatthias Ringwald     if (it->advance_on_next){
162*4fd23d47SMatthias Ringwald         if (it->prev->next == it->curr){
163*4fd23d47SMatthias Ringwald             it->prev = it->curr;
164*4fd23d47SMatthias Ringwald             it->curr = it->curr->next;
165*4fd23d47SMatthias Ringwald         } else {
166*4fd23d47SMatthias Ringwald             // curr was removed from the list, set it again but don't advance prev
167*4fd23d47SMatthias Ringwald             it->curr = it->prev->next;
168*4fd23d47SMatthias Ringwald         }
169*4fd23d47SMatthias Ringwald     } else {
170*4fd23d47SMatthias Ringwald         it->advance_on_next = 1;
171*4fd23d47SMatthias Ringwald     }
172*4fd23d47SMatthias Ringwald     return it->curr;
173*4fd23d47SMatthias Ringwald }
174*4fd23d47SMatthias Ringwald 
175*4fd23d47SMatthias Ringwald void linked_list_iterator_remove(linked_list_iterator_t * it){
176*4fd23d47SMatthias Ringwald     it->curr = it->curr->next;
177*4fd23d47SMatthias Ringwald     it->prev->next = it->curr;
178*4fd23d47SMatthias Ringwald     it->advance_on_next = 0;
179*4fd23d47SMatthias Ringwald }
180