1 | /********************************************************************************** |
2 | * lst.h |
3 | * |
4 | * lib for creating/managing/deleting doubly-linked lists. |
5 | * |
6 | ************************************************** |
7 | * This code was created by Peter Harvey @ CodeByDesign. |
8 | * Released under LGPL 04.APR.99 |
9 | * |
10 | * Contributions from... |
11 | * ----------------------------------------------- |
12 | * Peter Harvey - pharvey@codebydesign.com |
13 | **************************************************/ |
14 | |
15 | #ifndef INCLUDED_LST_H |
16 | #define INCLUDED_LST_H |
17 | |
18 | /*********[ CONSTANTS AND TYPES ]**************************************************/ |
19 | #include <stdlib.h> |
20 | #include <stdio.h> |
21 | #include <ctype.h> |
22 | #include <string.h> |
23 | |
24 | #ifndef true |
25 | #define true 1 |
26 | #endif |
27 | |
28 | #ifndef false |
29 | #define false 0 |
30 | #endif |
31 | |
32 | |
33 | #define LST_NO_DATA 2 |
34 | #define LST_SUCCESS 1 |
35 | #define LST_ERROR 0 |
36 | |
37 | /******************************************** |
38 | * tLSTITEM |
39 | * |
40 | ********************************************/ |
41 | |
42 | typedef struct tLSTITEM |
43 | { |
44 | struct tLSTITEM *pNext; |
45 | struct tLSTITEM *pPrev; |
46 | |
47 | int bDelete; /* true if flagged for delete. do delete when refs = 0 */ |
48 | /* will become invisible for new cursors */ |
49 | /* ONLY APPLIES TO THE root LIST */ |
50 | int bHide; /* used in nav funcs if HLST bShowHidden=false (default) */ |
51 | long nRefs; /* the number of hItems that refer to this item to get pData */ |
52 | /* if bDelete and refs = 0 then item is really removed */ |
53 | void *hLst; /* ptr to its list handle. */ |
54 | |
55 | void *pData; /* ptr to user data or (if Cursor item) ptr to some base LSTITEM */ |
56 | |
57 | } LSTITEM, *HLSTITEM; |
58 | |
59 | /******************************************** |
60 | * tLST |
61 | * |
62 | ********************************************/ |
63 | |
64 | typedef struct tLST |
65 | { |
66 | HLSTITEM hFirst; |
67 | HLSTITEM hLast; |
68 | HLSTITEM hCurrent; |
69 | long nItems; /* number of items in the list (not counting where bDelete or bHide)*/ |
70 | /* !!! not used anymore !!!! */ |
71 | |
72 | long nRefs; /* the number of cursors that are based upon this list */ |
73 | |
74 | int bExclusive; /* set this for exclusive access to list ie when navigating with */ |
75 | /* hCurrent or when doing an insert or delete */ |
76 | /* do this only for VERY short periods all other access will loop */ |
77 | /* until this is set back to false */ |
78 | /* THIS IS FOR INTERNAL USE... IT IS USED WHEN MAINTAINING INTERNAL */ |
79 | /* LISTS SUCH AS REFERENCE LISTS DO NOT USE IT TO LOCK A ROOT OR */ |
80 | /* CURSOR LIST */ |
81 | int bShowHidden; /* true to have nav funcs show bHidden items(default=false) */ |
82 | int bShowDeleted; /* true to have nav funcs show bDeleted items (default=false) */ |
83 | void (*pFree)( void *pData ); /* function to use when need to free pData. default is free() */ |
84 | |
85 | int (*pFilter)( struct tLST *, void * ); /* this function returns true if we want the data in our result set */ |
86 | /* default is all items included. no affect if root list */ |
87 | |
88 | struct tLST *hLstBase; /* this list was derived from hLstBase. NULL if root list. */ |
89 | /* we must use this if we are adding a new item in an empty list */ |
90 | /* and to dec nRefs in our base list */ |
91 | |
92 | void *; /* app can store what ever it wants here. no attempt to interpret it*/ |
93 | /* or to free it is made by lst */ |
94 | |
95 | } LST, *HLST; |
96 | |
97 | |
98 | /******************************************** |
99 | * tLSTBOOKMARK |
100 | * |
101 | ********************************************/ |
102 | |
103 | typedef struct tLSTBOOKMARK |
104 | { |
105 | HLST hLst; |
106 | HLSTITEM hCurrent; |
107 | |
108 | } LSTBOOKMARK, *HLSTBOOKMARK; |
109 | |
110 | |
111 | #if defined(__cplusplus) |
112 | extern "C" { |
113 | #endif |
114 | |
115 | /*********[ PRIMARY INTERFACE ]*****************************************************/ |
116 | |
117 | /****************************** |
118 | * lstAppend |
119 | * |
120 | * 1. Appends a new item to the end of the list. |
121 | * 2. Makes the new item the current item. |
122 | ******************************/ |
123 | int lstAppend( HLST hLst, void *pData ); |
124 | |
125 | /****************************** |
126 | * lstClose |
127 | * |
128 | * 1. free memory previously allocated for HLST |
129 | * 2. Will call lstDelete with bFreeData for each (if any) |
130 | * existing items. |
131 | ******************************/ |
132 | int lstClose( HLST hLst ); |
133 | |
134 | /****************************** |
135 | * lstDelete |
136 | * |
137 | * 1. deletes current item |
138 | * 2. dec ref count in root item |
139 | * 3. deletes root item if ref count < 1 OR sets delete flag |
140 | ******************************/ |
141 | int lstDelete( HLST hLst ); |
142 | |
143 | /****************************** |
144 | * lstEOL |
145 | * |
146 | ******************************/ |
147 | int lstEOL( HLST hLst ); |
148 | |
149 | /****************************** |
150 | * lstFirst |
151 | * |
152 | * 1. makes First item the current item. |
153 | * 2. returns pData or NULL |
154 | ******************************/ |
155 | void *lstFirst( HLST hLst ); |
156 | |
157 | /****************************** |
158 | * lstGet |
159 | * |
160 | * 1. Return pData for current item or NULL |
161 | * 2. Will recurse down to base data if bIsCursor. |
162 | ******************************/ |
163 | void *lstGet( HLST hLst ); |
164 | |
165 | /****************************** |
166 | * lstGetBookMark |
167 | * |
168 | * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!! |
169 | ******************************/ |
170 | int lstGetBookMark( HLST hLst, HLSTBOOKMARK hLstBookMark ); |
171 | |
172 | /****************************** |
173 | * lstGoto |
174 | * |
175 | * 1. Return pData for current item or NULL |
176 | * 2. IF nIndex is out of range THEN |
177 | * lstEOL = TRUE |
178 | * returns NULL |
179 | ******************************/ |
180 | void *lstGoto( HLST hLst, long nIndex ); |
181 | |
182 | /****************************** |
183 | * lstGotoBookMark |
184 | * |
185 | * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!! |
186 | ******************************/ |
187 | int lstGotoBookMark( HLSTBOOKMARK hLstBookMark ); |
188 | |
189 | /****************************** |
190 | * lstInsert |
191 | * |
192 | * 1. inserts a new item before the current item |
193 | * 2. becomes current |
194 | ******************************/ |
195 | int lstInsert( HLST hLst, void *pData ); |
196 | |
197 | /****************************** |
198 | * lstLast |
199 | * |
200 | * 1. makes last item the current item |
201 | * 2. returns pData or NULL |
202 | ******************************/ |
203 | void *lstLast( HLST hLst ); |
204 | |
205 | /****************************** |
206 | * lstNext |
207 | * |
208 | * 1. makes next item the current item |
209 | * 2. returns pData or NULL |
210 | ******************************/ |
211 | void *lstNext( HLST hLst ); |
212 | |
213 | /****************************** |
214 | * lstOpen |
215 | * |
216 | * 1. Create an empty list. |
217 | * |
218 | * *** MUST CALL lstClose WHEN DONE OR LOSE MEMORY *** |
219 | * |
220 | ******************************/ |
221 | HLST lstOpen(); |
222 | |
223 | /****************************** |
224 | * lstOpenCursor |
225 | * |
226 | * 1. If you are going to use cursors then just use cursors. Do |
227 | * not use move funcs, get funcs, etc on base list and use |
228 | * cursors as well. Garbage collection only accounts for |
229 | * cursors when deleting items that have been flagged for |
230 | * deletion... so direct access could result in the list |
231 | * changing unexpectedly. |
232 | * |
233 | * 2. pFilterFunc is optional. If you provide this function |
234 | * pointer the cursor list will be generated to include |
235 | * all items where pFilterFunc( lstGet( hBase ) ) = true. |
236 | * Leaving it NULL just means that all items in hBase will |
237 | * be included in the cursor list. |
238 | * |
239 | * *** MUST CALL lstClose WHEN DONE OR LOSE MEMORY *** |
240 | * |
241 | ******************************/ |
242 | HLST lstOpenCursor( HLST hBase, int (*pFilterFunc)( HLST, void * ), void * ); |
243 | |
244 | /****************************** |
245 | * lstPrev |
246 | * |
247 | * 1. makes prev item the current item |
248 | * 2. returns pData or NULL |
249 | ******************************/ |
250 | void *lstPrev( HLST hLst ); |
251 | |
252 | /****************************** |
253 | * lstSet |
254 | * |
255 | * 1. replaces pData pointer |
256 | * 2. returns pData |
257 | * 3. Will recurse down to base data. |
258 | * |
259 | * *** THIS SHOULD BE CHANGED TO AVOID CHANGING THE pData POINTER AND RESIZE THE BUFFER INSTEAD |
260 | * |
261 | ******************************/ |
262 | void *lstSet( HLST hLst, void *pData ); |
263 | |
264 | /****************************** |
265 | * lstSetFreeFunc |
266 | * |
267 | * 1. The given function will be called when ever there is a need to free pData |
268 | * 2. The default action is to simply free(pData). |
269 | ******************************/ |
270 | int lstSetFreeFunc( HLST hLst, void (*pFree)( void *pData ) ); |
271 | |
272 | /****************************** |
273 | * lstSeek |
274 | * |
275 | * 1. Tries to set hCurrent to the item where pData is at |
276 | * 2. simply scans from 1st to last so lsEOL() = true when not found |
277 | * |
278 | ******************************/ |
279 | int lstSeek( HLST hLst, void *pData ); |
280 | |
281 | /****************************** |
282 | * lstSeekItem |
283 | * |
284 | * 1. Tries to set hCurrent to the item where hItem is at |
285 | * 2. simply scans from 1st to last so lsEOL() = true when not found |
286 | * |
287 | ******************************/ |
288 | int lstSeekItem( HLST hLst, HLSTITEM hItem ); |
289 | |
290 | /***************[ FOR INTERNAL USE ]***********************/ |
291 | |
292 | /*************************** |
293 | * ENSURE CURRENT IS NOT ON A bDelete ITEM |
294 | ***************************/ |
295 | void *_lstAdjustCurrent( HLST hLst ); |
296 | |
297 | /*************************** |
298 | * |
299 | ***************************/ |
300 | void _lstDump( HLST hLst ); |
301 | |
302 | /****************************** |
303 | * _lstFreeItem |
304 | * |
305 | * 1. Does a real delete. Frees memory used by item. |
306 | * will delete root item as required. |
307 | * |
308 | ******************************/ |
309 | int _lstFreeItem( HLSTITEM hItem ); |
310 | |
311 | /****************************** |
312 | * _lstNextValidItem |
313 | * |
314 | * 1. Starts scanning hLst at hItem until a non-deleted Item found or EOL |
315 | * |
316 | ******************************/ |
317 | HLSTITEM _lstNextValidItem( HLST hLst, HLSTITEM hItem ); |
318 | |
319 | /****************************** |
320 | * _lstPrevValidItem |
321 | * |
322 | * 1. Starts scanning hLst at hItem until a non-deleted Item found or EOL |
323 | * |
324 | ******************************/ |
325 | HLSTITEM _lstPrevValidItem( HLST hLst, HLSTITEM hItem ); |
326 | |
327 | |
328 | /****************************** |
329 | * _lstVisible |
330 | * |
331 | * |
332 | ******************************/ |
333 | int _lstVisible( HLSTITEM hItem ); |
334 | |
335 | |
336 | /****************************** |
337 | * _lstAppend |
338 | * |
339 | * |
340 | ******************************/ |
341 | int _lstAppend( HLST hLst, HLSTITEM hItem ); |
342 | |
343 | /****************************** |
344 | * _lstInsert |
345 | * |
346 | * |
347 | ******************************/ |
348 | int _lstInsert( HLST hLst, HLSTITEM hItem ); |
349 | |
350 | #if defined(__cplusplus) |
351 | } |
352 | #endif |
353 | |
354 | #endif |
355 | |
356 | |