| 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 | |