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.
 
 
 
 
 
 

323 lines
7.6 KiB

//+-------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1996.
//
// File: clist.hxx
//
// Contents: Class to create and maintain a singly linked list.
//
// History: 28-Jun-96 MacM Created
//
//--------------------------------------------------------------------
#ifndef __CLIST_HXX__
#define __CLIST_HXX__
typedef struct _CSLIST_NODE
{
PVOID pvData;
struct _CSLIST_NODE *pNext;
} CSLIST_NODE, *PCSLIST_NODE;
//
// Free function callback typedef. This function will delete the memory saved
// as the data in a list node on list destruction
//
typedef VOID (*FreeFunc)(PVOID);
//
// This function returns TRUE if the two items are the same, or FALSE if they
// are not
//
typedef BOOL (*CompFunc)(PVOID, PVOID);
//+---------------------------------------------------------------------------
//
// Class: CSList
//
// Synopsis: Singly linked list class, single threaded
//
// Methods: Insert
// InsertIfUnique
// Find
// Reset
// NextData
// Remove
// QueryCount
//
//----------------------------------------------------------------------------
class CSList
{
public:
CSList(FreeFunc pfnFree) : _pfnFree (pfnFree),
_pHead (NULL),
_pCurrent (NULL),
_cItems (0)
{
};
inline ~CSList();
DWORD QueryCount(void) { return(_cItems);};
inline DWORD Insert(PVOID pvData);
inline DWORD InsertIfUnique(PVOID pvData,
CompFunc pfnComp);
inline PVOID Find(PVOID pvData,
CompFunc pfnComp);
inline PVOID NextData();
VOID Reset() {_pCurrent = _pHead;};
inline DWORD Remove(PVOID pData);
protected:
PCSLIST_NODE _pHead;
PCSLIST_NODE _pCurrent;
DWORD _cItems;
FreeFunc _pfnFree;
};
//+------------------------------------------------------------------
//
// Member: CSList::~CSList
//
// Synopsis: Destructor for the CSList class
//
// Arguments: None
//
// Returns: void
//
//+------------------------------------------------------------------
CSList::~CSList()
{
PCSLIST_NODE pNext = _pHead;
//
// We'll do this in 2 seperate, but almost identical loops, so that we
// don't have to check for a null free pointer in every loop iteration.
//
if(_pfnFree != NULL)
{
while(pNext != NULL)
{
pNext = _pHead->pNext;
(*_pfnFree)(_pHead->pvData);
delete _pHead;
_pHead = pNext;
}
}
else
{
while(pNext != NULL)
{
pNext = _pHead->pNext;
delete _pHead;
_pHead = pNext;
}
}
}
//+------------------------------------------------------------------
//
// Member: CSList::Insert
//
// Synopsis: Creates a new node at the begining of the list and
// inserts it into the list
//
//
// Arguments: [IN pvData] -- Data to insert
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
//
//+------------------------------------------------------------------
DWORD CSList::Insert(PVOID pvData)
{
DWORD dwErr = ERROR_SUCCESS;
PCSLIST_NODE pNew = new CSLIST_NODE;
if(pNew == NULL)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
}
else
{
pNew->pvData = pvData;
pNew->pNext = _pHead;
_pHead = pNew;
_cItems++;
}
return(dwErr);
}
//+------------------------------------------------------------------
//
// Member: CSList::InsertIfUnique
//
// Synopsis: Creates a new node at the begining of the list and
// inserts it into the list if the data does not already
// exist in the list. If the data does exist, nothing
// is done, but SUCCESS is returned
//
//
// Arguments: [IN pvData] -- Data to insert
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
//
//+------------------------------------------------------------------
DWORD CSList::InsertIfUnique(PVOID pvData,
CompFunc pfnComp)
{
DWORD dwErr = ERROR_SUCCESS;
//
// First, make sure it doesn't already exist, and then insert it
//
PCSLIST_NODE pWalk = _pHead;
while(pWalk)
{
if((pfnComp)(pvData, pWalk->pvData) == TRUE)
{
break;
}
pWalk = pWalk->pNext;
}
if(pWalk == NULL)
{
dwErr = Insert(pvData);
}
return(dwErr);
}
//+------------------------------------------------------------------
//
// Member: CSList::Find
//
// Synopsis: Locates the given data in the list, if it exists
//
// Arguments: [IN pvData] -- Data to insert
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
//
//+------------------------------------------------------------------
PVOID CSList::Find(PVOID pvData,
CompFunc pfnComp)
{
PCSLIST_NODE pWalk = _pHead;
while(pWalk)
{
if((pfnComp)(pvData, pWalk->pvData) == TRUE)
{
break;
}
pWalk = pWalk->pNext;
}
return(pWalk == NULL ? NULL : pWalk->pvData);
}
//+------------------------------------------------------------------
//
// Member: CSList::NextData
//
// Synopsis: Returns the next data in the list
//
//
// Arguments: None
//
// Returns: NULL -- No more items
// Pointer to next data in list on success
//
//+------------------------------------------------------------------
PVOID CSList::NextData()
{
PVOID pvRet = NULL;
if(_pCurrent != NULL)
{
pvRet = _pCurrent->pvData;
_pCurrent = _pCurrent->pNext;
}
return(pvRet);
}
//+------------------------------------------------------------------
//
// Member: CSList::Remove
//
// Synopsis: Removes the node that references the indicated data
//
// Arguments: pData -- The data in the node to remove
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_PARAMETER Node not found
//
//+------------------------------------------------------------------
DWORD CSList::Remove(PVOID pData)
{
PCSLIST_NODE pWalk = _pHead;
PCSLIST_NODE pPrev = NULL;
DWORD dwErr = ERROR_INVALID_PARAMETER;
while(pWalk)
{
if(pData == pWalk->pvData)
{
if(pPrev == NULL)
{
_pHead = pWalk->pNext;
}
else
{
pPrev->pNext = pWalk->pNext;
}
delete pWalk;
dwErr = ERROR_SUCCESS;
_cItems--;
break;
}
pPrev = pWalk;
pWalk = pWalk->pNext;
}
return(dwErr);
}
#endif // __CLIST_HXX__