1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# frozen_string_literal: true
require 'fiddle'
module Fiddle
module ValueUtil #:nodoc: all
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR
[val].pack("c").unpack1("C")
when TYPE_SHORT
[val].pack("s!").unpack1("S!")
when TYPE_INT
[val].pack("i!").unpack1("I!")
when TYPE_LONG
[val].pack("l!").unpack1("L!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
[val].pack("q").unpack1("Q")
else
val
end
end
end
def signed_value(val, ty)
case ty.abs
when TYPE_CHAR
[val].pack("C").unpack1("c")
when TYPE_SHORT
[val].pack("S!").unpack1("s!")
when TYPE_INT
[val].pack("I!").unpack1("i!")
when TYPE_LONG
[val].pack("L!").unpack1("l!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
[val].pack("Q").unpack1("q")
else
val
end
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)
funcs ||= []
case arg
when nil
return 0
when Pointer
return arg.to_i
when IO
case ty
when TYPE_VOIDP
return Pointer[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").unpack1("l!")
else
if defined?(SIZEOF_LONG_LONG) and
SIZEOF_VOIDP == SIZEOF_LONG_LONG
return [arg].pack("p").unpack1("q")
else
raise(RuntimeError, "sizeof(void*)?")
end
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
end
return arg
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
|