Source code of Windows XP (NT5)
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.

285 lines
6.6 KiB

  1. // Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
  2. /* Dynamic arrays */
  3. #ifndef __AMUTIL_H__
  4. #define __AMUTIL_H__
  5. /* Dynamic array support */
  6. template <class _TInterface, class _TArray>
  7. class CDynamicArray
  8. {
  9. public:
  10. CDynamicArray(int iIncrement) : m_pArray(NULL),
  11. m_nElements(0),
  12. m_iIncrement(iIncrement),
  13. m_nSize(0) {}
  14. CDynamicArray() : m_pArray(NULL),
  15. m_nElements(0),
  16. m_iIncrement(4),
  17. m_nSize(0) {}
  18. ~CDynamicArray() { delete [] m_pArray; }
  19. _TInterface Element(int i) const {
  20. _ASSERTE(i < m_nElements);
  21. return m_pArray[i];
  22. }
  23. _TInterface operator [] (int i)
  24. {
  25. return m_pArray[i];
  26. }
  27. int Size() const {
  28. return m_nElements;
  29. }
  30. BOOL Add(_TInterface Element)
  31. {
  32. _ASSERTE(m_nSize >= m_nElements);
  33. if (m_nSize == m_nElements) {
  34. _TArray *pNewArray = new _TArray[m_nSize + m_iIncrement];
  35. if (pNewArray == NULL) {
  36. return FALSE;
  37. }
  38. for (int i = 0; i < m_nElements; i++) {
  39. pNewArray[i] = m_pArray[i];
  40. }
  41. delete [] m_pArray;
  42. m_pArray = pNewArray;
  43. m_nSize = m_nSize + m_iIncrement;
  44. }
  45. m_pArray[m_nElements++] = Element;
  46. return TRUE;
  47. }
  48. BOOL Remove(_TInterface Element)
  49. {
  50. for (int i = 0; m_pArray[i] != Element; i++ ) {
  51. if (i >= m_nElements) {
  52. return FALSE;
  53. }
  54. }
  55. Remove(i);
  56. return TRUE;
  57. }
  58. void Remove(int i)
  59. {
  60. _ASSERTE(i < m_nElements);
  61. m_nElements--;
  62. for (; i < m_nElements; i++) {
  63. m_pArray[i] = m_pArray[i + 1];
  64. }
  65. m_pArray[m_nElements] = NULL;
  66. }
  67. void RemoveAll()
  68. {
  69. for (int i = 0; i < m_nElements; i++) {
  70. m_pArray[i] = NULL;
  71. }
  72. m_nElements = 0;
  73. }
  74. private:
  75. _TArray *m_pArray;
  76. int m_nSize;
  77. int m_nElements;
  78. const int m_iIncrement;
  79. };
  80. template <class Base, const IID *piid, class T>
  81. class CAMEnumInterfaceImpl :
  82. public Base,
  83. public CDynamicArray<T*, CComPtr<T> >
  84. {
  85. public:
  86. CAMEnumInterfaceImpl() : m_iter(0) {}
  87. /* The actual interface we support */
  88. STDMETHOD(Next)(ULONG celt, T** rgelt, ULONG* pceltFetched);
  89. STDMETHOD(Skip)(ULONG celt);
  90. STDMETHOD(Reset)(void){m_iter = 0;return S_OK;}
  91. STDMETHOD(Clone)(Base** ppEnum);
  92. int m_iter;
  93. };
  94. template <class Base, const IID* piid, class T>
  95. STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::Next(ULONG celt, T** rgelt,
  96. ULONG* pceltFetched)
  97. {
  98. if (rgelt == NULL || (celt != 1 && pceltFetched == NULL))
  99. return E_POINTER;
  100. ULONG nRem = (ULONG)(Size() - m_iter);
  101. HRESULT hRes = S_OK;
  102. if (nRem < celt)
  103. hRes = S_FALSE;
  104. ULONG nMin = min(celt, nRem);
  105. if (pceltFetched != NULL)
  106. *pceltFetched = nMin;
  107. while(nMin--) {
  108. Element(m_iter)->AddRef();
  109. *(rgelt++) = Element(m_iter++);
  110. }
  111. return hRes;
  112. }
  113. template <class Base, const IID* piid, class T>
  114. STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::Skip(ULONG celt)
  115. {
  116. m_iter += celt;
  117. if (m_iter < Size())
  118. return S_OK;
  119. m_iter = Size();
  120. return S_FALSE;
  121. }
  122. template <class Base, const IID* piid, class T>
  123. STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::Clone(Base** ppEnum)
  124. {
  125. typedef CComObject<CAMEnumInterface<Base, piid, T> > _class;
  126. HRESULT hRes = E_POINTER;
  127. if (ppEnum != NULL)
  128. {
  129. _class* p = NULL;
  130. ATLTRY(p = new _class)
  131. if (p == NULL)
  132. {
  133. *ppEnum = NULL;
  134. hRes = E_OUTOFMEMORY;
  135. }
  136. else
  137. {
  138. for (int i = 0; i < Size(); i++) {
  139. if (!p->Add(Element(i))) {
  140. break;
  141. }
  142. }
  143. if (i != Size()) {
  144. delete p;
  145. hRes = E_OUTOFMEMORY;
  146. *ppEnum = NULL;
  147. }
  148. else
  149. {
  150. p->m_iter = m_iter;
  151. hRes = p->_InternalQueryInterface(*piid, (void**)ppEnum);
  152. if (FAILED(hRes))
  153. delete p;
  154. }
  155. }
  156. }
  157. return hRes;
  158. }
  159. template <class Base, const IID* piid, class T>
  160. class CAMEnumInterface : public CAMEnumInterfaceImpl<Base, piid, T>, public CComObjectRoot
  161. {
  162. public:
  163. typedef CComObjectRoot _BaseClass ;
  164. typedef CAMEnumInterface<Base, piid, T> _CComEnum;
  165. typedef CAMEnumInterfaceImpl<Base, piid, T> _CComEnumBase;
  166. #ifdef DEBUG
  167. ULONG InternalAddRef()
  168. {
  169. return _BaseClass::InternalAddRef();
  170. }
  171. ULONG InternalRelease()
  172. {
  173. return _BaseClass::InternalRelease();
  174. }
  175. #endif
  176. BEGIN_COM_MAP(_CComEnum)
  177. COM_INTERFACE_ENTRY_IID(*piid, _CComEnumBase)
  178. END_COM_MAP()
  179. };
  180. #ifndef __WXUTIL__
  181. // wrapper for whatever critical section we have
  182. class CCritSec {
  183. // make copy constructor and assignment operator inaccessible
  184. CCritSec(const CCritSec &refCritSec);
  185. CCritSec &operator=(const CCritSec &refCritSec);
  186. CRITICAL_SECTION m_CritSec;
  187. public:
  188. CCritSec() {
  189. InitializeCriticalSection(&m_CritSec);
  190. };
  191. ~CCritSec() {
  192. DeleteCriticalSection(&m_CritSec);
  193. };
  194. void Lock() {
  195. EnterCriticalSection(&m_CritSec);
  196. };
  197. void Unlock() {
  198. LeaveCriticalSection(&m_CritSec);
  199. };
  200. };
  201. // locks a critical section, and unlocks it automatically
  202. // when the lock goes out of scope
  203. class CAutoLock {
  204. // make copy constructor and assignment operator inaccessible
  205. CAutoLock(const CAutoLock &refAutoLock);
  206. CAutoLock &operator=(const CAutoLock &refAutoLock);
  207. protected:
  208. CCritSec * m_pLock;
  209. public:
  210. CAutoLock(CCritSec * plock)
  211. {
  212. m_pLock = plock;
  213. m_pLock->Lock();
  214. };
  215. ~CAutoLock() {
  216. m_pLock->Unlock();
  217. };
  218. };
  219. // locks a critical section, and unlocks it automatically
  220. // when the lock goes out of scope
  221. class CAutoObjectLock {
  222. // make copy constructor and assignment operator inaccessible
  223. CAutoObjectLock(const CAutoObjectLock &refAutoLock);
  224. CAutoObjectLock &operator=(const CAutoObjectLock &refAutoLock);
  225. protected:
  226. CComObjectRoot * m_pObject;
  227. public:
  228. CAutoObjectLock(CComObjectRoot * pobject)
  229. {
  230. m_pObject = pobject;
  231. m_pObject->Lock();
  232. };
  233. ~CAutoObjectLock() {
  234. m_pObject->Unlock();
  235. };
  236. };
  237. #define AUTO_CRIT_LOCK CAutoObjectLock lck(this);
  238. #ifdef _DEBUG
  239. #define EXECUTE_ASSERT(_x_) _ASSERTE(_x_)
  240. #else
  241. #define EXECUTE_ASSERT(_x_) _x_
  242. #endif
  243. #endif
  244. #endif // __AMUTIL_H__