diff options
author | Wayne Meissner <wmeissner@gmail.com> | 2010-01-27 18:49:38 +1000 |
---|---|---|
committer | Wayne Meissner <wmeissner@gmail.com> | 2010-01-27 18:49:38 +1000 |
commit | f3611c44c84a757bc33d5981c05f0209bda709da (patch) | |
tree | 27a0befe4643c6f05b52cd79814e753425e13fe0 | |
parent | 3f96bbb61b2f17ba9761a1d02745101a60cd26e1 (diff) | |
download | ffi-f3611c44c84a757bc33d5981c05f0209bda709da.tar.gz |
Move inner struct field code into ruby
-rw-r--r-- | ext/ffi_c/Struct.c | 22 | ||||
-rw-r--r-- | ext/ffi_c/Struct.h | 2 | ||||
-rw-r--r-- | ext/ffi_c/StructLayout.c | 21 | ||||
-rw-r--r-- | lib/ffi/struct.rb | 12 |
4 files changed, 32 insertions, 25 deletions
diff --git a/ext/ffi_c/Struct.c b/ext/ffi_c/Struct.c index 503fc8f..ada9d55 100644 --- a/ext/ffi_c/Struct.c +++ b/ext/ffi_c/Struct.c @@ -429,13 +429,21 @@ struct_layout_builder_add_field(int argc, VALUE* argv, VALUE self) fargv[0] = rbName; fargv[1] = UINT2NUM(offset); fargv[2] = rbType; + if (rb_obj_is_kind_of(rbType, rbffi_FunctionTypeClass)) { + rbFieldClass = rbffi_StructLayoutFunctionFieldClass; + } else if (rb_obj_is_kind_of(rbType, rbffi_StructByValueClass)) { - rbFieldClass = rbffi_StructLayoutStructFieldClass; + + rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct")); + } else if (rb_obj_is_kind_of(rbType, rbffi_ArrayTypeClass)) { + rbFieldClass = rbffi_StructLayoutArrayFieldClass; + } else if (rb_obj_is_kind_of(rbType, rbffi_EnumTypeClass)) { + rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("Enum")); } else { @@ -461,7 +469,8 @@ static VALUE struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self) { StructLayoutBuilder* builder; - VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil, rbStructClass = Qnil; + VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil; + VALUE rbFieldClass = Qnil, rbStructClass = Qnil; VALUE fargv[3]; unsigned int size, alignment, offset; int nargs; @@ -484,7 +493,14 @@ struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self) fargv[0] = rbName; fargv[1] = UINT2NUM(offset); fargv[2] = rbType; - rbField = rb_class_new_instance(3, fargv, rbffi_StructLayoutStructFieldClass); + rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct")); + if (!RTEST(rbFieldClass)) { + rb_raise(rb_eRuntimeError, "could not locate StructLayout::InlineStruct"); + return Qnil; + } + + rbField = rb_class_new_instance(3, fargv, rbFieldClass); + store_field(builder, rbName, rbField, offset, size, alignment); return self; diff --git a/ext/ffi_c/Struct.h b/ext/ffi_c/Struct.h index 1b8df40..ef1ed6f 100644 --- a/ext/ffi_c/Struct.h +++ b/ext/ffi_c/Struct.h @@ -77,7 +77,7 @@ extern "C" { extern VALUE rbffi_StructClass, rbffi_StructLayoutClass; extern VALUE rbffi_StructLayoutFieldClass, rbffi_StructLayoutFunctionFieldClass; - extern VALUE rbffi_StructLayoutArrayFieldClass, rbffi_StructLayoutStructFieldClass; + extern VALUE rbffi_StructLayoutArrayFieldClass; extern VALUE rbffi_StructInlineArrayClass; extern VALUE rbffi_StructLayoutCharArrayClass; diff --git a/ext/ffi_c/StructLayout.c b/ext/ffi_c/StructLayout.c index 8d4b0a0..fb14719 100644 --- a/ext/ffi_c/StructLayout.c +++ b/ext/ffi_c/StructLayout.c @@ -53,7 +53,6 @@ static void struct_field_mark(StructField* ); VALUE rbffi_StructLayoutFieldClass = Qnil; VALUE rbffi_StructLayoutFunctionFieldClass = Qnil, rbffi_StructLayoutArrayFieldClass = Qnil; -VALUE rbffi_StructLayoutStructFieldClass = Qnil; VALUE rbffi_StructLayoutClass = Qnil; @@ -310,22 +309,6 @@ array_field_put(VALUE self, VALUE pointer, VALUE value) return value; } -static VALUE -inline_struct_field_get(VALUE self, VALUE pointer) -{ - StructField* f; - StructByValue* sbv; - VALUE rbPointer = Qnil, rbOffset = Qnil; - - Data_Get_Struct(self, StructField, f); - Data_Get_Struct(f->rbType, StructByValue, sbv); - - rbOffset = UINT2NUM(f->offset); - rbPointer = rb_funcall2(pointer, rb_intern("+"), 1, &rbOffset); - - return rb_class_new_instance(1, &rbPointer, sbv->rbStructClass); -} - static VALUE struct_layout_allocate(VALUE klass) @@ -475,9 +458,6 @@ rbffi_StructLayout_Init(VALUE moduleFFI) rbffi_StructLayoutFunctionFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Function", rbffi_StructLayoutFieldClass); rb_global_variable(&rbffi_StructLayoutFunctionFieldClass); - rbffi_StructLayoutStructFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "StructByValue", rbffi_StructLayoutFieldClass); - rb_global_variable(&rbffi_StructLayoutStructFieldClass); - rbffi_StructLayoutArrayFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Array", rbffi_StructLayoutFieldClass); rb_global_variable(&rbffi_StructLayoutArrayFieldClass); @@ -496,7 +476,6 @@ rbffi_StructLayout_Init(VALUE moduleFFI) rb_define_method(rbffi_StructLayoutArrayFieldClass, "get", array_field_get, 1); rb_define_method(rbffi_StructLayoutArrayFieldClass, "put", array_field_put, 2); - rb_define_method(rbffi_StructLayoutStructFieldClass, "get", inline_struct_field_get, 1); rb_define_alloc_func(rbffi_StructLayoutClass, struct_layout_allocate); rb_define_method(rbffi_StructLayoutClass, "initialize", struct_layout_initialize, 4); diff --git a/lib/ffi/struct.rb b/lib/ffi/struct.rb index b35b1ab..11924cc 100644 --- a/lib/ffi/struct.rb +++ b/lib/ffi/struct.rb @@ -52,6 +52,18 @@ module FFI end end + + class InlineStruct < Field + def get(ptr) + # FIXME: really should use ptr#slice(off, len) to limit the inner struct + # to just its part of the outer struct + type.struct_class.new(ptr + self.offset) + end + +# def put(ptr, value) +# raise TypeError, "wrong value type (expected #{type.struct_class}" unless value.is_a(type.struct_class) +# end + end end |