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.
|
|
//+-------------------------------------------------------------------
//
// 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__
|