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

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. vs_list.h
  5. Abstract:
  6. CVssDLList definition
  7. Author:
  8. Adi Oltean [aoltean] 11/23/1999
  9. Revision History:
  10. Stefan Steiner [ssteiner] 02-21-2000
  11. Removed VolSnapshot specific code to reuse for fsdump. Added
  12. the optional compiling of the signature checking code.
  13. --*/
  14. #ifndef __VSS_DLLIST_HXX__
  15. #define __VSS_DLLIST_HXX__
  16. #if _MSC_VER > 1000
  17. #pragma once
  18. #endif
  19. typedef PVOID VS_COOKIE;
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Constants
  22. const VS_COOKIE VS_NULL_COOKIE = NULL;
  23. const DWORD VS_ELEMENT_SIGNATURE = 0x47e347e4;
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Forward declarations
  26. template <class T> class CVssDLList;
  27. template <class T> class CVssDLListIterator;
  28. template <class T> class CVssDLListElement;
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CVssDLList
  31. template <class T>
  32. class CVssDLList
  33. {
  34. // Constructors& Destructors
  35. private:
  36. CVssDLList(const CVssDLList&);
  37. public:
  38. CVssDLList():
  39. m_pFirst(NULL), m_pLast(NULL), m_dwNumElements( 0 ) {};
  40. ~CVssDLList()
  41. {
  42. ClearAll();
  43. }
  44. // Attributes
  45. public:
  46. bool IsEmpty() const;
  47. DWORD Size() { return m_dwNumElements; }
  48. // Operations
  49. public:
  50. VS_COOKIE Add(
  51. IN const T& object
  52. );
  53. VS_COOKIE AddTail(
  54. IN const T& object
  55. );
  56. bool Extract(
  57. OUT T& refObject
  58. );
  59. bool ExtractTail(
  60. OUT T& refObject
  61. );
  62. void ExtractByCookie(
  63. IN VS_COOKIE cookie,
  64. OUT T& refObject
  65. );
  66. void ClearAll();
  67. private:
  68. bool IsValid() const;
  69. // Data members
  70. private:
  71. CVssDLListElement<T>* m_pFirst;
  72. CVssDLListElement<T>* m_pLast;
  73. DWORD m_dwNumElements;
  74. friend class CVssDLListIterator<T>;
  75. };
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CVssDLListIterator
  78. template <class T>
  79. class CVssDLListIterator
  80. {
  81. private:
  82. CVssDLListIterator();
  83. CVssDLListIterator(const CVssDLListIterator&);
  84. public:
  85. CVssDLListIterator(const CVssDLList<T>& list):
  86. m_List(list),
  87. m_pNextInEnum(list.m_pFirst)
  88. {};
  89. bool GetNext( OUT T& refObject );
  90. VOID Reset() { m_pNextInEnum = m_List.m_pFirst; }
  91. private:
  92. const CVssDLList<T>& m_List;
  93. const CVssDLListElement<T>* m_pNextInEnum;
  94. };
  95. /////////////////////////////////////////////////////////////////////////////
  96. // CVssDLListElement
  97. template <class T>
  98. class CVssDLListElement
  99. {
  100. // Constructors& Destructors
  101. private:
  102. CVssDLListElement();
  103. CVssDLListElement(const CVssDLListElement&);
  104. public:
  105. CVssDLListElement( IN const T& object ):
  106. m_Object(object),
  107. m_pNext(NULL),
  108. m_pPrev(NULL)
  109. {
  110. #ifndef NDEBUG
  111. m_dwSignature = VS_ELEMENT_SIGNATURE;
  112. #endif
  113. };
  114. // Attributes
  115. public:
  116. bool IsValid() const
  117. {
  118. #ifndef NDEBUG
  119. return (m_dwSignature == VS_ELEMENT_SIGNATURE);
  120. #else
  121. return ( TRUE );
  122. #endif
  123. };
  124. // Data members
  125. public:
  126. #ifndef NDEBUG
  127. DWORD m_dwSignature;
  128. #endif
  129. CVssDLListElement* m_pPrev;
  130. CVssDLListElement* m_pNext;
  131. T m_Object;
  132. };
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CVssDLList implementation
  135. template <class T>
  136. bool CVssDLList<T>::IsEmpty() const
  137. {
  138. assert(IsValid());
  139. return (m_pFirst == NULL);
  140. }
  141. template <class T>
  142. VS_COOKIE CVssDLList<T>::Add(
  143. IN const T& object
  144. )
  145. {
  146. assert(IsValid());
  147. CVssDLListElement<T>* pElement = new CVssDLListElement<T>(object);
  148. if (pElement == NULL)
  149. return VS_NULL_COOKIE;
  150. // Setting neighbour element links
  151. if (m_pFirst)
  152. {
  153. assert(m_pFirst->m_pPrev == NULL);
  154. m_pFirst->m_pPrev = pElement;
  155. }
  156. // Setting element links
  157. assert(pElement->m_pNext == NULL);
  158. assert(pElement->m_pPrev == NULL);
  159. if (m_pFirst)
  160. pElement->m_pNext = m_pFirst;
  161. // Setting list head links
  162. m_pFirst = pElement;
  163. if (m_pLast == NULL)
  164. m_pLast = pElement;
  165. ++m_dwNumElements;
  166. return reinterpret_cast<VS_COOKIE>(pElement);
  167. }
  168. template <class T>
  169. VS_COOKIE CVssDLList<T>::AddTail(
  170. IN const T& object
  171. )
  172. {
  173. assert(IsValid());
  174. CVssDLListElement<T>* pElement = new CVssDLListElement<T>(object);
  175. if (pElement == NULL)
  176. return VS_NULL_COOKIE;
  177. // Setting neighbour element links
  178. if (m_pLast)
  179. {
  180. assert(m_pLast->m_pNext == NULL);
  181. m_pLast->m_pNext = pElement;
  182. }
  183. // Setting element links
  184. assert(pElement->m_pNext == NULL);
  185. assert(pElement->m_pPrev == NULL);
  186. if (m_pLast)
  187. pElement->m_pPrev = m_pLast;
  188. // Setting list head links
  189. if (m_pFirst == NULL)
  190. m_pFirst = pElement;
  191. m_pLast = pElement;
  192. ++m_dwNumElements;
  193. return reinterpret_cast<VS_COOKIE>(pElement);
  194. }
  195. template <class T>
  196. void CVssDLList<T>::ExtractByCookie(
  197. IN VS_COOKIE cookie,
  198. OUT T& refObject
  199. )
  200. {
  201. if (cookie == VS_NULL_COOKIE)
  202. return;
  203. CVssDLListElement<T>* pElement =
  204. reinterpret_cast<CVssDLListElement<T>*>(cookie);
  205. assert(pElement);
  206. assert(pElement->IsValid());
  207. // Setting neighbours links
  208. if (pElement->m_pPrev)
  209. pElement->m_pPrev->m_pNext = pElement->m_pNext;
  210. if (pElement->m_pNext)
  211. pElement->m_pNext->m_pPrev = pElement->m_pPrev;
  212. // Setting list head links
  213. if (m_pFirst == pElement)
  214. m_pFirst = pElement->m_pNext;
  215. if (m_pLast == pElement)
  216. m_pLast = pElement->m_pPrev;
  217. // Destroying the element after getting the original object.
  218. refObject = pElement->m_Object;
  219. delete pElement;
  220. --m_dwNumElements;
  221. }
  222. template <class T>
  223. bool CVssDLList<T>::Extract(
  224. OUT T& refObject
  225. )
  226. {
  227. CVssDLListElement<T>* pElement = m_pFirst;
  228. if (pElement == NULL)
  229. return false;
  230. assert(pElement->IsValid());
  231. // Setting neighbours links
  232. assert(pElement->m_pPrev == NULL);
  233. if (pElement->m_pNext)
  234. pElement->m_pNext->m_pPrev = NULL;
  235. // Setting list head links
  236. m_pFirst = pElement->m_pNext;
  237. if (m_pLast == pElement)
  238. m_pLast = NULL;
  239. // Destroying the element after getting the original object.
  240. refObject = pElement->m_Object;
  241. delete pElement;
  242. --m_dwNumElements;
  243. return true;
  244. }
  245. template <class T>
  246. bool CVssDLList<T>::ExtractTail(
  247. OUT T& refObject
  248. )
  249. {
  250. CVssDLListElement<T>* pElement = m_pLast;
  251. if (pElement == NULL)
  252. return false;
  253. assert(pElement->IsValid());
  254. // Setting neighbours links
  255. assert(pElement->m_pNext == NULL);
  256. if (pElement->m_pPrev)
  257. pElement->m_pPrev->m_pNext = NULL;
  258. // Setting list head links
  259. m_pLast = pElement->m_pPrev;
  260. if (m_pFirst == pElement)
  261. m_pFirst = NULL;
  262. // Destroying the element after getting the original object.
  263. refObject = pElement->m_Object;
  264. delete pElement;
  265. --m_dwNumElements;
  266. return true;
  267. }
  268. template <class T>
  269. void CVssDLList<T>::ClearAll(
  270. )
  271. {
  272. CVssDLListElement<T>* pElement = m_pFirst;
  273. CVssDLListElement<T>* pNextElem;
  274. while( pElement != NULL )
  275. {
  276. pNextElem = pElement->m_pNext;
  277. delete pElement;
  278. pElement = pNextElem;
  279. }
  280. m_pFirst = NULL;
  281. m_pLast = NULL;
  282. m_dwNumElements = 0;
  283. }
  284. template <class T>
  285. bool CVssDLList<T>::IsValid() const
  286. {
  287. if ((m_pFirst == NULL) && (m_pLast == NULL))
  288. return true;
  289. if ((m_pFirst != NULL) && (m_pLast != NULL))
  290. return (m_pFirst->IsValid() && m_pLast->IsValid());
  291. return false;
  292. }
  293. /////////////////////////////////////////////////////////////////////////////
  294. // CVssDLListIterator implementation
  295. template <class T>
  296. bool CVssDLListIterator<T>::GetNext( OUT T& object )
  297. {
  298. if (m_pNextInEnum == NULL)
  299. return false;
  300. else
  301. {
  302. object = m_pNextInEnum->m_Object;
  303. m_pNextInEnum = m_pNextInEnum->m_pNext;
  304. return true;
  305. }
  306. }
  307. #endif // __VSS_DLLIST_HXX__