ReactOS 0.4.15-dev-7788-g1ad9096
enumerator.c
Go to the documentation of this file.
1/*
2 * Copyright 2019 Andreas Maier
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <assert.h>
20
21#include "jscript.h"
22
23#include "wine/debug.h"
24
26
27typedef struct {
29 /* IEnumVARIANT returned by _NewEnum */
31 /* current item */
35
36static const WCHAR atEndW[] = {'a','t','E','n','d',0};
37static const WCHAR itemW[] = {'i','t','e','m',0};
38static const WCHAR moveFirstW[] = {'m','o','v','e','F','i','r','s','t',0};
39static const WCHAR moveNextW[] = {'m','o','v','e','N','e','x','t',0};
40
42{
43 return CONTAINING_RECORD(jsdisp, EnumeratorInstance, dispex);
44}
45
47{
48 return enumerator_from_jsdisp(vdisp->u.jsdisp);
49}
50
52{
53 return is_vclass(jsthis, JSCLASS_ENUMERATOR) ? enumerator_from_vdisp(jsthis) : NULL;
54}
55
57{
60
61 if (This->atend)
62 return S_OK;
63
64 /* don't leak previous value */
65 jsval_release(This->item);
66
67 /* not at end ... get next item */
69 hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
70 if (hres == S_OK)
71 {
74 if (FAILED(hres))
75 {
76 WARN("failed to convert jsval to variant!\n");
77 This->item = jsval_undefined();
78 return hres;
79 }
80 }
81 else
82 {
83 This->item = jsval_undefined();
84 This->atend = TRUE;
85 }
86
87 return S_OK;
88}
89
90static void Enumerator_destructor(jsdisp_t *dispex)
91{
93
94 TRACE("\n");
95
96 jsval_release(This->item);
97 heap_free(dispex);
98}
99
101 jsval_t *r)
102{
104
105 if (!(This = enumerator_this(jsthis)))
107
108 TRACE("%d\n", This->atend);
109
110 if (r)
111 *r = jsval_bool(This->atend);
112 return S_OK;
113}
114
116 jsval_t *r)
117{
119
120 TRACE("\n");
121
122 if (!(This = enumerator_this(jsthis)))
124
125 return r ? jsval_copy(This->item, r) : S_OK;
126}
127
129 jsval_t *r)
130{
132 HRESULT hres = S_OK;
133
134 TRACE("\n");
135
136 if (!(This = enumerator_this(jsthis)))
138
139 if (This->enumvar)
140 {
141 hres = IEnumVARIANT_Reset(This->enumvar);
142 if (FAILED(hres))
143 return hres;
144
145 This->atend = FALSE;
147 if(FAILED(hres))
148 return hres;
149 }
150
151 if (r)
152 *r = jsval_undefined();
153 return S_OK;
154}
155
157 jsval_t *r)
158{
160 HRESULT hres = S_OK;
161
162 TRACE("\n");
163
164 if (!(This = enumerator_this(jsthis)))
166
167 if (This->enumvar)
168 {
170 if (FAILED(hres))
171 return hres;
172 }
173
174 if (r)
175 *r = jsval_undefined();
176 return S_OK;
177}
178
184};
185
188 {NULL, NULL, 0},
191 NULL,
192 NULL
193};
194
197 {NULL, NULL, 0, NULL},
198 0,
199 NULL,
201 NULL
202};
203
205{
206 EnumeratorInstance *enumerator;
208
209 enumerator = heap_alloc_zero(sizeof(EnumeratorInstance));
210 if(!enumerator)
211 return E_OUTOFMEMORY;
212
213 if(object_prototype)
214 hres = init_dispex(&enumerator->dispex, ctx, &Enumerator_info, object_prototype);
215 else
217 ctx->enumerator_constr);
218
219 if(FAILED(hres))
220 {
221 heap_free(enumerator);
222 return hres;
223 }
224
225 *ret = enumerator;
226 return S_OK;
227}
228
230{
231 EnumeratorInstance *enumerator;
233 IDispatch *obj;
234 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
236
237 if (argv)
238 {
239 VARIANT varresult;
240
242 {
243 FIXME("I don't know how to handle this type!\n");
244 return E_NOTIMPL;
245 }
246
247 obj = get_object(*argv);
248
249 /* Try to get a IEnumVARIANT by _NewEnum */
250 VariantInit(&varresult);
251 hres = IDispatch_Invoke(obj, DISPID_NEWENUM, &IID_NULL, LOCALE_NEUTRAL,
252 DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
253 if (FAILED(hres))
254 {
255 WARN("Enumerator: no DISPID_NEWENUM.\n");
256 return E_INVALIDARG;
257 }
258
259 if ((V_VT(&varresult) == VT_DISPATCH) || (V_VT(&varresult) == VT_UNKNOWN))
260 {
261 hres = IUnknown_QueryInterface(V_UNKNOWN(&varresult),
262 &IID_IEnumVARIANT, (void**)&enumvar);
263 }
264 else
265 {
266 FIXME("Enumerator: NewEnum unexpected type of varresult (%d).\n", V_VT(&varresult));
268 }
269 VariantClear(&varresult);
270 if (FAILED(hres))
271 return hres;
272 }
273
274 hres = alloc_enumerator(ctx, NULL, &enumerator);
275 if (FAILED(hres))
276 {
277 if (enumvar)
278 IEnumVARIANT_Release(enumvar);
279 return hres;
280 }
281
282 enumerator->enumvar = enumvar;
283 enumerator->atend = !enumvar;
284 hres = enumvar_get_next_item(enumerator);
285 if (FAILED(hres))
286 {
287 jsdisp_release(&enumerator->dispex);
288 return hres;
289 }
290
291 *ret = &enumerator->dispex;
292 return S_OK;
293}
294
296 jsval_t *r)
297{
298 jsdisp_t *obj;
300
301 TRACE("\n");
302
303 switch(flags) {
304 case DISPATCH_CONSTRUCT: {
305 if (argc > 1)
307
308 hres = create_enumerator(ctx, (argc == 1) ? &argv[0] : 0, &obj);
309 if(FAILED(hres))
310 return hres;
311
312 *r = jsval_obj(obj);
313 break;
314 }
315 default:
316 FIXME("unimplemented flags: %x\n", flags);
317 return E_NOTIMPL;
318 }
319
320 return S_OK;
321}
322
326 0,
327 NULL,
328 NULL,
329 NULL
330};
331
333{
334 EnumeratorInstance *enumerator;
336 static const WCHAR EnumeratorW[] = {'E','n','u','m','e','r','a','t','o','r',0};
337
338 hres = alloc_enumerator(ctx, object_prototype, &enumerator);
339 if(FAILED(hres))
340 return hres;
341
344 PROPF_CONSTR|7, &enumerator->dispex, ret);
345 jsdisp_release(&enumerator->dispex);
346
347 return hres;
348}
static int argc
Definition: ServiceArgs.c:12
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_DISPATCH
Definition: compat.h:2304
HRESULT throw_syntax_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:435
HRESULT throw_type_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:440
HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
Definition: function.c:686
static const WCHAR itemW[]
Definition: enumerator.c:37
static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:295
static const WCHAR atEndW[]
Definition: enumerator.c:36
static const builtin_prop_t Enumerator_props[]
Definition: enumerator.c:179
static const builtin_info_t EnumeratorConstr_info
Definition: enumerator.c:323
static EnumeratorInstance * enumerator_from_vdisp(vdisp_t *vdisp)
Definition: enumerator.c:46
static const WCHAR moveFirstW[]
Definition: enumerator.c:38
static const WCHAR moveNextW[]
Definition: enumerator.c:39
static EnumeratorInstance * enumerator_this(vdisp_t *jsthis)
Definition: enumerator.c:51
static EnumeratorInstance * enumerator_from_jsdisp(jsdisp_t *jsdisp)
Definition: enumerator.c:41
static void Enumerator_destructor(jsdisp_t *dispex)
Definition: enumerator.c:90
static const builtin_info_t EnumeratorInst_info
Definition: enumerator.c:195
static HRESULT Enumerator_atEnd(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:100
static HRESULT enumvar_get_next_item(EnumeratorInstance *This)
Definition: enumerator.c:56
static HRESULT alloc_enumerator(script_ctx_t *ctx, jsdisp_t *object_prototype, EnumeratorInstance **ret)
Definition: enumerator.c:204
static HRESULT Enumerator_moveNext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:156
static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:128
static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **ret)
Definition: enumerator.c:229
static const builtin_info_t Enumerator_info
Definition: enumerator.c:186
HRESULT create_enumerator_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
Definition: enumerator.c:332
static HRESULT Enumerator_item(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:115
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLbitfield flags
Definition: glext.h:7161
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
Definition: dispex.c:1030
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
static const WCHAR EnumeratorW[]
Definition: global.c:54
#define PROPF_CONSTR
Definition: jscript.h:98
static BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
Definition: jscript.h:509
#define DEFAULT_FUNCTION_VALUE
Definition: jscript.h:315
#define JS_E_ENUMERATOR_EXPECTED
Definition: jscript.h:562
static void jsdisp_release(jsdisp_t *jsdisp)
Definition: jscript.h:268
#define PROPF_METHOD
Definition: jscript.h:97
@ JSCLASS_ENUMERATOR
Definition: jscript.h:124
@ JSCLASS_FUNCTION
Definition: jscript.h:126
#define JS_E_INVALIDARG
Definition: jscript.h:529
HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
Definition: jsutils.c:258
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:231
void jsval_release(jsval_t val)
Definition: jsutils.c:191
static jsval_t jsval_undefined(void)
Definition: jsval.h:137
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
static jsval_t jsval_bool(BOOL b)
Definition: jsval.h:101
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:219
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:166
LOCAL void nextitem(arg_t *ap)
Definition: match.c:428
HRESULT hres
Definition: protocol.c:465
#define argv
Definition: mplay32.c:18
#define LOCALE_NEUTRAL
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_VT(A)
Definition: oleauto.h:211
#define IID_NULL
Definition: guiddef.h:98
#define TRACE(s)
Definition: solgame.cpp:4
IEnumVARIANT * enumvar
Definition: enumerator.c:30
Definition: jsval.h:54
union vdisp_t::@443 u
jsdisp_t * jsdisp
Definition: jscript.h:144
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
int ret
__wchar_t WCHAR
Definition: xmlstorage.h:180