BufferTest.java revision a47f80079c7147f6edc83ae812435326bd82dd40
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.nio;
18
19import java.io.*;
20import java.nio.*;
21import java.nio.channels.*;
22import java.util.Arrays;
23import junit.framework.TestCase;
24
25public class BufferTest extends TestCase {
26    private static ByteBuffer allocateMapped(int size) throws Exception {
27        File f = File.createTempFile("mapped", "tmp");
28        f.deleteOnExit();
29        RandomAccessFile raf = new RandomAccessFile(f, "rw");
30        raf.setLength(size);
31        FileChannel ch = raf.getChannel();
32        MappedByteBuffer result = ch.map(FileChannel.MapMode.READ_WRITE, 0, size);
33        ch.close();
34        return result;
35    }
36
37    public void testByteSwappedBulkGetDirect() throws Exception {
38        testByteSwappedBulkGet(ByteBuffer.allocateDirect(10));
39    }
40
41    public void testByteSwappedBulkGetHeap() throws Exception {
42        testByteSwappedBulkGet(ByteBuffer.allocate(10));
43    }
44
45    public void testByteSwappedBulkGetMapped() throws Exception {
46        testByteSwappedBulkGet(allocateMapped(10));
47    }
48
49    private void testByteSwappedBulkGet(ByteBuffer b) throws Exception {
50        for (int i = 0; i < b.limit(); ++i) {
51            b.put(i, (byte) i);
52        }
53        b.position(1);
54
55        char[] chars = new char[6];
56        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(chars, 1, 4);
57        assertEquals("[\u0000, \u0102, \u0304, \u0506, \u0708, \u0000]", Arrays.toString(chars));
58        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().get(chars, 1, 4);
59        assertEquals("[\u0000, \u0201, \u0403, \u0605, \u0807, \u0000]", Arrays.toString(chars));
60
61        double[] doubles = new double[3];
62        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
63        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
64        assertEquals(0x0102030405060708L, Double.doubleToRawLongBits(doubles[1]));
65        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
66        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
67        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
68        assertEquals(0x0807060504030201L, Double.doubleToRawLongBits(doubles[1]));
69        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
70
71        float[] floats = new float[4];
72        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().get(floats, 1, 2);
73        assertEquals(0, Float.floatToRawIntBits(floats[0]));
74        assertEquals(0x01020304, Float.floatToRawIntBits(floats[1]));
75        assertEquals(0x05060708, Float.floatToRawIntBits(floats[2]));
76        assertEquals(0, Float.floatToRawIntBits(floats[3]));
77        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().get(floats, 1, 2);
78        assertEquals(0, Float.floatToRawIntBits(floats[0]));
79        assertEquals(0x04030201, Float.floatToRawIntBits(floats[1]));
80        assertEquals(0x08070605, Float.floatToRawIntBits(floats[2]));
81        assertEquals(0, Float.floatToRawIntBits(floats[3]));
82
83        int[] ints = new int[4];
84        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().get(ints, 1, 2);
85        assertEquals(0, ints[0]);
86        assertEquals(0x01020304, ints[1]);
87        assertEquals(0x05060708, ints[2]);
88        assertEquals(0, ints[3]);
89        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(ints, 1, 2);
90        assertEquals(0, ints[0]);
91        assertEquals(0x04030201, ints[1]);
92        assertEquals(0x08070605, ints[2]);
93        assertEquals(0, ints[3]);
94
95        long[] longs = new long[3];
96        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().get(longs, 1, 1);
97        assertEquals(0, longs[0]);
98        assertEquals(0x0102030405060708L, longs[1]);
99        assertEquals(0, longs[2]);
100        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().get(longs, 1, 1);
101        assertEquals(0, longs[0]);
102        assertEquals(0x0807060504030201L, longs[1]);
103        assertEquals(0, longs[2]);
104
105        short[] shorts = new short[6];
106        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(shorts, 1, 4);
107        assertEquals(0, shorts[0]);
108        assertEquals(0x0102, shorts[1]);
109        assertEquals(0x0304, shorts[2]);
110        assertEquals(0x0506, shorts[3]);
111        assertEquals(0x0708, shorts[4]);
112        assertEquals(0, shorts[5]);
113        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts, 1, 4);
114        assertEquals(0, shorts[0]);
115        assertEquals(0x0201, shorts[1]);
116        assertEquals(0x0403, shorts[2]);
117        assertEquals(0x0605, shorts[3]);
118        assertEquals(0x0807, shorts[4]);
119        assertEquals(0, shorts[5]);
120    }
121
122    private static String toString(ByteBuffer b) {
123        StringBuilder result = new StringBuilder();
124        for (int i = 0; i < b.limit(); ++i) {
125            result.append(String.format("%02x", (int) b.get(i)));
126        }
127        return result.toString();
128    }
129
130    public void testByteSwappedBulkPutDirect() throws Exception {
131        testByteSwappedBulkPut(ByteBuffer.allocateDirect(10));
132    }
133
134    public void testByteSwappedBulkPutHeap() throws Exception {
135        testByteSwappedBulkPut(ByteBuffer.allocate(10));
136    }
137
138    public void testByteSwappedBulkPutMapped() throws Exception {
139        testByteSwappedBulkPut(allocateMapped(10));
140    }
141
142    private void testByteSwappedBulkPut(ByteBuffer b) throws Exception {
143        b.position(1);
144
145        char[] chars = new char[] { '\u2222', '\u0102', '\u0304', '\u0506', '\u0708', '\u2222' };
146        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().put(chars, 1, 4);
147        assertEquals("00010203040506070800", toString(b));
148        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().put(chars, 1, 4);
149        assertEquals("00020104030605080700", toString(b));
150
151        double[] doubles = new double[] { 0, Double.longBitsToDouble(0x0102030405060708L), 0 };
152        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
153        assertEquals("00010203040506070800", toString(b));
154        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
155        assertEquals("00080706050403020100", toString(b));
156
157        float[] floats = new float[] { 0, Float.intBitsToFloat(0x01020304),
158                Float.intBitsToFloat(0x05060708), 0 };
159        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().put(floats, 1, 2);
160        assertEquals("00010203040506070800", toString(b));
161        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().put(floats, 1, 2);
162        assertEquals("00040302010807060500", toString(b));
163
164        int[] ints = new int[] { 0, 0x01020304, 0x05060708, 0 };
165        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().put(ints, 1, 2);
166        assertEquals("00010203040506070800", toString(b));
167        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(ints, 1, 2);
168        assertEquals("00040302010807060500", toString(b));
169
170        long[] longs = new long[] { 0, 0x0102030405060708L, 0 };
171        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().put(longs, 1, 1);
172        assertEquals("00010203040506070800", toString(b));
173        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(longs, 1, 1);
174        assertEquals("00080706050403020100", toString(b));
175
176        short[] shorts = new short[] { 0, 0x0102, 0x0304, 0x0506, 0x0708, 0 };
177        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().put(shorts, 1, 4);
178        assertEquals("00010203040506070800", toString(b));
179        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shorts, 1, 4);
180        assertEquals("00020104030605080700", toString(b));
181    }
182
183    public void testByteBufferByteOrderDirectRW() throws Exception {
184        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), false);
185    }
186
187    public void testByteBufferByteOrderHeapRW() throws Exception {
188        testByteBufferByteOrder(ByteBuffer.allocate(10), false);
189    }
190
191    public void testByteBufferByteOrderMappedRW() throws Exception {
192        testByteBufferByteOrder(allocateMapped(10), false);
193    }
194
195    public void testByteBufferByteOrderDirectRO() throws Exception {
196        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), true);
197    }
198
199    public void testByteBufferByteOrderHeapRO() throws Exception {
200        testByteBufferByteOrder(ByteBuffer.allocate(10), true);
201    }
202
203    public void testByteBufferByteOrderMappedRO() throws Exception {
204        testByteBufferByteOrder(allocateMapped(10), true);
205    }
206
207    private void testByteBufferByteOrder(ByteBuffer b, boolean readOnly) throws Exception {
208        if (readOnly) {
209            b = b.asReadOnlyBuffer();
210        }
211        // allocate/allocateDirect/map always returns a big-endian buffer.
212        assertEquals(ByteOrder.BIG_ENDIAN, b.order());
213
214        // wrap always returns a big-endian buffer.
215        assertEquals(ByteOrder.BIG_ENDIAN, b.wrap(new byte[10]).order());
216
217        // duplicate always returns a big-endian buffer.
218        b.order(ByteOrder.BIG_ENDIAN);
219        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
220        b.order(ByteOrder.LITTLE_ENDIAN);
221        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
222
223        // slice always returns a big-endian buffer.
224        b.order(ByteOrder.BIG_ENDIAN);
225        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
226        b.order(ByteOrder.LITTLE_ENDIAN);
227        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
228
229        // asXBuffer always returns a current-endian buffer.
230        b.order(ByteOrder.BIG_ENDIAN);
231        assertEquals(ByteOrder.BIG_ENDIAN, b.asCharBuffer().order());
232        assertEquals(ByteOrder.BIG_ENDIAN, b.asDoubleBuffer().order());
233        assertEquals(ByteOrder.BIG_ENDIAN, b.asFloatBuffer().order());
234        assertEquals(ByteOrder.BIG_ENDIAN, b.asIntBuffer().order());
235        assertEquals(ByteOrder.BIG_ENDIAN, b.asLongBuffer().order());
236        assertEquals(ByteOrder.BIG_ENDIAN, b.asShortBuffer().order());
237        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
238        b.order(ByteOrder.LITTLE_ENDIAN);
239        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asCharBuffer().order());
240        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asDoubleBuffer().order());
241        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asFloatBuffer().order());
242        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asIntBuffer().order());
243        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asLongBuffer().order());
244        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asShortBuffer().order());
245        // ...except for asReadOnlyBuffer, which always returns a big-endian buffer.
246        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
247    }
248
249    public void testCharBufferByteOrder() throws Exception {
250        // Everything always returns a native-endian buffer.
251        CharBuffer b = CharBuffer.allocate(10);
252        assertEquals(ByteOrder.nativeOrder(), b.order());
253        assertEquals(ByteOrder.nativeOrder(), b.wrap(new char[10]).order());
254        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
255        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
256        b = b.asReadOnlyBuffer();
257        assertEquals(ByteOrder.nativeOrder(), b.order());
258        assertEquals(ByteOrder.nativeOrder(), b.wrap(new char[10]).order());
259        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
260        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
261        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
262        ByteBuffer bb = ByteBuffer.allocate(10);
263        bb.order(ByteOrder.BIG_ENDIAN);
264        assertEquals(ByteOrder.BIG_ENDIAN, bb.asCharBuffer().asReadOnlyBuffer().order());
265        bb.order(ByteOrder.LITTLE_ENDIAN);
266        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asCharBuffer().asReadOnlyBuffer().order());
267    }
268
269    public void testDoubleBufferByteOrder() throws Exception {
270        // Everything always returns a native-endian buffer.
271        DoubleBuffer b = DoubleBuffer.allocate(10);
272        assertEquals(ByteOrder.nativeOrder(), b.order());
273        assertEquals(ByteOrder.nativeOrder(), b.wrap(new double[10]).order());
274        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
275        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
276        b = b.asReadOnlyBuffer();
277        assertEquals(ByteOrder.nativeOrder(), b.order());
278        assertEquals(ByteOrder.nativeOrder(), b.wrap(new double[10]).order());
279        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
280        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
281        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
282        ByteBuffer bb = ByteBuffer.allocate(10);
283        bb.order(ByteOrder.BIG_ENDIAN);
284        assertEquals(ByteOrder.BIG_ENDIAN, bb.asDoubleBuffer().asReadOnlyBuffer().order());
285        bb.order(ByteOrder.LITTLE_ENDIAN);
286        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asDoubleBuffer().asReadOnlyBuffer().order());
287    }
288
289    public void testFloatBufferByteOrder() throws Exception {
290        // Everything always returns a native-endian buffer.
291        FloatBuffer b = FloatBuffer.allocate(10);
292        assertEquals(ByteOrder.nativeOrder(), b.order());
293        assertEquals(ByteOrder.nativeOrder(), b.wrap(new float[10]).order());
294        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
295        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
296        b = b.asReadOnlyBuffer();
297        assertEquals(ByteOrder.nativeOrder(), b.order());
298        assertEquals(ByteOrder.nativeOrder(), b.wrap(new float[10]).order());
299        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
300        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
301        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
302        ByteBuffer bb = ByteBuffer.allocate(10);
303        bb.order(ByteOrder.BIG_ENDIAN);
304        assertEquals(ByteOrder.BIG_ENDIAN, bb.asFloatBuffer().asReadOnlyBuffer().order());
305        bb.order(ByteOrder.LITTLE_ENDIAN);
306        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asFloatBuffer().asReadOnlyBuffer().order());
307    }
308
309    public void testIntBufferByteOrder() throws Exception {
310        // Everything always returns a native-endian buffer.
311        IntBuffer b = IntBuffer.allocate(10);
312        assertEquals(ByteOrder.nativeOrder(), b.order());
313        assertEquals(ByteOrder.nativeOrder(), b.wrap(new int[10]).order());
314        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
315        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
316        b = b.asReadOnlyBuffer();
317        assertEquals(ByteOrder.nativeOrder(), b.order());
318        assertEquals(ByteOrder.nativeOrder(), b.wrap(new int[10]).order());
319        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
320        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
321        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
322        ByteBuffer bb = ByteBuffer.allocate(10);
323        bb.order(ByteOrder.BIG_ENDIAN);
324        assertEquals(ByteOrder.BIG_ENDIAN, bb.asIntBuffer().asReadOnlyBuffer().order());
325        bb.order(ByteOrder.LITTLE_ENDIAN);
326        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asIntBuffer().asReadOnlyBuffer().order());
327    }
328
329    public void testLongBufferByteOrder() throws Exception {
330        // Everything always returns a native-endian buffer.
331        LongBuffer b = LongBuffer.allocate(10);
332        assertEquals(ByteOrder.nativeOrder(), b.order());
333        assertEquals(ByteOrder.nativeOrder(), b.wrap(new long[10]).order());
334        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
335        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
336        b = b.asReadOnlyBuffer();
337        assertEquals(ByteOrder.nativeOrder(), b.order());
338        assertEquals(ByteOrder.nativeOrder(), b.wrap(new long[10]).order());
339        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
340        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
341        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
342        ByteBuffer bb = ByteBuffer.allocate(10);
343        bb.order(ByteOrder.BIG_ENDIAN);
344        assertEquals(ByteOrder.BIG_ENDIAN, bb.asLongBuffer().asReadOnlyBuffer().order());
345        bb.order(ByteOrder.LITTLE_ENDIAN);
346        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asLongBuffer().asReadOnlyBuffer().order());
347    }
348
349    public void testShortBufferByteOrder() throws Exception {
350        // Everything always returns a native-endian buffer.
351        ShortBuffer b = ShortBuffer.allocate(10);
352        assertEquals(ByteOrder.nativeOrder(), b.order());
353        assertEquals(ByteOrder.nativeOrder(), b.wrap(new short[10]).order());
354        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
355        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
356        b = b.asReadOnlyBuffer();
357        assertEquals(ByteOrder.nativeOrder(), b.order());
358        assertEquals(ByteOrder.nativeOrder(), b.wrap(new short[10]).order());
359        assertEquals(ByteOrder.nativeOrder(), b.duplicate().order());
360        assertEquals(ByteOrder.nativeOrder(), b.slice().order());
361        // ...except for asReadOnlyBuffer, which returns a current-endian buffer.
362        ByteBuffer bb = ByteBuffer.allocate(10);
363        bb.order(ByteOrder.BIG_ENDIAN);
364        assertEquals(ByteOrder.BIG_ENDIAN, bb.asShortBuffer().asReadOnlyBuffer().order());
365        bb.order(ByteOrder.LITTLE_ENDIAN);
366        assertEquals(ByteOrder.LITTLE_ENDIAN, bb.asShortBuffer().asReadOnlyBuffer().order());
367    }
368
369    public void testRelativePositionsHeap() throws Exception {
370        testRelativePositions(ByteBuffer.allocate(10));
371    }
372
373    public void testRelativePositionsDirect() throws Exception {
374        testRelativePositions(ByteBuffer.allocateDirect(10));
375    }
376
377    public void testRelativePositionsMapped() throws Exception {
378        testRelativePositions(allocateMapped(10));
379    }
380
381    // http://b/3291927 - ensure that the relative get and put methods advance 'position'.
382    private void testRelativePositions(ByteBuffer b) throws Exception {
383        // gets
384        b.position(0);
385        b.get();
386        assertEquals(1, b.position());
387
388        byte[] buf = new byte[5];
389        b.position(0);
390        b.get(buf);
391        assertEquals(5, b.position());
392
393        b.position(0);
394        b.get(buf, 1, 3);
395        assertEquals(3, b.position());
396
397        b.position(0);
398        b.getChar();
399        assertEquals(2, b.position());
400
401        b.position(0);
402        b.getDouble();
403        assertEquals(8, b.position());
404
405        b.position(0);
406        b.getFloat();
407        assertEquals(4, b.position());
408
409        b.position(0);
410        b.getInt();
411        assertEquals(4, b.position());
412
413        b.position(0);
414        b.getLong();
415        assertEquals(8, b.position());
416
417        b.position(0);
418        b.getShort();
419        assertEquals(2, b.position());
420
421        // puts
422        b.position(0);
423        b.put((byte) 0);
424        assertEquals(1, b.position());
425
426        b.position(0);
427        b.put(buf);
428        assertEquals(5, b.position());
429
430        b.position(0);
431        b.put(buf, 1, 3);
432        assertEquals(3, b.position());
433
434        b.position(0);
435        b.putChar('x');
436        assertEquals(2, b.position());
437
438        b.position(0);
439        b.putDouble(0);
440        assertEquals(8, b.position());
441
442        b.position(0);
443        b.putFloat(0);
444        assertEquals(4, b.position());
445
446        b.position(0);
447        b.putInt(0);
448        assertEquals(4, b.position());
449
450        b.position(0);
451        b.putLong(0);
452        assertEquals(8, b.position());
453
454        b.position(0);
455        b.putShort((short) 0);
456        assertEquals(2, b.position());
457    }
458}
459