windows-nt/Source/XPSP1/NT/enduser/netmeeting/nmutil/oblist.cpp
2020-09-26 16:20:57 +08:00

198 lines
3.2 KiB
C++

// ChrisPi: This is a quick attempt to create a list class that uses the
// same member functions and parameters as MFC's CObList. Only the members
// used in DCL's master objects are implemented.
#include "precomp.h"
#include <oblist.h>
#ifdef DEBUG
VOID* COBLIST::GetHead()
{
ASSERT(m_pHead);
return m_pHead->pItem;
}
#endif // ifdef DEBUG
VOID* COBLIST::GetTail()
{
ASSERT(m_pTail);
return m_pTail->pItem;
}
VOID* COBLIST::GetNext(POSITION& rPos)
{
ASSERT(rPos);
VOID* pReturn = rPos->pItem;
rPos = rPos->pNext;
return pReturn;
}
VOID* COBLIST::RemoveAt(POSITION Pos)
{
VOID* pReturn = NULL;
if (m_pHead)
{
if (m_pHead == Pos)
{
// Removing the first element in the list
m_pHead = Pos->pNext;
pReturn = Pos->pItem;
delete Pos;
if (NULL == m_pHead)
{
// Removing the only element!
m_pTail = NULL;
}
}
else
{
POSITION pCur = m_pHead;
while (pCur && pCur->pNext)
{
if (pCur->pNext == Pos)
{
// Removing
pCur->pNext = Pos->pNext;
if (m_pTail == Pos)
{
m_pTail = pCur;
}
pReturn = Pos->pItem;
delete Pos;
}
pCur = pCur->pNext;
}
}
}
return pReturn;
}
POSITION COBLIST::AddTail(VOID* pItem)
{
POSITION posRet = NULL;
if (m_pTail)
{
if (m_pTail->pNext = new COBNODE)
{
m_pTail = m_pTail->pNext;
m_pTail->pItem = pItem;
m_pTail->pNext = NULL;
}
}
else
{
ASSERT(!m_pHead);
if (m_pHead = new COBNODE)
{
m_pTail = m_pHead;
m_pTail->pItem = pItem;
m_pTail->pNext = NULL;
}
}
return m_pTail;
}
void COBLIST::EmptyList()
{
while (!IsEmpty()) {
RemoveAt(GetHeadPosition());
}
}
COBLIST::~COBLIST()
{
ASSERT(IsEmpty());
}
#ifdef DEBUG
#if 0
VOID* COBLIST::RemoveTail()
{
ASSERT(m_pHead);
ASSERT(m_pTail);
return RemoveAt(m_pTail);
}
#endif
VOID* COBLIST::RemoveHead()
{
ASSERT(m_pHead);
ASSERT(m_pTail);
return RemoveAt(m_pHead);
}
void * COBLIST::GetFromPosition(POSITION Pos)
{
void * Result = SafeGetFromPosition(Pos);
ASSERT(Result);
return Result;
}
#endif /* if DEBUG */
POSITION COBLIST::GetPosition(void* _pItem)
{
// For potential efficiency of lookup (if we switched to
// a doubly linked list), users should really store the POSITION
// of an item. For those that don't, this method is provided.
POSITION Position = m_pHead;
while (Position) {
if (Position->pItem == _pItem) {
break;
}
GetNext(Position);
}
return Position;
}
POSITION COBLIST::Lookup(void* pComparator)
{
POSITION Position = m_pHead;
while (Position) {
if (Compare(Position->pItem, pComparator)) {
break;
}
GetNext(Position);
}
return Position;
}
void * COBLIST::SafeGetFromPosition(POSITION Pos)
{
// Safe way to validate that an entry is still in the list,
// which ensures bugs that would reference deleted memory,
// reference a NULL pointer instead
// (e.g. an event handler fires late/twice).
// Note that versioning on entries would provide an additional
// safeguard against re-use of a position.
// Walk list to find entry.
POSITION PosWork = m_pHead;
while (PosWork) {
if (PosWork == Pos) {
return Pos->pItem;
}
GetNext(PosWork);
}
return NULL;
}