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.

332 lines
7.8 KiB

  1. #ifndef __LIST_H_INCLUDED__
  2. #define __LIST_H_INCLUDED__
  3. //+---------------------------------------------------------------------------
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999.
  6. //
  7. // File: list.h
  8. //
  9. // Contents: Quick 'n dirty basic templated list class.
  10. //
  11. // History: 04-26-1999 Alan Shi (AlanShi) Created.
  12. //
  13. //----------------------------------------------------------------------------
  14. //
  15. // ListNode
  16. //
  17. typedef void * LISTNODE;
  18. template <class Type> class ListNode {
  19. public:
  20. ListNode(Type item);
  21. virtual ~ListNode();
  22. void SetNext(ListNode *pNode);
  23. void SetPrev(ListNode *pNode);
  24. Type GetItem();
  25. ListNode *GetNext();
  26. ListNode *GetPrev();
  27. private:
  28. DWORD _dwSig;
  29. Type _type;
  30. ListNode *_pNext;
  31. ListNode *_pPrev;
  32. };
  33. //
  34. // List
  35. //
  36. template <class Type> class List {
  37. public:
  38. List();
  39. ~List();
  40. LISTNODE AddHead(const Type &item);
  41. LISTNODE AddTail(const Type &item);
  42. LISTNODE GetHeadPosition();
  43. LISTNODE GetTailPosition();
  44. void RemoveAt(LISTNODE pNode);
  45. void RemoveAll();
  46. LISTNODE Find(const Type &item);
  47. int GetCount();
  48. Type GetNext(LISTNODE &pNode);
  49. Type GetAt(LISTNODE pNode);
  50. LISTNODE AddSorted(const Type &item, LPVOID pfn);
  51. public:
  52. DWORD _dwSig;
  53. private:
  54. ListNode<Type> *_pHead;
  55. ListNode<Type> *_pTail;
  56. int _iCount;
  57. };
  58. //
  59. // ListNode Implementation
  60. //
  61. template <class Type> ListNode<Type>::ListNode(Type item)
  62. : _pNext(NULL)
  63. , _pPrev(NULL)
  64. , _type(item)
  65. {
  66. _dwSig = 'EDON';
  67. }
  68. template <class Type> ListNode<Type>::~ListNode()
  69. {
  70. }
  71. template <class Type> void ListNode<Type>::SetNext(ListNode *pNode)
  72. {
  73. _pNext = pNode;
  74. }
  75. template <class Type> void ListNode<Type>::SetPrev(ListNode *pNode)
  76. {
  77. _pPrev = pNode;
  78. }
  79. template <class Type> Type ListNode<Type>::GetItem()
  80. {
  81. return _type;
  82. }
  83. template <class Type> ListNode<Type> *ListNode<Type>::GetNext()
  84. {
  85. return _pNext;
  86. }
  87. template <class Type> ListNode<Type> *ListNode<Type>::GetPrev()
  88. {
  89. return _pPrev;
  90. }
  91. //
  92. // List Implementation
  93. //
  94. template <class Type> List<Type>::List()
  95. : _pHead(NULL)
  96. , _pTail(NULL)
  97. , _iCount(0)
  98. {
  99. _dwSig = 'TSIL';
  100. }
  101. template <class Type> List<Type>::~List()
  102. {
  103. RemoveAll();
  104. }
  105. template <class Type> LISTNODE List<Type>::AddHead(const Type &item)
  106. {
  107. ListNode<Type> *pNode = NULL;
  108. pNode = new ListNode<Type>(item);
  109. if (pNode) {
  110. _iCount++;
  111. pNode->SetNext(_pHead);
  112. pNode->SetPrev(NULL);
  113. if (_pHead == NULL) {
  114. _pTail = pNode;
  115. }
  116. else {
  117. _pHead->SetPrev(pNode);
  118. }
  119. _pHead = pNode;
  120. }
  121. return (LISTNODE)pNode;
  122. }
  123. template <class Type> LISTNODE List<Type>::AddSorted(const Type &item,
  124. LPVOID pfn)
  125. {
  126. ListNode<Type> *pNode = NULL;
  127. LISTNODE pCurrNode = NULL;
  128. LISTNODE pPrevNode = NULL;
  129. int i;
  130. Type curItem;
  131. LONG (*pFN) (const Type item1, const Type item2);
  132. pFN = (LONG (*) (const Type item1, const Type item2))pfn;
  133. if(_pHead == NULL) {
  134. return AddHead(item);
  135. }
  136. else {
  137. pCurrNode = GetHeadPosition();
  138. curItem = ((ListNode<Type> *) pCurrNode)->GetItem();
  139. for (i = 0; i < _iCount; i++) {
  140. if (pFN(item, curItem) < 1) {
  141. pNode = new(ListNode<Type>(item));
  142. pNode->SetPrev((ListNode<Type> *)pPrevNode);
  143. pNode->SetNext((ListNode<Type> *)pCurrNode);
  144. if(pPrevNode) {
  145. ((ListNode<Type> *)pPrevNode)->SetNext(pNode);
  146. }
  147. else {
  148. _pHead = pNode;
  149. }
  150. _iCount++;
  151. break;
  152. }
  153. pPrevNode = pCurrNode;
  154. curItem = GetNext(pCurrNode);
  155. if(i+1 == _iCount)
  156. return AddTail(item);
  157. }
  158. }
  159. return (LISTNODE)pNode;
  160. }
  161. template <class Type> LISTNODE List<Type>::AddTail(const Type &item)
  162. {
  163. ListNode<Type> *pNode = NULL;
  164. pNode = new ListNode<Type>(item);
  165. if (pNode) {
  166. _iCount++;
  167. if (_pTail) {
  168. pNode->SetPrev(_pTail);
  169. _pTail->SetNext(pNode);
  170. _pTail = pNode;
  171. }
  172. else {
  173. _pHead = _pTail = pNode;
  174. }
  175. }
  176. return (LISTNODE)pNode;
  177. }
  178. template <class Type> int List<Type>::GetCount()
  179. {
  180. return _iCount;
  181. }
  182. template <class Type> LISTNODE List<Type>::GetHeadPosition()
  183. {
  184. return (LISTNODE)_pHead;
  185. }
  186. template <class Type> LISTNODE List<Type>::GetTailPosition()
  187. {
  188. return (LISTNODE)_pTail;
  189. }
  190. template <class Type> Type List<Type>::GetNext(LISTNODE &pNode)
  191. {
  192. Type item;
  193. ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
  194. // Faults if you pass NULL
  195. item = pListNode->GetItem();
  196. pNode = (LISTNODE)(pListNode->GetNext());
  197. return item;
  198. }
  199. template <class Type> void List<Type>::RemoveAll()
  200. {
  201. int i;
  202. LISTNODE listNode = NULL;
  203. ListNode<Type> *pDelNode = NULL;
  204. listNode = GetHeadPosition();
  205. for (i = 0; i < _iCount; i++) {
  206. pDelNode = (ListNode<Type> *)listNode;
  207. GetNext(listNode);
  208. delete pDelNode;
  209. }
  210. _iCount = 0;
  211. _pHead = NULL;
  212. _pTail = NULL;
  213. }
  214. template <class Type> void List<Type>::RemoveAt(LISTNODE pNode)
  215. {
  216. ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
  217. ListNode<Type> *pPrevNode = NULL;
  218. ListNode<Type> *pNextNode = NULL;
  219. if (pNode) {
  220. pPrevNode = pListNode->GetPrev();
  221. pNextNode = pListNode->GetNext();
  222. if (pPrevNode) {
  223. pPrevNode->SetNext(pNextNode);
  224. if (pNextNode) {
  225. pNextNode->SetPrev(pPrevNode);
  226. }
  227. else {
  228. // We're removing the last node, so we have a new tail
  229. _pTail = pPrevNode;
  230. }
  231. delete pNode;
  232. pNode = NULL;
  233. }
  234. else {
  235. // No previous, so we are the head of the list
  236. _pHead = pNextNode;
  237. if (pNextNode) {
  238. pNextNode->SetPrev(NULL);
  239. }
  240. else {
  241. // No previous, or next. There was only one node.
  242. _pHead = NULL;
  243. _pTail = NULL;
  244. }
  245. delete pNode;
  246. }
  247. _iCount--;
  248. }
  249. }
  250. template <class Type> LISTNODE List<Type>::Find(const Type &item)
  251. {
  252. int i;
  253. Type curItem;
  254. LISTNODE pNode = NULL;
  255. LISTNODE pMatchNode = NULL;
  256. ListNode<Type> * pListNode = NULL;
  257. pNode = GetHeadPosition();
  258. for (i = 0; i < _iCount; i++) {
  259. pListNode = (ListNode<Type> *)pNode;
  260. curItem = GetNext(pNode);
  261. if (curItem == item) {
  262. pMatchNode = (LISTNODE)pListNode;
  263. break;
  264. }
  265. }
  266. return pMatchNode;
  267. }
  268. template <class Type> Type List<Type>::GetAt(LISTNODE pNode)
  269. {
  270. ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
  271. // Faults if pListNode == NULL
  272. return pListNode->GetItem();
  273. }
  274. #endif