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.

207 lines
4.7 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. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. // CLASS
  24. //
  25. // CVariantVector
  26. //
  27. // DESCRIPTION
  28. //
  29. // This class provides a wrapper around a one-dimensional SAFEARRAY stored
  30. // in a VARIANT.
  31. //
  32. // CAVEATS
  33. //
  34. // This class does not assume ownership of the VARIANT struct. In other
  35. // words, you are responsible for calling VariantClear() to free any
  36. // allocated memory.
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. template <class T>
  40. class CVariantVector : NonCopyable
  41. {
  42. public:
  43. // Manipulates an existing array.
  44. explicit CVariantVector(VARIANT* pv) throw (_com_error);
  45. // Creates a new array cElements in length.
  46. CVariantVector(VARIANT* pv, unsigned int cElements) throw (_com_error);
  47. ~CVariantVector() throw()
  48. {
  49. SafeArrayUnaccessData(m_psa);
  50. }
  51. T* data() throw()
  52. {
  53. return m_pData;
  54. }
  55. long size() const throw()
  56. {
  57. return m_lSize;
  58. }
  59. T& operator[](size_t index) throw()
  60. {
  61. return m_pData[index];
  62. }
  63. protected:
  64. SAFEARRAY* m_psa; // The SAFEARRAY being manipulated.
  65. long m_lSize; // The number of elements in the array.
  66. T* m_pData; // The raw array inside the SAFEARRAY.
  67. };
  68. ///////////////////////////////////////////////////////////////////////////////
  69. //
  70. // These inline functions convert a C++ type to a VARTYPE.
  71. //
  72. ///////////////////////////////////////////////////////////////////////////////
  73. inline VARTYPE GetVARTYPE(BSTR*)
  74. {
  75. return VT_BSTR;
  76. }
  77. inline VARTYPE GetVARTYPE(BYTE*)
  78. {
  79. return VT_UI1;
  80. }
  81. inline VARTYPE GetVARTYPE(LONG*)
  82. {
  83. return VT_I4;
  84. }
  85. inline VARTYPE GetVARTYPE(DWORD*)
  86. {
  87. return VT_UI4;
  88. }
  89. inline VARTYPE GetVARTYPE(IDispatch**)
  90. {
  91. return VT_DISPATCH;
  92. }
  93. inline VARTYPE GetVARTYPE(IUnknown**)
  94. {
  95. return VT_UNKNOWN;
  96. }
  97. inline VARTYPE GetVARTYPE(VARIANT*)
  98. {
  99. return VT_VARIANT;
  100. }
  101. ///////////////////////////////////////////////////////////////////////////////
  102. //
  103. // METHOD
  104. //
  105. // CVariantVector::CVariantVector
  106. //
  107. // DESCRIPTION
  108. //
  109. // Creates a CVariantVector that accesses an existing SAFEARRAY (which
  110. // is contained in the passed in VARIANT).
  111. //
  112. ///////////////////////////////////////////////////////////////////////////////
  113. template <class T>
  114. CVariantVector<T>::CVariantVector(VARIANT* pv) throw (_com_error)
  115. : m_psa(V_ARRAY(pv))
  116. {
  117. using _com_util::CheckError;
  118. // Make sure the variant contains a one-dimensional array of the right type.
  119. if (V_VT(pv) != (VT_ARRAY | GetVARTYPE((T*)NULL)) ||
  120. SafeArrayGetDim(m_psa) != 1)
  121. {
  122. throw _com_error(DISP_E_TYPEMISMATCH);
  123. }
  124. // Get the upper and lower bound.
  125. long lLBound, lUBound;
  126. CheckError(SafeArrayGetLBound(m_psa, 1, &lLBound));
  127. CheckError(SafeArrayGetUBound(m_psa, 1, &lUBound));
  128. // Compute the size.
  129. m_lSize = lUBound - lLBound + 1;
  130. if (m_lSize < 0)
  131. {
  132. throw _com_error(DISP_E_BADINDEX);
  133. }
  134. // Lock the array data.
  135. CheckError(SafeArrayAccessData(m_psa, (void**)&m_pData));
  136. }
  137. ///////////////////////////////////////////////////////////////////////////////
  138. //
  139. // METHOD
  140. //
  141. // CVariantVector::CVariantVector
  142. //
  143. // DESCRIPTION
  144. //
  145. // Initializes both the passed in VARIANT and the CVariantVector to
  146. // manipulate a new array, cElements in length.
  147. //
  148. ///////////////////////////////////////////////////////////////////////////////
  149. template <class T>
  150. CVariantVector<T>::CVariantVector(VARIANT* pv,
  151. unsigned int cElements) throw (_com_error)
  152. : m_lSize(cElements)
  153. {
  154. // Initalize the variant.
  155. VariantInit(pv);
  156. // Create the SAFEARRAY.
  157. V_ARRAY(pv) = SafeArrayCreateVector(GetVARTYPE((T*)NULL), 0, cElements);
  158. if ((m_psa = V_ARRAY(pv)) == NULL)
  159. {
  160. throw _com_error(E_OUTOFMEMORY);
  161. }
  162. // Set the type.
  163. V_VT(pv) = VT_ARRAY | GetVARTYPE((T*)NULL);
  164. // Lock the array data.
  165. HRESULT hr = SafeArrayAccessData(m_psa, (void**)&m_pData);
  166. if (FAILED(hr))
  167. {
  168. // Free the memory we allocated.
  169. VariantClear(pv);
  170. throw _com_error(hr);
  171. }
  172. }
  173. #endif / _VARVEC_H_