summaryrefslogtreecommitdiff
path: root/ext/fiddle/lib/fiddle
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fiddle/lib/fiddle')
-rw-r--r--ext/fiddle/lib/fiddle/closure.rb25
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb42
-rw-r--r--ext/fiddle/lib/fiddle/import.rb2
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb47
-rw-r--r--ext/fiddle/lib/fiddle/value.rb28
-rw-r--r--ext/fiddle/lib/fiddle/version.rb2
6 files changed, 99 insertions, 47 deletions
diff --git a/ext/fiddle/lib/fiddle/closure.rb b/ext/fiddle/lib/fiddle/closure.rb
index c865a63c20..7e0077ea52 100644
--- a/ext/fiddle/lib/fiddle/closure.rb
+++ b/ext/fiddle/lib/fiddle/closure.rb
@@ -1,6 +1,31 @@
# frozen_string_literal: true
module Fiddle
class Closure
+ class << self
+ # Create a new closure. If a block is given, the created closure
+ # is automatically freed after the given block is executed.
+ #
+ # The all given arguments are passed to Fiddle::Closure.new. So
+ # using this method without block equals to Fiddle::Closure.new.
+ #
+ # == Example
+ #
+ # Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure|
+ # # closure is freed automatically when this block is finished.
+ # end
+ def create(*args)
+ if block_given?
+ closure = new(*args)
+ begin
+ yield(closure)
+ ensure
+ closure.free
+ end
+ else
+ new(*args)
+ end
+ end
+ end
# the C type of the return of the FFI closure
attr_reader :ctype
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index 93a05513c9..264ca166dd 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -164,23 +164,35 @@ module Fiddle
unless Fiddle.const_defined?(:TYPE_LONG_LONG)
raise(RuntimeError, "unsupported type: #{ty}")
end
- return -TYPE_LONG_LONG
- when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
+ return TYPE_ULONG_LONG
+ when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\Aunsigned\s+int\s+long(?:\s+\w+)?\z/,
+ /\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
+ /\Aint\s+unsigned\s+long(?:\s+\w+)?\z/,
+ /\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/
+ return TYPE_ULONG
+ when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/,
+ /\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/
return TYPE_LONG
- when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
- return -TYPE_LONG
+ when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\Aunsigned\s+int\s+short(?:\s+\w+)?\z/,
+ /\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
+ /\Aint\s+unsigned\s+short(?:\s+\w+)?\z/,
+ /\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/
+ return TYPE_USHORT
+ when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/,
+ /\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/
+ return TYPE_SHORT
when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
return TYPE_INT
when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
- return -TYPE_INT
- when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
- return TYPE_SHORT
- when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
- return -TYPE_SHORT
+ return TYPE_UINT
when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
return TYPE_CHAR
when /\Aunsigned\s+char(?:\s+\w+)?\z/
- return -TYPE_CHAR
+ return TYPE_UCHAR
when /\Aint8_t(?:\s+\w+)?\z/
unless Fiddle.const_defined?(:TYPE_INT8_T)
raise(RuntimeError, "unsupported type: #{ty}")
@@ -190,7 +202,7 @@ module Fiddle
unless Fiddle.const_defined?(:TYPE_INT8_T)
raise(RuntimeError, "unsupported type: #{ty}")
end
- return -TYPE_INT8_T
+ return TYPE_UINT8_T
when /\Aint16_t(?:\s+\w+)?\z/
unless Fiddle.const_defined?(:TYPE_INT16_T)
raise(RuntimeError, "unsupported type: #{ty}")
@@ -200,7 +212,7 @@ module Fiddle
unless Fiddle.const_defined?(:TYPE_INT16_T)
raise(RuntimeError, "unsupported type: #{ty}")
end
- return -TYPE_INT16_T
+ return TYPE_UINT16_T
when /\Aint32_t(?:\s+\w+)?\z/
unless Fiddle.const_defined?(:TYPE_INT32_T)
raise(RuntimeError, "unsupported type: #{ty}")
@@ -210,7 +222,7 @@ module Fiddle
unless Fiddle.const_defined?(:TYPE_INT32_T)
raise(RuntimeError, "unsupported type: #{ty}")
end
- return -TYPE_INT32_T
+ return TYPE_UINT32_T
when /\Aint64_t(?:\s+\w+)?\z/
unless Fiddle.const_defined?(:TYPE_INT64_T)
raise(RuntimeError, "unsupported type: #{ty}")
@@ -220,7 +232,7 @@ module Fiddle
unless Fiddle.const_defined?(:TYPE_INT64_T)
raise(RuntimeError, "unsupported type: #{ty}")
end
- return -TYPE_INT64_T
+ return TYPE_UINT64_T
when /\Afloat(?:\s+\w+)?\z/
return TYPE_FLOAT
when /\Adouble(?:\s+\w+)?\z/
@@ -235,6 +247,8 @@ module Fiddle
return TYPE_INTPTR_T
when /\Auintptr_t(?:\s+\w+)?\z/
return TYPE_UINTPTR_T
+ when "bool"
+ return TYPE_BOOL
when /\*/, /\[[\s\d]*\]/
return TYPE_VOIDP
when "..."
diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb
index 09ffcef544..050708fb96 100644
--- a/ext/fiddle/lib/fiddle/import.rb
+++ b/ext/fiddle/lib/fiddle/import.rb
@@ -119,6 +119,8 @@ module Fiddle
return SIZEOF_VOIDP
when TYPE_CONST_STRING
return SIZEOF_CONST_STRING
+ when TYPE_BOOL
+ return SIZEOF_BOOL
else
if defined?(TYPE_LONG_LONG) and
ty == TYPE_LONG_LONG
diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb
index 22eccedb76..81088f402b 100644
--- a/ext/fiddle/lib/fiddle/pack.rb
+++ b/ext/fiddle/lib/fiddle/pack.rb
@@ -11,25 +11,36 @@ module Fiddle
TYPE_LONG => ALIGN_LONG,
TYPE_FLOAT => ALIGN_FLOAT,
TYPE_DOUBLE => ALIGN_DOUBLE,
- -TYPE_CHAR => ALIGN_CHAR,
- -TYPE_SHORT => ALIGN_SHORT,
- -TYPE_INT => ALIGN_INT,
- -TYPE_LONG => ALIGN_LONG,
+ TYPE_UCHAR => ALIGN_CHAR,
+ TYPE_USHORT => ALIGN_SHORT,
+ TYPE_UINT => ALIGN_INT,
+ TYPE_ULONG => ALIGN_LONG,
+ TYPE_BOOL => ALIGN_BOOL,
}
PACK_MAP = {
- TYPE_VOIDP => "l!",
+ TYPE_VOIDP => "L!",
TYPE_CHAR => "c",
TYPE_SHORT => "s!",
TYPE_INT => "i!",
TYPE_LONG => "l!",
TYPE_FLOAT => "f",
TYPE_DOUBLE => "d",
- -TYPE_CHAR => "c",
- -TYPE_SHORT => "s!",
- -TYPE_INT => "i!",
- -TYPE_LONG => "l!",
+ TYPE_UCHAR => "C",
+ TYPE_USHORT => "S!",
+ TYPE_UINT => "I!",
+ TYPE_ULONG => "L!",
}
+ case SIZEOF_BOOL
+ when SIZEOF_CHAR
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR]
+ when SIZEOF_SHORT
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT]
+ when SIZEOF_INT
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT]
+ when SIZEOF_LONG
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG]
+ end
SIZE_MAP = {
TYPE_VOIDP => SIZEOF_VOIDP,
@@ -39,16 +50,18 @@ module Fiddle
TYPE_LONG => SIZEOF_LONG,
TYPE_FLOAT => SIZEOF_FLOAT,
TYPE_DOUBLE => SIZEOF_DOUBLE,
- -TYPE_CHAR => SIZEOF_CHAR,
- -TYPE_SHORT => SIZEOF_SHORT,
- -TYPE_INT => SIZEOF_INT,
- -TYPE_LONG => SIZEOF_LONG,
+ TYPE_UCHAR => SIZEOF_CHAR,
+ TYPE_USHORT => SIZEOF_SHORT,
+ TYPE_UINT => SIZEOF_INT,
+ TYPE_ULONG => SIZEOF_LONG,
+ TYPE_BOOL => SIZEOF_BOOL,
}
if defined?(TYPE_LONG_LONG)
- ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG
- PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q"
- SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG
- PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
+ ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
+ PACK_MAP[TYPE_LONG_LONG] = "q"
+ PACK_MAP[TYPE_ULONG_LONG] = "Q"
+ SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[TYPE_ULONG_LONG] = SIZEOF_LONG_LONG
+ PACK_MAP[TYPE_VOIDP] = "Q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
end
def align(addr, align)
diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb
index 01fec1c206..5f0b2e951e 100644
--- a/ext/fiddle/lib/fiddle/value.rb
+++ b/ext/fiddle/lib/fiddle/value.rb
@@ -6,17 +6,17 @@ module Fiddle
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("c").unpack("C")[0]
+ [val].pack("c").unpack1("C")
when TYPE_SHORT
- [val].pack("s!").unpack("S!")[0]
+ [val].pack("s!").unpack1("S!")
when TYPE_INT
- [val].pack("i!").unpack("I!")[0]
+ [val].pack("i!").unpack1("I!")
when TYPE_LONG
- [val].pack("l!").unpack("L!")[0]
+ [val].pack("l!").unpack1("L!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("q").unpack("Q")[0]
+ [val].pack("q").unpack1("Q")
else
val
end
@@ -26,17 +26,17 @@ module Fiddle
def signed_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("C").unpack("c")[0]
+ [val].pack("C").unpack1("c")
when TYPE_SHORT
- [val].pack("S!").unpack("s!")[0]
+ [val].pack("S!").unpack1("s!")
when TYPE_INT
- [val].pack("I!").unpack("i!")[0]
+ [val].pack("I!").unpack1("i!")
when TYPE_LONG
- [val].pack("L!").unpack("l!")[0]
+ [val].pack("L!").unpack1("l!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("Q").unpack("q")[0]
+ [val].pack("Q").unpack1("q")
else
val
end
@@ -80,11 +80,11 @@ module Fiddle
else
case SIZEOF_VOIDP
when SIZEOF_LONG
- return [arg].pack("p").unpack("l!")[0]
+ return [arg].pack("p").unpack1("l!")
else
if defined?(SIZEOF_LONG_LONG) and
SIZEOF_VOIDP == SIZEOF_LONG_LONG
- return [arg].pack("p").unpack("q")[0]
+ return [arg].pack("p").unpack1("q")
else
raise(RuntimeError, "sizeof(void*)?")
end
@@ -102,10 +102,8 @@ module Fiddle
return val.unpack('C*')
end
end
- return arg
- else
- return arg
end
+ return arg
else
if( arg.respond_to?(:to_ptr) )
return arg.to_ptr.to_i
diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb
index db6504b650..6c5109dca8 100644
--- a/ext/fiddle/lib/fiddle/version.rb
+++ b/ext/fiddle/lib/fiddle/version.rb
@@ -1,3 +1,3 @@
module Fiddle
- VERSION = "1.1.0"
+ VERSION = "1.1.3"
end