1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.nio; 28 29 import jdk.internal.misc.Unsafe; 30 import jdk.internal.vm.annotation.IntrinsicCandidate; 31 32 import java.io.FileDescriptor; 33 import java.util.Spliterator; 34 35 import jdk.internal.misc.Unsafe; 36 37 /** 38 * A container for data of a specific primitive type. 39 * 40 * <p> A buffer is a linear, finite sequence of elements of a specific 41 * primitive type. Aside from its content, the essential properties of a 42 * buffer are its capacity, limit, and position: </p> 43 * 44 * <blockquote> 45 * 46 * <p> A buffer's <i>capacity</i> is the number of elements it contains. The 47 * capacity of a buffer is never negative and never changes. </p> 48 * 49 * <p> A buffer's <i>limit</i> is the index of the first element that should 50 * not be read or written. A buffer's limit is never negative and is never 51 * greater than its capacity. </p> 52 * 53 * <p> A buffer's <i>position</i> is the index of the next element to be 54 * read or written. A buffer's position is never negative and is never 55 * greater than its limit. </p> 56 * 57 * </blockquote> 58 * 59 * <p> There is one subclass of this class for each non-boolean primitive type. 60 * 61 * 62 * <h2> Transferring data </h2> 63 * 64 * <p> Each subclass of this class defines two categories of <i>get</i> and 65 * <i>put</i> operations: </p> 66 * 67 * <blockquote> 68 * 69 * <p> <i>Relative</i> operations read or write one or more elements starting 70 * at the current position and then increment the position by the number of 71 * elements transferred. If the requested transfer exceeds the limit then a 72 * relative <i>get</i> operation throws a {@link BufferUnderflowException} 73 * and a relative <i>put</i> operation throws a {@link 74 * BufferOverflowException}; in either case, no data is transferred. </p> 75 * 76 * <p> <i>Absolute</i> operations take an explicit element index and do not 77 * affect the position. Absolute <i>get</i> and <i>put</i> operations throw 78 * an {@link IndexOutOfBoundsException} if the index argument exceeds the 79 * limit. </p> 80 * 81 * </blockquote> 82 * 83 * <p> Data may also, of course, be transferred in to or out of a buffer by the 84 * I/O operations of an appropriate channel, which are always relative to the 85 * current position. 86 * 87 * 88 * <h2> Marking and resetting </h2> 89 * 90 * <p> A buffer's <i>mark</i> is the index to which its position will be reset 91 * when the {@link #reset reset} method is invoked. The mark is not always 92 * defined, but when it is defined it is never negative and is never greater 93 * than the position. If the mark is defined then it is discarded when the 94 * position or the limit is adjusted to a value smaller than the mark. If the 95 * mark is not defined then invoking the {@link #reset reset} method causes an 96 * {@link InvalidMarkException} to be thrown. 97 * 98 * 99 * <h2> Invariants </h2> 100 * 101 * <p> The following invariant holds for the mark, position, limit, and 102 * capacity values: 103 * 104 * <blockquote> 105 * {@code 0} {@code <=} 106 * <i>mark</i> {@code <=} 107 * <i>position</i> {@code <=} 108 * <i>limit</i> {@code <=} 109 * <i>capacity</i> 110 * </blockquote> 111 * 112 * <p> A newly-created buffer always has a position of zero and a mark that is 113 * undefined. The initial limit may be zero, or it may be some other value 114 * that depends upon the type of the buffer and the manner in which it is 115 * constructed. Each element of a newly-allocated buffer is initialized 116 * to zero. 117 * 118 * 119 * <h2> Additional operations </h2> 120 * 121 * <p> In addition to methods for accessing the position, limit, and capacity 122 * values and for marking and resetting, this class also defines the following 123 * operations upon buffers: 124 * 125 * <ul> 126 * 127 * <li><p> {@link #clear} makes a buffer ready for a new sequence of 128 * channel-read or relative <i>put</i> operations: It sets the limit to the 129 * capacity and the position to zero. </p></li> 130 * 131 * <li><p> {@link #flip} makes a buffer ready for a new sequence of 132 * channel-write or relative <i>get</i> operations: It sets the limit to the 133 * current position and then sets the position to zero. </p></li> 134 * 135 * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that 136 * it already contains: It leaves the limit unchanged and sets the position 137 * to zero. </p></li> 138 * 139 * <li><p> The {@link #slice} and {@link #slice(int,int) slice(index,length)} 140 * methods create a subsequence of a buffer: They leave the limit and the 141 * position unchanged. </p></li> 142 * 143 * <li><p> {@link #duplicate} creates a shallow copy of a buffer: It leaves 144 * the limit and the position unchanged. </p></li> 145 * 146 * </ul> 147 * 148 * 149 * <h2> Read-only buffers </h2> 150 * 151 * <p> Every buffer is readable, but not every buffer is writable. The 152 * mutation methods of each buffer class are specified as <i>optional 153 * operations</i> that will throw a {@link ReadOnlyBufferException} when 154 * invoked upon a read-only buffer. A read-only buffer does not allow its 155 * content to be changed, but its mark, position, and limit values are mutable. 156 * Whether or not a buffer is read-only may be determined by invoking its 157 * {@link #isReadOnly isReadOnly} method. 158 * 159 * 160 * <h2> Thread safety </h2> 161 * 162 * <p> Buffers are not safe for use by multiple concurrent threads. If a 163 * buffer is to be used by more than one thread then access to the buffer 164 * should be controlled by appropriate synchronization. 165 * 166 * 167 * <h2> Invocation chaining </h2> 168 * 169 * <p> Methods in this class that do not otherwise have a value to return are 170 * specified to return the buffer upon which they are invoked. This allows 171 * method invocations to be chained; for example, the sequence of statements 172 * 173 * <blockquote><pre> 174 * b.flip(); 175 * b.position(23); 176 * b.limit(42);</pre></blockquote> 177 * 178 * can be replaced by the single, more compact statement 179 * 180 * <blockquote><pre> 181 * b.flip().position(23).limit(42);</pre></blockquote> 182 * 183 * 184 * @author Mark Reinhold 185 * @author JSR-51 Expert Group 186 * @since 1.4 187 */ 188 189 public abstract class Buffer { 190 // Cached unsafe-access object 191 static final Unsafe UNSAFE = Unsafe.getUnsafe(); 192 193 // Android-removed: Remove unsupported scoped memory access. 194 // static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess(); 195 196 /** 197 * The characteristics of Spliterators that traverse and split elements 198 * maintained in Buffers. 199 */ 200 static final int SPLITERATOR_CHARACTERISTICS = 201 Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED; 202 203 // Invariants: mark <= position <= limit <= capacity 204 private int mark = -1; 205 // Android-changed: position field non-private for use by Android's nio implementation classes. 206 int position = 0; 207 private int limit; 208 private int capacity; 209 210 // Used by heap byte buffers or direct buffers with Unsafe access 211 // For heap byte buffers this field will be the address relative to the 212 // array base address and offset into that array. The address might 213 // not align on a word boundary for slices, nor align at a long word 214 // (8 byte) boundary for byte[] allocations on 32-bit systems. 215 // For direct buffers it is the start address of the memory region. The 216 // address might not align on a word boundary for slices, nor when created 217 // using JNI, see NewDirectByteBuffer(void*, long). 218 // Should ideally be declared final 219 // NOTE: hoisted here for speed in JNI GetDirectBufferAddress 220 long address; 221 222 // Android-added: _elementSizeShift field for NIOAccess class and framework native code. 223 /** 224 * The log base 2 of the element size of this buffer. Each typed subclass 225 * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this 226 * value. The value is used by JNI code in frameworks/base/ to avoid the 227 * need for costly 'instanceof' tests. 228 */ 229 final int _elementSizeShift; 230 231 // Used by buffers generated by the memory access API (JEP-370) 232 // Android-removed: Remove unsupported MemorySegmentProxy. 233 // final MemorySegmentProxy segment; 234 235 236 // Creates a new buffer with given address and capacity. 237 // 238 // Android-removed: Remove unsupported constructor. 239 /* 240 Buffer(long addr, int cap, MemorySegmentProxy segement) { 241 this.address = addr; 242 this.capacity = cap; 243 this.segement = segement; 244 } 245 */ 246 247 // Creates a new buffer with the given mark, position, limit, and capacity, 248 // after checking invariants. 249 // 250 // Android-added: _elementSizeShift field for NIOAccess class and framework native code. Buffer(int mark, int pos, int lim, int cap, int elementSizeShift)251 Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) { // package-private 252 if (cap < 0) 253 throw createCapacityException(cap); 254 this.capacity = cap; 255 limit(lim); 256 position(pos); 257 if (mark >= 0) { 258 if (mark > pos) 259 throw new IllegalArgumentException("mark > position: (" 260 + mark + " > " + pos + ")"); 261 this.mark = mark; 262 } 263 // Android-added: _elementSizeShift field for NIOAccess class and framework native code. 264 _elementSizeShift = elementSizeShift; 265 } 266 267 /** 268 * Returns an {@code IllegalArgumentException} indicating that the source 269 * and target are the same {@code Buffer}. Intended for use in 270 * {@code put(src)} when the parameter is the {@code Buffer} on which the 271 * method is being invoked. 272 * 273 * @return IllegalArgumentException 274 * With a message indicating equal source and target buffers 275 */ createSameBufferException()276 static IllegalArgumentException createSameBufferException() { 277 return new IllegalArgumentException("The source buffer is this buffer"); 278 } 279 280 /** 281 * Verify that the capacity is nonnegative. 282 * 283 * @param capacity 284 * The new buffer's capacity, in $type$s 285 * 286 * @throws IllegalArgumentException 287 * If the {@code capacity} is a negative integer 288 */ createCapacityException(int capacity)289 static IllegalArgumentException createCapacityException(int capacity) { 290 assert capacity < 0 : "capacity expected to be negative"; 291 return new IllegalArgumentException("capacity < 0: (" 292 + capacity + " < 0)"); 293 } 294 295 /** 296 * Returns this buffer's capacity. 297 * 298 * @return The capacity of this buffer 299 */ 300 public final int capacity() { 301 return capacity; 302 } 303 304 /** 305 * Returns this buffer's position. 306 * 307 * @return The position of this buffer 308 */ 309 public final int position() { 310 return position; 311 } 312 313 /** 314 * Sets this buffer's position. If the mark is defined and larger than the 315 * new position then it is discarded. 316 * 317 * @param newPosition 318 * The new position value; must be non-negative 319 * and no larger than the current limit 320 * 321 * @return This buffer 322 * 323 * @throws IllegalArgumentException 324 * If the preconditions on {@code newPosition} do not hold 325 */ 326 public Buffer position(int newPosition) { 327 if (newPosition > limit | newPosition < 0) 328 throw createPositionException(newPosition); 329 if (mark > newPosition) mark = -1; 330 position = newPosition; 331 return this; 332 } 333 334 /** 335 * Verify that {@code 0 < newPosition <= limit} 336 * 337 * @param newPosition 338 * The new position value 339 * 340 * @throws IllegalArgumentException 341 * If the specified position is out of bounds. 342 */ createPositionException(int newPosition)343 private IllegalArgumentException createPositionException(int newPosition) { 344 String msg = null; 345 346 if (newPosition > limit) { 347 msg = "newPosition > limit: (" + newPosition + " > " + limit + ")"; 348 } else { // assume negative 349 assert newPosition < 0 : "newPosition expected to be negative"; 350 msg = "newPosition < 0: (" + newPosition + " < 0)"; 351 } 352 353 return new IllegalArgumentException(msg); 354 } 355 356 /** 357 * Returns this buffer's limit. 358 * 359 * @return The limit of this buffer 360 */ 361 public final int limit() { 362 return limit; 363 } 364 365 /** 366 * Sets this buffer's limit. If the position is larger than the new limit 367 * then it is set to the new limit. If the mark is defined and larger than 368 * the new limit then it is discarded. 369 * 370 * @param newLimit 371 * The new limit value; must be non-negative 372 * and no larger than this buffer's capacity 373 * 374 * @return This buffer 375 * 376 * @throws IllegalArgumentException 377 * If the preconditions on {@code newLimit} do not hold 378 */ 379 public Buffer limit(int newLimit) { 380 if (newLimit > capacity | newLimit < 0) 381 throw createLimitException(newLimit); 382 limit = newLimit; 383 if (position > newLimit) position = newLimit; 384 if (mark > newLimit) mark = -1; 385 return this; 386 } 387 388 /** 389 * Verify that {@code 0 < newLimit <= capacity} 390 * 391 * @param newLimit 392 * The new limit value 393 * 394 * @throws IllegalArgumentException 395 * If the specified limit is out of bounds. 396 */ createLimitException(int newLimit)397 private IllegalArgumentException createLimitException(int newLimit) { 398 String msg = null; 399 400 if (newLimit > capacity) { 401 msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")"; 402 } else { // assume negative 403 assert newLimit < 0 : "newLimit expected to be negative"; 404 msg = "newLimit < 0: (" + newLimit + " < 0)"; 405 } 406 407 return new IllegalArgumentException(msg); 408 } 409 410 /** 411 * Sets this buffer's mark at its position. 412 * 413 * @return This buffer 414 */ 415 public Buffer mark() { 416 mark = position; 417 return this; 418 } 419 420 /** 421 * Resets this buffer's position to the previously-marked position. 422 * 423 * <p> Invoking this method neither changes nor discards the mark's 424 * value. </p> 425 * 426 * @return This buffer 427 * 428 * @throws InvalidMarkException 429 * If the mark has not been set 430 */ 431 public Buffer reset() { 432 int m = mark; 433 if (m < 0) 434 throw new InvalidMarkException(); 435 position = m; 436 return this; 437 } 438 439 /** 440 * Clears this buffer. The position is set to zero, the limit is set to 441 * the capacity, and the mark is discarded. 442 * 443 * <p> Invoke this method before using a sequence of channel-read or 444 * <i>put</i> operations to fill this buffer. For example: 445 * 446 * <blockquote><pre> 447 * buf.clear(); // Prepare buffer for reading 448 * in.read(buf); // Read data</pre></blockquote> 449 * 450 * <p> This method does not actually erase the data in the buffer, but it 451 * is named as if it did because it will most often be used in situations 452 * in which that might as well be the case. </p> 453 * 454 * @return This buffer 455 */ 456 public Buffer clear() { 457 position = 0; 458 limit = capacity; 459 mark = -1; 460 return this; 461 } 462 463 /** 464 * Flips this buffer. The limit is set to the current position and then 465 * the position is set to zero. If the mark is defined then it is 466 * discarded. 467 * 468 * <p> After a sequence of channel-read or <i>put</i> operations, invoke 469 * this method to prepare for a sequence of channel-write or relative 470 * <i>get</i> operations. For example: 471 * 472 * <blockquote><pre> 473 * buf.put(magic); // Prepend header 474 * in.read(buf); // Read data into rest of buffer 475 * buf.flip(); // Flip buffer 476 * out.write(buf); // Write header + data to channel</pre></blockquote> 477 * 478 * <p> This method is often used in conjunction with the {@link 479 * java.nio.ByteBuffer#compact compact} method when transferring data from 480 * one place to another. </p> 481 * 482 * @return This buffer 483 */ 484 public Buffer flip() { 485 limit = position; 486 position = 0; 487 mark = -1; 488 return this; 489 } 490 491 /** 492 * Rewinds this buffer. The position is set to zero and the mark is 493 * discarded. 494 * 495 * <p> Invoke this method before a sequence of channel-write or <i>get</i> 496 * operations, assuming that the limit has already been set 497 * appropriately. For example: 498 * 499 * <blockquote><pre> 500 * out.write(buf); // Write remaining data 501 * buf.rewind(); // Rewind buffer 502 * buf.get(array); // Copy data into array</pre></blockquote> 503 * 504 * @return This buffer 505 */ 506 public Buffer rewind() { 507 position = 0; 508 mark = -1; 509 return this; 510 } 511 512 /** 513 * Returns the number of elements between the current position and the 514 * limit. 515 * 516 * @return The number of elements remaining in this buffer 517 */ 518 public final int remaining() { 519 int rem = limit - position; 520 return rem > 0 ? rem : 0; 521 } 522 523 /** 524 * Tells whether there are any elements between the current position and 525 * the limit. 526 * 527 * @return {@code true} if, and only if, there is at least one element 528 * remaining in this buffer 529 */ 530 public final boolean hasRemaining() { 531 return position < limit; 532 } 533 534 /** 535 * Tells whether or not this buffer is read-only. 536 * 537 * @return {@code true} if, and only if, this buffer is read-only 538 */ 539 public abstract boolean isReadOnly(); 540 541 /** 542 * Tells whether or not this buffer is backed by an accessible 543 * array. 544 * 545 * <p> If this method returns {@code true} then the {@link #array() array} 546 * and {@link #arrayOffset() arrayOffset} methods may safely be invoked. 547 * </p> 548 * 549 * @return {@code true} if, and only if, this buffer 550 * is backed by an array and is not read-only 551 * 552 * @since 1.6 553 */ 554 public abstract boolean hasArray(); 555 556 /** 557 * Returns the array that backs this 558 * buffer <i>(optional operation)</i>. 559 * 560 * <p> This method is intended to allow array-backed buffers to be 561 * passed to native code more efficiently. Concrete subclasses 562 * provide more strongly-typed return values for this method. 563 * 564 * <p> Modifications to this buffer's content will cause the returned 565 * array's content to be modified, and vice versa. 566 * 567 * <p> Invoke the {@link #hasArray hasArray} method before invoking this 568 * method in order to ensure that this buffer has an accessible backing 569 * array. </p> 570 * 571 * @return The array that backs this buffer 572 * 573 * @throws ReadOnlyBufferException 574 * If this buffer is backed by an array but is read-only 575 * 576 * @throws UnsupportedOperationException 577 * If this buffer is not backed by an accessible array 578 * 579 * @since 1.6 580 */ 581 public abstract Object array(); 582 583 /** 584 * Returns the offset within this buffer's backing array of the first 585 * element of the buffer <i>(optional operation)</i>. 586 * 587 * <p> If this buffer is backed by an array then buffer position <i>p</i> 588 * corresponds to array index <i>p</i> + {@code arrayOffset()}. 589 * 590 * <p> Invoke the {@link #hasArray hasArray} method before invoking this 591 * method in order to ensure that this buffer has an accessible backing 592 * array. </p> 593 * 594 * @return The offset within this buffer's array 595 * of the first element of the buffer 596 * 597 * @throws ReadOnlyBufferException 598 * If this buffer is backed by an array but is read-only 599 * 600 * @throws UnsupportedOperationException 601 * If this buffer is not backed by an accessible array 602 * 603 * @since 1.6 604 */ 605 public abstract int arrayOffset(); 606 607 /** 608 * Tells whether or not this buffer is 609 * <a href="ByteBuffer.html#direct"><i>direct</i></a>. 610 * 611 * @return {@code true} if, and only if, this buffer is direct 612 * 613 * @since 1.6 614 */ 615 public abstract boolean isDirect(); 616 617 /** 618 * Creates a new buffer whose content is a shared subsequence of 619 * this buffer's content. 620 * 621 * <p> The content of the new buffer will start at this buffer's current 622 * position. Changes to this buffer's content will be visible in the new 623 * buffer, and vice versa; the two buffers' position, limit, and mark 624 * values will be independent. 625 * 626 * <p> The new buffer's position will be zero, its capacity and its limit 627 * will be the number of elements remaining in this buffer, its mark will be 628 * undefined. The new buffer will be direct if, and only if, this buffer is 629 * direct, and it will be read-only if, and only if, this buffer is 630 * read-only. </p> 631 * 632 * @return The new buffer 633 * 634 * @since 9 635 */ 636 public abstract Buffer slice(); 637 638 /** 639 * Creates a new buffer whose content is a shared subsequence of 640 * this buffer's content. 641 * 642 * <p> The content of the new buffer will start at position {@code index} 643 * in this buffer, and will contain {@code length} elements. Changes to 644 * this buffer's content will be visible in the new buffer, and vice versa; 645 * the two buffers' position, limit, and mark values will be independent. 646 * 647 * <p> The new buffer's position will be zero, its capacity and its limit 648 * will be {@code length}, its mark will be undefined. The new buffer will 649 * be direct if, and only if, this buffer is direct, and it will be 650 * read-only if, and only if, this buffer is read-only. </p> 651 * 652 * @param index 653 * The position in this buffer at which the content of the new 654 * buffer will start; must be non-negative and no larger than 655 * {@link #limit() limit()} 656 * 657 * @param length 658 * The number of elements the new buffer will contain; must be 659 * non-negative and no larger than {@code limit() - index} 660 * 661 * @return The new buffer 662 * 663 * @throws IndexOutOfBoundsException 664 * If {@code index} is negative or greater than {@code limit()}, 665 * {@code length} is negative, or {@code length > limit() - index} 666 * 667 * @since 13 668 */ 669 public abstract Buffer slice(int index, int length); 670 671 /** 672 * Creates a new buffer that shares this buffer's content. 673 * 674 * <p> The content of the new buffer will be that of this buffer. Changes 675 * to this buffer's content will be visible in the new buffer, and vice 676 * versa; the two buffers' position, limit, and mark values will be 677 * independent. 678 * 679 * <p> The new buffer's capacity, limit, position and mark values will be 680 * identical to those of this buffer. The new buffer will be direct if, and 681 * only if, this buffer is direct, and it will be read-only if, and only if, 682 * this buffer is read-only. </p> 683 * 684 * @return The new buffer 685 * 686 * @since 9 687 */ 688 public abstract Buffer duplicate(); 689 690 691 // -- Package-private methods for bounds checking, etc. -- 692 693 /** 694 * 695 * @return the base reference, paired with the address 696 * field, which in combination can be used for unsafe access into a heap 697 * buffer or direct byte buffer (and views of). 698 */ 699 abstract Object base(); 700 701 /** 702 * Checks the current position against the limit, throwing a {@link 703 * BufferUnderflowException} if it is not smaller than the limit, and then 704 * increments the position. 705 * 706 * @return The current position value, before it is incremented 707 */ 708 final int nextGetIndex() { // package-private 709 int p = position; 710 if (p >= limit) 711 throw new BufferUnderflowException(); 712 position = p + 1; 713 return p; 714 } 715 716 final int nextGetIndex(int nb) { // package-private 717 int p = position; 718 if (limit - p < nb) 719 throw new BufferUnderflowException(); 720 position = p + nb; 721 return p; 722 } 723 724 /** 725 * Checks the current position against the limit, throwing a {@link 726 * BufferOverflowException} if it is not smaller than the limit, and then 727 * increments the position. 728 * 729 * @return The current position value, before it is incremented 730 */ 731 final int nextPutIndex() { // package-private 732 int p = position; 733 if (p >= limit) 734 throw new BufferOverflowException(); 735 position = p + 1; 736 return p; 737 } 738 739 final int nextPutIndex(int nb) { // package-private 740 int p = position; 741 if (limit - p < nb) 742 throw new BufferOverflowException(); 743 position = p + nb; 744 return p; 745 } 746 747 /** 748 * Checks the given index against the limit, throwing an {@link 749 * IndexOutOfBoundsException} if it is not smaller than the limit 750 * or is smaller than zero. 751 */ 752 @IntrinsicCandidate 753 final int checkIndex(int i) { // package-private 754 if ((i < 0) || (i >= limit)) 755 // Android-changed: Add bounds details to exception. 756 throw new IndexOutOfBoundsException( 757 "index=" + i + " out of bounds (limit=" + limit + ")"); 758 return i; 759 } 760 761 final int checkIndex(int i, int nb) { // package-private 762 if ((i < 0) || (nb > limit - i)) 763 // Android-changed: Add bounds details to exception. 764 throw new IndexOutOfBoundsException( 765 "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")"); 766 return i; 767 } 768 769 final int markValue() { // package-private 770 return mark; 771 } 772 773 final void discardMark() { // package-private 774 mark = -1; 775 } 776 777 static void checkBounds(int off, int len, int size) { // package-private 778 if ((off | len | (off + len) | (size - (off + len))) < 0) 779 // Android-changed: Add bounds details to exception. 780 throw new IndexOutOfBoundsException( 781 "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")"); 782 } 783 784 final void checkScope() { 785 // Android-removed: ScopedMemoryAccess isn't used, as Android doesn't support it yet. 786 /* 787 ScopedMemoryAccess.Scope scope = scope(); 788 if (scope != null) { 789 scope.checkValidState(); 790 } 791 */ 792 } 793 794 // Android-removed: Remove unsupported scoped memory access. 795 /* 796 @ForceInline 797 final ScopedMemoryAccess.Scope scope() { 798 if (segment != null) { 799 return segment.scope(); 800 } else { 801 return null; 802 } 803 } 804 */ 805 806 807 // Android-added: getElementSizeShift() method for testing. 808 /** 809 * For testing only. This field is accessed directly via JNI from frameworks code. 810 * 811 * @hide 812 */ 813 public int getElementSizeShift() { 814 return _elementSizeShift; 815 } 816 817 // Android-removed: Remove unused SharedSecrets. 818 /* 819 static { 820 // setup access to this package in SharedSecrets 821 SharedSecrets.setJavaNioAccess( 822 new JavaNioAccess() { 823 @Override 824 public BufferPool getDirectBufferPool() { 825 return Bits.BUFFER_POOL; 826 } 827 828 @Override 829 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object obj, MemorySegmentProxy segment) { 830 return new DirectByteBuffer(addr, cap, obj, segment); 831 } 832 833 @Override 834 public ByteBuffer newMappedByteBuffer(UnmapperProxy unmapperProxy, long address, int cap, Object obj, MemorySegmentProxy segment) { 835 return new DirectByteBuffer(address, cap, obj, unmapperProxy.fileDescriptor(), unmapperProxy.isSync(), segment); 836 } 837 838 @Override 839 public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) { 840 return new HeapByteBuffer(hb, -1, 0, capacity, capacity, offset, segment); 841 } 842 843 @Override 844 public Object getBufferBase(ByteBuffer bb) { 845 return bb.base(); 846 } 847 848 @Override 849 public long getBufferAddress(ByteBuffer bb) { 850 return bb.address; 851 } 852 853 @Override 854 public UnmapperProxy unmapper(ByteBuffer bb) { 855 if (bb instanceof MappedByteBuffer) { 856 return ((MappedByteBuffer)bb).unmapper(); 857 } else { 858 return null; 859 } 860 } 861 862 @Override 863 public MemorySegmentProxy bufferSegment(Buffer buffer) { 864 return buffer.segment; 865 } 866 867 @Override 868 public Scope.Handle acquireScope(Buffer buffer, boolean async) { 869 var scope = buffer.scope(); 870 if (scope == null) { 871 return null; 872 } 873 if (async && scope.ownerThread() != null) { 874 throw new IllegalStateException("Confined scope not supported"); 875 } 876 return scope.acquire(); 877 } 878 879 @Override 880 public void force(FileDescriptor fd, long address, boolean isSync, long offset, long size) { 881 MappedMemoryUtils.force(fd, address, isSync, offset, size); 882 } 883 884 @Override 885 public void load(long address, boolean isSync, long size) { 886 MappedMemoryUtils.load(address, isSync, size); 887 } 888 889 @Override 890 public void unload(long address, boolean isSync, long size) { 891 MappedMemoryUtils.unload(address, isSync, size); 892 } 893 894 @Override 895 public boolean isLoaded(long address, boolean isSync, long size) { 896 return MappedMemoryUtils.isLoaded(address, isSync, size); 897 } 898 899 @Override 900 public void reserveMemory(long size, long cap) { 901 Bits.reserveMemory(size, cap); 902 } 903 904 @Override 905 public void unreserveMemory(long size, long cap) { 906 Bits.unreserveMemory(size, cap); 907 } 908 909 @Override 910 public int pageSize() { 911 return Bits.pageSize(); 912 } 913 }); 914 } 915 */ 916 917 } 918