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.

527 lines
13 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. ARRTEMPL.H
  5. Abstract:
  6. This file defines a simple template for an array of arbitrary pointers.
  7. Actual growing array functionality is provided by CFlexArray.
  8. Classes defined:
  9. template CPointerArray
  10. History:
  11. 11/27/96 a-levn Compiles.
  12. --*/
  13. #ifndef __ARRAY_TEMPLATE__H_
  14. #define __ARRAY_TEMPLATE__H_
  15. #pragma warning(disable:4786)
  16. #include <map>
  17. #include <strutils.h>
  18. using namespace std;
  19. class wcsless : public binary_function<LPWSTR, LPWSTR, bool>
  20. {
  21. public:
  22. bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const
  23. {return wcscmp(wcs1, wcs2) < 0;}
  24. };
  25. class wcsiless : public binary_function<LPWSTR, LPWSTR, bool>
  26. {
  27. public:
  28. bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const
  29. {return wbem_wcsicmp(wcs1, wcs2) < 0;}
  30. };
  31. class CReleaseMe
  32. {
  33. protected:
  34. IUnknown* m_pUnk;
  35. public:
  36. CReleaseMe(IUnknown* pUnk) : m_pUnk(pUnk){}
  37. ~CReleaseMe() { release();}
  38. void release() { if(m_pUnk) m_pUnk->Release(); m_pUnk=0;}
  39. IUnknown* dismiss(){ IUnknown* p_ = m_pUnk; m_pUnk = NULL; return p_;}
  40. };
  41. template <typename T>
  42. class CReleaseMeRef
  43. {
  44. protected:
  45. T & m_pUnkRef;
  46. public:
  47. CReleaseMeRef(T& pUnkRef) : m_pUnkRef(pUnkRef){}
  48. ~CReleaseMeRef() { release();}
  49. void release() { if(m_pUnkRef) m_pUnkRef->Release(); m_pUnkRef=0;}
  50. T dismiss(){ T p_ = m_pUnkRef; m_pUnkRef = NULL; return p_;}
  51. };
  52. template<class T>
  53. class CTemplateReleaseMe
  54. {
  55. protected:
  56. T* m_p;
  57. public:
  58. CTemplateReleaseMe(T* p) : m_p(p){}
  59. ~CTemplateReleaseMe() { release();}
  60. void release(){ if(m_p) m_p->Release();m_p=0;}
  61. };
  62. template<class T>
  63. class CDeleteMe
  64. {
  65. protected:
  66. T* m_p;
  67. public:
  68. CDeleteMe(T* p = NULL) : m_p(p){}
  69. ~CDeleteMe() {delete m_p;}
  70. // overwrites the previous pointer, does NOT delete it
  71. void operator= (T* p) {m_p = p;}
  72. };
  73. class CCloseMe
  74. {
  75. protected:
  76. HANDLE m_h;
  77. public:
  78. CCloseMe(HANDLE hToClose){m_h = hToClose;};
  79. ~CCloseMe(){if(m_h && m_h != INVALID_HANDLE_VALUE)CloseHandle(m_h);};
  80. };
  81. class CfcloseMe
  82. {
  83. protected:
  84. FILE * m_h;
  85. public:
  86. CfcloseMe(FILE * ToClose){m_h = ToClose;};
  87. ~CfcloseMe(){if(m_h != NULL)fclose(m_h);};
  88. };
  89. typedef CCloseMe CCloseHandle;
  90. class CRegCloseMe
  91. {
  92. protected:
  93. HKEY m_h;
  94. public:
  95. CRegCloseMe(HKEY hToClose){m_h = hToClose;};
  96. ~CRegCloseMe(){if(m_h)RegCloseKey(m_h);};
  97. };
  98. template<class T>
  99. class CVectorDeleteMe
  100. {
  101. protected:
  102. T* m_p;
  103. T** m_pp;
  104. public:
  105. CVectorDeleteMe(T* p) : m_p(p), m_pp(NULL){}
  106. CVectorDeleteMe(T** pp) : m_p(NULL), m_pp(pp){}
  107. ~CVectorDeleteMe() {if(m_p) delete [] m_p; else if(m_pp) delete [] *m_pp;}
  108. };
  109. class CClearMe
  110. {
  111. protected:
  112. VARIANT* m_pv;
  113. public:
  114. CClearMe(VARIANT* pv) : m_pv(pv){}
  115. ~CClearMe() {VariantClear(m_pv);}
  116. };
  117. class CSysFreeMe
  118. {
  119. protected:
  120. BSTR m_str;
  121. public:
  122. CSysFreeMe(BSTR str) : m_str(str){}
  123. ~CSysFreeMe() { if ( NULL != m_str ) SysFreeString(m_str);}
  124. };
  125. class CSysFreeMeRef
  126. {
  127. protected:
  128. BSTR & m_str;
  129. public:
  130. CSysFreeMeRef(BSTR & str) : m_str(str){}
  131. ~CSysFreeMeRef() { SysFreeString(m_str);}
  132. };
  133. class CUnaccessMe
  134. {
  135. protected:
  136. SAFEARRAY* m_psa;
  137. public:
  138. CUnaccessMe(SAFEARRAY* psa) : m_psa(psa){}
  139. ~CUnaccessMe() {SafeArrayUnaccessData(m_psa);}
  140. };
  141. class CMemFreeMe
  142. {
  143. protected:
  144. void* m_pMem;
  145. public:
  146. CMemFreeMe( void* pMem ) : m_pMem(pMem){}
  147. ~CMemFreeMe() { if ( NULL != m_pMem ) CoTaskMemFree(m_pMem);}
  148. };
  149. #include <arena.h>
  150. #include <flexarry.h>
  151. #include <flexq.h>
  152. #include <smallarr.h>
  153. //*****************************************************************************
  154. //
  155. // class CPointerArray
  156. //
  157. // Array of pointers to TMember, where TMember is any class. See CFlexArray
  158. // in coredll\flexarry.h/cpp for documentation.
  159. //
  160. //*****************************************************************************
  161. template <class TMember>
  162. class CNullManager
  163. {
  164. public:
  165. void AddRefElement(TMember*){}
  166. void ReleaseElement(TMember*){}
  167. };
  168. template <class TMember, class TManager = CNullManager<TMember>,
  169. class TArray = CFlexArray>
  170. class CPointerArray
  171. {
  172. protected:
  173. TArray m_Array;
  174. TManager m_Manager;
  175. public:
  176. CPointerArray(const TManager& Manager = TManager())
  177. : m_Manager(Manager){}
  178. ~CPointerArray();
  179. int GetSize() const
  180. {return m_Array.Size();}
  181. void SetSize(int nNewSize)
  182. {m_Array.SetSize(nNewSize);}
  183. const TMember* GetAt(int nIndex) const
  184. {return (TMember*)m_Array.GetAt(nIndex);}
  185. TMember* GetAt(int nIndex)
  186. {return (TMember*)m_Array.GetAt(nIndex);}
  187. const TMember* operator[](int nIndex) const
  188. {return (TMember*)m_Array.GetAt(nIndex);}
  189. TMember* operator[](int nIndex)
  190. {return (TMember*)m_Array.GetAt(nIndex);}
  191. void SetAt(int nIndex, TMember* pElement, TMember** ppOld = NULL);
  192. void Discard(int nIndex);
  193. bool RemoveAt(int nIndex, TMember** ppOld = NULL);
  194. bool InsertAt(int nIndex, TMember* pElement);
  195. int Add(TMember* pElement);
  196. TMember** GetArrayPtr();
  197. TMember** UnbindPtr();
  198. void RemoveAll();
  199. void Swap(int nIndex1, int nIndex2);
  200. void Trim() {m_Array.Trim();}
  201. TArray & GetArray(){ return m_Array; };
  202. protected:
  203. void AddRefElement(TMember* p){m_Manager.AddRefElement(p);}
  204. void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);}
  205. };
  206. template<class TMember>
  207. class CPointerSmallArray :
  208. public CPointerArray<TMember, CNullManager<TMember>, CSmallArray>
  209. {
  210. };
  211. //*****************************************************************************
  212. //
  213. // class CPointerQueue
  214. //
  215. // Queue of pointers to TMember, where TMember is any class. See CFlexQueue
  216. // in coredll\flexq.h/cpp for documentation.
  217. //
  218. //*****************************************************************************
  219. template <class TMember, class TManager = CNullManager<TMember> >
  220. class CPointerQueue
  221. {
  222. protected:
  223. CFlexQueue m_Queue;
  224. TManager m_Manager;
  225. public:
  226. CPointerQueue(int nInitialSize = 1, const TManager& Manager = TManager())
  227. : m_Manager(Manager), m_Queue(nInitialSize){}
  228. void Clear();
  229. ~CPointerQueue()
  230. {Clear();}
  231. inline int GetQueueSize() const
  232. {return m_Queue.GetQueueSize();}
  233. bool Enqueue(TMember* pNew)
  234. {
  235. AddRefElement(pNew);
  236. return m_Queue.Enqueue(pNew);
  237. }
  238. TMember* Dequeue()
  239. {
  240. TMember* p = (TMember*)m_Queue.Dequeue();
  241. return p;
  242. }
  243. bool Requeue(TMember* pNew)
  244. {
  245. AddRefElement(pNew);
  246. return m_Queue.Requeue(pNew);
  247. }
  248. TMember* Unqueue()
  249. {
  250. TMember* p = (TMember*)m_Queue.Unqueue();
  251. AddRefElement(p);
  252. return p;
  253. }
  254. protected:
  255. void AddRefElement(TMember* p){m_Manager.AddRefElement(p);}
  256. void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);}
  257. };
  258. //*****************************************************************************
  259. //
  260. // UNIQUE POINTER ARRAY
  261. //
  262. //*****************************************************************************
  263. template <class TMember>
  264. class CUniqueManager
  265. {
  266. public:
  267. void AddRefElement(TMember*){}
  268. void ReleaseElement(TMember* pMember) {delete pMember;}
  269. };
  270. template<class TMember>
  271. class CUniquePointerArray :
  272. public CPointerArray<TMember, CUniqueManager<TMember> >
  273. {
  274. };
  275. template<class TMember>
  276. class CUniquePointerSmallArray :
  277. public CPointerArray<TMember, CUniqueManager<TMember>, CSmallArray>
  278. {
  279. };
  280. template<class TMember>
  281. class CUniquePointerQueue :
  282. public CPointerQueue<TMember, CUniqueManager<TMember> >
  283. {
  284. public:
  285. CUniquePointerQueue<TMember>(int nInitialSize = 1)
  286. : CPointerQueue<TMember, CUniqueManager<TMember> >(nInitialSize)
  287. {}
  288. };
  289. //*****************************************************************************
  290. //
  291. // REFED POINTER ARRAY
  292. //
  293. //*****************************************************************************
  294. template <class TMember>
  295. class CReferenceManager
  296. {
  297. public:
  298. void AddRefElement(TMember* pMember) {if(pMember)pMember->AddRef();}
  299. void ReleaseElement(TMember* pMember) {if(pMember)pMember->Release();}
  300. };
  301. template<class TMember>
  302. class CRefedPointerArray :
  303. public CPointerArray<TMember, CReferenceManager<TMember> >
  304. {
  305. };
  306. template<class TMember>
  307. class CRefedPointerSmallArray :
  308. public CPointerArray<TMember, CReferenceManager<TMember>, CSmallArray>
  309. {
  310. };
  311. template<class TMember>
  312. class CRefedPointerQueue :
  313. public CPointerQueue<TMember, CReferenceManager<TMember> >
  314. {
  315. public:
  316. CRefedPointerQueue(int nInitialSize = 1)
  317. : CPointerQueue<TMember, CReferenceManager<TMember> >(nInitialSize)
  318. {}
  319. };
  320. //*****************************************************************************
  321. //
  322. // ARRAY OF UNIQUE ARRAYS
  323. //
  324. //*****************************************************************************
  325. template <class TMember>
  326. class CUniqueArrayManager
  327. {
  328. void AddRefElement(TMember**){}
  329. void ReleaseElement(TMember** pMember) {delete [] pMember;}
  330. };
  331. template<class TMember>
  332. class CUniqueArrayArray : public CPointerArray<TMember,
  333. CUniqueArrayManager<TMember> >
  334. {
  335. };
  336. //*****************************************************************************
  337. //
  338. // IMPLEMENTATION
  339. //
  340. //*****************************************************************************
  341. template <class TMember, class TManager, class TArray>
  342. CPointerArray<TMember, TManager, TArray>::~CPointerArray()
  343. {
  344. RemoveAll();
  345. }
  346. template <class TMember, class TManager, class TArray>
  347. void CPointerArray<TMember, TManager, TArray>::RemoveAll()
  348. {
  349. for(int i = 0; i < m_Array.Size(); i++)
  350. {
  351. //
  352. // Remove it from array before releasing --- otherwise for a moment
  353. // there we have a garbage pointer in array!
  354. //
  355. TMember* p = GetAt(i);
  356. m_Array.SetAt(i, NULL);
  357. ReleaseElement(p);
  358. }
  359. m_Array.Empty();
  360. }
  361. template <class TMember, class TManager, class TArray>
  362. void CPointerArray<TMember, TManager, TArray>::SetAt(int nIndex,
  363. TMember* pElement, TMember** ppOld)
  364. {
  365. AddRefElement(pElement);
  366. //
  367. // Remove it from array before releasing --- otherwise for a moment
  368. // there we have a garbage pointer in array!
  369. //
  370. TMember* pOld = GetAt(nIndex);
  371. m_Array.SetAt(nIndex, (void*)pElement);
  372. if(ppOld == NULL)
  373. ReleaseElement(pOld);
  374. else
  375. *ppOld = pOld;
  376. }
  377. template <class TMember, class TManager, class TArray>
  378. void CPointerArray<TMember, TManager, TArray>::Discard(int nIndex)
  379. {
  380. m_Array.SetAt(nIndex, NULL);
  381. }
  382. template <class TMember, class TManager, class TArray>
  383. bool CPointerArray<TMember, TManager, TArray>::RemoveAt(int nIndex,
  384. TMember** ppOld)
  385. {
  386. //
  387. // Remove it from array before releasing --- otherwise for a moment
  388. // there we have a garbage pointer in array!
  389. //
  390. TMember* pOld = GetAt(nIndex);
  391. if(m_Array.RemoveAt(nIndex) != CFlexArray::no_error)
  392. return false;
  393. if(ppOld == NULL)
  394. ReleaseElement(pOld);
  395. else
  396. *ppOld = pOld;
  397. return true;
  398. }
  399. template <class TMember, class TManager, class TArray>
  400. bool CPointerArray<TMember, TManager, TArray>::InsertAt(int nIndex,
  401. TMember* pElement)
  402. {
  403. if(m_Array.InsertAt(nIndex, (void*)pElement) != CFlexArray::no_error)
  404. return false;
  405. AddRefElement(pElement);
  406. return true;
  407. }
  408. template <class TMember, class TManager, class TArray>
  409. int CPointerArray<TMember, TManager, TArray>::Add(TMember* pElement)
  410. {
  411. if(m_Array.Add((void*)pElement) != CFlexArray::no_error)
  412. return -1;
  413. AddRefElement(pElement);
  414. return m_Array.Size()-1;
  415. }
  416. template <class TMember, class TManager, class TArray>
  417. TMember** CPointerArray<TMember, TManager, TArray>::GetArrayPtr()
  418. {
  419. return (TMember**)m_Array.GetArrayPtr();
  420. }
  421. template <class TMember, class TManager, class TArray>
  422. TMember** CPointerArray<TMember, TManager, TArray>::UnbindPtr()
  423. {
  424. return (TMember**)m_Array.UnbindPtr();
  425. }
  426. template <class TMember, class TManager, class TArray>
  427. void CPointerArray<TMember, TManager, TArray>::Swap(int nIndex1, int nIndex2)
  428. {
  429. void* pTemp = m_Array[nIndex1];
  430. m_Array.SetAt(nIndex1, m_Array[nIndex2]);
  431. m_Array.SetAt(nIndex2, pTemp);
  432. }
  433. template <class TMember, class TManager>
  434. void CPointerQueue<TMember, TManager>::Clear()
  435. {
  436. TMember* p;
  437. while(p = (TMember*)m_Queue.Dequeue())
  438. {
  439. ReleaseElement(p);
  440. }
  441. }
  442. #endif