2 * Copyright 2017 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/debug.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(vbscript
);
26 IEnumVARIANT IEnumVARIANT_iface
;
34 static inline safearray_iter
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
36 return CONTAINING_RECORD(iface
, safearray_iter
, IEnumVARIANT_iface
);
39 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_QueryInterface(
40 IEnumVARIANT
*iface
, REFIID riid
, void **ppv
)
42 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
44 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
45 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
46 *ppv
= &This
->IEnumVARIANT_iface
;
47 }else if(IsEqualGUID(riid
, &IID_IEnumVARIANT
)) {
48 TRACE("(%p)->(IID_IEnumVARIANT %p)\n", This
, ppv
);
49 *ppv
= &This
->IEnumVARIANT_iface
;
51 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
56 IUnknown_AddRef((IUnknown
*)*ppv
);
60 static ULONG WINAPI
safearray_iter_IEnumVARIANT_AddRef(IEnumVARIANT
*iface
)
62 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
63 LONG ref
= InterlockedIncrement(&This
->ref
);
65 TRACE("(%p) ref=%d\n", This
, ref
);
70 static ULONG WINAPI
safearray_iter_IEnumVARIANT_Release(IEnumVARIANT
*iface
)
72 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
73 LONG ref
= InterlockedDecrement(&This
->ref
);
75 TRACE("(%p) ref=%d\n", iface
, ref
);
79 SafeArrayUnlock(This
->sa
);
86 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Next(IEnumVARIANT
*iface
,
87 ULONG celt
, VARIANT
*rgVar
, ULONG
*pCeltFetched
)
89 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
93 TRACE("(%p)->(%u %p %p)\n", This
, celt
, rgVar
, pCeltFetched
);
100 if(This
->i
>= This
->size
) {
106 if(!This
->sa
->cLocks
)
107 ERR("SAFEARRAY not locked\n");
109 v
= (VARIANT
*)(((BYTE
*)This
->sa
->pvData
) + This
->i
* This
->sa
->cbElements
);
110 V_VT(rgVar
) = VT_EMPTY
;
111 hres
= VariantCopy(rgVar
, v
);
121 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Skip(IEnumVARIANT
*iface
, ULONG celt
)
127 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Reset(IEnumVARIANT
*iface
)
133 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Clone(
134 IEnumVARIANT
*iface
, IEnumVARIANT
**ppEnum
)
140 static const IEnumVARIANTVtbl safearray_iter_EnumVARIANTVtbl
= {
141 safearray_iter_IEnumVARIANT_QueryInterface
,
142 safearray_iter_IEnumVARIANT_AddRef
,
143 safearray_iter_IEnumVARIANT_Release
,
144 safearray_iter_IEnumVARIANT_Next
,
145 safearray_iter_IEnumVARIANT_Skip
,
146 safearray_iter_IEnumVARIANT_Reset
,
147 safearray_iter_IEnumVARIANT_Clone
150 static ULONG
get_safearray_size(SAFEARRAY
*sa
)
158 for(i
=0; i
<sa
->cDims
&& ret
; i
++)
159 ret
*= sa
->rgsabound
[i
].cElements
;
163 HRESULT
create_safearray_iter(SAFEARRAY
*sa
, IEnumVARIANT
**ev
)
165 safearray_iter
*iter
;
168 if(sa
&& !(sa
->fFeatures
& FADF_VARIANT
)) {
169 FIXME("enumeration not supported: %x\n", sa
->fFeatures
);
173 iter
= heap_alloc(sizeof(*iter
));
175 return E_OUTOFMEMORY
;
178 hres
= SafeArrayLock(sa
);
185 iter
->IEnumVARIANT_iface
.lpVtbl
= &safearray_iter_EnumVARIANTVtbl
;
189 iter
->size
= get_safearray_size(sa
);
191 *ev
= &iter
->IEnumVARIANT_iface
;