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
|
#
# This file is part of ruby-ffi.
#
# This code is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License version 3 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# version 3 for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
#
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
describe "Function with variadic arguments" do
module LibTest
extend FFI::Library
ffi_lib TestLibrary::PATH
attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
end
[ 0, 127, -128, -1 ].each do |i|
it "call variadic with (:char (#{i})) argument" do
buf = FFI::Buffer.new :long_long
LibTest.pack_varargs(buf, "c", :char, i)
buf.get_int64(0).should eq i
end
end
[ 0, 0x7f, 0x80, 0xff ].each do |i|
it "call variadic with (:uchar (#{i})) argument" do
buf = FFI::Buffer.new :long_long
LibTest.pack_varargs(buf, "C", :uchar, i)
buf.get_int64(0).should eq i
end
end
[ 0, 1.234567, 9.87654321 ].each do |v|
it "call variadic with (:float (#{v})) argument" do
buf = FFI::Buffer.new :long_long
LibTest.pack_varargs(buf, "f", :float, v.to_f)
buf.get_float64(0).should eq v
end
end
[ 0, 1.234567, 9.87654321 ].each do |v|
it "call variadic with (:double (#{v})) argument" do
buf = FFI::Buffer.new :long_long
LibTest.pack_varargs(buf, "f", :double, v.to_f)
buf.get_float64(0).should eq v
end
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
def verify(p, off, v)
if v.kind_of?(Float)
p.get_float64(off).should eq v
else
p.get_int64(off).should eq v
end
end
Varargs::PACK_VALUES.keys.each do |t1|
Varargs::PACK_VALUES.keys.each do |t2|
Varargs::PACK_VALUES.keys.each do |t3|
Varargs::PACK_VALUES[t1].each do |v1|
Varargs::PACK_VALUES[t2].each do |v2|
Varargs::PACK_VALUES[t3].each do |v3|
fmt = "#{t1}#{t2}#{t3}"
params = [ Varargs::TYPE_MAP[t1], v1, Varargs::TYPE_MAP[t2], v2, Varargs::TYPE_MAP[t3], v3 ]
it "call(#{fmt}, #{params.join(',')})" do
buf = FFI::Buffer.new :long_long, 3
LibTest.pack_varargs(buf, fmt, *params)
verify(buf, 0, v1)
verify(buf, 8, v2)
verify(buf, 16, v3)
end
end
end
end
end
end
end
end
|