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
42typedef 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
64typedef 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 *pExtras; /* 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
103typedef 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 ******************************/
123int 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 ******************************/
132int 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 ******************************/
141int lstDelete( HLST hLst );
142
143/******************************
144 * lstEOL
145 *
146 ******************************/
147int lstEOL( HLST hLst );
148
149/******************************
150 * lstFirst
151 *
152 * 1. makes First item the current item.
153 * 2. returns pData or NULL
154 ******************************/
155void *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 ******************************/
163void *lstGet( HLST hLst );
164
165/******************************
166 * lstGetBookMark
167 *
168 * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!!
169 ******************************/
170int 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 ******************************/
180void *lstGoto( HLST hLst, long nIndex );
181
182/******************************
183 * lstGotoBookMark
184 *
185 * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!!
186 ******************************/
187int lstGotoBookMark( HLSTBOOKMARK hLstBookMark );
188
189/******************************
190 * lstInsert
191 *
192 * 1. inserts a new item before the current item
193 * 2. becomes current
194 ******************************/
195int 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 ******************************/
203void *lstLast( HLST hLst );
204
205/******************************
206 * lstNext
207 *
208 * 1. makes next item the current item
209 * 2. returns pData or NULL
210 ******************************/
211void *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 ******************************/
221HLST 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 ******************************/
242HLST lstOpenCursor( HLST hBase, int (*pFilterFunc)( HLST, void * ), void *pExtras );
243
244/******************************
245 * lstPrev
246 *
247 * 1. makes prev item the current item
248 * 2. returns pData or NULL
249 ******************************/
250void *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 ******************************/
262void *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 ******************************/
270int 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 ******************************/
279int 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 ******************************/
288int lstSeekItem( HLST hLst, HLSTITEM hItem );
289
290/***************[ FOR INTERNAL USE ]***********************/
291
292/***************************
293 * ENSURE CURRENT IS NOT ON A bDelete ITEM
294 ***************************/
295void *_lstAdjustCurrent( HLST hLst );
296
297/***************************
298 *
299 ***************************/
300void _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 ******************************/
309int _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 ******************************/
317HLSTITEM _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 ******************************/
325HLSTITEM _lstPrevValidItem( HLST hLst, HLSTITEM hItem );
326
327
328/******************************
329 * _lstVisible
330 *
331 *
332 ******************************/
333int _lstVisible( HLSTITEM hItem );
334
335
336/******************************
337 * _lstAppend
338 *
339 *
340 ******************************/
341int _lstAppend( HLST hLst, HLSTITEM hItem );
342
343/******************************
344 * _lstInsert
345 *
346 *
347 ******************************/
348int _lstInsert( HLST hLst, HLSTITEM hItem );
349
350#if defined(__cplusplus)
351 }
352#endif
353
354#endif
355
356