Jacek Caban : jscript: Added Array.concat implementation.

Alexandre Julliard julliard at winehq.org
Mon Sep 22 07:04:08 CDT 2008


Module: wine
Branch: master
Commit: 5fa649cae6c95114ad7ecaaae216b4b9c8262be0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5fa649cae6c95114ad7ecaaae216b4b9c8262be0

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sun Sep 21 15:39:18 2008 +0200

jscript: Added Array.concat implementation.

---

 dlls/jscript/array.c      |   85 +++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/api.js |   17 +++++++++
 2 files changed, 99 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index 11ae558..4dd59be 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -69,11 +69,90 @@ static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
     return S_OK;
 }
 
+static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len, LCID lcid,
+        jsexcept_t *ei, IServiceProvider *caller)
+{
+    VARIANT var;
+    DWORD i;
+    HRESULT hres;
+
+    for(i=0; i < obj->length; i++) {
+        hres = jsdisp_propget_idx(&obj->dispex, i, lcid, &var, ei, caller);
+        if(hres == DISP_E_UNKNOWNNAME)
+            continue;
+        if(FAILED(hres))
+            return hres;
+
+        hres = jsdisp_propput_idx(array, *len+i, lcid, &var, ei, caller);
+        VariantClear(&var);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    *len += obj->length;
+    return S_OK;
+}
+
+static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, LCID lcid, jsexcept_t *ei, IServiceProvider *caller)
+{
+    DispatchEx *jsobj;
+    VARIANT var;
+    HRESULT hres;
+
+    jsobj = iface_to_jsdisp((IUnknown*)obj);
+    if(jsobj) {
+        if(is_class(jsobj, JSCLASS_ARRAY)) {
+            hres = concat_array(array, (ArrayInstance*)jsobj, len, lcid, ei, caller);
+            jsdisp_release(jsobj);
+            return hres;
+        }
+        jsdisp_release(jsobj);
+    }
+
+    V_VT(&var) = VT_DISPATCH;
+    V_DISPATCH(&var) = obj;
+    return jsdisp_propput_idx(array, (*len)++, lcid, &var, ei, caller);
+}
+
 static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
-        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    DispatchEx *ret;
+    DWORD len = 0;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = create_array(dispex->ctx, 0, &ret);
+    if(FAILED(hres))
+        return hres;
+
+    hres = concat_obj(ret, (IDispatch*)_IDispatchEx_(dispex), &len, lcid, ei, caller);
+    if(SUCCEEDED(hres)) {
+        VARIANT *arg;
+        DWORD i;
+
+        for(i=0; i < arg_cnt(dp); i++) {
+            arg = get_arg(dp, i);
+            if(V_VT(arg) == VT_DISPATCH)
+                hres = concat_obj(ret, V_DISPATCH(arg), &len, lcid, ei, caller);
+            else
+                hres = jsdisp_propput_idx(ret, len++, lcid, arg, ei, caller);
+            if(FAILED(hres))
+                break;
+        }
+    }
+
+    if(FAILED(hres))
+        return hres;
+
+    if(retv) {
+        V_VT(retv) = VT_DISPATCH;
+        V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
+    }else {
+        jsdisp_release(ret);
+    }
+    return S_OK;
 }
 
 static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHAR *sep, VARIANT *retv,
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 9fa392e..0dfa178 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -104,6 +104,23 @@ ok(arr.sort() === arr, "arr.sort() !== arr");
 for(var i=0; i < arr.length; i++)
     ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]);
 
+var num = new Number(6);
+arr = [0,1,2];
+tmp = arr.concat(3, [4,5], num);
+ok(tmp !== arr, "tmp === arr");
+for(var i=0; i<6; i++)
+    ok(tmp[i] === i, "tmp[" + i + "] = " + tmp[i]);
+ok(tmp[6] === num, "tmp[6] !== num");
+ok(tmp.length === 7, "tmp.length = " + tmp.length);
+
+arr = [].concat();
+ok(arr.length === 0, "arr.length = " + arr.lrngth);
+
+arr = [1,];
+tmp = arr.concat([2]);
+ok(tmp.length === 3, "tmp.length = " + tmp.length);
+ok(tmp[1] === undefined, "tmp[1] = " + tmp[1]);
+
 var num = new Number(2);
 ok(num.toString() === "2", "num(2).toString !== 2");
 var num = new Number();




More information about the wine-cvs mailing list