JezK
Edit File: classes.rb
module FFISpecs # # Callback fixtures # module LibTest callback :cbVrS8, [ ], :char callback :cbVrU8, [ ], :uchar callback :cbVrS16, [ ], :short callback :cbVrU16, [ ], :ushort callback :cbVrS32, [ ], :int callback :cbVrU32, [ ], :uint callback :cbVrL, [ ], :long callback :cbVrUL, [ ], :ulong callback :cbVrS64, [ ], :long_long callback :cbVrU64, [ ], :ulong_long callback :cbVrP, [], :pointer callback :cbCrV, [ :char ], :void callback :cbSrV, [ :short ], :void callback :cbIrV, [ :int ], :void callback :cbLrV, [ :long ], :void callback :cbULrV, [ :ulong ], :void callback :cbLrV, [ :long_long ], :void attach_function :testCallbackVrS8, :testClosureVrB, [ :cbVrS8 ], :char attach_function :testCallbackVrU8, :testClosureVrB, [ :cbVrU8 ], :uchar attach_function :testCallbackVrS16, :testClosureVrS, [ :cbVrS16 ], :short attach_function :testCallbackVrU16, :testClosureVrS, [ :cbVrU16 ], :ushort attach_function :testCallbackVrS32, :testClosureVrI, [ :cbVrS32 ], :int attach_function :testCallbackVrU32, :testClosureVrI, [ :cbVrU32 ], :uint attach_function :testCallbackVrL, :testClosureVrL, [ :cbVrL ], :long attach_function :testCallbackVrUL, :testClosureVrL, [ :cbVrUL ], :ulong attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer attach_function :testCallbackCrV, :testClosureBrV, [ :cbCrV, :char ], :void attach_variable :cbVrS8, :gvar_pointer, :cbVrS8 attach_variable :pVrS8, :gvar_pointer, :pointer attach_function :testGVarCallbackVrS8, :testClosureVrB, [ :pointer ], :char attach_function :testOptionalCallbackCrV, :testOptionalClosureBrV, [ :cbCrV, :char ], :void attach_function :testCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char callback :cb_return_type, [ :int ], :int callback :cb_lookup, [ ], :cb_return_type attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int callback :funcptr, [ :int ], :int attach_function :testReturnsFunctionPointer, [ ], :funcptr callback :cbS8rV, [ :char ], :void callback :cbU8rV, [ :uchar ], :void callback :cbS16rV, [ :short ], :void callback :cbU16rV, [ :ushort ], :void callback :cbS32rV, [ :int ], :void callback :cbU32rV, [ :uint ], :void callback :cbLrV, [ :long ], :void callback :cbULrV, [ :ulong ], :void callback :cbS64rV, [ :long_long ], :void attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void attach_function :testCallbackU8rV, :testClosureBrV, [ :cbU8rV, :uchar ], :void attach_function :testCallbackSrV, :testClosureSrV, [ :cbS16rV, :short ], :void attach_function :testCallbackU16rV, :testClosureSrV, [ :cbU16rV, :ushort ], :void attach_function :testCallbackIrV, :testClosureIrV, [ :cbS32rV, :int ], :void attach_function :testCallbackU32rV, :testClosureIrV, [ :cbU32rV, :uint ], :void attach_function :testCallbackLrV, :testClosureLrV, [ :cbLrV, :long ], :void attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void end # # Enum fixtures # module TestEnum0 extend FFI::Library end module TestEnum1 extend FFI::Library ffi_lib LIBRARY enum [:c1, :c2, :c3, :c4] enum [:c5, 42, :c6, :c7, :c8] enum [:c9, 42, :c10, :c11, 4242, :c12] enum [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242] attach_function :test_untagged_enum, [:int], :int end module TestEnum3 extend FFI::Library ffi_lib LIBRARY enum :enum_type1, [:c1, :c2, :c3, :c4] enum :enum_type2, [:c5, 42, :c6, :c7, :c8] enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12] enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242] attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1 attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2 attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3 attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4 end # # Errno fixtures # module LibTest attach_function :setLastError, [ :int ], :void end # # ManagedStruct fixtures # module LibTest attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer end class NoRelease < ManagedStruct layout :i, :int end class WhatClassAmI < ManagedStruct layout :i, :int def self.release; end end class PleaseReleaseMe < ManagedStruct layout :i, :int @@count = 0 def self.release @@count += 1 end def self.wait_gc(count) loop = 5 while loop > 0 && @@count < count loop -= 1 if RUBY_PLATFORM =~ /java/ require 'java' java.lang.System.gc else GC.start end sleep 0.05 if @@count < count end end end # # Number fixtures # module LibTest attach_function :ret_s8, [ :char ], :char attach_function :ret_u8, [ :uchar ], :uchar attach_function :ret_s16, [ :short ], :short attach_function :ret_u16, [ :ushort ], :ushort attach_function :ret_s32, [ :int ], :int attach_function :ret_u32, [ :uint ], :uint attach_function :ret_s64, [ :long_long ], :long_long attach_function :ret_u64, [ :ulong_long ], :ulong_long attach_function :ret_long, [ :long ], :long attach_function :ret_ulong, [ :ulong ], :ulong attach_function :set_s8, [ :char ], :void attach_function :get_s8, [ ], :char attach_function :set_float, [ :float ], :void attach_function :get_float, [ ], :float attach_function :set_double, [ :double ], :void attach_function :get_double, [ ], :double end PACK_VALUES = { 's8' => [ 0x12 ], 'u8' => [ 0x34 ], 's16' => [ 0x5678 ], 'u16' => [ 0x9abc ], 's32' => [ 0x7654321f ], 'u32' => [ 0xfee1babe ], 'sL' => [ 0x1f2e3d4c ], 'uL' => [ 0xf7e8d9ca ], 's64' => [ 0x1eafdeadbeefa1b2 ], #'f32' => [ 1.234567 ], # TODO: Why is this disabled? 'f64' => [ 9.87654321 ] } TYPE_MAP = { 's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort, 's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long, 'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double } TYPES = TYPE_MAP.keys module LibTest [ 's32', 'u32', 's64', 'u64' ].each do |rt| TYPES.each do |t1| TYPES.each do |t2| TYPES.each do |t3| begin attach_function "pack_#{t1}#{t2}#{t3}_#{rt}", [ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void rescue FFI::NotFoundError end end end end end end # # Pointer fixtures # module LibTest attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void end class ToPtrTest def initialize(ptr) @ptr = ptr end def to_ptr @ptr end end require 'delegate' class PointerDelegate < DelegateClass(FFI::Pointer) def initialize(ptr) super @ptr = ptr end def to_ptr @ptr end end class AutoPointerTestHelper @@count = 0 def self.release @@count += 1 if @@count > 0 end def self.reset @@count = 0 end def self.gc_everything(count) loop = 5 while @@count < count && loop > 0 loop -= 1 if RUBY_PLATFORM =~ /java/ require "java" java.lang.System.gc else GC.start end sleep 0.05 unless @@count == count end @@count = 0 end def self.finalizer self.method(:release).to_proc end end # # String fixtures # module LibTest attach_function :ptr_ret_pointer, [ :pointer, :int], :string attach_function :string_equals, [ :string, :string ], :int attach_function :string_dummy, [ :string ], :void end # # Struct initialize fixtures # class StructWithInitialize < FFI::Struct layout :string, :string attr_accessor :magic def initialize super self.magic = 42 end end # # Struct fixtures # StructTypes = { 's8' => :char, 's16' => :short, 's32' => :int, 's64' => :long_long, 'long' => :long, 'f32' => :float, 'f64' => :double } module LibTest attach_function :ptr_ret_pointer, [ :pointer, :int], :string attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int attach_function :ptr_from_address, [ :ulong ], :pointer attach_function :string_equals, [ :string, :string ], :int [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t| attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t] end end class PointerMember < FFI::Struct layout :pointer, :pointer end class StringMember < FFI::Struct layout :string, :string end module CallbackMember extend FFI::Library ffi_lib LIBRARY callback :add, [ :int, :int ], :int callback :sub, [ :int, :int ], :int class TestStruct < FFI::Struct layout :add, :add, :sub, :sub end attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int end module LibTest class NestedStruct < FFI::Struct layout :i, :int end class ContainerStruct < FFI::Struct layout :first, :char, :ns, NestedStruct end attach_function :struct_align_nested_struct, [ :pointer ], :int attach_function :struct_make_container_struct, [ :int ], :pointer class StructWithArray < FFI::Struct layout :first, :char, :a, [:int, 5] end attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer attach_function :struct_field_array, [:pointer], :pointer class BuggedStruct < FFI::Struct layout :visible, :uchar, :x, :uint, :y, :uint, :rx, :short, :ry, :short, :order, :uchar, :size, :uchar end attach_function :bugged_struct_size, [], :uint end module StructCustomTypedef extend FFI::Library ffi_lib LIBRARY typedef :uint, :fubar3_t class S < FFI::Struct layout :a, :fubar3_t end end # # Union fixtures # module LibTest Types = { 's8' => [:char, :c, 1], 's16' => [:short, :s, 0xff0], 's32' => [:int, :i, 0xff00], 's64' => [:long_long, :j, 0xffff00], 'long' => [:long, :l, 0xffff], 'f32' => [:float, :f, 1.0001], 'f64' => [:double, :d, 1.000000001] } class TestUnion < FFI::Union layout( :a, [:char, 10], :i, :int, :f, :float, :d, :double, :s, :short, :l, :long, :j, :long_long, :c, :char ) end Types.keys.each do |k| attach_function "union_align_#{k}", [ :pointer ], Types[k][0] attach_function "union_make_union_with_#{k}", [ Types[k][0] ], :pointer end attach_function :union_size, [], :uint end # # Variadic fixtures # module LibTest attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void end module Varargs PACK_VALUES = { 'c' => [ 0x12 ], 'C' => [ 0x34 ], 's' => [ 0x5678 ], 'S' => [ 0x9abc ], 'i' => [ 0x7654321f ], 'I' => [ 0xfee1babe ], 'l' => [ 0x1f2e3d4c ], 'L' => [ 0xf7e8d9ca ], 'j' => [ 0x1eafdeadbeefa1b2 ], 'f' => [ 1.23456789 ], 'd' => [ 9.87654321 ] } TYPE_MAP = { 'c' => :char, 'C' => :uchar, 's' => :short, 'S' => :ushort, 'i' => :int, 'I' => :uint, 'j' => :long_long, 'J' => :ulong_long, 'l' => :long, 'L' => :ulong, 'f' => :float, 'd' => :double } end end