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.

356 lines
7.2 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_T123PSTN);
  3. /* slist.cpp
  4. *
  5. * Copyright (c) 1996 by Microsoft Corporation
  6. *
  7. * Written by: Christos Tsollis
  8. *
  9. * Revisions:
  10. *
  11. * Abstract:
  12. *
  13. * This is the implementation of a linked list data structure.
  14. *
  15. */
  16. #define MyMalloc(size) LocalAlloc (LMEM_FIXED, (size))
  17. #define MyFree(ptr) LocalFree ((HLOCAL) (ptr))
  18. #define Max(a,b) (((a) > (b)) ? (a) : (b))
  19. /* Function: Constructor
  20. *
  21. * Parameters:
  22. * ltype: List type
  23. * num_of_items: Size of the list's cache
  24. *
  25. * Return value:
  26. * None
  27. */
  28. SListClass::SListClass (DWORD num_of_items)
  29. {
  30. MaxEntries = Max (num_of_items, DEFAULT_NUMBER_OF_ITEMS);
  31. // Allocate the block of items (which, hopefully, will be the last one)
  32. Entries = (DWORD_PTR *) MyMalloc (MaxEntries * sizeof (DWORD_PTR));
  33. // Initialize the private member variables
  34. NumOfEntries = 0;
  35. HeadOffset = 0;
  36. CurrOffset = 0xFFFFFFFF;
  37. }
  38. /* Function: Destructor
  39. *
  40. * Parameters:
  41. * None.
  42. *
  43. * Return value:
  44. * None
  45. *
  46. */
  47. SListClass::~SListClass (void)
  48. {
  49. if (Entries != NULL)
  50. MyFree (Entries);
  51. }
  52. /* Function: Expand
  53. * This private member function, expands the storage array of a list. It doubles its size.
  54. *
  55. * Parameters:
  56. * None.
  57. *
  58. * Return value:
  59. * TRUE, if the expansion was successful. FALSE, otherwise.
  60. *
  61. */
  62. BOOL SListClass::Expand (void)
  63. {
  64. DWORD_PTR *OldEntries; // Keeps a copy of the old array of values.
  65. DWORD dwTemp; // Temporary DWORD value
  66. if (Entries == NULL) {
  67. // the list is empty; we try to allocate space anyway.
  68. Entries = (DWORD_PTR *) MyMalloc (MaxEntries * sizeof (DWORD_PTR));
  69. if (Entries == NULL)
  70. return FALSE;
  71. return TRUE;
  72. }
  73. ASSERT (Entries != NULL);
  74. // The current array of entries is full, so we need to allocate a bigger one
  75. // The new array has twice the size of the old one
  76. OldEntries = Entries;
  77. Entries = (DWORD_PTR *) MyMalloc ((MaxEntries << 1) * sizeof (DWORD_PTR));
  78. if (Entries == NULL) {
  79. // we failed; we have to return
  80. Entries = OldEntries;
  81. return FALSE;
  82. }
  83. // copy the old entries into the new array, starting from the beginning
  84. dwTemp = MaxEntries - HeadOffset;
  85. memcpy ((void *) Entries, (void *) (OldEntries + HeadOffset), dwTemp * sizeof (DWORD));
  86. memcpy ((void *) (Entries + dwTemp), (void *) OldEntries, HeadOffset * sizeof (DWORD));
  87. // Free the old array of entries
  88. MyFree (OldEntries);
  89. // Set the instance variables
  90. MaxEntries <<= 1;
  91. HeadOffset = 0;
  92. return TRUE;
  93. }
  94. /* Function: append
  95. * Inserts a value at the end of a list.
  96. *
  97. * Parameters:
  98. * new_key: The new value that has to be inserted in the list
  99. *
  100. * Return value:
  101. * None.
  102. *
  103. */
  104. void SListClass::append (DWORD_PTR new_key)
  105. {
  106. DWORD_PTR dwTemp;
  107. if (Entries == NULL || NumOfEntries >= MaxEntries)
  108. if (! Expand ())
  109. return;
  110. ASSERT (Entries != NULL);
  111. ASSERT (NumOfEntries < MaxEntries);
  112. dwTemp = HeadOffset + (NumOfEntries++);
  113. if (dwTemp >= MaxEntries)
  114. dwTemp -= MaxEntries;
  115. Entries[dwTemp] = new_key;
  116. }
  117. /* Function: prepend
  118. * Inserts a value at the beginning of a list.
  119. *
  120. * Parameters:
  121. * new_key: The new value that has to be inserted in the list
  122. *
  123. * Return value:
  124. * None.
  125. *
  126. */
  127. void SListClass::prepend (DWORD_PTR new_key)
  128. {
  129. if (Entries == NULL || NumOfEntries >= MaxEntries)
  130. if (! Expand ())
  131. return;
  132. ASSERT (Entries != NULL);
  133. ASSERT (NumOfEntries < MaxEntries);
  134. NumOfEntries++;
  135. if (HeadOffset == 0)
  136. HeadOffset = MaxEntries - 1;
  137. else
  138. HeadOffset--;
  139. Entries[HeadOffset] = new_key;
  140. }
  141. /* Function: find
  142. * Looks up a value in a DWORD_LIST list.
  143. *
  144. * Parameters:
  145. * Key: The value to look up
  146. *
  147. * Return value:
  148. * TRUE, if "Key" is found in the list. FALSE, otherwise.
  149. *
  150. */
  151. BOOL SListClass::find (DWORD_PTR Key)
  152. {
  153. DWORD i;
  154. DWORD_PTR *pItem; // Goes through the items in the list.
  155. for (i = 0, pItem = Entries + HeadOffset; i < NumOfEntries; i++) {
  156. if (Key == *pItem)
  157. return TRUE;
  158. // Advance the "pItem" pointer
  159. if ((DWORD) (++pItem - Entries) >= MaxEntries)
  160. pItem = Entries;
  161. }
  162. return FALSE;
  163. }
  164. /* Function: read
  165. * Reads an item from the list. The list item is not removed from the list.
  166. *
  167. * Parameters:
  168. * index: Index of the item to be read. 0 is the index of the 1st list item.
  169. * NumOfEntries - 1 is the last valid index.
  170. *
  171. * Return value:
  172. * The value at the index-th entry in the list. If the index is invalid, 0.
  173. *
  174. */
  175. DWORD_PTR SListClass::read (DWORD index)
  176. {
  177. DWORD dwTemp;
  178. if (index >= NumOfEntries)
  179. return 0;
  180. dwTemp = HeadOffset + index;
  181. if (dwTemp >= MaxEntries)
  182. dwTemp -= MaxEntries;
  183. return (Entries[dwTemp]);
  184. }
  185. /* Function: remove
  186. * Removes a value from the list
  187. *
  188. * Parameters:
  189. * Key: The value that has to be removed from the DWORD_LIST list
  190. *
  191. * Return value:
  192. * None.
  193. *
  194. */
  195. void SListClass::remove (DWORD_PTR Key)
  196. {
  197. DWORD i, dwTemp;
  198. DWORD_PTR *pItem; // Goes through the list items
  199. for (i = 0, pItem = Entries + HeadOffset; i < NumOfEntries; i++) {
  200. if (Key == *pItem) {
  201. // we found the "Key"; to remove it, we move the last value into its place.
  202. dwTemp = HeadOffset + (--NumOfEntries);
  203. if (dwTemp >= MaxEntries)
  204. dwTemp -= MaxEntries;
  205. *pItem = Entries[dwTemp];
  206. return;
  207. }
  208. // Advance the "pItem" pointer
  209. if ((DWORD) (++pItem - Entries) >= MaxEntries)
  210. pItem = Entries;
  211. }
  212. }
  213. /* Function: get
  214. * Reads and removes the 1st item from the list.
  215. *
  216. * Parameters:
  217. * None.
  218. *
  219. * Return value:
  220. * The value at the 1st entry in the list. If the list is empty, 0.
  221. *
  222. */
  223. DWORD_PTR SListClass::get (void)
  224. {
  225. DWORD_PTR return_value = 0;
  226. if (NumOfEntries > 0) {
  227. return_value = Entries[HeadOffset];
  228. NumOfEntries--;
  229. if (++HeadOffset >= MaxEntries)
  230. HeadOffset = 0;
  231. }
  232. return return_value;
  233. }
  234. /* Function: removeLast
  235. * Reads and removes the last item from the list
  236. *
  237. * Parameters:
  238. * None.
  239. *
  240. * Return value:
  241. * The value at the last entry in the list. If the list is empty, 0.
  242. *
  243. */
  244. DWORD_PTR SListClass::removeLast (void)
  245. {
  246. DWORD_PTR return_value = 0;
  247. DWORD dwTemp;
  248. if (NumOfEntries > 0) {
  249. dwTemp = HeadOffset + (--NumOfEntries);
  250. if (dwTemp >= MaxEntries)
  251. dwTemp -= MaxEntries;
  252. return_value = Entries[dwTemp];
  253. }
  254. return return_value;
  255. }
  256. /* Function: iterate
  257. * Iterates through the items of a list. It remembers where it has
  258. * stopped during the last call and starts from there.
  259. *
  260. * Parameters
  261. * pKey: Pointer to DWORD or unsigned short value to receive the next item's value.
  262. * It can be NULL.
  263. *
  264. * Return value:
  265. * FALSE, when we reach the end of the dictionary
  266. * TRUE, otherwise. Then, *pKey is valid
  267. *
  268. */
  269. BOOL SListClass::iterate (DWORD_PTR *pKey)
  270. {
  271. DWORD dwTemp;
  272. if (NumOfEntries <= 0)
  273. return FALSE;
  274. if (CurrOffset == 0xFFFFFFFF) {
  275. // start from the beginning
  276. CurrOffset = 0;
  277. }
  278. else {
  279. if (++CurrOffset >= NumOfEntries) {
  280. // reset the iterator
  281. CurrOffset = 0xFFFFFFFF;
  282. return FALSE;
  283. }
  284. }
  285. dwTemp = CurrOffset + HeadOffset;
  286. if (dwTemp >= MaxEntries)
  287. dwTemp -= MaxEntries;
  288. *pKey = Entries[dwTemp];
  289. return TRUE;
  290. }
  291.