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
7.6 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // VarVec.h
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file describes the class CVariantVector
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 08/05/1997 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #ifndef _VARVEC_H_
  19. #define _VARVEC_H_
  20. #include "nocopy.h"
  21. #pragma warning( disable : 4290 )
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // CLASS
  25. //
  26. // CVariantVector
  27. //
  28. // DESCRIPTION
  29. //
  30. // This class provides a wrapper around a one-dimensional SAFEARRAY stored
  31. // in a VARIANT.
  32. //
  33. // CAVEATS
  34. //
  35. // This class does not assume ownership of the VARIANT struct. In other
  36. // words, you are responsible for calling VariantClear() to free any
  37. // allocated memory.
  38. //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. template <class T>
  41. class CVariantVector : NonCopyable
  42. {
  43. public:
  44. // Manipulates an existing array.
  45. explicit CVariantVector(VARIANT* pv) throw (_com_error);
  46. // Creates a new array cElements in length.
  47. CVariantVector(
  48. VARIANT* pv,
  49. unsigned int cElements
  50. ) throw (_com_error);
  51. // Create or manipulate a safe array of any automation compatible type
  52. CVariantVector(
  53. VARIANT* pv,
  54. VARTYPE vt,
  55. unsigned int cElements
  56. ) throw (_com_error);
  57. ~CVariantVector() throw()
  58. {
  59. SafeArrayUnaccessData(m_psa);
  60. }
  61. T* data() throw()
  62. {
  63. return m_pData;
  64. }
  65. long size() const throw()
  66. {
  67. return m_lSize;
  68. }
  69. T& operator[](size_t index) throw()
  70. {
  71. return m_pData[index];
  72. }
  73. protected:
  74. SAFEARRAY* m_psa; // The SAFEARRAY being manipulated.
  75. long m_lSize; // The number of elements in the array.
  76. T* m_pData; // The raw array inside the SAFEARRAY.
  77. };
  78. ///////////////////////////////////////////////////////////////////////////////
  79. //
  80. // These inline functions convert a C++ type to a VARTYPE.
  81. //
  82. ///////////////////////////////////////////////////////////////////////////////
  83. inline VARTYPE GetVARTYPE(BYTE*)
  84. {
  85. return VT_UI1;
  86. }
  87. inline VARTYPE GetVARTYPE(short*)
  88. {
  89. return VT_I2;
  90. }
  91. inline VARTYPE GetVARTYPE(long*)
  92. {
  93. return VT_I4;
  94. }
  95. inline VARTYPE GetVARTYPE(float*)
  96. {
  97. return VT_R4;
  98. }
  99. inline VARTYPE GetVARTYPE(double*)
  100. {
  101. return VT_R8;
  102. }
  103. inline VARTYPE GetVARTYPE(CY*)
  104. {
  105. return VT_CY;
  106. }
  107. inline VARTYPE GetVARTYPE(BSTR*)
  108. {
  109. return VT_BSTR;
  110. }
  111. inline VARTYPE GetVARTYPE(IDispatch**)
  112. {
  113. return VT_DISPATCH;
  114. }
  115. inline VARTYPE GetVARTYPE(IUnknown**)
  116. {
  117. return VT_UNKNOWN;
  118. }
  119. inline VARTYPE GetVARTYPE(VARIANT*)
  120. {
  121. return VT_VARIANT;
  122. }
  123. ///////////////////////////////////////////////////////////////////////////////
  124. //
  125. // METHOD
  126. //
  127. // CVariantVector::CVariantVector
  128. //
  129. // DESCRIPTION
  130. //
  131. // Creates a CVariantVector that accesses an existing SAFEARRAY (which
  132. // is contained in the passed in VARIANT).
  133. //
  134. ///////////////////////////////////////////////////////////////////////////////
  135. template <class T>
  136. CVariantVector<T>::CVariantVector(VARIANT* pv) throw (_com_error)
  137. : m_psa(V_ARRAY(pv))
  138. {
  139. using _com_util::CheckError;
  140. // Make sure the variant contains a one-dimensional array of the right type.
  141. if (V_VT(pv) != (VT_ARRAY | GetVARTYPE((T*)NULL)) ||
  142. SafeArrayGetDim(m_psa) != 1)
  143. {
  144. throw _com_error(DISP_E_TYPEMISMATCH);
  145. }
  146. // Get the upper and lower bound.
  147. long lLBound, lUBound;
  148. CheckError(SafeArrayGetLBound(m_psa, 1, &lLBound));
  149. CheckError(SafeArrayGetUBound(m_psa, 1, &lUBound));
  150. // Compute the size.
  151. m_lSize = lUBound - lLBound + 1;
  152. if (m_lSize < 0)
  153. {
  154. throw _com_error(DISP_E_BADINDEX);
  155. }
  156. // Lock the array data.
  157. CheckError(SafeArrayAccessData(m_psa, (void**)&m_pData));
  158. }
  159. ///////////////////////////////////////////////////////////////////////////////
  160. //
  161. // METHOD
  162. //
  163. // CVariantVector::CVariantVector
  164. //
  165. // DESCRIPTION
  166. //
  167. // Initializes both the passed in VARIANT and the CVariantVector to
  168. // manipulate a new array, cElements in length.
  169. //
  170. ///////////////////////////////////////////////////////////////////////////////
  171. template <class T>
  172. CVariantVector<T>::CVariantVector(
  173. VARIANT* pv,
  174. unsigned int cElements
  175. ) throw (_com_error)
  176. : m_lSize(cElements)
  177. {
  178. // Initalize the variant.
  179. VariantInit(pv);
  180. // Create the SAFEARRAY.
  181. V_ARRAY(pv) = SafeArrayCreateVector(GetVARTYPE((T*)NULL), 0, cElements);
  182. if ((m_psa = V_ARRAY(pv)) == NULL)
  183. {
  184. throw _com_error(E_OUTOFMEMORY);
  185. }
  186. // Set the type.
  187. V_VT(pv) = VT_ARRAY | GetVARTYPE((T*)NULL);
  188. // Lock the array data.
  189. HRESULT hr = SafeArrayAccessData(m_psa, (void**)&m_pData);
  190. if (FAILED(hr))
  191. {
  192. // Free the memory we allocated.
  193. VariantClear(pv);
  194. throw _com_error(hr);
  195. }
  196. }
  197. ///////////////////////////////////////////////////////////////////////////////
  198. //
  199. // METHOD
  200. //
  201. // CVariantVector::CVariantVector
  202. //
  203. // DESCRIPTION
  204. //
  205. // Create a new safe array or manipulate an existing safearray of any
  206. // automation compatible type
  207. //
  208. ///////////////////////////////////////////////////////////////////////////////
  209. template <class T>
  210. CVariantVector<T>::CVariantVector(
  211. VARIANT* pv,
  212. VARTYPE vt,
  213. unsigned int cElements
  214. ) throw (_com_error)
  215. {
  216. if ( 0 == cElements )
  217. {
  218. // Manipulate an existing array
  219. m_psa = V_ARRAY(pv);
  220. // Make sure the variant contains a one-dimensional array of the right type.
  221. if ( V_VT(pv) != (VT_ARRAY | vt) || SafeArrayGetDim(m_psa) != 1)
  222. {
  223. throw _com_error(DISP_E_TYPEMISMATCH);
  224. }
  225. // Get the upper and lower bound.
  226. long lLBound, lUBound;
  227. HRESULT hr = SafeArrayGetLBound(m_psa, 1, &lLBound);
  228. if ( FAILED(hr) )
  229. {
  230. throw _com_error(hr);
  231. }
  232. hr = SafeArrayGetUBound(m_psa, 1, &lUBound);
  233. if ( FAILED(hr) )
  234. {
  235. throw _com_error(hr);
  236. }
  237. // Compute the size.
  238. m_lSize = lUBound - lLBound + 1;
  239. if (m_lSize < 0)
  240. {
  241. throw _com_error(DISP_E_BADINDEX);
  242. }
  243. // Lock the array data.
  244. hr = SafeArrayAccessData(m_psa, (void**)&m_pData);
  245. if ( FAILED(hr) )
  246. {
  247. throw _com_error(hr);
  248. }
  249. }
  250. else
  251. {
  252. // Create a new array
  253. m_lSize = cElements;
  254. // Initalize the variant.
  255. VariantInit(pv);
  256. // Create the SAFEARRAY.
  257. _ASSERT( vt < VT_ARRAY );
  258. V_ARRAY(pv) = SafeArrayCreateVector(vt, 0, cElements);
  259. if ( NULL == (m_psa = V_ARRAY(pv)) )
  260. {
  261. throw _com_error(E_OUTOFMEMORY);
  262. }
  263. // Set the type.
  264. V_VT(pv) = VT_ARRAY | vt;
  265. // Lock the array data.
  266. HRESULT hr = SafeArrayAccessData(m_psa, (void**)&m_pData);
  267. if (FAILED(hr))
  268. {
  269. // Free the memory we allocated.
  270. VariantClear(pv);
  271. throw _com_error(hr);
  272. }
  273. }
  274. }
  275. #endif // _VARVEC_H_