5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 2000 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
26 /****h* silcutil/SILC Dynamic List Interface
30 * SILC Dynamic List API can be used to add opaque contexts to list that
31 * will automatically allocate list entries. Normal SILC List API cannot
32 * be used for this purpose because in that case the context passed to the
33 * list must be defined as list structure already. This is not the case in
36 * This is slower than SilcList because this requires one extra memory
37 * allocation when adding new entries to the list. The context is probably
38 * allocated already and the new list entry requires one additional memory
39 * allocation. The memory allocation and freeing is done automatically in
40 * the API and does not show to the caller.
44 /****s* silcutil/SilcDListAPI/SilcDList
48 * typedef struct { ... } *SilcDList;
52 * This is the actual SilcDList object that is used by application.
53 * Application defines this object and adds contexts to this list with
54 * Dynamic List Interface functions.
63 /* SilcDListEntry structure, one entry in the list. This MUST NOT be used
64 directly by the application. */
65 typedef struct SilcDListEntryStruct {
67 struct SilcDListEntryStruct *next;
70 /****f* silcutil/SilcDListAPI/silc_dlist_init
75 * SilcDList silc_dlist_init();
79 * Initializes SilcDList.
84 SilcDList silc_dlist_init()
88 list = (SilcDList)silc_calloc(1, sizeof(*list));
89 silc_list_init(list->list, struct SilcDListEntryStruct, next);
94 /****f* silcutil/SilcDListAPI/silc_dlist_uninit
99 * void silc_dlist_uninit(SilcDList list);
103 * Uninits and frees all memory. Must be called to free memory. Does NOT
104 * free the contexts saved by caller.
109 void silc_dlist_uninit(SilcDList list)
113 silc_list_start(list->list);
114 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
115 silc_list_del(list->list, e);
122 /****f* silcutil/SilcDListAPI/silc_dlist_count
127 * int silc_dlist_count(SilcDList list);
131 * Return the number of entries in the list.
136 int silc_dlist_count(SilcDList list)
138 return silc_list_count(list->list);
141 /****f* silcutil/SilcDListAPI/silc_dlist_start
146 * void silc_dlist_start(SilcDList list);
150 * Set the start of the list. This prepares the list for traversing entries
151 * from the start of the list.
156 void silc_dlist_start(SilcDList list)
158 silc_list_start(list->list);
161 /****f* silcutil/SilcDListAPI/silc_dlist_add
166 * void silc_dlist_add(SilcDList list, void *context);
170 * Adds new entry to the list. This is the default function to add new
171 * entries to the list.
176 void silc_dlist_add(SilcDList list, void *context)
178 SilcDListEntry e = (SilcDListEntry)silc_calloc(1, sizeof(*e));
179 e->context = context;
180 silc_list_add(list->list, e);
183 /****f* silcutil/SilcDListAPI/silc_dlist_del
188 * void silc_dlist_del(SilcDList list, void *context);
192 * Remove entry from the list. Returns < 0 on error, 0 otherwise.
197 void silc_dlist_del(SilcDList list, void *context)
201 silc_list_start(list->list);
202 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
203 if (e->context == context) {
204 silc_list_del(list->list, e);
205 #if defined(SILC_DEBUG)
206 memset(e, 'F', sizeof(*e));
214 /****f* silcutil/SilcDListAPI/silc_dlist_get
219 * void *silc_dlist_get(SilcDList list);
223 * Returns current entry from the list and moves the list pointer forward
224 * so that calling this next time returns the next entry from the list.
225 * This can be used to traverse the list. Return SILC_LIST_END when the
226 * entire list has been traversed. Later, silc_list_start must be called
227 * again when re-starting list traversing.
231 * // Traverse the list from the beginning to the end
232 * silc_dlist_start(list)
233 * while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
240 void *silc_dlist_get(SilcDList list)
242 SilcDListEntry e = (SilcDListEntry)silc_list_get(list->list);
243 if (e != SILC_LIST_END)
245 return SILC_LIST_END;