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