• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* Type-specific source code for unit test
25 *
26 * Regenerate the BasicX classes via genBasic.sh whenever this file changes.
27 * We check in the generated source files so that the test tree can be used
28 * independently of the rest of the source tree.
29 */
30package test.java.nio.Buffer;
31
32#warn This file is preprocessed before being compiled
33
34#if[byte]
35import java.io.IOException;
36import java.io.UncheckedIOException;
37#end[byte]
38import java.nio.*;
39#if[byte]
40import java.nio.channels.FileChannel;
41import java.nio.file.Files;
42import java.nio.file.Path;
43import java.util.Random;
44#end[byte]
45
46
47public class Basic$Type$
48    extends Basic
49{
50
51    private static final $type$[] VALUES = {
52        $Fulltype$.MIN_VALUE,
53        ($type$) -1,
54        ($type$) 0,
55        ($type$) 1,
56        $Fulltype$.MAX_VALUE,
57#if[float]
58        $Fulltype$.NEGATIVE_INFINITY,
59        $Fulltype$.POSITIVE_INFINITY,
60        $Fulltype$.NaN,
61        ($type$) -0.0,
62#end[float]
63#if[double]
64        $Fulltype$.NEGATIVE_INFINITY,
65        $Fulltype$.POSITIVE_INFINITY,
66        $Fulltype$.NaN,
67        ($type$) -0.0,
68#end[double]
69    };
70
71    private static void relGet($Type$Buffer b) {
72        int n = b.capacity();
73        for (int i = 0; i < n; i++)
74            ck(b, (long)b.get(), (long)(($type$)ic(i)));
75        b.rewind();
76    }
77
78    private static void relGet($Type$Buffer b, int start) {
79        int n = b.remaining();
80        for (int i = start; i < n; i++)
81            ck(b, (long)b.get(), (long)(($type$)ic(i)));
82        b.rewind();
83    }
84
85    private static void absGet($Type$Buffer b) {
86        int n = b.capacity();
87        for (int i = 0; i < n; i++)
88            ck(b, (long)b.get(), (long)(($type$)ic(i)));
89        b.rewind();
90    }
91
92    private static void bulkGet($Type$Buffer b) {
93        int n = b.capacity();
94        $type$[] a = new $type$[n + 7];
95        b.get(a, 7, n);
96        for (int i = 0; i < n; i++) {
97            ck(b, (long)a[i + 7], (long)(($type$)ic(i)));
98        }
99    }
100
101    private static void relPut($Type$Buffer b) {
102        int n = b.capacity();
103        b.clear();
104        for (int i = 0; i < n; i++)
105            b.put(($type$)ic(i));
106        b.flip();
107    }
108
109    private static void absPut($Type$Buffer b) {
110        int n = b.capacity();
111        b.clear();
112        for (int i = 0; i < n; i++)
113            b.put(i, ($type$)ic(i));
114        b.limit(n);
115        b.position(0);
116    }
117
118    private static void bulkPutArray($Type$Buffer b) {
119        int n = b.capacity();
120        b.clear();
121        $type$[] a = new $type$[n + 7];
122        for (int i = 0; i < n; i++)
123            a[i + 7] = ($type$)ic(i);
124        b.put(a, 7, n);
125        b.flip();
126    }
127
128    private static void bulkPutBuffer($Type$Buffer b) {
129        int n = b.capacity();
130        b.clear();
131        $Type$Buffer c = $Type$Buffer.allocate(n + 7);
132        c.position(7);
133        for (int i = 0; i < n; i++)
134            c.put(($type$)ic(i));
135        c.flip();
136        c.position(7);
137        b.put(c);
138        b.flip();
139        try {
140            b.put(b);
141            fail("IllegalArgumentException expected for put into same buffer");
142        } catch (IllegalArgumentException e) {
143            if (e.getMessage() == null) {
144                fail("Non-null IllegalArgumentException message expected from"
145                     + " put into same buffer");
146            }
147        }
148    }
149
150    //6231529
151    private static void callReset($Type$Buffer b) {
152        b.position(0);
153        b.mark();
154
155        b.duplicate().reset();
156        b.asReadOnlyBuffer().reset();
157    }
158
159#if[byte]
160#else[byte]
161    // 6221101-6234263
162
163    private static void putBuffer() {
164        final int cap = 10;
165
166        $Type$Buffer direct1 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
167        $Type$Buffer nondirect1 = ByteBuffer.allocate(cap).as$Type$Buffer();
168        direct1.put(nondirect1);
169
170        $Type$Buffer direct2 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
171        $Type$Buffer nondirect2 = ByteBuffer.allocate(cap).as$Type$Buffer();
172        nondirect2.put(direct2);
173
174        $Type$Buffer direct3 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
175        $Type$Buffer direct4 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
176        direct3.put(direct4);
177
178        $Type$Buffer nondirect3 = ByteBuffer.allocate(cap).as$Type$Buffer();
179        $Type$Buffer nondirect4 = ByteBuffer.allocate(cap).as$Type$Buffer();
180        nondirect3.put(nondirect4);
181    }
182#end[byte]
183
184#if[char]
185
186    private static void bulkPutString($Type$Buffer b) {
187        int n = b.capacity();
188        b.clear();
189        StringBuilder sb = new StringBuilder(n + 7);
190        sb.append("1234567");
191        for (int i = 0; i < n; i++)
192            sb.append((char)ic(i));
193        b.put(sb.toString(), 7, 7 + n);
194        b.flip();
195    }
196
197#end[char]
198
199    private static void checkSlice($Type$Buffer b, $Type$Buffer slice) {
200        ck(slice, 0, slice.position());
201        ck(slice, b.remaining(), slice.limit());
202        ck(slice, b.remaining(), slice.capacity());
203        if (b.isDirect() != slice.isDirect())
204            fail("Lost direction", slice);
205        if (b.isReadOnly() != slice.isReadOnly())
206            fail("Lost read-only", slice);
207    }
208
209#if[byte]
210
211    private static void checkBytes(ByteBuffer b, byte[] bs) {
212        int n = bs.length;
213        int p = b.position();
214        if (b.order() == ByteOrder.BIG_ENDIAN) {
215            for (int i = 0; i < n; i++) {
216                ck(b, b.get(), bs[i]);
217            }
218        } else {
219            for (int i = n - 1; i >= 0; i--) {
220                ck(b, b.get(), bs[i]);
221            }
222        }
223        b.position(p);
224    }
225
226    private static void compact(Buffer b) {
227        try {
228            Class<?> cl = b.getClass();
229            java.lang.reflect.Method m = cl.getDeclaredMethod("compact");
230            m.setAccessible(true);
231            m.invoke(b);
232        } catch (Exception e) {
233            fail(e.getMessage(), b);
234        }
235    }
236
237    private static void checkInvalidMarkException(final Buffer b) {
238        tryCatch(b, InvalidMarkException.class, () -> {
239                b.mark();
240                compact(b);
241                b.reset();
242            });
243    }
244
245    private static void testHet(int level, ByteBuffer b) {
246
247        int p = b.position();
248        b.limit(b.capacity());
249
250        b.putChar((char)1);
251        b.putChar((char)Character.MAX_VALUE);
252
253        b.putShort((short)1);
254        b.putShort((short)Short.MAX_VALUE);
255
256        b.putInt(1);
257        b.putInt(Integer.MAX_VALUE);
258
259        b.putLong((long)1);
260        b.putLong((long)Long.MAX_VALUE);
261
262        b.putFloat((float)1);
263        b.putFloat((float)Float.MIN_VALUE);
264        b.putFloat((float)Float.MAX_VALUE);
265
266        b.putDouble((double)1);
267        b.putDouble((double)Double.MIN_VALUE);
268        b.putDouble((double)Double.MAX_VALUE);
269
270        b.limit(b.position());
271        b.position(p);
272
273        ck(b, b.getChar(), 1);
274        ck(b, b.getChar(), Character.MAX_VALUE);
275
276        ck(b, b.getShort(), 1);
277        ck(b, b.getShort(), Short.MAX_VALUE);
278
279        ck(b, b.getInt(), 1);
280        ck(b, b.getInt(), Integer.MAX_VALUE);
281
282        ck(b, b.getLong(), 1);
283        ck(b, b.getLong(), Long.MAX_VALUE);
284
285        ck(b, (long)b.getFloat(), 1);
286        ck(b, (long)b.getFloat(), (long)Float.MIN_VALUE);
287        ck(b, (long)b.getFloat(), (long)Float.MAX_VALUE);
288
289        ck(b, (long)b.getDouble(), 1);
290        ck(b, (long)b.getDouble(), (long)Double.MIN_VALUE);
291        ck(b, (long)b.getDouble(), (long)Double.MAX_VALUE);
292
293    }
294
295    private static void testAlign(final ByteBuffer b, boolean direct) {
296        // index out-of bounds
297        catchIllegalArgument(b, () -> b.alignmentOffset(-1, (short) 1));
298
299        // unit size values
300        catchIllegalArgument(b, () -> b.alignmentOffset(0, (short) 0));
301        for (int us = 1; us < 65; us++) {
302            int _us = us;
303            if ((us & (us - 1)) != 0) {
304                // unit size not a power of two
305                catchIllegalArgument(b, () -> b.alignmentOffset(0, _us));
306            } else {
307                if (direct || us <= 8) {
308                    b.alignmentOffset(0, us);
309                } else {
310                    // unit size > 8 with non-direct buffer
311                    tryCatch(b, UnsupportedOperationException.class,
312                            () -> b.alignmentOffset(0, _us));
313                }
314            }
315        }
316
317        // Probe for long misalignment at index zero for a newly created buffer
318        ByteBuffer empty =
319                direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
320        int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
321
322        if (direct) {
323            // Freshly created direct byte buffers should be aligned at index 0
324            // for ref and primitive values (see Unsafe.allocateMemory)
325            if (longMisalignmentAtZero != 0) {
326                fail("Direct byte buffer misaligned at index 0"
327                        + " for ref and primitive values "
328                        + longMisalignmentAtZero);
329            }
330        } else {
331            // For heap byte buffers misalignment may occur on 32-bit systems
332            // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
333            // Note the GC will preserve alignment of the base address of the
334            // array
335            if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8
336                    != longMisalignmentAtZero) {
337                fail("Heap byte buffer misaligned at index 0"
338                        + " for ref and primitive values "
339                        + longMisalignmentAtZero);
340            }
341        }
342
343        // Ensure test buffer is correctly aligned at index 0
344        if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
345            fail("Test input buffer not correctly aligned at index 0", b);
346
347        // Test misalignment values
348        for (int us : new int[]{1, 2, 4, 8}) {
349            for (int i = 0; i < us * 2; i++) {
350                int am = b.alignmentOffset(i, us);
351                int expectedAm = (longMisalignmentAtZero + i) % us;
352
353                if (am != expectedAm) {
354                    String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d";
355                    fail(String.format(f, i, us, am, expectedAm));
356                }
357            }
358        }
359
360        // Created aligned slice to test against
361        int ap = 8 - longMisalignmentAtZero;
362        int al = b.limit() - b.alignmentOffset(b.limit(), 8);
363        $Type$Buffer intermediate = ($Type$Buffer) b.position(ap).limit(al);
364        ByteBuffer ab = intermediate.slice();
365        if (ab.limit() == 0) {
366            fail("Test input buffer not sufficiently sized to cover" +
367                    " an aligned region for all values", b);
368        }
369        if (ab.alignmentOffset(0, 8) != 0)
370            fail("Aligned test input buffer not correctly aligned at index 0", ab);
371
372        for (int us : new int[]{1, 2, 4, 8}) {
373            for (int p = 1; p < 16; p++) {
374                int l = ab.limit() - p;
375
376                intermediate = ($Type$Buffer) ab.slice().position(p).limit(l);
377                ByteBuffer as = intermediate.alignedSlice(us);
378
379                ck(as, 0, as.position());
380                ck(as, as.capacity(), as.limit());
381                if (b.isDirect() != as.isDirect())
382                    fail("Lost direction", as);
383                if (b.isReadOnly() != as.isReadOnly())
384                    fail("Lost read-only", as);
385
386                int p_mod = ab.alignmentOffset(p, us);
387                int l_mod = ab.alignmentOffset(l, us);
388                // Round up position
389                p = (p_mod > 0) ? p + (us - p_mod) : p;
390                // Round down limit
391                l = l - l_mod;
392
393                int ec = l - p;
394                if (as.limit() != ec) {
395                    fail("Buffer capacity incorrect, expected: " + ec, as);
396                }
397            }
398        }
399
400        // mapped buffers
401        try {
402            for (MappedByteBuffer bb : mappedBuffers()) {
403                try {
404                    int offset = bb.alignmentOffset(1, 4);
405                    ck(bb, offset >= 0);
406                } catch (UnsupportedOperationException e) {
407                }
408            }
409        } catch (IOException e) {
410            throw new UncheckedIOException(e);
411        }
412
413        // alignment identities
414        final int maxPow2 = 12;
415        ByteBuffer bb = ByteBuffer.allocateDirect(1 << maxPow2); // cap 4096
416
417        Random rnd = new Random();
418        long seed = rnd.nextLong();
419        rnd = new Random(seed);
420
421        for (int i = 0; i < 100; i++) {
422            // 1 == 2^0 <= unitSize == 2^k <= bb.capacity()/2
423            int unitSize = 1 << rnd.nextInt(maxPow2);
424            // 0 <= index < 2*unitSize
425            int index = rnd.nextInt(unitSize << 1);
426            int value = bb.alignmentOffset(index, unitSize);
427            try {
428                if (value < 0 || value >= unitSize) {
429                    throw new RuntimeException(value + " < 0 || " +
430                        value + " >= " + unitSize);
431                }
432                if (value <= index &&
433                    bb.alignmentOffset(index - value, unitSize) != 0)
434                    throw new RuntimeException("Identity 1");
435                if (bb.alignmentOffset(index + (unitSize - value),
436                    unitSize) != 0)
437                    throw new RuntimeException("Identity 2");
438            } catch (RuntimeException re) {
439                System.err.format("seed %d, index %d, unitSize %d, value %d%n",
440                    seed, index, unitSize, value);
441                throw re;
442            }
443        }
444    }
445
446    private static MappedByteBuffer[] mappedBuffers() throws IOException {
447        return new MappedByteBuffer[]{
448                createMappedBuffer(new byte[]{0, 1, 2, 3}),
449                createMappedBuffer(new byte[]{0, 1, 2, -3,
450                    45, 6, 7, 78, 3, -7, 6, 7, -128, 127}),
451        };
452    }
453
454    private static MappedByteBuffer createMappedBuffer(byte[] contents)
455        throws IOException {
456        Path tempFile = Files.createTempFile("mbb", null);
457        tempFile.toFile().deleteOnExit();
458        Files.write(tempFile, contents);
459        try (FileChannel fc = FileChannel.open(tempFile)) {
460            MappedByteBuffer map =
461                fc.map(FileChannel.MapMode.READ_ONLY, 0, contents.length);
462            map.load();
463            return map;
464        }
465    }
466#end[byte]
467
468    private static void fail(String problem,
469                             $Type$Buffer xb, $Type$Buffer yb,
470                             $type$ x, $type$ y) {
471        fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
472    }
473
474    private static void catchNullArgument(Buffer b, Runnable thunk) {
475        tryCatch(b, NullPointerException.class, thunk);
476    }
477
478    private static void catchIllegalArgument(Buffer b, Runnable thunk) {
479        tryCatch(b, IllegalArgumentException.class, thunk);
480    }
481
482    private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) {
483        tryCatch(b, ReadOnlyBufferException.class, thunk);
484    }
485
486    private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) {
487        tryCatch(b, IndexOutOfBoundsException.class, thunk);
488    }
489
490    private static void catchIndexOutOfBounds($type$[] t, Runnable thunk) {
491        tryCatch(t, IndexOutOfBoundsException.class, thunk);
492    }
493
494    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
495        boolean caught = false;
496        try {
497            thunk.run();
498        } catch (Throwable x) {
499            if (ex.isAssignableFrom(x.getClass())) {
500                caught = true;
501            } else {
502                String s = x.getMessage();
503                if (s == null)
504                    s = x.getClass().getName();
505                fail(s + " not expected");
506            }
507        }
508        if (!caught) {
509            fail(ex.getName() + " not thrown", b);
510        }
511    }
512
513    private static void tryCatch($type$[] t, Class<?> ex, Runnable thunk) {
514        tryCatch($Type$Buffer.wrap(t), ex, thunk);
515    }
516
517    public static void test(int level, final $Type$Buffer b, boolean direct) {
518
519        if (direct != b.isDirect())
520            fail("Wrong direction", b);
521
522        // Gets and puts
523
524        relPut(b);
525        relGet(b);
526        absGet(b);
527        bulkGet(b);
528
529        absPut(b);
530        relGet(b);
531        absGet(b);
532        bulkGet(b);
533
534        bulkPutArray(b);
535        relGet(b);
536
537        bulkPutBuffer(b);
538        relGet(b);
539
540#if[char]
541
542        bulkPutString(b);
543        relGet(b);
544        b.position(1);
545        b.limit(7);
546        ck(b, b.toString().equals("bcdefg"));
547
548        // CharSequence ops
549
550        b.position(2);
551        ck(b, b.charAt(1), 'd');
552        CharBuffer c = b.subSequence(1, 4);
553        ck(c, c.capacity(), b.capacity());
554        ck(c, c.position(), b.position()+1);
555        ck(c, c.limit(), b.position()+4);
556        ck(c, b.subSequence(1, 4).toString().equals("def"));
557
558        // 4938424
559        b.position(4);
560        ck(b, b.charAt(1), 'f');
561        ck(b, b.subSequence(1, 3).toString().equals("fg"));
562
563        // String ops
564
565        // 7190219
566        b.clear();
567        int pos = b.position();
568        tryCatch(b, BufferOverflowException.class, () ->
569                b.put(String.valueOf(new char[b.capacity() + 1]), 0, b.capacity() + 1)
570            );
571        ck(b, b.position(), pos);
572        relGet(b);
573
574#end[char]
575
576        // Compact
577
578        relPut(b);
579        b.position(13);
580        b.compact();
581        b.flip();
582        relGet(b, 13);
583
584        // Exceptions
585
586        relPut(b);
587        b.limit(b.capacity() / 2);
588        b.position(b.limit());
589
590        tryCatch(b, BufferUnderflowException.class, () -> b.get());
591        tryCatch(b, BufferOverflowException.class, () -> b.put(($type$)42));
592        // The index must be non-negative and less than the buffer's limit.
593        catchIndexOutOfBounds(b, () -> b.get(b.limit()));
594        catchIndexOutOfBounds(b, () -> b.get(-1));
595        catchIndexOutOfBounds(b, () -> b.put(b.limit(), ($type$)42));
596        $Type$Buffer intermediate = ($Type$Buffer) b.position(0).mark();
597        tryCatch(b, InvalidMarkException.class,
598                () -> intermediate.compact().reset());
599
600        try {
601            b.position(b.limit() + 1);
602            fail("IllegalArgumentException expected for position beyond limit");
603        } catch (IllegalArgumentException e) {
604            if (e.getMessage() == null) {
605                fail("Non-null IllegalArgumentException message expected for"
606                     + " position beyond limit");
607            }
608        }
609
610        try {
611            b.position(-1);
612            fail("IllegalArgumentException expected for negative position");
613        } catch (IllegalArgumentException e) {
614            if (e.getMessage() == null) {
615                fail("Non-null IllegalArgumentException message expected for"
616                     + " negative position");
617            }
618        }
619
620        try {
621            b.limit(b.capacity() + 1);
622            fail("IllegalArgumentException expected for limit beyond capacity");
623        } catch (IllegalArgumentException e) {
624            if (e.getMessage() == null) {
625                fail("Non-null IllegalArgumentException message expected for"
626                     + " limit beyond capacity");
627            }
628        }
629
630        try {
631            b.limit(-1);
632            fail("IllegalArgumentException expected for negative limit");
633        } catch (IllegalArgumentException e) {
634            if (e.getMessage() == null) {
635                fail("Non-null IllegalArgumentException message expected for"
636                     + " negative limit");
637            }
638        }
639
640        // Exceptions in absolute bulk and slice operations
641
642        catchIndexOutOfBounds(b, () -> b.slice(-1, 7));
643        catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7));
644        catchIndexOutOfBounds(b, () -> b.slice(0, -1));
645        catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1));
646
647        // Values
648
649        b.clear();
650        b.put(($type$)0);
651        b.put(($type$)-1);
652        b.put(($type$)1);
653        b.put($Fulltype$.MAX_VALUE);
654        b.put($Fulltype$.MIN_VALUE);
655#if[float]
656        b.put(-Float.MAX_VALUE);
657        b.put(-Float.MIN_VALUE);
658        b.put(Float.NEGATIVE_INFINITY);
659        b.put(Float.POSITIVE_INFINITY);
660        b.put(Float.NaN);
661        b.put(0.91697687f);             // Changes value if incorrectly swapped
662#end[float]
663#if[double]
664        b.put(-Double.MAX_VALUE);
665        b.put(-Double.MIN_VALUE);
666        b.put(Double.NEGATIVE_INFINITY);
667        b.put(Double.POSITIVE_INFINITY);
668        b.put(Double.NaN);
669        b.put(0.5121609353879392);      // Changes value if incorrectly swapped
670#end[double]
671
672        b.flip();
673        ck(b, b.get(), 0);
674        ck(b, b.get(), ($type$)-1);
675        ck(b, b.get(), 1);
676        ck(b, b.get(), $Fulltype$.MAX_VALUE);
677        ck(b, b.get(), $Fulltype$.MIN_VALUE);
678
679#if[float]
680        $type$ v;
681        ck(b, b.get(), -Float.MAX_VALUE);
682        ck(b, b.get(), -Float.MIN_VALUE);
683        ck(b, b.get(), Float.NEGATIVE_INFINITY);
684        ck(b, b.get(), Float.POSITIVE_INFINITY);
685        if (Float.floatToRawIntBits(v = b.get()) !=
686            Float.floatToRawIntBits(Float.NaN)) {
687            fail(b, (long)Float.NaN, (long)v);
688        }
689        ck(b, b.get(), 0.91697687f);
690#end[float]
691#if[double]
692        $type$ v;
693        ck(b, b.get(), -Double.MAX_VALUE);
694        ck(b, b.get(), -Double.MIN_VALUE);
695        ck(b, b.get(), Double.NEGATIVE_INFINITY);
696        ck(b, b.get(), Double.POSITIVE_INFINITY);
697        if (Double.doubleToRawLongBits(v = b.get())
698            != Double.doubleToRawLongBits(Double.NaN)) {
699            fail(b, (long)Double.NaN, (long)v);
700        }
701        ck(b, b.get(), 0.5121609353879392);
702#end[double]
703
704
705        // Comparison
706        b.rewind();
707        $Type$Buffer b2 = $Type$Buffer.allocate(b.capacity());
708        b2.put(b);
709        b2.flip();
710        b.position(2);
711        b2.position(2);
712        if (!b.equals(b2)) {
713            for (int i = 2; i < b.limit(); i++) {
714                $type$ x = b.get(i);
715                $type$ y = b2.get(i);
716                if (x != y
717#if[double]
718                    || Double.compare(x, y) != 0
719#end[double]
720#if[float]
721                    || Float.compare(x, y) != 0
722#end[float]
723                    ) {
724                }
725            }
726            fail("Identical buffers not equal", b, b2);
727        }
728        if (b.compareTo(b2) != 0) {
729            fail("Comparison to identical buffer != 0", b, b2);
730        }
731        b.limit(b.limit() + 1);
732        b.position(b.limit() - 1);
733        b.put(($type$)99);
734        b.rewind();
735        b2.rewind();
736        if (b.equals(b2))
737            fail("Non-identical buffers equal", b, b2);
738        if (b.compareTo(b2) <= 0)
739            fail("Comparison to shorter buffer <= 0", b, b2);
740        b.limit(b.limit() - 1);
741
742        b.put(2, ($type$)42);
743        if (b.equals(b2))
744            fail("Non-identical buffers equal", b, b2);
745        if (b.compareTo(b2) <= 0)
746            fail("Comparison to lesser buffer <= 0", b, b2);
747
748        // Check equals and compareTo with interesting values
749        for ($type$ x : VALUES) {
750            $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x });
751            for ($type$ y : VALUES) {
752                $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y });
753                if (xb.compareTo(yb) != - yb.compareTo(xb)) {
754                    fail("compareTo not anti-symmetric",
755                         xb, yb, x, y);
756                }
757                if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
758                    fail("compareTo inconsistent with equals",
759                         xb, yb, x, y);
760                }
761                if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) {
762#if[float]
763                    if (x == 0.0 && y == 0.0) continue;
764#end[float]
765#if[double]
766                    if (x == 0.0 && y == 0.0) continue;
767#end[double]
768                    fail("Incorrect results for $Type$Buffer.compareTo",
769                         xb, yb, x, y);
770                }
771
772#if[float]
773		// Android-changed: fix issue flagged by error prone (x != x) instead of isNan(x).
774                if (!(Float.isNaN(x) && Float.isNaN(y))) {
775#end[float]
776#if[double]
777		// Android-changed: fix issue flagged by error prone (x != x) instead of isNan(x).
778                if (!(Double.isNaN(x) && Double.isNaN(y))) {
779#end[double]
780                if (xb.equals(yb) != (x == y)) {
781                    fail("Incorrect results for $Type$Buffer.equals",
782                         xb, yb, x, y);
783                }
784
785#if[float]
786                }
787#end[float]
788#if[double]
789                }
790#end[double]
791            }
792        }
793
794        // Sub, dup
795
796        relPut(b);
797        relGet(b.duplicate());
798        b.position(13);
799        relGet(b.duplicate(), 13);
800        relGet(b.duplicate().slice(), 13);
801        relGet(b.slice(), 13);
802        relGet(b.slice().duplicate(), 13);
803
804        // Slice
805
806        b.position(5);
807        $Type$Buffer sb = b.slice();
808        checkSlice(b, sb);
809        b.position(0);
810        $Type$Buffer sb2 = sb.slice();
811        checkSlice(sb, sb2);
812
813        if (!sb.equals(sb2))
814            fail("Sliced slices do not match", sb, sb2);
815        if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) {
816            fail("Array offsets do not match: "
817                 + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2);
818        }
819
820        int bPos = b.position();
821        int bLim = b.limit();
822
823        b.position(7);
824        b.limit(42);
825        $Type$Buffer rsb = b.slice();
826        b.position(0);
827        b.limit(b.capacity());
828        $Type$Buffer asb = b.slice(7, 35);
829        checkSlice(rsb, asb);
830
831        b.position(bPos);
832        b.limit(bLim);
833
834#if[byte]
835
836
837
838        // Heterogeneous accessors
839
840        b.order(ByteOrder.BIG_ENDIAN);
841        for (int i = 0; i <= 9; i++) {
842            b.position(i);
843            testHet(level + 1, b);
844        }
845        b.order(ByteOrder.LITTLE_ENDIAN);
846        b.position(3);
847        testHet(level + 1, b);
848
849        // Test alignment
850
851        testAlign(b, direct);
852#end[byte]
853    }
854
855#if[char]
856
857    private static void testStr() {
858        final String s = "abcdefghijklm";
859        int start = 3;
860        int end = 9;
861        final CharBuffer b = CharBuffer.wrap(s, start, end);
862        ck(b, b.toString().equals(s.substring(start, end)));
863        ck(b, b.toString().equals("defghi"));
864        ck(b, b.isReadOnly());
865        catchReadOnlyBuffer(b, () -> b.put('x'));
866        ck(b, start, b.position());
867        ck(b, end, b.limit());
868        ck(b, s.length(), b.capacity());
869        b.position(6);
870        ck(b, b.subSequence(0,3).toString().equals("ghi"));
871
872        // The index, relative to the position, must be non-negative and
873        // smaller than remaining().
874        catchIndexOutOfBounds(b, () -> b.charAt(-1));
875        catchIndexOutOfBounds(b, () -> b.charAt(b.remaining()));
876        // The index must be non-negative and less than the buffer's limit.
877        catchIndexOutOfBounds(b, () -> b.get(b.limit()));
878        catchIndexOutOfBounds(b, () -> b.get(-1));
879        // The start must be non-negative and no larger than remaining().
880        catchIndexOutOfBounds(b, () -> b.subSequence(-1, b.remaining()));
881        catchIndexOutOfBounds(b, () -> b.subSequence(b.remaining() + 1, b.remaining()));
882
883        // The end must be no smaller than start and no larger than
884        // remaining().
885        catchIndexOutOfBounds(b, () -> b.subSequence(2, 1));
886        catchIndexOutOfBounds(b, () -> b.subSequence(0, b.remaining() + 1));
887
888        // The offset must be non-negative and no larger than <array.length>.
889        catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, -1, s.length()));
890        catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, s.length() + 1, s.length()));
891        catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 1, 0));
892        catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 0, s.length() + 1));
893    }
894
895#end[char]
896
897    public static void test(final $type$ [] ba) {
898        int offset = 47;
899        int length = 900;
900        final $Type$Buffer b = $Type$Buffer.wrap(ba, offset, length);
901        ck(b, b.capacity(), ba.length);
902        ck(b, b.position(), offset);
903        ck(b, b.limit(), offset + length);
904
905        // The offset must be non-negative and no larger than <array.length>.
906        catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, -1, ba.length));
907        catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, ba.length + 1, ba.length));
908        catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, -1));
909        catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, ba.length + 1));
910
911        // A NullPointerException will be thrown if the array is null.
912        tryCatch(ba, NullPointerException.class,
913                () -> $Type$Buffer.wrap(($type$ []) null, 0, 5));
914        tryCatch(ba, NullPointerException.class,
915                () -> $Type$Buffer.wrap(($type$ []) null));
916    }
917
918    private static void testAllocate() {
919        // An IllegalArgumentException will be thrown for negative capacities.
920        catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocate(-1));
921        try {
922            $Type$Buffer.allocate(-1);
923        } catch (IllegalArgumentException e) {
924            if (e.getMessage() == null) {
925                fail("Non-null IllegalArgumentException message expected for"
926                     + " attempt to allocate negative capacity buffer");
927            }
928        }
929#if[byte]
930        catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocateDirect(-1));
931        try {
932            $Type$Buffer.allocateDirect(-1);
933        } catch (IllegalArgumentException e) {
934            if (e.getMessage() == null) {
935                fail("Non-null IllegalArgumentException message expected for"
936                     + " attempt to allocate negative capacity direct buffer");
937            }
938        }
939#end[byte]
940    }
941
942    public static void test() {
943        testAllocate();
944        test(0, $Type$Buffer.allocate(7 * 1024), false);
945        test(0, $Type$Buffer.wrap(new $type$[7 * 1024], 0, 7 * 1024), false);
946        test(new $type$[1024]);
947#if[byte]
948        $Type$Buffer b = $Type$Buffer.allocateDirect(7 * 1024);
949        for (b.position(0); b.position() < b.limit(); )
950            ck(b, b.get(), 0);
951        test(0, b, true);
952#end[byte]
953#if[char]
954        testStr();
955#end[char]
956
957        callReset($Type$Buffer.allocate(10));
958
959#if[byte]
960#else[byte]
961        putBuffer();
962#end[byte]
963    }
964
965}
966