finished documenting objhelp_enumgeneric and implementing the IConnectionPointContainer interface on the heap
This commit is contained in:
parent
c728482744
commit
6efccb8d19
|
@ -47,6 +47,7 @@
|
|||
|
||||
typedef struct tagENUMGENERICDATA {
|
||||
UINT32 uiRefCount; /* reference count */
|
||||
REFIID riidObjects; /* IID of underlying objects */
|
||||
UINT32 nObjects; /* count of IUnknown pointers */
|
||||
PUNKNOWN rgObjects[0]; /* array of IUnknown pointers */
|
||||
} ENUMGENERICDATA, *PENUMGENERICDATA;
|
||||
|
@ -65,9 +66,9 @@ typedef struct tagENUMGENERIC {
|
|||
*---------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, UINT32 nCapacity);
|
||||
extern PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, REFIID riidObjects, UINT32 nCapacity);
|
||||
extern void _ObjHlpAddToEnumGenericData(PENUMGENERICDATA pegd, IUnknown *pUnk);
|
||||
extern void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pecd);
|
||||
extern void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pegd);
|
||||
extern PENUMGENERIC _ObjHlpAllocateEnumGeneric(IMalloc *pAllocator, REFIID riidActual, PENUMGENERICDATA pegd,
|
||||
UINT32 nCurrent);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <comrogue/heap.h>
|
||||
#include <comrogue/internals/seg.h>
|
||||
#include "heap_internals.h"
|
||||
#include "enumgeneric.h"
|
||||
|
||||
#define PHDFLAGS_DELETING 0x80000000 /* deleting the heap */
|
||||
|
||||
|
@ -221,13 +222,64 @@ static UINT32 cpc_Release(IUnknown *pThis)
|
|||
return malloc_Release((IUnknown *)HeapDataPtr(pThis));
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an enumerator object to iterate through all the connection points in this container.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the ConnectionPointContainer interface in the heap data object.
|
||||
* - ppEnum = Pointer to a variable to receive a new reference to IEnumConnectionPoints.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = Enumerator created successfully; pointer to it in *ppEnum.
|
||||
* - E_OUTOFMEMORY = Unable to allocate the enumerator; *ppEnum is NULL.
|
||||
* - E_POINTER = The ppEnum pointer is not valid.
|
||||
*/
|
||||
static HRESULT cpc_EnumConnectionPoints(IConnectionPointContainer *pThis, IEnumConnectionPoints **ppEnum)
|
||||
{
|
||||
PHEAPDATA phd = (PHEAPDATA)HeapDataPtr(pThis); /* pointer to heap data */
|
||||
PENUMGENERICDATA pegd; /* pointer to data block */
|
||||
PENUMGENERIC peg; /* pointer to enumerator */
|
||||
|
||||
return E_NOTIMPL; /* TODO */
|
||||
if (!ppEnum)
|
||||
return E_POINTER;
|
||||
*ppEnum = NULL;
|
||||
|
||||
/* Allocate the data block. */
|
||||
pegd = _ObjHlpAllocateEnumGenericData((IMalloc *)phd, &IID_IConnectionPoint, 2);
|
||||
if (!pegd)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Build the data block. */
|
||||
_ObjHlpAddToEnumGenericData(pegd, (IUnknown *)(&(phd->fcpMallocSpy)));
|
||||
_ObjHlpAddToEnumGenericData(pegd, (IUnknown *)(&(phd->fcpSequentialStream)));
|
||||
|
||||
/* Allocate the enumerator. */
|
||||
peg = _ObjHlpAllocateEnumGeneric((IMalloc *)phd, &IID_IEnumConnectionPoints, pegd, 0);
|
||||
if (peg)
|
||||
{
|
||||
IUnknown_QueryInterface((IUnknown *)peg, &IID_IEnumConnectionPoints, (PPVOID)ppEnum);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Enumerator allocation failed?!? */
|
||||
_ObjHlpDiscardEnumGenericData(pegd);
|
||||
malloc_Free((IMalloc *)phd, pegd);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a reference to the IConnectionPoint interface corresponding to a specific outgoing IID.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the ConnectionPointContainer interface in the heap data object.
|
||||
* - riid = IID of the outgoing interface to get the connection point for.
|
||||
* - ppCP = Pointer to a variable to receive the IConnectionPoint interface pointer.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = Found connection point; interface pointer is in *ppCP.
|
||||
* - E_POINTER = The ppCP pointer is not valid.
|
||||
* - CONNECT_E_NOCONNECTION = The object does not support the interface indicated by riid. *ppCP is NULL.
|
||||
*/
|
||||
static HRESULT cpc_FindConnectionPoint(IConnectionPointContainer *pThis, REFIID riid, IConnectionPoint **ppCP)
|
||||
{
|
||||
PHEAPDATA phd = (PHEAPDATA)HeapDataPtr(pThis); /* pointer to heap data */
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <comrogue/connpoint.h>
|
||||
#include <comrogue/allocator.h>
|
||||
#include <comrogue/objhelp.h>
|
||||
#include <comrogue/internals/seg.h>
|
||||
#include "enumconn.h"
|
||||
|
||||
/*-------------------------------------------
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <comrogue/allocator.h>
|
||||
#include <comrogue/objhelp.h>
|
||||
#include <comrogue/stdobj.h>
|
||||
#include <comrogue/internals/seg.h>
|
||||
#include "enumgeneric.h"
|
||||
|
||||
/*---------------------------------------
|
||||
|
@ -43,6 +44,22 @@
|
|||
*---------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Retrieves pointers to the supported interfaces on an object. Any pointer returned by this method
|
||||
* has AddRef called on it before it returns.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Base interface pointer.
|
||||
* - riid = The identifier of the interface being requested.
|
||||
* - ppvObject = Address of a pointer variable that receives the interface pointer requested by riid.
|
||||
* On return, *ppvObject contains the requested interface pointer, or NULL if the interface
|
||||
* is not supported.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = If the interface is supported. *ppvObject contains the pointer to the interface.
|
||||
* - E_NOINTERFACE = If the interface is not supported. *ppvObject contains NULL.
|
||||
* - E_POINTER = If ppvObject is NULL.
|
||||
*/
|
||||
static HRESULT enumGeneric_QueryInterface(IUnknown *pThis, REFIID riid, PPVOID ppvObject)
|
||||
{
|
||||
PENUMGENERIC peg = (PENUMGENERIC)pThis;
|
||||
|
@ -60,11 +77,29 @@ static HRESULT enumGeneric_QueryInterface(IUnknown *pThis, REFIID riid, PPVOID p
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a reference to the enumerator object.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
*
|
||||
* Returns:
|
||||
* The new reference count on the object.
|
||||
*/
|
||||
static UINT32 enumGeneric_AddRef(IUnknown *pThis)
|
||||
{
|
||||
return ++(((PENUMGENERIC)pThis)->uiRefCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes a reference from the enumerator object. The object is freed when its reference count reaches 0.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
*
|
||||
* Returns:
|
||||
* The new reference count on the object.
|
||||
*/
|
||||
static UINT32 enumGeneric_Release(IUnknown *pThis)
|
||||
{
|
||||
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to actual data block */
|
||||
|
@ -92,6 +127,23 @@ static UINT32 enumGeneric_Release(IUnknown *pThis)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the next number of interface pointers in the enumeration sequence.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
* - celt = Number of interface pointers to be retrieved. If there are more than this many interface pointers
|
||||
* in the enumeration sequence, this many are returned.
|
||||
* - rgelt = Array of enumerated items which will be filled in by this function. Note that the caller is
|
||||
* responsible for releasing all interface pointers returned as a result of this call.
|
||||
* - pceltFetched = Pointer to a variable which will receive the number of interface pointers retrieved. This
|
||||
* value will always be less than or equal to celt.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = All the interface pointers requested were retrieved. *pceltFetched is equal to celt.
|
||||
* - S_FALSE = Not all the interface pointers requested could be retrieved. *pceltFetched is less than celt.
|
||||
* - Other = An error result.
|
||||
*/
|
||||
static HRESULT enumGeneric_Next(IEnumUnknown *pThis, UINT32 celt, IUnknown **rgelt, UINT32 *pceltFetched)
|
||||
{
|
||||
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||
|
@ -110,15 +162,29 @@ static HRESULT enumGeneric_Next(IEnumUnknown *pThis, UINT32 celt, IUnknown **rge
|
|||
/* get number of items to fetch */
|
||||
*pceltFetched = intMin(peg->pPayload->nObjects - peg->nCurrent, celt);
|
||||
for (i = 0; i < *pceltFetched; i++)
|
||||
{ /* fetch the items */
|
||||
rgelt[i] = peg->pPayload->rgObjects[i + peg->nCurrent];
|
||||
IUnknown_AddRef(rgelt[i]);
|
||||
{ /* fetch the items - note we QI for the actual interface we're supposed to be enumerating for */
|
||||
if (FAILED(IUnknown_QueryInterface(peg->pPayload->rgObjects[i + peg->nCurrent], peg->pPayload->riidObjects,
|
||||
(PPVOID)(&(rgelt[i])))))
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
peg->nCurrent += *pceltFetched; /* advance pointer */
|
||||
return (*pceltFetched == celt) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skips over the next number of interface pointers in the enumeration sequence.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
* - celt = Number of elements to be skipped. If there are fewer than this many elements
|
||||
* in the enumeration sequence, we skip straight to the end.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = We were able to skip over all the specified items.
|
||||
* - S_FALSE = We were not able to skip over all the specified items. The current position of the enumeration
|
||||
* is at the end of the sequence.
|
||||
*/
|
||||
static HRESULT enumGeneric_Skip(IEnumUnknown *pThis, UINT32 celt)
|
||||
{
|
||||
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||
|
@ -133,12 +199,34 @@ static HRESULT enumGeneric_Skip(IEnumUnknown *pThis, UINT32 celt)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resets the enumeration sequence to the beginning.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
*
|
||||
* Returns:
|
||||
* S_OK.
|
||||
*/
|
||||
static HRESULT enumGeneric_Reset(IEnumUnknown *pThis)
|
||||
{
|
||||
((PENUMGENERIC)pThis)->nCurrent = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new enumerator with the same state as the current one.
|
||||
*
|
||||
* Parameters:
|
||||
* - pThis = Pointer to the enumerator object (actually its IEnumUnknown interface pointer).
|
||||
* - ppEnum = Pointer to variable to receive the new enumerator object. The caller is responsible for releasing
|
||||
* this pointer.
|
||||
*
|
||||
* Returns:
|
||||
* - S_OK = Success.
|
||||
* - E_INVALIDARG = The pointer argument is not valid.
|
||||
* - E_OUTOFMEMORY = The memory for a new enumerator could not be allocated.
|
||||
*/
|
||||
static HRESULT enumGeneric_Clone(IEnumUnknown *pThis, IEnumUnknown **ppEnum)
|
||||
{
|
||||
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||
|
@ -154,6 +242,7 @@ static HRESULT enumGeneric_Clone(IEnumUnknown *pThis, IEnumUnknown **ppEnum)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* VTable for the IEnumUnknown interface. */
|
||||
static const SEG_RODATA struct IEnumUnknownVTable vtblEnum =
|
||||
{
|
||||
.QueryInterface = enumGeneric_QueryInterface,
|
||||
|
@ -170,7 +259,20 @@ static const SEG_RODATA struct IEnumUnknownVTable vtblEnum =
|
|||
*---------------------------------
|
||||
*/
|
||||
|
||||
PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, UINT32 nCapacity)
|
||||
/*
|
||||
* Allocate the "inner" connection data object for an enumerator.
|
||||
*
|
||||
* Parameters:
|
||||
* - pAllocator = Allocator to use to allocate the memory.
|
||||
* - riidObjects = IID that the objects stored in this block will actually have. NULL is interpreted
|
||||
* as the IID of IUnknown.
|
||||
* - nCapacity = Number of slots to allocate for the object pointers.
|
||||
*
|
||||
* Returns:
|
||||
* - NULL = The data object could not be allocated.
|
||||
* - Other = Pointer to the new data object. Its reference count is 0 and it contains no elements.
|
||||
*/
|
||||
PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, REFIID riidObjects, UINT32 nCapacity)
|
||||
{
|
||||
register PENUMGENERICDATA rc; /* return from this function */
|
||||
register SIZE_T cbReturn = sizeof(ENUMGENERICDATA) + (nCapacity * sizeof(PUNKNOWN)); /* bytes to allocate */
|
||||
|
@ -180,12 +282,22 @@ PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, UINT32 nCap
|
|||
{
|
||||
StrSetMem(rc, 0, cbReturn);
|
||||
rc->uiRefCount = 0;
|
||||
rc->riidObjects = riidObjects ? riidObjects : &IID_IUnknown;
|
||||
rc->nObjects = 0;
|
||||
}
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an element to the specified "inner" object reference data object. Used when building the object.
|
||||
*
|
||||
* Parameters:
|
||||
* - pegd = Pointer to the reference data object.
|
||||
* - pUnk = IUnknown pointer to add to the "next" slot. A reference is added to this pointer.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void _ObjHlpAddToEnumGenericData(PENUMGENERICDATA pegd, IUnknown *pUnk)
|
||||
{
|
||||
pegd->rgObjects[pegd->nObjects] = pUnk;
|
||||
|
@ -193,6 +305,16 @@ void _ObjHlpAddToEnumGenericData(PENUMGENERICDATA pegd, IUnknown *pUnk)
|
|||
pegd->nObjects++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Discards the contents of an "inner" object reference data object by releasing all the interface pointers
|
||||
* it contains.
|
||||
*
|
||||
* Parameters:
|
||||
* - pegd = Pointer to the reference data object.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pegd)
|
||||
{
|
||||
register UINT32 i; /* loop counter */
|
||||
|
@ -201,6 +323,20 @@ void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pegd)
|
|||
IUnknown_Release(pegd->rgObjects[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates a new "enumerator" data object.
|
||||
*
|
||||
* Parameters:
|
||||
* - pAllocator = Allocator to use to allocate the memory.
|
||||
* - riidActual = IID that this enumerator will actually support, in addition to IUnknown. NULL is
|
||||
* interpreted as IID_IEnumUnknown.
|
||||
* - pegd = Pointer to the "inner" reference data object to be used.
|
||||
* - nCurrent = Value to set the "current" element pointer to.
|
||||
*
|
||||
* Returns:
|
||||
* - NULL = The enumerator object could not be allocated.
|
||||
* - Other = Pointer to the new enumerator object. Its reference count is 0.
|
||||
*/
|
||||
PENUMGENERIC _ObjHlpAllocateEnumGeneric(IMalloc *pAllocator, REFIID riidActual, PENUMGENERICDATA pegd,
|
||||
UINT32 nCurrent)
|
||||
{
|
||||
|
@ -211,7 +347,7 @@ PENUMGENERIC _ObjHlpAllocateEnumGeneric(IMalloc *pAllocator, REFIID riidActual,
|
|||
{ /* initialize all the fields */
|
||||
rc->enumUnknown.pVTable = &vtblEnum;
|
||||
rc->uiRefCount = 0;
|
||||
rc->riidActual = riidActual;
|
||||
rc->riidActual = riidActual ? riidActual : &IID_IEnumUnknown;
|
||||
rc->nCurrent = nCurrent;
|
||||
rc->pPayload = pegd;
|
||||
pegd->uiRefCount++;
|
||||
|
|
Loading…
Reference in New Issue
Block a user