Module: wine Branch: master Commit: 2325e2cdb8fe9b7c7eb5de4f4be4a5f4ad3e5909 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2325e2cdb8fe9b7c7eb5de4f4b...
Author: Piotr Caban piotr.caban@gmail.com Date: Tue Jul 14 01:36:43 2009 +0200
jscript: Added Array_slice implementation.
---
dlls/jscript/array.c | 77 +++++++++++++++++++++++++++++++++++++++++++- dlls/jscript/tests/api.js | 17 ++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index e5d6b2d..9b43142 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -421,8 +421,81 @@ static HRESULT Array_shift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + DispatchEx *arr; + VARIANT v; + DOUBLE range; + DWORD length, start, end, idx; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + length = ((ArrayInstance*)dispex)->length; + }else { + FIXME("not Array this\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp)) { + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) + range = V_I4(&v); + else + range = floor(V_R8(&v)); + + if(-range>length || isnan(range)) start = 0; + else if(range < 0) start = range+length; + else if(range <= length) start = range; + else start = length; + } + else start = 0; + + if(arg_cnt(dp)>1) { + hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) + range = V_I4(&v); + else + range = floor(V_R8(&v)); + + if(-range>length) end = 0; + else if(range < 0) end = range+length; + else if(range <= length) end = range; + else end = length; + } + else end = length; + + hres = create_array(dispex->ctx, (end>start)?end-start:0, &arr); + if(FAILED(hres)) + return hres; + + for(idx=start; idx<end; idx++) { + hres = jsdisp_propget_idx(dispex, idx, lcid, &v, ei, sp); + if(hres == DISP_E_UNKNOWNNAME) + continue; + + if(SUCCEEDED(hres)) + hres = jsdisp_propput_idx(arr, idx-start, lcid, &v, ei, sp); + + if(FAILED(hres)) { + jsdisp_release(arr); + return hres; + } + } + + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(arr); + } + else + jsdisp_release(arr); + + return S_OK; }
static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VARIANT *v2, jsexcept_t *ei, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 7e3df38..1e3a6dc 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -524,6 +524,23 @@ tmp = arr.concat([2]); ok(tmp.length === 3, "tmp.length = " + tmp.length); ok(tmp[1] === undefined, "tmp[1] = " + tmp[1]);
+arr = [1,false,'a',null,undefined,'a']; +ok(arr.slice(0,6).toString() === "1,false,a,,,a", "arr.slice(0,6).toString() = " + arr.slice(0,6)); +ok(arr.slice(0,6).length === 6, "arr.slice(0,6).length = " + arr.slice(0,6).length); +ok(arr.slice().toString() === "1,false,a,,,a", "arr.slice().toString() = " + arr.slice()); +ok(arr.slice("abc").toString() === "1,false,a,,,a", "arr.slice("abc").toString() = " + arr.slice("abc")); +ok(arr.slice(3,8).toString() === ",,a", "arr.slice(3,8).toString() = " + arr.slice(3,8)); +ok(arr.slice(3,8).length === 3, "arr.slice(3,8).length = " + arr.slice(3,8).length); +ok(arr.slice(1).toString() === "false,a,,,a", "arr.slice(1).toString() = " + arr.slice(1)); +ok(arr.slice(-2).toString() === ",a", "arr.slice(-2).toString() = " + arr.slice(-2)); +ok(arr.slice(3,1).toString() === "", "arr.slice(3,1).toString() = " + arr.slice(3,1)); +tmp = arr.slice(0,6); +for(var i=0; i < arr.length; i++) + ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]); +arr[12] = 2; +ok(arr.slice(5).toString() === "a,,,,,,,2", "arr.slice(5).toString() = " + arr.slice(5).toString()); +ok(arr.slice(5).length === 8, "arr.slice(5).length = " + arr.slice(5).length); + var num = new Number(2); ok(num.toString() === "2", "num(2).toString !== 2"); var num = new Number();