From 6057695c87cf8281f3ff9aa37cfdf1c317e1f9c1 Mon Sep 17 00:00:00 2001 From: suke Date: Sat, 6 Sep 2014 07:52:04 +0000 Subject: * ext/win32ole/win32ole_variant.c (ole_val2variant_err, ole_val2variantdata, Init_win32ole_variant): support VT_ERROR variant with error code. add WIN32OLE_VARIANT::NoParam. * test/win32ole/test_win32ole_variant.rb(test_c_noparam, test_vt_error_noparam): ditto. * ext/win32ole/win32ole.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47432 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/win32ole/win32ole.c | 2 +- ext/win32ole/win32ole_variant.c | 45 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) (limited to 'ext/win32ole') diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index fee197dbce..3e037c52d8 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -26,7 +26,7 @@ const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}}; #endif -#define WIN32OLE_VERSION "1.8.0" +#define WIN32OLE_VERSION "1.8.1" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); diff --git a/ext/win32ole/win32ole_variant.c b/ext/win32ole/win32ole_variant.c index 21de9b7264..b0cc5ee5df 100644 --- a/ext/win32ole/win32ole_variant.c +++ b/ext/win32ole/win32ole_variant.c @@ -2,6 +2,7 @@ static void olevariant_free(struct olevariantdata *pvar); static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar); +static void ole_val2variant_err(VALUE val, VARIANT *var); static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt); static VALUE folevariant_s_allocate(VALUE klass); static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt); @@ -83,6 +84,13 @@ ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar) ole_set_byref(&(pvar->realvar), &(pvar->var), vt); } #endif + } else if ( (vt & ~VT_BYREF) == VT_ERROR) { + ole_val2variant_err(val, &(pvar->realvar)); + if (vt & VT_BYREF) { + ole_set_byref(&(pvar->realvar), &(pvar->var), vt); + } else { + hr = VariantCopy(&(pvar->var), &(pvar->realvar)); + } } else { if (val == Qnil) { V_VT(&(pvar->var)) = vt; @@ -121,6 +129,24 @@ ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar) } } +static void +ole_val2variant_err(VALUE val, VARIANT *var) +{ + VALUE v = val; + if (rb_obj_is_kind_of(v, cWIN32OLE_VARIANT)) { + v = folevariant_value(v); + } + if (TYPE(v) != T_FIXNUM && TYPE(v) != T_BIGNUM && v != Qnil) { + rb_raise(eWIN32OLERuntimeError, "failed to convert VT_ERROR VARIANT:`%"PRIsVALUE"'", rb_inspect(v)); + } + V_VT(var) = VT_ERROR; + if (v != Qnil) { + V_ERROR(var) = NUM2LONG(val); + } else { + V_ERROR(var) = 0; + } +} + static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt) { @@ -654,15 +680,28 @@ Init_win32ole_variant() /* * represents VT_EMPTY OLE object. */ - rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY))); + rb_define_const(cWIN32OLE_VARIANT, "Empty", + rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY))); /* * represents VT_NULL OLE object. */ - rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL))); + rb_define_const(cWIN32OLE_VARIANT, "Null", + rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL))); /* * represents Nothing of VB.NET or VB. */ - rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH))); + rb_define_const(cWIN32OLE_VARIANT, "Nothing", + rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH))); + + /* + * represents VT_ERROR variant with DISP_E_PARAMNOTFOUND. + * This constants is used for not specified parameter. + * + * fso = WIN32OLE.new("Scripting.FileSystemObject") + * fso.openTextFile(filename, WIN32OLE_VARIANT::NoParam, false) + */ + rb_define_const(cWIN32OLE_VARIANT, "NoParam", + rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, INT2NUM(DISP_E_PARAMNOTFOUND), INT2FIX(VT_ERROR))); } -- cgit v1.2.3