summaryrefslogtreecommitdiff
path: root/lib/ffi/struct_layout_builder.rb
diff options
context:
space:
mode:
authorWayne Meissner <wmeissner@gmail.com>2010-05-22 10:00:25 +1000
committerWayne Meissner <wmeissner@gmail.com>2010-05-22 10:00:25 +1000
commitdaa6030da4fc0f5b8d7d4540d42bb8632cb1c3fa (patch)
treeeb32dcc81fa9637889175e3b23bc3788b16f62c9 /lib/ffi/struct_layout_builder.rb
parent8e6781fd6d38a9aa2d7d6469bc89a3bfa6c2938f (diff)
downloadffi-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.rb76
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