ROBODoc documented. Patch by Ville Räsänen.
[silc.git] / lib / silcutil / silcdlist.h
1 /*
2
3   silcdlist.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 2000 Pekka Riikonen
8
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.
13   
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.
18
19 */
20
21 #ifndef SILDCLIST_H
22 #define SILDCLIST_H
23
24 #include "silclist.h"
25  
26 /****h* silcutil/SILC Dynamic List Interface
27  *
28  * DESCRIPTION
29  *
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
34  *    SilcDList.
35  *
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.
41  *
42  ***/
43
44 /****s* silcutil/SilcDListAPI/SilcDList
45  *
46  * NAME
47  *
48  *    typedef struct { ... } *SilcDList;
49  *
50  * DESCRIPTION
51  *
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.
55  *
56  * SOURCE
57  */
58 typedef struct {
59   SilcList list;
60 } *SilcDList;
61 /***/
62
63 /****s* silcutil/SilcDListAPI/SilcDListEntry
64  *
65  * NAME
66  *
67  *    typedef struct SilcDListEntryStruct { ... } *SilcDListEntry;
68  *
69  * DESCRIPTION
70  *
71  *    SilcDListEntry structure, one entry in the list. This MUST NOT be used
72  *    directly by the application.
73  *
74  * SOURCE
75  */
76 typedef struct SilcDListEntryStruct {
77   void *context;
78   struct SilcDListEntryStruct *next;
79 } *SilcDListEntry;
80 /***/
81
82 /****f* silcutil/SilcDListAPI/silc_dlist_init
83  *
84  * SYNOPSIS
85  * 
86  *    static inline
87  *    SilcDList silc_dlist_init();
88  *
89  * DESCRIPTION
90  *
91  *    Initializes SilcDList.
92  *
93  ***/
94
95 static inline
96 SilcDList silc_dlist_init()
97 {
98   SilcDList list;
99
100   list = (SilcDList)silc_calloc(1, sizeof(*list));
101   silc_list_init(list->list, struct SilcDListEntryStruct, next);
102
103   return list;
104 }
105
106 /****f* silcutil/SilcDListAPI/silc_dlist_uninit
107  *
108  * SYNOPSIS
109  *
110  *    static inline
111  *    void silc_dlist_uninit(SilcDList list);
112  *
113  * DESCRIPTION
114  *
115  *    Uninits and frees all memory. Must be called to free memory. Does NOT
116  *    free the contexts saved by caller.
117  *
118  ***/
119
120 static inline
121 void silc_dlist_uninit(SilcDList list)
122 {
123   if (list) {
124     SilcDListEntry e;
125     silc_list_start(list->list);
126     while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
127       silc_list_del(list->list, e);
128       silc_free(e);
129     }
130     silc_free(list);
131   }
132 }
133
134 /****f* silcutil/SilcDListAPI/silc_dlist_count
135  *
136  * SYNOPSIS
137  *
138  *    static inline
139  *    int silc_dlist_count(SilcDList list);
140  *
141  * DESCRIPTION
142  *
143  * Return the number of entries in the list.
144  *
145  ***/
146
147 static inline
148 int silc_dlist_count(SilcDList list)
149 {
150   return silc_list_count(list->list);
151 }
152
153 /****f* silcutil/SilcDListAPI/silc_dlist_start
154  *
155  * SYNOPSIS
156  *
157  *    static inline
158  *    void silc_dlist_start(SilcDList list);
159  *
160  * DESCRIPTION
161  *
162  *    Set the start of the list. This prepares the list for traversing entries
163  *    from the start of the list.
164  *
165  ***/
166
167 static inline
168 void silc_dlist_start(SilcDList list)
169 {
170   silc_list_start(list->list);
171 }
172
173 /****f* silcutil/SilcDListAPI/silc_dlist_add
174  *
175  * SYNOPSIS
176  *
177  *    static inline
178  *    void silc_dlist_add(SilcDList list, void *context);
179  *
180  * DESCRIPTION
181  *
182  *    Adds new entry to the list. This is the default function to add new
183  *    entries to the list.
184  *
185  ***/
186
187 static inline
188 void silc_dlist_add(SilcDList list, void *context)
189 {
190   SilcDListEntry e = (SilcDListEntry)silc_calloc(1, sizeof(*e));
191   e->context = context;
192   silc_list_add(list->list, e);
193 }
194
195 /****f* silcutil/SilcDListAPI/silc_dlist_del
196  *
197  * SYNOPSIS
198  *
199  *    static inline
200  *    void silc_dlist_del(SilcDList list, void *context);
201  *
202  * DESCRIPTION
203  *
204  *    Remove entry from the list. Returns < 0 on error, 0 otherwise.
205  *
206  ***/
207
208 static inline
209 void silc_dlist_del(SilcDList list, void *context)
210 {
211   SilcDListEntry e;
212
213   silc_list_start(list->list);
214   while ((e = (SilcDListEntry)silc_list_get(list->list)) != SILC_LIST_END) {
215     if (e->context == context) {
216       silc_list_del(list->list, e);
217       silc_free(e);
218       break;
219     }
220   }
221 }
222
223 /****f* silcutil/SilcDListAPI/silc_dlist_get
224  *
225  * SYNOPSIS
226  *
227  *    static inline
228  *    void *silc_dlist_get(SilcDList list);
229  *
230  * DESCRIPTION
231  *
232  *    Returns current entry from the list and moves the list pointer forward
233  *    so that calling this next time returns the next entry from the list.
234  *    This can be used to traverse the list. Return SILC_LIST_END when the
235  *    entire list has been traversed. Later, silc_list_start must be called
236  *    again when re-starting list traversing.
237  *
238  * EXAMPLE
239  *
240  *    // Traverse the list from the beginning to the end 
241  *    silc_dlist_start(list)
242  *    while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
243  *      ...
244  *    }
245  *
246  ***/
247
248 static inline
249 void *silc_dlist_get(SilcDList list)
250 {
251   SilcDListEntry e = (SilcDListEntry)silc_list_get(list->list);
252   if (e != SILC_LIST_END)
253     return e->context;
254   return SILC_LIST_END;
255 }
256
257 #endif