stdenum.cpp
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 7k
Category:

Windows Develop

Development Platform:

Visual C++

  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. }