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// BEGIN android-note
19// This test was copied from a newer version of Harmony
20// END android-note
21
22package org.apache.harmony.nio.tests.java.nio;
23
24import dalvik.annotation.TestLevel;
25import dalvik.annotation.TestTargetNew;
26import dalvik.annotation.TestTargetClass;
27
28import java.io.File;
29import java.io.FileInputStream;
30import java.io.FileOutputStream;
31import java.io.IOException;
32import java.io.RandomAccessFile;
33import java.nio.ByteBuffer;
34import java.nio.IntBuffer;
35import java.nio.MappedByteBuffer;
36import java.nio.channels.FileChannel;
37import java.nio.channels.FileChannel.MapMode;
38
39@TestTargetClass(
40    value = MappedByteBuffer.class,
41    untestedMethods = {
42        @TestTargetNew(
43            level = TestLevel.NOT_FEASIBLE,
44            method = "isLoaded",
45            args = {}
46        )
47    }
48)
49public class MappedByteBufferTest extends DirectByteBufferTest {
50
51    File tmpFile;
52    FileChannel fc;
53
54    /**
55     * A regression test for failing to correctly set capacity of underlying
56     * wrapped buffer from a mapped byte buffer.
57     */
58    @TestTargetNew(
59        level = TestLevel.PARTIAL_COMPLETE,
60        notes = "A regression test for failing to correctly set capacity",
61        method = "asIntBuffer",
62        args = {}
63    )
64    public void test_asIntBuffer() {
65        int len = buf.capacity();
66        assertEquals("Got wrong number of bytes", BUFFER_LENGTH, len); //$NON-NLS-1$
67
68        // Read in our 26 bytes
69        for (int i = 0; i < BUFFER_LENGTH - 20; i++) {
70            byte b = buf.get();
71            assertEquals("Got wrong byte value", (byte) i, b); //$NON-NLS-1$
72        }
73
74        // Now convert to an IntBuffer to read our ints
75        IntBuffer ibuffer = buf.asIntBuffer();
76        for (int i = BUFFER_LENGTH - 20; i < BUFFER_LENGTH; i+=4) {
77            int val = ibuffer.get();
78            int res = i * 16777216 + (i + 1) * 65536 + (i + 2) * 256 + (i + 3);
79            assertEquals("Got wrong int value", res, val); //$NON-NLS-1$
80        }
81    }
82
83    /**
84     * @tests {@link java.nio.MappedByteBuffer#force()}
85     */
86    @TestTargetNew(
87        level = TestLevel.COMPLETE,
88        notes = "",
89        method = "force",
90        args = {}
91    )
92    public void test_force() throws IOException {
93        // buffer was not mapped in read/write mode
94        FileInputStream fileInputStream = new FileInputStream(tmpFile);
95        FileChannel fileChannelRead = fileInputStream.getChannel();
96        MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
97                fileChannelRead.size());
98
99        mmbRead.force();
100
101        FileInputStream inputStream = new FileInputStream(tmpFile);
102        FileChannel fileChannelR = inputStream.getChannel();
103        MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0,
104                fileChannelR.size());
105
106        //If this buffer was not mapped in read/write mode, then invoking this method has no effect.
107        assertEquals(
108                "Invoking force() should have no effect when this buffer was not mapped in read/write mode",
109                mmbRead, resultRead);
110
111        // Buffer was mapped in read/write mode
112        RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
113        FileChannel fileChannelReadWrite = randomFile.getChannel();
114        MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
115                FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
116
117        mmbReadWrite.put((byte) 'o');
118        mmbReadWrite.force();
119
120        RandomAccessFile random = new RandomAccessFile(tmpFile, "rw");
121        FileChannel fileChannelRW = random.getChannel();
122        MappedByteBuffer resultReadWrite = fileChannelRW.map(
123                FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size());
124
125        // Invoking force() will change the buffer
126        assertFalse(mmbReadWrite.equals(resultReadWrite));
127
128        fileChannelRead.close();
129        fileChannelR.close();
130        fileChannelReadWrite.close();
131        fileChannelRW.close();
132    }
133
134    /**
135     * @tests {@link java.nio.MappedByteBuffer#load()}
136     */
137    @TestTargetNew(
138        level = TestLevel.COMPLETE,
139        notes = "",
140        method = "load",
141        args = {}
142    )
143    public void test_load() throws IOException {
144        FileInputStream fileInputStream = new FileInputStream(tmpFile);
145        FileChannel fileChannelRead = fileInputStream.getChannel();
146        MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
147                fileChannelRead.size());
148
149        assertEquals(mmbRead, mmbRead.load());
150
151        RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
152        FileChannel fileChannelReadWrite = randomFile.getChannel();
153        MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
154                FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
155
156        assertEquals(mmbReadWrite, mmbReadWrite.load());
157
158        fileChannelRead.close();
159        fileChannelReadWrite.close();
160    }
161
162    protected void setUp() throws IOException {
163        // Create temp file with 26 bytes and 5 ints
164        tmpFile = File.createTempFile("MappedByteBufferTest", ".tmp");  //$NON-NLS-1$//$NON-NLS-2$
165        tmpFile.createNewFile();
166        tmpFile.deleteOnExit();
167
168        fillTempFile();
169
170        // Map file
171        RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
172        fc = raf.getChannel();
173        capacity = (int) fc.size();
174        buf = fc.map(FileChannel.MapMode.READ_WRITE, 0, capacity);
175        baseBuf = buf;
176    }
177
178    protected void tearDown() throws IOException {
179        fc.close();
180    }
181
182    private void fillTempFile() throws IOException {
183        FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
184        FileChannel fileChannel = fileOutputStream.getChannel();
185        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_LENGTH);
186
187        loadTestData1(byteBuffer);
188        byteBuffer.clear();
189        fileChannel.write(byteBuffer);
190
191        fileChannel.close();
192        fileOutputStream.close();
193    }
194}