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.
 
 
 
 
 
 

195 lines
4.5 KiB

#ifndef _LIST_H
#define _LIST_H
#include "msoedbg.h"
// =================================================================================
// CNode class definition and implementation
// =================================================================================
template<class Value_T>
class CNode
{
private:
CNode<Value_T> *m_pNext,
*m_pPrev;
Value_T m_pValue;
public:
CNode<Value_T>(): m_pNext(NULL), m_pPrev(NULL), m_pValue(0) {}
CNode<Value_T>* GetNext() {return m_pNext;}
CNode<Value_T>* GetPrev() {return m_pPrev;}
void SetNext(CNode<Value_T> *pNext) {m_pNext = pNext;}
void SetPrev(CNode<Value_T> *pPrev) {m_pPrev = pPrev;}
Value_T GetValue() {return m_pValue;}
static HRESULT CreateNode(CNode<Value_T> **ppNode, Value_T value);
};
//***************************************************
template<class Value_T>
HRESULT CNode<Value_T>::CreateNode(CNode<Value_T> **ppNode, Value_T value)
{
HRESULT hr = S_OK;
CNode<Value_T> *pNode = new CNode<Value_T>;
if (NULL == pNode)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
pNode->m_pValue = value;
Exit:
*ppNode = pNode;
return hr;
}
// =================================================================================
// CList template class
// Basic list for keeping some class Value_T
// Value_T must have AddRef and Release defined
// =================================================================================
template<class Value_T>
class CList
{
private:
CNode<Value_T> *m_pHead;
ULONG m_cCount;
public:
CList<Value_T>();
~CList<Value_T>();
void ClearList();
ULONG GetCount() {return m_cCount;}
HRESULT AddValue(Value_T value, DWORD *pdwCookie);
HRESULT RemoveValue(DWORD dwCookie);
HRESULT GetNext(Value_T *value, DWORD *pdwCookie);
};
// =================================================================================
// CList function implementaions
// =================================================================================
template<class Value_T>
CList<Value_T>::CList<Value_T>(): m_pHead(NULL), m_cCount(0)
{
}
//***************************************************
template<class Value_T>
CList<Value_T>::~CList<Value_T>()
{
ClearList();
}
//***************************************************
template<class Value_T>
void CList<Value_T>::ClearList()
{
CNode<Value_T> *pNext;
while (m_pHead)
{
pNext = m_pHead->GetNext();
(m_pHead->GetValue())->Release();
delete m_pHead;
m_pHead = pNext;
}
m_cCount = 0;
}
//***************************************************
template<class Value_T>
HRESULT CList<Value_T>::AddValue(Value_T value, DWORD *pdwCookie)
{
CNode<Value_T> *pNode = NULL;
HRESULT hr = CNode<Value_T>::CreateNode(&pNode, value);
if (SUCCEEDED(hr))
{
value->AddRef();
m_cCount++;
if (m_pHead)
{
m_pHead->SetPrev(pNode);
pNode->SetNext(m_pHead);
}
m_pHead = pNode;
*pdwCookie = reinterpret_cast<DWORD>(pNode);
}
else
*pdwCookie = 0;
return hr;
}
//***************************************************
template<class Value_T>
HRESULT CList<Value_T>::RemoveValue(DWORD dwCookie)
{
CNode<Value_T> *pCurr = reinterpret_cast< CNode<Value_T>* >(dwCookie);
CNode<Value_T> *pPrev = pCurr->GetPrev(),
*pNext = pCurr->GetNext();
Assert(pCurr);
if (pPrev)
pPrev->SetNext(pNext);
else
m_pHead = pNext;
if (pNext)
pNext->SetPrev(pPrev);
(pCurr->GetValue())->Release();
delete pCurr;
m_cCount--;
return S_OK;
}
//***************************************************
// *pdwCookie must equal 0 for first time.
template<class Value_T>
HRESULT CList<Value_T>::GetNext(Value_T *pValue, DWORD* pdwCookie)
{
CNode<Value_T> *pNode = reinterpret_cast< CNode<Value_T>* >(*pdwCookie);
if (0 == m_cCount)
return E_FAIL;
if (pNode)
{
pNode = pNode->GetNext();
if (!pNode)
{
*pdwCookie = 0;
*pValue = 0;
return E_FAIL;
}
}
else
pNode = m_pHead;
if (pNode)
{
*pValue = pNode->GetValue();
*pdwCookie = reinterpret_cast<DWORD>(pNode);
(*pValue)->AddRef();
}
else
{
*pValue = NULL;
*pdwCookie = 0;
}
return S_OK;
}
#endif