source: trunk/module-datastruct-llist.c@ 4149

Last change on this file since 4149 was 4066, checked in by schlocke, 13 years ago

cccam: fixed dup cards check

File size: 3.7 KB
Line 
1
2/* singularly linked-list */
3
4#include <stdlib.h>
5
6#include "globals.h"
7#include "module-datastruct-llist.h"
8
9static void _destroy(LLIST *l)
10{
11 if (!l) return;
12 pthread_mutex_unlock(&l->lock);
13 pthread_mutex_destroy(&l->lock);
14
15 NULLFREE(l);
16}
17
18LLIST *ll_create()
19{
20 LLIST *l = calloc(1, sizeof(LLIST));
21
22 pthread_mutex_init(&l->lock, NULL);
23
24 return l;
25}
26
27void ll_destroy(LLIST *l)
28{
29 if (!l) return;
30 ll_clear(l);
31
32 _destroy(l);
33}
34
35void ll_destroy_data(LLIST *l)
36{
37 if (!l) return;
38 ll_clear_data(l);
39
40 _destroy(l);
41}
42
43void ll_clear(LLIST *l)
44{
45 void *obj;
46
47 LL_ITER *it = ll_iter_create(l);
48 while ((obj = ll_iter_next(it)))
49 ll_iter_remove(it);
50 ll_iter_release(it);
51}
52
53void ll_clear_data(LLIST *l)
54{
55 void *obj;
56
57 LL_ITER *it = ll_iter_create(l);
58 while ((obj = ll_iter_next(it)))
59 ll_iter_remove_data(it);
60 ll_iter_release(it);
61}
62
63void ll_append(LLIST *l, void *obj)
64{
65 if (obj) {
66 LL_NODE *new = calloc(1, sizeof(LL_NODE));
67 LL_NODE *n = l->initial;
68
69 new->obj = obj;
70
71 if (n) {
72 while (n->nxt) n = n->nxt;
73 n->nxt = new;
74 new->prv = n;
75 } else
76 l->initial = new;
77 }
78}
79
80LL_ITER *ll_iter_create(LLIST *l)
81{
82 LL_ITER *it = malloc(sizeof(LL_ITER));
83
84 it->l = l;
85 if (l) {
86 it->cur = l->initial;
87 pthread_mutex_lock(&l->lock);
88 }
89 else
90 it->cur = NULL;
91
92
93 return it;
94}
95
96void ll_iter_release(LL_ITER *it)
97{
98 if(it->l)
99 pthread_mutex_unlock(&it->l->lock);
100
101 NULLFREE(it);
102}
103
104void *ll_iter_next(LL_ITER *it)
105{
106 if (it) {
107 if (it->cur) {
108 void *obj = it->cur->obj;
109
110 it->cur = it->cur->nxt;
111
112 return obj;
113 }
114 }
115
116 return NULL;
117}
118
119void *ll_iter_peek(LL_ITER *it, int offset)
120{
121 LL_NODE *n = it->cur;
122 int i;
123
124 for (i = 0; i < offset; i++)
125 if (n)
126 n = n->nxt;
127 else
128 return NULL;
129
130 if (!n)
131 return NULL;
132
133 return n->obj;
134}
135
136void ll_iter_reset(LL_ITER *it)
137{
138 it->cur = it->l->initial;
139}
140
141void ll_iter_insert(LL_ITER *it, void *obj)
142{
143 if(obj) {
144 LL_NODE *n = calloc(1, sizeof(LL_NODE));
145 n->obj = obj;
146 n->nxt = it->cur;
147 n->prv = it->cur->prv;
148
149 it->cur->prv->nxt = n;
150 it->cur->prv = n;
151 }
152}
153
154void *ll_iter_remove(LL_ITER *it)
155{
156 if (it) {
157 LL_NODE *n;
158
159 // if is last node, handle differently
160 if (!it->cur && it->l->initial) {
161 n = it->l->initial;
162 while (n->nxt) n = n->nxt;
163 } else
164 n = it->cur->prv;
165
166 if (n) {
167 void *obj = n->obj;
168 if (n->nxt) n->nxt->prv = n->prv;
169 if (n->prv) n->prv->nxt = n->nxt;
170 else it->l->initial = n->nxt;
171
172 NULLFREE(n);
173 return obj;
174 }
175 }
176
177 return NULL;
178}
179
180void ll_iter_remove_data(LL_ITER *it)
181{
182 void *obj = ll_iter_remove(it);
183 NULLFREE(obj);
184}
185
186int ll_count(LLIST *l)
187{
188 void *obj;
189 int c = 0;
190
191 LL_ITER *it = ll_iter_create(l);;
192 while ((obj = ll_iter_next(it))) c++;
193 ll_iter_release(it);
194
195 return c;
196}
197
198void ll_insert_at(LLIST *l, void *obj, int pos)
199{
200 LL_NODE *new = calloc(1, sizeof(LL_NODE));
201 LL_NODE *n = l->initial;
202 int i;
203
204 for (i = 0; i < pos; i++)
205 if (n)
206 n = n->nxt;
207 else
208 break;
209
210 new->obj = obj;
211 new->nxt = n;
212
213 if (n && n->prv) n->prv->nxt = new;
214 else l->initial = new;
215
216 if (n) n->prv = new;
217}
218
219//Returns first object if there is one
220void *ll_has_elements(LLIST *l) {
221 if (!l || !l->initial)
222 return NULL;
223 return l->initial->obj;
224}
225
Note: See TracBrowser for help on using the repository browser.