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
;
35 static inline safearray_iter
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
37 return CONTAINING_RECORD(iface
, safearray_iter
, IEnumVARIANT_iface
);
40 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_QueryInterface(
41 IEnumVARIANT
*iface
, REFIID riid
, void **ppv
)
43 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
45 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
46 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
47 *ppv
= &This
->IEnumVARIANT_iface
;
48 }else if(IsEqualGUID(riid
, &IID_IEnumVARIANT
)) {
49 TRACE("(%p)->(IID_IEnumVARIANT %p)\n", This
, ppv
);
50 *ppv
= &This
->IEnumVARIANT_iface
;
52 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
57 IUnknown_AddRef((IUnknown
*)*ppv
);
61 static ULONG WINAPI
safearray_iter_IEnumVARIANT_AddRef(IEnumVARIANT
*iface
)
63 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
64 LONG ref
= InterlockedIncrement(&This
->ref
);
66 TRACE("(%p) ref=%ld\n", This
, ref
);
71 static ULONG WINAPI
safearray_iter_IEnumVARIANT_Release(IEnumVARIANT
*iface
)
73 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
74 LONG ref
= InterlockedDecrement(&This
->ref
);
76 TRACE("(%p) ref=%ld\n", iface
, ref
);
80 SafeArrayUnlock(This
->sa
);
82 SafeArrayDestroy(This
->sa
);
90 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Next(IEnumVARIANT
*iface
,
91 ULONG celt
, VARIANT
*rgVar
, ULONG
*pCeltFetched
)
93 safearray_iter
*This
= impl_from_IEnumVARIANT(iface
);
97 TRACE("(%p)->(%lu %p %p)\n", This
, celt
, rgVar
, pCeltFetched
);
100 FIXME("celt != 1\n");
104 if(This
->i
>= This
->size
) {
110 if(!This
->sa
->cLocks
)
111 ERR("SAFEARRAY not locked\n");
113 v
= (VARIANT
*)(((BYTE
*)This
->sa
->pvData
) + This
->i
* This
->sa
->cbElements
);
114 V_VT(rgVar
) = VT_EMPTY
;
115 hres
= VariantCopy(rgVar
, v
);
125 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Skip(IEnumVARIANT
*iface
, ULONG celt
)
131 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Reset(IEnumVARIANT
*iface
)
137 static HRESULT WINAPI
safearray_iter_IEnumVARIANT_Clone(
138 IEnumVARIANT
*iface
, IEnumVARIANT
**ppEnum
)
144 static const IEnumVARIANTVtbl safearray_iter_EnumVARIANTVtbl
= {
145 safearray_iter_IEnumVARIANT_QueryInterface
,
146 safearray_iter_IEnumVARIANT_AddRef
,
147 safearray_iter_IEnumVARIANT_Release
,
148 safearray_iter_IEnumVARIANT_Next
,
149 safearray_iter_IEnumVARIANT_Skip
,
150 safearray_iter_IEnumVARIANT_Reset
,
151 safearray_iter_IEnumVARIANT_Clone
154 static ULONG
get_safearray_size(SAFEARRAY
*sa
)
162 for(i
=0; i
<sa
->cDims
&& ret
; i
++)
163 ret
*= sa
->rgsabound
[i
].cElements
;
167 HRESULT
create_safearray_iter(SAFEARRAY
*sa
, BOOL owned
, IEnumVARIANT
**ev
)
169 safearray_iter
*iter
;
172 if(sa
&& !(sa
->fFeatures
& FADF_VARIANT
)) {
173 FIXME("enumeration not supported: %x\n", sa
->fFeatures
);
177 iter
= malloc(sizeof(*iter
));
179 return E_OUTOFMEMORY
;
182 hres
= SafeArrayLock(sa
);
189 iter
->IEnumVARIANT_iface
.lpVtbl
= &safearray_iter_EnumVARIANTVtbl
;
194 iter
->size
= get_safearray_size(sa
);
196 *ev
= &iter
->IEnumVARIANT_iface
;