BufferTest.java revision 9ce6a2533b50ffcd24b8b10bae7f234042768819
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.lang.reflect.*;
21import java.nio.*;
22import java.nio.channels.*;
23import java.util.Arrays;
24import junit.framework.TestCase;
25
26public class BufferTest extends TestCase {
27    private static ByteBuffer allocateMapped(int size) throws Exception {
28        File f = File.createTempFile("mapped", "tmp");
29        f.deleteOnExit();
30        RandomAccessFile raf = new RandomAccessFile(f, "rw");
31        raf.setLength(size);
32        FileChannel ch = raf.getChannel();
33        MappedByteBuffer result = ch.map(FileChannel.MapMode.READ_WRITE, 0, size);
34        ch.close();
35        return result;
36    }
37
38    /**
39     * Try to create a {@link MappedByteBuffer} from /dev/zero, to see if
40     * we support mapping UNIX character devices.
41     */
42    public void testDevZeroMap() throws Exception {
43        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "r");
44        try {
45            MappedByteBuffer mbb = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, 65536);
46
47            // Create an array initialized to all "(byte) 1"
48            byte[] buf1 = new byte[65536];
49            Arrays.fill(buf1, (byte) 1);
50
51            // Read from mapped /dev/zero, and overwrite this array.
52            mbb.get(buf1);
53
54            // Verify that everything is zero
55            for (int i = 0; i < 65536; i++) {
56                assertEquals((byte) 0, buf1[i]);
57            }
58        } finally {
59            raf.close();
60        }
61    }
62
63    /**
64     * Same as {@link libcore.java.nio.BufferTest#testDevZeroMap()}, but try to see
65     * if we can write to the UNIX character device.
66     */
67    public void testDevZeroMapRW() throws Exception {
68        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "rw");
69        try {
70            MappedByteBuffer mbb = raf.getChannel()
71                    .map(FileChannel.MapMode.READ_WRITE, 65536, 131072);
72
73            // Create an array initialized to all "(byte) 1"
74            byte[] buf1 = new byte[65536];
75            Arrays.fill(buf1, (byte) 1);
76
77            // Put all "(byte) 1"s into the /dev/zero MappedByteBuffer.
78            mbb.put(buf1);
79
80            mbb.position(0);
81
82            byte[] buf2 = new byte[65536];
83            mbb.get(buf2);
84
85            // Verify that everything is one
86            for (int i = 0; i < 65536; i++) {
87                assertEquals((byte) 1, buf2[i]);
88            }
89        } finally {
90            raf.close();
91        }
92    }
93
94    public void testByteSwappedBulkGetDirect() throws Exception {
95        testByteSwappedBulkGet(ByteBuffer.allocateDirect(10));
96    }
97
98    public void testByteSwappedBulkGetHeap() throws Exception {
99        testByteSwappedBulkGet(ByteBuffer.allocate(10));
100    }
101
102    public void testByteSwappedBulkGetMapped() throws Exception {
103        testByteSwappedBulkGet(allocateMapped(10));
104    }
105
106    private void testByteSwappedBulkGet(ByteBuffer b) throws Exception {
107        for (int i = 0; i < b.limit(); ++i) {
108            b.put(i, (byte) i);
109        }
110        b.position(1);
111
112        char[] chars = new char[6];
113        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(chars, 1, 4);
114        assertEquals("[\u0000, \u0102, \u0304, \u0506, \u0708, \u0000]", Arrays.toString(chars));
115        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().get(chars, 1, 4);
116        assertEquals("[\u0000, \u0201, \u0403, \u0605, \u0807, \u0000]", Arrays.toString(chars));
117
118        double[] doubles = new double[3];
119        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
120        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
121        assertEquals(0x0102030405060708L, Double.doubleToRawLongBits(doubles[1]));
122        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
123        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
124        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
125        assertEquals(0x0807060504030201L, Double.doubleToRawLongBits(doubles[1]));
126        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
127
128        float[] floats = new float[4];
129        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().get(floats, 1, 2);
130        assertEquals(0, Float.floatToRawIntBits(floats[0]));
131        assertEquals(0x01020304, Float.floatToRawIntBits(floats[1]));
132        assertEquals(0x05060708, Float.floatToRawIntBits(floats[2]));
133        assertEquals(0, Float.floatToRawIntBits(floats[3]));
134        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().get(floats, 1, 2);
135        assertEquals(0, Float.floatToRawIntBits(floats[0]));
136        assertEquals(0x04030201, Float.floatToRawIntBits(floats[1]));
137        assertEquals(0x08070605, Float.floatToRawIntBits(floats[2]));
138        assertEquals(0, Float.floatToRawIntBits(floats[3]));
139
140        int[] ints = new int[4];
141        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().get(ints, 1, 2);
142        assertEquals(0, ints[0]);
143        assertEquals(0x01020304, ints[1]);
144        assertEquals(0x05060708, ints[2]);
145        assertEquals(0, ints[3]);
146        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(ints, 1, 2);
147        assertEquals(0, ints[0]);
148        assertEquals(0x04030201, ints[1]);
149        assertEquals(0x08070605, ints[2]);
150        assertEquals(0, ints[3]);
151
152        long[] longs = new long[3];
153        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().get(longs, 1, 1);
154        assertEquals(0, longs[0]);
155        assertEquals(0x0102030405060708L, longs[1]);
156        assertEquals(0, longs[2]);
157        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().get(longs, 1, 1);
158        assertEquals(0, longs[0]);
159        assertEquals(0x0807060504030201L, longs[1]);
160        assertEquals(0, longs[2]);
161
162        short[] shorts = new short[6];
163        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(shorts, 1, 4);
164        assertEquals(0, shorts[0]);
165        assertEquals(0x0102, shorts[1]);
166        assertEquals(0x0304, shorts[2]);
167        assertEquals(0x0506, shorts[3]);
168        assertEquals(0x0708, shorts[4]);
169        assertEquals(0, shorts[5]);
170        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts, 1, 4);
171        assertEquals(0, shorts[0]);
172        assertEquals(0x0201, shorts[1]);
173        assertEquals(0x0403, shorts[2]);
174        assertEquals(0x0605, shorts[3]);
175        assertEquals(0x0807, shorts[4]);
176        assertEquals(0, shorts[5]);
177    }
178
179    private static String toString(ByteBuffer b) {
180        StringBuilder result = new StringBuilder();
181        for (int i = 0; i < b.limit(); ++i) {
182            result.append(String.format("%02x", (int) b.get(i)));
183        }
184        return result.toString();
185    }
186
187    public void testByteSwappedBulkPutDirect() throws Exception {
188        testByteSwappedBulkPut(ByteBuffer.allocateDirect(10));
189    }
190
191    public void testByteSwappedBulkPutHeap() throws Exception {
192        testByteSwappedBulkPut(ByteBuffer.allocate(10));
193    }
194
195    public void testByteSwappedBulkPutMapped() throws Exception {
196        testByteSwappedBulkPut(allocateMapped(10));
197    }
198
199    private void testByteSwappedBulkPut(ByteBuffer b) throws Exception {
200        b.position(1);
201
202        char[] chars = new char[] { '\u2222', '\u0102', '\u0304', '\u0506', '\u0708', '\u2222' };
203        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().put(chars, 1, 4);
204        assertEquals("00010203040506070800", toString(b));
205        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().put(chars, 1, 4);
206        assertEquals("00020104030605080700", toString(b));
207
208        double[] doubles = new double[] { 0, Double.longBitsToDouble(0x0102030405060708L), 0 };
209        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
210        assertEquals("00010203040506070800", toString(b));
211        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
212        assertEquals("00080706050403020100", toString(b));
213
214        float[] floats = new float[] { 0, Float.intBitsToFloat(0x01020304),
215                Float.intBitsToFloat(0x05060708), 0 };
216        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().put(floats, 1, 2);
217        assertEquals("00010203040506070800", toString(b));
218        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().put(floats, 1, 2);
219        assertEquals("00040302010807060500", toString(b));
220
221        int[] ints = new int[] { 0, 0x01020304, 0x05060708, 0 };
222        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().put(ints, 1, 2);
223        assertEquals("00010203040506070800", toString(b));
224        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(ints, 1, 2);
225        assertEquals("00040302010807060500", toString(b));
226
227        long[] longs = new long[] { 0, 0x0102030405060708L, 0 };
228        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().put(longs, 1, 1);
229        assertEquals("00010203040506070800", toString(b));
230        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(longs, 1, 1);
231        assertEquals("00080706050403020100", toString(b));
232
233        short[] shorts = new short[] { 0, 0x0102, 0x0304, 0x0506, 0x0708, 0 };
234        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().put(shorts, 1, 4);
235        assertEquals("00010203040506070800", toString(b));
236        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shorts, 1, 4);
237        assertEquals("00020104030605080700", toString(b));
238    }
239
240    public void testByteBufferByteOrderDirectRW() throws Exception {
241        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), false);
242    }
243
244    public void testByteBufferByteOrderHeapRW() throws Exception {
245        testByteBufferByteOrder(ByteBuffer.allocate(10), false);
246    }
247
248    public void testByteBufferByteOrderMappedRW() throws Exception {
249        testByteBufferByteOrder(allocateMapped(10), false);
250    }
251
252    public void testByteBufferByteOrderDirectRO() throws Exception {
253        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), true);
254    }
255
256    public void testByteBufferByteOrderHeapRO() throws Exception {
257        testByteBufferByteOrder(ByteBuffer.allocate(10), true);
258    }
259
260    public void testByteBufferByteOrderMappedRO() throws Exception {
261        testByteBufferByteOrder(allocateMapped(10), true);
262    }
263
264    private void testByteBufferByteOrder(ByteBuffer b, boolean readOnly) throws Exception {
265        if (readOnly) {
266            b = b.asReadOnlyBuffer();
267        }
268        // allocate/allocateDirect/map always returns a big-endian buffer.
269        assertEquals(ByteOrder.BIG_ENDIAN, b.order());
270
271        // wrap always returns a big-endian buffer.
272        assertEquals(ByteOrder.BIG_ENDIAN, b.wrap(new byte[10]).order());
273
274        // duplicate always returns a big-endian buffer.
275        b.order(ByteOrder.BIG_ENDIAN);
276        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
277        b.order(ByteOrder.LITTLE_ENDIAN);
278        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
279
280        // slice always returns a big-endian buffer.
281        b.order(ByteOrder.BIG_ENDIAN);
282        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
283        b.order(ByteOrder.LITTLE_ENDIAN);
284        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
285
286        // asXBuffer always returns a current-endian buffer.
287        b.order(ByteOrder.BIG_ENDIAN);
288        assertEquals(ByteOrder.BIG_ENDIAN, b.asCharBuffer().order());
289        assertEquals(ByteOrder.BIG_ENDIAN, b.asDoubleBuffer().order());
290        assertEquals(ByteOrder.BIG_ENDIAN, b.asFloatBuffer().order());
291        assertEquals(ByteOrder.BIG_ENDIAN, b.asIntBuffer().order());
292        assertEquals(ByteOrder.BIG_ENDIAN, b.asLongBuffer().order());
293        assertEquals(ByteOrder.BIG_ENDIAN, b.asShortBuffer().order());
294        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
295        b.order(ByteOrder.LITTLE_ENDIAN);
296        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asCharBuffer().order());
297        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asDoubleBuffer().order());
298        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asFloatBuffer().order());
299        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asIntBuffer().order());
300        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asLongBuffer().order());
301        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asShortBuffer().order());
302        // ...except for asReadOnlyBuffer, which always returns a big-endian buffer.
303        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
304    }
305
306    public void testCharBufferByteOrderWrapped() throws Exception {
307        assertEquals(ByteOrder.nativeOrder(), CharBuffer.wrap(new char[10]).order());
308        assertEquals(ByteOrder.nativeOrder(), CharBuffer.wrap(new char[10]).asReadOnlyBuffer().order());
309    }
310
311    private void testCharBufferByteOrder(CharBuffer b, ByteOrder bo) throws Exception {
312        assertEquals(bo, b.order());
313        assertEquals(bo, b.duplicate().order());
314        assertEquals(bo, b.slice().order());
315        b = b.asReadOnlyBuffer();
316        assertEquals(bo, b.order());
317        assertEquals(bo, b.duplicate().order());
318        assertEquals(bo, b.slice().order());
319    }
320
321    private CharBuffer allocateCharBuffer(ByteOrder order) {
322        return ByteBuffer.allocate(10).order(order).asCharBuffer();
323    }
324
325    public void testCharBufferByteOrderArray() throws Exception {
326        testCharBufferByteOrder(CharBuffer.allocate(10), ByteOrder.nativeOrder());
327    }
328
329    public void testCharBufferByteOrderBE() throws Exception {
330        testCharBufferByteOrder(allocateCharBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
331    }
332
333    public void testCharBufferByteOrderLE() throws Exception {
334        testCharBufferByteOrder(allocateCharBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
335    }
336
337    public void testDoubleBufferByteOrderWrapped() throws Exception {
338        assertEquals(ByteOrder.nativeOrder(), DoubleBuffer.wrap(new double[10]).order());
339        assertEquals(ByteOrder.nativeOrder(), DoubleBuffer.wrap(new double[10]).asReadOnlyBuffer().order());
340    }
341
342    private void testDoubleBufferByteOrder(DoubleBuffer b, ByteOrder bo) throws Exception {
343        assertEquals(bo, b.order());
344        assertEquals(bo, b.duplicate().order());
345        assertEquals(bo, b.slice().order());
346        b = b.asReadOnlyBuffer();
347        assertEquals(bo, b.order());
348        assertEquals(bo, b.duplicate().order());
349        assertEquals(bo, b.slice().order());
350    }
351
352    private DoubleBuffer allocateDoubleBuffer(ByteOrder order) {
353        return ByteBuffer.allocate(10*8).order(order).asDoubleBuffer();
354    }
355
356    public void testDoubleBufferByteOrderArray() throws Exception {
357        testDoubleBufferByteOrder(DoubleBuffer.allocate(10), ByteOrder.nativeOrder());
358    }
359
360    public void testDoubleBufferByteOrderBE() throws Exception {
361        testDoubleBufferByteOrder(allocateDoubleBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
362    }
363
364    public void testDoubleBufferByteOrderLE() throws Exception {
365        testDoubleBufferByteOrder(allocateDoubleBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
366    }
367
368    public void testFloatBufferByteOrderWrapped() throws Exception {
369        assertEquals(ByteOrder.nativeOrder(), FloatBuffer.wrap(new float[10]).order());
370        assertEquals(ByteOrder.nativeOrder(), FloatBuffer.wrap(new float[10]).asReadOnlyBuffer().order());
371    }
372
373    private void testFloatBufferByteOrder(FloatBuffer b, ByteOrder bo) throws Exception {
374        assertEquals(bo, b.order());
375        assertEquals(bo, b.duplicate().order());
376        assertEquals(bo, b.slice().order());
377        b = b.asReadOnlyBuffer();
378        assertEquals(bo, b.order());
379        assertEquals(bo, b.duplicate().order());
380        assertEquals(bo, b.slice().order());
381    }
382
383    private FloatBuffer allocateFloatBuffer(ByteOrder order) {
384        return ByteBuffer.allocate(10*8).order(order).asFloatBuffer();
385    }
386
387    public void testFloatBufferByteOrderArray() throws Exception {
388        testFloatBufferByteOrder(FloatBuffer.allocate(10), ByteOrder.nativeOrder());
389    }
390
391    public void testFloatBufferByteOrderBE() throws Exception {
392        testFloatBufferByteOrder(allocateFloatBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
393    }
394
395    public void testFloatBufferByteOrderLE() throws Exception {
396        testFloatBufferByteOrder(allocateFloatBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
397    }
398
399    public void testIntBufferByteOrderWrapped() throws Exception {
400        assertEquals(ByteOrder.nativeOrder(), IntBuffer.wrap(new int[10]).order());
401        assertEquals(ByteOrder.nativeOrder(), IntBuffer.wrap(new int[10]).asReadOnlyBuffer().order());
402    }
403
404    private void testIntBufferByteOrder(IntBuffer b, ByteOrder bo) throws Exception {
405        assertEquals(bo, b.order());
406        assertEquals(bo, b.duplicate().order());
407        assertEquals(bo, b.slice().order());
408        b = b.asReadOnlyBuffer();
409        assertEquals(bo, b.order());
410        assertEquals(bo, b.duplicate().order());
411        assertEquals(bo, b.slice().order());
412    }
413
414    private IntBuffer allocateIntBuffer(ByteOrder order) {
415        return ByteBuffer.allocate(10*8).order(order).asIntBuffer();
416    }
417
418    public void testIntBufferByteOrderArray() throws Exception {
419        testIntBufferByteOrder(IntBuffer.allocate(10), ByteOrder.nativeOrder());
420    }
421
422    public void testIntBufferByteOrderBE() throws Exception {
423        testIntBufferByteOrder(allocateIntBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
424    }
425
426    public void testIntBufferByteOrderLE() throws Exception {
427        testIntBufferByteOrder(allocateIntBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
428    }
429
430    public void testLongBufferByteOrderWrapped() throws Exception {
431        assertEquals(ByteOrder.nativeOrder(), LongBuffer.wrap(new long[10]).order());
432        assertEquals(ByteOrder.nativeOrder(), LongBuffer.wrap(new long[10]).asReadOnlyBuffer().order());
433    }
434
435    private void testLongBufferByteOrder(LongBuffer b, ByteOrder bo) throws Exception {
436        assertEquals(bo, b.order());
437        assertEquals(bo, b.duplicate().order());
438        assertEquals(bo, b.slice().order());
439        b = b.asReadOnlyBuffer();
440        assertEquals(bo, b.order());
441        assertEquals(bo, b.duplicate().order());
442        assertEquals(bo, b.slice().order());
443    }
444
445    private LongBuffer allocateLongBuffer(ByteOrder order) {
446        return ByteBuffer.allocate(10*8).order(order).asLongBuffer();
447    }
448
449    public void testLongBufferByteOrderArray() throws Exception {
450        testLongBufferByteOrder(LongBuffer.allocate(10), ByteOrder.nativeOrder());
451    }
452
453    public void testLongBufferByteOrderBE() throws Exception {
454        testLongBufferByteOrder(allocateLongBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
455    }
456
457    public void testLongBufferByteOrderLE() throws Exception {
458        testLongBufferByteOrder(allocateLongBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
459    }
460
461    public void testShortBufferByteOrderWrapped() throws Exception {
462        assertEquals(ByteOrder.nativeOrder(), ShortBuffer.wrap(new short[10]).order());
463        assertEquals(ByteOrder.nativeOrder(), ShortBuffer.wrap(new short[10]).asReadOnlyBuffer().order());
464    }
465
466    private void testShortBufferByteOrder(ShortBuffer b, ByteOrder bo) throws Exception {
467        assertEquals(bo, b.order());
468        assertEquals(bo, b.duplicate().order());
469        assertEquals(bo, b.slice().order());
470        b = b.asReadOnlyBuffer();
471        assertEquals(bo, b.order());
472        assertEquals(bo, b.duplicate().order());
473        assertEquals(bo, b.slice().order());
474    }
475
476    private ShortBuffer allocateShortBuffer(ByteOrder order) {
477        return ByteBuffer.allocate(10*8).order(order).asShortBuffer();
478    }
479
480    public void testShortBufferByteOrderArray() throws Exception {
481        testShortBufferByteOrder(ShortBuffer.allocate(10), ByteOrder.nativeOrder());
482    }
483
484    public void testShortBufferByteOrderBE() throws Exception {
485        testShortBufferByteOrder(allocateShortBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
486    }
487
488    public void testShortBufferByteOrderLE() throws Exception {
489        testShortBufferByteOrder(allocateShortBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
490    }
491
492    public void testRelativePositionsHeap() throws Exception {
493        testRelativePositions(ByteBuffer.allocate(10));
494    }
495
496    public void testRelativePositionsDirect() throws Exception {
497        testRelativePositions(ByteBuffer.allocateDirect(10));
498    }
499
500    public void testRelativePositionsMapped() throws Exception {
501        testRelativePositions(allocateMapped(10));
502    }
503
504    // http://b/3291927 - ensure that the relative get and put methods advance 'position'.
505    private void testRelativePositions(ByteBuffer b) throws Exception {
506        // gets
507        b.position(0);
508        b.get();
509        assertEquals(1, b.position());
510
511        byte[] buf = new byte[5];
512        b.position(0);
513        b.get(buf);
514        assertEquals(5, b.position());
515
516        b.position(0);
517        b.get(buf, 1, 3);
518        assertEquals(3, b.position());
519
520        b.position(0);
521        b.getChar();
522        assertEquals(2, b.position());
523
524        b.position(0);
525        b.getDouble();
526        assertEquals(8, b.position());
527
528        b.position(0);
529        b.getFloat();
530        assertEquals(4, b.position());
531
532        b.position(0);
533        b.getInt();
534        assertEquals(4, b.position());
535
536        b.position(0);
537        b.getLong();
538        assertEquals(8, b.position());
539
540        b.position(0);
541        b.getShort();
542        assertEquals(2, b.position());
543
544        // puts
545        b.position(0);
546        b.put((byte) 0);
547        assertEquals(1, b.position());
548
549        b.position(0);
550        b.put(buf);
551        assertEquals(5, b.position());
552
553        b.position(0);
554        b.put(buf, 1, 3);
555        assertEquals(3, b.position());
556
557        b.position(0);
558        b.putChar('x');
559        assertEquals(2, b.position());
560
561        b.position(0);
562        b.putDouble(0);
563        assertEquals(8, b.position());
564
565        b.position(0);
566        b.putFloat(0);
567        assertEquals(4, b.position());
568
569        b.position(0);
570        b.putInt(0);
571        assertEquals(4, b.position());
572
573        b.position(0);
574        b.putLong(0);
575        assertEquals(8, b.position());
576
577        b.position(0);
578        b.putShort((short) 0);
579        assertEquals(2, b.position());
580    }
581
582    // This test will fail on the RI. Our direct buffers are cooler than theirs.
583    // http://b/3384431
584    public void testDirectByteBufferHasArray() throws Exception {
585        ByteBuffer b = ByteBuffer.allocateDirect(10);
586        assertTrue(b.isDirect());
587        // Check the buffer has an array of the right size.
588        assertTrue(b.hasArray());
589        assertEquals(0, b.arrayOffset());
590        byte[] array = b.array();
591        assertEquals(10, array.length);
592        // Check that writes to the array show up in the buffer.
593        assertEquals(0, b.get(0));
594        array[0] = 1;
595        assertEquals(1, b.get(0));
596        // Check that writes to the buffer show up in the array.
597        assertEquals(1, array[0]);
598        b.put(0, (byte) 0);
599        assertEquals(0, array[0]);
600    }
601
602    public void testSliceOffset() throws Exception {
603        // Slicing changes the array offset.
604        ByteBuffer buffer = ByteBuffer.allocate(10);
605        buffer.get();
606        ByteBuffer slice = buffer.slice();
607        assertEquals(0, buffer.arrayOffset());
608        assertEquals(1, slice.arrayOffset());
609
610        ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
611        directBuffer.get();
612        ByteBuffer directSlice = directBuffer.slice();
613        assertEquals(0, directBuffer.arrayOffset());
614        assertEquals(1, directSlice.arrayOffset());
615    }
616
617    // http://code.google.com/p/android/issues/detail?id=16184
618    public void testPutByteBuffer() throws Exception {
619        ByteBuffer dst = ByteBuffer.allocate(10).asReadOnlyBuffer();
620
621        // Can't put into a read-only buffer.
622        try {
623            dst.put(ByteBuffer.allocate(5));
624            fail();
625        } catch (ReadOnlyBufferException expected) {
626        }
627
628        // Can't put a buffer into itself.
629        dst = ByteBuffer.allocate(10);
630        try {
631            dst.put(dst);
632            fail();
633        } catch (IllegalArgumentException expected) {
634        }
635
636        // Can't put the null ByteBuffer.
637        try {
638            dst.put((ByteBuffer) null);
639            fail();
640        } catch (NullPointerException expected) {
641        }
642
643        // Can't put a larger source into a smaller destination.
644        try {
645            dst.put(ByteBuffer.allocate(dst.capacity() + 1));
646            fail();
647        } catch (BufferOverflowException expected) {
648        }
649
650        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocate(8), false);
651        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocateDirect(8), false);
652        assertPutByteBuffer(ByteBuffer.allocate(10), allocateMapped(8), false);
653        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocate(8), true);
654        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocateDirect(8), true);
655        assertPutByteBuffer(ByteBuffer.allocate(10), allocateMapped(8), true);
656
657        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocate(8), false);
658        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocateDirect(8), false);
659        assertPutByteBuffer(ByteBuffer.allocateDirect(10), allocateMapped(8), false);
660        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocate(8), true);
661        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocateDirect(8), true);
662        assertPutByteBuffer(ByteBuffer.allocateDirect(10), allocateMapped(8), true);
663    }
664
665    private void assertPutByteBuffer(ByteBuffer dst, ByteBuffer src, boolean readOnly) {
666        // Start 'dst' off as the index-identity pattern.
667        for (int i = 0; i < dst.capacity(); ++i) {
668            dst.put(i, (byte) i);
669        }
670        // Deliberately offset the position we'll write to by 1.
671        dst.position(1);
672
673        // Make the source more interesting.
674        for (int i = 0; i < src.capacity(); ++i) {
675            src.put(i, (byte) (16 + i));
676        }
677        if (readOnly) {
678            src = src.asReadOnlyBuffer();
679        }
680
681        ByteBuffer dst2 = dst.put(src);
682        assertSame(dst, dst2);
683        assertEquals(0, src.remaining());
684        assertEquals(src.position(), src.capacity());
685        assertEquals(dst.position(), src.capacity() + 1);
686        for (int i = 0; i < src.capacity(); ++i) {
687            assertEquals(src.get(i), dst.get(i + 1));
688        }
689
690        // No room for another.
691        src.position(0);
692        try {
693            dst.put(src);
694            fail();
695        } catch (BufferOverflowException expected) {
696        }
697    }
698
699    public void testCharBufferSubSequence() throws Exception {
700        ByteBuffer b = ByteBuffer.allocateDirect(10).order(ByteOrder.nativeOrder());
701        b.putChar('H');
702        b.putChar('e');
703        b.putChar('l');
704        b.putChar('l');
705        b.putChar('o');
706        b.flip();
707
708        assertEquals("Hello", b.asCharBuffer().toString());
709
710        CharBuffer cb = b.asCharBuffer();
711        CharSequence cs = cb.subSequence(0, cb.length());
712        assertEquals("Hello", cs.toString());
713    }
714
715    public void testHasArrayOnJniDirectByteBuffer() throws Exception {
716        // Simulate a call to JNI's NewDirectByteBuffer.
717        Class<?> c = Class.forName("java.nio.DirectByteBuffer");
718        Constructor<?> ctor = c.getDeclaredConstructor(long.class, int.class);
719        ctor.setAccessible(true);
720        ByteBuffer bb = (ByteBuffer) ctor.newInstance(0, 0);
721
722        try {
723            bb.array();
724            fail();
725        } catch (UnsupportedOperationException expected) {
726        }
727        try {
728            bb.arrayOffset();
729            fail();
730        } catch (UnsupportedOperationException expected) {
731        }
732        assertFalse(bb.hasArray());
733    }
734
735    public void testBug6085292() {
736        ByteBuffer b = ByteBuffer.allocateDirect(1);
737
738        try {
739            b.asCharBuffer().get();
740            fail();
741        } catch (BufferUnderflowException expected) {
742        }
743        try {
744            b.asCharBuffer().get(0);
745            fail();
746        } catch (IndexOutOfBoundsException expected) {
747            assertTrue(expected.getMessage().contains("limit=0"));
748        }
749
750        try {
751            b.asDoubleBuffer().get();
752            fail();
753        } catch (BufferUnderflowException expected) {
754        }
755        try {
756            b.asDoubleBuffer().get(0);
757            fail();
758        } catch (IndexOutOfBoundsException expected) {
759            assertTrue(expected.getMessage().contains("limit=0"));
760        }
761
762        try {
763            b.asFloatBuffer().get();
764            fail();
765        } catch (BufferUnderflowException expected) {
766        }
767        try {
768            b.asFloatBuffer().get(0);
769            fail();
770        } catch (IndexOutOfBoundsException expected) {
771            assertTrue(expected.getMessage().contains("limit=0"));
772        }
773
774        try {
775            b.asIntBuffer().get();
776            fail();
777        } catch (BufferUnderflowException expected) {
778        }
779        try {
780            b.asIntBuffer().get(0);
781            fail();
782        } catch (IndexOutOfBoundsException expected) {
783            assertTrue(expected.getMessage().contains("limit=0"));
784        }
785
786        try {
787            b.asLongBuffer().get();
788            fail();
789        } catch (BufferUnderflowException expected) {
790        }
791        try {
792            b.asLongBuffer().get(0);
793            fail();
794        } catch (IndexOutOfBoundsException expected) {
795            assertTrue(expected.getMessage().contains("limit=0"));
796        }
797
798        try {
799            b.asShortBuffer().get();
800            fail();
801        } catch (BufferUnderflowException expected) {
802        }
803        try {
804            b.asShortBuffer().get(0);
805            fail();
806        } catch (IndexOutOfBoundsException expected) {
807            assertTrue(expected.getMessage().contains("limit=0"));
808        }
809    }
810
811    public void testUsingDirectBufferAsMappedBuffer() throws Exception {
812        MappedByteBuffer notMapped = (MappedByteBuffer) ByteBuffer.allocateDirect(1);
813        try {
814            notMapped.force();
815            fail();
816        } catch (UnsupportedOperationException expected) {
817        }
818        try {
819            notMapped.isLoaded();
820            fail();
821        } catch (UnsupportedOperationException expected) {
822        }
823        try {
824            notMapped.load();
825            fail();
826        } catch (UnsupportedOperationException expected) {
827        }
828
829        MappedByteBuffer mapped = (MappedByteBuffer) allocateMapped(1);
830        mapped.force();
831        mapped.isLoaded();
832        mapped.load();
833    }
834
835    // https://code.google.com/p/android/issues/detail?id=53637
836    public void testBug53637() throws Exception {
837        MappedByteBuffer mapped = (MappedByteBuffer) allocateMapped(1);
838        mapped.get();
839        mapped.rewind();
840        mapped.get();
841
842        mapped.rewind();
843        mapped.mark();
844        mapped.get();
845        mapped.reset();
846        mapped.get();
847
848        mapped.rewind();
849        mapped.get();
850        mapped.clear();
851        mapped.get();
852
853        mapped.rewind();
854        mapped.get();
855        mapped.flip();
856        mapped.get();
857    }
858}
859