src/java.base/share/classes/java/nio/Buffer.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2013, 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


 178      * The characteristics of Spliterators that traverse and split elements
 179      * maintained in Buffers.
 180      */
 181     static final int SPLITERATOR_CHARACTERISTICS =
 182         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
 183 
 184     // Invariants: mark <= position <= limit <= capacity
 185     private int mark = -1;
 186     private int position = 0;
 187     private int limit;
 188     private int capacity;
 189 
 190     // Used only by direct buffers
 191     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
 192     long address;
 193 
 194     // Creates a new buffer with the given mark, position, limit, and capacity,
 195     // after checking invariants.
 196     //
 197     Buffer(int mark, int pos, int lim, int cap) {       // package-private
 198         if (cap < 0)
 199             throw new IllegalArgumentException("Negative capacity: " + cap);

 200         this.capacity = cap;
 201         limit(lim);
 202         position(pos);
 203         if (mark >= 0) {
 204             if (mark > pos)
 205                 throw new IllegalArgumentException("mark > position: ("
 206                                                    + mark + " > " + pos + ")");
 207             this.mark = mark;
 208         }
 209     }
 210 
 211     /**
 212      * Returns this buffer's capacity.
 213      *
 214      * @return  The capacity of this buffer
 215      */
 216     public final int capacity() {
 217         return capacity;
 218     }
 219 


 223      * @return  The position of this buffer
 224      */
 225     public final int position() {
 226         return position;
 227     }
 228 
 229     /**
 230      * Sets this buffer's position.  If the mark is defined and larger than the
 231      * new position then it is discarded.
 232      *
 233      * @param  newPosition
 234      *         The new position value; must be non-negative
 235      *         and no larger than the current limit
 236      *
 237      * @return  This buffer
 238      *
 239      * @throws  IllegalArgumentException
 240      *          If the preconditions on <tt>newPosition</tt> do not hold
 241      */
 242     public Buffer position(int newPosition) {
 243         if ((newPosition > limit) || (newPosition < 0))
 244             throw new IllegalArgumentException();

 245         position = newPosition;
 246         if (mark > position) mark = -1;
 247         return this;
 248     }
 249 
 250     /**






















 251      * Returns this buffer's limit.
 252      *
 253      * @return  The limit of this buffer
 254      */
 255     public final int limit() {
 256         return limit;
 257     }
 258 
 259     /**
 260      * Sets this buffer's limit.  If the position is larger than the new limit
 261      * then it is set to the new limit.  If the mark is defined and larger than
 262      * the new limit then it is discarded.
 263      *
 264      * @param  newLimit
 265      *         The new limit value; must be non-negative
 266      *         and no larger than this buffer's capacity
 267      *
 268      * @return  This buffer
 269      *
 270      * @throws  IllegalArgumentException
 271      *          If the preconditions on <tt>newLimit</tt> do not hold
 272      */
 273     public Buffer limit(int newLimit) {
 274         if ((newLimit > capacity) || (newLimit < 0))
 275             throw new IllegalArgumentException();

 276         limit = newLimit;
 277         if (position > limit) position = limit;
 278         if (mark > limit) mark = -1;
 279         return this;
 280     }
 281 
 282     /**






















 283      * Sets this buffer's mark at its position.
 284      *
 285      * @return  This buffer
 286      */
 287     public Buffer mark() {
 288         mark = position;
 289         return this;
 290     }
 291 
 292     /**
 293      * Resets this buffer's position to the previously-marked position.
 294      *
 295      * <p> Invoking this method neither changes nor discards the mark's
 296      * value. </p>
 297      *
 298      * @return  This buffer
 299      *
 300      * @throws  InvalidMarkException
 301      *          If the mark has not been set
 302      */


 468      * @throws  ReadOnlyBufferException
 469      *          If this buffer is backed by an array but is read-only
 470      *
 471      * @throws  UnsupportedOperationException
 472      *          If this buffer is not backed by an accessible array
 473      *
 474      * @since 1.6
 475      */
 476     public abstract int arrayOffset();
 477 
 478     /**
 479      * Tells whether or not this buffer is
 480      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
 481      *
 482      * @return  <tt>true</tt> if, and only if, this buffer is direct
 483      *
 484      * @since 1.6
 485      */
 486     public abstract boolean isDirect();
 487 
 488 
 489     // -- Package-private methods for bounds checking, etc. --
 490 
 491     /**
 492      * Checks the current position against the limit, throwing a {@link
 493      * BufferUnderflowException} if it is not smaller than the limit, and then
 494      * increments the position.
 495      *
 496      * @return  The current position value, before it is incremented
 497      */
 498     final int nextGetIndex() {                          // package-private
 499         if (position >= limit)
 500             throw new BufferUnderflowException();
 501         return position++;
 502     }
 503 
 504     final int nextGetIndex(int nb) {                    // package-private
 505         if (limit - position < nb)
 506             throw new BufferUnderflowException();
 507         int p = position;
 508         position += nb;


 550     final int markValue() {                             // package-private
 551         return mark;
 552     }
 553 
 554     final void truncate() {                             // package-private
 555         mark = -1;
 556         position = 0;
 557         limit = 0;
 558         capacity = 0;
 559     }
 560 
 561     final void discardMark() {                          // package-private
 562         mark = -1;
 563     }
 564 
 565     static void checkBounds(int off, int len, int size) { // package-private
 566         if ((off | len | (off + len) | (size - (off + len))) < 0)
 567             throw new IndexOutOfBoundsException();
 568     }
 569 































 570 }
   1 /*
   2  * Copyright (c) 2000, 2015, 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


 178      * The characteristics of Spliterators that traverse and split elements
 179      * maintained in Buffers.
 180      */
 181     static final int SPLITERATOR_CHARACTERISTICS =
 182         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
 183 
 184     // Invariants: mark <= position <= limit <= capacity
 185     private int mark = -1;
 186     private int position = 0;
 187     private int limit;
 188     private int capacity;
 189 
 190     // Used only by direct buffers
 191     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
 192     long address;
 193 
 194     // Creates a new buffer with the given mark, position, limit, and capacity,
 195     // after checking invariants.
 196     //
 197     Buffer(int mark, int pos, int lim, int cap) {       // package-private
 198         if (cap < 0) {
 199             throw negativeCapacityException(cap);
 200         }
 201         this.capacity = cap;
 202         limit(lim);
 203         position(pos);
 204         if (mark >= 0) {
 205             if (mark > pos)
 206                 throw new IllegalArgumentException("mark > position: ("
 207                                                    + mark + " > " + pos + ")");
 208             this.mark = mark;
 209         }
 210     }
 211 
 212     /**
 213      * Returns this buffer's capacity.
 214      *
 215      * @return  The capacity of this buffer
 216      */
 217     public final int capacity() {
 218         return capacity;
 219     }
 220 


 224      * @return  The position of this buffer
 225      */
 226     public final int position() {
 227         return position;
 228     }
 229 
 230     /**
 231      * Sets this buffer's position.  If the mark is defined and larger than the
 232      * new position then it is discarded.
 233      *
 234      * @param  newPosition
 235      *         The new position value; must be non-negative
 236      *         and no larger than the current limit
 237      *
 238      * @return  This buffer
 239      *
 240      * @throws  IllegalArgumentException
 241      *          If the preconditions on <tt>newPosition</tt> do not hold
 242      */
 243     public Buffer position(int newPosition) {
 244         if ((newPosition > limit) || (newPosition < 0)) {
 245             throw positionOutOfBoundsException(newPosition);
 246         }
 247         position = newPosition;
 248         if (mark > position) mark = -1;
 249         return this;
 250     }
 251 
 252     /**
 253      * Verify that {@code 0 < newPosition <= limit}
 254      *
 255      * @param newPosition
 256      *        The new position value
 257      *
 258      * @throws IllegalArgumentException
 259      *         If the specified position is out of bounds.
 260      */
 261     private IllegalArgumentException positionOutOfBoundsException(int newPosition) {
 262         String msg = null;
 263 
 264         if (newPosition > limit) {
 265             msg = "newPosition > limit: (" + newPosition + " > " + limit + ")";
 266         } else { // assume negative
 267             assert newPosition < 0 : "newPosition expected to be negative";
 268             msg = "newPosition < 0: (" + newPosition + " < 0)";
 269         }
 270 
 271         return new IllegalArgumentException(msg);
 272     }
 273 
 274     /**
 275      * Returns this buffer's limit.
 276      *
 277      * @return  The limit of this buffer
 278      */
 279     public final int limit() {
 280         return limit;
 281     }
 282 
 283     /**
 284      * Sets this buffer's limit.  If the position is larger than the new limit
 285      * then it is set to the new limit.  If the mark is defined and larger than
 286      * the new limit then it is discarded.
 287      *
 288      * @param  newLimit
 289      *         The new limit value; must be non-negative
 290      *         and no larger than this buffer's capacity
 291      *
 292      * @return  This buffer
 293      *
 294      * @throws  IllegalArgumentException
 295      *          If the preconditions on <tt>newLimit</tt> do not hold
 296      */
 297     public Buffer limit(int newLimit) {
 298         if (newLimit > capacity || newLimit < 0) {
 299             throw limitOutOfBoundsException(newLimit);
 300         }
 301         limit = newLimit;
 302         if (position > limit) position = limit;
 303         if (mark > limit) mark = -1;
 304         return this;
 305     }
 306 
 307     /**
 308      * Verify that {@code 0 < newLimit <= capacity}
 309      *
 310      * @param newLimit
 311      *        The new limit value
 312      *
 313      * @throws IllegalArgumentException
 314      *         If the specified limit is out of bounds.
 315      */
 316     private IllegalArgumentException limitOutOfBoundsException(int newLimit) {
 317         String msg = null;
 318 
 319         if (newLimit > capacity) {
 320             msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")";
 321         } else { // assume negative
 322             assert newLimit < 0 : "newLimit expected to be negative";
 323             msg = "newLimit < 0: (" + newLimit + " < 0)";
 324         }
 325 
 326         return new IllegalArgumentException(msg);
 327     }
 328 
 329     /**
 330      * Sets this buffer's mark at its position.
 331      *
 332      * @return  This buffer
 333      */
 334     public Buffer mark() {
 335         mark = position;
 336         return this;
 337     }
 338 
 339     /**
 340      * Resets this buffer's position to the previously-marked position.
 341      *
 342      * <p> Invoking this method neither changes nor discards the mark's
 343      * value. </p>
 344      *
 345      * @return  This buffer
 346      *
 347      * @throws  InvalidMarkException
 348      *          If the mark has not been set
 349      */


 515      * @throws  ReadOnlyBufferException
 516      *          If this buffer is backed by an array but is read-only
 517      *
 518      * @throws  UnsupportedOperationException
 519      *          If this buffer is not backed by an accessible array
 520      *
 521      * @since 1.6
 522      */
 523     public abstract int arrayOffset();
 524 
 525     /**
 526      * Tells whether or not this buffer is
 527      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
 528      *
 529      * @return  <tt>true</tt> if, and only if, this buffer is direct
 530      *
 531      * @since 1.6
 532      */
 533     public abstract boolean isDirect();
 534 

 535     // -- Package-private methods for bounds checking, etc. --
 536 
 537     /**
 538      * Checks the current position against the limit, throwing a {@link
 539      * BufferUnderflowException} if it is not smaller than the limit, and then
 540      * increments the position.
 541      *
 542      * @return  The current position value, before it is incremented
 543      */
 544     final int nextGetIndex() {                          // package-private
 545         if (position >= limit)
 546             throw new BufferUnderflowException();
 547         return position++;
 548     }
 549 
 550     final int nextGetIndex(int nb) {                    // package-private
 551         if (limit - position < nb)
 552             throw new BufferUnderflowException();
 553         int p = position;
 554         position += nb;


 596     final int markValue() {                             // package-private
 597         return mark;
 598     }
 599 
 600     final void truncate() {                             // package-private
 601         mark = -1;
 602         position = 0;
 603         limit = 0;
 604         capacity = 0;
 605     }
 606 
 607     final void discardMark() {                          // package-private
 608         mark = -1;
 609     }
 610 
 611     static void checkBounds(int off, int len, int size) { // package-private
 612         if ((off | len | (off + len) | (size - (off + len))) < 0)
 613             throw new IndexOutOfBoundsException();
 614     }
 615 
 616     /**
 617      * Verify that the parameter is not this {@code Buffer}.  Intended for
 618      * checking that in {@code put(src)} the parameter is not the {@code Buffer}
 619      * on which the method is being invoked.
 620      *
 621      * @param src
 622      *        The buffer to compare with.
 623      *
 624      * @throws  IllegalArgumentException
 625      *          If the source buffer is this buffer
 626      */
 627     void checkSourceBufferNotThisBuffer(Buffer src) {   // package-private
 628         if (src == this) {
 629             throw new IllegalArgumentException("The source buffer is this buffer");
 630         }
 631     }
 632 
 633     /**
 634      * Verify that the capacity is nonnegative.
 635      *
 636      * @param  capacity
 637      *         The new buffer's capacity, in $type$s
 638      *
 639      * @throws  IllegalArgumentException
 640      *          If the <tt>capacity</tt> is a negative integer
 641      */
 642     static IllegalArgumentException negativeCapacityException(int capacity) { // package-private
 643         assert capacity < 0 : "capacity expected to be negative";
 644         return new IllegalArgumentException("capacity < 0: ("
 645             + capacity + " < 0)");
 646     }
 647 }