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