Source code of Windows XP (NT5)
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.

194 lines
4.5 KiB

  1. #ifndef _LIST_H
  2. #define _LIST_H
  3. #include "msoedbg.h"
  4. // =================================================================================
  5. // CNode class definition and implementation
  6. // =================================================================================
  7. template<class Value_T>
  8. class CNode
  9. {
  10. private:
  11. CNode<Value_T> *m_pNext,
  12. *m_pPrev;
  13. Value_T m_pValue;
  14. public:
  15. CNode<Value_T>(): m_pNext(NULL), m_pPrev(NULL), m_pValue(0) {}
  16. CNode<Value_T>* GetNext() {return m_pNext;}
  17. CNode<Value_T>* GetPrev() {return m_pPrev;}
  18. void SetNext(CNode<Value_T> *pNext) {m_pNext = pNext;}
  19. void SetPrev(CNode<Value_T> *pPrev) {m_pPrev = pPrev;}
  20. Value_T GetValue() {return m_pValue;}
  21. static HRESULT CreateNode(CNode<Value_T> **ppNode, Value_T value);
  22. };
  23. //***************************************************
  24. template<class Value_T>
  25. HRESULT CNode<Value_T>::CreateNode(CNode<Value_T> **ppNode, Value_T value)
  26. {
  27. HRESULT hr = S_OK;
  28. CNode<Value_T> *pNode = new CNode<Value_T>;
  29. if (NULL == pNode)
  30. {
  31. hr = E_OUTOFMEMORY;
  32. goto Exit;
  33. }
  34. pNode->m_pValue = value;
  35. Exit:
  36. *ppNode = pNode;
  37. return hr;
  38. }
  39. // =================================================================================
  40. // CList template class
  41. // Basic list for keeping some class Value_T
  42. // Value_T must have AddRef and Release defined
  43. // =================================================================================
  44. template<class Value_T>
  45. class CList
  46. {
  47. private:
  48. CNode<Value_T> *m_pHead;
  49. ULONG m_cCount;
  50. public:
  51. CList<Value_T>();
  52. ~CList<Value_T>();
  53. void ClearList();
  54. ULONG GetCount() {return m_cCount;}
  55. HRESULT AddValue(Value_T value, DWORD *pdwCookie);
  56. HRESULT RemoveValue(DWORD dwCookie);
  57. HRESULT GetNext(Value_T *value, DWORD *pdwCookie);
  58. };
  59. // =================================================================================
  60. // CList function implementaions
  61. // =================================================================================
  62. template<class Value_T>
  63. CList<Value_T>::CList<Value_T>(): m_pHead(NULL), m_cCount(0)
  64. {
  65. }
  66. //***************************************************
  67. template<class Value_T>
  68. CList<Value_T>::~CList<Value_T>()
  69. {
  70. ClearList();
  71. }
  72. //***************************************************
  73. template<class Value_T>
  74. void CList<Value_T>::ClearList()
  75. {
  76. CNode<Value_T> *pNext;
  77. while (m_pHead)
  78. {
  79. pNext = m_pHead->GetNext();
  80. (m_pHead->GetValue())->Release();
  81. delete m_pHead;
  82. m_pHead = pNext;
  83. }
  84. m_cCount = 0;
  85. }
  86. //***************************************************
  87. template<class Value_T>
  88. HRESULT CList<Value_T>::AddValue(Value_T value, DWORD *pdwCookie)
  89. {
  90. CNode<Value_T> *pNode = NULL;
  91. HRESULT hr = CNode<Value_T>::CreateNode(&pNode, value);
  92. if (SUCCEEDED(hr))
  93. {
  94. value->AddRef();
  95. m_cCount++;
  96. if (m_pHead)
  97. {
  98. m_pHead->SetPrev(pNode);
  99. pNode->SetNext(m_pHead);
  100. }
  101. m_pHead = pNode;
  102. *pdwCookie = reinterpret_cast<DWORD>(pNode);
  103. }
  104. else
  105. *pdwCookie = 0;
  106. return hr;
  107. }
  108. //***************************************************
  109. template<class Value_T>
  110. HRESULT CList<Value_T>::RemoveValue(DWORD dwCookie)
  111. {
  112. CNode<Value_T> *pCurr = reinterpret_cast< CNode<Value_T>* >(dwCookie);
  113. CNode<Value_T> *pPrev = pCurr->GetPrev(),
  114. *pNext = pCurr->GetNext();
  115. Assert(pCurr);
  116. if (pPrev)
  117. pPrev->SetNext(pNext);
  118. else
  119. m_pHead = pNext;
  120. if (pNext)
  121. pNext->SetPrev(pPrev);
  122. (pCurr->GetValue())->Release();
  123. delete pCurr;
  124. m_cCount--;
  125. return S_OK;
  126. }
  127. //***************************************************
  128. // *pdwCookie must equal 0 for first time.
  129. template<class Value_T>
  130. HRESULT CList<Value_T>::GetNext(Value_T *pValue, DWORD* pdwCookie)
  131. {
  132. CNode<Value_T> *pNode = reinterpret_cast< CNode<Value_T>* >(*pdwCookie);
  133. if (0 == m_cCount)
  134. return E_FAIL;
  135. if (pNode)
  136. {
  137. pNode = pNode->GetNext();
  138. if (!pNode)
  139. {
  140. *pdwCookie = 0;
  141. *pValue = 0;
  142. return E_FAIL;
  143. }
  144. }
  145. else
  146. pNode = m_pHead;
  147. if (pNode)
  148. {
  149. *pValue = pNode->GetValue();
  150. *pdwCookie = reinterpret_cast<DWORD>(pNode);
  151. (*pValue)->AddRef();
  152. }
  153. else
  154. {
  155. *pValue = NULL;
  156. *pdwCookie = 0;
  157. }
  158. return S_OK;
  159. }
  160. #endif