/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 for more details.
*/
package com.sun.jna;
import junit.framework.TestCase;
public class UnionTest extends TestCase {
public static class TestStructure extends Structure {
public String value;
}
public static class BigTestStructure extends Structure {
public long field1;
public long field2;
}
public static class IntStructure extends Structure {
public int value;
}
public static class SubIntStructure extends IntStructure {}
public static interface Func1 extends Callback {
public void callback();
}
public static class SizedUnion extends Union {
public byte byteField;
public short shortField;
public int intField;
public long longField;
public TestStructure structField;
public BigTestStructure structField2;
public String string;
public WString wstring;
public Pointer pointer;
}
public static class StructUnion extends Union {
public int intField;
public TestStructure testStruct;
public IntStructure intStruct;
public Func1 func1;
}
public void testCalculateSize() {
Union u = new SizedUnion();
assertEquals("Union should be size of largest field",
new BigTestStructure().size(), u.size());
}
public void testFieldOffsets() {
StructUnion u = new StructUnion();
u.setType(u.testStruct.getClass());
u.write();
assertEquals("Wrong struct member base address",
u.getPointer(), u.testStruct.getPointer());
u.setType(u.intStruct.getClass());
u.write();
assertEquals("Wrong struct member base address (2)",
u.getPointer(), u.intStruct.getPointer());
}
public void testWriteUnion() {
SizedUnion u = new SizedUnion();
final int VALUE = 0x12345678;
u.intField = VALUE;
u.setType(int.class);
u.write();
assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0));
}
public void testReadUnion() {
SizedUnion u = new SizedUnion();
final int VALUE = 0x12345678;
u.getPointer().setInt(0, VALUE);
u.read();
assertEquals("int field not read properly", VALUE, u.intField);
assertTrue("byte field not read", u.byteField != 0);
assertTrue("short field not read", u.shortField != 0);
assertTrue("long field not read", u.longField != 0);
assertNotNull("Unselected Pointer not read", u.pointer);
assertNull("Unselected structure should not be read", u.structField.value);
assertNull("Unselected String should be null", u.string);
assertNull("Unselected WString should be null", u.wstring);
}
public void testWriteTypedUnion() {
final int VALUE = 0x12345678;
// write an instance of a direct union class to memory
StructUnion u = new StructUnion();
IntStructure intStruct = new IntStructure();
intStruct.value = VALUE;
u.setTypedValue(intStruct);
u.write();
assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0));
// write an instance of a sub class of an union class to memory
u = new StructUnion();
SubIntStructure subIntStructure = new SubIntStructure();
subIntStructure.value = VALUE;
u.setTypedValue(subIntStructure);
u.write();
assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0));
// write an instance of an interface
u = new StructUnion();
Func1 func1 = new Func1() {
public void callback() {
System.out.println("hi");
}
};
u.setTypedValue(func1);
}
public void testReadTypedUnion() {
StructUnion u = new StructUnion();
final int VALUE = 0x12345678;
u.getPointer().setInt(0, VALUE);
assertEquals("int structure not read properly", VALUE, ((IntStructure) u.getTypedValue(IntStructure.class)).value);
}
public void testReadTypeInfo() {
SizedUnion u = new SizedUnion();
if (Native.POINTER_SIZE == 4) {
assertEquals("Type size should be that of longest field if no field active",
Structure.getTypeInfo(BigTestStructure.class).getInt(0),
u.getTypeInfo().getInt(0));
}
else {
assertEquals("Type size should be that of longest field if no field active",
Structure.getTypeInfo(BigTestStructure.class).getLong(0),
u.getTypeInfo().getLong(0));
}
u.setType(int.class);
if (Native.POINTER_SIZE == 4) {
assertEquals("Type size should be that of longest field if field active",
Structure.getTypeInfo(BigTestStructure.class).getInt(0),
u.getTypeInfo().getInt(0));
}
else {
assertEquals("Type size should be that of longest field if field active",
Structure.getTypeInfo(BigTestStructure.class).getLong(0),
u.getTypeInfo().getLong(0));
}
}
public void testArraysInUnion() {
class TestUnion extends Union {
public byte[] bytes = new byte[16];
public short[] shorts = new short[8];
public int[] ints = new int[4];
}
Union u = new TestUnion();
u.setType(byte[].class);
u.setType(short[].class);
u.setType(int[].class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(UnionTest.class);
}
}