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.

264 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name: conlist.cxx
  4. Abstract:
  5. Linked list of URL_CONTAINERs
  6. Author:
  7. Adriaan Canter (adriaanc) 04-02-97
  8. --*/
  9. #include <cache.hxx>
  10. /*------------------------ CConElem -----------------------------------------*/
  11. /*-----------------------------------------------------------------------------
  12. CConElem constructor
  13. ---------------------------------------------------------------------------*/
  14. CConElem::CConElem(URL_CONTAINER* pUrlCon)
  15. {
  16. _pUrlCon = pUrlCon;
  17. _pNext = NULL;
  18. }
  19. /*-----------------------------------------------------------------------------
  20. CConElem destructor. Destructs URL_CONTAINER* member.
  21. ---------------------------------------------------------------------------*/
  22. CConElem::~CConElem()
  23. {
  24. delete _pUrlCon;
  25. }
  26. /*------------------------ CConList Private Functions------------------------*/
  27. /*-----------------------------------------------------------------------------
  28. CConList::Seek Sets current pointer to element of index nElem.
  29. ---------------------------------------------------------------------------*/
  30. BOOL CConList::Seek(DWORD nElem)
  31. {
  32. // Bad list or index too high.
  33. if (!_pHead || nElem > _n)
  34. {
  35. INET_ASSERT(FALSE);
  36. return FALSE;
  37. }
  38. // Seek to element from current.
  39. if (nElem > _nCur)
  40. {
  41. while (_nCur < nElem)
  42. {
  43. _pCur = _pCur->_pNext;
  44. _nCur++;
  45. }
  46. }
  47. //
  48. // BUGBUG: VC5 optimizer assumes if (a < b), then (b > a), so check (a != b) instead
  49. //
  50. else if (nElem != _nCur) // if (nElem < _nCur)
  51. {
  52. // Seek to element from head.
  53. _nCur = 0;
  54. _pCur = _pHead;
  55. while (_nCur < nElem)
  56. {
  57. _pCur = _pCur->_pNext;
  58. _nCur++;
  59. }
  60. }
  61. INET_ASSERT(_nCur != 0 || (_pCur == _pHead));
  62. return TRUE;
  63. }
  64. /*------------------------ CConList Public Functions------------------------*/
  65. /*-----------------------------------------------------------------------------
  66. CConList constructor.
  67. ---------------------------------------------------------------------------*/
  68. CConList::CConList()
  69. : _n(0), _nCur(0), _pCur(NULL), _pHead(NULL)
  70. {
  71. }
  72. /*-----------------------------------------------------------------------------
  73. CConList destructor.
  74. ---------------------------------------------------------------------------*/
  75. CConList::~CConList()
  76. {
  77. }
  78. /*-----------------------------------------------------------------------------
  79. CConList::Size Returns number of elements in list.
  80. ---------------------------------------------------------------------------*/
  81. DWORD CConList::Size()
  82. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  83. {
  84. DWORD n = (_pHead ? _n+1 : 0);
  85. return n;
  86. }
  87. /*-----------------------------------------------------------------------------
  88. CConList::Free Removes and destructs each element in list.
  89. ---------------------------------------------------------------------------*/
  90. BOOL CConList::Free()
  91. {
  92. LOCK_CACHE();
  93. DWORD i = Size();
  94. // Delete CONTENT last, as we reference fields of it's header (dwChangeCount)
  95. // in destructors of extensible containers
  96. while (i)
  97. {
  98. Remove(--i);
  99. }
  100. UNLOCK_CACHE();
  101. return TRUE;
  102. }
  103. /*-----------------------------------------------------------------------------
  104. CConList::Add Appends new element to list.
  105. ---------------------------------------------------------------------------*/
  106. BOOL CConList::Add(URL_CONTAINER * pUrlCon)
  107. {
  108. LOCK_CACHE();
  109. BOOL bSuccess = FALSE;
  110. CConElem *pNew;
  111. DWORD i;
  112. // Bad pointer.
  113. if (!pUrlCon)
  114. {
  115. INET_ASSERT(FALSE);
  116. goto exit;
  117. }
  118. if (_pHead)
  119. {
  120. // try to reuse a Container which has been deleted
  121. for (i = 0; i <= _n; i++)
  122. {
  123. if (Seek(i))
  124. {
  125. if (_pCur->_pUrlCon->GetDeleted())
  126. {
  127. delete _pCur->_pUrlCon;
  128. _pCur->_pUrlCon = pUrlCon;
  129. bSuccess = TRUE;
  130. goto exit;
  131. }
  132. }
  133. }
  134. }
  135. // Construct new element.
  136. pNew = new CConElem(pUrlCon);
  137. if (!pNew)
  138. {
  139. INET_ASSERT(FALSE);
  140. goto exit;
  141. }
  142. // If valid list, seek to last element and add element.
  143. if (_pHead)
  144. {
  145. if (_n == LARGEST_INDEX)
  146. {
  147. delete pNew;
  148. INET_ASSERT(FALSE);
  149. goto exit;
  150. }
  151. Seek(_n);
  152. _pCur->_pNext = pNew;
  153. pNew->_pNext = _pHead;
  154. _n++;
  155. }
  156. // If empty list, set head and current to new element.
  157. else
  158. {
  159. _pHead = _pCur = pNew;
  160. pNew->_pNext = _pHead;
  161. _n = _nCur = 0;
  162. }
  163. bSuccess = TRUE;
  164. exit:
  165. UNLOCK_CACHE();
  166. return bSuccess;
  167. }
  168. /*-----------------------------------------------------------------------------
  169. CConList::Remove Removes nElem'th element from list.
  170. ---------------------------------------------------------------------------*/
  171. BOOL CConList::Remove(DWORD nElem)
  172. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  173. {
  174. DWORD nPrev;
  175. CConElem *pElem;
  176. BOOL bSuccess = FALSE;
  177. // Empty list or index too high.
  178. if (!_pHead || nElem > _n)
  179. {
  180. INET_ASSERT(FALSE);
  181. goto exit;
  182. }
  183. // Seek to previous element, or last if removing head.
  184. nPrev = (nElem == 0 ? _n : nElem - 1);
  185. Seek(nPrev);
  186. // Save pointer to element, update prevous' next pointer.
  187. pElem = _pCur->_pNext;
  188. _pCur->_pNext = _pCur->_pNext->_pNext;
  189. // Update head if necessary.
  190. if (nElem == 0)
  191. _pHead = _pHead->_pNext;
  192. // Decrement index of last, zero out values if empty.
  193. if (_n > 0)
  194. _n--;
  195. else
  196. {
  197. _pHead = _pCur = NULL;
  198. _n = _nCur = 0;
  199. }
  200. // Destruct element.
  201. delete pElem;
  202. bSuccess = TRUE;
  203. exit:
  204. return bSuccess;
  205. }
  206. /*-----------------------------------------------------------------------------
  207. CConList::operator Get Returns Addref'ed reference to URL_CONTAINER* of index nElem.
  208. ---------------------------------------------------------------------------*/
  209. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  210. URL_CONTAINER* CConList::Get (DWORD nElem)
  211. {
  212. URL_CONTAINER* pUrlCon;
  213. if (Seek(nElem))
  214. pUrlCon = _pCur->_pUrlCon;
  215. else
  216. pUrlCon = NULL;
  217. if (pUrlCon) pUrlCon->AddRef();
  218. return pUrlCon;
  219. }