1 /*
   2  * Copyright (c) 2000, 2019, 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  */
  30 
  31 #warn This file is preprocessed before being compiled
  32 
  33 import java.nio.*;
  34 
  35 
  36 public class Basic$Type$
  37     extends Basic
  38 {
  39 
  40     private static final $type$[] VALUES = {
  41         $Fulltype$.MIN_VALUE,
  42         ($type$) -1,
  43         ($type$) 0,
  44         ($type$) 1,
  45         $Fulltype$.MAX_VALUE,
  46 #if[float]
  47         $Fulltype$.NEGATIVE_INFINITY,
  48         $Fulltype$.POSITIVE_INFINITY,
  49         $Fulltype$.NaN,
  50         ($type$) -0.0,
  51 #end[float]
  52 #if[double]
  53         $Fulltype$.NEGATIVE_INFINITY,
  54         $Fulltype$.POSITIVE_INFINITY,
  55         $Fulltype$.NaN,
  56         ($type$) -0.0,
  57 #end[double]
  58     };
  59 
  60     private static void relGet($Type$Buffer b) {
  61         int n = b.capacity();
  62         for (int i = 0; i < n; i++)
  63             ck(b, (long)b.get(), (long)(($type$)ic(i)));
  64         b.rewind();
  65     }
  66 
  67     private static void relGet($Type$Buffer b, int start) {
  68         int n = b.remaining();
  69         for (int i = start; i < n; i++)
  70             ck(b, (long)b.get(), (long)(($type$)ic(i)));
  71         b.rewind();
  72     }
  73 
  74     private static void absGet($Type$Buffer b) {
  75         int n = b.capacity();
  76         for (int i = 0; i < n; i++)
  77             ck(b, (long)b.get(), (long)(($type$)ic(i)));
  78         b.rewind();
  79     }
  80 
  81     private static void bulkGet($Type$Buffer b) {
  82         int n = b.capacity();
  83         $type$[] a = new $type$[n + 7];
  84         b.get(a, 7, n);
  85         for (int i = 0; i < n; i++) {
  86             ck(b, (long)a[i + 7], (long)(($type$)ic(i)));
  87         }
  88     }
  89 
  90     private static void absBulkGet($Type$Buffer b) {
  91         int n = b.capacity();
  92         int len = n - 7*2;
  93         $type$[] a = new $type$[n + 7];
  94         b.position(42);
  95         b.get(7, a, 7, len);
  96         ck(b, b.position() == 42);
  97         for (int i = 0; i < len; i++) {
  98             ck(b, (long)a[i + 7], (long)(($type$)ic(i)));
  99         }
 100     }
 101 
 102     private static void relPut($Type$Buffer b) {
 103         int n = b.capacity();
 104         b.clear();
 105         for (int i = 0; i < n; i++)
 106             b.put(($type$)ic(i));
 107         b.flip();
 108     }
 109 
 110     private static void absPut($Type$Buffer b) {
 111         int n = b.capacity();
 112         b.clear();
 113         for (int i = 0; i < n; i++)
 114             b.put(i, ($type$)ic(i));
 115         b.limit(n);
 116         b.position(0);
 117     }
 118 
 119     private static void bulkPutArray($Type$Buffer b) {
 120         int n = b.capacity();
 121         b.clear();
 122         $type$[] a = new $type$[n + 7];
 123         for (int i = 0; i < n; i++)
 124             a[i + 7] = ($type$)ic(i);
 125         b.put(a, 7, n);
 126         b.flip();
 127     }
 128 
 129     private static void bulkPutBuffer($Type$Buffer b) {
 130         int n = b.capacity();
 131         b.clear();
 132         $Type$Buffer c = $Type$Buffer.allocate(n + 7);
 133         c.position(7);
 134         for (int i = 0; i < n; i++)
 135             c.put(($type$)ic(i));
 136         c.flip();
 137         c.position(7);
 138         b.put(c);
 139         b.flip();
 140         try {
 141             b.put(b);
 142             fail("IllegalArgumentException expected for put into same buffer");
 143         } catch (IllegalArgumentException e) {
 144             if (e.getMessage() == null) {
 145                 fail("Non-null IllegalArgumentException message expected from"
 146                      + " put into same buffer");
 147             }
 148         }
 149     }
 150 
 151     private static void absBulkPutArray($Type$Buffer b) {
 152         int n = b.capacity();
 153         b.clear();
 154         int lim = n - 7;
 155         int len = lim - 7;
 156         b.limit(lim);
 157         $type$[] a = new $type$[len + 7];
 158         for (int i = 0; i < len; i++)
 159             a[i + 7] = ($type$)ic(i);
 160         b.position(42);
 161         b.put(7, a, 7, len);
 162         ck(b, b.position() == 42);
 163     }
 164 
 165     //6231529
 166     private static void callReset($Type$Buffer b) {
 167         b.position(0);
 168         b.mark();
 169 
 170         b.duplicate().reset();
 171         b.asReadOnlyBuffer().reset();
 172     }
 173 
 174 #if[byte]
 175 #else[byte]
 176     // 6221101-6234263
 177 
 178     private static void putBuffer() {
 179         final int cap = 10;
 180 
 181         $Type$Buffer direct1 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
 182         $Type$Buffer nondirect1 = ByteBuffer.allocate(cap).as$Type$Buffer();
 183         direct1.put(nondirect1);
 184 
 185         $Type$Buffer direct2 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
 186         $Type$Buffer nondirect2 = ByteBuffer.allocate(cap).as$Type$Buffer();
 187         nondirect2.put(direct2);
 188 
 189         $Type$Buffer direct3 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
 190         $Type$Buffer direct4 = ByteBuffer.allocateDirect(cap).as$Type$Buffer();
 191         direct3.put(direct4);
 192 
 193         $Type$Buffer nondirect3 = ByteBuffer.allocate(cap).as$Type$Buffer();
 194         $Type$Buffer nondirect4 = ByteBuffer.allocate(cap).as$Type$Buffer();
 195         nondirect3.put(nondirect4);
 196     }
 197 #end[byte]
 198 
 199 #if[char]
 200 
 201     private static void bulkPutString($Type$Buffer b) {
 202         int n = b.capacity();
 203         b.clear();
 204         StringBuilder sb = new StringBuilder(n + 7);
 205         sb.append("1234567");
 206         for (int i = 0; i < n; i++)
 207             sb.append((char)ic(i));
 208         b.put(sb.toString(), 7, 7 + n);
 209         b.flip();
 210     }
 211 
 212 #end[char]
 213 
 214     private static void checkSlice($Type$Buffer b, $Type$Buffer slice) {
 215         ck(slice, 0, slice.position());
 216         ck(slice, b.remaining(), slice.limit());
 217         ck(slice, b.remaining(), slice.capacity());
 218         if (b.isDirect() != slice.isDirect())
 219             fail("Lost direction", slice);
 220         if (b.isReadOnly() != slice.isReadOnly())
 221             fail("Lost read-only", slice);
 222     }
 223 
 224 #if[byte]
 225 
 226     private static void checkBytes(ByteBuffer b, byte[] bs) {
 227         int n = bs.length;
 228         int p = b.position();
 229         if (b.order() == ByteOrder.BIG_ENDIAN) {
 230             for (int i = 0; i < n; i++) {
 231                 ck(b, b.get(), bs[i]);
 232             }
 233         } else {
 234             for (int i = n - 1; i >= 0; i--) {
 235                 ck(b, b.get(), bs[i]);
 236             }
 237         }
 238         b.position(p);
 239     }
 240 
 241     private static void compact(Buffer b) {
 242         try {
 243             Class<?> cl = b.getClass();
 244             java.lang.reflect.Method m = cl.getDeclaredMethod("compact");
 245             m.setAccessible(true);
 246             m.invoke(b);
 247         } catch (Exception e) {
 248             fail(e.getMessage(), b);
 249         }
 250     }
 251 
 252     private static void checkInvalidMarkException(final Buffer b) {
 253         tryCatch(b, InvalidMarkException.class, () -> {
 254                 b.mark();
 255                 compact(b);
 256                 b.reset();
 257             });
 258     }
 259 
 260     private static void testViews(int level, ByteBuffer b, boolean direct) {
 261 
 262         ShortBuffer sb = b.asShortBuffer();
 263         BasicShort.test(level, sb, direct);
 264         checkBytes(b, new byte[] { 0, (byte)ic(0) });
 265         checkInvalidMarkException(sb);
 266 
 267         CharBuffer cb = b.asCharBuffer();
 268         BasicChar.test(level, cb, direct);
 269         checkBytes(b, new byte[] { 0, (byte)ic(0) });
 270         checkInvalidMarkException(cb);
 271 
 272         IntBuffer ib = b.asIntBuffer();
 273         BasicInt.test(level, ib, direct);
 274         checkBytes(b, new byte[] { 0, 0, 0, (byte)ic(0) });
 275         checkInvalidMarkException(ib);
 276 
 277         LongBuffer lb = b.asLongBuffer();
 278         BasicLong.test(level, lb, direct);
 279         checkBytes(b, new byte[] { 0, 0, 0, 0, 0, 0, 0, (byte)ic(0) });
 280         checkInvalidMarkException(lb);
 281 
 282         FloatBuffer fb = b.asFloatBuffer();
 283         BasicFloat.test(level, fb, direct);
 284         checkBytes(b, new byte[] { 0x42, (byte)0xc2, 0, 0 });
 285         checkInvalidMarkException(fb);
 286 
 287         DoubleBuffer db = b.asDoubleBuffer();
 288         BasicDouble.test(level, db, direct);
 289         checkBytes(b, new byte[] { 0x40, 0x58, 0x40, 0, 0, 0, 0, 0 });
 290         checkInvalidMarkException(db);
 291     }
 292 
 293     private static void testHet(int level, ByteBuffer b) {
 294 
 295         int p = b.position();
 296         b.limit(b.capacity());
 297         show(level, b);
 298         out.print("    put:");
 299 
 300         b.putChar((char)1);
 301         b.putChar((char)Character.MAX_VALUE);
 302         out.print(" char");
 303 
 304         b.putShort((short)1);
 305         b.putShort((short)Short.MAX_VALUE);
 306         out.print(" short");
 307 
 308         b.putInt(1);
 309         b.putInt(Integer.MAX_VALUE);
 310         out.print(" int");
 311 
 312         b.putLong((long)1);
 313         b.putLong((long)Long.MAX_VALUE);
 314         out.print(" long");
 315 
 316         b.putFloat((float)1);
 317         b.putFloat((float)Float.MIN_VALUE);
 318         b.putFloat((float)Float.MAX_VALUE);
 319         out.print(" float");
 320 
 321         b.putDouble((double)1);
 322         b.putDouble((double)Double.MIN_VALUE);
 323         b.putDouble((double)Double.MAX_VALUE);
 324         out.print(" double");
 325 
 326         out.println();
 327         b.limit(b.position());
 328         b.position(p);
 329         show(level, b);
 330         out.print("    get:");
 331 
 332         ck(b, b.getChar(), 1);
 333         ck(b, b.getChar(), Character.MAX_VALUE);
 334         out.print(" char");
 335 
 336         ck(b, b.getShort(), 1);
 337         ck(b, b.getShort(), Short.MAX_VALUE);
 338         out.print(" short");
 339 
 340         ck(b, b.getInt(), 1);
 341         ck(b, b.getInt(), Integer.MAX_VALUE);
 342         out.print(" int");
 343 
 344         ck(b, b.getLong(), 1);
 345         ck(b, b.getLong(), Long.MAX_VALUE);
 346         out.print(" long");
 347 
 348         ck(b, (long)b.getFloat(), 1);
 349         ck(b, (long)b.getFloat(), (long)Float.MIN_VALUE);
 350         ck(b, (long)b.getFloat(), (long)Float.MAX_VALUE);
 351         out.print(" float");
 352 
 353         ck(b, (long)b.getDouble(), 1);
 354         ck(b, (long)b.getDouble(), (long)Double.MIN_VALUE);
 355         ck(b, (long)b.getDouble(), (long)Double.MAX_VALUE);
 356         out.print(" double");
 357 
 358         out.println();
 359 
 360     }
 361 
 362     private static void testAlign(final ByteBuffer b, boolean direct) {
 363         // index out-of bounds
 364         catchIllegalArgument(b, () -> b.alignmentOffset(-1, (short) 1));
 365 
 366         // unit size values
 367         catchIllegalArgument(b, () -> b.alignmentOffset(0, (short) 0));
 368         for (int us = 1; us < 65; us++) {
 369             int _us = us;
 370             if ((us & (us - 1)) != 0) {
 371                 // unit size not a power of two
 372                 catchIllegalArgument(b, () -> b.alignmentOffset(0, _us));
 373             } else {
 374                 if (direct || us <= 8) {
 375                     b.alignmentOffset(0, us);
 376                 } else {
 377                     // unit size > 8 with non-direct buffer
 378                     tryCatch(b, UnsupportedOperationException.class,
 379                             () -> b.alignmentOffset(0, _us));
 380                 }
 381             }
 382         }
 383 
 384         // Probe for long misalignment at index zero for a newly created buffer
 385         ByteBuffer empty =
 386                 direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
 387         int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
 388 
 389         if (direct) {
 390             // Freshly created direct byte buffers should be aligned at index 0
 391             // for ref and primitive values (see Unsafe.allocateMemory)
 392             if (longMisalignmentAtZero != 0) {
 393                 fail("Direct byte buffer misaligned at index 0"
 394                         + " for ref and primitive values "
 395                         + longMisalignmentAtZero);
 396             }
 397         } else {
 398             // For heap byte buffers misalignment may occur on 32-bit systems
 399             // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
 400             // Note the GC will preserve alignment of the base address of the
 401             // array
 402             if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8
 403                     != longMisalignmentAtZero) {
 404                 fail("Heap byte buffer misaligned at index 0"
 405                         + " for ref and primitive values "
 406                         + longMisalignmentAtZero);
 407             }
 408         }
 409 
 410         // Ensure test buffer is correctly aligned at index 0
 411         if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
 412             fail("Test input buffer not correctly aligned at index 0", b);
 413 
 414         // Test misalignment values
 415         for (int us : new int[]{1, 2, 4, 8}) {
 416             for (int i = 0; i < us * 2; i++) {
 417                 int am = b.alignmentOffset(i, us);
 418                 int expectedAm = (longMisalignmentAtZero + i) % us;
 419 
 420                 if (am != expectedAm) {
 421                     String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d";
 422                     fail(String.format(f, i, us, am, expectedAm));
 423                 }
 424             }
 425         }
 426 
 427         // Created aligned slice to test against
 428         int ap = 8 - longMisalignmentAtZero;
 429         int al = b.limit() - b.alignmentOffset(b.limit(), 8);
 430         ByteBuffer ab = b.position(ap).limit(al).
 431                 slice();
 432         if (ab.limit() == 0) {
 433             fail("Test input buffer not sufficiently sized to cover" +
 434                     " an aligned region for all values", b);
 435         }
 436         if (ab.alignmentOffset(0, 8) != 0)
 437             fail("Aligned test input buffer not correctly aligned at index 0", ab);
 438 
 439         for (int us : new int[]{1, 2, 4, 8}) {
 440             for (int p = 1; p < 16; p++) {
 441                 int l = ab.limit() - p;
 442 
 443                 ByteBuffer as = ab.slice().position(p).limit(l).
 444                         alignedSlice(us);
 445 
 446                 ck(as, 0, as.position());
 447                 ck(as, as.capacity(), as.limit());
 448                 if (b.isDirect() != as.isDirect())
 449                     fail("Lost direction", as);
 450                 if (b.isReadOnly() != as.isReadOnly())
 451                     fail("Lost read-only", as);
 452 
 453                 if (as.alignmentOffset(0, us) != 0)
 454                     fail("Buffer not correctly aligned at index 0", as);
 455 
 456                 if (as.alignmentOffset(as.limit(), us) != 0)
 457                     fail("Buffer not correctly aligned at limit", as);
 458 
 459                 int p_mod = ab.alignmentOffset(p, us);
 460                 int l_mod = ab.alignmentOffset(l, us);
 461                 // Round up position
 462                 p = (p_mod > 0) ? p + (us - p_mod) : p;
 463                 // Round down limit
 464                 l = l - l_mod;
 465 
 466                 int ec = l - p;
 467                 if (as.limit() != ec) {
 468                     fail("Buffer capacity incorrect, expected: " + ec, as);
 469                 }
 470             }
 471         }
 472     }
 473 #end[byte]
 474 
 475     private static void fail(String problem,
 476                              $Type$Buffer xb, $Type$Buffer yb,
 477                              $type$ x, $type$ y) {
 478         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
 479     }
 480 
 481     private static void catchNullArgument(Buffer b, Runnable thunk) {
 482         tryCatch(b, NullPointerException.class, thunk);
 483     }
 484 
 485     private static void catchIllegalArgument(Buffer b, Runnable thunk) {
 486         tryCatch(b, IllegalArgumentException.class, thunk);
 487     }
 488 
 489     private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) {
 490         tryCatch(b, ReadOnlyBufferException.class, thunk);
 491     }
 492 
 493     private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) {
 494         tryCatch(b, IndexOutOfBoundsException.class, thunk);
 495     }
 496 
 497     private static void catchIndexOutOfBounds($type$[] t, Runnable thunk) {
 498         tryCatch(t, IndexOutOfBoundsException.class, thunk);
 499     }
 500 
 501     private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
 502         boolean caught = false;
 503         try {
 504             thunk.run();
 505         } catch (Throwable x) {
 506             if (ex.isAssignableFrom(x.getClass())) {
 507                 caught = true;
 508             } else {
 509                 String s = x.getMessage();
 510                 if (s == null)
 511                     s = x.getClass().getName();
 512                 fail(s + " not expected");
 513             }
 514         }
 515         if (!caught) {
 516             fail(ex.getName() + " not thrown", b);
 517         }
 518     }
 519 
 520     private static void tryCatch($type$[] t, Class<?> ex, Runnable thunk) {
 521         tryCatch($Type$Buffer.wrap(t), ex, thunk);
 522     }
 523 
 524     public static void test(int level, final $Type$Buffer b, boolean direct) {
 525 
 526         show(level, b);
 527 
 528         if (direct != b.isDirect())
 529             fail("Wrong direction", b);
 530 
 531         // Gets and puts
 532 
 533         relPut(b);
 534         relGet(b);
 535         absGet(b);
 536         bulkGet(b);
 537 
 538         absPut(b);
 539         relGet(b);
 540         absGet(b);
 541         bulkGet(b);
 542 
 543         bulkPutArray(b);
 544         relGet(b);
 545 
 546         bulkPutBuffer(b);
 547         relGet(b);
 548 
 549         absBulkPutArray(b);
 550         absBulkGet(b);
 551 
 552 #if[char]
 553 
 554         bulkPutString(b);
 555         relGet(b);
 556         b.position(1);
 557         b.limit(7);
 558         ck(b, b.toString().equals("bcdefg"));
 559 
 560         // CharSequence ops
 561 
 562         b.position(2);
 563         ck(b, b.charAt(1), 'd');
 564         CharBuffer c = b.subSequence(1, 4);
 565         ck(c, c.capacity(), b.capacity());
 566         ck(c, c.position(), b.position()+1);
 567         ck(c, c.limit(), b.position()+4);
 568         ck(c, b.subSequence(1, 4).toString().equals("def"));
 569 
 570         // 4938424
 571         b.position(4);
 572         ck(b, b.charAt(1), 'f');
 573         ck(b, b.subSequence(1, 3).toString().equals("fg"));
 574 
 575         // String ops
 576 
 577         // 7190219
 578         b.clear();
 579         int pos = b.position();
 580         tryCatch(b, BufferOverflowException.class, () ->
 581                 b.put(String.valueOf(new char[b.capacity() + 1]), 0, b.capacity() + 1)
 582             );
 583         ck(b, b.position(), pos);
 584         relGet(b);
 585 
 586 #end[char]
 587 
 588         // Compact
 589 
 590         relPut(b);
 591         b.position(13);
 592         b.compact();
 593         b.flip();
 594         relGet(b, 13);
 595 
 596         // Exceptions
 597 
 598         relPut(b);
 599         b.limit(b.capacity() / 2);
 600         b.position(b.limit());
 601 
 602         tryCatch(b, BufferUnderflowException.class, () -> b.get());
 603         tryCatch(b, BufferOverflowException.class, () -> b.put(($type$)42));
 604         // The index must be non-negative and less than the buffer's limit.
 605         catchIndexOutOfBounds(b, () -> b.get(b.limit()));
 606         catchIndexOutOfBounds(b, () -> b.get(-1));
 607         catchIndexOutOfBounds(b, () -> b.put(b.limit(), ($type$)42));
 608         tryCatch(b, InvalidMarkException.class,
 609                 () -> b.position(0).mark().compact().reset());
 610 
 611         try {
 612             b.position(b.limit() + 1);
 613             fail("IllegalArgumentException expected for position beyond limit");
 614         } catch (IllegalArgumentException e) {
 615             if (e.getMessage() == null) {
 616                 fail("Non-null IllegalArgumentException message expected for"
 617                      + " position beyond limit");
 618             }
 619         }
 620 
 621         try {
 622             b.position(-1);
 623             fail("IllegalArgumentException expected for negative position");
 624         } catch (IllegalArgumentException e) {
 625             if (e.getMessage() == null) {
 626                 fail("Non-null IllegalArgumentException message expected for"
 627                      + " negative position");
 628             }
 629         }
 630 
 631         try {
 632             b.limit(b.capacity() + 1);
 633             fail("IllegalArgumentException expected for limit beyond capacity");
 634         } catch (IllegalArgumentException e) {
 635             if (e.getMessage() == null) {
 636                 fail("Non-null IllegalArgumentException message expected for"
 637                      + " limit beyond capacity");
 638             }
 639         }
 640 
 641         try {
 642             b.limit(-1);
 643             fail("IllegalArgumentException expected for negative limit");
 644         } catch (IllegalArgumentException e) {
 645             if (e.getMessage() == null) {
 646                 fail("Non-null IllegalArgumentException message expected for"
 647                      + " negative limit");
 648             }
 649         }
 650 
 651         // Exceptions in absolute bulk and slice operations
 652 
 653         catchNullArgument(b, () -> b.get(7, null, 0, 42));
 654         catchNullArgument(b, () -> b.put(7, ($type$[])null, 0, 42));
 655 
 656         $type$[] tmpa = new $type$[42];
 657         catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42));
 658         catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1));
 659         catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1));
 660         catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1));
 661         catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1));
 662         catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42));
 663 
 664         catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42));
 665         catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1));
 666         catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1));
 667         catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1));
 668         catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1));
 669         catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42));
 670 
 671         catchIndexOutOfBounds(b, () -> b.slice(-1, 7));
 672         catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7));
 673         catchIndexOutOfBounds(b, () -> b.slice(0, -1));
 674         catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1));
 675 
 676         // Values
 677 
 678         b.clear();
 679         b.put(($type$)0);
 680         b.put(($type$)-1);
 681         b.put(($type$)1);
 682         b.put($Fulltype$.MAX_VALUE);
 683         b.put($Fulltype$.MIN_VALUE);
 684 #if[float]
 685         b.put(-Float.MAX_VALUE);
 686         b.put(-Float.MIN_VALUE);
 687         b.put(Float.NEGATIVE_INFINITY);
 688         b.put(Float.POSITIVE_INFINITY);
 689         b.put(Float.NaN);
 690         b.put(0.91697687f);             // Changes value if incorrectly swapped
 691 #end[float]
 692 #if[double]
 693         b.put(-Double.MAX_VALUE);
 694         b.put(-Double.MIN_VALUE);
 695         b.put(Double.NEGATIVE_INFINITY);
 696         b.put(Double.POSITIVE_INFINITY);
 697         b.put(Double.NaN);
 698         b.put(0.5121609353879392);      // Changes value if incorrectly swapped
 699 #end[double]
 700 
 701         b.flip();
 702         ck(b, b.get(), 0);
 703         ck(b, b.get(), ($type$)-1);
 704         ck(b, b.get(), 1);
 705         ck(b, b.get(), $Fulltype$.MAX_VALUE);
 706         ck(b, b.get(), $Fulltype$.MIN_VALUE);
 707 
 708 #if[float]
 709         $type$ v;
 710         ck(b, b.get(), -Float.MAX_VALUE);
 711         ck(b, b.get(), -Float.MIN_VALUE);
 712         ck(b, b.get(), Float.NEGATIVE_INFINITY);
 713         ck(b, b.get(), Float.POSITIVE_INFINITY);
 714         if (Float.floatToRawIntBits(v = b.get()) !=
 715             Float.floatToRawIntBits(Float.NaN)) {
 716             fail(b, (long)Float.NaN, (long)v);
 717         }
 718         ck(b, b.get(), 0.91697687f);
 719 #end[float]
 720 #if[double]
 721         $type$ v;
 722         ck(b, b.get(), -Double.MAX_VALUE);
 723         ck(b, b.get(), -Double.MIN_VALUE);
 724         ck(b, b.get(), Double.NEGATIVE_INFINITY);
 725         ck(b, b.get(), Double.POSITIVE_INFINITY);
 726         if (Double.doubleToRawLongBits(v = b.get())
 727             != Double.doubleToRawLongBits(Double.NaN)) {
 728             fail(b, (long)Double.NaN, (long)v);
 729         }
 730         ck(b, b.get(), 0.5121609353879392);
 731 #end[double]
 732 
 733 
 734         // Comparison
 735         b.rewind();
 736         $Type$Buffer b2 = $Type$Buffer.allocate(b.capacity());
 737         b2.put(b);
 738         b2.flip();
 739         b.position(2);
 740         b2.position(2);
 741         if (!b.equals(b2)) {
 742             for (int i = 2; i < b.limit(); i++) {
 743                 $type$ x = b.get(i);
 744                 $type$ y = b2.get(i);
 745                 if (x != y
 746 #if[double]
 747                     || Double.compare(x, y) != 0
 748 #end[double]
 749 #if[float]
 750                     || Float.compare(x, y) != 0
 751 #end[float]
 752                     ) {
 753                     out.println("[" + i + "] " + x + " != " + y);
 754                 }
 755             }
 756             fail("Identical buffers not equal", b, b2);
 757         }
 758         if (b.compareTo(b2) != 0) {
 759             fail("Comparison to identical buffer != 0", b, b2);
 760         }
 761         b.limit(b.limit() + 1);
 762         b.position(b.limit() - 1);
 763         b.put(($type$)99);
 764         b.rewind();
 765         b2.rewind();
 766         if (b.equals(b2))
 767             fail("Non-identical buffers equal", b, b2);
 768         if (b.compareTo(b2) <= 0)
 769             fail("Comparison to shorter buffer <= 0", b, b2);
 770         b.limit(b.limit() - 1);
 771 
 772         b.put(2, ($type$)42);
 773         if (b.equals(b2))
 774             fail("Non-identical buffers equal", b, b2);
 775         if (b.compareTo(b2) <= 0)
 776             fail("Comparison to lesser buffer <= 0", b, b2);
 777 
 778         // Check equals and compareTo with interesting values
 779         for ($type$ x : VALUES) {
 780             $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x });
 781             if (xb.compareTo(xb) != 0) {
 782                 fail("compareTo not reflexive", xb, xb, x, x);
 783             }
 784             if (!xb.equals(xb)) {
 785                 fail("equals not reflexive", xb, xb, x, x);
 786             }
 787             for ($type$ y : VALUES) {
 788                 $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y });
 789                 if (xb.compareTo(yb) != - yb.compareTo(xb)) {
 790                     fail("compareTo not anti-symmetric",
 791                          xb, yb, x, y);
 792                 }
 793                 if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
 794                     fail("compareTo inconsistent with equals",
 795                          xb, yb, x, y);
 796                 }
 797                 if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) {
 798 #if[float]
 799                     if (x == 0.0 && y == 0.0) continue;
 800 #end[float]
 801 #if[double]
 802                     if (x == 0.0 && y == 0.0) continue;
 803 #end[double]
 804                     fail("Incorrect results for $Type$Buffer.compareTo",
 805                          xb, yb, x, y);
 806                 }
 807                 if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
 808                     fail("Incorrect results for $Type$Buffer.equals",
 809                          xb, yb, x, y);
 810                 }
 811             }
 812         }
 813 
 814         // Sub, dup
 815 
 816         relPut(b);
 817         relGet(b.duplicate());
 818         b.position(13);
 819         relGet(b.duplicate(), 13);
 820         relGet(b.duplicate().slice(), 13);
 821         relGet(b.slice(), 13);
 822         relGet(b.slice().duplicate(), 13);
 823 
 824         // Slice
 825 
 826         b.position(5);
 827         $Type$Buffer sb = b.slice();
 828         checkSlice(b, sb);
 829         b.position(0);
 830         $Type$Buffer sb2 = sb.slice();
 831         checkSlice(sb, sb2);
 832 
 833         if (!sb.equals(sb2))
 834             fail("Sliced slices do not match", sb, sb2);
 835         if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) {
 836             fail("Array offsets do not match: "
 837                  + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2);
 838         }
 839 
 840         int bPos = b.position();
 841         int bLim = b.limit();
 842 
 843         b.position(7);
 844         b.limit(42);
 845         $Type$Buffer rsb = b.slice();
 846         b.position(0);
 847         b.limit(b.capacity());
 848         $Type$Buffer asb = b.slice(7, 35);
 849         checkSlice(rsb, asb);
 850 
 851         b.position(bPos);
 852         b.limit(bLim);
 853 
 854 #if[byte]
 855 
 856         // Views
 857 
 858         b.clear();
 859         b.order(ByteOrder.BIG_ENDIAN);
 860         testViews(level + 1, b, direct);
 861 
 862         for (int i = 1; i <= 9; i++) {
 863             b.position(i);
 864             show(level + 1, b);
 865             testViews(level + 2, b, direct);
 866         }
 867 
 868         b.position(0);
 869         b.order(ByteOrder.LITTLE_ENDIAN);
 870         testViews(level + 1, b, direct);
 871 
 872         // Heterogeneous accessors
 873 
 874         b.order(ByteOrder.BIG_ENDIAN);
 875         for (int i = 0; i <= 9; i++) {
 876             b.position(i);
 877             testHet(level + 1, b);
 878         }
 879         b.order(ByteOrder.LITTLE_ENDIAN);
 880         b.position(3);
 881         testHet(level + 1, b);
 882 
 883 #end[byte]
 884 
 885         // Read-only views
 886 
 887         b.rewind();
 888         final $Type$Buffer rb = b.asReadOnlyBuffer();
 889         if (!b.equals(rb))
 890             fail("Buffer not equal to read-only view", b, rb);
 891         show(level + 1, rb);
 892 
 893         catchReadOnlyBuffer(b, () -> relPut(rb));
 894         catchReadOnlyBuffer(b, () -> absPut(rb));
 895         catchReadOnlyBuffer(b, () -> bulkPutArray(rb));
 896         catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb));
 897         catchReadOnlyBuffer(b, () -> absBulkPutArray(rb));
 898 
 899         // put($Type$Buffer) should not change source position
 900         final $Type$Buffer src = $Type$Buffer.allocate(1);
 901         catchReadOnlyBuffer(b, () -> rb.put(src));
 902         ck(src, src.position(), 0);
 903 
 904         catchReadOnlyBuffer(b, () -> rb.compact());
 905 
 906 #if[byte]
 907 
 908         catchReadOnlyBuffer(b, () -> rb.putChar((char)1));
 909         catchReadOnlyBuffer(b, () -> rb.putChar(0, (char)1));
 910         catchReadOnlyBuffer(b, () -> rb.putShort((short)1));
 911         catchReadOnlyBuffer(b, () -> rb.putShort(0, (short)1));
 912         catchReadOnlyBuffer(b, () -> rb.putInt(1));
 913         catchReadOnlyBuffer(b, () -> rb.putInt(0, 1));
 914         catchReadOnlyBuffer(b, () -> rb.putLong((long)1));
 915         catchReadOnlyBuffer(b, () -> rb.putLong(0, (long)1));
 916         catchReadOnlyBuffer(b, () -> rb.putFloat((float)1));
 917         catchReadOnlyBuffer(b, () -> rb.putFloat(0, (float)1));
 918         catchReadOnlyBuffer(b, () -> rb.putDouble((double)1));
 919         catchReadOnlyBuffer(b, () -> rb.putDouble(0, (double)1));
 920 
 921 #end[byte]
 922 
 923 #if[char]
 924 
 925         // 7199551
 926         catchReadOnlyBuffer(b, () -> rb.put(new String(new char[rb.remaining() + 1])));
 927         catchReadOnlyBuffer(b, () -> rb.append(new String(new char[rb.remaining() + 1])));
 928 
 929 #end[char]
 930 
 931         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 932             catchReadOnlyBuffer(b, () -> rb.array());
 933             catchReadOnlyBuffer(b, () -> rb.arrayOffset());
 934             if (rb.hasArray()) {
 935                 fail("Read-only heap buffer's backing array is accessible", rb);
 936             }
 937         }
 938 
 939         // Bulk puts from read-only buffers
 940 
 941         b.clear();
 942         rb.rewind();
 943         b.put(rb);
 944 
 945 #if[byte]
 946         // For byte buffers, test both the direct and non-direct cases
 947         $Type$Buffer ob
 948             = (b.isDirect()
 949                ? $Type$Buffer.allocate(rb.capacity())
 950                : $Type$Buffer.allocateDirect(rb.capacity()));
 951         rb.rewind();
 952         ob.put(rb);
 953 #end[byte]
 954 
 955         relPut(b);                       // Required by testViews
 956 
 957 #if[byte]
 958         // Test alignment
 959 
 960         testAlign(b, direct);
 961 #end[byte]
 962     }
 963 
 964 #if[char]
 965 
 966     private static void testStr() {
 967         final String s = "abcdefghijklm";
 968         int start = 3;
 969         int end = 9;
 970         final CharBuffer b = CharBuffer.wrap(s, start, end);
 971         show(0, b);
 972         ck(b, b.toString().equals(s.substring(start, end)));
 973         ck(b, b.toString().equals("defghi"));
 974         ck(b, b.isReadOnly());
 975         catchReadOnlyBuffer(b, () -> b.put('x'));
 976         ck(b, start, b.position());
 977         ck(b, end, b.limit());
 978         ck(b, s.length(), b.capacity());
 979         b.position(6);
 980         ck(b, b.subSequence(0,3).toString().equals("ghi"));
 981 
 982         // absolute bulk get
 983         char[] c = new char[end + 1 - (start - 1) + 1]; // [start - 1, end + 1]
 984         b.limit(end + 2);
 985         b.get(start - 1, c, 0, c.length);
 986         for (int i = 0; i < c.length; i++)
 987             ck(b, c[i], s.charAt(start - 1 + i));
 988 
 989         // The index, relative to the position, must be non-negative and
 990         // smaller than remaining().
 991         catchIndexOutOfBounds(b, () -> b.charAt(-1));
 992         catchIndexOutOfBounds(b, () -> b.charAt(b.remaining()));
 993         // The index must be non-negative and less than the buffer's limit.
 994         catchIndexOutOfBounds(b, () -> b.get(b.limit()));
 995         catchIndexOutOfBounds(b, () -> b.get(-1));
 996         // The start must be non-negative and no larger than remaining().
 997         catchIndexOutOfBounds(b, () -> b.subSequence(-1, b.remaining()));
 998         catchIndexOutOfBounds(b, () -> b.subSequence(b.remaining() + 1, b.remaining()));
 999 
1000         // The end must be no smaller than start and no larger than
1001         // remaining().
1002         catchIndexOutOfBounds(b, () -> b.subSequence(2, 1));
1003         catchIndexOutOfBounds(b, () -> b.subSequence(0, b.remaining() + 1));
1004 
1005         // The offset must be non-negative and no larger than <array.length>.
1006         catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, -1, s.length()));
1007         catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, s.length() + 1, s.length()));
1008         catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 1, 0));
1009         catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 0, s.length() + 1));
1010     }
1011 
1012 #end[char]
1013 
1014     public static void test(final $type$ [] ba) {
1015         int offset = 47;
1016         int length = 900;
1017         final $Type$Buffer b = $Type$Buffer.wrap(ba, offset, length);
1018         show(0, b);
1019         ck(b, b.capacity(), ba.length);
1020         ck(b, b.position(), offset);
1021         ck(b, b.limit(), offset + length);
1022 
1023         // The offset must be non-negative and no larger than <array.length>.
1024         catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, -1, ba.length));
1025         catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, ba.length + 1, ba.length));
1026         catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, -1));
1027         catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, ba.length + 1));
1028 
1029         // A NullPointerException will be thrown if the array is null.
1030         tryCatch(ba, NullPointerException.class,
1031                 () -> $Type$Buffer.wrap(($type$ []) null, 0, 5));
1032         tryCatch(ba, NullPointerException.class,
1033                 () -> $Type$Buffer.wrap(($type$ []) null));
1034     }
1035 
1036     private static void testAllocate() {
1037         // An IllegalArgumentException will be thrown for negative capacities.
1038         catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocate(-1));
1039         try {
1040             $Type$Buffer.allocate(-1);
1041         } catch (IllegalArgumentException e) {
1042             if (e.getMessage() == null) {
1043                 fail("Non-null IllegalArgumentException message expected for"
1044                      + " attempt to allocate negative capacity buffer");
1045             }
1046         }
1047 #if[byte]
1048         catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocateDirect(-1));
1049         try {
1050             $Type$Buffer.allocateDirect(-1);
1051         } catch (IllegalArgumentException e) {
1052             if (e.getMessage() == null) {
1053                 fail("Non-null IllegalArgumentException message expected for"
1054                      + " attempt to allocate negative capacity direct buffer");
1055             }
1056         }
1057 #end[byte]
1058     }
1059 
1060     public static void test() {
1061         testAllocate();
1062         test(0, $Type$Buffer.allocate(7 * 1024), false);
1063         test(0, $Type$Buffer.wrap(new $type$[7 * 1024], 0, 7 * 1024), false);
1064         test(new $type$[1024]);
1065 #if[byte]
1066         $Type$Buffer b = $Type$Buffer.allocateDirect(7 * 1024);
1067         for (b.position(0); b.position() < b.limit(); )
1068             ck(b, b.get(), 0);
1069         test(0, b, true);
1070 #end[byte]
1071 #if[char]
1072         testStr();
1073 #end[char]
1074 
1075         callReset($Type$Buffer.allocate(10));
1076 
1077 #if[byte]
1078 #else[byte]
1079         putBuffer();
1080 #end[byte]
1081     }
1082 
1083 }