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.

278 lines
11 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/util/VARIANT_functions.h
  3. *
  4. * Purpose: VARIANT helper functions.
  5. *
  6. * Created: 23rd August 2008
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2008-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file comstl/util/VARIANT_functions.h
  40. *
  41. * \brief [C++ only; requires COM] VARIANT helper functions
  42. * (\ref group__library__utility__com "COM Utility" Library).
  43. */
  44. #ifndef COMSTL_INCL_COMSTL_UTIL_H_VARIANT_FUNCTIONS
  45. #define COMSTL_INCL_COMSTL_UTIL_H_VARIANT_FUNCTIONS
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define COMSTL_VER_COMSTL_UTIL_H_VARIANT_FUNCTIONS_MAJOR 1
  48. # define COMSTL_VER_COMSTL_UTIL_H_VARIANT_FUNCTIONS_MINOR 0
  49. # define COMSTL_VER_COMSTL_UTIL_H_VARIANT_FUNCTIONS_REVISION 2
  50. # define COMSTL_VER_COMSTL_UTIL_H_VARIANT_FUNCTIONS_EDIT 3
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  56. # include <comstl/comstl.h>
  57. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  58. #ifndef COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
  59. # include <comstl/string/BSTR_functions.h>
  60. #endif /* !COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS */
  61. #ifndef COMSTL_INCL_COMSTL_UTIL_H_CY_FUNCTIONS
  62. # include <comstl/util/CY_functions.h>
  63. #endif /* !COMSTL_INCL_COMSTL_UTIL_H_CY_FUNCTIONS */
  64. #ifndef COMSTL_INCL_COMSTL_UTIL_H_DECIMAL_FUNCTIONS
  65. # include <comstl/util/DECIMAL_functions.h>
  66. #endif /* !COMSTL_INCL_COMSTL_UTIL_H_DECIMAL_FUNCTIONS */
  67. #ifndef COMSTL_INCL_COMSTL_UTIL_H_OBJECT_FUNCTIONS
  68. # include <comstl/util/object_functions.h>
  69. #endif /* !COMSTL_INCL_COMSTL_UTIL_H_OBJECT_FUNCTIONS */
  70. /* /////////////////////////////////////////////////////////////////////////
  71. * Namespace
  72. */
  73. #if !defined(_COMSTL_NO_NAMESPACE) && \
  74. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  75. # if defined(_STLSOFT_NO_NAMESPACE)
  76. /* There is no stlsoft namespace, so must define ::comstl */
  77. namespace comstl
  78. {
  79. # else
  80. /* Define stlsoft::comstl_project */
  81. namespace stlsoft
  82. {
  83. namespace comstl_project
  84. {
  85. # endif /* _STLSOFT_NO_NAMESPACE */
  86. #endif /* !_COMSTL_NO_NAMESPACE */
  87. /* /////////////////////////////////////////////////////////////////////////
  88. * C functions
  89. */
  90. /** \brief [C only] Indicates whether two VARIANT structures are equal
  91. *
  92. * \ingroup group__library__utility__com
  93. *
  94. * \param lhs Pointer to the left-hand instances to compare
  95. * \param lhs Pointer to the right-hand instances to compare
  96. * \param comparisonSucceeded Pointer to a result-code instance that will have
  97. * an HRESULT value not equal to S_OK if the comparison cannot be made. May
  98. * be NULL if the caller does not care
  99. *
  100. * \return a value indicating whether the values are equal
  101. * \retval 0 The structures are not equal
  102. * \retval >0 The structures are equal
  103. *
  104. * \pre \c lhs must not be NULL.
  105. * \pre \c rhs must not be NULL.
  106. */
  107. STLSOFT_INLINE int comstl__VARIANT_equal(VARIANT const* lhs, VARIANT const* rhs, HRESULT* comparisonSucceeded)
  108. {
  109. HRESULT comparisonSucceeded_;
  110. COMSTL_MESSAGE_ASSERT("Cannot pass NULL pointer(s) to VARIANT_compare()", (NULL != lhs && NULL != rhs));
  111. /* Use the Null Object (Variable) pattern to relieve rest of code
  112. * of burden of knowing whether value required by caller
  113. */
  114. if(NULL == comparisonSucceeded)
  115. {
  116. comparisonSucceeded = &comparisonSucceeded_;
  117. }
  118. *comparisonSucceeded = S_OK;
  119. if(COMSTL_ACCESS_VARIANT_vt_BYPTR(lhs) != COMSTL_ACCESS_VARIANT_vt_BYPTR(rhs))
  120. {
  121. return 0;
  122. }
  123. else
  124. {
  125. switch(COMSTL_ACCESS_VARIANT_vt_BYPTR(lhs))
  126. {
  127. case VT_EMPTY:
  128. case VT_NULL:
  129. return 1;
  130. case VT_I1:
  131. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, cVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, cVal);
  132. case VT_UI1:
  133. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, bVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, bVal);
  134. case VT_I2:
  135. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, iVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, iVal);
  136. case VT_UI2:
  137. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, uiVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, uiVal);
  138. case VT_I4:
  139. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, lVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, lVal);
  140. case VT_UI4:
  141. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, ulVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, ulVal);
  142. case VT_INT:
  143. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, intVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, intVal);
  144. case VT_UINT:
  145. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, uintVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, uintVal);
  146. case VT_R4:
  147. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, fltVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, fltVal);
  148. case VT_R8:
  149. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, dblVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, dblVal);
  150. case VT_BOOL:
  151. return (VARIANT_FALSE != COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, boolVal)) == (VARIANT_FALSE != COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, boolVal));
  152. case VT_BSTR:
  153. return 0 == comstl__bstr_compare(COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, bstrVal), COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, bstrVal));
  154. case VT_ERROR:
  155. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, scode) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, scode);
  156. case VT_DECIMAL:
  157. return 0 == comstl__DECIMAL_compare(&COMSTL_ACCESS_VARIANT_decVal_BYPTR(lhs), &COMSTL_ACCESS_VARIANT_decVal_BYPTR(rhs));
  158. case VT_CY:
  159. return 0 == comstl__CY_compare(&COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, cyVal), &COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, cyVal));
  160. case VT_UNKNOWN:
  161. return (COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, punkVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, punkVal)) || (S_OK == comstl__is_same_object(COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, punkVal), COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, punkVal)));
  162. case VT_DISPATCH:
  163. return (COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, pdispVal) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, pdispVal)) || (S_OK == comstl__is_same_object(stlsoft_static_cast(LPUNKNOWN, COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, pdispVal)), stlsoft_static_cast(LPUNKNOWN, COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, pdispVal))));
  164. case VT_DATE:
  165. return COMSTL_ACCESS_VARIANT_MEM_BYPTR(lhs, date) == COMSTL_ACCESS_VARIANT_MEM_BYPTR(rhs, date);
  166. #if 0
  167. case VT_VARIANT:
  168. case VT_RECORD:
  169. #endif /* 0 */
  170. default:
  171. *comparisonSucceeded = E_NOTIMPL;
  172. break;
  173. }
  174. }
  175. return 0;
  176. }
  177. /* /////////////////////////////////////////////////////////////////////////
  178. * Namespace
  179. */
  180. #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
  181. namespace comstl
  182. {
  183. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  184. /* /////////////////////////////////////////////////////////////////////////
  185. * C++ functions
  186. */
  187. #ifdef __cplusplus
  188. /** \brief [C++ only] Indicates whether two VARIANT structures are equal
  189. *
  190. * \ingroup group__library__utility__com
  191. *
  192. * \param lhs Pointer to the left-hand instances to compare
  193. * \param lhs Pointer to the right-hand instances to compare
  194. * \param comparisonSucceeded Pointer to a result-code instance that will have
  195. * an HRESULT value not equal to S_OK if the comparison cannot be made. May
  196. * be NULL if the caller does not care
  197. *
  198. * \return a value indicating whether the values are equal
  199. * \retval 0 The structures are not equal
  200. * \retval >0 The structures are equal
  201. *
  202. * \pre \c lhs must not be NULL.
  203. * \pre \c rhs must not be NULL.
  204. */
  205. inline bool VARIANT_equal(VARIANT const* lhs, VARIANT const* rhs, HRESULT* comparisonSucceeded)
  206. {
  207. return 0 != comstl__VARIANT_equal(lhs, rhs, comparisonSucceeded);
  208. }
  209. /** \brief [C++ only] Indicates whether two VARIANT structures are equal
  210. *
  211. * \ingroup group__library__utility__com
  212. *
  213. * \param lhs Reference to the left-hand instances to compare
  214. * \param lhs Reference to the right-hand instances to compare
  215. * \param comparisonSucceeded Pointer to a result-code instance that will have
  216. * an HRESULT value not equal to S_OK if the comparison cannot be made. May
  217. * be NULL if the caller does not care
  218. *
  219. * \return a value indicating whether the values are equal
  220. * \retval 0 The structures are not equal
  221. * \retval >0 The structures are equal
  222. */
  223. inline bool VARIANT_equal(VARIANT const& lhs, VARIANT const& rhs, HRESULT* comparisonSucceeded)
  224. {
  225. return 0 != comstl__VARIANT_equal(&lhs, &rhs, comparisonSucceeded);
  226. }
  227. #endif /* __cplusplus */
  228. /* /////////////////////////////////////////////////////////////////////////
  229. * Unit-testing
  230. */
  231. #ifdef STLSOFT_UNITTEST
  232. # include "./unittest/VARIANT_functions_unittest_.h"
  233. #endif /* STLSOFT_UNITTEST */
  234. /* ////////////////////////////////////////////////////////////////////// */
  235. #ifndef _COMSTL_NO_NAMESPACE
  236. # if defined(_STLSOFT_NO_NAMESPACE) || \
  237. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  238. } /* namespace comstl */
  239. # else
  240. } /* namespace comstl_project */
  241. } /* namespace stlsoft */
  242. # endif /* _STLSOFT_NO_NAMESPACE */
  243. #endif /* !_COMSTL_NO_NAMESPACE */
  244. /* ////////////////////////////////////////////////////////////////////// */
  245. #endif /* !COMSTL_INCL_COMSTL_UTIL_H_VARIANT_FUNCTIONS */
  246. /* ///////////////////////////// end of file //////////////////////////// */