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 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@get_strings") 55 @NativeType(layout="(p:p:p:cp:i)V", ctype="void (const char***, int*)") 56 void get_strings(Pointer<Pointer<Pointer<Byte>>> p, Pointer<Integer> pcount); 57 58 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@get_strings2") 59 @NativeType(layout="(p:i)p:p:c", ctype="const char **(int *)") 60 Pointer<Pointer<Byte>> get_strings2(Pointer<Integer> pcount); 61 62 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@get_structs") 63 @NativeType(layout="(p:p:p:[3ip:c]p:i)V", ctype="void (const struct MyStruct ***, int *)" ) 64 void get_structs(Pointer<Pointer<Pointer<MyStruct>>> p, Pointer<Integer> pcount); 65 66 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@get_structs2") 67 @NativeType(layout="(p:i)p:p:[3ip:c]", ctype="const struct MyStruct **(int *)") 68 Pointer<Pointer<MyStruct>> get_structs2(Pointer<Integer> pcount); 69 70 @NativeLocation(file="dummy", line=47, column=11, USR="C:@S@MyStruct") 71 @NativeStruct("[3ip:c]") 72 static interface MyStruct extends Struct<MyStruct> { 73 @Offset(offset=0l) 74 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@ia") 75 @Array(elementType="int", elementSize=4l, length=3l) 76 @NativeType(layout="3i", ctype="int []") 77 int[] ia$get(); 78 void ia$set(int[] i); 79 80 @Offset(offset=128l) 81 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@str") 82 @NativeType(layout="p:c", ctype="const char*") 83 Pointer<Byte> str$get(); 84 void str$set(Pointer<Byte> str); 85 } 86 } 87 88 private static void debug(String str) { 89 if (DEBUG) { 90 System.err.println(str); 91 } 92 } 93 94 private void verifyStrings(Pointer<Pointer<Byte>> values, Pointer<Integer> pi) { 95 debug("values: " + values); 96 debug("nvalues: " + pi.get()); 97 98 assertEquals(VERIFICATION_STRINGS.length, pi.get()); 99 100 for (int i = 0; i < pi.get(); i++) { 101 Pointer<Byte> cstr = values.offset(i).get(); 102 String str = Pointer.toString(cstr); 103 104 debug("str[" + i + "] = " + str); 105 106 assertEquals(VERIFICATION_STRINGS[i], str); 107 } 108 } 109 110 111 void testStrings() { 112 try (Scope scope = Scope.newNativeScope()) { 113 LayoutType<Integer> iType = NativeTypes.INT32; 114 LayoutType<Pointer<Pointer<Byte>>> ppcType = NativeTypes.UINT8.pointer().pointer(); 115 116 Pointer<Pointer<Pointer<Byte>>> pppc = scope.allocate(ppcType); 117 Pointer<Integer> pi = scope.allocate(iType); 118 119 ptrs.get_strings(pppc, pi); 120 121 Pointer<Pointer<Byte>> values = pppc.get(); 122 123 verifyStrings(values, pi); 124 } 125 } 126 127 void testStrings2() { 128 try (Scope scope = Scope.newNativeScope()) { 129 LayoutType<Integer> iType = NativeTypes.UINT32; 130 131 Pointer<Integer> pi = scope.allocate(iType); 132 133 Pointer<Pointer<Byte>> values = ptrs.get_strings2(pi); 134 135 verifyStrings(values, pi); 136 } 137 } 138 139 private void verifyStructs(Pointer<Pointer<pointers.MyStruct>> structs, Pointer<Integer> pi) { 140 debug("structs: " + structs); 141 debug("nstructs: " + pi.get()); 142 143 assertEquals(VERIFICATION_STRINGS.length, pi.get()); 144 145 int counter = 1; 146 147 for (int i = 0; i < pi.get(); i++) { 148 pointers.MyStruct s = structs.offset(i).get().get(); 149 String str = Pointer.toString(s.str$get()); 150 debug("str[" + i + "] = " + str); 151 152 assertEquals(VERIFICATION_STRINGS[i], str); 153 int[] ia = s.ia$get(); 154 155 assertEquals(3, ia.length); 156 157 for (int j = 0; j < ia.length; j++) { 158 assertEquals(counter++, ia[j]); 159 } 160 } 161 } 162 163 void testStructs() { 164 try (Scope scope = Scope.newNativeScope()) { 165 LayoutType<Integer> iType = NativeTypes.INT32; 166 LayoutType<Pointer<Pointer<pointers.MyStruct>>> ppsType = LayoutType.ofStruct(pointers.MyStruct.class).pointer().pointer(); 167 168 Pointer<Pointer<Pointer<pointers.MyStruct>>> ppps = scope.allocate(ppsType); 169 Pointer<Integer> pi = scope.allocate(iType); 170 171 ptrs.get_structs(ppps, pi); 172 173 Pointer<Pointer<pointers.MyStruct>> pps = ppps.get(); 174 175 verifyStructs(pps, pi); 176 } 177 } 178 179 void testStructs2() { 180 try (Scope scope = Scope.newNativeScope()) { 181 LayoutType<Integer> iType = NativeTypes.INT32; 182 183 Pointer<Integer> pi = scope.allocate(iType); 184 185 Pointer<Pointer<pointers.MyStruct>> pps = ptrs.get_structs2(pi); 186 187 verifyStructs(pps, pi); 188 } 189 } 190 191 public void test() { 192 testStrings(); 193 testStrings2(); 194 testStructs(); 195 testStructs2(); 196 } 197 198 static void assertEquals(Object expected, Object actual) { 199 if (!expected.equals(actual)) { 200 throw new RuntimeException("expected: " + expected + " does not match actual: " + actual); 201 } 202 } 203 204 public static void main(String[] args) { 205 PointerTest pt = new PointerTest(); 206 pt.test(); 207 } 208 }