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