Source code of Windows XP (NT5)
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.

239 lines
6.4 KiB

  1. //=--------------------------------------------------------------------------=
  2. // StdEnum.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of a generic enumerator object.
  13. //
  14. #include "IPServer.H"
  15. #include "StdEnum.H"
  16. #include "Globals.H"
  17. SZTHISFILE
  18. //=--------------------------------------------------------------------------=
  19. // CStandardEnum::CStandardEnum
  20. //=--------------------------------------------------------------------------=
  21. // create the object and initialize the refcount
  22. //
  23. // Parameters:
  24. // REFCLSID - [in] type of enumerator that we are
  25. // int - [in] number of elements in the enumeration
  26. // int - [in] size of each element
  27. // void * - [in] pointer to element data
  28. // void (WINAPI *pfnCopyElement)(void *, const void *, DWORD)
  29. // - [in] copying function
  30. //
  31. // Notes:
  32. //
  33. #pragma warning(disable:4355) // using 'this' in constructor
  34. CStandardEnum::CStandardEnum
  35. (
  36. REFCLSID rclsid,
  37. int cElements,
  38. int cbElementSize,
  39. void *rgElements,
  40. void (WINAPI *pfnCopyElement)(void *, const void *, DWORD)
  41. )
  42. : CUnknownObject(NULL, (IEnumGeneric *)this),
  43. m_iid(rclsid),
  44. m_cElements(cElements),
  45. m_cbElementSize(cbElementSize),
  46. m_iCurrent(0),
  47. m_rgElements(rgElements),
  48. m_pfnCopyElement(pfnCopyElement)
  49. {
  50. m_pEnumClonedFrom = NULL;
  51. }
  52. #pragma warning(default:4355) // using 'this' in constructor
  53. //=--------------------------------------------------------------------------=
  54. // CStandardEnum::CStandardEnum
  55. //=--------------------------------------------------------------------------=
  56. // "it is not death, but dying, which is terrible."
  57. // - Henry Fielding (1707-54)
  58. //
  59. // Notes:
  60. //
  61. CStandardEnum::~CStandardEnum ()
  62. {
  63. // if we're a cloned object, then just release our parent object and
  64. // we're done. otherwise, free up the allocated memory we were given
  65. //
  66. if (m_pEnumClonedFrom)
  67. m_pEnumClonedFrom->Release();
  68. else {
  69. if (m_rgElements) HeapFree(g_hHeap, 0, m_rgElements);
  70. }
  71. }
  72. //=--------------------------------------------------------------------------=
  73. // CStandardEnum::InternalQueryInterface
  74. //=--------------------------------------------------------------------------=
  75. // we support our internal iid, and that's all
  76. //
  77. // Parameters:
  78. // REFIID - [in] interface they want
  79. // void ** - [out] where they want to put the resulting object ptr.
  80. //
  81. // Output:
  82. // HRESULT - S_OK, E_NOINTERFACE
  83. //
  84. // Notes:
  85. //
  86. HRESULT CStandardEnum::InternalQueryInterface
  87. (
  88. REFIID riid,
  89. void **ppvObjOut
  90. )
  91. {
  92. if (DO_GUIDS_MATCH(riid, m_iid)) {
  93. ExternalAddRef();
  94. *ppvObjOut = (IEnumGeneric *)this;
  95. return S_OK;
  96. }
  97. return E_NOINTERFACE;
  98. }
  99. //=--------------------------------------------------------------------------=
  100. // CStandardEnum::Next
  101. //=--------------------------------------------------------------------------=
  102. // returns the next dude in our iteration
  103. //
  104. // Parameters:
  105. // unsigned long - [in] count of elements requested
  106. // void * - [out] array of slots to put values in.
  107. // unsigned long * - [out] actual number fetched
  108. //
  109. // Output:
  110. // HRESULT - S_OK, E_INVALIDARG, S_FALSE
  111. //
  112. // Notes:
  113. //
  114. STDMETHODIMP CStandardEnum::Next
  115. (
  116. unsigned long cElm,
  117. void *rgDest,
  118. unsigned long *pcElmOut
  119. )
  120. {
  121. unsigned long cElementsFetched = 0;
  122. void *pElementDest = rgDest;
  123. const void *pElementSrc = (const BYTE *)m_rgElements + (m_cbElementSize * m_iCurrent);
  124. while (cElementsFetched < cElm) {
  125. // if we hit EOF, break out
  126. //
  127. if (m_iCurrent >= m_cElements)
  128. break;
  129. // copy the element out for them
  130. //
  131. m_pfnCopyElement(pElementDest, pElementSrc, m_cbElementSize);
  132. // increase the counters
  133. //
  134. pElementDest = (LPBYTE)pElementDest + m_cbElementSize;
  135. pElementSrc = (const BYTE *)pElementSrc + m_cbElementSize;
  136. m_iCurrent++;
  137. cElementsFetched++;
  138. }
  139. if (pcElmOut)
  140. *pcElmOut = cElementsFetched;
  141. return (cElementsFetched < cElm)? S_FALSE : S_OK;
  142. }
  143. //=--------------------------------------------------------------------------=
  144. // CStandardEnum::Skip
  145. //=--------------------------------------------------------------------------=
  146. // skips the requested number of rows.
  147. //
  148. // Parameters:
  149. // unsigned long - [in] number to skip
  150. //
  151. // Output:
  152. // HRESULT - S_OK, S_FALSE
  153. //
  154. // Notes:
  155. //
  156. STDMETHODIMP CStandardEnum::Skip
  157. (
  158. unsigned long cSkip
  159. )
  160. {
  161. // handle running off the end
  162. //
  163. if (m_iCurrent + (int)cSkip > m_cElements) {
  164. m_iCurrent = m_cElements;
  165. return S_FALSE;
  166. }
  167. m_iCurrent += cSkip;
  168. return S_OK;
  169. }
  170. //=--------------------------------------------------------------------------=
  171. // CStandardEnum::Reset
  172. //=--------------------------------------------------------------------------=
  173. // reset the counter.
  174. //
  175. // Output:
  176. // HRESULT - S_OK
  177. //
  178. // Notes:
  179. //
  180. STDMETHODIMP CStandardEnum::Reset
  181. (
  182. void
  183. )
  184. {
  185. m_iCurrent = 0;
  186. return S_OK;
  187. }
  188. //=--------------------------------------------------------------------------=
  189. // CStandardEnum::Clone
  190. //=--------------------------------------------------------------------------=
  191. // clones the object and gives the new one the same position
  192. //
  193. // Parameters:
  194. // IEnumVARIANT ** - [out] where to put the new object.
  195. //
  196. // Output;
  197. // HRESULT - S_OK, E_OUTOFMEMORY
  198. //
  199. // Notes:
  200. //
  201. STDMETHODIMP CStandardEnum::Clone
  202. (
  203. IEnumGeneric **ppEnumClone
  204. )
  205. {
  206. CStandardEnum *pNewEnum;
  207. pNewEnum = new CStandardEnum(m_iid, m_cElements, m_cbElementSize, m_rgElements, m_pfnCopyElement);
  208. RETURN_ON_NULLALLOC(pNewEnum);
  209. // hold on to who we were cloned from so m_rgElements stays alive, and we don't
  210. // have to copy it.
  211. //
  212. pNewEnum->m_pEnumClonedFrom = this;
  213. // AddRef() ourselves on their behalf.
  214. //
  215. AddRef();
  216. *ppEnumClone = (IEnumGeneric *)pNewEnum;
  217. return S_OK;
  218. }