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.

197 lines
3.4 KiB

  1. // ChrisPi: This is a quick attempt to create a list class that uses the
  2. // same member functions and parameters as MFC's CObList. Only the members
  3. // used in DCL's master objects are implemented.
  4. #include "precomp.h"
  5. #include <oblist.h>
  6. #ifdef DEBUG
  7. VOID* COBLIST::GetHead()
  8. {
  9. ASSERT(m_pHead);
  10. return m_pHead->pItem;
  11. }
  12. #endif // ifdef DEBUG
  13. VOID* COBLIST::GetTail()
  14. {
  15. ASSERT(m_pTail);
  16. return m_pTail->pItem;
  17. }
  18. VOID* COBLIST::GetNext(POSITION& rPos)
  19. {
  20. ASSERT(rPos);
  21. VOID* pReturn = rPos->pItem;
  22. rPos = rPos->pNext;
  23. return pReturn;
  24. }
  25. VOID* COBLIST::RemoveAt(POSITION Pos)
  26. {
  27. VOID* pReturn = NULL;
  28. if (m_pHead)
  29. {
  30. if (m_pHead == Pos)
  31. {
  32. // Removing the first element in the list
  33. m_pHead = Pos->pNext;
  34. pReturn = Pos->pItem;
  35. delete Pos;
  36. if (NULL == m_pHead)
  37. {
  38. // Removing the only element!
  39. m_pTail = NULL;
  40. }
  41. }
  42. else
  43. {
  44. POSITION pCur = m_pHead;
  45. while (pCur && pCur->pNext)
  46. {
  47. if (pCur->pNext == Pos)
  48. {
  49. // Removing
  50. pCur->pNext = Pos->pNext;
  51. if (m_pTail == Pos)
  52. {
  53. m_pTail = pCur;
  54. }
  55. pReturn = Pos->pItem;
  56. delete Pos;
  57. }
  58. pCur = pCur->pNext;
  59. }
  60. }
  61. }
  62. return pReturn;
  63. }
  64. POSITION COBLIST::AddTail(VOID* pItem)
  65. {
  66. POSITION posRet = NULL;
  67. if (m_pTail)
  68. {
  69. if (m_pTail->pNext = new COBNODE)
  70. {
  71. m_pTail = m_pTail->pNext;
  72. m_pTail->pItem = pItem;
  73. m_pTail->pNext = NULL;
  74. }
  75. }
  76. else
  77. {
  78. ASSERT(!m_pHead);
  79. if (m_pHead = new COBNODE)
  80. {
  81. m_pTail = m_pHead;
  82. m_pTail->pItem = pItem;
  83. m_pTail->pNext = NULL;
  84. }
  85. }
  86. return m_pTail;
  87. }
  88. void COBLIST::EmptyList()
  89. {
  90. while (!IsEmpty()) {
  91. RemoveAt(GetHeadPosition());
  92. }
  93. }
  94. COBLIST::~COBLIST()
  95. {
  96. ASSERT(IsEmpty());
  97. }
  98. #ifdef DEBUG
  99. #if 0
  100. VOID* COBLIST::RemoveTail()
  101. {
  102. ASSERT(m_pHead);
  103. ASSERT(m_pTail);
  104. return RemoveAt(m_pTail);
  105. }
  106. #endif
  107. VOID* COBLIST::RemoveHead()
  108. {
  109. ASSERT(m_pHead);
  110. ASSERT(m_pTail);
  111. return RemoveAt(m_pHead);
  112. }
  113. void * COBLIST::GetFromPosition(POSITION Pos)
  114. {
  115. void * Result = SafeGetFromPosition(Pos);
  116. ASSERT(Result);
  117. return Result;
  118. }
  119. #endif /* if DEBUG */
  120. POSITION COBLIST::GetPosition(void* _pItem)
  121. {
  122. // For potential efficiency of lookup (if we switched to
  123. // a doubly linked list), users should really store the POSITION
  124. // of an item. For those that don't, this method is provided.
  125. POSITION Position = m_pHead;
  126. while (Position) {
  127. if (Position->pItem == _pItem) {
  128. break;
  129. }
  130. GetNext(Position);
  131. }
  132. return Position;
  133. }
  134. POSITION COBLIST::Lookup(void* pComparator)
  135. {
  136. POSITION Position = m_pHead;
  137. while (Position) {
  138. if (Compare(Position->pItem, pComparator)) {
  139. break;
  140. }
  141. GetNext(Position);
  142. }
  143. return Position;
  144. }
  145. void * COBLIST::SafeGetFromPosition(POSITION Pos)
  146. {
  147. // Safe way to validate that an entry is still in the list,
  148. // which ensures bugs that would reference deleted memory,
  149. // reference a NULL pointer instead
  150. // (e.g. an event handler fires late/twice).
  151. // Note that versioning on entries would provide an additional
  152. // safeguard against re-use of a position.
  153. // Walk list to find entry.
  154. POSITION PosWork = m_pHead;
  155. while (PosWork) {
  156. if (PosWork == Pos) {
  157. return Pos->pItem;
  158. }
  159. GetNext(PosWork);
  160. }
  161. return NULL;
  162. }