Piotr Caban : vbscript: Added IMatchCollection2::_NewEnum implementation.

Alexandre Julliard julliard at winehq.org
Tue Feb 19 13:33:04 CST 2013


Module: wine
Branch: master
Commit: 56b2a7b1bd86211d5bad9bda8c238b0b7aa133d1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=56b2a7b1bd86211d5bad9bda8c238b0b7aa133d1

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Feb 19 12:42:27 2013 +0100

vbscript: Added IMatchCollection2::_NewEnum implementation.

---

 dlls/vbscript/vbregexp.c |  162 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/vbregexp.c b/dlls/vbscript/vbregexp.c
index 7e2a1cf..0aaa140 100644
--- a/dlls/vbscript/vbregexp.c
+++ b/dlls/vbscript/vbregexp.c
@@ -98,6 +98,16 @@ typedef struct Match2 {
     SubMatches *sub_matches;
 } Match2;
 
+typedef struct MatchCollectionEnum {
+    IEnumVARIANT IEnumVARIANT_iface;
+
+    LONG ref;
+
+    IMatchCollection2 *mc;
+    LONG pos;
+    LONG count;
+} MatchCollectionEnum;
+
 typedef struct MatchCollection2 {
     IMatchCollection2 IMatchCollection2_iface;
 
@@ -528,6 +538,149 @@ static HRESULT create_match2(DWORD pos, match_state_t **result, IMatch2 **match)
     return hres;
 }
 
+static inline MatchCollectionEnum* impl_from_IMatchCollectionEnum(IEnumVARIANT *iface)
+{
+    return CONTAINING_RECORD(iface, MatchCollectionEnum, IEnumVARIANT_iface);
+}
+
+static HRESULT WINAPI MatchCollectionEnum_QueryInterface(
+        IEnumVARIANT *iface, REFIID riid, void **ppv)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+
+    if(IsEqualGUID(riid, &IID_IUnknown)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IEnumVARIANT_iface;
+    }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) {
+        TRACE("(%p)->(IID_IEnumVARIANT %p)\n", This, ppv);
+        *ppv = &This->IEnumVARIANT_iface;
+    }else {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI MatchCollectionEnum_AddRef(IEnumVARIANT *iface)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI MatchCollectionEnum_Release(IEnumVARIANT *iface)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        IMatchCollection2_Release(This->mc);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI MatchCollectionEnum_Next(IEnumVARIANT *iface,
+        ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+    DWORD i;
+    HRESULT hres = S_OK;
+
+    TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
+
+    if(This->pos>=This->count) {
+        if(pCeltFetched)
+            *pCeltFetched = 0;
+        return S_FALSE;
+    }
+
+    for(i=0; i<celt && This->pos+i<This->count; i++) {
+        V_VT(rgVar+i) = VT_DISPATCH;
+        hres = IMatchCollection2_get_Item(This->mc, This->pos+i, &V_DISPATCH(rgVar+i));
+        if(FAILED(hres))
+            break;
+    }
+    if(FAILED(hres)) {
+        while(i--)
+            VariantClear(rgVar+i);
+        return hres;
+    }
+
+    if(pCeltFetched)
+        *pCeltFetched = i;
+    This->pos += i;
+    return S_OK;
+}
+
+static HRESULT WINAPI MatchCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+
+    TRACE("(%p)->(%u)\n", This, celt);
+
+    if(This->pos+celt <= This->count)
+        This->pos += celt;
+    else
+        This->pos = This->count;
+    return S_OK;
+}
+
+static HRESULT WINAPI MatchCollectionEnum_Reset(IEnumVARIANT *iface)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+
+    TRACE("(%p)\n", This);
+
+    This->pos = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI MatchCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
+{
+    MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
+    FIXME("(%p)->(%p)\n", This, ppEnum);
+    return E_NOTIMPL;
+}
+
+static const IEnumVARIANTVtbl MatchCollectionEnum_Vtbl = {
+    MatchCollectionEnum_QueryInterface,
+    MatchCollectionEnum_AddRef,
+    MatchCollectionEnum_Release,
+    MatchCollectionEnum_Next,
+    MatchCollectionEnum_Skip,
+    MatchCollectionEnum_Reset,
+    MatchCollectionEnum_Clone
+};
+
+static HRESULT create_enum_variant_mc2(IMatchCollection2 *mc, ULONG pos, IEnumVARIANT **enum_variant)
+{
+    MatchCollectionEnum *ret;
+
+    ret = heap_alloc_zero(sizeof(*ret));
+    if(!ret)
+        return E_OUTOFMEMORY;
+
+    ret->IEnumVARIANT_iface.lpVtbl = &MatchCollectionEnum_Vtbl;
+    ret->ref = 1;
+    ret->pos = pos;
+    IMatchCollection2_get_Count(mc, &ret->count);
+    ret->mc = mc;
+    IMatchCollection2_AddRef(mc);
+
+    *enum_variant = &ret->IEnumVARIANT_iface;
+    return S_OK;
+}
+
 static inline MatchCollection2* impl_from_IMatchCollection2(IMatchCollection2 *iface)
 {
     return CONTAINING_RECORD(iface, MatchCollection2, IMatchCollection2_iface);
@@ -667,8 +820,13 @@ static HRESULT WINAPI MatchCollection2_get_Count(IMatchCollection2 *iface, LONG
 static HRESULT WINAPI MatchCollection2_get__NewEnum(IMatchCollection2 *iface, IUnknown **ppEnum)
 {
     MatchCollection2 *This = impl_from_IMatchCollection2(iface);
-    FIXME("(%p)->(%p)\n", This, ppEnum);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p)\n", This, ppEnum);
+
+    if(!ppEnum)
+        return E_POINTER;
+
+    return create_enum_variant_mc2(&This->IMatchCollection2_iface, 0, (IEnumVARIANT**)ppEnum);
 }
 
 static const IMatchCollection2Vtbl MatchCollection2Vtbl = {




More information about the wine-cvs mailing list