crypt32/tests: Use the available ARRAY_SIZE() macro.
[wine.git] / dlls / vbscript / utils.c
blobd30842c52eb55608a7b829f0ec4b2bfa6db14e27
1 /*
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
19 #include "vbscript.h"
21 #include "wine/debug.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
25 typedef struct {
26 IEnumVARIANT IEnumVARIANT_iface;
28 LONG ref;
30 SAFEARRAY *sa;
31 ULONG i, size;
32 } safearray_iter;
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;
50 }else {
51 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
52 *ppv = NULL;
53 return E_NOINTERFACE;
56 IUnknown_AddRef((IUnknown*)*ppv);
57 return S_OK;
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);
67 return 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);
77 if(!ref) {
78 if(This->sa)
79 SafeArrayUnlock(This->sa);
80 heap_free(This);
83 return ref;
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);
90 HRESULT hres;
91 VARIANT *v;
93 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
95 if(celt != 1) {
96 FIXME("celt != 1\n");
97 return E_NOTIMPL;
100 if(This->i >= This->size) {
101 if(pCeltFetched)
102 *pCeltFetched = 0;
103 return S_FALSE;
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);
112 if(FAILED(hres))
113 return hres;
115 This->i++;
116 if(pCeltFetched)
117 *pCeltFetched = 1;
118 return S_OK;
121 static HRESULT WINAPI safearray_iter_IEnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
123 FIXME("\n");
124 return E_NOTIMPL;
127 static HRESULT WINAPI safearray_iter_IEnumVARIANT_Reset(IEnumVARIANT *iface)
129 FIXME("\n");
130 return E_NOTIMPL;
133 static HRESULT WINAPI safearray_iter_IEnumVARIANT_Clone(
134 IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
136 FIXME("\n");
137 return E_NOTIMPL;
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)
152 ULONG ret = 1;
153 USHORT i;
155 if(!sa)
156 return 0;
158 for(i=0; i<sa->cDims && ret; i++)
159 ret *= sa->rgsabound[i].cElements;
160 return ret;
163 HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
165 safearray_iter *iter;
166 HRESULT hres;
168 if(sa && !(sa->fFeatures & FADF_VARIANT)) {
169 FIXME("enumeration not supported: %x\n", sa->fFeatures);
170 return E_NOTIMPL;
173 iter = heap_alloc(sizeof(*iter));
174 if(!iter)
175 return E_OUTOFMEMORY;
177 if(sa) {
178 hres = SafeArrayLock(sa);
179 if(FAILED(hres)) {
180 heap_free(iter);
181 return hres;
185 iter->IEnumVARIANT_iface.lpVtbl = &safearray_iter_EnumVARIANTVtbl;
186 iter->ref = 1;
187 iter->sa = sa;
188 iter->i = 0;
189 iter->size = get_safearray_size(sa);
191 *ev = &iter->IEnumVARIANT_iface;
192 return S_OK;