fleshed out the connection point implementation, especially the enumerations part
This commit is contained in:
parent
a5aeeb2980
commit
c728482744
|
@ -69,3 +69,20 @@ interface IServiceProvider : IUnknown
|
||||||
[unique] typedef IServiceProvider *PSERVICEPROVIDER;
|
[unique] typedef IServiceProvider *PSERVICEPROVIDER;
|
||||||
HRESULT QueryService([in] REFGUID guidService, [in] REFIID riid, [out, iid_is(riid)] PPVOID ppvObject);
|
HRESULT QueryService([in] REFGUID guidService, [in] REFIID riid, [out, iid_is(riid)] PPVOID ppvObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------
|
||||||
|
* IEnumUnknown interface
|
||||||
|
*------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
[object, uuid(00000100-0000-0000-C000-000000000046), pointer_default(unique)]
|
||||||
|
interface IEnumUnknown: IUnknown
|
||||||
|
{
|
||||||
|
[unique] typedef IEnumUnknown *PENUMUNKNOWN;
|
||||||
|
|
||||||
|
HRESULT Next([in] UINT32 celt, [out, size_is(celt), length_is(*pceltFetched)] IUnknown **rgelt,
|
||||||
|
[out] UINT32 *pceltFetched);
|
||||||
|
HRESULT Skip([in] UINT32 celt);
|
||||||
|
HRESULT Reset(void);
|
||||||
|
HRESULT Clone([out] IEnumUnknown **ppEnum);
|
||||||
|
}
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
|
|
||||||
typedef struct tagRAWHEAPDATA
|
typedef struct tagRAWHEAPDATA
|
||||||
{
|
{
|
||||||
UINT32 opaque[8];
|
UINT32 opaque[32]; /* opaque data, do not modify */
|
||||||
} RAWHEAPDATA, *PRAWHEAPDATA;
|
} RAWHEAPDATA, *PRAWHEAPDATA;
|
||||||
|
|
||||||
typedef void (*PFNRAWHEAPDATAFREE)(PRAWHEAPDATA prhd);
|
typedef void (*PFNRAWHEAPDATAFREE)(PRAWHEAPDATA prhd); /* function that optionally frees the heap data */
|
||||||
|
|
||||||
/*--------------------
|
/*--------------------
|
||||||
* External functions
|
* External functions
|
||||||
|
|
|
@ -51,8 +51,9 @@ typedef struct tagFIXEDCPDATA
|
||||||
PUNKNOWN punkOuter; /* outer unknown used for reference counts */
|
PUNKNOWN punkOuter; /* outer unknown used for reference counts */
|
||||||
REFIID riidConnection; /* IID of outgoing interface for this connection point */
|
REFIID riidConnection; /* IID of outgoing interface for this connection point */
|
||||||
IUnknown **ppSlots; /* pointer to actual slots used for connection point storage */
|
IUnknown **ppSlots; /* pointer to actual slots used for connection point storage */
|
||||||
INT32 ncpSize; /* number of connection points actually connected */
|
UINT32 ncpSize; /* number of connection points actually connected */
|
||||||
INT32 ncpCapacity; /* maximum number of connection points connectable */
|
UINT32 ncpCapacity; /* maximum number of connection points connectable */
|
||||||
|
IMalloc *pAllocator; /* pointer to allocator */
|
||||||
} FIXEDCPDATA, *PFIXEDCPDATA;
|
} FIXEDCPDATA, *PFIXEDCPDATA;
|
||||||
|
|
||||||
/*---------------------
|
/*---------------------
|
||||||
|
@ -64,6 +65,7 @@ CDECL_BEGIN
|
||||||
|
|
||||||
/* QueryInterface helpers */
|
/* QueryInterface helpers */
|
||||||
extern HRESULT ObjHlpStandardQueryInterface_IConnectionPoint(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
extern HRESULT ObjHlpStandardQueryInterface_IConnectionPoint(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
||||||
|
extern HRESULT ObjHlpStandardQueryInterface_IEnumConnections(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
||||||
extern HRESULT ObjHlpStandardQueryInterface_IMalloc(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
extern HRESULT ObjHlpStandardQueryInterface_IMalloc(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
||||||
extern HRESULT ObjHlpStandardQueryInterface_ISequentialStream(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
extern HRESULT ObjHlpStandardQueryInterface_ISequentialStream(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ extern UINT32 ObjHlpStaticAddRefRelease(IUnknown *pThis);
|
||||||
|
|
||||||
/* Connection point helpers */
|
/* Connection point helpers */
|
||||||
extern void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection,
|
extern void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection,
|
||||||
IUnknown **ppSlots, INT32 nSlots);
|
IUnknown **ppSlots, UINT32 nSlots, IMalloc *pAllocator);
|
||||||
extern void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData);
|
extern void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData);
|
||||||
|
|
||||||
/* Other helpers */
|
/* Other helpers */
|
||||||
|
|
|
@ -93,6 +93,10 @@
|
||||||
#define STG_S_CONSOLIDATIONFAILED SCODE_CAST(0x00030205) /* consolidation failed but commit OK */
|
#define STG_S_CONSOLIDATIONFAILED SCODE_CAST(0x00030205) /* consolidation failed but commit OK */
|
||||||
#define STG_S_CANNOTCONSOLIDATE SCODE_CAST(0x00030206) /* cannot consolidate but commit OK */
|
#define STG_S_CANNOTCONSOLIDATE SCODE_CAST(0x00030206) /* cannot consolidate but commit OK */
|
||||||
|
|
||||||
|
/* Connection success codes */
|
||||||
|
#define CONNECT_S_FIRST SCODE_CAST(0x00040200) /* first connection success code */
|
||||||
|
#define CONNECT_S_LAST SCODE_CAST(0x0004020F) /* last connection success code */
|
||||||
|
|
||||||
/* Memory manager success codes */
|
/* Memory manager success codes */
|
||||||
#define MEMMGR_S_NONZEROED SCODE_CAST(0x06010001) /* returned memory is non-zeroed */
|
#define MEMMGR_S_NONZEROED SCODE_CAST(0x06010001) /* returned memory is non-zeroed */
|
||||||
|
|
||||||
|
@ -158,6 +162,15 @@
|
||||||
#define STG_E_CSSINVALIDREGION SCODE_CAST(0x8003030A) /* region identifier mismatch */
|
#define STG_E_CSSINVALIDREGION SCODE_CAST(0x8003030A) /* region identifier mismatch */
|
||||||
#define STG_E_NOMOREREGIONRESETS SCODE_CAST(0x8003030B) /* can't reset drive region anymore */
|
#define STG_E_NOMOREREGIONRESETS SCODE_CAST(0x8003030B) /* can't reset drive region anymore */
|
||||||
|
|
||||||
|
/* Connection error codes */
|
||||||
|
#define CONNECT_E_FIRST SCODE_CAST(0x80040200) /* first connection error code */
|
||||||
|
#define CONNECT_E_LAST SCODE_CAST(0x8004020F) /* last connection error code */
|
||||||
|
|
||||||
|
#define CONNECT_E_NOCONNECTION (CONNECT_E_FIRST+0) /* no connection found */
|
||||||
|
#define CONNECT_E_ADVISELIMIT (CONNECT_E_FIRST+1) /* limit for number of connections reached */
|
||||||
|
#define CONNECT_E_CANNOTCONNECT (CONNECT_E_FIRST+2) /* connection attempt failed */
|
||||||
|
#define CONNECT_E_OVERRIDDEN (CONNECT_E_FIRST+3) /* interface overridden, must use derived */
|
||||||
|
|
||||||
/* Memory manager error codes */
|
/* Memory manager error codes */
|
||||||
#define MEMMGR_E_NOPGTBL SCODE_CAST(0x86010001) /* no page tables available */
|
#define MEMMGR_E_NOPGTBL SCODE_CAST(0x86010001) /* no page tables available */
|
||||||
#define MEMMGR_E_BADTTBFLG SCODE_CAST(0x86010002) /* bad TTB flags encountered */
|
#define MEMMGR_E_BADTTBFLG SCODE_CAST(0x86010002) /* bad TTB flags encountered */
|
||||||
|
|
|
@ -32,8 +32,8 @@ MAKEFLAGS += -rR
|
||||||
CRBASEDIR := $(abspath ../..)
|
CRBASEDIR := $(abspath ../..)
|
||||||
include $(CRBASEDIR)/armcompile.mk
|
include $(CRBASEDIR)/armcompile.mk
|
||||||
|
|
||||||
LIB_OBJS = divide.o qdivrem.o heap_toplevel.o intlib.o objhelp.o objhelp_fixedcp.o rbtree.o str.o \
|
LIB_OBJS = divide.o qdivrem.o heap_toplevel.o intlib.o objhelp.o objhelp_enumconn.o objhelp_enumgeneric.o \
|
||||||
strcopymem.o strcomparemem.o strsetmem.o lib_guids.o
|
objhelp_fixedcp.o rbtree.o str.o strcopymem.o strcomparemem.o strsetmem.o lib_guids.o
|
||||||
|
|
||||||
all: kernel-lib.o
|
all: kernel-lib.o
|
||||||
|
|
||||||
|
|
77
kernel/lib/enumconn.h
Normal file
77
kernel/lib/enumconn.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ENUMCONN_H_INCLUDED
|
||||||
|
#define __ENUMCONN_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __COMROGUE_INTERNALS__
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/connpoint.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
|
||||||
|
/*---------------------------------------------------
|
||||||
|
* Data structures for implementing IEnumConnections
|
||||||
|
*---------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct tagENUMCONNDATA {
|
||||||
|
UINT32 uiRefCount; /* reference count */
|
||||||
|
UINT32 nConnectData; /* count of CONNECTDATA */
|
||||||
|
CONNECTDATA rgConnectData[0]; /* array of CONNECTDATA */
|
||||||
|
} ENUMCONNDATA, *PENUMCONNDATA;
|
||||||
|
|
||||||
|
typedef struct tagENUMCONN {
|
||||||
|
IEnumConnections enumConnections; /* interface pointer */
|
||||||
|
UINT32 uiRefCount; /* reference count */
|
||||||
|
UINT32 nCurrent; /* current pointer into array */
|
||||||
|
PENUMCONNDATA pPayload; /* payload array */
|
||||||
|
IMalloc *pAllocator; /* allocator pointer */
|
||||||
|
} ENUMCONN, *PENUMCONN;
|
||||||
|
|
||||||
|
/*---------------------------------------------------
|
||||||
|
* Functions for implementing IEnumConnections
|
||||||
|
*---------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern PENUMCONNDATA _ObjHlpAllocateEnumConnData(IMalloc *pAllocator, UINT32 nCapacity);
|
||||||
|
extern void _ObjHlpAddToEnumConnData(PENUMCONNDATA pecd, IUnknown *pUnk, UINT32 uiCookie);
|
||||||
|
extern void _ObjHlpDiscardEnumConnData(PENUMCONNDATA pecd);
|
||||||
|
extern PENUMCONN _ObjHlpAllocateEnumConn(IMalloc *pAllocator, PENUMCONNDATA pecd, UINT32 nCurrent);
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __COMROGUE_INTERNALS__ */
|
||||||
|
|
||||||
|
#endif /* __ENUMCONN_H_INCLUDED */
|
78
kernel/lib/enumgeneric.h
Normal file
78
kernel/lib/enumgeneric.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __ENUMGENERIC_H_INCLUDED
|
||||||
|
#define __ENUMGENERIC_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __COMROGUE_INTERNALS__
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------
|
||||||
|
* Data structures for implementing IEnumUnknown or any interface that enumerates interface pointers
|
||||||
|
*---------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct tagENUMGENERICDATA {
|
||||||
|
UINT32 uiRefCount; /* reference count */
|
||||||
|
UINT32 nObjects; /* count of IUnknown pointers */
|
||||||
|
PUNKNOWN rgObjects[0]; /* array of IUnknown pointers */
|
||||||
|
} ENUMGENERICDATA, *PENUMGENERICDATA;
|
||||||
|
|
||||||
|
typedef struct tagENUMGENERIC {
|
||||||
|
IEnumUnknown enumUnknown; /* interface pointer */
|
||||||
|
UINT32 uiRefCount; /* reference count */
|
||||||
|
REFIID riidActual; /* IID of actual interface */
|
||||||
|
UINT32 nCurrent; /* current pointer into array */
|
||||||
|
PENUMGENERICDATA pPayload; /* payload array */
|
||||||
|
IMalloc *pAllocator; /* allocator pointer */
|
||||||
|
} ENUMGENERIC, *PENUMGENERIC;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Functions for implementing IEnumUnknown or any interface that enumerates interface pointers
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, UINT32 nCapacity);
|
||||||
|
extern void _ObjHlpAddToEnumGenericData(PENUMGENERICDATA pegd, IUnknown *pUnk);
|
||||||
|
extern void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pecd);
|
||||||
|
extern PENUMGENERIC _ObjHlpAllocateEnumGeneric(IMalloc *pAllocator, REFIID riidActual, PENUMGENERICDATA pegd,
|
||||||
|
UINT32 nCurrent);
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __COMROGUE_INTERNALS__ */
|
||||||
|
|
||||||
|
#endif /* __ENUMGENERIC_H_INCLUDED */
|
|
@ -35,10 +35,15 @@
|
||||||
#ifndef __HEAP_INTERNALS_H_INCLUDED
|
#ifndef __HEAP_INTERNALS_H_INCLUDED
|
||||||
#define __HEAP_INTERNALS_H_INCLUDED
|
#define __HEAP_INTERNALS_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __COMROGUE_INTERNALS__
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
#include <comrogue/objectbase.h>
|
#include <comrogue/objectbase.h>
|
||||||
#include <comrogue/connpoint.h>
|
#include <comrogue/connpoint.h>
|
||||||
#include <comrogue/allocator.h>
|
#include <comrogue/allocator.h>
|
||||||
#include <comrogue/heap.h>
|
#include <comrogue/heap.h>
|
||||||
|
#include <comrogue/objhelp.h>
|
||||||
|
|
||||||
/*----------------------------------
|
/*----------------------------------
|
||||||
* The actual heap data declaration
|
* The actual heap data declaration
|
||||||
|
@ -49,8 +54,17 @@ typedef struct tagHEAPDATA {
|
||||||
IMalloc mallocInterface; /* pointer to IMalloc interface - MUST BE FIRST! */
|
IMalloc mallocInterface; /* pointer to IMalloc interface - MUST BE FIRST! */
|
||||||
IConnectionPointContainer cpContainerInterface; /* pointer to IConnectionPointContainer interface */
|
IConnectionPointContainer cpContainerInterface; /* pointer to IConnectionPointContainer interface */
|
||||||
UINT32 uiRefCount; /* reference count */
|
UINT32 uiRefCount; /* reference count */
|
||||||
|
UINT32 uiFlags; /* flags word */
|
||||||
PFNRAWHEAPDATAFREE pfnFreeRawHeapData; /* pointer to function that frees the raw heap data, if any */
|
PFNRAWHEAPDATAFREE pfnFreeRawHeapData; /* pointer to function that frees the raw heap data, if any */
|
||||||
IChunkAllocator *pChunkAllocator; /* chunk allocator pointer */
|
IChunkAllocator *pChunkAllocator; /* chunk allocator pointer */
|
||||||
|
FIXEDCPDATA fcpMallocSpy; /* connection point for IMallocSpy */
|
||||||
|
FIXEDCPDATA fcpSequentialStream; /* connection point for ISequentialStream for debugging */
|
||||||
|
IMallocSpy *pMallocSpy; /* IMallocSpy interface for the allocator */
|
||||||
|
ISequentialStream *pDebugStream; /* debugging output stream */
|
||||||
} HEAPDATA, *PHEAPDATA;
|
} HEAPDATA, *PHEAPDATA;
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __COMROGUE_INTERNALS__ */
|
||||||
|
|
||||||
#endif /* __HEAP_INTERNALS_H_INCLUDED */
|
#endif /* __HEAP_INTERNALS_H_INCLUDED */
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
#include <comrogue/internals/seg.h>
|
#include <comrogue/internals/seg.h>
|
||||||
#include "heap_internals.h"
|
#include "heap_internals.h"
|
||||||
|
|
||||||
|
#define PHDFLAGS_DELETING 0x80000000 /* deleting the heap */
|
||||||
|
|
||||||
/*------------------------
|
/*------------------------
|
||||||
* IMalloc implementation
|
* IMalloc implementation
|
||||||
*------------------------
|
*------------------------
|
||||||
|
@ -105,8 +107,11 @@ static UINT32 malloc_Release(IUnknown *pThis)
|
||||||
PFNRAWHEAPDATAFREE pfnFree; /* pointer to "free" function */
|
PFNRAWHEAPDATAFREE pfnFree; /* pointer to "free" function */
|
||||||
|
|
||||||
rc = --(phd->uiRefCount);
|
rc = --(phd->uiRefCount);
|
||||||
if (rc == 0)
|
if ((rc == 0) && !(phd->uiFlags & PHDFLAGS_DELETING))
|
||||||
{
|
{
|
||||||
|
phd->uiFlags |= PHDFLAGS_DELETING;
|
||||||
|
ObjHlpFixedCpTeardown(&(phd->fcpMallocSpy));
|
||||||
|
ObjHlpFixedCpTeardown(&(phd->fcpSequentialStream));
|
||||||
IUnknown_Release(phd->pChunkAllocator);
|
IUnknown_Release(phd->pChunkAllocator);
|
||||||
if (phd->pfnFreeRawHeapData)
|
if (phd->pfnFreeRawHeapData)
|
||||||
{
|
{
|
||||||
|
@ -218,12 +223,26 @@ static UINT32 cpc_Release(IUnknown *pThis)
|
||||||
|
|
||||||
static HRESULT cpc_EnumConnectionPoints(IConnectionPointContainer *pThis, IEnumConnectionPoints **ppEnum)
|
static HRESULT cpc_EnumConnectionPoints(IConnectionPointContainer *pThis, IEnumConnectionPoints **ppEnum)
|
||||||
{
|
{
|
||||||
|
PHEAPDATA phd = (PHEAPDATA)HeapDataPtr(pThis); /* pointer to heap data */
|
||||||
|
|
||||||
return E_NOTIMPL; /* TODO */
|
return E_NOTIMPL; /* TODO */
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT cpc_FindConnectionPoint(IConnectionPointContainer *pThis, REFIID riid, IConnectionPoint **ppCP)
|
static HRESULT cpc_FindConnectionPoint(IConnectionPointContainer *pThis, REFIID riid, IConnectionPoint **ppCP)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL; /* TODO */
|
PHEAPDATA phd = (PHEAPDATA)HeapDataPtr(pThis); /* pointer to heap data */
|
||||||
|
|
||||||
|
if (!ppCP)
|
||||||
|
return E_POINTER;
|
||||||
|
*ppCP = NULL;
|
||||||
|
if (IsEqualIID(riid, &IID_IMallocSpy))
|
||||||
|
*ppCP = (IConnectionPoint *)(&(phd->fcpMallocSpy));
|
||||||
|
else if (IsEqualIID(riid, &IID_ISequentialStream))
|
||||||
|
*ppCP = (IConnectionPoint *)(&(phd->fcpSequentialStream));
|
||||||
|
else
|
||||||
|
return CONNECT_E_NOCONNECTION;
|
||||||
|
IUnknown_AddRef(*ppCP);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The IConnectionPointContainer vtable. */
|
/* The IConnectionPointContainer vtable. */
|
||||||
|
@ -272,9 +291,13 @@ HRESULT HeapCreate(PRAWHEAPDATA prhd, PFNRAWHEAPDATAFREE pfnFree, IChunkAllocato
|
||||||
phd->mallocInterface.pVTable = &vtblMalloc;
|
phd->mallocInterface.pVTable = &vtblMalloc;
|
||||||
phd->cpContainerInterface.pVTable = &vtblConnectionPointContainer;
|
phd->cpContainerInterface.pVTable = &vtblConnectionPointContainer;
|
||||||
phd->uiRefCount = 1;
|
phd->uiRefCount = 1;
|
||||||
|
phd->uiFlags = 0;
|
||||||
phd->pfnFreeRawHeapData = pfnFree;
|
phd->pfnFreeRawHeapData = pfnFree;
|
||||||
phd->pChunkAllocator = pChunkAllocator;
|
phd->pChunkAllocator = pChunkAllocator;
|
||||||
IUnknown_AddRef(phd->pChunkAllocator);
|
IUnknown_AddRef(phd->pChunkAllocator);
|
||||||
|
ObjHlpFixedCpSetup(&(phd->fcpMallocSpy), (PUNKNOWN)phd, &IID_IMallocSpy, (IUnknown **)(&(phd->pMallocSpy)), 1, NULL);
|
||||||
|
ObjHlpFixedCpSetup(&(phd->fcpSequentialStream), (PUNKNOWN)phd, &IID_ISequentialStream,
|
||||||
|
(IUnknown **)(&(phd->pDebugStream)), 1, NULL);
|
||||||
|
|
||||||
*ppHeap = (IMalloc *)phd;
|
*ppHeap = (IMalloc *)phd;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -94,6 +94,7 @@ HRESULT ObjHlpStandardQueryInterface_ ## iface (IUnknown *pThis, REFIID riid, PP
|
||||||
}
|
}
|
||||||
|
|
||||||
MAKE_BASE_QI(IConnectionPoint)
|
MAKE_BASE_QI(IConnectionPoint)
|
||||||
|
MAKE_BASE_QI(IEnumConnections)
|
||||||
MAKE_BASE_QI(IMalloc)
|
MAKE_BASE_QI(IMalloc)
|
||||||
MAKE_BASE_QI(ISequentialStream)
|
MAKE_BASE_QI(ISequentialStream)
|
||||||
|
|
||||||
|
|
319
kernel/lib/objhelp_enumconn.c
Normal file
319
kernel/lib/objhelp_enumconn.c
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/intlib.h>
|
||||||
|
#include <comrogue/str.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/connpoint.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
#include <comrogue/objhelp.h>
|
||||||
|
#include "enumconn.h"
|
||||||
|
|
||||||
|
/*-------------------------------------------
|
||||||
|
* IEnumConnections interface implementation
|
||||||
|
*-------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a reference to the enumerator object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the enumerator object (actually its IEnumConnections interface pointer).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The new reference count on the object.
|
||||||
|
*/
|
||||||
|
static UINT32 enumConn_AddRef(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
return ++(((PENUMCONN)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 IEnumConnections interface pointer).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The new reference count on the object.
|
||||||
|
*/
|
||||||
|
static UINT32 enumConn_Release(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
register PENUMCONN pec = (PENUMCONN)pThis; /* pointer to actual data block */
|
||||||
|
register UINT32 rc; /* return from this function */
|
||||||
|
IMalloc *pAllocator; /* temporary for allocator */
|
||||||
|
PENUMCONNDATA pecd; /* temporary for underlying connections data block */
|
||||||
|
|
||||||
|
rc = --(pec->uiRefCount);
|
||||||
|
if (rc == 0)
|
||||||
|
{ /* save off allocator before deallocating */
|
||||||
|
pAllocator = pec->pAllocator;
|
||||||
|
IUnknown_AddRef(pAllocator);
|
||||||
|
/* save off payload too */
|
||||||
|
pecd = pec->pPayload;
|
||||||
|
/* erase enumerator */
|
||||||
|
IUnknown_Release(pec->pAllocator);
|
||||||
|
IMalloc_Free(pAllocator, pec);
|
||||||
|
if (--(pecd->uiRefCount) == 0)
|
||||||
|
{ /* we need to erase the data block too */
|
||||||
|
_ObjHlpDiscardEnumConnData(pecd);
|
||||||
|
IMalloc_Free(pAllocator, pecd);
|
||||||
|
}
|
||||||
|
IUnknown_Release(pAllocator); /* release temporary reference we added */
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieves the next number of connections in the enumeration sequence.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the enumerator object (actually its IEnumConnections interface pointer).
|
||||||
|
* - cConnections = Number of connections to be retrieved. If there are more than this many connections
|
||||||
|
* in the enumeration sequence, this many are returned.
|
||||||
|
* - rgcd = 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.
|
||||||
|
* - pcFetched = Pointer to a variable which will receive the number of connections retrieved. This value will
|
||||||
|
* always be less than or equal to cConnections.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - S_OK = All the connections requested were retrieved. *pcFetched is equal to cConnections.
|
||||||
|
* - S_FALSE = Not all the connections requested could be retrieved. *pcFetched is less than cConnections.
|
||||||
|
* - Other = An error result.
|
||||||
|
*/
|
||||||
|
static HRESULT enumConn_Next(IEnumConnections *pThis, UINT32 cConnections, PCONNECTDATA rgcd, UINT32 *pcFetched)
|
||||||
|
{
|
||||||
|
register PENUMCONN pec = (PENUMCONN)pThis; /* pointer to data block */
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
if (cConnections == 0)
|
||||||
|
{ /* nothing to retrieve */
|
||||||
|
if (pcFetched)
|
||||||
|
*pcFetched = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pcFetched)
|
||||||
|
return E_POINTER; /* invalid pointer */
|
||||||
|
|
||||||
|
/* get number of items to fetch */
|
||||||
|
*pcFetched = intMin(pec->pPayload->nConnectData - pec->nCurrent, cConnections);
|
||||||
|
for (i = 0; i < *pcFetched; i++)
|
||||||
|
{ /* fetch the items */
|
||||||
|
rgcd[i].pUnk = pec->pPayload->rgConnectData[i + pec->nCurrent].pUnk;
|
||||||
|
IUnknown_AddRef(rgcd[i].pUnk);
|
||||||
|
rgcd[i].uiCookie = pec->pPayload->rgConnectData[i + pec->nCurrent].uiCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
pec->nCurrent += *pcFetched; /* advance pointer */
|
||||||
|
return (*pcFetched == cConnections) ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skips over the next number of connections in the enumeration sequence.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the enumerator object (actually its IEnumConnections interface pointer).
|
||||||
|
* - cConnections = Number of connections to be skipped. If there are fewer than this many connections
|
||||||
|
* 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 enumConn_Skip(IEnumConnections *pThis, UINT32 cConnections)
|
||||||
|
{
|
||||||
|
register PENUMCONN pec = (PENUMCONN)pThis; /* pointer to data block */
|
||||||
|
register HRESULT rc = S_OK; /* return from this function */
|
||||||
|
|
||||||
|
pec->nCurrent += cConnections;
|
||||||
|
if (pec->nCurrent > pec->pPayload->nConnectData)
|
||||||
|
{ /* clamp current pointer and return FALSE */
|
||||||
|
pec->nCurrent = pec->pPayload->nConnectData;
|
||||||
|
rc = S_FALSE;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resets the enumeration sequence to the beginning.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the enumerator object (actually its IEnumConnections interface pointer).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* S_OK.
|
||||||
|
*/
|
||||||
|
static HRESULT enumConn_Reset(IEnumConnections *pThis)
|
||||||
|
{
|
||||||
|
((PENUMCONN)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 IEnumConnections 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 enumConn_Clone(IEnumConnections *pThis, IEnumConnections **ppEnum)
|
||||||
|
{
|
||||||
|
register PENUMCONN pec = (PENUMCONN)pThis; /* pointer to data block */
|
||||||
|
register PENUMCONN pecNew; /* pointer to new enumerator */
|
||||||
|
|
||||||
|
if (!ppEnum) /* no pointer? */
|
||||||
|
return E_INVALIDARG;
|
||||||
|
*ppEnum = NULL;
|
||||||
|
pecNew = _ObjHlpAllocateEnumConn(pec->pAllocator, pec->pPayload, pec->nCurrent);
|
||||||
|
if (!pecNew) /* failed to allocate? */
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
IUnknown_QueryInterface((IUnknown *)pecNew, &IID_IEnumConnections, (PPVOID)ppEnum);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The VTable for the IEnumConnections interface. */
|
||||||
|
static const SEG_RODATA struct IEnumConnectionsVTable vtblEnumConnections =
|
||||||
|
{
|
||||||
|
.QueryInterface = ObjHlpStandardQueryInterface_IEnumConnections,
|
||||||
|
.AddRef = enumConn_AddRef,
|
||||||
|
.Release = enumConn_Release,
|
||||||
|
.Next = enumConn_Next,
|
||||||
|
.Skip = enumConn_Skip,
|
||||||
|
.Reset = enumConn_Reset,
|
||||||
|
.Clone = enumConn_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------
|
||||||
|
* IEnumConnections helper functions
|
||||||
|
*-----------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate the "inner" connection data object for an enumerator.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pAllocator = Allocator to use to allocate the memory.
|
||||||
|
* - nCapacity = Number of slots to allocate for the connection data.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
PENUMCONNDATA _ObjHlpAllocateEnumConnData(IMalloc *pAllocator, UINT32 nCapacity)
|
||||||
|
{
|
||||||
|
register PENUMCONNDATA rc; /* return from this function */
|
||||||
|
register SIZE_T cbReturn = sizeof(ENUMCONNDATA) + (nCapacity * sizeof(CONNECTDATA)); /* bytes to allocate */
|
||||||
|
|
||||||
|
rc = (PENUMCONNDATA)(IMalloc_Alloc(pAllocator, cbReturn));
|
||||||
|
if (rc != NULL)
|
||||||
|
{
|
||||||
|
StrSetMem(rc, 0, cbReturn);
|
||||||
|
rc->uiRefCount = 0;
|
||||||
|
rc->nConnectData = 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an element to the specified "inner" connection data object. Used when building the object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pecd = Pointer to the connection data object.
|
||||||
|
* - pUnk = IUnknown pointer to add to the "next" slot. A reference is added to this pointer.
|
||||||
|
* - uiCookie = Cookie value to add to the "next" slot.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
|
void _ObjHlpAddToEnumConnData(PENUMCONNDATA pecd, IUnknown *pUnk, UINT32 uiCookie)
|
||||||
|
{
|
||||||
|
pecd->rgConnectData[pecd->nConnectData].pUnk = pUnk;
|
||||||
|
IUnknown_AddRef(pecd->rgConnectData[pecd->nConnectData].pUnk);
|
||||||
|
pecd->rgConnectData[pecd->nConnectData].uiCookie = uiCookie;
|
||||||
|
pecd->nConnectData++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Discards the contents of an "inner" connection data object by releasing all the interface pointers
|
||||||
|
* it contains.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pecd = Pointer to the connection data object.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
|
void _ObjHlpDiscardEnumConnData(PENUMCONNDATA pecd)
|
||||||
|
{
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
for (i = 0; i < pecd->nConnectData; i++)
|
||||||
|
IUnknown_Release(pecd->rgConnectData[i].pUnk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocates a new "enumerator" data object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pAllocator = Allocator to use to allocate the memory.
|
||||||
|
* - pecd = Pointer to the "inner" connection 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.
|
||||||
|
*/
|
||||||
|
PENUMCONN _ObjHlpAllocateEnumConn(IMalloc *pAllocator, PENUMCONNDATA pecd, UINT32 nCurrent)
|
||||||
|
{
|
||||||
|
register PENUMCONN rc; /* return from this function */
|
||||||
|
|
||||||
|
rc = (PENUMCONN)(IMalloc_Alloc(pAllocator, sizeof(ENUMCONN)));
|
||||||
|
if (rc)
|
||||||
|
{ /* initialize all the fields */
|
||||||
|
rc->enumConnections.pVTable = &vtblEnumConnections;
|
||||||
|
rc->uiRefCount = 0;
|
||||||
|
rc->nCurrent = nCurrent;
|
||||||
|
rc->pPayload = pecd;
|
||||||
|
pecd->uiRefCount++;
|
||||||
|
rc->pAllocator = pAllocator;
|
||||||
|
IUnknown_AddRef(rc->pAllocator);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
222
kernel/lib/objhelp_enumgeneric.c
Normal file
222
kernel/lib/objhelp_enumgeneric.c
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/intlib.h>
|
||||||
|
#include <comrogue/str.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
#include <comrogue/objhelp.h>
|
||||||
|
#include <comrogue/stdobj.h>
|
||||||
|
#include "enumgeneric.h"
|
||||||
|
|
||||||
|
/*---------------------------------------
|
||||||
|
* IEnumUnknown interface implementation
|
||||||
|
*---------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static HRESULT enumGeneric_QueryInterface(IUnknown *pThis, REFIID riid, PPVOID ppvObject)
|
||||||
|
{
|
||||||
|
PENUMGENERIC peg = (PENUMGENERIC)pThis;
|
||||||
|
|
||||||
|
if (!ppvObject)
|
||||||
|
return E_POINTER;
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, peg->riidActual))
|
||||||
|
{
|
||||||
|
*ppvObject = pThis;
|
||||||
|
IUnknown_AddRef((PUNKNOWN)(*ppvObject));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT32 enumGeneric_AddRef(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
return ++(((PENUMGENERIC)pThis)->uiRefCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT32 enumGeneric_Release(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to actual data block */
|
||||||
|
register UINT32 rc; /* return from this function */
|
||||||
|
IMalloc *pAllocator; /* temporary for allocator */
|
||||||
|
PENUMGENERICDATA pegd; /* temporary for underlying objects data block */
|
||||||
|
|
||||||
|
rc = --(peg->uiRefCount);
|
||||||
|
if (rc == 0)
|
||||||
|
{ /* save off allocator before deallocating */
|
||||||
|
pAllocator = peg->pAllocator;
|
||||||
|
IUnknown_AddRef(pAllocator);
|
||||||
|
/* save off payload too */
|
||||||
|
pegd = peg->pPayload;
|
||||||
|
/* erase enumerator */
|
||||||
|
IUnknown_Release(peg->pAllocator);
|
||||||
|
IMalloc_Free(pAllocator, peg);
|
||||||
|
if (--(pegd->uiRefCount) == 0)
|
||||||
|
{ /* we need to erase the data block too */
|
||||||
|
_ObjHlpDiscardEnumGenericData(pegd);
|
||||||
|
IMalloc_Free(pAllocator, pegd);
|
||||||
|
}
|
||||||
|
IUnknown_Release(pAllocator); /* release temporary reference we added */
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT enumGeneric_Next(IEnumUnknown *pThis, UINT32 celt, IUnknown **rgelt, UINT32 *pceltFetched)
|
||||||
|
{
|
||||||
|
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
if (celt == 0)
|
||||||
|
{ /* nothing to retrieve */
|
||||||
|
if (pceltFetched)
|
||||||
|
*pceltFetched = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pceltFetched)
|
||||||
|
return E_POINTER; /* invalid pointer */
|
||||||
|
|
||||||
|
/* 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
peg->nCurrent += *pceltFetched; /* advance pointer */
|
||||||
|
return (*pceltFetched == celt) ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT enumGeneric_Skip(IEnumUnknown *pThis, UINT32 celt)
|
||||||
|
{
|
||||||
|
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||||
|
register HRESULT rc = S_OK; /* return from this function */
|
||||||
|
|
||||||
|
peg->nCurrent += celt;
|
||||||
|
if (peg->nCurrent > peg->pPayload->nObjects)
|
||||||
|
{ /* clamp current pointer and return FALSE */
|
||||||
|
peg->nCurrent = peg->pPayload->nObjects;
|
||||||
|
rc = S_FALSE;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT enumGeneric_Reset(IEnumUnknown *pThis)
|
||||||
|
{
|
||||||
|
((PENUMGENERIC)pThis)->nCurrent = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT enumGeneric_Clone(IEnumUnknown *pThis, IEnumUnknown **ppEnum)
|
||||||
|
{
|
||||||
|
register PENUMGENERIC peg = (PENUMGENERIC)pThis; /* pointer to data block */
|
||||||
|
register PENUMGENERIC pegNew; /* pointer to new enumerator */
|
||||||
|
|
||||||
|
if (!ppEnum) /* no pointer? */
|
||||||
|
return E_INVALIDARG;
|
||||||
|
*ppEnum = NULL;
|
||||||
|
pegNew = _ObjHlpAllocateEnumGeneric(peg->pAllocator, peg->riidActual, peg->pPayload, peg->nCurrent);
|
||||||
|
if (!pegNew) /* failed to allocate? */
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
IUnknown_QueryInterface((IUnknown *)pegNew, peg->riidActual, (PPVOID)ppEnum);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SEG_RODATA struct IEnumUnknownVTable vtblEnum =
|
||||||
|
{
|
||||||
|
.QueryInterface = enumGeneric_QueryInterface,
|
||||||
|
.AddRef = enumGeneric_AddRef,
|
||||||
|
.Release = enumGeneric_Release,
|
||||||
|
.Next = enumGeneric_Next,
|
||||||
|
.Skip = enumGeneric_Skip,
|
||||||
|
.Reset = enumGeneric_Reset,
|
||||||
|
.Clone = enumGeneric_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
/*---------------------------------
|
||||||
|
* IEnum[Generic] helper functions
|
||||||
|
*---------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
PENUMGENERICDATA _ObjHlpAllocateEnumGenericData(IMalloc *pAllocator, UINT32 nCapacity)
|
||||||
|
{
|
||||||
|
register PENUMGENERICDATA rc; /* return from this function */
|
||||||
|
register SIZE_T cbReturn = sizeof(ENUMGENERICDATA) + (nCapacity * sizeof(PUNKNOWN)); /* bytes to allocate */
|
||||||
|
|
||||||
|
rc = (PENUMGENERICDATA)(IMalloc_Alloc(pAllocator, cbReturn));
|
||||||
|
if (rc != NULL)
|
||||||
|
{
|
||||||
|
StrSetMem(rc, 0, cbReturn);
|
||||||
|
rc->uiRefCount = 0;
|
||||||
|
rc->nObjects = 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ObjHlpAddToEnumGenericData(PENUMGENERICDATA pegd, IUnknown *pUnk)
|
||||||
|
{
|
||||||
|
pegd->rgObjects[pegd->nObjects] = pUnk;
|
||||||
|
IUnknown_AddRef(pegd->rgObjects[pegd->nObjects]);
|
||||||
|
pegd->nObjects++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ObjHlpDiscardEnumGenericData(PENUMGENERICDATA pegd)
|
||||||
|
{
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
for (i = 0; i < pegd->nObjects; i++)
|
||||||
|
IUnknown_Release(pegd->rgObjects[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PENUMGENERIC _ObjHlpAllocateEnumGeneric(IMalloc *pAllocator, REFIID riidActual, PENUMGENERICDATA pegd,
|
||||||
|
UINT32 nCurrent)
|
||||||
|
{
|
||||||
|
register PENUMGENERIC rc; /* return from this function */
|
||||||
|
|
||||||
|
rc = (PENUMGENERIC)(IMalloc_Alloc(pAllocator, sizeof(ENUMGENERIC)));
|
||||||
|
if (rc)
|
||||||
|
{ /* initialize all the fields */
|
||||||
|
rc->enumUnknown.pVTable = &vtblEnum;
|
||||||
|
rc->uiRefCount = 0;
|
||||||
|
rc->riidActual = riidActual;
|
||||||
|
rc->nCurrent = nCurrent;
|
||||||
|
rc->pPayload = pegd;
|
||||||
|
pegd->uiRefCount++;
|
||||||
|
rc->pAllocator = pAllocator;
|
||||||
|
IUnknown_AddRef(rc->pAllocator);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
|
@ -34,22 +34,54 @@
|
||||||
#include <comrogue/str.h>
|
#include <comrogue/str.h>
|
||||||
#include <comrogue/connpoint.h>
|
#include <comrogue/connpoint.h>
|
||||||
#include <comrogue/objhelp.h>
|
#include <comrogue/objhelp.h>
|
||||||
|
#include "enumconn.h"
|
||||||
|
|
||||||
|
/* Mask we XOR with the index of the slot plus 1. */
|
||||||
|
#define FIXEDCP_MASK 0x4669782A /* "Fix*" */
|
||||||
|
|
||||||
/*---------------------------------------------
|
/*---------------------------------------------
|
||||||
* IConnectionPoint vtable and implementations
|
* IConnectionPoint vtable and implementations
|
||||||
*---------------------------------------------
|
*---------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a reference to the connection point object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The new reference count on the object.
|
||||||
|
*/
|
||||||
static UINT32 fixedcp_AddRef(IUnknown *pThis)
|
static UINT32 fixedcp_AddRef(IUnknown *pThis)
|
||||||
{
|
{
|
||||||
return IUnknown_AddRef(((PFIXEDCPDATA)pThis)->punkOuter);
|
return IUnknown_AddRef(((PFIXEDCPDATA)pThis)->punkOuter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes a reference from the connection point object. The object is freed when its reference count reaches 0.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The new reference count on the object.
|
||||||
|
*/
|
||||||
static UINT32 fixedcp_Release(IUnknown *pThis)
|
static UINT32 fixedcp_Release(IUnknown *pThis)
|
||||||
{
|
{
|
||||||
return IUnknown_Release(((PFIXEDCPDATA)pThis)->punkOuter);
|
return IUnknown_Release(((PFIXEDCPDATA)pThis)->punkOuter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieves the IID of the outgoing interface managed by this connection point.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
* - pIID = Pointer to buffer to receive the IID of the outgoing interface managed by this connection point.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Standard HRESULT success/failure indicator.
|
||||||
|
*/
|
||||||
static HRESULT fixedcp_GetConnectionInterface(IConnectionPoint *pThis, IID *pIID)
|
static HRESULT fixedcp_GetConnectionInterface(IConnectionPoint *pThis, IID *pIID)
|
||||||
{
|
{
|
||||||
if (!pIID)
|
if (!pIID)
|
||||||
|
@ -58,7 +90,18 @@ static HRESULT fixedcp_GetConnectionInterface(IConnectionPoint *pThis, IID *pIID
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT fixedcp_GetConnectionPointContainer(IConnectionPoint *pThis, IConnectionPointContainer *ppCPC)
|
/*
|
||||||
|
* Retrieves the IConnectionPointContainer interface for this connection point's parent connectable object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
* - ppCPC = Pointer to variable to receive the IConnectionPointContainer interface. The caller is responsible
|
||||||
|
* for releasing this interface pointer.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Standard HRESULT success/failure indicator.
|
||||||
|
*/
|
||||||
|
static HRESULT fixedcp_GetConnectionPointContainer(IConnectionPoint *pThis, IConnectionPointContainer **ppCPC)
|
||||||
{
|
{
|
||||||
register HRESULT rc; /* return from underlying QI */
|
register HRESULT rc; /* return from underlying QI */
|
||||||
|
|
||||||
|
@ -68,19 +111,132 @@ static HRESULT fixedcp_GetConnectionPointContainer(IConnectionPoint *pThis, ICon
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Establishes a connection between the connection point and an event sink interface.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
* - punkSink = Pointer to the event sink interface to attach.
|
||||||
|
* - puiCookie = Pointer to a variable to receive a "cookie" that can later be used with the Unadvise method
|
||||||
|
* on this interface to delete the connection.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - S_OK = Connection established; *puiCookie contains the connection cookie.
|
||||||
|
* - E_POINTER = Either punkSink or puiCookie is invalid.
|
||||||
|
* - CONNECT_E_ADVISELIMIT = The connection point cannot accept any more connections.
|
||||||
|
* - CONNECT_E_CANNOTCONNECT = The event sink does not support the correct interface.
|
||||||
|
*/
|
||||||
static HRESULT fixedcp_Advise(IConnectionPoint *pThis, IUnknown *punkSink, UINT32 *puiCookie)
|
static HRESULT fixedcp_Advise(IConnectionPoint *pThis, IUnknown *punkSink, UINT32 *puiCookie)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL; /* TODO */
|
register PFIXEDCPDATA pData; /* pointer to actual data block */
|
||||||
|
register UINT32 i; /* index of slot to put sink in */
|
||||||
|
IUnknown *punkActualSink = NULL; /* actual sink pointer */
|
||||||
|
|
||||||
|
if (!punkSink || !puiCookie)
|
||||||
|
return E_POINTER; /* bogus */
|
||||||
|
*puiCookie = 0;
|
||||||
|
|
||||||
|
pData = (PFIXEDCPDATA)pThis;
|
||||||
|
if (pData->ncpSize == pData->ncpCapacity)
|
||||||
|
return CONNECT_E_ADVISELIMIT; /* too many connections */
|
||||||
|
|
||||||
|
if (FAILED(IUnknown_QueryInterface(punkSink, pData->riidConnection, (PPVOID)(&punkActualSink))))
|
||||||
|
return CONNECT_E_CANNOTCONNECT; /* cannot QI for our interface */
|
||||||
|
|
||||||
|
for (i = 0; i < pData->ncpCapacity; i++)
|
||||||
|
{ /* search for a slot */
|
||||||
|
if (!(pData->ppSlots[i]))
|
||||||
|
{ /* found slot, store sink */
|
||||||
|
pData->ppSlots[i] = punkActualSink;
|
||||||
|
*puiCookie = (UINT32)((i + 1) ^ FIXEDCP_MASK);
|
||||||
|
pData->ncpSize++;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* slot not found?!? */
|
||||||
|
IUnknown_Release(punkActualSink);
|
||||||
|
return E_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terminates a previously-established connection between the connection point and an event sink interface.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
* - uiCookie = Cookie previously returned by the Advise method on this interface.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - S_OK = Connection was terminated successfully.
|
||||||
|
* - E_POINTER = The cookie value is invalid.
|
||||||
|
*/
|
||||||
static HRESULT fixedcp_Unadvise(IConnectionPoint *pThis, UINT32 uiCookie)
|
static HRESULT fixedcp_Unadvise(IConnectionPoint *pThis, UINT32 uiCookie)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL; /* TODO */
|
register PFIXEDCPDATA pData = (PFIXEDCPDATA)pThis; /* pointer to actual data block */
|
||||||
|
register UINT32 i; /* index of slot sink is in */
|
||||||
|
|
||||||
|
/* Decode the cookie value */
|
||||||
|
i = (UINT32)(uiCookie ^ FIXEDCP_MASK) - 1;
|
||||||
|
if ((i < 0) || (i >= pData->ncpCapacity) || !(pData->ppSlots[i]))
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
/* Free up the slot */
|
||||||
|
IUnknown_Release(pData->ppSlots[i]);
|
||||||
|
pData->ppSlots[i] = NULL;
|
||||||
|
pData->ncpSize--;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates an enumerator object to iterate through the current connections on this connection point.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Pointer to the connection point object (actually its IConnectionPoint interface pointer).
|
||||||
|
* - ppEnum = Pointer to variable to receive the enumerator object interface. The caller is responsible for
|
||||||
|
* releasing this object when it's no longer needed.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - S_OK = Created the enumerator successfully.
|
||||||
|
* - E_NOTIMPL = Enumeration is not supported.
|
||||||
|
* - E_POINTER = ppEnum was not a valid pointer.
|
||||||
|
* - E_OUTOFMEMORY = Could not allocate the enumerator.
|
||||||
|
*/
|
||||||
static HRESULT fixedcp_EnumConnections(IConnectionPoint *pThis, IEnumConnections **ppEnum)
|
static HRESULT fixedcp_EnumConnections(IConnectionPoint *pThis, IEnumConnections **ppEnum)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL; /* TODO */
|
register PFIXEDCPDATA pData = (PFIXEDCPDATA)pThis; /* pointer to actual data block */
|
||||||
|
PENUMCONNDATA pecd; /* pointer to enumeration data */
|
||||||
|
PENUMCONN pec; /* pointer to enumerator */
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
if (!(pData->pAllocator))
|
||||||
|
return E_NOTIMPL; /* enumeration not implemented */
|
||||||
|
|
||||||
|
if (!ppEnum)
|
||||||
|
return E_POINTER; /* bad return pointer */
|
||||||
|
*ppEnum = NULL;
|
||||||
|
|
||||||
|
/* Allocate a data block. */
|
||||||
|
pecd = _ObjHlpAllocateEnumConnData(pData->pAllocator, pData->ncpSize);
|
||||||
|
if (!pecd)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
/* Fill the allocated data block. */
|
||||||
|
for (i = 0; i < pData->ncpCapacity; i++)
|
||||||
|
if (pData->ppSlots[i])
|
||||||
|
_ObjHlpAddToEnumConnData(pecd, pData->ppSlots[i], (UINT32)((i + 1) ^ FIXEDCP_MASK));
|
||||||
|
|
||||||
|
/* Allocate the enumerator. */
|
||||||
|
pec = _ObjHlpAllocateEnumConn(pData->pAllocator, pecd, 0);
|
||||||
|
if (pec)
|
||||||
|
{ /* QI it for our return value */
|
||||||
|
IUnknown_QueryInterface((IUnknown *)pec, &IID_IEnumConnections, (PPVOID)ppEnum);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unable to allocate enumerator - bug out */
|
||||||
|
_ObjHlpDiscardEnumConnData(pecd);
|
||||||
|
IMalloc_Free(pData->pAllocator, pecd);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VTable for the fixed-size connection point implementation. */
|
/* VTable for the fixed-size connection point implementation. */
|
||||||
|
@ -101,8 +257,23 @@ static const SEG_RODATA struct IConnectionPointVTable vtblFixedCP =
|
||||||
*-----------------------------------------------
|
*-----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets up a fixed-size connection point object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pData = Pointer to the data block to initialize.
|
||||||
|
* - punkOuter = Pointer to "outer unknown" for the connection point, which must implement IConnectionPointContainer.
|
||||||
|
* - riidConnection = Reference to the IID of the outgoing event interface.
|
||||||
|
* - ppSlots = Pointer to the array of IUnknown "slots" used by this connection point.
|
||||||
|
* - nSlots = Number of slots to allocate.
|
||||||
|
* - pAllocator = Pointer to a memory allocator to use to allocate enumerators. This may be NULL if you don't
|
||||||
|
* want to support enumeration.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection,
|
void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection,
|
||||||
IUnknown **ppSlots, INT32 nSlots)
|
IUnknown **ppSlots, UINT32 nSlots, IMalloc *pAllocator)
|
||||||
{
|
{
|
||||||
pData->connectionPointInterface.pVTable = &vtblFixedCP;
|
pData->connectionPointInterface.pVTable = &vtblFixedCP;
|
||||||
pData->punkOuter = punkOuter;
|
pData->punkOuter = punkOuter;
|
||||||
|
@ -110,15 +281,29 @@ void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConne
|
||||||
pData->ppSlots = ppSlots;
|
pData->ppSlots = ppSlots;
|
||||||
pData->ncpSize = 0;
|
pData->ncpSize = 0;
|
||||||
pData->ncpCapacity = nSlots;
|
pData->ncpCapacity = nSlots;
|
||||||
|
pData->pAllocator = pAllocator;
|
||||||
|
if (pData->pAllocator)
|
||||||
|
IUnknown_AddRef(pData->pAllocator);
|
||||||
StrSetMem(ppSlots, 0, nSlots * sizeof(IUnknown *));
|
StrSetMem(ppSlots, 0, nSlots * sizeof(IUnknown *));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tears down a fixed-size connection-point object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pData = Pointer to the data block to destroy.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData)
|
void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData)
|
||||||
{
|
{
|
||||||
register INT32 i; /* loop counter */
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
for (i = 0; i < pData->ncpCapacity; i++)
|
for (i = 0; i < pData->ncpCapacity; i++)
|
||||||
if (pData->ppSlots[i])
|
if (pData->ppSlots[i])
|
||||||
IUnknown_Release(pData->ppSlots[i]);
|
IUnknown_Release(pData->ppSlots[i]);
|
||||||
|
if (pData->pAllocator)
|
||||||
|
IUnknown_Release(pData->pAllocator);
|
||||||
StrSetMem(pData, 0, sizeof(FIXEDCPDATA));
|
StrSetMem(pData, 0, sizeof(FIXEDCPDATA));
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ INT32 RbtStdCompareByValue(TREEKEY k1, TREEKEY k2)
|
||||||
static PRBTREENODE rotate_left(PRBTREENODE ptn)
|
static PRBTREENODE rotate_left(PRBTREENODE ptn)
|
||||||
{
|
{
|
||||||
register PRBTREENODE ptnNewRoot = rbtNodeRight(ptn);
|
register PRBTREENODE ptnNewRoot = rbtNodeRight(ptn);
|
||||||
ASSERT(ptnNewRoot);
|
//ASSERT(ptnNewRoot);
|
||||||
rbtSetNodeRight(ptn, ptnNewRoot->ptnLeft);
|
rbtSetNodeRight(ptn, ptnNewRoot->ptnLeft);
|
||||||
ptnNewRoot->ptnLeft = ptn;
|
ptnNewRoot->ptnLeft = ptn;
|
||||||
rbtSetNodeColor(ptnNewRoot, rbtNodeColor(ptn));
|
rbtSetNodeColor(ptnNewRoot, rbtNodeColor(ptn));
|
||||||
|
@ -103,7 +103,7 @@ static PRBTREENODE rotate_left(PRBTREENODE ptn)
|
||||||
static PRBTREENODE rotate_right(PRBTREENODE ptn)
|
static PRBTREENODE rotate_right(PRBTREENODE ptn)
|
||||||
{
|
{
|
||||||
register PRBTREENODE ptnNewRoot = ptn->ptnLeft;
|
register PRBTREENODE ptnNewRoot = ptn->ptnLeft;
|
||||||
ASSERT(ptnNewRoot);
|
//ASSERT(ptnNewRoot);
|
||||||
ptn->ptnLeft = rbtNodeRight(ptnNewRoot);
|
ptn->ptnLeft = rbtNodeRight(ptnNewRoot);
|
||||||
rbtSetNodeRight(ptnNewRoot, ptn);
|
rbtSetNodeRight(ptnNewRoot, ptn);
|
||||||
rbtSetNodeColor(ptnNewRoot, rbtNodeColor(ptn));
|
rbtSetNodeColor(ptnNewRoot, rbtNodeColor(ptn));
|
||||||
|
@ -172,7 +172,7 @@ static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENO
|
||||||
if (!ptnCurrent)
|
if (!ptnCurrent)
|
||||||
return ptnNew; /* degenerate case */
|
return ptnNew; /* degenerate case */
|
||||||
cmp = (*(ptree->pfnTreeCompare))(ptnNew->treekey, ptnCurrent->treekey);
|
cmp = (*(ptree->pfnTreeCompare))(ptnNew->treekey, ptnCurrent->treekey);
|
||||||
ASSERT(cmp != 0);
|
//ASSERT(cmp != 0);
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew);
|
ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue
Block a user