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.

289 lines
8.7 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/memory/functions.h
  3. *
  4. * Purpose: COM memory functions.
  5. *
  6. * Created: 2nd March 1996
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 1996-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/memory/functions.h
  40. *
  41. * \brief [C, C++] COM memory functions
  42. * (\ref group__library__memory "Memory" Library).
  43. */
  44. #ifndef COMSTL_INCL_COMSTL_MEMORY_H_FUNCTIONS
  45. #define COMSTL_INCL_COMSTL_MEMORY_H_FUNCTIONS
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define COMSTL_VER_COMSTL_MEMORY_H_FUNCTIONS_MAJOR 4
  48. # define COMSTL_VER_COMSTL_MEMORY_H_FUNCTIONS_MINOR 1
  49. # define COMSTL_VER_COMSTL_MEMORY_H_FUNCTIONS_REVISION 3
  50. # define COMSTL_VER_COMSTL_MEMORY_H_FUNCTIONS_EDIT 49
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Compatibility
  54. */
  55. /*
  56. [DocumentationStatus:Ready]
  57. */
  58. /* /////////////////////////////////////////////////////////////////////////
  59. * Includes
  60. */
  61. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  62. # include <comstl/comstl.h>
  63. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  64. /* /////////////////////////////////////////////////////////////////////////
  65. * Namespace
  66. */
  67. #if !defined(_COMSTL_NO_NAMESPACE) && \
  68. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  69. # if defined(_STLSOFT_NO_NAMESPACE)
  70. /* There is no stlsoft namespace, so must define ::comstl */
  71. namespace comstl
  72. {
  73. # else
  74. /* Define stlsoft::comstl_project */
  75. namespace stlsoft
  76. {
  77. namespace comstl_project
  78. {
  79. # endif /* _STLSOFT_NO_NAMESPACE */
  80. #endif /* !_COMSTL_NO_NAMESPACE */
  81. /* /////////////////////////////////////////////////////////////////////////
  82. * C functions
  83. */
  84. /** \brief [C only] Gives the size of a memory block
  85. *
  86. * \ingroup group__library__memory
  87. *
  88. * This function returns the size of a memory block relative to the COM task
  89. * alloctor, as per <code>IMalloc::GetSize()</code>
  90. *
  91. * \param pv Pointer to the memory block
  92. * \return The size of the memory block (in bytes)
  93. *
  94. * \note [C++] This function is wrapped by the comstl::CoTaskMemGetSize()
  95. * function.
  96. */
  97. STLSOFT_INLINE cs_size_t comstl__CoTaskMemGetSize(void *pv)
  98. {
  99. LPMALLOC lpmalloc;
  100. cs_size_t ulRet;
  101. HRESULT hr = STLSOFT_NS_GLOBAL(CoGetMalloc)(MEMCTX_TASK, &lpmalloc);
  102. if(SUCCEEDED(hr))
  103. {
  104. ulRet = COMSTL_ITF_CALL(lpmalloc)->GetSize(COMSTL_ITF_THIS(lpmalloc) pv);
  105. COMSTL_ITF_CALL(lpmalloc)->Release(COMSTL_ITF_THIS0(lpmalloc));
  106. }
  107. else
  108. {
  109. STLSOFT_NS_GLOBAL(SetLastError)(stlsoft_static_cast(DWORD, hr));
  110. ulRet = 0;
  111. }
  112. return ulRet;
  113. }
  114. /** \brief [C only] Determines allocation ownership of a memory block
  115. *
  116. * \ingroup group__library__memory
  117. *
  118. * This function returns a value indicating whether a memory block was allocated
  119. * by the COM task allocator, as per <code>IMalloc::DidAlloc()</code>
  120. *
  121. * \param pv Pointer to the memory block
  122. * \return Result indicating ownership
  123. * \retval 1 The memory block was allocated by the task allocator
  124. * \retval 0 The memory block was <i>not</i> allocated by the task allocator
  125. * \retval -1 CoTaskMemDidAlloc() cannot determine whether the memory block was allocated by the task allocator
  126. *
  127. * \note [C++] This function is wrapped by the comstl::CoTaskMemDidAlloc()
  128. * function.
  129. */
  130. STLSOFT_INLINE cs_sint_t comstl__CoTaskMemDidAlloc(void *pv)
  131. {
  132. LPMALLOC lpmalloc;
  133. cs_sint_t iRet;
  134. HRESULT hr = STLSOFT_NS_GLOBAL(CoGetMalloc)(MEMCTX_TASK, &lpmalloc);
  135. if(SUCCEEDED(hr))
  136. {
  137. iRet = COMSTL_ITF_CALL(lpmalloc)->DidAlloc(COMSTL_ITF_THIS(lpmalloc) pv);
  138. COMSTL_ITF_CALL(lpmalloc)->Release(COMSTL_ITF_THIS0(lpmalloc));
  139. }
  140. else
  141. {
  142. STLSOFT_NS_GLOBAL(SetLastError)(stlsoft_static_cast(DWORD, hr));
  143. iRet = -1;
  144. }
  145. return iRet;
  146. }
  147. /** \brief [C only] Minimises the heap
  148. *
  149. * \ingroup group__library__memory
  150. *
  151. * This function minimises the heap as much as possible by releasing unused
  152. * memory to the operating system, coalescing adjacent free blocks and
  153. * committing free pages, as as per <code>IMalloc::HeapMinimize()</code>.
  154. *
  155. * \note [C++] This function is wrapped by the comstl::CoTaskMemHeapMinimise()
  156. * function.
  157. */
  158. STLSOFT_INLINE void comstl__CoTaskMemHeapMinimise(void)
  159. {
  160. LPMALLOC lpmalloc;
  161. HRESULT hr = STLSOFT_NS_GLOBAL(CoGetMalloc)(MEMCTX_TASK, &lpmalloc);
  162. if(SUCCEEDED(hr))
  163. {
  164. COMSTL_ITF_CALL(lpmalloc)->HeapMinimize(COMSTL_ITF_THIS0(lpmalloc));
  165. COMSTL_ITF_CALL(lpmalloc)->Release(COMSTL_ITF_THIS0(lpmalloc));
  166. }
  167. else
  168. {
  169. STLSOFT_NS_GLOBAL(SetLastError)(stlsoft_static_cast(DWORD, hr));
  170. }
  171. }
  172. /* /////////////////////////////////////////////////////////////////////////
  173. * Namespace
  174. */
  175. #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
  176. namespace comstl
  177. {
  178. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  179. /* /////////////////////////////////////////////////////////////////////////
  180. * C++ functions
  181. */
  182. #ifdef __cplusplus
  183. /** \brief Gives the size of a memory block
  184. *
  185. * \ingroup group__library__memory
  186. *
  187. * This function is a wrapper for comstl__CoTaskMemGetSize().
  188. *
  189. * \param pv Pointer to the memory block
  190. * \return The size of the memory block (in bytes)
  191. */
  192. inline cs_size_t CoTaskMemGetSize(void *pv)
  193. {
  194. return comstl__CoTaskMemGetSize(pv);
  195. }
  196. /** \brief Determines allocation ownership of a memory block
  197. *
  198. * \ingroup group__library__memory
  199. *
  200. * This function is a wrapper for comstl__CoTaskMemDidAlloc().
  201. *
  202. * \param pv Pointer to the memory block
  203. * \return Result indicating ownership
  204. * \retval 1 The memory block was allocated by the task allocator
  205. * \retval 0 The memory block was <i>not</i> allocated by the task allocator
  206. * \retval -1 CoTaskMemDidAlloc() cannot determine whether the memory block was allocated by the task allocator
  207. */
  208. inline cs_sint_t CoTaskMemDidAlloc(void *pv)
  209. {
  210. return comstl__CoTaskMemDidAlloc(pv);
  211. }
  212. /** \brief Minimises the heap
  213. *
  214. * \ingroup group__library__memory
  215. *
  216. * This function is a wrapper for comstl__CoTaskMemHeapMinimise().
  217. */
  218. inline void CoTaskMemHeapMinimise()
  219. {
  220. comstl__CoTaskMemHeapMinimise();
  221. }
  222. /** \brief Minimises the heap
  223. *
  224. * \ingroup group__library__memory
  225. *
  226. * This function is a wrapper for comstl__CoTaskMemHeapMinimise().
  227. */
  228. inline void CoTaskMemHeapMinimize()
  229. {
  230. comstl__CoTaskMemHeapMinimise();
  231. }
  232. #endif /* __cplusplus */
  233. /* /////////////////////////////////////////////////////////////////////////
  234. * Unit-testing
  235. */
  236. #ifdef STLSOFT_UNITTEST
  237. # include "./unittest/functions_unittest_.h"
  238. #endif /* STLSOFT_UNITTEST */
  239. /* ////////////////////////////////////////////////////////////////////// */
  240. #ifndef _COMSTL_NO_NAMESPACE
  241. # if defined(_STLSOFT_NO_NAMESPACE) || \
  242. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  243. } /* namespace comstl */
  244. # else
  245. } /* namespace stlsoft::comstl_project */
  246. } /* namespace stlsoft */
  247. # endif /* _STLSOFT_NO_NAMESPACE */
  248. #endif /* !_COMSTL_NO_NAMESPACE */
  249. /* ////////////////////////////////////////////////////////////////////// */
  250. #endif /* !COMSTL_INCL_COMSTL_MEMORY_H_FUNCTIONS */
  251. /* ///////////////////////////// end of file //////////////////////////// */