diff --git a/ChangeLog b/ChangeLog index 620552fa7e..0712c382a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sun Mar 19 09:46:30 2006 Masaki Suketa <masaki.suketa@nifty.ne.jp> + + * ext/win32ole/win32ole.c(ole_val2olevariantdata): change behavior + of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby + String object. + + * ext/win32ole/win32ole.c(folevariant_value): ditto. + + * ext/win32ole/tests/testOLEVARIANT.rb: ditto. + Wed Mar 15 16:51:11 2006 NAKAMURA Usaku <usa@ruby-lang.org> * lib/mkmf.rb (create_makefile): support libraries without *.so. @@ -9,7 +19,7 @@ Wed Mar 15 16:39:29 2006 GOTOU Yuuzou <gotoyuzo@notwork.org> Sun Mar 12 17:02:10 2006 Masaki Suketa <masaki.suketa@nifty.ne.jp> - * ext/win32ole/win32ole.c(ole_val2olevariantdata): support VT_VARIANT in + * ext/win32ole/win32ole.c(ole_val2olevariantdata): support VT_ARRAY in WIN32OLE_VARIANT.new(). * ext/win32ole/tests/testOLEVARIANT.rb: ditto. diff --git a/ext/win32ole/tests/testOLEVARIANT.rb b/ext/win32ole/tests/testOLEVARIANT.rb index d94eede2da..247ceb1f86 100644 --- a/ext/win32ole/tests/testOLEVARIANT.rb +++ b/ext/win32ole/tests/testOLEVARIANT.rb @@ -76,4 +76,23 @@ class TestWIN32OLE_VARIANT < Test::Unit::TestCase assert_equal([1.2, 2.3], obj.value) end + def test_create_vt_array_str2ui1array + obj = WIN32OLE_VARIANT.new("ABC", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1) + assert_equal("ABC", obj.value) + + obj = WIN32OLE_VARIANT.new([65, 0].pack("C*"), WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1) + assert_equal([65, 0].pack("C*"), obj.value) + + end + def test_create_vt_array_int + obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1) + assert_equal([65, 0].pack("C*"), obj.value) + + obj = WIN32OLE_VARIANT.new([65, 0]) + assert_equal([65, 0], obj.value) + + obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_ARRAY) + assert_equal([65, 0], obj.value) + end + end diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 0cab89bdce..e3912bcdad 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -79,7 +79,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "0.7.1" +#define WIN32OLE_VERSION "0.7.2" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -1124,12 +1124,30 @@ ole_val2olevariantdata(val, vtype, pvar) { HRESULT hr = S_OK; VARIANT var; - if (vtype & VT_ARRAY) { + + if (((vtype & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && TYPE(val) == T_STRING) { + long len = RSTRING(val)->len; + char *pdest = NULL; + SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len); + if (!psa) { + rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector"); + } + hr = SafeArrayAccessData(psa, (void **)&pdest); + if (SUCCEEDED(hr)) { + memcpy(pdest, RSTRING(val)->ptr, len); + SafeArrayUnaccessData(psa); + V_VT(&(pvar->realvar)) = vtype; + V_ARRAY(&(pvar->realvar)) = psa; + hr = VariantCopy(&(pvar->var), &(pvar->realvar)); + } else { + if (psa) + SafeArrayDestroy(psa); + } + } else if (vtype & VT_ARRAY) { VALUE val1; long dim = 0; int i = 0; - HRESULT hr; SAFEARRAYBOUND *psab = NULL; SAFEARRAY *psa = NULL; long *pub, *pid; @@ -7105,8 +7123,25 @@ folevariant_value(self) { struct olevariantdata *pvar; VALUE val = Qnil; + VARTYPE vt; Data_Get_Struct(self, struct olevariantdata, pvar); + val = ole_variant2val(&(pvar->var)); + vt = V_VT(&(pvar->var)); + + if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) { + SAFEARRAY *psa; + if (vt & VT_BYREF) { + psa = *V_ARRAYREF(&(pvar->var)); + } else { + psa = V_ARRAY(&(pvar->var)); + } + int dim = SafeArrayGetDim(psa); + if (dim == 1) { + VALUE args = rb_ary_new3(1, rb_str_new2("C*")); + val = rb_apply(val, rb_intern("pack"), args); + } + } return val; }