Home | History | Annotate | Download | only in nio
      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