[前][次][番号順一覧][スレッド一覧]

ruby-changes:34702

From: suke <ko1@a...>
Date: Fri, 11 Jul 2014 20:51:02 +0900 (JST)
Subject: [ruby-changes:34702] suke:r46785 (trunk): * ext/win32ole/win32ole.c: add WIN32OLE_RECORD class to support

suke	2014-07-11 20:50:51 +0900 (Fri, 11 Jul 2014)

  New Revision: 46785

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46785

  Log:
    * ext/win32ole/win32ole.c: add WIN32OLE_RECORD class to support
      VT_RECORD OLE variables.

  Modified files:
    trunk/ChangeLog
    trunk/ext/win32ole/win32ole.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46784)
+++ ChangeLog	(revision 46785)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jul 11 20:49:10 2014  Masaki Suketa <masaki.suketa@n...>
+
+	* ext/win32ole/win32ole.c: add WIN32OLE_RECORD class to support
+	  VT_RECORD OLE variables.
+
 Fri Jul 11 17:15:08 2014  SHIBATA Hiroshi  <shibata.hiroshi@g...>
 
 	* lib/abbrev.rb: remove executable.
Index: ext/win32ole/win32ole.c
===================================================================
--- ext/win32ole/win32ole.c	(revision 46784)
+++ ext/win32ole/win32ole.c	(revision 46785)
@@ -143,7 +143,7 @@ const IID IID_IMultiLanguage2 = {0xDCCFC https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L143
 
 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
 
-#define WIN32OLE_VERSION "1.5.6"
+#define WIN32OLE_VERSION "1.5.7"
 
 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
     (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -211,6 +211,7 @@ VALUE cWIN32OLE_VARIANT; https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L211
 VALUE eWIN32OLERuntimeError;
 VALUE mWIN32OLE_VARIANT;
 VALUE cWIN32OLE_PROPERTY;
+VALUE cWIN32OLE_RECORD;
 
 static VALUE ary_ole_event;
 static ID id_events;
@@ -595,6 +596,9 @@ static VALUE folevariant_ary_aset(int ar https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L596
 static VALUE folevariant_value(VALUE self);
 static VALUE folevariant_vartype(VALUE self);
 static VALUE folevariant_set_value(VALUE self, VALUE val);
+static VALUE fole_record_to_h(VALUE self);
+static VALUE fole_record_typename(VALUE self);
+static VALUE fole_record_method_missing(VALUE self, VALUE member);
 static void init_enc2cp(void);
 static void free_enc2cp(void);
 
@@ -2333,6 +2337,53 @@ ole_variant2val(VARIANT *pvar) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2337
         obj =  vtdate2rbtime(date);
         break;
     }
+
+    case VT_RECORD:
+    {
+        IRecordInfo *pri = V_RECORDINFO(pvar);
+        void *prec = V_RECORD(pvar);
+        HRESULT hr;
+        BSTR bstr;
+        BSTR *bstrs;
+        ULONG count = 0;
+        ULONG i;
+        VARIANT var;
+        void *pdata = NULL;
+        VALUE fields = Qnil;
+        VALUE val;
+        VALUE key;
+
+        obj = rb_funcall(cWIN32OLE_RECORD, rb_intern("new"), 0);
+        hr = pri->lpVtbl->GetName(pri, &bstr);
+        if (SUCCEEDED(hr)) {
+            rb_ivar_set(obj, rb_intern("typename"), WC2VSTR(bstr));
+        }
+
+        hr = pri->lpVtbl->GetFieldNames(pri, &count, NULL);
+        if (FAILED(hr) || count == 0)
+            break;
+        bstrs = ALLOCA_N(BSTR, count);
+        hr = pri->lpVtbl->GetFieldNames(pri, &count, bstrs);
+        if (FAILED(hr)) {
+            break;
+        }
+
+        fields = rb_hash_new();
+        rb_ivar_set(obj, rb_intern("fields"), fields);
+        for (i = 0; i < count; i++) {
+            pdata = NULL;
+            VariantInit(&var);
+            hr = pri->lpVtbl->GetFieldNoCopy(pri, prec, bstrs[i], &var, &pdata);
+            if (FAILED(hr)) {
+                break;
+            }
+            val = ole_variant2val(&var);
+            key = WC2VSTR(bstrs[i]);
+            rb_hash_aset(fields, key, val);
+        }
+        break;
+    }
+
     case VT_CY:
     default:
         {
@@ -9106,6 +9157,51 @@ folevariant_set_value(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L9157
     return Qnil;
 }
 
+/*
+ *  call-seq:
+ *     WIN32OLE_RECORD#to_h #=> Ruby Hash object.
+ *
+ *  Returns Ruby Hash object which represents VT_RECORD variable.
+ *  The keys of Hash object are member names of VT_RECORD OLE variable and 
+ *  the values of Hash object are values of VT_RECORD OLE variable.
+ *
+ */
+static VALUE 
+fole_record_to_h(VALUE self)
+{
+    return rb_ivar_get(self, rb_intern("fields"));
+}
+
+/*
+ *  call-seq:
+ *     WIN32OLE_RECORD#typename #=> String object
+ *
+ *  Returns the type name of VT_RECORD OLE variable.
+ */
+static VALUE 
+fole_record_typename(VALUE self)
+{
+    return rb_ivar_get(self, rb_intern("typename"));
+}
+
+/*
+ *  call-seq:
+ *     WIN32OLE_RECORD#method_missing(name)
+ *
+ *  Returns value specified by VT_RECORD OLE variable member name.
+ */
+static VALUE
+fole_record_method_missing(VALUE self, VALUE member)
+{
+    
+    VALUE fields = rb_ivar_get(self, rb_intern("fields"));
+    VALUE val = rb_hash_aref(fields, rb_to_id(member));
+    if (val != Qnil) {
+        return val;
+    }
+    return rb_call_super(0, 0);
+}
+
 static void
 init_enc2cp(void)
 {
@@ -9356,6 +9452,11 @@ Init_win32ole(void) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L9452
     rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
     rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
 
+    cWIN32OLE_RECORD = rb_define_class("WIN32OLE_RECORD", rb_cObject);
+    rb_define_method(cWIN32OLE_RECORD, "to_h", fole_record_to_h, 0);
+    rb_define_method(cWIN32OLE_RECORD, "typename", fole_record_typename, 0);
+    rb_define_method(cWIN32OLE_RECORD, "method_missing", fole_record_method_missing, 1);
+
     eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
 
     init_enc2cp();

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]