1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules java.base/jdk.internal.misc 27 */ 28 29 import java.lang.invoke.MethodHandles; 30 import java.nicl.*; 31 import java.nicl.metadata.*; 32 import java.nicl.metadata.Array; 33 import java.nicl.types.*; 34 35 public class PointerTest { 36 private static final boolean DEBUG = Boolean.getBoolean("PointerTest.DEBUG"); 37 38 private static final Library lib; 39 private static final pointers ptrs; 40 41 private static final String[] VERIFICATION_STRINGS = { 42 "String A", 43 "String B", 44 "String C" 45 }; 46 47 static { 48 lib = Libraries.loadLibrary(MethodHandles.lookup(), "Pointers"); 49 ptrs = Libraries.bind(pointers.class, lib); 50 } 51 52 @NativeHeader 53 static interface pointers { 54 @C(file="dummy", line=47, column=11, USR="c:@F@get_strings") 55 @CallingConvention(value=1) 56 @NativeType(layout="(p:p:p:cp:i)V", ctype="void (const char***, int*)", size=1l) 57 void get_strings(Pointer<Pointer<Pointer<Byte>>> p, Pointer<Integer> pcount); 58 59 @C(file="dummy", line=47, column=11, USR="c:@F@get_strings2") 60 @CallingConvention(value=1) 61 @NativeType(layout="(p:i)p:p:c", ctype="const char **(int *)", size=1l) 62 Pointer<Pointer<Byte>> get_strings2(Pointer<Integer> pcount); 63 64 @C(file="dummy", line=47, column=11, USR="c:@F@get_structs") 65 @CallingConvention(value=1) 66 @NativeType(layout="(p:p:p:[3ip:c]p:i)V", ctype="void (const struct MyStruct ***, int *)", size=1l) 67 void get_structs(Pointer<Pointer<Pointer<MyStruct>>> p, Pointer<Integer> pcount); 68 69 @C(file="dummy", line=47, column=11, USR="c:@F@get_structs2") 70 @CallingConvention(value=1) 71 @NativeType(layout="(p:i)p:p:[3ip:c]", ctype="const struct MyStruct **(int *)", size=1l) 72 Pointer<Pointer<MyStruct>> get_structs2(Pointer<Integer> pcount); 73 74 @NativeType(layout="[3ip:c]", ctype="dummy", size=24, isRecordType=true) 75 @C(file="dummy", line=47, column=11, USR="C:@S@MyStruct") 76 static interface MyStruct extends Struct<MyStruct> { 77 @Offset(offset=0l) 78 @C(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@ia") 79 @Array(elementType="int", elementSize=4l, length=3l) 80 @NativeType(layout="3i", ctype="int []", size=12l) 81 int[] ia$get(); 82 void ia$set(int[] i); 83 84 @Offset(offset=128l) 85 @C(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@str") 86 @NativeType(layout="p:c", ctype="const char*", size=4l) 87 Pointer<Byte> str$get(); 88 void str$set(Pointer<Byte> str); 89 } 90 } 91 92 private static void debug(String str) { 93 if (DEBUG) { 94 System.err.println(str); 95 } 96 } 97 98 private void verifyStrings(Pointer<Pointer<Byte>> values, Pointer<Integer> pi) { 99 debug("values: " + values); 100 debug("nvalues: " + pi.get()); 101 102 assertEquals(VERIFICATION_STRINGS.length, pi.get()); 103 104 for (int i = 0; i < pi.get(); i++) { 105 Pointer<Byte> cstr = values.offset(i).get(); 106 String str = Pointer.toString(cstr); 107 108 debug("str[" + i + "] = " + str); 109 110 assertEquals(VERIFICATION_STRINGS[i], str); 111 } 112 } 113 114 115 void testStrings() { 116 try (Scope scope = Scope.newNativeScope()) { 117 LayoutType<Integer> iType = NativeTypes.INT32; 118 LayoutType<Pointer<Pointer<Byte>>> ppcType = NativeTypes.UINT8.pointer().pointer(); 119 120 Pointer<Pointer<Pointer<Byte>>> pppc = scope.allocate(ppcType); 121 Pointer<Integer> pi = scope.allocate(iType); 122 123 ptrs.get_strings(pppc, pi); 124 125 Pointer<Pointer<Byte>> values = pppc.get(); 126 127 verifyStrings(values, pi); 128 } 129 } 130 131 void testStrings2() { 132 try (Scope scope = Scope.newNativeScope()) { 133 LayoutType<Integer> iType = NativeTypes.UINT32; 134 135 Pointer<Integer> pi = scope.allocate(iType); 136 137 Pointer<Pointer<Byte>> values = ptrs.get_strings2(pi); 138 139 verifyStrings(values, pi); 140 } 141 } 142 143 private void verifyStructs(Pointer<Pointer<pointers.MyStruct>> structs, Pointer<Integer> pi) { 144 debug("structs: " + structs); 145 debug("nstructs: " + pi.get()); 146 147 assertEquals(VERIFICATION_STRINGS.length, pi.get()); 148 149 int counter = 1; 150 151 for (int i = 0; i < pi.get(); i++) { 152 pointers.MyStruct s = structs.offset(i).get().get(); 153 String str = Pointer.toString(s.str$get()); 154 debug("str[" + i + "] = " + str); 155 156 assertEquals(VERIFICATION_STRINGS[i], str); 157 int[] ia = s.ia$get(); 158 159 assertEquals(3, ia.length); 160 161 for (int j = 0; j < ia.length; j++) { 162 assertEquals(counter++, ia[j]); 163 } 164 } 165 } 166 167 void testStructs() { 168 try (Scope scope = Scope.newNativeScope()) { 169 LayoutType<Integer> iType = NativeTypes.INT32; 170 LayoutType<Pointer<Pointer<pointers.MyStruct>>> ppsType = LayoutType.ofStruct(pointers.MyStruct.class).pointer().pointer(); 171 172 Pointer<Pointer<Pointer<pointers.MyStruct>>> ppps = scope.allocate(ppsType); 173 Pointer<Integer> pi = scope.allocate(iType); 174 175 ptrs.get_structs(ppps, pi); 176 177 Pointer<Pointer<pointers.MyStruct>> pps = ppps.get(); 178 179 verifyStructs(pps, pi); 180 } 181 } 182 183 void testStructs2() { 184 try (Scope scope = Scope.newNativeScope()) { 185 LayoutType<Integer> iType = NativeTypes.INT32; 186 187 Pointer<Integer> pi = scope.allocate(iType); 188 189 Pointer<Pointer<pointers.MyStruct>> pps = ptrs.get_structs2(pi); 190 191 verifyStructs(pps, pi); 192 } 193 } 194 195 public void test() { 196 testStrings(); 197 testStrings2(); 198 testStructs(); 199 testStructs2(); 200 } 201 202 static void assertEquals(Object expected, Object actual) { 203 if (!expected.equals(actual)) { 204 throw new RuntimeException("expected: " + expected + " does not match actual: " + actual); 205 } 206 } 207 208 public static void main(String[] args) { 209 PointerTest pt = new PointerTest(); 210 pt.test(); 211 } 212 }