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.
 
 
 
 
 
 

413 lines
7.7 KiB

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
vs_list.h
Abstract:
CVssDLList definition
Author:
Adi Oltean [aoltean] 11/23/1999
Revision History:
Stefan Steiner [ssteiner] 02-21-2000
Removed VolSnapshot specific code to reuse for fsdump. Added
the optional compiling of the signature checking code.
--*/
#ifndef __VSS_DLLIST_HXX__
#define __VSS_DLLIST_HXX__
#if _MSC_VER > 1000
#pragma once
#endif
typedef PVOID VS_COOKIE;
/////////////////////////////////////////////////////////////////////////////
// Constants
const VS_COOKIE VS_NULL_COOKIE = NULL;
const DWORD VS_ELEMENT_SIGNATURE = 0x47e347e4;
/////////////////////////////////////////////////////////////////////////////
// Forward declarations
template <class T> class CVssDLList;
template <class T> class CVssDLListIterator;
template <class T> class CVssDLListElement;
/////////////////////////////////////////////////////////////////////////////
// CVssDLList
template <class T>
class CVssDLList
{
// Constructors& Destructors
private:
CVssDLList(const CVssDLList&);
public:
CVssDLList():
m_pFirst(NULL), m_pLast(NULL), m_dwNumElements( 0 ) {};
~CVssDLList()
{
ClearAll();
}
// Attributes
public:
bool IsEmpty() const;
DWORD Size() { return m_dwNumElements; }
// Operations
public:
VS_COOKIE Add(
IN const T& object
);
VS_COOKIE AddTail(
IN const T& object
);
bool Extract(
OUT T& refObject
);
bool ExtractTail(
OUT T& refObject
);
void ExtractByCookie(
IN VS_COOKIE cookie,
OUT T& refObject
);
void ClearAll();
private:
bool IsValid() const;
// Data members
private:
CVssDLListElement<T>* m_pFirst;
CVssDLListElement<T>* m_pLast;
DWORD m_dwNumElements;
friend class CVssDLListIterator<T>;
};
/////////////////////////////////////////////////////////////////////////////
// CVssDLListIterator
template <class T>
class CVssDLListIterator
{
private:
CVssDLListIterator();
CVssDLListIterator(const CVssDLListIterator&);
public:
CVssDLListIterator(const CVssDLList<T>& list):
m_List(list),
m_pNextInEnum(list.m_pFirst)
{};
bool GetNext( OUT T& refObject );
VOID Reset() { m_pNextInEnum = m_List.m_pFirst; }
private:
const CVssDLList<T>& m_List;
const CVssDLListElement<T>* m_pNextInEnum;
};
/////////////////////////////////////////////////////////////////////////////
// CVssDLListElement
template <class T>
class CVssDLListElement
{
// Constructors& Destructors
private:
CVssDLListElement();
CVssDLListElement(const CVssDLListElement&);
public:
CVssDLListElement( IN const T& object ):
m_Object(object),
m_pNext(NULL),
m_pPrev(NULL)
{
#ifndef NDEBUG
m_dwSignature = VS_ELEMENT_SIGNATURE;
#endif
};
// Attributes
public:
bool IsValid() const
{
#ifndef NDEBUG
return (m_dwSignature == VS_ELEMENT_SIGNATURE);
#else
return ( TRUE );
#endif
};
// Data members
public:
#ifndef NDEBUG
DWORD m_dwSignature;
#endif
CVssDLListElement* m_pPrev;
CVssDLListElement* m_pNext;
T m_Object;
};
/////////////////////////////////////////////////////////////////////////////
// CVssDLList implementation
template <class T>
bool CVssDLList<T>::IsEmpty() const
{
assert(IsValid());
return (m_pFirst == NULL);
}
template <class T>
VS_COOKIE CVssDLList<T>::Add(
IN const T& object
)
{
assert(IsValid());
CVssDLListElement<T>* pElement = new CVssDLListElement<T>(object);
if (pElement == NULL)
return VS_NULL_COOKIE;
// Setting neighbour element links
if (m_pFirst)
{
assert(m_pFirst->m_pPrev == NULL);
m_pFirst->m_pPrev = pElement;
}
// Setting element links
assert(pElement->m_pNext == NULL);
assert(pElement->m_pPrev == NULL);
if (m_pFirst)
pElement->m_pNext = m_pFirst;
// Setting list head links
m_pFirst = pElement;
if (m_pLast == NULL)
m_pLast = pElement;
++m_dwNumElements;
return reinterpret_cast<VS_COOKIE>(pElement);
}
template <class T>
VS_COOKIE CVssDLList<T>::AddTail(
IN const T& object
)
{
assert(IsValid());
CVssDLListElement<T>* pElement = new CVssDLListElement<T>(object);
if (pElement == NULL)
return VS_NULL_COOKIE;
// Setting neighbour element links
if (m_pLast)
{
assert(m_pLast->m_pNext == NULL);
m_pLast->m_pNext = pElement;
}
// Setting element links
assert(pElement->m_pNext == NULL);
assert(pElement->m_pPrev == NULL);
if (m_pLast)
pElement->m_pPrev = m_pLast;
// Setting list head links
if (m_pFirst == NULL)
m_pFirst = pElement;
m_pLast = pElement;
++m_dwNumElements;
return reinterpret_cast<VS_COOKIE>(pElement);
}
template <class T>
void CVssDLList<T>::ExtractByCookie(
IN VS_COOKIE cookie,
OUT T& refObject
)
{
if (cookie == VS_NULL_COOKIE)
return;
CVssDLListElement<T>* pElement =
reinterpret_cast<CVssDLListElement<T>*>(cookie);
assert(pElement);
assert(pElement->IsValid());
// Setting neighbours links
if (pElement->m_pPrev)
pElement->m_pPrev->m_pNext = pElement->m_pNext;
if (pElement->m_pNext)
pElement->m_pNext->m_pPrev = pElement->m_pPrev;
// Setting list head links
if (m_pFirst == pElement)
m_pFirst = pElement->m_pNext;
if (m_pLast == pElement)
m_pLast = pElement->m_pPrev;
// Destroying the element after getting the original object.
refObject = pElement->m_Object;
delete pElement;
--m_dwNumElements;
}
template <class T>
bool CVssDLList<T>::Extract(
OUT T& refObject
)
{
CVssDLListElement<T>* pElement = m_pFirst;
if (pElement == NULL)
return false;
assert(pElement->IsValid());
// Setting neighbours links
assert(pElement->m_pPrev == NULL);
if (pElement->m_pNext)
pElement->m_pNext->m_pPrev = NULL;
// Setting list head links
m_pFirst = pElement->m_pNext;
if (m_pLast == pElement)
m_pLast = NULL;
// Destroying the element after getting the original object.
refObject = pElement->m_Object;
delete pElement;
--m_dwNumElements;
return true;
}
template <class T>
bool CVssDLList<T>::ExtractTail(
OUT T& refObject
)
{
CVssDLListElement<T>* pElement = m_pLast;
if (pElement == NULL)
return false;
assert(pElement->IsValid());
// Setting neighbours links
assert(pElement->m_pNext == NULL);
if (pElement->m_pPrev)
pElement->m_pPrev->m_pNext = NULL;
// Setting list head links
m_pLast = pElement->m_pPrev;
if (m_pFirst == pElement)
m_pFirst = NULL;
// Destroying the element after getting the original object.
refObject = pElement->m_Object;
delete pElement;
--m_dwNumElements;
return true;
}
template <class T>
void CVssDLList<T>::ClearAll(
)
{
CVssDLListElement<T>* pElement = m_pFirst;
CVssDLListElement<T>* pNextElem;
while( pElement != NULL )
{
pNextElem = pElement->m_pNext;
delete pElement;
pElement = pNextElem;
}
m_pFirst = NULL;
m_pLast = NULL;
m_dwNumElements = 0;
}
template <class T>
bool CVssDLList<T>::IsValid() const
{
if ((m_pFirst == NULL) && (m_pLast == NULL))
return true;
if ((m_pFirst != NULL) && (m_pLast != NULL))
return (m_pFirst->IsValid() && m_pLast->IsValid());
return false;
}
/////////////////////////////////////////////////////////////////////////////
// CVssDLListIterator implementation
template <class T>
bool CVssDLListIterator<T>::GetNext( OUT T& object )
{
if (m_pNextInEnum == NULL)
return false;
else
{
object = m_pNextInEnum->m_Object;
m_pNextInEnum = m_pNextInEnum->m_pNext;
return true;
}
}
#endif // __VSS_DLLIST_HXX__