5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2003 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
25 /****h* silcutil/SILC Dynamic List Interface
29 * SILC Dynamic List API can be used to add opaque contexts to list that
30 * will automatically allocate list entries. Normal SILC List API cannot
31 * be used for this purpose because in that case the context passed to the
32 * list must be defined as list structure already. This is not the case in
35 * This is slower than SilcList because this requires one extra memory
36 * allocation when adding new entries to the list. The context is probably
37 * allocated already and the new list entry requires one additional memory
38 * allocation. The memory allocation and freeing is done automatically in
39 * the API and does not show to the caller.
43 /****s* silcutil/SilcDListAPI/SilcDList
47 * typedef struct { ... } *SilcDList;
51 * This is the actual SilcDList object that is used by application.
52 * Application defines this object and adds contexts to this list with
53 * Dynamic List Interface functions.
57 typedef struct SilcDListStruct {
62 /* SilcDListEntry structure, one entry in the list. This MUST NOT be used
63 directly by the application. */
64 typedef struct SilcDListEntryStruct {
66 struct SilcDListEntryStruct *next;
67 struct SilcDListEntryStruct *prev;
70 /****f* silcutil/SilcDListAPI/silc_dlist_init
75 * SilcDList silc_dlist_init(void);
79 * Initializes SilcDList.
84 SilcDList silc_dlist_init(void)
88 list = (SilcDList)silc_malloc(sizeof(*list));
91 silc_list_init_prev(list->list, struct SilcDListEntryStruct, next, prev);
96 /****f* silcutil/SilcDListAPI/silc_dlist_uninit
101 * void silc_dlist_uninit(SilcDList list);
105 * Uninits and frees all memory. Must be called to free memory. Does NOT
106 * free the contexts saved by caller.
111 void silc_dlist_uninit(SilcDList list)
115 silc_list_start(list->list);
116 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
117 silc_list_del(list->list, e);
124 /****f* silcutil/SilcDListAPI/silc_dlist_count
129 * int silc_dlist_count(SilcDList list);
133 * Return the number of entries in the list.
138 int silc_dlist_count(SilcDList list)
140 return silc_list_count(list->list);
143 /****f* silcutil/SilcDListAPI/silc_dlist_start
148 * void silc_dlist_start(SilcDList list);
152 * Set the start of the list. This prepares the list for traversing entries
153 * from the start of the list towards end of the list.
158 void silc_dlist_start(SilcDList list)
160 silc_list_start(list->list);
163 /****f* silcutil/SilcDListAPI/silc_dlist_end
168 * void silc_dlist_end(SilcDList list);
172 * Set the end of the list. This prepares the list for traversing entries
173 * from the end of the list towards start of the list.
178 void silc_dlist_end(SilcDList list)
180 silc_list_end(list->list);
183 /****f* silcutil/SilcDListAPI/silc_dlist_add
188 * void silc_dlist_add(SilcDList list, void *context);
192 * Adds new entry to the list. This is the default function to add new
193 * entries to the list.
198 void silc_dlist_add(SilcDList list, void *context)
200 SilcDListEntry e = (SilcDListEntry)silc_malloc(sizeof(*e));
203 e->context = context;
204 silc_list_add(list->list, e);
207 /****f* silcutil/SilcDListAPI/silc_dlist_del
212 * void silc_dlist_del(SilcDList list, void *context);
216 * Remove entry from the list. Returns < 0 on error, 0 otherwise.
221 void silc_dlist_del(SilcDList list, void *context)
225 silc_list_start(list->list);
226 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
227 if (e->context == context) {
228 silc_list_del(list->list, e);
229 #if defined(SILC_DEBUG)
230 memset(e, 'F', sizeof(*e));
238 /****f* silcutil/SilcDListAPI/silc_dlist_get
243 * void *silc_dlist_get(SilcDList list);
247 * Returns current entry from the list and moves the list pointer forward
248 * so that calling this next time returns the next entry from the list.
249 * This can be used to traverse the list. Return SILC_LIST_END when the
250 * entire list has been traversed. Later, silc_list_start (or
251 * silc_dlist_end) must be called again when re-starting list traversing.
255 * // Traverse the list from the beginning to the end
256 * silc_dlist_start(list)
257 * while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
264 void *silc_dlist_get(SilcDList list)
266 SilcDListEntry e = (SilcDListEntry)silc_list_get(list->list);
267 if (e != SILC_LIST_END)
269 return SILC_LIST_END;