d2d1: Add D2D1Crop.
[wine.git] / dlls / jscript / vbarray.c
blob69a77f1e56a2fd395274b89d34767da8f089dee5
1 /*
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
19 #include "jscript.h"
21 #include "wine/debug.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25 typedef struct {
26 jsdisp_t dispex;
28 SAFEARRAY *safearray;
29 } VBArrayInstance;
31 static inline VBArrayInstance *vbarray_from_jsdisp(jsdisp_t *jsdisp)
33 return CONTAINING_RECORD(jsdisp, VBArrayInstance, dispex);
36 static inline VBArrayInstance *vbarray_from_vdisp(vdisp_t *vdisp)
38 return vbarray_from_jsdisp(vdisp->u.jsdisp);
41 static inline VBArrayInstance *vbarray_this(vdisp_t *jsthis)
43 return is_vclass(jsthis, JSCLASS_VBARRAY) ? vbarray_from_vdisp(jsthis) : NULL;
46 static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
47 jsval_t *r)
49 VBArrayInstance *vbarray;
51 TRACE("\n");
53 vbarray = vbarray_this(vthis);
54 if(!vbarray)
55 return JS_E_VBARRAY_EXPECTED;
57 if(r)
58 *r = jsval_number(SafeArrayGetDim(vbarray->safearray));
59 return S_OK;
62 static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
63 jsval_t *r)
65 VBArrayInstance *vbarray;
66 int i, *indexes;
67 VARIANT out;
68 HRESULT hres;
70 TRACE("\n");
72 vbarray = vbarray_this(vthis);
73 if(!vbarray)
74 return JS_E_VBARRAY_EXPECTED;
76 if(argc < SafeArrayGetDim(vbarray->safearray))
77 return JS_E_SUBSCRIPT_OUT_OF_RANGE;
79 indexes = heap_alloc(sizeof(int)*argc);
80 if(!indexes)
81 return E_OUTOFMEMORY;
83 for(i=0; i<argc; i++) {
84 hres = to_int32(ctx, argv[i], indexes+i);
85 if(FAILED(hres)) {
86 heap_free(indexes);
87 return hres;
91 hres = SafeArrayGetElement(vbarray->safearray, indexes, (void*)&out);
92 heap_free(indexes);
93 if(hres == DISP_E_BADINDEX)
94 return JS_E_SUBSCRIPT_OUT_OF_RANGE;
95 else if(FAILED(hres))
96 return hres;
98 if(r) {
99 hres = variant_to_jsval(&out, r);
100 VariantClear(&out);
102 return hres;
105 static HRESULT VBArray_lbound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
106 jsval_t *r)
108 VBArrayInstance *vbarray;
109 int dim;
110 HRESULT hres;
112 TRACE("\n");
114 vbarray = vbarray_this(vthis);
115 if(!vbarray)
116 return JS_E_VBARRAY_EXPECTED;
118 if(argc) {
119 hres = to_int32(ctx, argv[0], &dim);
120 if(FAILED(hres))
121 return hres;
122 } else
123 dim = 1;
125 hres = SafeArrayGetLBound(vbarray->safearray, dim, &dim);
126 if(hres == DISP_E_BADINDEX)
127 return JS_E_SUBSCRIPT_OUT_OF_RANGE;
128 else if(FAILED(hres))
129 return hres;
131 if(r)
132 *r = jsval_number(dim);
133 return S_OK;
136 static HRESULT VBArray_toArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
137 jsval_t *r)
139 VBArrayInstance *vbarray;
140 jsdisp_t *array;
141 jsval_t val;
142 VARIANT *v;
143 int i, size = 1, ubound, lbound;
144 HRESULT hres;
146 TRACE("\n");
148 vbarray = vbarray_this(vthis);
149 if(!vbarray)
150 return JS_E_VBARRAY_EXPECTED;
152 for(i=1; i<=SafeArrayGetDim(vbarray->safearray); i++) {
153 SafeArrayGetLBound(vbarray->safearray, i, &lbound);
154 SafeArrayGetUBound(vbarray->safearray, i, &ubound);
155 size *= ubound-lbound+1;
158 hres = SafeArrayAccessData(vbarray->safearray, (void**)&v);
159 if(FAILED(hres))
160 return hres;
162 hres = create_array(ctx, 0, &array);
163 if(FAILED(hres)) {
164 SafeArrayUnaccessData(vbarray->safearray);
165 return hres;
168 for(i=0; i<size; i++) {
169 hres = variant_to_jsval(v, &val);
170 if(SUCCEEDED(hres)) {
171 hres = jsdisp_propput_idx(array, i, val);
172 jsval_release(val);
174 if(FAILED(hres)) {
175 SafeArrayUnaccessData(vbarray->safearray);
176 jsdisp_release(array);
177 return hres;
179 v++;
182 SafeArrayUnaccessData(vbarray->safearray);
184 if(r)
185 *r = jsval_obj(array);
186 else
187 jsdisp_release(array);
188 return S_OK;
191 static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
192 jsval_t *r)
194 VBArrayInstance *vbarray;
195 int dim;
196 HRESULT hres;
198 TRACE("\n");
200 vbarray = vbarray_this(vthis);
201 if(!vbarray)
202 return JS_E_VBARRAY_EXPECTED;
204 if(argc) {
205 hres = to_int32(ctx, argv[0], &dim);
206 if(FAILED(hres))
207 return hres;
208 } else
209 dim = 1;
211 hres = SafeArrayGetUBound(vbarray->safearray, dim, &dim);
212 if(hres == DISP_E_BADINDEX)
213 return JS_E_SUBSCRIPT_OUT_OF_RANGE;
214 else if(FAILED(hres))
215 return hres;
217 if(r)
218 *r = jsval_number(dim);
219 return S_OK;
222 static HRESULT VBArray_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
223 jsval_t *r)
225 FIXME("\n");
227 switch(flags) {
228 default:
229 FIXME("unimplemented flags %x\n", flags);
230 return E_NOTIMPL;
233 return S_OK;
236 static void VBArray_destructor(jsdisp_t *dispex)
238 VBArrayInstance *vbarray = vbarray_from_jsdisp(dispex);
240 SafeArrayDestroy(vbarray->safearray);
241 heap_free(vbarray);
244 static const builtin_prop_t VBArray_props[] = {
245 {L"dimensions", VBArray_dimensions, PROPF_METHOD},
246 {L"getItem", VBArray_getItem, PROPF_METHOD|1},
247 {L"lbound", VBArray_lbound, PROPF_METHOD},
248 {L"toArray", VBArray_toArray, PROPF_METHOD},
249 {L"ubound", VBArray_ubound, PROPF_METHOD}
252 static const builtin_info_t VBArray_info = {
253 JSCLASS_VBARRAY,
254 {NULL, VBArray_value, 0},
255 ARRAY_SIZE(VBArray_props),
256 VBArray_props,
257 VBArray_destructor,
258 NULL
261 static HRESULT alloc_vbarray(script_ctx_t *ctx, jsdisp_t *object_prototype, VBArrayInstance **ret)
263 VBArrayInstance *vbarray;
264 HRESULT hres;
266 vbarray = heap_alloc_zero(sizeof(VBArrayInstance));
267 if(!vbarray)
268 return E_OUTOFMEMORY;
270 if(object_prototype)
271 hres = init_dispex(&vbarray->dispex, ctx, &VBArray_info, object_prototype);
272 else
273 hres = init_dispex_from_constr(&vbarray->dispex, ctx, &VBArray_info, ctx->vbarray_constr);
275 if(FAILED(hres)) {
276 heap_free(vbarray);
277 return hres;
280 *ret = vbarray;
281 return S_OK;
284 static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
285 jsval_t *r)
287 VBArrayInstance *vbarray;
288 HRESULT hres;
290 TRACE("\n");
292 switch(flags) {
293 case DISPATCH_METHOD:
294 if(argc<1 || !is_variant(argv[0]) || V_VT(get_variant(argv[0])) != (VT_ARRAY|VT_VARIANT))
295 return JS_E_VBARRAY_EXPECTED;
297 return jsval_copy(argv[0], r);
299 case DISPATCH_CONSTRUCT:
300 if(argc<1 || !is_variant(argv[0]) || V_VT(get_variant(argv[0])) != (VT_ARRAY|VT_VARIANT))
301 return JS_E_VBARRAY_EXPECTED;
303 hres = alloc_vbarray(ctx, NULL, &vbarray);
304 if(FAILED(hres))
305 return hres;
307 hres = SafeArrayCopy(V_ARRAY(get_variant(argv[0])), &vbarray->safearray);
308 if(FAILED(hres)) {
309 jsdisp_release(&vbarray->dispex);
310 return hres;
313 *r = jsval_obj(&vbarray->dispex);
314 break;
316 default:
317 FIXME("unimplemented flags: %x\n", flags);
318 return E_NOTIMPL;
321 return S_OK;
324 HRESULT create_vbarray_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
326 VBArrayInstance *vbarray;
327 HRESULT hres;
329 hres = alloc_vbarray(ctx, object_prototype, &vbarray);
330 if(FAILED(hres))
331 return hres;
333 hres = create_builtin_constructor(ctx, VBArrayConstr_value, L"VBArray", NULL, PROPF_CONSTR|1, &vbarray->dispex, ret);
335 jsdisp_release(&vbarray->dispex);
336 return hres;
339 HRESULT create_vbarray(script_ctx_t *ctx, SAFEARRAY *sa, jsdisp_t **ret)
341 VBArrayInstance *vbarray;
342 HRESULT hres;
344 hres = alloc_vbarray(ctx, NULL, &vbarray);
345 if(FAILED(hres))
346 return hres;
348 hres = SafeArrayCopy(sa, &vbarray->safearray);
349 if(FAILED(hres)) {
350 jsdisp_release(&vbarray->dispex);
351 return hres;
354 *ret = &vbarray->dispex;
355 return S_OK;