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.

329 lines
6.7 KiB

  1. /****************************************************************************************
  2. * NAME: SafeArray.h
  3. *
  4. * CLASS: CSafeArray
  5. *
  6. * OVERVIEW
  7. *
  8. * Internet Authentication Server: Utility class for SafeArray
  9. *
  10. * Copyright (c) 1998, Microsoft Corporation. All Rights Reserved.
  11. *
  12. * History:
  13. * 3/1/98 Created byao
  14. * This file is created according to the online web document:
  15. * "Ole Development: Article 5: The Safe OLE Way of Handling Arrays"
  16. * by Bruce McKinney, http://tahiti/oledev/olecome/article5.htm"
  17. *
  18. * 5/14/98 Modified byao
  19. * CSafeArray used 0x80 as a contructed flag in fFeature.
  20. * This flag is now used in the official Win32API header file
  21. * We get rid of this flag, and added another private member for
  22. * the same purpose
  23. *
  24. *
  25. *****************************************************************************************/
  26. #ifndef _SAFEARRAY_H_
  27. #define _SAFEARRAY_H_
  28. // Dim class encapsulates an array dimension
  29. //@B Dim
  30. class Dim : public SAFEARRAYBOUND
  31. {
  32. public:
  33. Dim(const long iLo, const long iHi)
  34. { cElements = abs(iHi - iLo) + 1; lLbound = iLo; }
  35. Dim(const long c)
  36. { cElements = c; lLbound = 0; }
  37. const Dim & operator=(const Dim & dim)
  38. { cElements = dim.cElements; lLbound = dim.lLbound; return *this; }
  39. const Dim & operator=(const long c)
  40. { cElements = c; lLbound = 0; return *this; }
  41. ~Dim() {}
  42. long Elements() { return cElements; }
  43. long LBound() { return lLbound; }
  44. long UBound() { return lLbound + cElements - 1; }
  45. };
  46. //@E Dim
  47. // CSafeArray container class for OLE types
  48. //@B CSafeArray1
  49. template<class T, VARTYPE vt>
  50. class CSafeArray
  51. {
  52. public:
  53. // Constructors
  54. CSafeArray();
  55. CSafeArray(SAFEARRAY * psaSrc);
  56. CSafeArray(Dim & dim);
  57. // Copy constructor
  58. CSafeArray(const CSafeArray & saSrc);
  59. // Destructor
  60. ~CSafeArray();
  61. // Operator equal
  62. const CSafeArray & operator=(const CSafeArray & saSrc);
  63. // Indexing
  64. T & Get(long i);
  65. T & Set(T & t, long i);
  66. T & operator[](const long i); // C++ style (0-indexed)
  67. T & operator()(const long i); // Basic style (LBound-indexed)
  68. //@E CSafeArray1
  69. // Type casts
  70. operator SAFEARRAY();
  71. operator SAFEARRAY() const;
  72. // operator Variant();
  73. // operator Variant() const;
  74. // Operations
  75. BOOL ReDim(Dim & dim);
  76. long LBound();
  77. long UBound();
  78. long Elements();
  79. long Dimensions();
  80. BOOL IsSizable();
  81. void Lock();
  82. void Unlock();
  83. //@B CSafeArray2
  84. private:
  85. SAFEARRAY * psa;
  86. BOOL m_fConstructed; // is this safe array constructed?
  87. void Destroy();
  88. };
  89. //@E CSafeArray2
  90. // Private helpers
  91. template<class T, VARTYPE vt>
  92. inline void CSafeArray<T,vt>::Destroy()
  93. {
  94. m_fConstructed = FALSE;
  95. HRESULT hres = SafeArrayDestroy(psa);
  96. if (hres)
  97. {
  98. throw hres;
  99. }
  100. }
  101. // Constructors
  102. template<class T, VARTYPE vt>
  103. inline CSafeArray<T,vt>::CSafeArray()
  104. {
  105. Dim dim(0);
  106. psa = SafeArrayCreate(vt, 1, &dim);
  107. if (psa == NULL)
  108. {
  109. throw E_OUTOFMEMORY;
  110. }
  111. m_fConstructed = TRUE;
  112. }
  113. template<class T, VARTYPE vt>
  114. inline CSafeArray<T,vt>::CSafeArray(SAFEARRAY * psaSrc)
  115. {
  116. if (SafeArrayGetDim(psaSrc) != 1) throw E_INVALIDARG;
  117. HRESULT hres = SafeArrayCopy(psaSrc, &psa);
  118. if (hres)
  119. {
  120. throw hres;
  121. }
  122. m_fConstructed = TRUE;
  123. }
  124. template<class T, VARTYPE vt>
  125. inline CSafeArray<T,vt>::CSafeArray(const CSafeArray & saSrc)
  126. {
  127. HRESULT hres = SafeArrayCopy(saSrc.psa, &psa);
  128. if (hres)
  129. {
  130. throw hres;
  131. }
  132. m_fConstructed = TRUE;
  133. }
  134. template<class T, VARTYPE vt>
  135. inline CSafeArray<T,vt>::CSafeArray(Dim & dim)
  136. {
  137. psa = SafeArrayCreate(vt, 1, &dim);
  138. if (psa == NULL)
  139. {
  140. throw E_OUTOFMEMORY;
  141. }
  142. m_fConstructed = TRUE;
  143. }
  144. // Destructor
  145. template<class T, VARTYPE vt>
  146. inline CSafeArray<T,vt>::~CSafeArray()
  147. {
  148. if (m_fConstructed) {
  149. Destroy();
  150. }
  151. }
  152. // Operator =
  153. template<class T, VARTYPE vt>
  154. const CSafeArray<T,vt> & CSafeArray<T,vt>::operator=(const CSafeArray & saSrc)
  155. {
  156. if (psa)
  157. {
  158. SafeArrayDestroy(psa);
  159. }
  160. HRESULT hres = SafeArrayCopy(saSrc.psa, &psa);
  161. if (hres)
  162. {
  163. throw hres;
  164. }
  165. m_fConstructed = TRUE;
  166. return *this;
  167. }
  168. // Type casts
  169. template<class T, VARTYPE vt>
  170. inline CSafeArray<T,vt>::operator SAFEARRAY()
  171. {
  172. return *psa;
  173. }
  174. template<class T, VARTYPE vt>
  175. CSafeArray<T,vt>::operator SAFEARRAY() const
  176. {
  177. static SAFEARRAY * psaT;
  178. SafeArrayCopy(psa, &psaT);
  179. return *psaT;
  180. }
  181. /*
  182. template<class T, VARTYPE vt>
  183. CSafeArray<T,vt>::operator Variant()
  184. {
  185. return Variant(psa);
  186. }
  187. template<class T, VARTYPE vt>
  188. CSafeArray<T,vt>::operator Variant() const
  189. {
  190. static Variant v(psa);
  191. return v;
  192. }
  193. */
  194. // Indexing
  195. template<class T, VARTYPE vt>
  196. T & CSafeArray<T,vt>::Get(long i)
  197. {
  198. static T tRes;
  199. HRESULT hres = SafeArrayGetElement(psa, &i, &tRes);
  200. if (hres) throw hres;
  201. return tRes;
  202. }
  203. //@B Indexing
  204. template<class T, VARTYPE vt>
  205. inline T & CSafeArray<T,vt>::Set(T & t, long i)
  206. {
  207. HRESULT hres = SafeArrayPutElement(psa, &i, (T *)&t);
  208. if (hres) throw hres;
  209. return t;
  210. }
  211. template<class T, VARTYPE vt>
  212. inline T & CSafeArray<T,vt>::operator[](const long i)
  213. {
  214. if (i < 0 || i > Elements() - 1) throw DISP_E_BADINDEX;
  215. return ((T*)psa->pvData)[i];
  216. }
  217. template<class T, VARTYPE vt>
  218. T & CSafeArray<T,vt>::operator()(const long i)
  219. {
  220. if (i < LBound() || i > UBound()) throw DISP_E_BADINDEX;
  221. return ((T*)psa->pvData)[i - LBound()];
  222. }
  223. //@E Indexing
  224. // Operations
  225. template<class T, VARTYPE vt>
  226. BOOL CSafeArray<T,vt>::ReDim(Dim &dim)
  227. {
  228. if (!IsSizable()) {
  229. return FALSE;
  230. }
  231. HRESULT hres = SafeArrayRedim(psa, &dim);
  232. if (hres) throw hres;
  233. return TRUE;
  234. }
  235. template<class T, VARTYPE vt>
  236. long CSafeArray<T,vt>::LBound()
  237. {
  238. long iRes;
  239. HRESULT hres = SafeArrayGetLBound(psa, 1, &iRes);
  240. if (hres) throw hres;
  241. return iRes;
  242. }
  243. template<class T, VARTYPE vt>
  244. inline long CSafeArray<T,vt>::Elements()
  245. {
  246. return psa->rgsabound[0].cElements;
  247. }
  248. template<class T, VARTYPE vt>
  249. long CSafeArray<T,vt>::UBound()
  250. {
  251. long iRes;
  252. HRESULT hres = SafeArrayGetUBound(psa, 1, &iRes);
  253. if (hres) throw hres;
  254. return iRes;
  255. }
  256. template<class T, VARTYPE vt>
  257. inline long CSafeArray<T,vt>::Dimensions()
  258. {
  259. return 1;
  260. }
  261. template<class T, VARTYPE vt>
  262. inline BOOL CSafeArray<T,vt>::IsSizable()
  263. {
  264. return (psa->fFeatures & FADF_FIXEDSIZE) ? FALSE : TRUE;
  265. }
  266. template<class T, VARTYPE vt>
  267. inline void CSafeArray<T,vt>::Lock()
  268. {
  269. HRESULT hres = SafeArrayLock(psa);
  270. if (hres)
  271. {
  272. throw hres;
  273. }
  274. }
  275. template<class T, VARTYPE vt>
  276. inline void CSafeArray<T,vt>::Unlock()
  277. {
  278. HRESULT hres = SafeArrayUnlock(psa);
  279. if (hres)
  280. {
  281. throw hres;
  282. }
  283. }
  284. #endif // _SAFEARRAY_H_