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