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 }