diff options
author | Wayne Meissner <wmeissner@gmail.com> | 2010-05-22 10:00:25 +1000 |
---|---|---|
committer | Wayne Meissner <wmeissner@gmail.com> | 2010-05-22 10:00:25 +1000 |
commit | daa6030da4fc0f5b8d7d4540d42bb8632cb1c3fa (patch) | |
tree | eb32dcc81fa9637889175e3b23bc3788b16f62c9 /lib/ffi/struct_layout_builder.rb | |
parent | 8e6781fd6d38a9aa2d7d6469bc89a3bfa6c2938f (diff) | |
download | ffi-daa6030da4fc0f5b8d7d4540d42bb8632cb1c3fa.tar.gz |
Add custom data converters for parameter and return types
Diffstat (limited to 'lib/ffi/struct_layout_builder.rb')
-rw-r--r-- | lib/ffi/struct_layout_builder.rb | 76 |
1 files changed, 39 insertions, 37 deletions
diff --git a/lib/ffi/struct_layout_builder.rb b/lib/ffi/struct_layout_builder.rb index 4f45cc5..b1aecbc 100644 --- a/lib/ffi/struct_layout_builder.rb +++ b/lib/ffi/struct_layout_builder.rb @@ -90,43 +90,7 @@ module FFI # # If a FFI::Type type was passed in as the field arg, try and convert to a StructLayout::Field instance # - field = if !type.is_a?(StructLayout::Field) - - field_class = case - when type.is_a?(FFI::Type::Function) - StructLayout::Function - - when type.is_a?(FFI::Type::Struct) - StructLayout::InnerStruct - - when type.is_a?(FFI::Type::Array) - StructLayout::Array - - when type.is_a?(FFI::Enum) - StructLayout::Enum - - when NUMBER_TYPES.include?(type) - StructLayout::Number - - when type == FFI::Type::POINTER - StructLayout::Pointer - - when type == FFI::Type::STRING - StructLayout::String - - when type.is_a?(Class) && type < FFI::StructLayout::Field - type - - else - raise TypeError, "invalid struct field type #{type.inspect}" - end - - field_class.new(name, offset, type) - - else - type - end - + field = type.is_a?(StructLayout::Field) ? type : field_for_type(name, offset, type) @fields << field @alignment = [ @alignment, field.alignment ].max unless @packed @size = [ @size, field.size + (@union ? 0 : field.offset) ].max @@ -159,6 +123,44 @@ module FFI align + ((offset - 1) & ~(align - 1)); end + def field_for_type(name, offset, type) + field_class = case + when type.is_a?(FFI::Type::Function) + StructLayout::Function + + when type.is_a?(FFI::Type::Struct) + StructLayout::InnerStruct + + when type.is_a?(FFI::Type::Array) + StructLayout::Array + + when type.is_a?(FFI::Enum) + StructLayout::Enum + + when NUMBER_TYPES.include?(type) + StructLayout::Number + + when type == FFI::Type::POINTER + StructLayout::Pointer + + when type == FFI::Type::STRING + StructLayout::String + + when type.is_a?(Class) && type < FFI::StructLayout::Field + type + + when type.is_a?(DataConverter) + return StructLayout::Mapped.new(name, offset, FFI::Type::Mapped.new(type), field_for_type(name, offset, type.native_type)) + + when type.is_a?(FFI::Type::Mapped) + return StructLayout::Mapped.new(name, offset, type, field_for_type(name, offset, type.native_type)) + + else + raise TypeError, "invalid struct field type #{type.inspect}" + end + + field_class.new(name, offset, type) + end end end
\ No newline at end of file |