BufferTest.java revision e30eaf6894647ecf5e1ec3ec5ac8221e41b4d170
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 junit.framework.TestCase;
20import java.io.File;
21import java.io.RandomAccessFile;
22import java.lang.reflect.Constructor;
23import java.nio.BufferOverflowException;
24import java.nio.BufferUnderflowException;
25import java.nio.ByteBuffer;
26import java.nio.ByteOrder;
27import java.nio.CharBuffer;
28import java.nio.DoubleBuffer;
29import java.nio.FloatBuffer;
30import java.nio.IntBuffer;
31import java.nio.LongBuffer;
32import java.nio.MappedByteBuffer;
33import java.nio.NioUtils;
34import java.nio.ReadOnlyBufferException;
35import java.nio.ShortBuffer;
36import java.nio.channels.FileChannel;
37import java.util.Arrays;
38import libcore.io.SizeOf;
39
40public class BufferTest extends TestCase {
41    private static ByteBuffer allocateMapped(int size) throws Exception {
42        File f = File.createTempFile("mapped", "tmp");
43        f.deleteOnExit();
44        RandomAccessFile raf = new RandomAccessFile(f, "rw");
45        raf.setLength(size);
46        FileChannel ch = raf.getChannel();
47        MappedByteBuffer result = ch.map(FileChannel.MapMode.READ_WRITE, 0, size);
48        ch.close();
49        return result;
50    }
51
52    /**
53     * Try to create a {@link MappedByteBuffer} from /dev/zero, to see if
54     * we support mapping UNIX character devices.
55     */
56    public void testDevZeroMap() throws Exception {
57        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "r");
58        try {
59            MappedByteBuffer mbb = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, 65536);
60
61            // Create an array initialized to all "(byte) 1"
62            byte[] buf1 = new byte[65536];
63            Arrays.fill(buf1, (byte) 1);
64
65            // Read from mapped /dev/zero, and overwrite this array.
66            mbb.get(buf1);
67
68            // Verify that everything is zero
69            for (int i = 0; i < 65536; i++) {
70                assertEquals((byte) 0, buf1[i]);
71            }
72        } finally {
73            raf.close();
74        }
75    }
76
77    /**
78     * Same as {@link libcore.java.nio.BufferTest#testDevZeroMap()}, but try to see
79     * if we can write to the UNIX character device.
80     */
81    public void testDevZeroMapRW() throws Exception {
82        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "rw");
83        try {
84            MappedByteBuffer mbb = raf.getChannel()
85                    .map(FileChannel.MapMode.READ_WRITE, 65536, 131072);
86
87            // Create an array initialized to all "(byte) 1"
88            byte[] buf1 = new byte[65536];
89            Arrays.fill(buf1, (byte) 1);
90
91            // Put all "(byte) 1"s into the /dev/zero MappedByteBuffer.
92            mbb.put(buf1);
93
94            mbb.position(0);
95
96            byte[] buf2 = new byte[65536];
97            mbb.get(buf2);
98
99            // Verify that everything is one
100            for (int i = 0; i < 65536; i++) {
101                assertEquals((byte) 1, buf2[i]);
102            }
103        } finally {
104            raf.close();
105        }
106    }
107
108    public void testByteSwappedBulkGetDirect() throws Exception {
109        testByteSwappedBulkGet(ByteBuffer.allocateDirect(10));
110    }
111
112    public void testByteSwappedBulkGetHeap() throws Exception {
113        testByteSwappedBulkGet(ByteBuffer.allocate(10));
114    }
115
116    public void testByteSwappedBulkGetMapped() throws Exception {
117        testByteSwappedBulkGet(allocateMapped(10));
118    }
119
120    private void testByteSwappedBulkGet(ByteBuffer b) throws Exception {
121        for (int i = 0; i < b.limit(); ++i) {
122            b.put(i, (byte) i);
123        }
124        b.position(1);
125
126        char[] chars = new char[6];
127        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(chars, 1, 4);
128        assertEquals("[\u0000, \u0102, \u0304, \u0506, \u0708, \u0000]", Arrays.toString(chars));
129        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().get(chars, 1, 4);
130        assertEquals("[\u0000, \u0201, \u0403, \u0605, \u0807, \u0000]", Arrays.toString(chars));
131
132        double[] doubles = new double[3];
133        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
134        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
135        assertEquals(0x0102030405060708L, Double.doubleToRawLongBits(doubles[1]));
136        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
137        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().get(doubles, 1, 1);
138        assertEquals(0, Double.doubleToRawLongBits(doubles[0]));
139        assertEquals(0x0807060504030201L, Double.doubleToRawLongBits(doubles[1]));
140        assertEquals(0, Double.doubleToRawLongBits(doubles[2]));
141
142        float[] floats = new float[4];
143        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().get(floats, 1, 2);
144        assertEquals(0, Float.floatToRawIntBits(floats[0]));
145        assertEquals(0x01020304, Float.floatToRawIntBits(floats[1]));
146        assertEquals(0x05060708, Float.floatToRawIntBits(floats[2]));
147        assertEquals(0, Float.floatToRawIntBits(floats[3]));
148        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().get(floats, 1, 2);
149        assertEquals(0, Float.floatToRawIntBits(floats[0]));
150        assertEquals(0x04030201, Float.floatToRawIntBits(floats[1]));
151        assertEquals(0x08070605, Float.floatToRawIntBits(floats[2]));
152        assertEquals(0, Float.floatToRawIntBits(floats[3]));
153
154        int[] ints = new int[4];
155        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().get(ints, 1, 2);
156        assertEquals(0, ints[0]);
157        assertEquals(0x01020304, ints[1]);
158        assertEquals(0x05060708, ints[2]);
159        assertEquals(0, ints[3]);
160        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(ints, 1, 2);
161        assertEquals(0, ints[0]);
162        assertEquals(0x04030201, ints[1]);
163        assertEquals(0x08070605, ints[2]);
164        assertEquals(0, ints[3]);
165
166        long[] longs = new long[3];
167        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().get(longs, 1, 1);
168        assertEquals(0, longs[0]);
169        assertEquals(0x0102030405060708L, longs[1]);
170        assertEquals(0, longs[2]);
171        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().get(longs, 1, 1);
172        assertEquals(0, longs[0]);
173        assertEquals(0x0807060504030201L, longs[1]);
174        assertEquals(0, longs[2]);
175
176        short[] shorts = new short[6];
177        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(shorts, 1, 4);
178        assertEquals(0, shorts[0]);
179        assertEquals(0x0102, shorts[1]);
180        assertEquals(0x0304, shorts[2]);
181        assertEquals(0x0506, shorts[3]);
182        assertEquals(0x0708, shorts[4]);
183        assertEquals(0, shorts[5]);
184        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts, 1, 4);
185        assertEquals(0, shorts[0]);
186        assertEquals(0x0201, shorts[1]);
187        assertEquals(0x0403, shorts[2]);
188        assertEquals(0x0605, shorts[3]);
189        assertEquals(0x0807, shorts[4]);
190        assertEquals(0, shorts[5]);
191    }
192
193    private static String toString(ByteBuffer b) {
194        StringBuilder result = new StringBuilder();
195        for (int i = 0; i < b.limit(); ++i) {
196            result.append(String.format("%02x", (int) b.get(i)));
197        }
198        return result.toString();
199    }
200
201    public void testByteSwappedBulkPutDirect() throws Exception {
202        testByteSwappedBulkPut(ByteBuffer.allocateDirect(10));
203    }
204
205    public void testByteSwappedBulkPutHeap() throws Exception {
206        testByteSwappedBulkPut(ByteBuffer.allocate(10));
207    }
208
209    public void testByteSwappedBulkPutMapped() throws Exception {
210        testByteSwappedBulkPut(allocateMapped(10));
211    }
212
213    private void testByteSwappedBulkPut(ByteBuffer b) throws Exception {
214        b.position(1);
215
216        char[] chars = new char[] { '\u2222', '\u0102', '\u0304', '\u0506', '\u0708', '\u2222' };
217        b.order(ByteOrder.BIG_ENDIAN).asCharBuffer().put(chars, 1, 4);
218        assertEquals("00010203040506070800", toString(b));
219        b.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer().put(chars, 1, 4);
220        assertEquals("00020104030605080700", toString(b));
221
222        double[] doubles = new double[] { 0, Double.longBitsToDouble(0x0102030405060708L), 0 };
223        b.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
224        assertEquals("00010203040506070800", toString(b));
225        b.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer().put(doubles, 1, 1);
226        assertEquals("00080706050403020100", toString(b));
227
228        float[] floats = new float[] { 0, Float.intBitsToFloat(0x01020304),
229                Float.intBitsToFloat(0x05060708), 0 };
230        b.order(ByteOrder.BIG_ENDIAN).asFloatBuffer().put(floats, 1, 2);
231        assertEquals("00010203040506070800", toString(b));
232        b.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().put(floats, 1, 2);
233        assertEquals("00040302010807060500", toString(b));
234
235        int[] ints = new int[] { 0, 0x01020304, 0x05060708, 0 };
236        b.order(ByteOrder.BIG_ENDIAN).asIntBuffer().put(ints, 1, 2);
237        assertEquals("00010203040506070800", toString(b));
238        b.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(ints, 1, 2);
239        assertEquals("00040302010807060500", toString(b));
240
241        long[] longs = new long[] { 0, 0x0102030405060708L, 0 };
242        b.order(ByteOrder.BIG_ENDIAN).asLongBuffer().put(longs, 1, 1);
243        assertEquals("00010203040506070800", toString(b));
244        b.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(longs, 1, 1);
245        assertEquals("00080706050403020100", toString(b));
246
247        short[] shorts = new short[] { 0, 0x0102, 0x0304, 0x0506, 0x0708, 0 };
248        b.order(ByteOrder.BIG_ENDIAN).asShortBuffer().put(shorts, 1, 4);
249        assertEquals("00010203040506070800", toString(b));
250        b.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shorts, 1, 4);
251        assertEquals("00020104030605080700", toString(b));
252    }
253
254    public void testByteBufferByteOrderDirectRW() throws Exception {
255        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), false);
256    }
257
258    public void testByteBufferByteOrderHeapRW() throws Exception {
259        testByteBufferByteOrder(ByteBuffer.allocate(10), false);
260    }
261
262    public void testByteBufferByteOrderMappedRW() throws Exception {
263        testByteBufferByteOrder(allocateMapped(10), false);
264    }
265
266    public void testByteBufferByteOrderDirectRO() throws Exception {
267        testByteBufferByteOrder(ByteBuffer.allocateDirect(10), true);
268    }
269
270    public void testByteBufferByteOrderHeapRO() throws Exception {
271        testByteBufferByteOrder(ByteBuffer.allocate(10), true);
272    }
273
274    public void testByteBufferByteOrderMappedRO() throws Exception {
275        testByteBufferByteOrder(allocateMapped(10), true);
276    }
277
278    private void testByteBufferByteOrder(ByteBuffer b, boolean readOnly) throws Exception {
279        if (readOnly) {
280            b = b.asReadOnlyBuffer();
281        }
282        // allocate/allocateDirect/map always returns a big-endian buffer.
283        assertEquals(ByteOrder.BIG_ENDIAN, b.order());
284
285        // wrap always returns a big-endian buffer.
286        assertEquals(ByteOrder.BIG_ENDIAN, b.wrap(new byte[10]).order());
287
288        // duplicate always returns a big-endian buffer.
289        b.order(ByteOrder.BIG_ENDIAN);
290        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
291        b.order(ByteOrder.LITTLE_ENDIAN);
292        assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
293
294        // slice always returns a big-endian buffer.
295        b.order(ByteOrder.BIG_ENDIAN);
296        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
297        b.order(ByteOrder.LITTLE_ENDIAN);
298        assertEquals(ByteOrder.BIG_ENDIAN, b.slice().order());
299
300        // asXBuffer always returns a current-endian buffer.
301        b.order(ByteOrder.BIG_ENDIAN);
302        assertEquals(ByteOrder.BIG_ENDIAN, b.asCharBuffer().order());
303        assertEquals(ByteOrder.BIG_ENDIAN, b.asDoubleBuffer().order());
304        assertEquals(ByteOrder.BIG_ENDIAN, b.asFloatBuffer().order());
305        assertEquals(ByteOrder.BIG_ENDIAN, b.asIntBuffer().order());
306        assertEquals(ByteOrder.BIG_ENDIAN, b.asLongBuffer().order());
307        assertEquals(ByteOrder.BIG_ENDIAN, b.asShortBuffer().order());
308        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
309        b.order(ByteOrder.LITTLE_ENDIAN);
310        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asCharBuffer().order());
311        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asDoubleBuffer().order());
312        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asFloatBuffer().order());
313        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asIntBuffer().order());
314        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asLongBuffer().order());
315        assertEquals(ByteOrder.LITTLE_ENDIAN, b.asShortBuffer().order());
316        // ...except for asReadOnlyBuffer, which always returns a big-endian buffer.
317        assertEquals(ByteOrder.BIG_ENDIAN, b.asReadOnlyBuffer().order());
318    }
319
320    public void testCharBufferByteOrderWrapped() throws Exception {
321        assertEquals(ByteOrder.nativeOrder(), CharBuffer.wrap(new char[10]).order());
322        assertEquals(ByteOrder.nativeOrder(), CharBuffer.wrap(new char[10]).asReadOnlyBuffer().order());
323    }
324
325    private void testCharBufferByteOrder(CharBuffer b, ByteOrder bo) throws Exception {
326        assertEquals(bo, b.order());
327        assertEquals(bo, b.duplicate().order());
328        assertEquals(bo, b.slice().order());
329        b = b.asReadOnlyBuffer();
330        assertEquals(bo, b.order());
331        assertEquals(bo, b.duplicate().order());
332        assertEquals(bo, b.slice().order());
333    }
334
335    private CharBuffer allocateCharBuffer(ByteOrder order) {
336        return ByteBuffer.allocate(10).order(order).asCharBuffer();
337    }
338
339    public void testCharBufferByteOrderArray() throws Exception {
340        testCharBufferByteOrder(CharBuffer.allocate(10), ByteOrder.nativeOrder());
341    }
342
343    public void testCharBufferByteOrderBE() throws Exception {
344        testCharBufferByteOrder(allocateCharBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
345    }
346
347    public void testCharBufferByteOrderLE() throws Exception {
348        testCharBufferByteOrder(allocateCharBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
349    }
350
351    public void testDoubleBufferByteOrderWrapped() throws Exception {
352        assertEquals(ByteOrder.nativeOrder(), DoubleBuffer.wrap(new double[10]).order());
353        assertEquals(ByteOrder.nativeOrder(), DoubleBuffer.wrap(new double[10]).asReadOnlyBuffer().order());
354    }
355
356    private void testDoubleBufferByteOrder(DoubleBuffer b, ByteOrder bo) throws Exception {
357        assertEquals(bo, b.order());
358        assertEquals(bo, b.duplicate().order());
359        assertEquals(bo, b.slice().order());
360        b = b.asReadOnlyBuffer();
361        assertEquals(bo, b.order());
362        assertEquals(bo, b.duplicate().order());
363        assertEquals(bo, b.slice().order());
364    }
365
366    private DoubleBuffer allocateDoubleBuffer(ByteOrder order) {
367        return ByteBuffer.allocate(10*8).order(order).asDoubleBuffer();
368    }
369
370    public void testDoubleBufferByteOrderArray() throws Exception {
371        testDoubleBufferByteOrder(DoubleBuffer.allocate(10), ByteOrder.nativeOrder());
372    }
373
374    public void testDoubleBufferByteOrderBE() throws Exception {
375        testDoubleBufferByteOrder(allocateDoubleBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
376    }
377
378    public void testDoubleBufferByteOrderLE() throws Exception {
379        testDoubleBufferByteOrder(allocateDoubleBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
380    }
381
382    public void testFloatBufferByteOrderWrapped() throws Exception {
383        assertEquals(ByteOrder.nativeOrder(), FloatBuffer.wrap(new float[10]).order());
384        assertEquals(ByteOrder.nativeOrder(), FloatBuffer.wrap(new float[10]).asReadOnlyBuffer().order());
385    }
386
387    private void testFloatBufferByteOrder(FloatBuffer b, ByteOrder bo) throws Exception {
388        assertEquals(bo, b.order());
389        assertEquals(bo, b.duplicate().order());
390        assertEquals(bo, b.slice().order());
391        b = b.asReadOnlyBuffer();
392        assertEquals(bo, b.order());
393        assertEquals(bo, b.duplicate().order());
394        assertEquals(bo, b.slice().order());
395    }
396
397    private FloatBuffer allocateFloatBuffer(ByteOrder order) {
398        return ByteBuffer.allocate(10*8).order(order).asFloatBuffer();
399    }
400
401    public void testFloatBufferByteOrderArray() throws Exception {
402        testFloatBufferByteOrder(FloatBuffer.allocate(10), ByteOrder.nativeOrder());
403    }
404
405    public void testFloatBufferByteOrderBE() throws Exception {
406        testFloatBufferByteOrder(allocateFloatBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
407    }
408
409    public void testFloatBufferByteOrderLE() throws Exception {
410        testFloatBufferByteOrder(allocateFloatBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
411    }
412
413    public void testIntBufferByteOrderWrapped() throws Exception {
414        assertEquals(ByteOrder.nativeOrder(), IntBuffer.wrap(new int[10]).order());
415        assertEquals(ByteOrder.nativeOrder(), IntBuffer.wrap(new int[10]).asReadOnlyBuffer().order());
416    }
417
418    private void testIntBufferByteOrder(IntBuffer b, ByteOrder bo) throws Exception {
419        assertEquals(bo, b.order());
420        assertEquals(bo, b.duplicate().order());
421        assertEquals(bo, b.slice().order());
422        b = b.asReadOnlyBuffer();
423        assertEquals(bo, b.order());
424        assertEquals(bo, b.duplicate().order());
425        assertEquals(bo, b.slice().order());
426    }
427
428    private IntBuffer allocateIntBuffer(ByteOrder order) {
429        return ByteBuffer.allocate(10*8).order(order).asIntBuffer();
430    }
431
432    public void testIntBufferByteOrderArray() throws Exception {
433        testIntBufferByteOrder(IntBuffer.allocate(10), ByteOrder.nativeOrder());
434    }
435
436    public void testIntBufferByteOrderBE() throws Exception {
437        testIntBufferByteOrder(allocateIntBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
438    }
439
440    public void testIntBufferByteOrderLE() throws Exception {
441        testIntBufferByteOrder(allocateIntBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
442    }
443
444    public void testLongBufferByteOrderWrapped() throws Exception {
445        assertEquals(ByteOrder.nativeOrder(), LongBuffer.wrap(new long[10]).order());
446        assertEquals(ByteOrder.nativeOrder(), LongBuffer.wrap(new long[10]).asReadOnlyBuffer().order());
447    }
448
449    private void testLongBufferByteOrder(LongBuffer b, ByteOrder bo) throws Exception {
450        assertEquals(bo, b.order());
451        assertEquals(bo, b.duplicate().order());
452        assertEquals(bo, b.slice().order());
453        b = b.asReadOnlyBuffer();
454        assertEquals(bo, b.order());
455        assertEquals(bo, b.duplicate().order());
456        assertEquals(bo, b.slice().order());
457    }
458
459    private LongBuffer allocateLongBuffer(ByteOrder order) {
460        return ByteBuffer.allocate(10*8).order(order).asLongBuffer();
461    }
462
463    public void testLongBufferByteOrderArray() throws Exception {
464        testLongBufferByteOrder(LongBuffer.allocate(10), ByteOrder.nativeOrder());
465    }
466
467    public void testLongBufferByteOrderBE() throws Exception {
468        testLongBufferByteOrder(allocateLongBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
469    }
470
471    public void testLongBufferByteOrderLE() throws Exception {
472        testLongBufferByteOrder(allocateLongBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
473    }
474
475    public void testShortBufferByteOrderWrapped() throws Exception {
476        assertEquals(ByteOrder.nativeOrder(), ShortBuffer.wrap(new short[10]).order());
477        assertEquals(ByteOrder.nativeOrder(), ShortBuffer.wrap(new short[10]).asReadOnlyBuffer().order());
478    }
479
480    private void testShortBufferByteOrder(ShortBuffer b, ByteOrder bo) throws Exception {
481        assertEquals(bo, b.order());
482        assertEquals(bo, b.duplicate().order());
483        assertEquals(bo, b.slice().order());
484        b = b.asReadOnlyBuffer();
485        assertEquals(bo, b.order());
486        assertEquals(bo, b.duplicate().order());
487        assertEquals(bo, b.slice().order());
488    }
489
490    private ShortBuffer allocateShortBuffer(ByteOrder order) {
491        return ByteBuffer.allocate(10*8).order(order).asShortBuffer();
492    }
493
494    public void testShortBufferByteOrderArray() throws Exception {
495        testShortBufferByteOrder(ShortBuffer.allocate(10), ByteOrder.nativeOrder());
496    }
497
498    public void testShortBufferByteOrderBE() throws Exception {
499        testShortBufferByteOrder(allocateShortBuffer(ByteOrder.BIG_ENDIAN), ByteOrder.BIG_ENDIAN);
500    }
501
502    public void testShortBufferByteOrderLE() throws Exception {
503        testShortBufferByteOrder(allocateShortBuffer(ByteOrder.LITTLE_ENDIAN), ByteOrder.LITTLE_ENDIAN);
504    }
505
506    public void testRelativePositionsHeap() throws Exception {
507        testRelativePositions(ByteBuffer.allocate(10));
508    }
509
510    public void testRelativePositionsDirect() throws Exception {
511        testRelativePositions(ByteBuffer.allocateDirect(10));
512    }
513
514    public void testRelativePositionsMapped() throws Exception {
515        testRelativePositions(allocateMapped(10));
516    }
517
518    // http://b/3291927 - ensure that the relative get and put methods advance 'position'.
519    private void testRelativePositions(ByteBuffer b) throws Exception {
520        // gets
521        b.position(0);
522        b.get();
523        assertEquals(1, b.position());
524
525        byte[] buf = new byte[5];
526        b.position(0);
527        b.get(buf);
528        assertEquals(5, b.position());
529
530        b.position(0);
531        b.get(buf, 1, 3);
532        assertEquals(3, b.position());
533
534        b.position(0);
535        b.getChar();
536        assertEquals(2, b.position());
537
538        b.position(0);
539        b.getDouble();
540        assertEquals(8, b.position());
541
542        b.position(0);
543        b.getFloat();
544        assertEquals(4, b.position());
545
546        b.position(0);
547        b.getInt();
548        assertEquals(4, b.position());
549
550        b.position(0);
551        b.getLong();
552        assertEquals(8, b.position());
553
554        b.position(0);
555        b.getShort();
556        assertEquals(2, b.position());
557
558        // puts
559        b.position(0);
560        b.put((byte) 0);
561        assertEquals(1, b.position());
562
563        b.position(0);
564        b.put(buf);
565        assertEquals(5, b.position());
566
567        b.position(0);
568        b.put(buf, 1, 3);
569        assertEquals(3, b.position());
570
571        b.position(0);
572        b.putChar('x');
573        assertEquals(2, b.position());
574
575        b.position(0);
576        b.putDouble(0);
577        assertEquals(8, b.position());
578
579        b.position(0);
580        b.putFloat(0);
581        assertEquals(4, b.position());
582
583        b.position(0);
584        b.putInt(0);
585        assertEquals(4, b.position());
586
587        b.position(0);
588        b.putLong(0);
589        assertEquals(8, b.position());
590
591        b.position(0);
592        b.putShort((short) 0);
593        assertEquals(2, b.position());
594    }
595
596    // This test will fail on the RI. Our direct buffers are cooler than theirs.
597    // http://b/3384431
598    public void testDirectByteBufferHasArray() throws Exception {
599        ByteBuffer b = ByteBuffer.allocateDirect(10);
600        assertTrue(b.isDirect());
601        // Check the buffer has an array of the right size.
602        assertTrue(b.hasArray());
603        assertEquals(0, b.arrayOffset());
604        byte[] array = b.array();
605        assertEquals(10, array.length);
606        // Check that writes to the array show up in the buffer.
607        assertEquals(0, b.get(0));
608        array[0] = 1;
609        assertEquals(1, b.get(0));
610        // Check that writes to the buffer show up in the array.
611        assertEquals(1, array[0]);
612        b.put(0, (byte) 0);
613        assertEquals(0, array[0]);
614    }
615
616    public void testSliceOffset() throws Exception {
617        // Slicing changes the array offset.
618        ByteBuffer buffer = ByteBuffer.allocate(10);
619        buffer.get();
620        ByteBuffer slice = buffer.slice();
621        assertEquals(0, buffer.arrayOffset());
622        assertEquals(1, slice.arrayOffset());
623
624        ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
625        directBuffer.get();
626        ByteBuffer directSlice = directBuffer.slice();
627        assertEquals(0, directBuffer.arrayOffset());
628        assertEquals(1, directSlice.arrayOffset());
629    }
630
631    // http://code.google.com/p/android/issues/detail?id=16184
632    public void testPutByteBuffer() throws Exception {
633        ByteBuffer dst = ByteBuffer.allocate(10).asReadOnlyBuffer();
634
635        // Can't put into a read-only buffer.
636        try {
637            dst.put(ByteBuffer.allocate(5));
638            fail();
639        } catch (ReadOnlyBufferException expected) {
640        }
641
642        // Can't put a buffer into itself.
643        dst = ByteBuffer.allocate(10);
644        try {
645            dst.put(dst);
646            fail();
647        } catch (IllegalArgumentException expected) {
648        }
649
650        // Can't put the null ByteBuffer.
651        try {
652            dst.put((ByteBuffer) null);
653            fail();
654        } catch (NullPointerException expected) {
655        }
656
657        // Can't put a larger source into a smaller destination.
658        try {
659            dst.put(ByteBuffer.allocate(dst.capacity() + 1));
660            fail();
661        } catch (BufferOverflowException expected) {
662        }
663
664        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocate(8), false);
665        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocateDirect(8), false);
666        assertPutByteBuffer(ByteBuffer.allocate(10), allocateMapped(8), false);
667        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocate(8), true);
668        assertPutByteBuffer(ByteBuffer.allocate(10), ByteBuffer.allocateDirect(8), true);
669        assertPutByteBuffer(ByteBuffer.allocate(10), allocateMapped(8), true);
670
671        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocate(8), false);
672        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocateDirect(8), false);
673        assertPutByteBuffer(ByteBuffer.allocateDirect(10), allocateMapped(8), false);
674        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocate(8), true);
675        assertPutByteBuffer(ByteBuffer.allocateDirect(10), ByteBuffer.allocateDirect(8), true);
676        assertPutByteBuffer(ByteBuffer.allocateDirect(10), allocateMapped(8), true);
677    }
678
679    private void assertPutByteBuffer(ByteBuffer dst, ByteBuffer src, boolean readOnly) {
680        // Start 'dst' off as the index-identity pattern.
681        for (int i = 0; i < dst.capacity(); ++i) {
682            dst.put(i, (byte) i);
683        }
684        // Deliberately offset the position we'll write to by 1.
685        dst.position(1);
686
687        // Make the source more interesting.
688        for (int i = 0; i < src.capacity(); ++i) {
689            src.put(i, (byte) (16 + i));
690        }
691        if (readOnly) {
692            src = src.asReadOnlyBuffer();
693        }
694
695        ByteBuffer dst2 = dst.put(src);
696        assertSame(dst, dst2);
697        assertEquals(0, src.remaining());
698        assertEquals(src.position(), src.capacity());
699        assertEquals(dst.position(), src.capacity() + 1);
700        for (int i = 0; i < src.capacity(); ++i) {
701            assertEquals(src.get(i), dst.get(i + 1));
702        }
703
704        // No room for another.
705        src.position(0);
706        try {
707            dst.put(src);
708            fail();
709        } catch (BufferOverflowException expected) {
710        }
711    }
712
713    public void testCharBufferSubSequence() throws Exception {
714        ByteBuffer b = ByteBuffer.allocateDirect(10).order(ByteOrder.nativeOrder());
715        b.putChar('H');
716        b.putChar('e');
717        b.putChar('l');
718        b.putChar('l');
719        b.putChar('o');
720        b.flip();
721
722        assertEquals("Hello", b.asCharBuffer().toString());
723
724        CharBuffer cb = b.asCharBuffer();
725        CharSequence cs = cb.subSequence(0, cb.length());
726        assertEquals("Hello", cs.toString());
727    }
728
729    public void testHasArrayOnJniDirectByteBuffer() throws Exception {
730        // Simulate a call to JNI's NewDirectByteBuffer.
731        Class<?> c = Class.forName("java.nio.DirectByteBuffer");
732        Constructor<?> ctor = c.getDeclaredConstructor(long.class, int.class);
733        ctor.setAccessible(true);
734        ByteBuffer bb = (ByteBuffer) ctor.newInstance(0, 0);
735
736        try {
737            bb.array();
738            fail();
739        } catch (UnsupportedOperationException expected) {
740        }
741        try {
742            bb.arrayOffset();
743            fail();
744        } catch (UnsupportedOperationException expected) {
745        }
746        assertFalse(bb.hasArray());
747    }
748
749    public void testBug6085292() {
750        ByteBuffer b = ByteBuffer.allocateDirect(1);
751
752        try {
753            b.asCharBuffer().get();
754            fail();
755        } catch (BufferUnderflowException expected) {
756        }
757        try {
758            b.asCharBuffer().get(0);
759            fail();
760        } catch (IndexOutOfBoundsException expected) {
761            assertTrue(expected.getMessage().contains("limit=0"));
762        }
763
764        try {
765            b.asDoubleBuffer().get();
766            fail();
767        } catch (BufferUnderflowException expected) {
768        }
769        try {
770            b.asDoubleBuffer().get(0);
771            fail();
772        } catch (IndexOutOfBoundsException expected) {
773            assertTrue(expected.getMessage().contains("limit=0"));
774        }
775
776        try {
777            b.asFloatBuffer().get();
778            fail();
779        } catch (BufferUnderflowException expected) {
780        }
781        try {
782            b.asFloatBuffer().get(0);
783            fail();
784        } catch (IndexOutOfBoundsException expected) {
785            assertTrue(expected.getMessage().contains("limit=0"));
786        }
787
788        try {
789            b.asIntBuffer().get();
790            fail();
791        } catch (BufferUnderflowException expected) {
792        }
793        try {
794            b.asIntBuffer().get(0);
795            fail();
796        } catch (IndexOutOfBoundsException expected) {
797            assertTrue(expected.getMessage().contains("limit=0"));
798        }
799
800        try {
801            b.asLongBuffer().get();
802            fail();
803        } catch (BufferUnderflowException expected) {
804        }
805        try {
806            b.asLongBuffer().get(0);
807            fail();
808        } catch (IndexOutOfBoundsException expected) {
809            assertTrue(expected.getMessage().contains("limit=0"));
810        }
811
812        try {
813            b.asShortBuffer().get();
814            fail();
815        } catch (BufferUnderflowException expected) {
816        }
817        try {
818            b.asShortBuffer().get(0);
819            fail();
820        } catch (IndexOutOfBoundsException expected) {
821            assertTrue(expected.getMessage().contains("limit=0"));
822        }
823    }
824
825    public void testUsingDirectBufferAsMappedBuffer() throws Exception {
826        MappedByteBuffer notMapped = (MappedByteBuffer) ByteBuffer.allocateDirect(1);
827        try {
828            notMapped.force();
829            fail();
830        } catch (UnsupportedOperationException expected) {
831        }
832        try {
833            notMapped.isLoaded();
834            fail();
835        } catch (UnsupportedOperationException expected) {
836        }
837        try {
838            notMapped.load();
839            fail();
840        } catch (UnsupportedOperationException expected) {
841        }
842
843        MappedByteBuffer mapped = (MappedByteBuffer) allocateMapped(1);
844        mapped.force();
845        mapped.isLoaded();
846        mapped.load();
847    }
848
849    // https://code.google.com/p/android/issues/detail?id=53637
850    public void testBug53637() throws Exception {
851        MappedByteBuffer mapped = (MappedByteBuffer) allocateMapped(1);
852        mapped.get();
853        mapped.rewind();
854        mapped.get();
855
856        mapped.rewind();
857        mapped.mark();
858        mapped.get();
859        mapped.reset();
860        mapped.get();
861
862        mapped.rewind();
863        mapped.get();
864        mapped.clear();
865        mapped.get();
866
867        mapped.rewind();
868        mapped.get();
869        mapped.flip();
870        mapped.get();
871    }
872
873    public void testElementSizeShifts() {
874        // Element size shifts are the log base 2 of the element size
875        // of this buffer.
876        assertEquals(1, 1 << ByteBuffer.allocate(0).getElementSizeShift());
877
878        assertEquals(SizeOf.CHAR, 1 << CharBuffer.allocate(0).getElementSizeShift());
879        assertEquals(SizeOf.SHORT, 1 << ShortBuffer.allocate(0).getElementSizeShift());
880
881        assertEquals(SizeOf.INT, 1 << IntBuffer.allocate(0).getElementSizeShift());
882        assertEquals(SizeOf.FLOAT, 1 << FloatBuffer.allocate(0).getElementSizeShift());
883
884        assertEquals(SizeOf.LONG, 1 << LongBuffer.allocate(0).getElementSizeShift());
885        assertEquals(SizeOf.DOUBLE, 1 << DoubleBuffer.allocate(0).getElementSizeShift());
886    }
887
888    public void testFreed() {
889        ByteBuffer b1 = ByteBuffer.allocateDirect(1);
890        ByteBuffer b2 = b1.duplicate();
891        NioUtils.freeDirectBuffer(b1);
892        for (ByteBuffer b: new ByteBuffer[] { b1, b2 }) {
893            assertFalse(b.isAccessible());
894            try {
895                b.compact();
896                fail();
897            } catch (IllegalStateException expected) {
898            }
899            try {
900                b.duplicate();
901                fail();
902            } catch (IllegalStateException expected) {
903            }
904            testFailForPutMethods(b);
905            testFailForAsMethods(b);
906            testFailForGetMethods(b);
907            NioUtils.freeDirectBuffer(b); // should be able to free twice
908        }
909    }
910
911    public void testAccess() {
912        ByteBuffer b1 = ByteBuffer.allocate(1);
913        ByteBuffer b2 = b1.duplicate();
914        for (ByteBuffer b: new ByteBuffer[] { b1, b2 }) {
915            try {
916                b.setAccessible(true);
917                fail();
918            } catch (UnsupportedOperationException expected) {
919            }
920            try {
921                b.setAccessible(false);
922                fail();
923            } catch (UnsupportedOperationException expected) {
924            }
925        }
926        b1 = ByteBuffer.allocateDirect(8);
927        b2 = b1.duplicate();
928        b1.setAccessible(false);
929        ByteBuffer b3 = b1.asReadOnlyBuffer();
930        for (ByteBuffer b: new ByteBuffer[] { b1, b2, b3 }) {
931            b.duplicate();
932            assertFalse(b.isAccessible());
933            // even read-only buffers should fail with IllegalStateException
934            testFailForPutMethods(b);
935            testAsMethods(b);
936            testFailForGetMethods(b);
937            b.position(0);
938            b.limit(8);
939            try {
940                b.asCharBuffer().get(0);
941                fail();
942            } catch (IllegalStateException expected) {
943            }
944            try {
945                b.asShortBuffer().get(0);
946                fail();
947            } catch (IllegalStateException expected) {
948            }
949            try {
950                b.asIntBuffer().get(0);
951                fail();
952            } catch (IllegalStateException expected) {
953            }
954            try {
955                b.asLongBuffer().get(0);
956                fail();
957            } catch (IllegalStateException expected) {
958            }
959            try {
960                b.asFloatBuffer().get(0);
961                fail();
962            } catch (IllegalStateException expected) {
963            }
964            try {
965                b.asDoubleBuffer().get(0);
966                fail();
967            } catch (IllegalStateException expected) {
968            }
969        }
970        b2.setAccessible(true);
971        for (ByteBuffer b: new ByteBuffer[] { b1, b2, b3 }) {
972            assertTrue(b.isAccessible());
973            b.position(0);
974            b.limit(8);
975            b.asCharBuffer().get(0);
976            b.asShortBuffer().get(0);
977            b.asIntBuffer().get(0);
978            b.asLongBuffer().get(0);
979            b.asFloatBuffer().get(0);
980            b.asDoubleBuffer().get(0);
981            if (!b.isReadOnly()) {
982                testPutMethods(b);
983                b.compact();
984            } else {
985                try {
986                    b.put(0, (byte) 0);
987                    fail();
988                } catch (ReadOnlyBufferException expected) {
989                }
990            }
991            testAsMethods(b);
992            testGetMethods(b);
993        }
994    }
995
996    private void testPutMethods(ByteBuffer b) {
997        b.position(0);
998        b.put((byte) 0);
999        b.put(0, (byte) 0);
1000        b.put(new byte[1]);
1001        b.put(new byte[1], 0, 1);
1002        b.put(ByteBuffer.allocate(1));
1003        b.putChar('a');
1004        b.putChar(0, 'a');
1005        b.position(0);
1006        b.putDouble(0);
1007        b.putDouble(0, 0);
1008        b.position(0);
1009        b.putFloat(0);
1010        b.putFloat(0, 0);
1011        b.putInt(0);
1012        b.putInt(0, 0);
1013        b.position(0);
1014        b.putLong(0);
1015        b.putLong(0, 0);
1016        b.position(0);
1017        b.putShort((short) 0);
1018        b.putShort(0, (short) 0);
1019    }
1020
1021    private void testFailForPutMethods(ByteBuffer b) {
1022        try {
1023            b.put((byte) 0);
1024            fail();
1025        } catch (IllegalStateException expected) {
1026        }
1027        try {
1028            b.put(0, (byte) 0);
1029            fail();
1030        } catch (IllegalStateException expected) {
1031        }
1032        try {
1033            b.put(new byte[1]);
1034            fail();
1035        } catch (IllegalStateException expected) {
1036        }
1037        try {
1038            b.put(new byte[1], 0, 1);
1039            fail();
1040        } catch (IllegalStateException expected) {
1041        }
1042        try {
1043            b.put(ByteBuffer.allocate(1));
1044            fail();
1045        } catch (IllegalStateException expected) {
1046        }
1047        try {
1048            b.putChar('a');
1049            fail();
1050        } catch (IllegalStateException expected) {
1051        }
1052        try {
1053            b.putChar(0, 'a');
1054            fail();
1055        } catch (IllegalStateException expected) {
1056        }
1057        try {
1058            b.putDouble(0);
1059            fail();
1060        } catch (IllegalStateException expected) {
1061        }
1062        try {
1063            b.putDouble(0, 0);
1064            fail();
1065        } catch (IllegalStateException expected) {
1066        }
1067        try {
1068            b.putFloat(0);
1069            fail();
1070        } catch (IllegalStateException expected) {
1071        }
1072        try {
1073            b.putFloat(0, 0);
1074            fail();
1075        } catch (IllegalStateException expected) {
1076        }
1077        try {
1078            b.putInt(0);
1079            fail();
1080        } catch (IllegalStateException expected) {
1081        }
1082        try {
1083            b.putInt(0, 0);
1084            fail();
1085        } catch (IllegalStateException expected) {
1086        }
1087        try {
1088            b.putLong(0);
1089            fail();
1090        } catch (IllegalStateException expected) {
1091        }
1092        try {
1093            b.putLong(0, 0);
1094            fail();
1095        } catch (IllegalStateException expected) {
1096        }
1097        try {
1098            b.putShort((short) 0);
1099            fail();
1100        } catch (IllegalStateException expected) {
1101        }
1102        try {
1103            b.putShort(0, (short) 0);
1104            fail();
1105        } catch (IllegalStateException expected) {
1106        }
1107    }
1108
1109    private void testGetMethods(ByteBuffer b) {
1110        b.position(0);
1111        b.get();
1112        b.get(0);
1113        b.get(new byte[1]);
1114        b.get(new byte[1], 0, 1);
1115        b.getChar();
1116        b.getChar(0);
1117        b.position(0);
1118        b.getDouble();
1119        b.getDouble(0);
1120        b.position(0);
1121        b.getFloat();
1122        b.getFloat(0);
1123        b.getInt();
1124        b.getInt(0);
1125        b.position(0);
1126        b.getLong();
1127        b.getLong(0);
1128        b.position(0);
1129        b.getShort();
1130        b.getShort(0);
1131    }
1132
1133    private void testFailForGetMethods(ByteBuffer b) {
1134        try {
1135            b.get();
1136            fail();
1137        } catch (IllegalStateException expected) {
1138        }
1139        try {
1140            b.get(0);
1141            fail();
1142        } catch (IllegalStateException expected) {
1143        }
1144        try {
1145            b.get(new byte[1]);
1146            fail();
1147        } catch (IllegalStateException expected) {
1148        }
1149        try {
1150            b.get(new byte[1], 0, 1);
1151            fail();
1152        } catch (IllegalStateException expected) {
1153        }
1154        try {
1155            b.getChar();
1156            fail();
1157        } catch (IllegalStateException expected) {
1158        }
1159        try {
1160            b.getChar(0);
1161            fail();
1162        } catch (IllegalStateException expected) {
1163        }
1164        try {
1165            b.getDouble();
1166            fail();
1167        } catch (IllegalStateException expected) {
1168        }
1169        try {
1170            b.getDouble(0);
1171            fail();
1172        } catch (IllegalStateException expected) {
1173        }
1174        try {
1175            b.getFloat();
1176            fail();
1177        } catch (IllegalStateException expected) {
1178        }
1179        try {
1180            b.getFloat(0);
1181            fail();
1182        } catch (IllegalStateException expected) {
1183        }
1184        try {
1185            b.getInt();
1186            fail();
1187        } catch (IllegalStateException expected) {
1188        }
1189        try {
1190            b.getInt(0);
1191            fail();
1192        } catch (IllegalStateException expected) {
1193        }
1194        try {
1195            b.getLong();
1196            fail();
1197        } catch (IllegalStateException expected) {
1198        }
1199        try {
1200            b.getLong(0);
1201            fail();
1202        } catch (IllegalStateException expected) {
1203        }
1204        try {
1205            b.getShort();
1206            fail();
1207        } catch (IllegalStateException expected) {
1208        }
1209        try {
1210            b.getShort(0);
1211            fail();
1212        } catch (IllegalStateException expected) {
1213        }
1214    }
1215
1216    private void testAsMethods(ByteBuffer b) {
1217        b.asCharBuffer();
1218        b.asDoubleBuffer();
1219        b.asFloatBuffer();
1220        b.asIntBuffer();
1221        b.asLongBuffer();
1222        b.asReadOnlyBuffer();
1223        b.asShortBuffer();
1224    }
1225
1226    private void testFailForAsMethods(ByteBuffer b) {
1227        try {
1228            b.asCharBuffer();
1229            fail();
1230        } catch (IllegalStateException expected) {
1231        }
1232        try {
1233            b.asDoubleBuffer();
1234            fail();
1235        } catch (IllegalStateException expected) {
1236        }
1237        try {
1238            b.asFloatBuffer();
1239            fail();
1240        } catch (IllegalStateException expected) {
1241        }
1242        try {
1243            b.asIntBuffer();
1244            fail();
1245        } catch (IllegalStateException expected) {
1246        }
1247        try {
1248            b.asLongBuffer();
1249            fail();
1250        } catch (IllegalStateException expected) {
1251        }
1252        try {
1253            b.asReadOnlyBuffer();
1254            fail();
1255        } catch (IllegalStateException expected) {
1256        }
1257        try {
1258            b.asShortBuffer();
1259            fail();
1260        } catch (IllegalStateException expected) {
1261        }
1262    }
1263
1264}
1265