File: UnionTest.java

package info (click to toggle)
libjna-java 5.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,828 kB
  • sloc: java: 90,222; ansic: 4,994; xml: 3,713; makefile: 433; sh: 299
file content (228 lines) | stat: -rw-r--r-- 8,603 bytes parent folder | download | duplicates (3)
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);
    }
}