summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Meissner <wmeissner@gmail.com>2010-01-27 18:49:38 +1000
committerWayne Meissner <wmeissner@gmail.com>2010-01-27 18:49:38 +1000
commitf3611c44c84a757bc33d5981c05f0209bda709da (patch)
tree27a0befe4643c6f05b52cd79814e753425e13fe0
parent3f96bbb61b2f17ba9761a1d02745101a60cd26e1 (diff)
downloadffi-f3611c44c84a757bc33d5981c05f0209bda709da.tar.gz
Move inner struct field code into ruby
-rw-r--r--ext/ffi_c/Struct.c22
-rw-r--r--ext/ffi_c/Struct.h2
-rw-r--r--ext/ffi_c/StructLayout.c21
-rw-r--r--lib/ffi/struct.rb12
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