From 7864b823c6fa1c46d239383aab678bc01d5b1d70 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 7 Jan 2019 23:22:15 +0100 Subject: [PATCH 1/3] Move FFI::DataConverter to Ruby * Include DataConverter in StructByReference in Ruby code to simplify ordering. --- ext/ffi_c/DataConverter.c | 91 ----------------------------------- ext/ffi_c/StructByReference.c | 8 +-- ext/ffi_c/ffi.c | 3 -- ext/ffi_c/rbffi.h | 2 - lib/ffi/data_converter.rb | 37 ++++++++++++++ lib/ffi/ffi.rb | 1 + lib/ffi/struct.rb | 5 ++ 7 files changed, 44 insertions(+), 103 deletions(-) delete mode 100644 ext/ffi_c/DataConverter.c create mode 100644 lib/ffi/data_converter.rb diff --git a/ext/ffi_c/DataConverter.c b/ext/ffi_c/DataConverter.c deleted file mode 100644 index 2d5b82743..000000000 --- a/ext/ffi_c/DataConverter.c +++ /dev/null @@ -1,91 +0,0 @@ - -#include - -#include -#include "rbffi.h" - -#include "Type.h" -#include "MappedType.h" - - -VALUE rbffi_DataConverterClass = Qnil; -static ID id_native_type_ivar; - -/* - * Get native type. - * @overload native_type(type) - * @param [String, Symbol, Type] type - * @return [Type] - * Get native type from +type+. - * @overload native_type - * @raise {NotImplementedError} This method must be overriden. - */ -static VALUE -conv_native_type(int argc, VALUE* argv, VALUE self) -{ - if (argc == 0) { - if (!rb_ivar_defined(self, id_native_type_ivar)) { - rb_raise(rb_eNotImpError, "native_type method not overridden and no native_type set"); - } - - return rb_ivar_get(self, id_native_type_ivar); - - } else if (argc == 1) { - VALUE type = rbffi_Type_Find(argv[0]); - - rb_ivar_set(self, id_native_type_ivar, type); - - return type; - - } else { - rb_raise(rb_eArgError, "incorrect arguments"); - } -} - -/* - * call-seq: to_native(value, ctx) - * @param value - * @param ctx - * @return [value] - * Convert to a native type. - */ -static VALUE -conv_to_native(VALUE self, VALUE value, VALUE ctx) -{ - return value; -} - -/* - * call-seq: from_native(value, ctx) - * @param value - * @param ctx - * @return [value] - * Convert from a native type. - */ -static VALUE -conv_from_native(VALUE self, VALUE value, VALUE ctx) -{ - return value; -} - - - -void -rbffi_DataConverter_Init(VALUE moduleFFI) -{ - /* - * Document-module: FFI::DataConverter - * This module is used to extend somes classes and give then a common API. - * - * Most of methods defined here must be overriden. - */ - rbffi_DataConverterClass = rb_define_module_under(moduleFFI, "DataConverter"); - - rb_define_method(rbffi_DataConverterClass, "native_type", conv_native_type, -1); - rb_define_method(rbffi_DataConverterClass, "to_native", conv_to_native, 2); - rb_define_method(rbffi_DataConverterClass, "from_native", conv_from_native, 2); - - id_native_type_ivar = rb_intern("@native_type"); -} - - diff --git a/ext/ffi_c/StructByReference.c b/ext/ffi_c/StructByReference.c index 73e51116e..a27eff0a0 100644 --- a/ext/ffi_c/StructByReference.c +++ b/ext/ffi_c/StructByReference.c @@ -172,14 +172,9 @@ sbr_from_native(VALUE self, VALUE value, VALUE ctx) void rbffi_StructByReference_Init(VALUE moduleFFI) { - /* - * Document-class: FFI::StructByReference - * This class includes {FFI::DataConverter} module. - */ rbffi_StructByReferenceClass = rb_define_class_under(moduleFFI, "StructByReference", rb_cObject); rb_global_variable(&rbffi_StructByReferenceClass); - rb_include_module(rbffi_StructByReferenceClass, rb_const_get(moduleFFI, rb_intern("DataConverter"))); - + rb_define_alloc_func(rbffi_StructByReferenceClass, sbr_allocate); rb_define_method(rbffi_StructByReferenceClass, "initialize", sbr_initialize, 1); rb_define_method(rbffi_StructByReferenceClass, "struct_class", sbr_struct_class, 0); @@ -187,4 +182,3 @@ rbffi_StructByReference_Init(VALUE moduleFFI) rb_define_method(rbffi_StructByReferenceClass, "to_native", sbr_to_native, 2); rb_define_method(rbffi_StructByReferenceClass, "from_native", sbr_from_native, 2); } - diff --git a/ext/ffi_c/ffi.c b/ext/ffi_c/ffi.c index ea9a05876..fc0b766d0 100644 --- a/ext/ffi_c/ffi.c +++ b/ext/ffi_c/ffi.c @@ -74,8 +74,6 @@ Init_ffi_c(void) /* FFI::Type needs to be initialized before most other classes */ rbffi_Type_Init(moduleFFI); - rbffi_DataConverter_Init(moduleFFI); - rbffi_ArrayType_Init(moduleFFI); rbffi_LastError_Init(moduleFFI); rbffi_Call_Init(moduleFFI); @@ -95,4 +93,3 @@ Init_ffi_c(void) rbffi_Types_Init(moduleFFI); rbffi_MappedType_Init(moduleFFI); } - diff --git a/ext/ffi_c/rbffi.h b/ext/ffi_c/rbffi.h index b6fe4774f..89b3e320b 100644 --- a/ext/ffi_c/rbffi.h +++ b/ext/ffi_c/rbffi.h @@ -44,7 +44,6 @@ extern void rbffi_Type_Init(VALUE ffiModule); extern void rbffi_Buffer_Init(VALUE ffiModule); extern void rbffi_Invoker_Init(VALUE ffiModule); extern void rbffi_Variadic_Init(VALUE ffiModule); -extern void rbffi_DataConverter_Init(VALUE ffiModule); extern VALUE rbffi_AbstractMemoryClass, rbffi_InvokerClass; extern int rbffi_type_size(VALUE type); extern void rbffi_Thread_Init(VALUE moduleFFI); @@ -54,4 +53,3 @@ extern void rbffi_Thread_Init(VALUE moduleFFI); #endif #endif /* RBFFI_RBFFI_H */ - diff --git a/lib/ffi/data_converter.rb b/lib/ffi/data_converter.rb new file mode 100644 index 000000000..4d67b5680 --- /dev/null +++ b/lib/ffi/data_converter.rb @@ -0,0 +1,37 @@ +module FFI + # This module is used to extend somes classes and give then a common API. + # + # Most of methods defined here must be overriden. + module DataConverter + # Get native type. + # + # @overload native_type(type) + # @param [String, Symbol, Type] type + # @return [Type] + # Get native type from +type+. + # + # @overload native_type + # @raise {NotImplementedError} This method must be overriden. + def native_type(type = nil) + if type + @native_type = FFI.find_type(type) + else + native_type = @native_type + unless native_type + raise NotImplementedError, 'native_type method not overridden and no native_type set' + end + native_type + end + end + + # Convert to a native type. + def to_native(value, ctx) + value + end + + # Convert from a native type. + def from_native(value, ctx) + value + end + end +end diff --git a/lib/ffi/ffi.rb b/lib/ffi/ffi.rb index 11d451f0a..7d9cc2d0f 100644 --- a/lib/ffi/ffi.rb +++ b/lib/ffi/ffi.rb @@ -29,6 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. require 'ffi/platform' +require 'ffi/data_converter' require 'ffi/types' require 'ffi/library' require 'ffi/errno' diff --git a/lib/ffi/struct.rb b/lib/ffi/struct.rb index bd11a0136..1f2adfdd8 100644 --- a/lib/ffi/struct.rb +++ b/lib/ffi/struct.rb @@ -368,4 +368,9 @@ def array_layout(builder, spec) end end end + + # This class includes the {FFI::DataConverter} module. + class StructByReference + include DataConverter + end end From 96bf421ad8a39c766697539678458d2a544f5444 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 7 Jan 2019 23:32:36 +0100 Subject: [PATCH 2/3] Remove no longer used rbffi_Type_Find() --- ext/ffi_c/Type.c | 18 ------------------ ext/ffi_c/Type.h | 1 - 2 files changed, 19 deletions(-) diff --git a/ext/ffi_c/Type.c b/ext/ffi_c/Type.c index 034482f2c..bc8285717 100644 --- a/ext/ffi_c/Type.c +++ b/ext/ffi_c/Type.c @@ -235,24 +235,6 @@ rbffi_Type_Lookup(VALUE name) return Qnil; } -/** - * rbffi_Type_Find() is like rbffi_Type_Lookup, but an error is raised if the - * type is not found. - */ -VALUE -rbffi_Type_Find(VALUE name) -{ - VALUE rbType = rbffi_Type_Lookup(name); - - if (!RTEST(rbType)) { - VALUE s = rb_inspect(name); - rb_raise(rb_eTypeError, "invalid type, %s", RSTRING_PTR(s)); - RB_GC_GUARD(s); - } - - return rbType; -} - void rbffi_Type_Init(VALUE moduleFFI) { diff --git a/ext/ffi_c/Type.h b/ext/ffi_c/Type.h index d5522ee8a..b81995acf 100644 --- a/ext/ffi_c/Type.h +++ b/ext/ffi_c/Type.h @@ -52,7 +52,6 @@ struct Type_ { extern VALUE rbffi_TypeClass; extern VALUE rbffi_Type_Lookup(VALUE type); -extern VALUE rbffi_Type_Find(VALUE type); #ifdef __cplusplus } From 516e8f8664b274bc73818bcc6f4658af9eadca11 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 11 Jan 2019 00:29:24 +0100 Subject: [PATCH 3/3] Add license header * The same as errno.rb. DataConverter.c was added by Wayne Meissner. --- lib/ffi/data_converter.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/ffi/data_converter.rb b/lib/ffi/data_converter.rb index 4d67b5680..1527588b7 100644 --- a/lib/ffi/data_converter.rb +++ b/lib/ffi/data_converter.rb @@ -1,3 +1,33 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + module FFI # This module is used to extend somes classes and give then a common API. #