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.

386 lines
12 KiB

  1. //------------------------------------------------------------------------------------------
  2. // list.cpp
  3. //
  4. // Routines to manage a singly-linked list of "things".
  5. //
  6. // A "ListElement" is allocated for each item to be put on the list; it is de-allocated
  7. // when the item is removed. This means we don't need to keep a "next" pointer in every
  8. // object we want to put on a list.
  9. //
  10. // NOTE: Mutual exclusion must be provided by the caller. If you want a synchronized
  11. // list, you must use the routines in synchlist.cc.
  12. //
  13. //------------------------------------------------------------------------------------------
  14. #include "list.hpp"
  15. //------------------------------------------------------------------------------------------
  16. // ListElement::ListElement
  17. //
  18. // Initialize a list element, so it can be added somewhere on a list.
  19. //
  20. // "itemPtr" is the item to be put on the list. It can be a pointer to anything.
  21. // "sortKey" is the priority of the item, if any.
  22. //------------------------------------------------------------------------------------------
  23. ListElement::ListElement(void *itemPtr, int sortKey)
  24. {
  25. item = itemPtr;
  26. key = sortKey;
  27. next = NULL; // assume we'll put it at the end of the list
  28. previous = NULL;
  29. }
  30. //------------------------------------------------------------------------------------------
  31. // List::List
  32. //
  33. // Initialize a list, empty to start with.
  34. //
  35. // Elements can now be added to the list.
  36. //------------------------------------------------------------------------------------------
  37. List::List()
  38. {
  39. first = last = iterator = NULL;
  40. length = 0;
  41. }
  42. //------------------------------------------------------------------------------------------
  43. // List::~List
  44. //
  45. // Prepare a list for deallocation. If the list still contains any ListElements,
  46. // de-allocate them. However, note that we do *not* de-allocate the "items" on the
  47. // list -- this module allocates and de-allocates the ListElements to keep track of
  48. // each item, but a given item may be on multiple lists, so we can't de-allocate them here.
  49. //------------------------------------------------------------------------------------------
  50. List::~List()
  51. {
  52. Flush();
  53. }
  54. //------------------------------------------------------------------------------------------
  55. // List::Append
  56. //
  57. // Append an "item" to the end of the list.
  58. //
  59. // Allocate a ListElement to keep track of the item. If the list is empty, then this will
  60. // be the only element. Otherwise, put it at the end.
  61. //
  62. // "item" is the thing to put on the list, it can be a pointer to anything.
  63. //------------------------------------------------------------------------------------------
  64. void List::Append(void *item)
  65. {
  66. ListElement *element = new ListElement(item, 0);
  67. if (IsEmpty())
  68. {
  69. // list is empty
  70. first = element;
  71. last = element;
  72. }
  73. else
  74. {
  75. // else put it after last
  76. last->next = element;
  77. element->previous = last;
  78. last = element;
  79. }
  80. length++;
  81. }
  82. //------------------------------------------------------------------------------------------
  83. // List::Prepend
  84. //
  85. // Put an "item" on the front of the list.
  86. //
  87. // Allocate a ListElement to keep track of the item. If the list is empty, then this will
  88. // be the only element. Otherwise, put it at the beginning.
  89. //
  90. // "item" is the thing to put on the list, it can be a pointer to anything.
  91. //------------------------------------------------------------------------------------------
  92. void List::Prepend(void *item)
  93. {
  94. ListElement *element = new ListElement(item, 0);
  95. if (IsEmpty())
  96. {
  97. // list is empty
  98. first = element;
  99. last = element;
  100. }
  101. else
  102. {
  103. // else put it before first
  104. element->next = first;
  105. first->previous = element;
  106. first = element;
  107. }
  108. length++;
  109. }
  110. //------------------------------------------------------------------------------------------
  111. // List::Remove
  112. //
  113. // Remove the first "item" from the front of the list.
  114. //
  115. // Returns:
  116. //
  117. // Pointer to removed item, NULL if nothing on the list.
  118. //------------------------------------------------------------------------------------------
  119. void* List::Remove()
  120. {
  121. // Same as SortedRemove, but ignore the key
  122. return SortedRemove(NULL);
  123. }
  124. //------------------------------------------------------------------------------------------
  125. // List::Flush
  126. //
  127. // Remove everything from the list.
  128. //
  129. //------------------------------------------------------------------------------------------
  130. void List::Flush()
  131. {
  132. while (Remove() != NULL)
  133. ; // delete all the list elements
  134. }
  135. //------------------------------------------------------------------------------------------
  136. // List::Mapcar
  137. //
  138. // Apply a function to each item on the list, by walking through
  139. // the list, one element at a time.
  140. //
  141. // "func" is the procedure to apply to each element of the list.
  142. //------------------------------------------------------------------------------------------
  143. void List::Mapcar(VoidFunctionPtr func)
  144. {
  145. for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next)
  146. {
  147. (*func)( ptr->item );
  148. }
  149. }
  150. //------------------------------------------------------------------------------------------
  151. // List::IsEmpty
  152. //
  153. // Returns TRUE if the list is empty (has no items).
  154. //------------------------------------------------------------------------------------------
  155. bool List::IsEmpty()
  156. {
  157. return (first == NULL);
  158. }
  159. //------------------------------------------------------------------------------------------
  160. // List::MoveFirst
  161. //
  162. // move to the first node in the list.
  163. //
  164. //------------------------------------------------------------------------------------------
  165. void List::MoveFirst()
  166. {
  167. iterator = first;
  168. }
  169. //------------------------------------------------------------------------------------------
  170. // List::MoveNext
  171. //
  172. // move to the next state of the list.
  173. //
  174. //------------------------------------------------------------------------------------------
  175. bool List::MoveNext()
  176. {
  177. if (iterator == NULL || iterator->next == NULL)
  178. {
  179. return false;
  180. }
  181. iterator = iterator->next;
  182. return true;
  183. }
  184. //------------------------------------------------------------------------------------------
  185. // List::GetData
  186. //
  187. // get data of the current iterator.
  188. //
  189. //------------------------------------------------------------------------------------------
  190. void* List::GetData()
  191. {
  192. // make sure iterator is set.
  193. if (iterator == NULL)
  194. return NULL;
  195. // return the data.
  196. return iterator->item;
  197. }
  198. //------------------------------------------------------------------------------------------
  199. // List::SortedInsert
  200. //
  201. // Insert an "item" into a list, so that the list elements are sorted in increasing order
  202. // by "sortKey".
  203. //
  204. // Allocate a ListElement to keep track of the item. If the list is empty, then this will
  205. // be the only element. Otherwise, walk through the list, one element at a time, to find
  206. // where the new item should be placed.
  207. //
  208. // "item" is the thing to put on the list, it can be a pointer to anything.
  209. // "sortKey" is the priority of the item.
  210. //------------------------------------------------------------------------------------------
  211. void List::SortedInsert(void *item, int sortKey)
  212. {
  213. ListElement *element = new ListElement(item, sortKey);
  214. ListElement *ptr; // keep track
  215. if (IsEmpty())
  216. {
  217. // if list is empty, put
  218. first = element;
  219. last = element;
  220. }
  221. else if (sortKey < first->key)
  222. {
  223. // item goes on front of list
  224. element->next = first;
  225. first->previous = element;
  226. first = element;
  227. }
  228. else
  229. {
  230. // look for first elt in list bigger than item
  231. for (ptr = first; ptr->next != NULL; ptr = ptr->next)
  232. {
  233. if (sortKey < ptr->next->key)
  234. {
  235. element->next = ptr->next;
  236. element->previous = ptr;
  237. ptr->next->previous = element;
  238. ptr->next = element;
  239. return;
  240. }
  241. }
  242. // item goes at end of list
  243. last->next = element;
  244. element->previous = last;
  245. last = element;
  246. }
  247. length++;
  248. }
  249. //------------------------------------------------------------------------------------------
  250. // List::SortedRemove
  251. //
  252. // Remove the first "item" from the front of a sorted list.
  253. //
  254. // Returns:
  255. //
  256. // Pointer to removed item, NULL if nothing on the list. Sets *keyPtr to the priority value
  257. // of the removed item (this is needed by interrupt.cc, for instance).
  258. //
  259. // "keyPtr" is a pointer to the location in which to store the priority of the removed item
  260. //------------------------------------------------------------------------------------------
  261. void* List::SortedRemove(int *keyPtr)
  262. {
  263. ListElement *element = first;
  264. void *thing;
  265. // if empty nothing to remove just return.
  266. if (IsEmpty())
  267. {
  268. return NULL;
  269. }
  270. thing = first->item;
  271. if (first == last)
  272. {
  273. // list had one item, now has none
  274. first = NULL;
  275. last = NULL;
  276. }
  277. else
  278. {
  279. first = element->next;
  280. if (first != NULL)
  281. {
  282. first->previous = NULL;
  283. }
  284. }
  285. if (keyPtr != NULL)
  286. {
  287. *keyPtr = element->key;
  288. }
  289. delete element;
  290. length--;
  291. return thing;
  292. }
  293. //------------------------------------------------------------------------------------------
  294. // List::insertAfter
  295. //
  296. // insert a new item after this one
  297. //------------------------------------------------------------------------------------------
  298. void List::insertAfter(ListElement * listEl, void *item)
  299. {
  300. ListElement *newElement = new ListElement(item, 0);
  301. newElement->next = listEl->next;
  302. newElement->previous = listEl;
  303. listEl->next = newElement;
  304. if (last == listEl)
  305. {
  306. last = newElement;
  307. }
  308. length++;
  309. }
  310. //------------------------------------------------------------------------------------------
  311. // List::insertBefore
  312. //
  313. // insert a new item before this one
  314. //------------------------------------------------------------------------------------------
  315. void List::insertBefore(ListElement * listEl, void *item)
  316. {
  317. ListElement *newElement = new ListElement(item, 0);
  318. newElement->next = listEl;
  319. newElement->previous = listEl->previous;
  320. listEl->previous = newElement;
  321. if (first == listEl)
  322. {
  323. first = newElement;
  324. }
  325. length++;
  326. }
  327. //------------------------------------------------------------------------------------------
  328. // List::removeAt
  329. //
  330. // removes listEl from the list. Do not delete it from memory
  331. //------------------------------------------------------------------------------------------
  332. void List::removeAt(ListElement * listEl)
  333. {
  334. if(first != listEl)
  335. {
  336. (listEl->previous)->next = listEl->next;
  337. }
  338. else
  339. {
  340. first = listEl->next;
  341. }
  342. if(last != listEl)
  343. {
  344. (listEl->next)->previous = listEl->previous;
  345. }
  346. else
  347. {
  348. last = listEl->previous;
  349. }
  350. length --;
  351. }