From b3c318bffd951d7ea4b35bbc2a3c8d6c6d190716 Mon Sep 17 00:00:00 2001 From: suke Date: Sun, 27 Dec 2009 01:51:54 +0000 Subject: * ext/win32ole/win32ole.c (foleparam_initialize): add foleparam_initialize to check argument of WIN32OLE_PARAM.new * test/win32ole/test_win32ole_param.rb (test_s_new): add some assertion to test WIN32OLE_PARAM.new git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26184 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++ ext/win32ole/win32ole.c | 76 +++++++++++++++++++++++++++++++++++- test/win32ole/test_win32ole_param.rb | 17 +++++++- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb040e4c97..62d750480b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sun Dec 27 10:45:00 2009 Masaki Suketa + + * ext/win32ole/win32ole.c (foleparam_initialize): add foleparam_initialize + to check argument of WIN32OLE_PARAM.new + + * test/win32ole/test_win32ole_param.rb (test_s_new): add some assertion + to test WIN32OLE_PARAM.new + Sun Dec 27 09:41:54 2009 Yuki Sonoda (Yugui) * tool/rbinstall.rb (install?(:local, :comm, :bin, :'bin-comm')): diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 080d3aa2d2..77b66443f5 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -509,6 +509,10 @@ static VALUE folemethod_size_opt_params(VALUE self); static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index); static VALUE folemethod_params(VALUE self); static VALUE folemethod_inspect(VALUE self); +static VALUE foleparam_s_allocate(VALUE klass); +static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index); +static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n); +static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n); static VALUE foleparam_name(VALUE self); static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index); static VALUE foleparam_ole_type(VALUE self); @@ -2489,7 +2493,7 @@ ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self) continue; pName = ole_wc2mb(bstr); val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue)); - *pName = toupper(*pName); + *pName = toupper((int)*pName); id = rb_intern(pName); if (rb_is_const_id(id)) { rb_define_const(klass, pName, val); @@ -7159,6 +7163,74 @@ folemethod_inspect(VALUE self) * WIN32OLE_PARAM objects represent param information of * the OLE method. */ +static VALUE foleparam_s_allocate(VALUE klass) +{ + struct oleparamdata *pparam; + VALUE obj; + obj = Data_Make_Struct(klass, + struct oleparamdata, + 0, oleparam_free, pparam); + pparam->pTypeInfo = NULL; + pparam->method_index = 0; + pparam->index = 0; + return obj; +} + +static VALUE +oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index) +{ + FUNCDESC *pFuncDesc; + HRESULT hr; + BSTR *bstrs; + UINT len; + struct oleparamdata *pparam; + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if (FAILED(hr)) + ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc"); + + len = 0; + bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1); + hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, + bstrs, pFuncDesc->cParams + 1, + &len); + if (FAILED(hr)) { + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames"); + } + SysFreeString(bstrs[0]); + if (param_index < 1 || len <= (UINT)param_index) + { + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + rb_raise(rb_eIndexError, "index of param must be in 1..%d", len); + } + + Data_Get_Struct(self, struct oleparamdata, pparam); + pparam->pTypeInfo = pTypeInfo; + OLE_ADDREF(pTypeInfo); + pparam->method_index = method_index; + pparam->index = param_index - 1; + rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index])); + + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return self; +} + +static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n) +{ + struct olemethoddata *pmethod; + Data_Get_Struct(olemethod, struct olemethoddata, pmethod); + return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n); +} + +static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n) +{ + int idx; + if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) { + rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object"); + } + idx = FIX2INT(n); + return oleparam_ole_param(self, olemethod, idx); +} /* * call-seq: @@ -9127,6 +9199,8 @@ Init_win32ole() rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0); cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject); + rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate); + rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2); rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0); rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0); rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0); diff --git a/test/win32ole/test_win32ole_param.rb b/test/win32ole/test_win32ole_param.rb index 3b831c3937..1a4eeff301 100644 --- a/test/win32ole/test_win32ole_param.rb +++ b/test/win32ole/test_win32ole_param.rb @@ -33,9 +33,24 @@ if defined?(WIN32OLE_PARAM) assert_raise(ArgumentError) { WIN32OLE_PARAM.new("hoge") } + ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject") + m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile") + assert_raise(IndexError) { + WIN32OLE_PARAM.new(m_copyfile, 4); + } + assert_raise(IndexError) { + WIN32OLE_PARAM.new(m_copyfile, 0); + } + assert_raise(IndexError) { + WIN32OLE_PARAM.new(m_copyfile, 0); + } + param = WIN32OLE_PARAM.new(m_copyfile, 3) + assert_equal("OverWriteFiles", param.name) + assert_equal(WIN32OLE_PARAM, param.class) + assert_equal(true, param.default) + assert_equal("#", param.inspect) end - def test_name assert_equal('URL', @param_url.name) assert_equal('Flags', @param_flags.name) -- cgit v1.2.3