1 /* 2 * Copyright (c) 2022, 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 /* @test 25 * @bug 8281412 26 * @summary Test FileChannel::map to MemorySegment with custom file channel 27 * @run testng/othervm MapToMemorySegmentTest 28 */ 29 30 import java.io.File; 31 import java.io.IOException; 32 import java.lang.foreign.Arena; 33 import java.lang.foreign.MemorySegment; 34 import java.nio.ByteBuffer; 35 import java.nio.MappedByteBuffer; 36 import java.nio.channels.FileChannel; 37 import java.nio.channels.FileLock; 38 import java.nio.channels.ReadableByteChannel; 39 import java.nio.channels.WritableByteChannel; 40 import java.nio.file.Path; 41 import java.nio.file.StandardOpenOption; 42 import org.testng.annotations.Test; 43 44 import static org.testng.Assert.assertTrue; 45 import static org.testng.Assert.fail; 46 47 public class MapToMemorySegmentTest { 48 49 static Path tempPath; 50 51 static { 52 try { 53 File file = File.createTempFile("foo", "txt"); 54 file.deleteOnExit(); 55 tempPath = file.toPath(); 56 } catch (IOException ex) { 57 throw new ExceptionInInitializerError(ex); 58 } 59 } 60 61 @Test(expectedExceptions = UnsupportedOperationException.class) 62 public void testCustomFileChannel() throws IOException { 63 var arena = Arena.ofConfined(); 64 var fc = FileChannel.open(tempPath, StandardOpenOption.WRITE, StandardOpenOption.READ); 65 var fileChannel = new CustomFileChannel(fc); 66 try (arena; fileChannel){ 67 fileChannel.map(FileChannel.MapMode.READ_WRITE, 1L, 10L, arena); 68 } 69 } 70 71 @Test 72 public void testCustomFileChannelOverride() throws IOException { 73 var arena = Arena.ofConfined(); 74 var fc = FileChannel.open(tempPath, StandardOpenOption.WRITE, StandardOpenOption.READ); 75 var fileChannel = new CustomFileChannelOverride(fc); 76 try (arena; fileChannel){ 77 fileChannel.map(FileChannel.MapMode.READ_WRITE, 1L, 10L, arena); 78 } 79 } 80 81 static class CustomFileChannel extends FileChannel { 82 FileChannel fc; 83 84 public CustomFileChannel(FileChannel fc) { 85 this.fc = fc; 86 } 87 88 public int read(ByteBuffer dst) throws IOException { 89 return fc.read(dst); 90 } 91 92 public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { 93 return fc.read(dsts, offset, length); 94 } 95 96 public int write(ByteBuffer src) throws IOException { 97 return fc.write(src); 98 } 99 100 public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { 101 return fc.write(srcs, offset, length); 102 } 103 104 public long position() throws IOException { 105 return fc.position(); 106 } 107 108 public FileChannel position(long newPosition) throws IOException { 109 return fc.position(newPosition); 110 } 111 112 public long size() throws IOException { 113 return fc.size(); 114 } 115 116 public FileChannel truncate(long size) throws IOException { 117 return fc.truncate(size); 118 } 119 120 public void force(boolean metaData) throws IOException { 121 this.fc.force(metaData); 122 } 123 124 public long transferTo(long position, long count, WritableByteChannel target) throws IOException { 125 return fc.transferTo(position, count, target); 126 } 127 128 public long transferFrom(ReadableByteChannel src, long position, long count) throws IOException { 129 return fc.transferFrom(src, position, count); 130 } 131 132 public int read(ByteBuffer dst, long position) throws IOException { 133 return fc.read(dst, position); 134 } 135 136 public int write(ByteBuffer src, long position) throws IOException { 137 return fc.write(src, position); 138 } 139 140 public MappedByteBuffer map(MapMode mode, long position, long size) throws IOException { 141 return fc.map(mode, position, size); 142 } 143 144 public FileLock lock(long position, long size, boolean shared) throws IOException { 145 return fc.lock(position, size, shared); 146 } 147 148 public FileLock tryLock(long position, long size, boolean shared) throws IOException { 149 return fc.tryLock(position , size, shared); 150 } 151 152 protected void implCloseChannel() throws IOException { 153 fc.close(); 154 } 155 } 156 157 static class CustomFileChannelOverride extends CustomFileChannel { 158 159 public CustomFileChannelOverride(FileChannel fc) { super(fc); } 160 161 @Override 162 public MemorySegment map(MapMode mode, long offset, long size, Arena arena) 163 throws IOException, UnsupportedOperationException 164 { 165 return fc.map(mode, offset, size, arena); 166 } 167 } 168 }