1 /*
2     $Id: ll.c,v 1.1 2005/05/29 08:24:05 airborne Exp $
3 
4     Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be>
5 
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10 
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15 
16     You should have received a copy of the GNU Library General Public
17     License along with this library; if not, write to the
18     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19     Boston, MA  02111-1307, USA.
20 */
21 
22 
23 #include <stdlib.h>
24 
25 #include "cddb/ll.h"
26 
27 
28 /* --- type and structure definitions */
29 
30 
31 /**
32  * Linked list element.
33  */
34 struct elem_s {
35     struct elem_s *prev;        /**< previous element */
36     struct elem_s *next;        /**< next element  */
37     void *data;                 /**< the actual data of the element */
38 };
39 
40 struct list_s {
41     int cnt;                    /**< number of elements in the list */
42     elem_destroy_cb *free_data; /**< callback used to free element data */
43     elem_t *first;              /**< the first element in the list  */
44     elem_t *last;               /**< the last element in the list  */
45     elem_t *it;                 /**< iterator element */
46 };
47 
48 
49 /* --- private prototypes */
50 
51 
52 static elem_t *elem_construct(void *data);
53 
54 /**
55  * @return The next element.
56  */
57 static elem_t *elem_destroy(elem_t *elem, elem_destroy_cb *cb);
58 
59 
60 /* --- private functions */
61 
62 
elem_construct(void * data)63 static elem_t *elem_construct(void *data)
64 {
65     elem_t *elem;
66 
67     elem = (elem_t*)calloc(1, sizeof(elem_t));
68     elem->data = data;
69     return elem;
70 }
71 
elem_destroy(elem_t * elem,elem_destroy_cb * cb)72 static elem_t *elem_destroy(elem_t *elem, elem_destroy_cb *cb)
73 {
74     elem_t *next = NULL;
75 
76     if (elem) {
77         next = elem->next;
78         if (cb) {
79             cb(elem->data);
80         }
81         free(elem);
82     }
83     return next;
84 }
85 
86 
87 /* --- construction / destruction */
88 
89 
list_new(elem_destroy_cb * cb)90 list_t *list_new(elem_destroy_cb *cb)
91 {
92     list_t *list;
93 
94     list = (list_t*)calloc(1, sizeof(list_t));
95     list->free_data = cb;
96     return list;
97 }
98 
list_destroy(list_t * list)99 void list_destroy(list_t *list)
100 {
101     list_flush(list);
102     if (list) {
103         free(list);
104     }
105 }
106 
list_flush(list_t * list)107 void list_flush(list_t *list)
108 {
109     elem_t *elem;
110 
111     if (list) {
112         elem = list->first;
113         while (elem) {
114             elem = elem_destroy(elem, list->free_data);
115         }
116         list->first = list->last = NULL;
117         list->cnt = 0;
118     }
119 }
120 
121 
122 /* --- list elements --- */
123 
124 
element_data(elem_t * elem)125 void *element_data(elem_t *elem)
126 {
127     if (elem) {
128         return elem->data;
129     }
130     return NULL;
131 }
132 
133 
134 /* --- getters & setters --- */
135 
136 
list_append(list_t * list,void * data)137 elem_t *list_append(list_t *list, void *data)
138 {
139     elem_t *elem = NULL;
140 
141     if (list) {
142         elem = elem_construct(data);
143         if (elem) {
144             if (list->cnt == 0) {
145                 list->first = list->last = elem;
146             } else {
147                 list->last->next = elem;
148                 elem->prev = list->last;
149                 list->last = elem;
150             }
151             list->cnt++;
152         }
153     }
154     return elem;
155 }
156 
list_size(list_t * list)157 int list_size(list_t *list)
158 {
159     if (list) {
160         return list->cnt;
161     }
162     return 0;
163 }
164 
list_get(list_t * list,int idx)165 elem_t *list_get(list_t *list, int idx)
166 {
167     elem_t *elem = NULL;
168 
169     if (list) {
170         if ((idx >= 0) && (idx < list->cnt)) {
171             elem = list->first;
172             while (idx) {
173                 elem = elem->next;
174                 idx--;
175             }
176         }
177     }
178     return elem;
179 }
180 
list_first(list_t * list)181 elem_t *list_first(list_t *list)
182 {
183     if (list) {
184         list->it = list->first;
185         return list->it;
186     }
187     return NULL;
188 }
189 
list_next(list_t * list)190 elem_t *list_next(list_t *list)
191 {
192     if (list) {
193         if (list->it) {
194             list->it = list->it->next;
195         }
196         return list->it;
197     }
198     return NULL;
199 }
200 
201 
202 /* --- iteration */
203