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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio;
  27 
  28 import jdk.internal.HotSpotIntrinsicCandidate;
  29 import jdk.internal.access.JavaNioAccess;
  30 import jdk.internal.access.SharedSecrets;
  31 import jdk.internal.access.foreign.MemorySegmentProxy;
  32 import jdk.internal.misc.Unsafe;
  33 import jdk.internal.vm.annotation.ForceInline;
  34 
  35 import java.util.Spliterator;
  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     /**
 194      * The characteristics of Spliterators that traverse and split elements
 195      * maintained in Buffers.
 196      */
 197     static final int SPLITERATOR_CHARACTERISTICS =
 198         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
 199 
 200     // Invariants: mark <= position <= limit <= capacity
 201     private int mark = -1;
 202     private int position = 0;
 203     private int limit;
 204     private int capacity;
 205 
 206     // Used by heap byte buffers or direct buffers with Unsafe access
 207     // For heap byte buffers this field will be the address relative to the
 208     // array base address and offset into that array. The address might
 209     // not align on a word boundary for slices, nor align at a long word
 210     // (8 byte) boundary for byte[] allocations on 32-bit systems.
 211     // For direct buffers it is the start address of the memory region. The
 212     // address might not align on a word boundary for slices, nor when created
 213     // using JNI, see NewDirectByteBuffer(void*, long).
 214     // Should ideally be declared final
 215     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
 216     long address;
 217 
 218     // Used by buffers generated by the memory access API (JEP-370)
 219     final MemorySegmentProxy segment;
 220 
 221 
 222     // Creates a new buffer with given address and capacity.
 223     //
 224     Buffer(long addr, int cap, MemorySegmentProxy segment) {
 225         this.address = addr;
 226         this.capacity = cap;
 227         this.segment = segment;
 228     }
 229 
 230     // Creates a new buffer with the given mark, position, limit, and capacity,
 231     // after checking invariants.
 232     //
 233     Buffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) {       // package-private
 234         if (cap < 0)
 235             throw createCapacityException(cap);
 236         this.capacity = cap;
 237         this.segment = segment;
 238         limit(lim);
 239         position(pos);
 240         if (mark >= 0) {
 241             if (mark > pos)
 242                 throw new IllegalArgumentException("mark > position: ("
 243                                                    + mark + " > " + pos + ")");
 244             this.mark = mark;
 245         }
 246     }
 247 
 248     /**
 249      * Returns an {@code IllegalArgumentException} indicating that the source
 250      * and target are the same {@code Buffer}.  Intended for use in
 251      * {@code put(src)} when the parameter is the {@code Buffer} on which the
 252      * method is being invoked.
 253      *
 254      * @return  IllegalArgumentException
 255      *          With a message indicating equal source and target buffers
 256      */
 257     static IllegalArgumentException createSameBufferException() {
 258         return new IllegalArgumentException("The source buffer is this buffer");
 259     }
 260 
 261     /**
 262      * Verify that the capacity is nonnegative.
 263      *
 264      * @param  capacity
 265      *         The new buffer's capacity, in $type$s
 266      *
 267      * @throws IllegalArgumentException
 268      *         If the {@code capacity} is a negative integer
 269      */
 270     static IllegalArgumentException createCapacityException(int capacity) {
 271         assert capacity < 0 : "capacity expected to be negative";
 272         return new IllegalArgumentException("capacity < 0: ("
 273             + capacity + " < 0)");
 274     }
 275 
 276     /**
 277      * Returns this buffer's capacity.
 278      *
 279      * @return  The capacity of this buffer
 280      */
 281     public final int capacity() {
 282         return capacity;
 283     }
 284 
 285     /**
 286      * Returns this buffer's position.
 287      *
 288      * @return  The position of this buffer
 289      */
 290     public final int position() {
 291         return position;
 292     }
 293 
 294     /**
 295      * Sets this buffer's position.  If the mark is defined and larger than the
 296      * new position then it is discarded.
 297      *
 298      * @param  newPosition
 299      *         The new position value; must be non-negative
 300      *         and no larger than the current limit
 301      *
 302      * @return  This buffer
 303      *
 304      * @throws  IllegalArgumentException
 305      *          If the preconditions on {@code newPosition} do not hold
 306      */
 307     public Buffer position(int newPosition) {
 308         if (newPosition > limit | newPosition < 0)
 309             throw createPositionException(newPosition);
 310         position = newPosition;
 311         if (mark > position) mark = -1;
 312         return this;
 313     }
 314 
 315     /**
 316      * Verify that {@code 0 < newPosition <= limit}
 317      *
 318      * @param newPosition
 319      *        The new position value
 320      *
 321      * @throws IllegalArgumentException
 322      *         If the specified position is out of bounds.
 323      */
 324     private IllegalArgumentException createPositionException(int newPosition) {
 325         String msg = null;
 326 
 327         if (newPosition > limit) {
 328             msg = "newPosition > limit: (" + newPosition + " > " + limit + ")";
 329         } else { // assume negative
 330             assert newPosition < 0 : "newPosition expected to be negative";
 331             msg = "newPosition < 0: (" + newPosition + " < 0)";
 332         }
 333 
 334         return new IllegalArgumentException(msg);
 335     }
 336 
 337     /**
 338      * Returns this buffer's limit.
 339      *
 340      * @return  The limit of this buffer
 341      */
 342     public final int limit() {
 343         return limit;
 344     }
 345 
 346     /**
 347      * Sets this buffer's limit.  If the position is larger than the new limit
 348      * then it is set to the new limit.  If the mark is defined and larger than
 349      * the new limit then it is discarded.
 350      *
 351      * @param  newLimit
 352      *         The new limit value; must be non-negative
 353      *         and no larger than this buffer's capacity
 354      *
 355      * @return  This buffer
 356      *
 357      * @throws  IllegalArgumentException
 358      *          If the preconditions on {@code newLimit} do not hold
 359      */
 360     public Buffer limit(int newLimit) {
 361         if (newLimit > capacity | newLimit < 0)
 362             throw createLimitException(newLimit);
 363         limit = newLimit;
 364         if (position > limit) position = limit;
 365         if (mark > limit) mark = -1;
 366         return this;
 367     }
 368 
 369     /**
 370      * Verify that {@code 0 < newLimit <= capacity}
 371      *
 372      * @param newLimit
 373      *        The new limit value
 374      *
 375      * @throws IllegalArgumentException
 376      *         If the specified limit is out of bounds.
 377      */
 378     private IllegalArgumentException createLimitException(int newLimit) {
 379         String msg = null;
 380 
 381         if (newLimit > capacity) {
 382             msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")";
 383         } else { // assume negative
 384             assert newLimit < 0 : "newLimit expected to be negative";
 385             msg = "newLimit < 0: (" + newLimit + " < 0)";
 386         }
 387 
 388         return new IllegalArgumentException(msg);
 389     }
 390 
 391     /**
 392      * Sets this buffer's mark at its position.
 393      *
 394      * @return  This buffer
 395      */
 396     public Buffer mark() {
 397         mark = position;
 398         return this;
 399     }
 400 
 401     /**
 402      * Resets this buffer's position to the previously-marked position.
 403      *
 404      * <p> Invoking this method neither changes nor discards the mark's
 405      * value. </p>
 406      *
 407      * @return  This buffer
 408      *
 409      * @throws  InvalidMarkException
 410      *          If the mark has not been set
 411      */
 412     public Buffer reset() {
 413         int m = mark;
 414         if (m < 0)
 415             throw new InvalidMarkException();
 416         position = m;
 417         return this;
 418     }
 419 
 420     /**
 421      * Clears this buffer.  The position is set to zero, the limit is set to
 422      * the capacity, and the mark is discarded.
 423      *
 424      * <p> Invoke this method before using a sequence of channel-read or
 425      * <i>put</i> operations to fill this buffer.  For example:
 426      *
 427      * <blockquote><pre>
 428      * buf.clear();     // Prepare buffer for reading
 429      * in.read(buf);    // Read data</pre></blockquote>
 430      *
 431      * <p> This method does not actually erase the data in the buffer, but it
 432      * is named as if it did because it will most often be used in situations
 433      * in which that might as well be the case. </p>
 434      *
 435      * @return  This buffer
 436      */
 437     public Buffer clear() {
 438         position = 0;
 439         limit = capacity;
 440         mark = -1;
 441         return this;
 442     }
 443 
 444     /**
 445      * Flips this buffer.  The limit is set to the current position and then
 446      * the position is set to zero.  If the mark is defined then it is
 447      * discarded.
 448      *
 449      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
 450      * this method to prepare for a sequence of channel-write or relative
 451      * <i>get</i> operations.  For example:
 452      *
 453      * <blockquote><pre>
 454      * buf.put(magic);    // Prepend header
 455      * in.read(buf);      // Read data into rest of buffer
 456      * buf.flip();        // Flip buffer
 457      * out.write(buf);    // Write header + data to channel</pre></blockquote>
 458      *
 459      * <p> This method is often used in conjunction with the {@link
 460      * java.nio.ByteBuffer#compact compact} method when transferring data from
 461      * one place to another.  </p>
 462      *
 463      * @return  This buffer
 464      */
 465     public Buffer flip() {
 466         limit = position;
 467         position = 0;
 468         mark = -1;
 469         return this;
 470     }
 471 
 472     /**
 473      * Rewinds this buffer.  The position is set to zero and the mark is
 474      * discarded.
 475      *
 476      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
 477      * operations, assuming that the limit has already been set
 478      * appropriately.  For example:
 479      *
 480      * <blockquote><pre>
 481      * out.write(buf);    // Write remaining data
 482      * buf.rewind();      // Rewind buffer
 483      * buf.get(array);    // Copy data into array</pre></blockquote>
 484      *
 485      * @return  This buffer
 486      */
 487     public Buffer rewind() {
 488         position = 0;
 489         mark = -1;
 490         return this;
 491     }
 492 
 493     /**
 494      * Returns the number of elements between the current position and the
 495      * limit.
 496      *
 497      * @return  The number of elements remaining in this buffer
 498      */
 499     public final int remaining() {
 500         return limit - position;
 501     }
 502 
 503     /**
 504      * Tells whether there are any elements between the current position and
 505      * the limit.
 506      *
 507      * @return  {@code true} if, and only if, there is at least one element
 508      *          remaining in this buffer
 509      */
 510     public final boolean hasRemaining() {
 511         return position < limit;
 512     }
 513 
 514     /**
 515      * Tells whether or not this buffer is read-only.
 516      *
 517      * @return  {@code true} if, and only if, this buffer is read-only
 518      */
 519     public abstract boolean isReadOnly();
 520 
 521     /**
 522      * Tells whether or not this buffer is backed by an accessible
 523      * array.
 524      *
 525      * <p> If this method returns {@code true} then the {@link #array() array}
 526      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
 527      * </p>
 528      *
 529      * @return  {@code true} if, and only if, this buffer
 530      *          is backed by an array and is not read-only
 531      *
 532      * @since 1.6
 533      */
 534     public abstract boolean hasArray();
 535 
 536     /**
 537      * Returns the array that backs this
 538      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
 539      *
 540      * <p> This method is intended to allow array-backed buffers to be
 541      * passed to native code more efficiently. Concrete subclasses
 542      * provide more strongly-typed return values for this method.
 543      *
 544      * <p> Modifications to this buffer's content will cause the returned
 545      * array's content to be modified, and vice versa.
 546      *
 547      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
 548      * method in order to ensure that this buffer has an accessible backing
 549      * array.  </p>
 550      *
 551      * @return  The array that backs this buffer
 552      *
 553      * @throws  ReadOnlyBufferException
 554      *          If this buffer is backed by an array but is read-only
 555      *
 556      * @throws  UnsupportedOperationException
 557      *          If this buffer is not backed by an accessible array
 558      *
 559      * @since 1.6
 560      */
 561     public abstract Object array();
 562 
 563     /**
 564      * Returns the offset within this buffer's backing array of the first
 565      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
 566      *
 567      * <p> If this buffer is backed by an array then buffer position <i>p</i>
 568      * corresponds to array index <i>p</i>&nbsp;+&nbsp;{@code arrayOffset()}.
 569      *
 570      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
 571      * method in order to ensure that this buffer has an accessible backing
 572      * array.  </p>
 573      *
 574      * @return  The offset within this buffer's array
 575      *          of the first element of the buffer
 576      *
 577      * @throws  ReadOnlyBufferException
 578      *          If this buffer is backed by an array but is read-only
 579      *
 580      * @throws  UnsupportedOperationException
 581      *          If this buffer is not backed by an accessible array
 582      *
 583      * @since 1.6
 584      */
 585     public abstract int arrayOffset();
 586 
 587     /**
 588      * Tells whether or not this buffer is
 589      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
 590      *
 591      * @return  {@code true} if, and only if, this buffer is direct
 592      *
 593      * @since 1.6
 594      */
 595     public abstract boolean isDirect();
 596 
 597     /**
 598      * Creates a new buffer whose content is a shared subsequence of
 599      * this buffer's content.
 600      *
 601      * <p> The content of the new buffer will start at this buffer's current
 602      * position.  Changes to this buffer's content will be visible in the new
 603      * buffer, and vice versa; the two buffers' position, limit, and mark
 604      * values will be independent.
 605      *
 606      * <p> The new buffer's position will be zero, its capacity and its limit
 607      * will be the number of elements remaining in this buffer, its mark will be
 608      * undefined. The new buffer will be direct if, and only if, this buffer is
 609      * direct, and it will be read-only if, and only if, this buffer is
 610      * read-only.  </p>
 611      *
 612      * @return  The new buffer
 613      *
 614      * @since 9
 615      */
 616     public abstract Buffer slice();
 617 
 618     /**
 619      * Creates a new buffer whose content is a shared subsequence of
 620      * this buffer's content.
 621      *
 622      * <p> The content of the new buffer will start at position {@code index}
 623      * in this buffer, and will contain {@code length} elements. Changes to
 624      * this buffer's content will be visible in the new buffer, and vice versa;
 625      * the two buffers' position, limit, and mark values will be independent.
 626      *
 627      * <p> The new buffer's position will be zero, its capacity and its limit
 628      * will be {@code length}, its mark will be undefined. The new buffer will
 629      * be direct if, and only if, this buffer is direct, and it will be
 630      * read-only if, and only if, this buffer is read-only.  </p>
 631      *
 632      * @param   index
 633      *          The position in this buffer at which the content of the new
 634      *          buffer will start; must be non-negative and no larger than
 635      *          {@link #limit() limit()}
 636      *
 637      * @param   length
 638      *          The number of elements the new buffer will contain; must be
 639      *          non-negative and no larger than {@code limit() - index}
 640      *
 641      * @return  The new buffer
 642      *
 643      * @throws  IndexOutOfBoundsException
 644      *          If {@code index} is negative or greater than {@code limit()},
 645      *          {@code length} is negative, or {@code length > limit() - index}
 646      *
 647      * @since 13
 648      */
 649     public abstract Buffer slice(int index, int length);
 650 
 651     /**
 652      * Creates a new buffer that shares this buffer's content.
 653      *
 654      * <p> The content of the new buffer will be that of this buffer.  Changes
 655      * to this buffer's content will be visible in the new buffer, and vice
 656      * versa; the two buffers' position, limit, and mark values will be
 657      * independent.
 658      *
 659      * <p> The new buffer's capacity, limit, position and mark values will be
 660      * identical to those of this buffer. The new buffer will be direct if, and
 661      * only if, this buffer is direct, and it will be read-only if, and only if,
 662      * this buffer is read-only.  </p>
 663      *
 664      * @return  The new buffer
 665      *
 666      * @since 9
 667      */
 668     public abstract Buffer duplicate();
 669 
 670 
 671     // -- Package-private methods for bounds checking, etc. --
 672 
 673     /**
 674      *
 675      * @return the base reference, paired with the address
 676      * field, which in combination can be used for unsafe access into a heap
 677      * buffer or direct byte buffer (and views of).
 678      */
 679     abstract Object base();
 680 
 681     /**
 682      * Checks the current position against the limit, throwing a {@link
 683      * BufferUnderflowException} if it is not smaller than the limit, and then
 684      * increments the position.
 685      *
 686      * @return  The current position value, before it is incremented
 687      */
 688     final int nextGetIndex() {                          // package-private
 689         if (position >= limit)
 690             throw new BufferUnderflowException();
 691         return position++;
 692     }
 693 
 694     final int nextGetIndex(int nb) {                    // package-private
 695         if (limit - position < nb)
 696             throw new BufferUnderflowException();
 697         int p = position;
 698         position += nb;
 699         return p;
 700     }
 701 
 702     /**
 703      * Checks the current position against the limit, throwing a {@link
 704      * BufferOverflowException} if it is not smaller than the limit, and then
 705      * increments the position.
 706      *
 707      * @return  The current position value, before it is incremented
 708      */
 709     final int nextPutIndex() {                          // package-private
 710         if (position >= limit)
 711             throw new BufferOverflowException();
 712         return position++;
 713     }
 714 
 715     final int nextPutIndex(int nb) {                    // package-private
 716         if (limit - position < nb)
 717             throw new BufferOverflowException();
 718         int p = position;
 719         position += nb;
 720         return p;
 721     }
 722 
 723     /**
 724      * Checks the given index against the limit, throwing an {@link
 725      * IndexOutOfBoundsException} if it is not smaller than the limit
 726      * or is smaller than zero.
 727      */
 728     @HotSpotIntrinsicCandidate
 729     final int checkIndex(int i) {                       // package-private
 730         if ((i < 0) || (i >= limit))
 731             throw new IndexOutOfBoundsException();
 732         return i;
 733     }
 734 
 735     final int checkIndex(int i, int nb) {               // package-private
 736         if ((i < 0) || (nb > limit - i))
 737             throw new IndexOutOfBoundsException();
 738         return i;
 739     }
 740 
 741     final int markValue() {                             // package-private
 742         return mark;
 743     }
 744 
 745     final void discardMark() {                          // package-private
 746         mark = -1;
 747     }
 748 
 749     @ForceInline
 750     final void checkSegment() {
 751         if (segment != null) {
 752             segment.checkValidState();
 753         }
 754     }
 755 
 756     static {
 757         // setup access to this package in SharedSecrets
 758         SharedSecrets.setJavaNioAccess(
 759             new JavaNioAccess() {
 760                 @Override
 761                 public JavaNioAccess.BufferPool getDirectBufferPool() {
 762                     return Bits.BUFFER_POOL;
 763                 }
 764 
 765                 @Override
 766                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object obj, MemorySegmentProxy segment) {
 767                     return new DirectByteBuffer(addr, cap, obj, segment);
 768                 }
 769 
 770                 @Override
 771                 public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) {
 772                     return new HeapByteBuffer(hb, offset, capacity, segment);
 773                 }
 774 
 775                 @Override
 776                 public Object getBufferBase(ByteBuffer bb) {
 777                     return bb.base();
 778                 }
 779 
 780                 @Override
 781                 public long getBufferAddress(ByteBuffer bb) {
 782                     return bb.address;
 783                 }
 784 
 785                 @Override
 786                 public void checkSegment(Buffer buffer) {
 787                     buffer.checkSegment();
 788                 }
 789             });
 790     }
 791 
 792 }
--- EOF ---