ole32: Add a framework for implementing IEnum* interfaces.

This commit is contained in:
Mike McCormack 2006-07-11 16:12:38 +09:00 committed by Alexandre Julliard
parent 918cf3261b
commit 127ae2bf8b
3 changed files with 237 additions and 0 deletions

View File

@ -18,6 +18,7 @@ C_SRCS = \
datacache.c \ datacache.c \
defaulthandler.c \ defaulthandler.c \
dictionary.c \ dictionary.c \
enumx.c \
errorinfo.c \ errorinfo.c \
filemoniker.c \ filemoniker.c \
ftmarshal.c \ ftmarshal.c \

202
dlls/ole32/enumx.c Normal file
View File

@ -0,0 +1,202 @@
/*
* IEnum* implementation
*
* Copyright 2006 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef struct tagEnumSTATPROPSETSTG_impl
{
const void *vtbl;
LONG ref;
struct list elements;
struct list *current;
ULONG elem_size;
GUID riid;
} enumx_impl;
/************************************************************************
* enumx_QueryInterface
*/
HRESULT WINAPI enumx_QueryInterface(
enumx_impl *This,
REFIID riid,
void** ppvObject)
{
if ( (This==0) || (ppvObject==0) )
return E_INVALIDARG;
*ppvObject = 0;
if (IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&This->riid, riid))
{
IUnknown_AddRef(((IUnknown*)This));
*ppvObject = This;
return S_OK;
}
return E_NOINTERFACE;
}
/************************************************************************
* enumx_AddRef
*/
ULONG WINAPI enumx_AddRef(enumx_impl *This)
{
return InterlockedIncrement(&This->ref);
}
/************************************************************************
* enumx_Release
*/
ULONG WINAPI enumx_Release(enumx_impl *This)
{
ULONG ref;
ref = InterlockedDecrement(&This->ref);
if (ref == 0)
{
while (!list_empty(&This->elements))
{
struct list *x = list_head(&This->elements);
list_remove(x);
HeapFree(GetProcessHeap(), 0, x);
}
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/************************************************************************
* enumx_Next
*/
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
void *rgelt, ULONG *pceltFetched)
{
unsigned char *p;
ULONG count = 0;
TRACE("%p %lu %p\n", This, celt, pceltFetched);
if (This->current == NULL)
This->current = list_head(&This->elements);
p = rgelt;
while (count < celt && This->current && This->current != &This->elements)
{
memcpy(p, &This->current[1], This->elem_size);
p += This->elem_size;
This->current = This->current->next;
count++;
}
if (pceltFetched)
*pceltFetched = count;
if (count < celt)
return S_FALSE;
return S_OK;
}
/************************************************************************
* enumx_Skip
*/
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
{
ULONG count = 0;
TRACE("%p %lu\n", This, celt);
if (This->current == NULL)
This->current = list_head(&This->elements);
while (count < celt && This->current && This->current != &This->elements)
count++;
return S_OK;
}
/************************************************************************
* enumx_Reset
*/
HRESULT WINAPI enumx_Reset(enumx_impl *This)
{
TRACE("\n");
This->current = NULL;
return S_OK;
}
/************************************************************************
* enumx_fnClone
*/
HRESULT WINAPI enumx_Clone(
enumx_impl *iface,
enumx_impl **ppenum)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* enumx_allocate
*
* Allocate a generic enumerator
*/
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
{
enumx_impl *enumx;
enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
if (enumx)
{
enumx->vtbl = vtbl;
enumx->ref = 1;
enumx->current = NULL;
enumx->elem_size = elem_size;
memcpy(&enumx->riid, riid, sizeof *riid);
list_init(&enumx->elements);
}
return enumx;
}
/************************************************************************
* enumx_add_element
*
* Add an element to the enumeration.
*/
void *enumx_add_element(enumx_impl *enumx, void *data)
{
struct list *element;
element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
if (!element)
return NULL;
memcpy(&element[1], data, enumx->elem_size);
list_add_tail(&enumx->elements, element);
return &element[1];
}

34
dlls/ole32/enumx.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright 2006 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __OLE_ENUM_H__
#define __OLE_ENUM_H__
typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl;
extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**);
extern ULONG WINAPI enumx_AddRef(enumx_impl *);
extern ULONG WINAPI enumx_Release(enumx_impl *);
extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *);
extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG);
extern HRESULT WINAPI enumx_Reset(enumx_impl *);
extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **);
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG);
extern void *enumx_add_element(enumx_impl *, void *);
#endif