From 68daaab409c6b93423260756417756009cad38e6 Mon Sep 17 00:00:00 2001 From: suke Date: Sat, 27 Jan 2007 09:46:34 +0000 Subject: * ext/win32ole/win32ole.c (ole_val2olevariantdata): bug fix. WIN32OLE_VARIANT.new check that 1st argument should T_ARRAY when variant type is VT_ARRAY. * test/win32ole/test_win32ole_variant.rb: add some test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11581 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/win32ole/win32ole.c | 131 +++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 67 deletions(-) (limited to 'ext') diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 7fb0710205..44077576b5 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -80,7 +80,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "0.8.8" +#define WIN32OLE_VERSION "0.8.9" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -1008,65 +1008,62 @@ ole_val2ptr_variant(VALUE val, VARIANT *var) } static void -ole_var2ptr_var(VARIANT *var, VARIANT *pvar) +ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vtype) { - VARTYPE vt = V_VT(var); - V_VT(pvar) = V_VT(var) | VT_BYREF; - switch(vt) { - case VT_UI1: - V_UI1REF(pvar) = &V_UI1(var); - break; - case VT_I2: - V_I2REF(pvar) = &V_I2(var); - break; - case VT_I4: - V_I4REF(pvar) = &V_I4(var); - break; - case VT_UI4: - V_UI4REF(pvar) = &V_UI4(var); - break; -/* - case VT_I8: - V_I8REF(pvar) = &V_I8(var); - break; -*/ - case VT_R4: - V_R4REF(pvar) = &V_R4(var); - break; - case VT_R8: - V_R8REF(pvar) = &V_R8(var); - break; - case VT_CY: - V_CYREF(pvar) = &V_CY(var); - break; - case VT_DATE: - V_DATEREF(pvar) = &V_DATE(var); - break; - case VT_BSTR: - V_BSTRREF(pvar) = &V_BSTR(var); - break; - case VT_DISPATCH: - V_DISPATCHREF(pvar) = &V_DISPATCH(var); - break; - case VT_ERROR: - V_ERRORREF(pvar) = &V_ERROR(var); - break; - case VT_BOOL: - V_BOOLREF(pvar) = &V_BOOL(var); - break; -/* - case VT_VARIANT: - V_VARIANTREF(pvar) = &V_VARIANT(var); - break; -*/ - case VT_UNKNOWN: - V_UNKNOWNREF(pvar) = &V_UNKNOWN(var); - break; - case VT_ARRAY: - V_ARRAYREF(pvar) = &V_ARRAY(var); - break; - default: - break; + V_VT(var) = vtype; + if (vtype == (VT_VARIANT|VT_BYREF)) { + V_VARIANTREF(var) = realvar; + } else { + if (V_VT(realvar) != (vtype & ~VT_BYREF)) { + rb_raise(eWIN32OLE_RUNTIME_ERROR, "type mismatch"); + } + switch(vtype & ~VT_BYREF) { + case VT_UI1: + V_UI1REF(var) = &V_UI1(realvar); + break; + case VT_I2: + V_I2REF(var) = &V_I2(realvar); + break; + case VT_I4: + V_I4REF(var) = &V_I4(realvar); + break; + case VT_UI4: + V_UI4REF(var) = &V_UI4(realvar); + break; + case VT_R4: + V_R4REF(var) = &V_R4(realvar); + break; + case VT_R8: + V_R8REF(var) = &V_R8(realvar); + break; + case VT_CY: + V_CYREF(var) = &V_CY(realvar); + break; + case VT_DATE: + V_DATEREF(var) = &V_DATE(realvar); + break; + case VT_BSTR: + V_BSTRREF(var) = &V_BSTR(realvar); + break; + case VT_DISPATCH: + V_DISPATCHREF(var) = &V_DISPATCH(realvar); + break; + case VT_ERROR: + V_ERRORREF(var) = &V_ERROR(realvar); + break; + case VT_BOOL: + V_BOOLREF(var) = &V_BOOL(realvar); + break; + case VT_UNKNOWN: + V_UNKNOWNREF(var) = &V_UNKNOWN(realvar); + break; + case VT_ARRAY: + V_ARRAYREF(var) = &V_ARRAY(realvar); + break; + default: + rb_raise(eWIN32OLE_RUNTIME_ERROR, "unknown type specified:%d", vtype); + break; + } } } @@ -1103,6 +1100,8 @@ ole_val2olevariantdata(VALUE val, VARTYPE vtype, struct olevariantdata *pvar) SAFEARRAY *psa = NULL; long *pub, *pid; + Check_Type(val, T_ARRAY); + val1 = val; while(TYPE(val1) == T_ARRAY) { val1 = rb_ary_entry(val1, 0); @@ -1153,24 +1152,22 @@ ole_val2olevariantdata(VALUE val, VARTYPE vtype, struct olevariantdata *pvar) } } else { if (val == Qnil) { + V_VT(&(pvar->var)) = vtype; if (vtype == (VT_BYREF | VT_VARIANT)) { - V_VARIANTREF(&(pvar->var)) = &(pvar->realvar); - V_VT(&(pvar->var)) = vtype; + ole_set_byref(&(pvar->realvar), &(pvar->var), vtype); } else { V_VT(&(pvar->realvar)) = vtype & ~VT_BYREF; - V_VT(&(pvar->var)) = vtype; if (vtype & VT_BYREF) { - ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); + ole_set_byref(&(pvar->realvar), &(pvar->var), vtype); } } } else { ole_val2variant(val, &(pvar->realvar)); if (vtype == (VT_BYREF | VT_VARIANT)) { - V_VARIANTREF(&(pvar->var)) = &(pvar->realvar); - V_VT(&(pvar->var)) = vtype; + ole_set_byref(&(pvar->realvar), &(pvar->var), vtype); } else if (vtype & VT_BYREF) { if ( (vtype & ~VT_BYREF) == V_VT(&(pvar->realvar))) { - ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); + ole_set_byref(&(pvar->realvar), &(pvar->var), vtype); } else { VariantInit(&var); hr = VariantChangeTypeEx(&(var), &(pvar->realvar), @@ -1179,7 +1176,7 @@ ole_val2olevariantdata(VALUE val, VARTYPE vtype, struct olevariantdata *pvar) VariantClear(&(pvar->realvar)); hr = VariantCopy(&(pvar->realvar), &var); VariantClear(&var); - ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); + ole_set_byref(&(pvar->realvar), &(pvar->var), vtype); } } } else { -- cgit v1.2.3