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