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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna;
import java.util.List;
import junit.framework.TestCase;
//@SuppressWarnings("unused")
public class UnionTest extends TestCase {
public static class TestStructure extends Structure {
public static final List<String> FIELDS = createFieldsOrder("value");
public String value;
@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
}
public static class BigTestStructure extends Structure {
public static final List<String> FIELDS = createFieldsOrder("field1", "field2");
public long field1;
public long field2;
@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
}
public static class IntStructure extends Structure {
public static final List<String> FIELDS = createFieldsOrder("value");
public int value;
@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
}
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("Wrong union size: " + u, 16, u.size());
assertEquals("Union should be size of largest field",
new BigTestStructure().size(), u.size());
}
public void testFieldOffsets() {
StructUnion u = new StructUnion();
assertEquals("Wrong union size: " + u, Native.POINTER_SIZE, u.size());
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);
assertNotNull("Union struct field should be initialized", u.structField);
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();
assertEquals("Wrong union size: " + u, Native.POINTER_SIZE, u.size());
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() {
@Override
public void callback() {
System.out.println("hi");
}
};
u.setTypedValue(func1);
}
public void testReadTypedUnion() {
StructUnion u = new StructUnion();
assertEquals("Wrong union size: " + u, Native.POINTER_SIZE, u.size());
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();
assertEquals("Wrong union size: " + u, 16, u.size());
assertNotNull("Type information is missing for union field of type " + BigTestStructure.class, Structure.getTypeInfo(BigTestStructure.class));
assertNotNull("Type information is missing for union instance", u.getTypeInfo());
if (Native.POINTER_SIZE == 4) {
assertEquals("Type size should be that of largest field if no field is active",
Structure.getTypeInfo(BigTestStructure.class).getPointer().getInt(0),
u.getTypeInfo().getInt(0));
}
else {
assertEquals("Type size should be that of largest field if no field is active",
Structure.getTypeInfo(BigTestStructure.class).getPointer().getLong(0),
u.getTypeInfo().getLong(0));
}
u.setType(int.class);
assertNotNull("Type information is missing for union field of type " + BigTestStructure.class, Structure.getTypeInfo(BigTestStructure.class));
assertNotNull("Type information is missing for union instance after type set", u.getTypeInfo());
if (Native.POINTER_SIZE == 4) {
assertEquals("Type size should be that of largest field if any field is active",
Structure.getTypeInfo(BigTestStructure.class).getPointer().getInt(0),
u.getTypeInfo().getInt(0));
}
else {
assertEquals("Type size should be that of largest field if any field is active",
Structure.getTypeInfo(BigTestStructure.class).getPointer().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();
assertEquals("Wrong union size: " + u, 16, u.size());
u.setType(byte[].class);
u.setType(short[].class);
u.setType(int[].class);
}
public void testDuplicateFieldTypes() {
class TestUnion extends Union {
public int field1;
public int field2;
}
TestUnion u = new TestUnion();
assertEquals("Wrong union size: " + u, 4, u.size());
u.setType("field1");
u.field1 = 42;
u.write();
u.setType("field2");
u.read();
assertEquals("Wrong field value after write/read", 42, u.field2);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(UnionTest.class);
}
}
|