Module: wine Branch: master Commit: f62dd2a9fdc2a768205f93177285e89173caa093 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f62dd2a9fdc2a768205f931772...
Author: Jacek Caban jacek@codeweavers.com Date: Sun Sep 21 15:36:26 2008 +0200
jscript: Added Array.join implementation.
---
dlls/jscript/array.c | 130 +++++++++++++++++++++++++++++++++++++++++++- dlls/jscript/dispex.c | 28 ++++++++++ dlls/jscript/jscript.h | 6 ++ dlls/jscript/tests/api.js | 11 ++++ 4 files changed, 172 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 18ee3f5..944c0e8 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -47,6 +47,7 @@ static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
+const WCHAR default_separatorW[] = {',',0};
static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) @@ -75,11 +76,134 @@ static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM return E_NOTIMPL; }
+static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHAR *sep, VARIANT *retv, + jsexcept_t *ei, IServiceProvider *caller) +{ + BSTR *str_tab, ret = NULL; + VARIANT var; + DWORD i; + HRESULT hres = E_FAIL; + + if(!length) { + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = SysAllocStringLen(NULL, 0); + if(!V_BSTR(retv)) + return E_OUTOFMEMORY; + } + return S_OK; + } + + str_tab = heap_alloc_zero(length * sizeof(BSTR)); + if(!str_tab) + return E_OUTOFMEMORY; + + for(i=0; i < length; i++) { + hres = jsdisp_propget_idx(array, i, lcid, &var, ei, caller); + if(FAILED(hres)) + break; + + if(V_VT(&var) != VT_EMPTY && V_VT(&var) != VT_NULL) + hres = to_string(array->ctx, &var, ei, str_tab+i); + VariantClear(&var); + if(FAILED(hres)) + break; + } + + if(SUCCEEDED(hres)) { + DWORD seplen = 0, len = 0; + WCHAR *ptr; + + seplen = strlenW(sep); + + if(str_tab[0]) + len = SysStringLen(str_tab[0]); + for(i=1; i < length; i++) + len += seplen + SysStringLen(str_tab[i]); + + ret = SysAllocStringLen(NULL, len); + if(ret) { + DWORD tmplen = 0; + + if(str_tab[0]) { + tmplen = SysStringLen(str_tab[0]); + memcpy(ret, str_tab[0], tmplen*sizeof(WCHAR)); + } + + ptr = ret + tmplen; + for(i=1; i < length; i++) { + if(seplen) { + memcpy(ptr, sep, seplen*sizeof(WCHAR)); + ptr += seplen; + } + + if(str_tab[i]) { + tmplen = SysStringLen(str_tab[i]); + memcpy(ptr, str_tab[i], tmplen*sizeof(WCHAR)); + ptr += tmplen; + } + } + *ptr=0; + }else { + hres = E_OUTOFMEMORY; + } + } + + for(i=0; i < length; i++) + SysFreeString(str_tab[i]); + heap_free(str_tab); + if(FAILED(hres)) + return hres; + + TRACE("= %s\n", debugstr_w(ret)); + + if(retv) { + if(!ret) { + ret = SysAllocStringLen(NULL, 0); + if(!ret) + return E_OUTOFMEMORY; + } + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + }else { + SysFreeString(ret); + } + + return S_OK; +} + +/* ECMA-262 3rd Edition 15.4.4.5 */ static HRESULT Array_join(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; + DWORD length; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + length = ((ArrayInstance*)dispex)->length; + }else { + FIXME("dispid is not Array\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp)) { + BSTR sep; + + hres = to_string(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &sep); + if(FAILED(hres)) + return hres; + + hres = array_join(dispex, lcid, length, sep, retv, ei, caller); + + SysFreeString(sep); + }else { + hres = array_join(dispex, lcid, length, default_separatorW, retv, ei, caller); + } + + return hres; }
static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 1c643f6..7f7dd8c 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -931,6 +931,34 @@ HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce return hres; }
+static HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIANT *var, + jsexcept_t *ei, IServiceProvider *caller) +{ + DISPPARAMS dp = {NULL, NULL, 0, 0}; + dispex_prop_t *prop; + HRESULT hres; + + hres = find_prop_name_prot(obj, name, FALSE, &prop); + if(FAILED(hres)) + return hres; + + V_VT(var) = VT_EMPTY; + if(!prop) + return S_OK; + + return prop_get(obj, prop, lcid, &dp, var, ei, caller); +} + +HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller) +{ + WCHAR buf[12]; + + static const WCHAR formatW[] = {'%','d',0}; + + sprintfW(buf, formatW, idx); + return jsdisp_propget_name(obj, buf, lcid, var, ei, caller); +} + HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { DISPPARAMS dp = {NULL,NULL,0,0}; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 6c4e272..1857459 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -126,6 +126,7 @@ HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvide HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*,DispatchEx**);
@@ -208,6 +209,11 @@ static inline DWORD arg_cnt(const DISPPARAMS *dp) return dp->cArgs - dp->cNamedArgs; }
+static inline BOOL is_class(DispatchEx *jsdisp, jsclass_t class) +{ + return jsdisp->builtin_info->class == class; +} + static inline void num_set_val(VARIANT *v, DOUBLE d) { if(d == (DOUBLE)(INT)d) { diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index c76a485..f331670 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -68,4 +68,15 @@ ok(arr.push(true, 'b', false) === 10, "arr.push(true, 'b', false) !== 10"); ok(arr[8] === "b", "arr[8] != 'b'"); ok(arr.length === 10, "arr.length != 10");
+arr = [1,2,null,false,undefined,,"a"]; + +tmp = arr.join(); +ok(tmp === "1,2,,false,,,a", "arr.join() = " + tmp); +tmp = arr.join(";"); +ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp); +tmp = arr.join(";","test"); +ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp); +tmp = arr.join(""); +ok(tmp === "12falsea", "arr.join('') = " + tmp); + reportSuccess();