jscript: Added Array.join implementation.
This commit is contained in:
parent
34e82951c3
commit
f62dd2a9fd
|
@ -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 *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHAR *sep, VARIANT *retv,
|
||||
jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
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 *caller)
|
||||
{
|
||||
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,
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue