ole32/composite: Cleanup enumerator methods.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-09-30 11:26:48 +03:00 committed by Alexandre Julliard
parent b557c39555
commit 966d74a1b4
1 changed files with 52 additions and 85 deletions

View File

@ -72,13 +72,13 @@ static inline CompositeMonikerImpl *impl_from_IMarshal(IMarshal *iface)
return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMarshal_iface); return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMarshal_iface);
} }
/* EnumMoniker data structure */ typedef struct EnumMonikerImpl
typedef struct EnumMonikerImpl{ {
IEnumMoniker IEnumMoniker_iface; IEnumMoniker IEnumMoniker_iface;
LONG ref; LONG ref;
IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */ IMoniker **monikers;
ULONG tabSize; /* size of tabMoniker */ unsigned int count;
ULONG currentPos; /* index pointer on the current moniker */ unsigned int pos;
} EnumMonikerImpl; } EnumMonikerImpl;
static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface) static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
@ -86,7 +86,7 @@ static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface); return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
} }
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk); static HRESULT create_enumerator(IMoniker **components, unsigned int count, BOOL forward, IEnumMoniker **ret);
static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost); static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost);
static HRESULT composite_get_leftmost(CompositeMonikerImpl *composite, IMoniker **leftmost); static HRESULT composite_get_leftmost(CompositeMonikerImpl *composite, IMoniker **leftmost);
@ -492,21 +492,21 @@ static HRESULT composite_get_components_alloc(IMoniker *iface, unsigned int *cou
return S_OK; return S_OK;
} }
static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ppenumMoniker) static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ret_enum)
{ {
IMoniker **monikers; IMoniker **monikers;
unsigned int count; unsigned int count;
HRESULT hr; HRESULT hr;
TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker); TRACE("%p, %d, %p\n", iface, forward, ret_enum);
if (!ppenumMoniker) if (!ret_enum)
return E_INVALIDARG; return E_INVALIDARG;
if (FAILED(hr = composite_get_components_alloc(iface, &count, &monikers))) if (FAILED(hr = composite_get_components_alloc(iface, &count, &monikers)))
return hr; return hr;
hr = EnumMonikerImpl_CreateEnumMoniker(monikers, count, 0, forward, ppenumMoniker); hr = create_enumerator(monikers, count, forward, ret_enum);
heap_free(monikers); heap_free(monikers);
return hr; return hr;
@ -1280,36 +1280,30 @@ EnumMonikerImpl_AddRef(IEnumMoniker* iface)
} }
/****************************************************************************** static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker *iface)
* EnumMonikerImpl_Release
******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker* iface)
{ {
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
ULONG i; ULONG refcount = InterlockedDecrement(&e->ref);
ULONG ref; unsigned int i;
TRACE("(%p)\n",This);
ref = InterlockedDecrement(&This->ref); TRACE("%p, refcount %d.\n", iface, refcount);
/* destroy the object if there are no more references to it */ if (!refcount)
if (ref == 0) { {
for (i = 0; i < e->count; ++i)
for(i=0;i<This->tabSize;i++) IMoniker_Release(e->monikers[i]);
IMoniker_Release(This->tabMoniker[i]); heap_free(e->monikers);
heap_free(e);
HeapFree(GetProcessHeap(),0,This->tabMoniker);
HeapFree(GetProcessHeap(),0,This);
} }
return ref;
return refcount;
} }
static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count, static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count,
IMoniker **m, ULONG *fetched) IMoniker **m, ULONG *fetched)
{ {
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
ULONG i; unsigned int i;
TRACE("%p, %u, %p, %p.\n", iface, count, m, fetched); TRACE("%p, %u, %p, %p.\n", iface, count, m, fetched);
@ -1319,9 +1313,9 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count,
*m = NULL; *m = NULL;
/* retrieve the requested number of moniker from the current position */ /* retrieve the requested number of moniker from the current position */
for(i=0;((This->currentPos < This->tabSize) && (i < count));i++) for (i = 0; (e->pos < e->count) && (i < count); ++i)
{ {
m[i] = This->tabMoniker[This->currentPos++]; m[i] = e->monikers[e->pos++];
IMoniker_AddRef(m[i]); IMoniker_AddRef(m[i]);
} }
@ -1333,30 +1327,28 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count,
static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG count) static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG count)
{ {
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
TRACE("%p, %u.\n", iface, count); TRACE("%p, %u.\n", iface, count);
if (!count) if (!count)
return S_OK; return S_OK;
if ((This->currentPos + count) >= This->tabSize) if ((e->pos + count) >= e->count)
return S_FALSE; return S_FALSE;
This->currentPos += count; e->pos += count;
return S_OK; return S_OK;
} }
/****************************************************************************** static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface)
* EnumMonikerImpl_Reset
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker* iface)
{ {
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
This->currentPos=0; TRACE("%p.\n", iface);
e->pos = 0;
return S_OK; return S_OK;
} }
@ -1384,60 +1376,35 @@ static const IEnumMonikerVtbl VT_EnumMonikerImpl =
EnumMonikerImpl_Clone EnumMonikerImpl_Clone
}; };
/****************************************************************************** static HRESULT create_enumerator(IMoniker **components, unsigned int count, BOOL forward, IEnumMoniker **ret)
* EnumMonikerImpl_CreateEnumMoniker
******************************************************************************/
static HRESULT
EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
ULONG currentPos, BOOL leftToRight, IEnumMoniker ** ppmk)
{ {
EnumMonikerImpl* newEnumMoniker; EnumMonikerImpl *object;
ULONG i; unsigned int i;
if (currentPos > tabSize) if (!(object = heap_alloc_zero(sizeof(*object))))
return E_INVALIDARG; return E_OUTOFMEMORY;
newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl)); object->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl;
object->ref = 1;
object->count = count;
if (newEnumMoniker == 0) if (!(object->monikers = heap_calloc(count, sizeof(*object->monikers))))
return STG_E_INSUFFICIENTMEMORY; {
heap_free(object);
/* Initialize the virtual function table. */
newEnumMoniker->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl;
newEnumMoniker->ref = 1;
newEnumMoniker->tabSize=tabSize;
newEnumMoniker->currentPos=currentPos;
newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(newEnumMoniker->tabMoniker[0]));
if (newEnumMoniker->tabMoniker==NULL) {
HeapFree(GetProcessHeap(), 0, newEnumMoniker);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (leftToRight) for (i = 0; i < count; ++i)
for (i=0;i<tabSize;i++){ {
object->monikers[i] = forward ? components[i] : components[count - i - 1];
IMoniker_AddRef(object->monikers[i]);
}
newEnumMoniker->tabMoniker[i]=tabMoniker[i]; *ret = &object->IEnumMoniker_iface;
IMoniker_AddRef(tabMoniker[i]);
}
else
for (i = tabSize; i > 0; i--){
newEnumMoniker->tabMoniker[tabSize-i]=tabMoniker[i - 1];
IMoniker_AddRef(tabMoniker[i - 1]);
}
*ppmk=&newEnumMoniker->IEnumMoniker_iface;
return S_OK; return S_OK;
} }
/********************************************************************************/
/* Virtual function table for the CompositeMonikerImpl class which includes */
/* IPersist, IPersistStream and IMoniker functions. */
static const IMonikerVtbl VT_CompositeMonikerImpl = static const IMonikerVtbl VT_CompositeMonikerImpl =
{ {
CompositeMonikerImpl_QueryInterface, CompositeMonikerImpl_QueryInterface,