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.
29 SILC Dynamic List API can be used to add opaque contexts to list that will
30 automatically allocate list entries. Normal SILC List API cannot be used
31 for this purpose because in that case the context passed to the list must
32 be defined as list structure already. This is not the case in SilcDList.
34 This is slower than SilcList because this requires one extra memory
35 allocation when adding new entries to the list. The context is probably
36 allocated already and the new list entry requires one additional memory
37 allocation. The memory allocation and free'ing is done automatically in
38 the API and does not show to the caller.
41 /* SilcDList object. This is the actual SilcDList object that is used by
42 application. Application defines this object and adds context's to this
43 list with functions defined below. */
48 /* SilcDListEntry structure, one entry in the list. This MUST NOT be used
49 directly by the application. */
50 typedef struct SilcDListEntryStruct {
52 struct SilcDListEntryStruct *next;
55 /* Initializes SilcDList. */
58 SilcDList silc_dlist_init()
62 list = (SilcDList)silc_calloc(1, sizeof(*list));
63 silc_list_init(list->list, struct SilcDListEntryStruct, next);
68 /* Uninits and free's all memory. Must be called to free memory. Does NOT
69 free the contexts saved by caller. */
72 void silc_dlist_uninit(SilcDList list)
76 silc_list_start(list->list);
77 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
78 silc_list_del(list->list, e);
85 /* Return the number of entries in the list */
88 int silc_dlist_count(SilcDList list)
90 return silc_list_count(list->list);
93 /* Set the start of the list. This prepares the list for traversing entries
94 from the start of the list. */
97 void silc_dlist_start(SilcDList list)
99 silc_list_start(list->list);
102 /* Adds new entry to the list. This is the default function to add new
103 entries to the list. */
106 void silc_dlist_add(SilcDList list, void *context)
108 SilcDListEntry e = (SilcDListEntry)silc_calloc(1, sizeof(*e));
109 e->context = context;
110 silc_list_add(list->list, e);
113 /* Remove entry from the list. Returns < 0 on error, 0 otherwise. */
116 void silc_dlist_del(SilcDList list, void *context)
120 silc_list_start(list->list);
121 while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
122 if (e->context == context) {
123 silc_list_del(list->list, e);
130 /* Returns current entry from the list and moves the list pointer forward
131 so that calling this next time returns the next entry from the list. This
132 can be used to traverse the list. Return SILC_LIST_END when the entire
133 list has ben traversed. Later, silc_list_start must be called again when
134 re-starting list traversing. Example:
136 // Traverse the list from the beginning to the end
137 silc_dlist_start(list)
138 while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
144 void *silc_dlist_get(SilcDList list)
146 SilcDListEntry e = (SilcDListEntry)silc_list_get(list->list);
147 if (e != SILC_LIST_END)
149 return SILC_LIST_END;