2 * Copyright 2010 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(jscript
);
31 static inline VBArrayInstance
*vbarray_from_jsdisp(jsdisp_t
*jsdisp
)
33 return CONTAINING_RECORD(jsdisp
, VBArrayInstance
, dispex
);
36 static inline VBArrayInstance
*vbarray_this(jsval_t vthis
)
38 jsdisp_t
*jsdisp
= is_object_instance(vthis
) ? to_jsdisp(get_object(vthis
)) : NULL
;
39 return (jsdisp
&& is_class(jsdisp
, JSCLASS_VBARRAY
)) ? vbarray_from_jsdisp(jsdisp
) : NULL
;
42 static HRESULT
VBArray_dimensions(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
45 VBArrayInstance
*vbarray
;
49 vbarray
= vbarray_this(vthis
);
51 return JS_E_VBARRAY_EXPECTED
;
54 *r
= jsval_number(SafeArrayGetDim(vbarray
->safearray
));
58 static HRESULT
VBArray_getItem(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
61 VBArrayInstance
*vbarray
;
69 vbarray
= vbarray_this(vthis
);
71 return JS_E_VBARRAY_EXPECTED
;
73 if(argc
< SafeArrayGetDim(vbarray
->safearray
))
74 return JS_E_SUBSCRIPT_OUT_OF_RANGE
;
76 indexes
= malloc(sizeof(indexes
[0])*argc
);
80 for(i
=0; i
<argc
; i
++) {
81 hres
= to_long(ctx
, argv
[i
], indexes
+ i
);
88 hres
= SafeArrayGetElement(vbarray
->safearray
, indexes
, (void*)&out
);
90 if(hres
== DISP_E_BADINDEX
)
91 return JS_E_SUBSCRIPT_OUT_OF_RANGE
;
96 hres
= variant_to_jsval(ctx
, &out
, r
);
102 static HRESULT
VBArray_lbound(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
105 VBArrayInstance
*vbarray
;
111 vbarray
= vbarray_this(vthis
);
113 return JS_E_VBARRAY_EXPECTED
;
116 hres
= to_long(ctx
, argv
[0], &dim
);
122 hres
= SafeArrayGetLBound(vbarray
->safearray
, dim
, &dim
);
123 if(hres
== DISP_E_BADINDEX
)
124 return JS_E_SUBSCRIPT_OUT_OF_RANGE
;
125 else if(FAILED(hres
))
129 *r
= jsval_number(dim
);
133 static HRESULT
VBArray_toArray(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
136 VBArrayInstance
*vbarray
;
140 LONG i
, size
= 1, ubound
, lbound
;
145 vbarray
= vbarray_this(vthis
);
147 return JS_E_VBARRAY_EXPECTED
;
149 for(i
=1; i
<=SafeArrayGetDim(vbarray
->safearray
); i
++) {
150 SafeArrayGetLBound(vbarray
->safearray
, i
, &lbound
);
151 SafeArrayGetUBound(vbarray
->safearray
, i
, &ubound
);
152 size
*= ubound
-lbound
+1;
155 hres
= SafeArrayAccessData(vbarray
->safearray
, (void**)&v
);
159 hres
= create_array(ctx
, 0, &array
);
161 SafeArrayUnaccessData(vbarray
->safearray
);
165 for(i
=0; i
<size
; i
++) {
166 hres
= variant_to_jsval(ctx
, v
, &val
);
167 if(SUCCEEDED(hres
)) {
168 hres
= jsdisp_propput_idx(array
, i
, val
);
172 SafeArrayUnaccessData(vbarray
->safearray
);
173 jsdisp_release(array
);
179 SafeArrayUnaccessData(vbarray
->safearray
);
182 *r
= jsval_obj(array
);
184 jsdisp_release(array
);
188 static HRESULT
VBArray_ubound(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
191 VBArrayInstance
*vbarray
;
197 vbarray
= vbarray_this(vthis
);
199 return JS_E_VBARRAY_EXPECTED
;
202 hres
= to_long(ctx
, argv
[0], &dim
);
208 hres
= SafeArrayGetUBound(vbarray
->safearray
, dim
, &dim
);
209 if(hres
== DISP_E_BADINDEX
)
210 return JS_E_SUBSCRIPT_OUT_OF_RANGE
;
211 else if(FAILED(hres
))
215 *r
= jsval_number(dim
);
219 static HRESULT
VBArray_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
226 FIXME("unimplemented flags %x\n", flags
);
233 static void VBArray_destructor(jsdisp_t
*dispex
)
235 VBArrayInstance
*vbarray
= vbarray_from_jsdisp(dispex
);
237 SafeArrayDestroy(vbarray
->safearray
);
241 static const builtin_prop_t VBArray_props
[] = {
242 {L
"dimensions", VBArray_dimensions
, PROPF_METHOD
},
243 {L
"getItem", VBArray_getItem
, PROPF_METHOD
|1},
244 {L
"lbound", VBArray_lbound
, PROPF_METHOD
},
245 {L
"toArray", VBArray_toArray
, PROPF_METHOD
},
246 {L
"ubound", VBArray_ubound
, PROPF_METHOD
}
249 static const builtin_info_t VBArray_info
= {
252 ARRAY_SIZE(VBArray_props
),
258 static HRESULT
alloc_vbarray(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, VBArrayInstance
**ret
)
260 VBArrayInstance
*vbarray
;
263 vbarray
= calloc(1, sizeof(VBArrayInstance
));
265 return E_OUTOFMEMORY
;
268 hres
= init_dispex(&vbarray
->dispex
, ctx
, &VBArray_info
, object_prototype
);
270 hres
= init_dispex_from_constr(&vbarray
->dispex
, ctx
, &VBArray_info
, ctx
->vbarray_constr
);
281 static HRESULT
VBArrayConstr_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
284 VBArrayInstance
*vbarray
;
290 case DISPATCH_METHOD
:
291 if(argc
<1 || !is_variant(argv
[0]) || V_VT(get_variant(argv
[0])) != (VT_ARRAY
|VT_VARIANT
))
292 return JS_E_VBARRAY_EXPECTED
;
294 return r
? jsval_copy(argv
[0], r
) : S_OK
;
296 case DISPATCH_CONSTRUCT
:
297 if(argc
<1 || !is_variant(argv
[0]) || V_VT(get_variant(argv
[0])) != (VT_ARRAY
|VT_VARIANT
))
298 return JS_E_VBARRAY_EXPECTED
;
302 hres
= alloc_vbarray(ctx
, NULL
, &vbarray
);
306 hres
= SafeArrayCopy(V_ARRAY(get_variant(argv
[0])), &vbarray
->safearray
);
308 jsdisp_release(&vbarray
->dispex
);
312 *r
= jsval_obj(&vbarray
->dispex
);
316 FIXME("unimplemented flags: %x\n", flags
);
323 HRESULT
create_vbarray_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
325 VBArrayInstance
*vbarray
;
328 hres
= alloc_vbarray(ctx
, object_prototype
, &vbarray
);
332 hres
= create_builtin_constructor(ctx
, VBArrayConstr_value
, L
"VBArray", NULL
, PROPF_CONSTR
|1, &vbarray
->dispex
, ret
);
334 jsdisp_release(&vbarray
->dispex
);
338 HRESULT
create_vbarray(script_ctx_t
*ctx
, SAFEARRAY
*sa
, jsdisp_t
**ret
)
340 VBArrayInstance
*vbarray
;
343 hres
= alloc_vbarray(ctx
, NULL
, &vbarray
);
347 hres
= SafeArrayCopy(sa
, &vbarray
->safearray
);
349 jsdisp_release(&vbarray
->dispex
);
353 *ret
= &vbarray
->dispex
;