1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.nio.tests.java.nio; 19 20 import java.io.File; 21 import java.io.FileInputStream; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.RandomAccessFile; 25 import java.nio.BufferUnderflowException; 26 import java.nio.ByteBuffer; 27 import java.nio.IntBuffer; 28 import java.nio.MappedByteBuffer; 29 import java.nio.channels.FileChannel; 30 import java.nio.channels.NonWritableChannelException; 31 import java.nio.channels.FileChannel.MapMode; 32 33 import junit.framework.TestCase; 34 35 public class MappedByteBufferTest extends TestCase { 36 37 File tmpFile, emptyFile; 38 39 /** 40 * A regression test for failing to correctly set capacity of underlying 41 * wrapped buffer from a mapped byte buffer. 42 */ 43 public void testasIntBuffer() throws IOException { 44 // Map file 45 FileInputStream fis = new FileInputStream(tmpFile); 46 FileChannel fc = fis.getChannel(); 47 MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc 48 .size()); 49 int len = mmb.capacity(); 50 assertEquals("Got wrong number of bytes", 46, len); //$NON-NLS-1$ 51 52 // Read in our 26 bytes 53 for (int i = 0; i < 26; i++) { 54 byte b = mmb.get(); 55 assertEquals("Got wrong byte value", (byte) 'A' + i, b); //$NON-NLS-1$ 56 } 57 58 // Now convert to an IntBuffer to read our ints 59 IntBuffer ibuffer = mmb.asIntBuffer(); 60 for (int i = 0; i < 5; i++) { 61 int val = ibuffer.get(); 62 assertEquals("Got wrong int value", i + 1, val); //$NON-NLS-1$ 63 } 64 fc.close(); 65 } 66 67 /** 68 * Regression for HARMONY-6315 - FileChannel.map throws IOException 69 * when called with size 0 70 * 71 * @throws IOException 72 */ 73 public void testEmptyBuffer() throws IOException { 74 // Map empty file 75 FileInputStream fis = new FileInputStream(emptyFile); 76 FileChannel fc = fis.getChannel(); 77 MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 78 79 // check non-null 80 assertNotNull("MappedByteBuffer created from empty file should not be null", 81 mmb); 82 83 // check capacity is 0 84 int len = mmb.capacity(); 85 assertEquals("MappedByteBuffer created from empty file should have 0 capacity", 86 0, len); 87 88 assertFalse("MappedByteBuffer from empty file shouldn't be backed by an array ", 89 mmb.hasArray()); 90 91 try 92 { 93 byte b = mmb.get(); 94 fail("Calling MappedByteBuffer.get() on empty buffer should throw a BufferUnderflowException"); 95 } 96 catch (BufferUnderflowException e) 97 { 98 // expected behaviour 99 } 100 101 // test expected exceptions thrown 102 try 103 { 104 mmb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()); 105 fail("Expected NonWritableChannelException to be thrown"); 106 } 107 catch (NonWritableChannelException e) 108 { 109 // expected behaviour 110 } 111 try 112 { 113 mmb = fc.map(FileChannel.MapMode.PRIVATE, 0, fc.size()); 114 fail("Expected NonWritableChannelException to be thrown"); 115 } 116 catch (NonWritableChannelException e) 117 { 118 // expected behaviour 119 } 120 fc.close(); 121 } 122 123 /** 124 * @tests {@link java.nio.MappedByteBuffer#force()} 125 */ 126 public void test_force() throws IOException { 127 // buffer was not mapped in read/write mode 128 FileInputStream fileInputStream = new FileInputStream(tmpFile); 129 FileChannel fileChannelRead = fileInputStream.getChannel(); 130 MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0, 131 fileChannelRead.size()); 132 133 mmbRead.force(); 134 135 FileInputStream inputStream = new FileInputStream(tmpFile); 136 FileChannel fileChannelR = inputStream.getChannel(); 137 MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0, 138 fileChannelR.size()); 139 140 //If this buffer was not mapped in read/write mode, then invoking this method has no effect. 141 assertEquals( 142 "Invoking force() should have no effect when this buffer was not mapped in read/write mode", 143 mmbRead, resultRead); 144 145 // Buffer was mapped in read/write mode 146 RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw"); 147 FileChannel fileChannelReadWrite = randomFile.getChannel(); 148 MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map( 149 FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size()); 150 151 mmbReadWrite.put((byte) 'o'); 152 mmbReadWrite.force(); 153 154 RandomAccessFile random = new RandomAccessFile(tmpFile, "rw"); 155 FileChannel fileChannelRW = random.getChannel(); 156 MappedByteBuffer resultReadWrite = fileChannelRW.map( 157 FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size()); 158 159 // Invoking force() will change the buffer 160 assertFalse(mmbReadWrite.equals(resultReadWrite)); 161 162 fileChannelRead.close(); 163 fileChannelR.close(); 164 fileChannelReadWrite.close(); 165 fileChannelRW.close(); 166 } 167 168 /** 169 * @tests {@link java.nio.MappedByteBuffer#load()} 170 */ 171 public void test_load() throws IOException { 172 FileInputStream fileInputStream = new FileInputStream(tmpFile); 173 FileChannel fileChannelRead = fileInputStream.getChannel(); 174 MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0, 175 fileChannelRead.size()); 176 177 assertEquals(mmbRead, mmbRead.load()); 178 179 RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw"); 180 FileChannel fileChannelReadWrite = randomFile.getChannel(); 181 MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map( 182 FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size()); 183 184 assertEquals(mmbReadWrite, mmbReadWrite.load()); 185 186 fileChannelRead.close(); 187 fileChannelReadWrite.close(); 188 } 189 190 protected void setUp() throws IOException { 191 // Create temp file with 26 bytes and 5 ints 192 tmpFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$ 193 tmpFile.deleteOnExit(); 194 FileOutputStream fileOutputStream = new FileOutputStream(tmpFile); 195 FileChannel fileChannel = fileOutputStream.getChannel(); 196 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(26 + 20); 197 for (int i = 0; i < 26; i++) { 198 byteBuffer.put((byte) ('A' + i)); 199 } 200 for (int i = 0; i < 5; i++) { 201 byteBuffer.putInt(i + 1); 202 } 203 byteBuffer.rewind(); 204 fileChannel.write(byteBuffer); 205 fileChannel.close(); 206 fileOutputStream.close(); 207 208 emptyFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$ 209 emptyFile.deleteOnExit(); 210 } 211 212 public void test_position() throws IOException { 213 File tmp = File.createTempFile("hmy", "tmp"); 214 tmp.deleteOnExit(); 215 RandomAccessFile f = new RandomAccessFile(tmp, "rw"); 216 FileChannel ch = f.getChannel(); 217 MappedByteBuffer mbb = ch.map(MapMode.READ_WRITE, 0L, 100L); 218 ch.close(); 219 220 mbb.putInt(1, 1); 221 mbb.position(50); 222 mbb.putInt(50); 223 224 mbb.flip(); 225 mbb.get(); 226 assertEquals(1, mbb.getInt()); 227 228 mbb.position(50); 229 assertEquals(50, mbb.getInt()); 230 } 231 } 232