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 const WCHAR dimensionsW
[] = {'d','i','m','e','n','s','i','o','n','s',0};
32 static const WCHAR getItemW
[] = {'g','e','t','I','t','e','m',0};
33 static const WCHAR lboundW
[] = {'l','b','o','u','n','d',0};
34 static const WCHAR toArrayW
[] = {'t','o','A','r','r','a','y',0};
35 static const WCHAR uboundW
[] = {'u','b','o','u','n','d',0};
37 static inline VBArrayInstance
*vbarray_from_vdisp(vdisp_t
*vdisp
)
39 return (VBArrayInstance
*)vdisp
->u
.jsdisp
;
42 static inline VBArrayInstance
*vbarray_this(vdisp_t
*jsthis
)
44 return is_vclass(jsthis
, JSCLASS_VBARRAY
) ? vbarray_from_vdisp(jsthis
) : NULL
;
47 static HRESULT
VBArray_dimensions(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
48 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
50 VBArrayInstance
*vbarray
;
54 vbarray
= vbarray_this(vthis
);
56 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
59 num_set_val(retv
, SafeArrayGetDim(vbarray
->safearray
));
63 static HRESULT
VBArray_getItem(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
64 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
66 VBArrayInstance
*vbarray
;
67 int i
, *indexes
, size
;
73 vbarray
= vbarray_this(vthis
);
75 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
78 if(size
< SafeArrayGetDim(vbarray
->safearray
))
79 return throw_range_error(ctx
, ei
, IDS_SUBSCRIPT_OUT_OF_RANGE
, NULL
);
81 indexes
= heap_alloc(sizeof(int)*size
);
82 for(i
=0; i
<size
; i
++) {
83 hres
= to_int32(ctx
, get_arg(dp
, i
), ei
, indexes
+i
);
90 hres
= SafeArrayGetElement(vbarray
->safearray
, indexes
, (void*)&out
);
92 if(hres
== DISP_E_BADINDEX
)
93 return throw_range_error(ctx
, ei
, IDS_SUBSCRIPT_OUT_OF_RANGE
, NULL
);
98 hres
= VariantCopy(retv
, &out
);
103 static HRESULT
VBArray_lbound(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
104 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
106 VBArrayInstance
*vbarray
;
112 vbarray
= vbarray_this(vthis
);
114 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
117 hres
= to_int32(ctx
, get_arg(dp
, 0), ei
, &dim
);
123 hres
= SafeArrayGetLBound(vbarray
->safearray
, dim
, &dim
);
124 if(hres
== DISP_E_BADINDEX
)
125 return throw_range_error(ctx
, ei
, IDS_SUBSCRIPT_OUT_OF_RANGE
, NULL
);
126 else if(FAILED(hres
))
130 num_set_val(retv
, dim
);
134 static HRESULT
VBArray_toArray(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
135 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
141 static HRESULT
VBArray_ubound(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
142 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
144 VBArrayInstance
*vbarray
;
150 vbarray
= vbarray_this(vthis
);
152 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
155 hres
= to_int32(ctx
, get_arg(dp
, 0), ei
, &dim
);
161 hres
= SafeArrayGetUBound(vbarray
->safearray
, dim
, &dim
);
162 if(hres
== DISP_E_BADINDEX
)
163 return throw_range_error(ctx
, ei
, IDS_SUBSCRIPT_OUT_OF_RANGE
, NULL
);
164 else if(FAILED(hres
))
168 num_set_val(retv
, dim
);
172 static HRESULT
VBArray_value(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, DISPPARAMS
*dp
,
173 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*sp
)
179 FIXME("unimplemented flags %x\n", flags
);
186 static void VBArray_destructor(jsdisp_t
*dispex
)
188 VBArrayInstance
*vbarray
= (VBArrayInstance
*)dispex
;
190 SafeArrayDestroy(vbarray
->safearray
);
194 static const builtin_prop_t VBArray_props
[] = {
195 {dimensionsW
, VBArray_dimensions
, PROPF_METHOD
},
196 {getItemW
, VBArray_getItem
, PROPF_METHOD
|1},
197 {lboundW
, VBArray_lbound
, PROPF_METHOD
},
198 {toArrayW
, VBArray_toArray
, PROPF_METHOD
},
199 {uboundW
, VBArray_ubound
, PROPF_METHOD
}
202 static const builtin_info_t VBArray_info
= {
204 {NULL
, VBArray_value
, 0},
205 sizeof(VBArray_props
)/sizeof(*VBArray_props
),
211 static HRESULT
alloc_vbarray(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, VBArrayInstance
**ret
)
213 VBArrayInstance
*vbarray
;
216 vbarray
= heap_alloc_zero(sizeof(VBArrayInstance
));
218 return E_OUTOFMEMORY
;
221 hres
= init_dispex(&vbarray
->dispex
, ctx
, &VBArray_info
, object_prototype
);
223 hres
= init_dispex_from_constr(&vbarray
->dispex
, ctx
, &VBArray_info
, ctx
->vbarray_constr
);
234 static HRESULT
VBArrayConstr_value(script_ctx_t
*ctx
, vdisp_t
*vthis
, WORD flags
, DISPPARAMS
*dp
,
235 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
238 VBArrayInstance
*vbarray
;
244 case DISPATCH_METHOD
:
245 if(arg_cnt(dp
)<1 || V_VT((arg
= get_arg(dp
, 0)))!=(VT_ARRAY
|VT_VARIANT
))
246 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
248 VariantCopy(retv
, arg
);
251 case DISPATCH_CONSTRUCT
:
252 if(arg_cnt(dp
)<1 || V_VT((arg
= get_arg(dp
, 0)))!=(VT_ARRAY
|VT_VARIANT
))
253 return throw_type_error(ctx
, ei
, IDS_NOT_VBARRAY
, NULL
);
255 hres
= alloc_vbarray(ctx
, NULL
, &vbarray
);
258 SafeArrayCopy(V_ARRAY(arg
), &vbarray
->safearray
);
260 var_set_jsdisp(retv
, &vbarray
->dispex
);
264 FIXME("unimplemented flags: %x\n", flags
);
271 HRESULT
create_vbarray_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
273 VBArrayInstance
*vbarray
;
276 static const WCHAR VBArrayW
[] = {'V','B','A','r','r','a','y',0};
278 hres
= alloc_vbarray(ctx
, object_prototype
, &vbarray
);
282 hres
= create_builtin_function(ctx
, VBArrayConstr_value
, VBArrayW
, NULL
, PROPF_CONSTR
|1, &vbarray
->dispex
, ret
);
284 jsdisp_release(&vbarray
->dispex
);