ReactOS 0.4.17-dev-357-ga8f14ff
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
37{
38 return CONTAINING_RECORD(jsdisp, EnumeratorInstance, dispex);
39}
40
42{
43 jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
44 return (jsdisp && is_class(jsdisp, JSCLASS_ENUMERATOR)) ? enumerator_from_jsdisp(jsdisp) : NULL;
45}
46
48{
51
52 if (This->atend)
53 return S_OK;
54
55 /* don't leak previous value */
56 jsval_release(This->item);
57
58 /* not at end ... get next item */
60 hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
61 if (hres == S_OK)
62 {
65 if (FAILED(hres))
66 {
67 WARN("failed to convert jsval to variant!\n");
68 This->item = jsval_undefined();
69 return hres;
70 }
71 }
72 else
73 {
74 This->item = jsval_undefined();
75 This->atend = TRUE;
76 }
77
78 return S_OK;
79}
80
81static void Enumerator_destructor(jsdisp_t *dispex)
82{
84
85 TRACE("\n");
86
87 if(This->enumvar)
88 IEnumVARIANT_Release(This->enumvar);
89 jsval_release(This->item);
90}
91
93{
94 return gc_process_linked_val(gc_ctx, op, dispex, &enumerator_from_jsdisp(dispex)->item);
95}
96
98 jsval_t *r)
99{
101
102 if (!(This = enumerator_this(vthis)))
104
105 TRACE("%d\n", This->atend);
106
107 if (r)
108 *r = jsval_bool(This->atend);
109 return S_OK;
110}
111
113 jsval_t *r)
114{
116
117 TRACE("\n");
118
119 if (!(This = enumerator_this(vthis)))
121
122 return r ? jsval_copy(This->item, r) : S_OK;
123}
124
126 jsval_t *r)
127{
129 HRESULT hres = S_OK;
130
131 TRACE("\n");
132
133 if (!(This = enumerator_this(vthis)))
135
136 if (This->enumvar)
137 {
138 hres = IEnumVARIANT_Reset(This->enumvar);
139 if (FAILED(hres))
140 return hres;
141
142 This->atend = FALSE;
144 if(FAILED(hres))
145 return hres;
146 }
147
148 if (r)
149 *r = jsval_undefined();
150 return S_OK;
151}
152
154 jsval_t *r)
155{
157 HRESULT hres = S_OK;
158
159 TRACE("\n");
160
161 if (!(This = enumerator_this(vthis)))
163
164 if (This->enumvar)
165 {
167 if (FAILED(hres))
168 return hres;
169 }
170
171 if (r)
172 *r = jsval_undefined();
173 return S_OK;
174}
175
179 {L"moveFirst", Enumerator_moveFirst, PROPF_METHOD},
180 {L"moveNext", Enumerator_moveNext, PROPF_METHOD},
181};
182
185 .props_cnt = ARRAY_SIZE(Enumerator_props),
186 .props = Enumerator_props,
187};
188
191 .destructor = Enumerator_destructor,
192 .gc_traverse = Enumerator_gc_traverse
193};
194
196{
197 EnumeratorInstance *enumerator;
199
200 enumerator = calloc(1, sizeof(EnumeratorInstance));
201 if(!enumerator)
202 return E_OUTOFMEMORY;
203
204 if(object_prototype)
205 hres = init_dispex(&enumerator->dispex, ctx, &Enumerator_info, object_prototype);
206 else
208 ctx->enumerator_constr);
209
210 if(FAILED(hres))
211 {
212 free(enumerator);
213 return hres;
214 }
215
216 *ret = enumerator;
217 return S_OK;
218}
219
221{
222 EnumeratorInstance *enumerator;
224 IDispatch *obj;
225 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
227
228 if (argv)
229 {
230 VARIANT varresult;
231
233 {
234 FIXME("I don't know how to handle this type!\n");
235 return E_NOTIMPL;
236 }
237
238 obj = get_object(*argv);
239
240 /* Try to get a IEnumVARIANT by _NewEnum */
241 VariantInit(&varresult);
242 hres = IDispatch_Invoke(obj, DISPID_NEWENUM, &IID_NULL, LOCALE_NEUTRAL,
243 DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
244 if (FAILED(hres))
245 {
246 WARN("Enumerator: no DISPID_NEWENUM.\n");
248 }
249
250 if ((V_VT(&varresult) == VT_DISPATCH) || (V_VT(&varresult) == VT_UNKNOWN))
251 {
252 hres = IUnknown_QueryInterface(V_UNKNOWN(&varresult),
253 &IID_IEnumVARIANT, (void**)&enumvar);
254 }
255 else
256 {
257 FIXME("Enumerator: NewEnum unexpected type of varresult (%d).\n", V_VT(&varresult));
259 }
260 VariantClear(&varresult);
261 if (FAILED(hres))
262 return hres;
263 }
264
265 hres = alloc_enumerator(ctx, NULL, &enumerator);
266 if (FAILED(hres))
267 {
268 if (enumvar)
269 IEnumVARIANT_Release(enumvar);
270 return hres;
271 }
272
273 enumerator->enumvar = enumvar;
274 enumerator->atend = !enumvar;
275 hres = enumvar_get_next_item(enumerator, ctx);
276 if (FAILED(hres))
277 {
278 jsdisp_release(&enumerator->dispex);
279 return hres;
280 }
281
282 *ret = &enumerator->dispex;
283 return S_OK;
284}
285
287 jsval_t *r)
288{
289 jsdisp_t *obj;
291
292 TRACE("\n");
293
294 switch(flags) {
295 case DISPATCH_CONSTRUCT: {
296 if (argc > 1)
297 return JS_E_INVALIDARG;
298
299 hres = create_enumerator(ctx, (argc == 1) ? &argv[0] : 0, &obj);
300 if(FAILED(hres))
301 return hres;
302
303 if(r) *r = jsval_obj(obj);
304 else jsdisp_release(obj);
305 break;
306 }
307 default:
308 FIXME("unimplemented flags: %x\n", flags);
309 return E_NOTIMPL;
310 }
311
312 return S_OK;
313}
314
317 .call = Function_value,
318};
319
321{
322 EnumeratorInstance *enumerator;
324
325 hres = alloc_enumerator(ctx, object_prototype, &enumerator);
326 if(FAILED(hres))
327 return hres;
328
330 &EnumeratorConstr_info, PROPF_CONSTR|7, &enumerator->dispex, ret);
331 jsdisp_release(&enumerator->dispex);
332
333 return hres;
334}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_DISPATCH
Definition: compat.h:2304
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:809
HRESULT Function_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:600
MonoAssembly int argc
Definition: metahost.c:107
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:125
static const builtin_prop_t Enumerator_props[]
Definition: enumerator.c:176
static const builtin_info_t EnumeratorConstr_info
Definition: enumerator.c:315
static EnumeratorInstance * enumerator_from_jsdisp(jsdisp_t *jsdisp)
Definition: enumerator.c:36
static void Enumerator_destructor(jsdisp_t *dispex)
Definition: enumerator.c:81
static HRESULT enumvar_get_next_item(EnumeratorInstance *This, script_ctx_t *ctx)
Definition: enumerator.c:47
static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:286
static const builtin_info_t EnumeratorInst_info
Definition: enumerator.c:189
static HRESULT Enumerator_moveNext(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:153
static EnumeratorInstance * enumerator_this(jsval_t vthis)
Definition: enumerator.c:41
static HRESULT Enumerator_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
Definition: enumerator.c:92
static HRESULT alloc_enumerator(script_ctx_t *ctx, jsdisp_t *object_prototype, EnumeratorInstance **ret)
Definition: enumerator.c:195
static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **ret)
Definition: enumerator.c:220
static HRESULT Enumerator_item(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:112
static HRESULT Enumerator_atEnd(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: enumerator.c:97
static const builtin_info_t Enumerator_info
Definition: enumerator.c:183
HRESULT create_enumerator_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
Definition: enumerator.c:320
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
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:2512
HRESULT gc_process_linked_val(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *obj, jsval_t *link)
Definition: dispex.c:1139
ULONG jsdisp_release(jsdisp_t *obj)
Definition: dispex.c:1911
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:2454
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:2447
#define JS_E_OBJECT_NOT_COLLECTION
Definition: jscript.h:535
#define JS_E_ENUMERATOR_EXPECTED
Definition: jscript.h:562
@ JSCLASS_ENUMERATOR
Definition: jscript.h:107
@ JSCLASS_FUNCTION
Definition: jscript.h:109
gc_traverse_op
Definition: jscript.h:161
#define JS_E_INVALIDARG
Definition: jscript.h:527
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:503
const unsigned int PROPF_METHOD
Definition: jsdisp.idl:33
const unsigned int PROPF_CONSTR
Definition: jsdisp.idl:34
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:225
HRESULT variant_to_jsval(script_ctx_t *ctx, VARIANT *var, jsval_t *r)
Definition: jsutils.c:251
void jsval_release(jsval_t val)
Definition: jsutils.c:186
static jsval_t jsval_undefined(void)
Definition: jsval.h:146
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:228
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:175
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 DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define IID_NULL
Definition: guiddef.h:98
#define calloc
Definition: rosglue.h:14
#define TRACE(s)
Definition: solgame.cpp:4
IEnumVARIANT * enumvar
Definition: enumerator.c:30
Definition: jsval.h:54
jsclass_t class
Definition: jscript.h:183
Definition: dispex.c:889
#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