summaryrefslogtreecommitdiff
path: root/ext/dl/lib/dl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dl/lib/dl')
-rw-r--r--ext/dl/lib/dl/callback.rb112
-rw-r--r--ext/dl/lib/dl/cparser.rb156
-rw-r--r--ext/dl/lib/dl/func.rb251
-rw-r--r--ext/dl/lib/dl/import.rb268
-rw-r--r--ext/dl/lib/dl/pack.rb128
-rw-r--r--ext/dl/lib/dl/stack.rb116
-rw-r--r--ext/dl/lib/dl/struct.rb236
-rw-r--r--ext/dl/lib/dl/types.rb71
-rw-r--r--ext/dl/lib/dl/value.rb114
9 files changed, 0 insertions, 1452 deletions
diff --git a/ext/dl/lib/dl/callback.rb b/ext/dl/lib/dl/callback.rb
deleted file mode 100644
index 1722d3c6b9..0000000000
--- a/ext/dl/lib/dl/callback.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require 'dl'
-require 'thread'
-
-module DL
- # The mutual exclusion (Mutex) semaphore for the DL module
- SEM = Mutex.new # :nodoc:
-
- if DL.fiddle?
- # A Hash of callback Procs
- #
- # Uses Fiddle
- CdeclCallbackProcs = {} # :nodoc:
-
- # A Hash of the addresses of callback Proc
- #
- # Uses Fiddle
- CdeclCallbackAddrs = {} # :nodoc:
-
- # A Hash of Stdcall callback Procs
- #
- # Uses Fiddle on win32
- StdcallCallbackProcs = {} # :nodoc:
-
- # A Hash of the addresses of Stdcall callback Procs
- #
- # Uses Fiddle on win32
- StdcallCallbackAddrs = {} # :nodoc:
- end
-
- def set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp)
- if( argc < 0 )
- raise(ArgumentError, "arity should not be less than 0.")
- end
- addr = nil
-
- if DL.fiddle?
- abi ||= Fiddle::Function::DEFAULT
- closure = Fiddle::Closure::BlockCaller.new(ty, [TYPE_VOIDP] * argc, abi, &cbp)
- proc_entry[closure.to_i] = closure
- addr = closure.to_i
- else
- SEM.synchronize{
- ary = proc_entry[ty]
- (0...MAX_CALLBACK).each{|n|
- idx = (n * DLSTACK_SIZE) + argc
- if( ary[idx].nil? )
- ary[idx] = cbp
- addr = addr_entry[ty][idx]
- break
- end
- }
- }
- end
-
- addr
- end
-
- def set_cdecl_callback(ty, argc, &cbp)
- set_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, argc, ty, &cbp)
- end
-
- def set_stdcall_callback(ty, argc, &cbp)
- if DL.fiddle?
- set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, Fiddle::Function::STDCALL, &cbp)
- else
- set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, &cbp)
- end
- end
-
- def remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil)
- if DL.fiddle?
- addr = addr.to_i
- return false unless proc_entry.key?(addr)
- proc_entry.delete(addr)
- true
- else
- index = nil
- if( ctype )
- addr_entry[ctype].each_with_index{|xaddr, idx|
- if( xaddr == addr )
- index = idx
- end
- }
- else
- addr_entry.each{|ty,entry|
- entry.each_with_index{|xaddr, idx|
- if( xaddr == addr )
- index = idx
- end
- }
- }
- end
- if( index and proc_entry[ctype][index] )
- proc_entry[ctype][index] = nil
- return true
- else
- return false
- end
- end
- end
-
- def remove_cdecl_callback(addr, ctype = nil)
- remove_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, addr, ctype)
- end
-
- def remove_stdcall_callback(addr, ctype = nil)
- remove_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, addr, ctype)
- end
-
- alias set_callback set_cdecl_callback
- alias remove_callback remove_cdecl_callback
-end
diff --git a/ext/dl/lib/dl/cparser.rb b/ext/dl/lib/dl/cparser.rb
deleted file mode 100644
index e70e0f1dc1..0000000000
--- a/ext/dl/lib/dl/cparser.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-module DL
- # Methods for parsing C struct and C prototype signatures.
- module CParser
- # Parses a C struct's members
- #
- # Example:
- #
- # parse_struct_signature(['int i', 'char c'])
- # => [[DL::TYPE_INT, DL::TYPE_CHAR], ["i", "c"]]
- #
- def parse_struct_signature(signature, tymap=nil)
- if( signature.is_a?(String) )
- signature = signature.split(/\s*,\s*/)
- end
- mems = []
- tys = []
- signature.each{|msig|
- tks = msig.split(/\s+(\*)?/)
- ty = tks[0..-2].join(" ")
- member = tks[-1]
-
- case ty
- when /\[(\d+)\]/
- n = $1.to_i
- ty.gsub!(/\s*\[\d+\]/,"")
- ty = [ty, n]
- when /\[\]/
- ty.gsub!(/\s*\[\]/, "*")
- end
-
- case member
- when /\[(\d+)\]/
- ty = [ty, $1.to_i]
- member.gsub!(/\s*\[\d+\]/,"")
- when /\[\]/
- ty = ty + "*"
- member.gsub!(/\s*\[\]/, "")
- end
-
- mems.push(member)
- tys.push(parse_ctype(ty,tymap))
- }
- return tys, mems
- end
-
- # Parses a C prototype signature
- #
- # Example:
- #
- # include DL::CParser
- # => Object
- #
- # parse_signature('double sum(double, double)')
- # => ["sum", DL::TYPE_DOUBLE, [DL::TYPE_DOUBLE, DL::TYPE_DOUBLE]]
- #
- def parse_signature(signature, tymap=nil)
- tymap ||= {}
- signature = signature.gsub(/\s+/, " ").strip
- case signature
- when /^([\w@\*\s]+)\(([\w\*\s\,\[\]]*)\)$/
- ret = $1
- (args = $2).strip!
- ret = ret.split(/\s+/)
- args = args.split(/\s*,\s*/)
- func = ret.pop
- if( func =~ /^\*/ )
- func.gsub!(/^\*+/,"")
- ret.push("*")
- end
- ret = ret.join(" ")
- return [func, parse_ctype(ret, tymap), args.collect{|arg| parse_ctype(arg, tymap)}]
- else
- raise(RuntimeError,"can't parse the function prototype: #{signature}")
- end
- end
-
- # Given a String of C type +ty+, return the corresponding DL constant.
- #
- # +ty+ can also accept an Array of C type Strings, and will returned in a
- # corresponding Array.
- #
- # If Hash +tymap+ is provided, +ty+ is expected to be the key, and the
- # value will be the C type to be looked up.
- #
- # Example:
- #
- # parse_ctype('int')
- # => DL::TYPE_INT
- #
- # parse_ctype('double')
- # => DL::TYPE_DOUBLE
- #
- # parse_ctype('unsigned char')
- # => -DL::TYPE_CHAR
- #
- def parse_ctype(ty, tymap=nil)
- tymap ||= {}
- case ty
- when Array
- return [parse_ctype(ty[0], tymap), ty[1]]
- when "void"
- return TYPE_VOID
- when "char"
- return TYPE_CHAR
- when "unsigned char"
- return -TYPE_CHAR
- when "short"
- return TYPE_SHORT
- when "unsigned short"
- return -TYPE_SHORT
- when "int"
- return TYPE_INT
- when "unsigned int", 'uint'
- return -TYPE_INT
- when "long"
- return TYPE_LONG
- when "unsigned long"
- return -TYPE_LONG
- when "long long"
- if( defined?(TYPE_LONG_LONG) )
- return TYPE_LONG_LONG
- else
- raise(RuntimeError, "unsupported type: #{ty}")
- end
- when "unsigned long long"
- if( defined?(TYPE_LONG_LONG) )
- return -TYPE_LONG_LONG
- else
- raise(RuntimeError, "unsupported type: #{ty}")
- end
- when "float"
- return TYPE_FLOAT
- when "double"
- return TYPE_DOUBLE
- when "size_t"
- return TYPE_SIZE_T
- when "ssize_t"
- return TYPE_SSIZE_T
- when "ptrdiff_t"
- return TYPE_PTRDIFF_T
- when "intptr_t"
- return TYPE_INTPTR_T
- when "uintptr_t"
- return TYPE_UINTPTR_T
- when /\*/, /\[\s*\]/
- return TYPE_VOIDP
- else
- if( tymap[ty] )
- return parse_ctype(tymap[ty], tymap)
- else
- raise(DLError, "unknown type: #{ty}")
- end
- end
- end
- end
-end
diff --git a/ext/dl/lib/dl/func.rb b/ext/dl/lib/dl/func.rb
deleted file mode 100644
index 543711f651..0000000000
--- a/ext/dl/lib/dl/func.rb
+++ /dev/null
@@ -1,251 +0,0 @@
-require 'dl'
-require 'dl/callback'
-require 'dl/stack'
-require 'dl/value'
-require 'thread'
-
-module DL
- parent = DL.fiddle? ? Fiddle::Function : Object
-
- class Function < parent
- include DL
- include ValueUtil
-
- if DL.fiddle?
- # :stopdoc:
- CALL_TYPE_TO_ABI = Hash.new { |h, k|
- raise RuntimeError, "unsupported call type: #{k}"
- }.merge({ :stdcall =>
- (Fiddle::Function::STDCALL rescue Fiddle::Function::DEFAULT),
- :cdecl => Fiddle::Function::DEFAULT,
- nil => Fiddle::Function::DEFAULT
- }).freeze
- private_constant :CALL_TYPE_TO_ABI
- # :startdoc:
-
- def self.call_type_to_abi(call_type) # :nodoc:
- CALL_TYPE_TO_ABI[call_type]
- end
- private_class_method :call_type_to_abi
-
- class FiddleClosureCFunc < Fiddle::Closure # :nodoc: all
- def initialize ctype, arg, abi, name
- @name = name
- super(ctype, arg, abi)
- end
- def name
- @name
- end
- def ptr
- to_i
- end
- end
- private_constant :FiddleClosureCFunc
-
- def self.class_fiddle_closure_cfunc # :nodoc:
- FiddleClosureCFunc
- end
- private_class_method :class_fiddle_closure_cfunc
- end
-
- def initialize cfunc, argtypes, abi = nil, &block
- if DL.fiddle?
- abi ||= CALL_TYPE_TO_ABI[(cfunc.calltype rescue nil)]
- if block_given?
- @cfunc = Class.new(FiddleClosureCFunc) {
- define_method(:call, block)
- }.new(cfunc.ctype, argtypes, abi, cfunc.name)
- else
- @cfunc = cfunc
- end
-
- @args = argtypes
- super(@cfunc, @args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
- else
- @cfunc = cfunc
- @stack = Stack.new(argtypes.collect{|ty| ty.abs})
- if( @cfunc.ctype < 0 )
- @cfunc.ctype = @cfunc.ctype.abs
- @unsigned = true
- else
- @unsigned = false
- end
- if block_given?
- bind(&block)
- end
- end
- end
-
- def to_i()
- @cfunc.to_i
- end
-
- def name
- @cfunc.name
- end
-
- def call(*args, &block)
- if DL.fiddle?
- if block_given?
- args.find { |a| DL::Function === a }.bind_at_call(&block)
- end
- super
- else
- funcs = []
- if $SAFE >= 1 && args.any? { |x| x.tainted? }
- raise SecurityError, "tainted parameter not allowed"
- end
- _args = wrap_args(args, @stack.types, funcs, &block)
- r = @cfunc.call(@stack.pack(_args))
- funcs.each{|f| f.unbind_at_call()}
- return wrap_result(r)
- end
- end
-
- def wrap_result(r)
- case @cfunc.ctype
- when TYPE_VOIDP
- r = CPtr.new(r)
- else
- if( @unsigned )
- r = unsigned_value(r, @cfunc.ctype)
- end
- end
- r
- end
-
- def bind(&block)
- if DL.fiddle?
- @cfunc = Class.new(FiddleClosureCFunc) {
- def initialize ctype, args, abi, name, block
- super(ctype, args, abi, name)
- @block = block
- end
-
- def call *args
- @block.call(*args)
- end
- }.new(@cfunc.ctype, @args, abi, name, block)
- @ptr = @cfunc
- return nil
- else
- if( !block )
- raise(RuntimeError, "block must be given.")
- end
- unless block.lambda?
- block = Class.new(self.class){define_method(:call, block); def initialize(obj); obj.instance_variables.each{|s| instance_variable_set(s, obj.instance_variable_get(s))}; end}.new(self).method(:call)
- end
- if( @cfunc.ptr == 0 )
- cb = Proc.new{|*args|
- ary = @stack.unpack(args)
- @stack.types.each_with_index{|ty, idx|
- case ty
- when TYPE_VOIDP
- ary[idx] = CPtr.new(ary[idx])
- end
- }
- r = block.call(*ary)
- wrap_arg(r, @cfunc.ctype, [])
- }
- case @cfunc.calltype
- when :cdecl
- @cfunc.ptr = set_cdecl_callback(@cfunc.ctype, @stack.size, &cb)
- when :stdcall
- @cfunc.ptr = set_stdcall_callback(@cfunc.ctype, @stack.size, &cb)
- else
- raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
- end
- if( @cfunc.ptr == 0 )
- raise(RuntimeException, "can't bind C function.")
- end
- end
- end
- end
-
- def unbind()
- if DL.fiddle? then
- if @cfunc.kind_of?(Fiddle::Closure) and @cfunc.ptr != 0 then
- call_type = case abi
- when CALL_TYPE_TO_ABI[nil]
- nil
- when CALL_TYPE_TO_ABI[:stdcall]
- :stdcall
- else
- raise(RuntimeError, "unsupported abi: #{abi}")
- end
- @cfunc = CFunc.new(0, @cfunc.ctype, name, call_type)
- return 0
- elsif @cfunc.ptr != 0 then
- @cfunc.ptr = 0
- return 0
- else
- return nil
- end
- end
- if( @cfunc.ptr != 0 )
- case @cfunc.calltype
- when :cdecl
- remove_cdecl_callback(@cfunc.ptr, @cfunc.ctype)
- when :stdcall
- remove_stdcall_callback(@cfunc.ptr, @cfunc.ctype)
- else
- raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
- end
- @cfunc.ptr = 0
- end
- end
-
- def bound?()
- @cfunc.ptr != 0
- end
-
- def bind_at_call(&block)
- bind(&block)
- end
-
- def unbind_at_call()
- end
- end
-
- class TempFunction < Function
- def bind_at_call(&block)
- bind(&block)
- end
-
- def unbind_at_call()
- unbind()
- end
- end
-
- class CarriedFunction < Function
- def initialize(cfunc, argtypes, n)
- super(cfunc, argtypes)
- @carrier = []
- @index = n
- @mutex = Mutex.new
- end
-
- def create_carrier(data)
- ary = []
- userdata = [ary, data]
- @mutex.lock()
- @carrier.push(userdata)
- return dlwrap(userdata)
- end
-
- def bind_at_call(&block)
- userdata = @carrier[-1]
- userdata[0].push(block)
- bind{|*args|
- ptr = args[@index]
- if( !ptr )
- raise(RuntimeError, "The index of userdata should be lower than #{args.size}.")
- end
- userdata = dlunwrap(Integer(ptr))
- args[@index] = userdata[1]
- userdata[0][0].call(*args)
- }
- @mutex.unlock()
- end
- end
-end
diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb
deleted file mode 100644
index 6f157ccf28..0000000000
--- a/ext/dl/lib/dl/import.rb
+++ /dev/null
@@ -1,268 +0,0 @@
-require 'dl'
-require 'dl/func.rb'
-require 'dl/struct.rb'
-require 'dl/cparser.rb'
-
-module DL
- class CompositeHandler
- def initialize(handlers)
- @handlers = handlers
- end
-
- def handlers()
- @handlers
- end
-
- def sym(symbol)
- @handlers.each{|handle|
- if( handle )
- begin
- addr = handle.sym(symbol)
- return addr
- rescue DLError
- end
- end
- }
- return nil
- end
-
- def [](symbol)
- sym(symbol)
- end
- end
-
- # DL::Importer includes the means to dynamically load libraries and build
- # modules around them including calling extern functions within the C
- # library that has been loaded.
- #
- # == Example
- #
- # require 'dl'
- # require 'dl/import'
- #
- # module LibSum
- # extend DL::Importer
- # dlload './libsum.so'
- # extern 'double sum(double*, int)'
- # extern 'double split(double)'
- # end
- #
- module Importer
- include DL
- include CParser
- extend Importer
-
- def dlload(*libs)
- handles = libs.collect{|lib|
- case lib
- when nil
- nil
- when Handle
- lib
- when Importer
- lib.handlers
- else
- begin
- DL.dlopen(lib)
- rescue DLError
- raise(DLError, "can't load #{lib}")
- end
- end
- }.flatten()
- @handler = CompositeHandler.new(handles)
- @func_map = {}
- @type_alias = {}
- end
-
- def typealias(alias_type, orig_type)
- @type_alias[alias_type] = orig_type
- end
-
- def sizeof(ty)
- @type_alias ||= nil
- case ty
- when String
- ty = parse_ctype(ty, @type_alias).abs()
- case ty
- when TYPE_CHAR
- return SIZEOF_CHAR
- when TYPE_SHORT
- return SIZEOF_SHORT
- when TYPE_INT
- return SIZEOF_INT
- when TYPE_LONG
- return SIZEOF_LONG
- when TYPE_LONG_LONG
- return SIZEOF_LONG_LON
- when TYPE_FLOAT
- return SIZEOF_FLOAT
- when TYPE_DOUBLE
- return SIZEOF_DOUBLE
- when TYPE_VOIDP
- return SIZEOF_VOIDP
- else
- raise(DLError, "unknown type: #{ty}")
- end
- when Class
- if( ty.instance_methods().include?(:to_ptr) )
- return ty.size()
- end
- end
- return CPtr[ty].size()
- end
-
- def parse_bind_options(opts)
- h = {}
- while( opt = opts.shift() )
- case opt
- when :stdcall, :cdecl
- h[:call_type] = opt
- when :carried, :temp, :temporal, :bind
- h[:callback_type] = opt
- h[:carrier] = opts.shift()
- else
- h[opt] = true
- end
- end
- h
- end
- private :parse_bind_options
-
- def extern(signature, *opts)
- @type_alias ||= nil
- symname, ctype, argtype = parse_signature(signature, @type_alias)
- opt = parse_bind_options(opts)
- f = import_function(symname, ctype, argtype, opt[:call_type])
- name = symname.gsub(/@.+/,'')
- @func_map[name] = f
- # define_method(name){|*args,&block| f.call(*args,&block)}
- begin
- /^(.+?):(\d+)/ =~ caller.first
- file, line = $1, $2.to_i
- rescue
- file, line = __FILE__, __LINE__+3
- end
- module_eval(<<-EOS, file, line)
- def #{name}(*args, &block)
- @func_map['#{name}'].call(*args,&block)
- end
- EOS
- module_function(name)
- f
- end
-
- def bind(signature, *opts, &blk)
- @type_alias ||= nil
- name, ctype, argtype = parse_signature(signature, @type_alias)
- h = parse_bind_options(opts)
- case h[:callback_type]
- when :bind, nil
- f = bind_function(name, ctype, argtype, h[:call_type], &blk)
- when :temp, :temporal
- f = create_temp_function(name, ctype, argtype, h[:call_type])
- when :carried
- f = create_carried_function(name, ctype, argtype, h[:call_type], h[:carrier])
- else
- raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
- end
- @func_map[name] = f
- #define_method(name){|*args,&block| f.call(*args,&block)}
- begin
- /^(.+?):(\d+)/ =~ caller.first
- file, line = $1, $2.to_i
- rescue
- file, line = __FILE__, __LINE__+3
- end
- module_eval(<<-EOS, file, line)
- def #{name}(*args,&block)
- @func_map['#{name}'].call(*args,&block)
- end
- EOS
- module_function(name)
- f
- end
-
- # Creates a class to wrap the C struct described by +signature+.
- #
- # MyStruct = struct ['int i', 'char c']
- def struct(signature)
- @type_alias ||= nil
- tys, mems = parse_struct_signature(signature, @type_alias)
- DL::CStructBuilder.create(CStruct, tys, mems)
- end
-
- # Creates a class to wrap the C union described by +signature+.
- #
- # MyUnion = union ['int i', 'char c']
- def union(signature)
- @type_alias ||= nil
- tys, mems = parse_struct_signature(signature, @type_alias)
- DL::CStructBuilder.create(CUnion, tys, mems)
- end
-
- def [](name)
- @func_map[name]
- end
-
- def create_value(ty, val=nil)
- s = struct([ty + " value"])
- ptr = s.malloc()
- if( val )
- ptr.value = val
- end
- return ptr
- end
- alias value create_value
-
- def import_value(ty, addr)
- s = struct([ty + " value"])
- ptr = s.new(addr)
- return ptr
- end
-
- def handler
- defined?(@handler) or raise "call dlload before importing symbols and functions"
- @handler
- end
-
- def import_symbol(name)
- addr = handler.sym(name)
- if( !addr )
- raise(DLError, "cannot find the symbol: #{name}")
- end
- CPtr.new(addr)
- end
-
- def import_function(name, ctype, argtype, call_type = nil)
- addr = handler.sym(name)
- if( !addr )
- raise(DLError, "cannot find the function: #{name}()")
- end
- Function.new(CFunc.new(addr, ctype, name, call_type || :cdecl), argtype)
- end
-
- def bind_function(name, ctype, argtype, call_type = nil, &block)
- if DL.fiddle?
- klass = Function.instance_eval { class_fiddle_closure_cfunc }
- abi = Function.instance_eval { call_type_to_abi(call_type) }
- closure = Class.new(klass) {
- define_method(:call, block)
- }.new(ctype, argtype, abi, name)
-
- Function.new(closure, argtype, abi)
- else
- f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
- f.bind(&block)
- f
- end
- end
-
- def create_temp_function(name, ctype, argtype, call_type = nil)
- TempFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
- end
-
- def create_carried_function(name, ctype, argtype, call_type = nil, n = 0)
- CarriedFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype, n)
- end
- end
-end
diff --git a/ext/dl/lib/dl/pack.rb b/ext/dl/lib/dl/pack.rb
deleted file mode 100644
index 7fbc802b0f..0000000000
--- a/ext/dl/lib/dl/pack.rb
+++ /dev/null
@@ -1,128 +0,0 @@
-require 'dl'
-
-module DL
- module PackInfo
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_CHAR,
- TYPE_SHORT => ALIGN_SHORT,
- TYPE_INT => ALIGN_INT,
- 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,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG) ? "q" : "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!",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- 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,
- }
- 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
- end
-
- def align(addr, align)
- d = addr % align
- if( d == 0 )
- addr
- else
- addr + (align - d)
- end
- end
- module_function :align
- end
-
- class Packer
- include PackInfo
-
- def self.[](*types)
- new(types)
- end
-
- def initialize(types)
- parse_types(types)
- end
-
- def size()
- @size
- end
-
- def pack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack(@template)
- when SIZEOF_LONG_LONG
- ary.pack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- def unpack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.join().unpack(@template)
- when SIZEOF_LONG_LONG
- ary.join().unpack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- private
-
- def parse_types(types)
- @template = ""
- addr = 0
- types.each{|t|
- orig_addr = addr
- if( t.is_a?(Array) )
- addr = align(orig_addr, ALIGN_MAP[TYPE_VOIDP])
- else
- addr = align(orig_addr, ALIGN_MAP[t])
- end
- d = addr - orig_addr
- if( d > 0 )
- @template << "x#{d}"
- end
- if( t.is_a?(Array) )
- @template << (PACK_MAP[t[0]] * t[1])
- addr += (SIZE_MAP[t[0]] * t[1])
- else
- @template << PACK_MAP[t]
- addr += SIZE_MAP[t]
- end
- }
- addr = align(addr, ALIGN_MAP[TYPE_VOIDP])
- @size = addr
- end
- end
-end
diff --git a/ext/dl/lib/dl/stack.rb b/ext/dl/lib/dl/stack.rb
deleted file mode 100644
index dc22378fcb..0000000000
--- a/ext/dl/lib/dl/stack.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'dl'
-
-module DL
- class Stack
- def self.[](*types)
- new(types)
- end
-
- def initialize(types)
- parse_types(types)
- end
-
- def size()
- @size
- end
-
- def types()
- @types
- end
-
- def pack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack(@template).unpack('l!*')
- when SIZEOF_LONG_LONG
- ary.pack(@template).unpack('q*')
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- def unpack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack('l!*').unpack(@template)
- when SIZEOF_LONG_LONG
- ary.pack('q*').unpack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- private
-
- def align(addr, align)
- d = addr % align
- if( d == 0 )
- addr
- else
- addr + (align - d)
- end
- end
-
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_VOIDP,
- TYPE_SHORT => ALIGN_VOIDP,
- TYPE_INT => ALIGN_VOIDP,
- TYPE_LONG => ALIGN_VOIDP,
- TYPE_FLOAT => ALIGN_FLOAT,
- TYPE_DOUBLE => ALIGN_DOUBLE,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG)? "q" : "l!"),
- TYPE_CHAR => "c",
- TYPE_SHORT => "s!",
- TYPE_INT => "i!",
- TYPE_LONG => "l!",
- TYPE_FLOAT => "f",
- TYPE_DOUBLE => "d",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- TYPE_LONG => SIZEOF_LONG,
- TYPE_FLOAT => SIZEOF_FLOAT,
- TYPE_DOUBLE => SIZEOF_DOUBLE,
- }
- if defined?(TYPE_LONG_LONG)
- ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_LONG_LONG
- PACK_MAP[TYPE_LONG_LONG] = "q"
- SIZE_MAP[TYPE_LONG_LONG] = SIZEOF_LONG_LONG
- end
-
- def parse_types(types)
- @types = types
- @template = ""
- addr = 0
- types.each{|t|
- addr = add_padding(addr, ALIGN_MAP[t])
- @template << PACK_MAP[t]
- addr += SIZE_MAP[t]
- }
- addr = add_padding(addr, ALIGN_MAP[SIZEOF_VOIDP])
- if( addr % SIZEOF_VOIDP == 0 )
- @size = addr / SIZEOF_VOIDP
- else
- @size = (addr / SIZEOF_VOIDP) + 1
- end
- end
-
- def add_padding(addr, align)
- orig_addr = addr
- addr = align(orig_addr, align)
- d = addr - orig_addr
- if( d > 0 )
- @template << "x#{d}"
- end
- addr
- end
- end
-end
diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb
deleted file mode 100644
index e2d91a6d14..0000000000
--- a/ext/dl/lib/dl/struct.rb
+++ /dev/null
@@ -1,236 +0,0 @@
-require 'dl'
-require 'dl/value'
-require 'dl/pack.rb'
-
-module DL
- # C struct shell
- class CStruct
- # accessor to DL::CStructEntity
- def CStruct.entity_class()
- CStructEntity
- end
- end
-
- # C union shell
- class CUnion
- # accessor to DL::CUnionEntity
- def CUnion.entity_class()
- CUnionEntity
- end
- end
-
- # Used to construct C classes (CUnion, CStruct, etc)
- #
- # DL::Importer#struct and DL::Importer#union wrap this functionality in an
- # easy-to-use manner.
- module CStructBuilder
- # Construct a new class given a C:
- # * class +klass+ (CUnion, CStruct, or other that provide an
- # #entity_class)
- # * +types+ (DL:TYPE_INT, DL::TYPE_SIZE_T, etc., see the C types
- # constants)
- # * corresponding +members+
- #
- # DL::Importer#struct and DL::Importer#union wrap this functionality in an
- # easy-to-use manner.
- #
- # Example:
- #
- # require 'dl/struct'
- # require 'dl/cparser'
- #
- # include DL::CParser
- #
- # types, members = parse_struct_signature(['int i','char c'])
- #
- # MyStruct = DL::CStructBuilder.create(CUnion, types, members)
- #
- # obj = MyStruct.allocate
- #
- def create(klass, types, members)
- new_class = Class.new(klass){
- define_method(:initialize){|addr|
- @entity = klass.entity_class.new(addr, types)
- @entity.assign_names(members)
- }
- define_method(:to_ptr){ @entity }
- define_method(:to_i){ @entity.to_i }
- members.each{|name|
- define_method(name){ @entity[name] }
- define_method(name + "="){|val| @entity[name] = val }
- }
- }
- size = klass.entity_class.size(types)
- new_class.module_eval(<<-EOS, __FILE__, __LINE__+1)
- def new_class.size()
- #{size}
- end
- def new_class.malloc()
- addr = DL.malloc(#{size})
- new(addr)
- end
- EOS
- return new_class
- end
- module_function :create
- end
-
- # A C struct wrapper
- class CStructEntity < (DL.fiddle? ? Fiddle::Pointer : CPtr)
- include PackInfo
- include ValueUtil
-
- # Allocates a C struct the +types+ provided. The C function +func+ is
- # called when the instance is garbage collected.
- def CStructEntity.malloc(types, func = nil)
- addr = DL.malloc(CStructEntity.size(types))
- CStructEntity.new(addr, types, func)
- end
-
- # Given +types+, returns the offset for the packed sizes of those types
- #
- # DL::CStructEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
- # DL::TYPE_VOIDP])
- # => 24
- def CStructEntity.size(types)
- offset = 0
-
- max_align = types.map { |type, count = 1|
- last_offset = offset
-
- align = PackInfo::ALIGN_MAP[type]
- offset = PackInfo.align(last_offset, align) +
- (PackInfo::SIZE_MAP[type] * count)
-
- align
- }.max
-
- PackInfo.align(offset, max_align)
- end
-
- # Wraps the C pointer +addr+ as a C struct with the given +types+. The C
- # function +func+ is called when the instance is garbage collected.
- #
- # See also DL::CPtr.new
- def initialize(addr, types, func = nil)
- set_ctypes(types)
- super(addr, @size, func)
- end
-
- # Set the names of the +members+ in this C struct
- def assign_names(members)
- @members = members
- end
-
- # Given +types+, calculate the offsets and sizes for the types in the
- # struct.
- def set_ctypes(types)
- @ctypes = types
- @offset = []
- offset = 0
-
- max_align = types.map { |type, count = 1|
- orig_offset = offset
- align = ALIGN_MAP[type]
- offset = PackInfo.align(orig_offset, align)
-
- @offset << offset
-
- offset += (SIZE_MAP[type] * count)
-
- align
- }.max
-
- @size = PackInfo.align(offset, max_align)
- end
-
- # Fetch struct member +name+
- def [](name)
- idx = @members.index(name)
- if( idx.nil? )
- raise(ArgumentError, "no such member: #{name}")
- end
- ty = @ctypes[idx]
- if( ty.is_a?(Array) )
- r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
- else
- r = super(@offset[idx], SIZE_MAP[ty.abs])
- end
- packer = Packer.new([ty])
- val = packer.unpack([r])
- case ty
- when Array
- case ty[0]
- when TYPE_VOIDP
- val = val.collect{|v| CPtr.new(v)}
- end
- when TYPE_VOIDP
- val = CPtr.new(val[0])
- else
- val = val[0]
- end
- if( ty.is_a?(Integer) && (ty < 0) )
- return unsigned_value(val, ty)
- elsif( ty.is_a?(Array) && (ty[0] < 0) )
- return val.collect{|v| unsigned_value(v,ty[0])}
- else
- return val
- end
- end
-
- # Set struct member +name+, to value +val+
- def []=(name, val)
- idx = @members.index(name)
- if( idx.nil? )
- raise(ArgumentError, "no such member: #{name}")
- end
- ty = @ctypes[idx]
- packer = Packer.new([ty])
- val = wrap_arg(val, ty, [])
- buff = packer.pack([val].flatten())
- super(@offset[idx], buff.size, buff)
- if( ty.is_a?(Integer) && (ty < 0) )
- return unsigned_value(val, ty)
- elsif( ty.is_a?(Array) && (ty[0] < 0) )
- return val.collect{|v| unsigned_value(v,ty[0])}
- else
- return val
- end
- end
-
- def to_s() # :nodoc:
- super(@size)
- end
- end
-
- # A C union wrapper
- class CUnionEntity < CStructEntity
- include PackInfo
-
- # Allocates a C union the +types+ provided. The C function +func+ is
- # called when the instance is garbage collected.
- def CUnionEntity.malloc(types, func=nil)
- addr = DL.malloc(CUnionEntity.size(types))
- CUnionEntity.new(addr, types, func)
- end
-
- # Given +types+, returns the size needed for the union.
- #
- # DL::CUnionEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
- # DL::TYPE_VOIDP])
- # => 8
- def CUnionEntity.size(types)
- types.map { |type, count = 1|
- PackInfo::SIZE_MAP[type] * count
- }.max
- end
-
- # Given +types+, calculate the necessary offset and for each union member
- def set_ctypes(types)
- @ctypes = types
- @offset = Array.new(types.length, 0)
- @size = self.class.size types
- end
- end
-end
-
diff --git a/ext/dl/lib/dl/types.rb b/ext/dl/lib/dl/types.rb
deleted file mode 100644
index d5724e407b..0000000000
--- a/ext/dl/lib/dl/types.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-module DL
- # Adds Windows type aliases to the including class for use with
- # DL::Importer.
- #
- # The aliases added are:
- # * ATOM
- # * BOOL
- # * BYTE
- # * DWORD
- # * DWORD32
- # * DWORD64
- # * HANDLE
- # * HDC
- # * HINSTANCE
- # * HWND
- # * LPCSTR
- # * LPSTR
- # * PBYTE
- # * PDWORD
- # * PHANDLE
- # * PVOID
- # * PWORD
- # * UCHAR
- # * UINT
- # * ULONG
- # * WORD
- module Win32Types
- def included(m) # :nodoc:
- m.module_eval{
- typealias "DWORD", "unsigned long"
- typealias "PDWORD", "unsigned long *"
- typealias "DWORD32", "unsigned long"
- typealias "DWORD64", "unsigned long long"
- typealias "WORD", "unsigned short"
- typealias "PWORD", "unsigned short *"
- typealias "BOOL", "int"
- typealias "ATOM", "int"
- typealias "BYTE", "unsigned char"
- typealias "PBYTE", "unsigned char *"
- typealias "UINT", "unsigned int"
- typealias "ULONG", "unsigned long"
- typealias "UCHAR", "unsigned char"
- typealias "HANDLE", "uintptr_t"
- typealias "PHANDLE", "void*"
- typealias "PVOID", "void*"
- typealias "LPCSTR", "char*"
- typealias "LPSTR", "char*"
- typealias "HINSTANCE", "unsigned int"
- typealias "HDC", "unsigned int"
- typealias "HWND", "unsigned int"
- }
- end
- module_function :included
- end
-
- # Adds basic type aliases to the including class for use with DL::Importer.
- #
- # The aliases added are +uint+ and +u_int+ (<tt>unsigned int</tt>) and
- # +ulong+ and +u_long+ (<tt>unsigned long</tt>)
- module BasicTypes
- def included(m) # :nodoc:
- m.module_eval{
- typealias "uint", "unsigned int"
- typealias "u_int", "unsigned int"
- typealias "ulong", "unsigned long"
- typealias "u_long", "unsigned long"
- }
- end
- module_function :included
- end
-end
diff --git a/ext/dl/lib/dl/value.rb b/ext/dl/lib/dl/value.rb
deleted file mode 100644
index 147d9d120a..0000000000
--- a/ext/dl/lib/dl/value.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-require 'dl'
-
-module DL
- module ValueUtil
- def unsigned_value(val, ty)
- case ty.abs
- when TYPE_CHAR
- [val].pack("c").unpack("C")[0]
- when TYPE_SHORT
- [val].pack("s!").unpack("S!")[0]
- when TYPE_INT
- [val].pack("i!").unpack("I!")[0]
- when TYPE_LONG
- [val].pack("l!").unpack("L!")[0]
- when TYPE_LONG_LONG
- [val].pack("q").unpack("Q")[0]
- else
- val
- end
- end
-
- def signed_value(val, ty)
- case ty.abs
- when TYPE_CHAR
- [val].pack("C").unpack("c")[0]
- when TYPE_SHORT
- [val].pack("S!").unpack("s!")[0]
- when TYPE_INT
- [val].pack("I!").unpack("i!")[0]
- when TYPE_LONG
- [val].pack("L!").unpack("l!")[0]
- when TYPE_LONG_LONG
- [val].pack("Q").unpack("q")[0]
- else
- val
- end
- end
-
- def wrap_args(args, tys, funcs, &block)
- result = []
- tys ||= []
- args.each_with_index{|arg, idx|
- result.push(wrap_arg(arg, tys[idx], funcs, &block))
- }
- result
- end
-
- def wrap_arg(arg, ty, funcs = [], &block)
- require 'dl/func'
-
- funcs ||= []
- case arg
- when nil
- return 0
- when CPtr
- return arg.to_i
- when IO
- case ty
- when TYPE_VOIDP
- return CPtr[arg].to_i
- else
- return arg.to_i
- end
- when Function
- if( block )
- arg.bind_at_call(&block)
- funcs.push(arg)
- elsif !arg.bound?
- raise(RuntimeError, "block must be given.")
- end
- return arg.to_i
- when String
- if( ty.is_a?(Array) )
- return arg.unpack('C*')
- else
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- return [arg].pack("p").unpack("l!")[0]
- when SIZEOF_LONG_LONG
- return [arg].pack("p").unpack("q")[0]
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
- when Float, Integer
- return arg
- when Array
- if( ty.is_a?(Array) ) # used only by struct
- case ty[0]
- when TYPE_VOIDP
- return arg.collect{|v| Integer(v)}
- when TYPE_CHAR
- if( arg.is_a?(String) )
- return val.unpack('C*')
- end
- end
- return arg
- else
- return arg
- end
- else
- if( arg.respond_to?(:to_ptr) )
- return arg.to_ptr.to_i
- else
- begin
- return Integer(arg)
- rescue
- raise(ArgumentError, "unknown argument type: #{arg.class}")
- end
- end
- end
- end
- end
-end