From bac7c1ef3650a6b48e97094bef87d87ad4bd7a4a Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 12 Mar 2012 12:12:26 +0100 Subject: [PATCH] jscript: Added ChangeType implementation. --- dlls/jscript/jscript.c | 16 ++++++++-- dlls/jscript/jscript.h | 2 ++ dlls/jscript/jsutils.c | 70 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 4453bcc9caf..1ca5f9c065a 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -1002,8 +1002,20 @@ static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface) static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt) { JScript *This = impl_from_IVariantChangeType(iface); - FIXME("(%p)->(%p %s %x %d)\n", This, dst, debugstr_variant(src), lcid, vt); - return E_NOTIMPL; + HRESULT hres; + + TRACE("(%p)->(%p %s %x %d)\n", This, dst, debugstr_variant(src), lcid, vt); + + if(!This->ctx) { + FIXME("Object uninitialized\n"); + return E_UNEXPECTED; + } + + hres = VariantClear(dst); + if(FAILED(hres)) + return hres; + + return variant_change_type(This->ctx, dst, src, vt); } static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 2e2d57b14d7..47df16dd0e5 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -260,6 +260,8 @@ HRESULT to_uint32(script_ctx_t*,VARIANT*,jsexcept_t*,DWORD*) DECLSPEC_HIDDEN; HRESULT to_string(script_ctx_t*,VARIANT*,jsexcept_t*,BSTR*) DECLSPEC_HIDDEN; HRESULT to_object(script_ctx_t*,VARIANT*,IDispatch**) DECLSPEC_HIDDEN; +HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE); + BSTR int_to_bstr(int) DECLSPEC_HIDDEN; HRESULT double_to_bstr(double,BSTR*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index 2e1030eba43..6d77fe1ab29 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -657,6 +657,76 @@ HRESULT to_object(script_ctx_t *ctx, VARIANT *v, IDispatch **disp) return S_OK; } +HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt) +{ + jsexcept_t ei; + HRESULT hres; + + memset(&ei, 0, sizeof(ei)); + + switch(vt) { + case VT_I2: + case VT_I4: { + INT i; + + hres = to_int32(ctx, src, &ei, &i); + if(SUCCEEDED(hres)) { + if(vt == VT_I4) + V_I4(dst) = i; + else + V_I2(dst) = i; + } + break; + } + case VT_R8: + hres = to_number(ctx, src, &ei, dst); + if(SUCCEEDED(hres) && V_VT(dst) == VT_I4) + V_R8(dst) = V_I4(dst); + break; + case VT_R4: { + VARIANT n; + + hres = to_number(ctx, src, &ei, &n); + if(SUCCEEDED(hres)) + V_R4(dst) = num_val(&n); + break; + } + case VT_BOOL: { + VARIANT_BOOL b; + + hres = to_boolean(src, &b); + if(SUCCEEDED(hres)) + V_BOOL(dst) = b; + break; + } + case VT_BSTR: { + BSTR str; + + hres = to_string(ctx, src, &ei, &str); + if(SUCCEEDED(hres)) + V_BSTR(dst) = str; + break; + } + case VT_EMPTY: + hres = V_VT(src) == VT_EMPTY ? S_OK : E_NOTIMPL; + break; + case VT_NULL: + hres = V_VT(src) == VT_NULL ? S_OK : E_NOTIMPL; + break; + default: + FIXME("vt %d not implemented\n", vt); + hres = E_NOTIMPL; + } + + if(FAILED(hres)) { + VariantClear(&ei.var); + return hres; + } + + V_VT(dst) = vt; + return S_OK; +} + static inline JSCaller *impl_from_IServiceProvider(IServiceProvider *iface) { return CONTAINING_RECORD(iface, JSCaller, IServiceProvider_iface);