summaryrefslogtreecommitdiff
path: root/test/fiddle/test_import.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/fiddle/test_import.rb')
-rw-r--r--test/fiddle/test_import.rb324
1 files changed, 284 insertions, 40 deletions
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb
index 4afd8e5562..afa8df9e00 100644
--- a/test/fiddle/test_import.rb
+++ b/test/fiddle/test_import.rb
@@ -36,6 +36,29 @@ module Fiddle
"char c",
"unsigned char buff[7]",
]
+ StructNestedStruct = struct [
+ {
+ "vertices[2]" => {
+ position: ["float x", "float y", "float z"],
+ texcoord: ["float u", "float v"]
+ },
+ object: ["int id", "void *user_data"],
+ },
+ "int id"
+ ]
+ UnionNestedStruct = union [
+ {
+ keyboard: [
+ 'unsigned int state',
+ 'char key'
+ ],
+ mouse: [
+ 'unsigned int button',
+ 'unsigned short x',
+ 'unsigned short y'
+ ]
+ }
+ ]
CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2|
f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID)
@@ -56,22 +79,18 @@ module Fiddle
def test_struct_memory_access()
# check memory operations performed directly on struct
- my_struct = Fiddle::Importer.struct(['int id']).malloc
- begin
+ Fiddle::Importer.struct(['int id']).malloc(Fiddle::RUBY_FREE) do |my_struct|
my_struct[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
assert_equal 0x01010101, my_struct.id
my_struct.id = 0
assert_equal "\x00".b * Fiddle::SIZEOF_INT, my_struct[0, Fiddle::SIZEOF_INT]
- ensure
- Fiddle.free my_struct.to_ptr
end
end
def test_struct_ptr_array_subscript_multiarg()
# check memory operations performed on struct#to_ptr
- struct = Fiddle::Importer.struct([ 'int x' ]).malloc
- begin
+ Fiddle::Importer.struct([ 'int x' ]).malloc(Fiddle::RUBY_FREE) do |struct|
ptr = struct.to_ptr
struct.x = 0x02020202
@@ -79,35 +98,25 @@ module Fiddle
ptr[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
assert_equal 0x01010101, struct.x
- ensure
- Fiddle.free struct.to_ptr
end
end
def test_malloc()
- s1 = LIBC::Timeval.malloc()
- begin
- s2 = LIBC::Timeval.malloc()
- begin
+ LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s1|
+ LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s2|
refute_equal(s1.to_ptr.to_i, s2.to_ptr.to_i)
- ensure
- Fiddle.free s2.to_ptr
end
- ensure
- Fiddle.free s1.to_ptr
end
end
def test_sizeof()
assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
- my_struct = LIBC::MyStruct.malloc()
- begin
+ LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |my_struct|
assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(my_struct))
- ensure
- Fiddle.free my_struct.to_ptr
end
assert_equal(SIZEOF_LONG_LONG, LIBC.sizeof("long long")) if defined?(SIZEOF_LONG_LONG)
+ assert_equal(LIBC::StructNestedStruct.size(), LIBC.sizeof(LIBC::StructNestedStruct))
end
Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(.*)/) do
@@ -158,8 +167,7 @@ module Fiddle
end
def test_struct_array_assignment()
- instance = Fiddle::Importer.struct(["unsigned int stages[3]"]).malloc
- begin
+ Fiddle::Importer.struct(["unsigned int stages[3]"]).malloc(Fiddle::RUBY_FREE) do |instance|
instance.stages[0] = 1024
instance.stages[1] = 10
instance.stages[2] = 100
@@ -170,39 +178,279 @@ module Fiddle
instance.to_ptr[0, 3 * Fiddle::SIZEOF_INT]
assert_raise(IndexError) { instance.stages[-1] = 5 }
assert_raise(IndexError) { instance.stages[3] = 5 }
- ensure
- Fiddle.free instance.to_ptr
+ end
+ end
+
+ def test_nested_struct_reusing_other_structs()
+ position_struct = Fiddle::Importer.struct(['float x', 'float y', 'float z'])
+ texcoord_struct = Fiddle::Importer.struct(['float u', 'float v'])
+ vertex_struct = Fiddle::Importer.struct(position: position_struct, texcoord: texcoord_struct)
+ mesh_struct = Fiddle::Importer.struct([
+ {
+ "vertices[2]" => vertex_struct,
+ object: [
+ "int id",
+ "void *user_data",
+ ],
+ },
+ "int id",
+ ])
+ assert_equal LIBC::StructNestedStruct.size, mesh_struct.size
+
+
+ keyboard_event_struct = Fiddle::Importer.struct(['unsigned int state', 'char key'])
+ mouse_event_struct = Fiddle::Importer.struct(['unsigned int button', 'unsigned short x', 'unsigned short y'])
+ event_union = Fiddle::Importer.union([{ keboard: keyboard_event_struct, mouse: mouse_event_struct}])
+ assert_equal LIBC::UnionNestedStruct.size, event_union.size
+ end
+
+ def test_nested_struct_alignment_is_not_its_size()
+ inner = Fiddle::Importer.struct(['int x', 'int y', 'int z', 'int w'])
+ outer = Fiddle::Importer.struct(['char a', { 'nested' => inner }, 'char b'])
+ outer.malloc(Fiddle::RUBY_FREE) do |instance|
+ offset = instance.to_ptr.instance_variable_get(:"@offset")
+ assert_equal Fiddle::SIZEOF_INT * 5, offset.last
+ assert_equal Fiddle::SIZEOF_INT * 6, outer.size
+ assert_equal instance.to_ptr.size, outer.size
+ end
+ end
+
+ def test_struct_nested_struct_members()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ Fiddle::Pointer.malloc(24, Fiddle::RUBY_FREE) do |user_data|
+ s.vertices[0].position.x = 1
+ s.vertices[0].position.y = 2
+ s.vertices[0].position.z = 3
+ s.vertices[0].texcoord.u = 4
+ s.vertices[0].texcoord.v = 5
+ s.vertices[1].position.x = 6
+ s.vertices[1].position.y = 7
+ s.vertices[1].position.z = 8
+ s.vertices[1].texcoord.u = 9
+ s.vertices[1].texcoord.v = 10
+ s.object.id = 100
+ s.object.user_data = user_data
+ s.id = 101
+ assert_equal({
+ "vertices" => [
+ {
+ "position" => {
+ "x" => 1,
+ "y" => 2,
+ "z" => 3,
+ },
+ "texcoord" => {
+ "u" => 4,
+ "v" => 5,
+ },
+ },
+ {
+ "position" => {
+ "x" => 6,
+ "y" => 7,
+ "z" => 8,
+ },
+ "texcoord" => {
+ "u" => 9,
+ "v" => 10,
+ },
+ },
+ ],
+ "object" => {
+ "id" => 100,
+ "user_data" => user_data,
+ },
+ "id" => 101,
+ },
+ s.to_h)
+ end
+ end
+ end
+
+ def test_union_nested_struct_members()
+ LIBC::UnionNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ s.keyboard.state = 100
+ s.keyboard.key = 101
+ assert_equal(100, s.mouse.button)
+ refute_equal( 0, s.mouse.x)
+ end
+ end
+
+ def test_struct_nested_struct_replace_array_element()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ s.vertices[0].position.x = 5
+
+ vertex_struct = Fiddle::Importer.struct [{
+ position: ["float x", "float y", "float z"],
+ texcoord: ["float u", "float v"]
+ }]
+ vertex_struct.malloc(Fiddle::RUBY_FREE) do |vertex|
+ vertex.position.x = 100
+ s.vertices[0] = vertex
+
+ # make sure element was copied by value, but things like memory address
+ # should not be changed
+ assert_equal(100, s.vertices[0].position.x)
+ refute_equal(vertex.object_id, s.vertices[0].object_id)
+ refute_equal(vertex.to_ptr, s.vertices[0].to_ptr)
+ end
+ end
+ end
+
+ def test_struct_nested_struct_replace_array_element_nil()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ s.vertices[0].position.x = 5
+ s.vertices[0] = nil
+ assert_equal({
+ "position" => {
+ "x" => 0.0,
+ "y" => 0.0,
+ "z" => 0.0,
+ },
+ "texcoord" => {
+ "u" => 0.0,
+ "v" => 0.0,
+ },
+ },
+ s.vertices[0].to_h)
+ end
+ end
+
+ def test_struct_nested_struct_replace_array_element_hash()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ s.vertices[0] = {
+ position: {
+ x: 10,
+ y: 100,
+ }
+ }
+ assert_equal({
+ "position" => {
+ "x" => 10.0,
+ "y" => 100.0,
+ "z" => 0.0,
+ },
+ "texcoord" => {
+ "u" => 0.0,
+ "v" => 0.0,
+ },
+ },
+ s.vertices[0].to_h)
+ end
+ end
+
+ def test_struct_nested_struct_replace_entire_array()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ vertex_struct = Fiddle::Importer.struct [{
+ position: ["float x", "float y", "float z"],
+ texcoord: ["float u", "float v"]
+ }]
+
+ vertex_struct.malloc(Fiddle::RUBY_FREE) do |same0|
+ vertex_struct.malloc(Fiddle::RUBY_FREE) do |same1|
+ same = [same0, same1]
+ same[0].position.x = 1; same[1].position.x = 6
+ same[0].position.y = 2; same[1].position.y = 7
+ same[0].position.z = 3; same[1].position.z = 8
+ same[0].texcoord.u = 4; same[1].texcoord.u = 9
+ same[0].texcoord.v = 5; same[1].texcoord.v = 10
+ s.vertices = same
+ assert_equal([
+ {
+ "position" => {
+ "x" => 1.0,
+ "y" => 2.0,
+ "z" => 3.0,
+ },
+ "texcoord" => {
+ "u" => 4.0,
+ "v" => 5.0,
+ },
+ },
+ {
+ "position" => {
+ "x" => 6.0,
+ "y" => 7.0,
+ "z" => 8.0,
+ },
+ "texcoord" => {
+ "u" => 9.0,
+ "v" => 10.0,
+ },
+ }
+ ],
+ s.vertices.collect(&:to_h))
+ end
+ end
+ end
+ end
+
+ def test_struct_nested_struct_replace_entire_array_with_different_struct()
+ LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
+ different_struct_same_size = Fiddle::Importer.struct [{
+ a: ['float i', 'float j', 'float k'],
+ b: ['float l', 'float m']
+ }]
+
+ different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different0|
+ different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different1|
+ different = [different0, different1]
+ different[0].a.i = 11; different[1].a.i = 16
+ different[0].a.j = 12; different[1].a.j = 17
+ different[0].a.k = 13; different[1].a.k = 18
+ different[0].b.l = 14; different[1].b.l = 19
+ different[0].b.m = 15; different[1].b.m = 20
+ s.vertices[0][0, s.vertices[0].class.size] = different[0].to_ptr
+ s.vertices[1][0, s.vertices[1].class.size] = different[1].to_ptr
+ assert_equal([
+ {
+ "position" => {
+ "x" => 11.0,
+ "y" => 12.0,
+ "z" => 13.0,
+ },
+ "texcoord" => {
+ "u" => 14.0,
+ "v" => 15.0,
+ },
+ },
+ {
+ "position" => {
+ "x" => 16.0,
+ "y" => 17.0,
+ "z" => 18.0,
+ },
+ "texcoord" => {
+ "u" => 19.0,
+ "v" => 20.0,
+ },
+ }
+ ],
+ s.vertices.collect(&:to_h))
+ end
+ end
end
end
def test_struct()
- s = LIBC::MyStruct.malloc()
- begin
+ LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |s|
s.num = [0,1,2,3,4]
s.c = ?a.ord
s.buff = "012345\377"
assert_equal([0,1,2,3,4], s.num)
assert_equal(?a.ord, s.c)
assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff)
- ensure
- Fiddle.free s.to_ptr
end
end
def test_gettimeofday()
if( defined?(LIBC.gettimeofday) )
- timeval = LIBC::Timeval.malloc()
- begin
- timezone = LIBC::Timezone.malloc()
- begin
+ LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |timeval|
+ LIBC::Timezone.malloc(Fiddle::RUBY_FREE) do |timezone|
LIBC.gettimeofday(timeval, timezone)
- ensure
- Fiddle.free timezone.to_ptr
end
cur = Time.now()
assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
- ensure
- Fiddle.free timeval.to_ptr
end
end
end
@@ -227,9 +475,5 @@ module Fiddle
r = LIBC.atof("12.34")
assert_includes(12.00..13.00, r)
end
-
- def test_no_message_with_debug
- assert_in_out_err(%w[--debug --disable=gems -rfiddle/import], 'p Fiddle::Importer', ['Fiddle::Importer'])
- end
end
end if defined?(Fiddle)