Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
7.6 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1996.
  5. //
  6. // File: clist.hxx
  7. //
  8. // Contents: Class to create and maintain a singly linked list.
  9. //
  10. // History: 28-Jun-96 MacM Created
  11. //
  12. //--------------------------------------------------------------------
  13. #ifndef __CLIST_HXX__
  14. #define __CLIST_HXX__
  15. typedef struct _CSLIST_NODE
  16. {
  17. PVOID pvData;
  18. struct _CSLIST_NODE *pNext;
  19. } CSLIST_NODE, *PCSLIST_NODE;
  20. //
  21. // Free function callback typedef. This function will delete the memory saved
  22. // as the data in a list node on list destruction
  23. //
  24. typedef VOID (*FreeFunc)(PVOID);
  25. //
  26. // This function returns TRUE if the two items are the same, or FALSE if they
  27. // are not
  28. //
  29. typedef BOOL (*CompFunc)(PVOID, PVOID);
  30. //+---------------------------------------------------------------------------
  31. //
  32. // Class: CSList
  33. //
  34. // Synopsis: Singly linked list class, single threaded
  35. //
  36. // Methods: Insert
  37. // InsertIfUnique
  38. // Find
  39. // Reset
  40. // NextData
  41. // Remove
  42. // QueryCount
  43. //
  44. //----------------------------------------------------------------------------
  45. class CSList
  46. {
  47. public:
  48. CSList(FreeFunc pfnFree) : _pfnFree (pfnFree),
  49. _pHead (NULL),
  50. _pCurrent (NULL),
  51. _cItems (0)
  52. {
  53. };
  54. inline ~CSList();
  55. DWORD QueryCount(void) { return(_cItems);};
  56. inline DWORD Insert(PVOID pvData);
  57. inline DWORD InsertIfUnique(PVOID pvData,
  58. CompFunc pfnComp);
  59. inline PVOID Find(PVOID pvData,
  60. CompFunc pfnComp);
  61. inline PVOID NextData();
  62. VOID Reset() {_pCurrent = _pHead;};
  63. inline DWORD Remove(PVOID pData);
  64. protected:
  65. PCSLIST_NODE _pHead;
  66. PCSLIST_NODE _pCurrent;
  67. DWORD _cItems;
  68. FreeFunc _pfnFree;
  69. };
  70. //+------------------------------------------------------------------
  71. //
  72. // Member: CSList::~CSList
  73. //
  74. // Synopsis: Destructor for the CSList class
  75. //
  76. // Arguments: None
  77. //
  78. // Returns: void
  79. //
  80. //+------------------------------------------------------------------
  81. CSList::~CSList()
  82. {
  83. PCSLIST_NODE pNext = _pHead;
  84. //
  85. // We'll do this in 2 seperate, but almost identical loops, so that we
  86. // don't have to check for a null free pointer in every loop iteration.
  87. //
  88. if(_pfnFree != NULL)
  89. {
  90. while(pNext != NULL)
  91. {
  92. pNext = _pHead->pNext;
  93. (*_pfnFree)(_pHead->pvData);
  94. delete _pHead;
  95. _pHead = pNext;
  96. }
  97. }
  98. else
  99. {
  100. while(pNext != NULL)
  101. {
  102. pNext = _pHead->pNext;
  103. delete _pHead;
  104. _pHead = pNext;
  105. }
  106. }
  107. }
  108. //+------------------------------------------------------------------
  109. //
  110. // Member: CSList::Insert
  111. //
  112. // Synopsis: Creates a new node at the begining of the list and
  113. // inserts it into the list
  114. //
  115. //
  116. // Arguments: [IN pvData] -- Data to insert
  117. //
  118. // Returns: ERROR_SUCCESS -- Everything worked
  119. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  120. //
  121. //+------------------------------------------------------------------
  122. DWORD CSList::Insert(PVOID pvData)
  123. {
  124. DWORD dwErr = ERROR_SUCCESS;
  125. PCSLIST_NODE pNew = new CSLIST_NODE;
  126. if(pNew == NULL)
  127. {
  128. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  129. }
  130. else
  131. {
  132. pNew->pvData = pvData;
  133. pNew->pNext = _pHead;
  134. _pHead = pNew;
  135. _cItems++;
  136. }
  137. return(dwErr);
  138. }
  139. //+------------------------------------------------------------------
  140. //
  141. // Member: CSList::InsertIfUnique
  142. //
  143. // Synopsis: Creates a new node at the begining of the list and
  144. // inserts it into the list if the data does not already
  145. // exist in the list. If the data does exist, nothing
  146. // is done, but SUCCESS is returned
  147. //
  148. //
  149. // Arguments: [IN pvData] -- Data to insert
  150. //
  151. // Returns: ERROR_SUCCESS -- Everything worked
  152. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  153. //
  154. //+------------------------------------------------------------------
  155. DWORD CSList::InsertIfUnique(PVOID pvData,
  156. CompFunc pfnComp)
  157. {
  158. DWORD dwErr = ERROR_SUCCESS;
  159. //
  160. // First, make sure it doesn't already exist, and then insert it
  161. //
  162. PCSLIST_NODE pWalk = _pHead;
  163. while(pWalk)
  164. {
  165. if((pfnComp)(pvData, pWalk->pvData) == TRUE)
  166. {
  167. break;
  168. }
  169. pWalk = pWalk->pNext;
  170. }
  171. if(pWalk == NULL)
  172. {
  173. dwErr = Insert(pvData);
  174. }
  175. return(dwErr);
  176. }
  177. //+------------------------------------------------------------------
  178. //
  179. // Member: CSList::Find
  180. //
  181. // Synopsis: Locates the given data in the list, if it exists
  182. //
  183. // Arguments: [IN pvData] -- Data to insert
  184. //
  185. // Returns: ERROR_SUCCESS -- Everything worked
  186. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  187. //
  188. //+------------------------------------------------------------------
  189. PVOID CSList::Find(PVOID pvData,
  190. CompFunc pfnComp)
  191. {
  192. PCSLIST_NODE pWalk = _pHead;
  193. while(pWalk)
  194. {
  195. if((pfnComp)(pvData, pWalk->pvData) == TRUE)
  196. {
  197. break;
  198. }
  199. pWalk = pWalk->pNext;
  200. }
  201. return(pWalk == NULL ? NULL : pWalk->pvData);
  202. }
  203. //+------------------------------------------------------------------
  204. //
  205. // Member: CSList::NextData
  206. //
  207. // Synopsis: Returns the next data in the list
  208. //
  209. //
  210. // Arguments: None
  211. //
  212. // Returns: NULL -- No more items
  213. // Pointer to next data in list on success
  214. //
  215. //+------------------------------------------------------------------
  216. PVOID CSList::NextData()
  217. {
  218. PVOID pvRet = NULL;
  219. if(_pCurrent != NULL)
  220. {
  221. pvRet = _pCurrent->pvData;
  222. _pCurrent = _pCurrent->pNext;
  223. }
  224. return(pvRet);
  225. }
  226. //+------------------------------------------------------------------
  227. //
  228. // Member: CSList::Remove
  229. //
  230. // Synopsis: Removes the node that references the indicated data
  231. //
  232. // Arguments: pData -- The data in the node to remove
  233. //
  234. // Returns: ERROR_SUCCESS -- Success
  235. // ERROR_INVALID_PARAMETER Node not found
  236. //
  237. //+------------------------------------------------------------------
  238. DWORD CSList::Remove(PVOID pData)
  239. {
  240. PCSLIST_NODE pWalk = _pHead;
  241. PCSLIST_NODE pPrev = NULL;
  242. DWORD dwErr = ERROR_INVALID_PARAMETER;
  243. while(pWalk)
  244. {
  245. if(pData == pWalk->pvData)
  246. {
  247. if(pPrev == NULL)
  248. {
  249. _pHead = pWalk->pNext;
  250. }
  251. else
  252. {
  253. pPrev->pNext = pWalk->pNext;
  254. }
  255. delete pWalk;
  256. dwErr = ERROR_SUCCESS;
  257. _cItems--;
  258. break;
  259. }
  260. pPrev = pWalk;
  261. pWalk = pWalk->pNext;
  262. }
  263. return(dwErr);
  264. }
  265. #endif // __CLIST_HXX__