winhttp: Don't refill buffer after receiving server response.
[wine.git] / dlls / jscript / vbarray.c
blob998dc230818973f32902379ea8f490db71a4162c
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_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,
43 jsval_t *r)
45 VBArrayInstance *vbarray;
47 TRACE("\n");
49 vbarray = vbarray_this(vthis);
50 if(!vbarray)
51 return JS_E_VBARRAY_EXPECTED;
53 if(r)
54 *r = jsval_number(SafeArrayGetDim(vbarray->safearray));
55 return S_OK;
58 static HRESULT VBArray_getItem(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
59 jsval_t *r)
61 VBArrayInstance *vbarray;
62 unsigned i;
63 LONG *indexes;
64 VARIANT out;
65 HRESULT hres;
67 TRACE("\n");
69 vbarray = vbarray_this(vthis);
70 if(!vbarray)
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);
77 if(!indexes)
78 return E_OUTOFMEMORY;
80 for(i=0; i<argc; i++) {
81 hres = to_long(ctx, argv[i], indexes + i);
82 if(FAILED(hres)) {
83 free(indexes);
84 return hres;
88 hres = SafeArrayGetElement(vbarray->safearray, indexes, (void*)&out);
89 free(indexes);
90 if(hres == DISP_E_BADINDEX)
91 return JS_E_SUBSCRIPT_OUT_OF_RANGE;
92 else if(FAILED(hres))
93 return hres;
95 if(r) {
96 hres = variant_to_jsval(ctx, &out, r);
97 VariantClear(&out);
99 return hres;
102 static HRESULT VBArray_lbound(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
103 jsval_t *r)
105 VBArrayInstance *vbarray;
106 LONG dim;
107 HRESULT hres;
109 TRACE("\n");
111 vbarray = vbarray_this(vthis);
112 if(!vbarray)
113 return JS_E_VBARRAY_EXPECTED;
115 if(argc) {
116 hres = to_long(ctx, argv[0], &dim);
117 if(FAILED(hres))
118 return hres;
119 } else
120 dim = 1;
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))
126 return hres;
128 if(r)
129 *r = jsval_number(dim);
130 return S_OK;
133 static HRESULT VBArray_toArray(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
134 jsval_t *r)
136 VBArrayInstance *vbarray;
137 jsdisp_t *array;
138 jsval_t val;
139 VARIANT *v;
140 LONG i, size = 1, ubound, lbound;
141 HRESULT hres;
143 TRACE("\n");
145 vbarray = vbarray_this(vthis);
146 if(!vbarray)
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);
156 if(FAILED(hres))
157 return hres;
159 hres = create_array(ctx, 0, &array);
160 if(FAILED(hres)) {
161 SafeArrayUnaccessData(vbarray->safearray);
162 return hres;
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);
169 jsval_release(val);
171 if(FAILED(hres)) {
172 SafeArrayUnaccessData(vbarray->safearray);
173 jsdisp_release(array);
174 return hres;
176 v++;
179 SafeArrayUnaccessData(vbarray->safearray);
181 if(r)
182 *r = jsval_obj(array);
183 else
184 jsdisp_release(array);
185 return S_OK;
188 static HRESULT VBArray_ubound(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
189 jsval_t *r)
191 VBArrayInstance *vbarray;
192 LONG dim;
193 HRESULT hres;
195 TRACE("\n");
197 vbarray = vbarray_this(vthis);
198 if(!vbarray)
199 return JS_E_VBARRAY_EXPECTED;
201 if(argc) {
202 hres = to_long(ctx, argv[0], &dim);
203 if(FAILED(hres))
204 return hres;
205 } else
206 dim = 1;
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))
212 return hres;
214 if(r)
215 *r = jsval_number(dim);
216 return S_OK;
219 static HRESULT VBArray_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
220 jsval_t *r)
222 FIXME("\n");
224 switch(flags) {
225 default:
226 FIXME("unimplemented flags %x\n", flags);
227 return E_NOTIMPL;
230 return S_OK;
233 static void VBArray_destructor(jsdisp_t *dispex)
235 VBArrayInstance *vbarray = vbarray_from_jsdisp(dispex);
237 SafeArrayDestroy(vbarray->safearray);
238 free(vbarray);
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 = {
250 JSCLASS_VBARRAY,
251 VBArray_value,
252 ARRAY_SIZE(VBArray_props),
253 VBArray_props,
254 VBArray_destructor,
255 NULL
258 static HRESULT alloc_vbarray(script_ctx_t *ctx, jsdisp_t *object_prototype, VBArrayInstance **ret)
260 VBArrayInstance *vbarray;
261 HRESULT hres;
263 vbarray = calloc(1, sizeof(VBArrayInstance));
264 if(!vbarray)
265 return E_OUTOFMEMORY;
267 if(object_prototype)
268 hres = init_dispex(&vbarray->dispex, ctx, &VBArray_info, object_prototype);
269 else
270 hres = init_dispex_from_constr(&vbarray->dispex, ctx, &VBArray_info, ctx->vbarray_constr);
272 if(FAILED(hres)) {
273 free(vbarray);
274 return hres;
277 *ret = vbarray;
278 return S_OK;
281 static HRESULT VBArrayConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
282 jsval_t *r)
284 VBArrayInstance *vbarray;
285 HRESULT hres;
287 TRACE("\n");
289 switch(flags) {
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;
299 if(!r)
300 return S_OK;
302 hres = alloc_vbarray(ctx, NULL, &vbarray);
303 if(FAILED(hres))
304 return hres;
306 hres = SafeArrayCopy(V_ARRAY(get_variant(argv[0])), &vbarray->safearray);
307 if(FAILED(hres)) {
308 jsdisp_release(&vbarray->dispex);
309 return hres;
312 *r = jsval_obj(&vbarray->dispex);
313 break;
315 default:
316 FIXME("unimplemented flags: %x\n", flags);
317 return E_NOTIMPL;
320 return S_OK;
323 HRESULT create_vbarray_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
325 VBArrayInstance *vbarray;
326 HRESULT hres;
328 hres = alloc_vbarray(ctx, object_prototype, &vbarray);
329 if(FAILED(hres))
330 return hres;
332 hres = create_builtin_constructor(ctx, VBArrayConstr_value, L"VBArray", NULL, PROPF_CONSTR|1, &vbarray->dispex, ret);
334 jsdisp_release(&vbarray->dispex);
335 return hres;
338 HRESULT create_vbarray(script_ctx_t *ctx, SAFEARRAY *sa, jsdisp_t **ret)
340 VBArrayInstance *vbarray;
341 HRESULT hres;
343 hres = alloc_vbarray(ctx, NULL, &vbarray);
344 if(FAILED(hres))
345 return hres;
347 hres = SafeArrayCopy(sa, &vbarray->safearray);
348 if(FAILED(hres)) {
349 jsdisp_release(&vbarray->dispex);
350 return hres;
353 *ret = &vbarray->dispex;
354 return S_OK;