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 }
--- EOF ---