Home | History | Annotate | Download | only in nio
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 2000, 2013, 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 java.util.Spliterator;
     30 
     31 /**
     32  * A container for data of a specific primitive type.
     33  *
     34  * <p> A buffer is a linear, finite sequence of elements of a specific
     35  * primitive type.  Aside from its content, the essential properties of a
     36  * buffer are its capacity, limit, and position: </p>
     37  *
     38  * <blockquote>
     39  *
     40  * <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
     41  * capacity of a buffer is never negative and never changes.  </p>
     42  *
     43  * <p> A buffer's <i>limit</i> is the index of the first element that should
     44  * not be read or written.  A buffer's limit is never negative and is never
     45  * greater than its capacity.  </p>
     46  *
     47  * <p> A buffer's <i>position</i> is the index of the next element to be
     48  * read or written.  A buffer's position is never negative and is never
     49  * greater than its limit.  </p>
     50  *
     51  * </blockquote>
     52  *
     53  * <p> There is one subclass of this class for each non-boolean primitive type.
     54  *
     55  *
     56  * <h2> Transferring data </h2>
     57  *
     58  * <p> Each subclass of this class defines two categories of <i>get</i> and
     59  * <i>put</i> operations: </p>
     60  *
     61  * <blockquote>
     62  *
     63  * <p> <i>Relative</i> operations read or write one or more elements starting
     64  * at the current position and then increment the position by the number of
     65  * elements transferred.  If the requested transfer exceeds the limit then a
     66  * relative <i>get</i> operation throws a {@link BufferUnderflowException}
     67  * and a relative <i>put</i> operation throws a {@link
     68  * BufferOverflowException}; in either case, no data is transferred.  </p>
     69  *
     70  * <p> <i>Absolute</i> operations take an explicit element index and do not
     71  * affect the position.  Absolute <i>get</i> and <i>put</i> operations throw
     72  * an {@link IndexOutOfBoundsException} if the index argument exceeds the
     73  * limit.  </p>
     74  *
     75  * </blockquote>
     76  *
     77  * <p> Data may also, of course, be transferred in to or out of a buffer by the
     78  * I/O operations of an appropriate channel, which are always relative to the
     79  * current position.
     80  *
     81  *
     82  * <h2> Marking and resetting </h2>
     83  *
     84  * <p> A buffer's <i>mark</i> is the index to which its position will be reset
     85  * when the {@link #reset reset} method is invoked.  The mark is not always
     86  * defined, but when it is defined it is never negative and is never greater
     87  * than the position.  If the mark is defined then it is discarded when the
     88  * position or the limit is adjusted to a value smaller than the mark.  If the
     89  * mark is not defined then invoking the {@link #reset reset} method causes an
     90  * {@link InvalidMarkException} to be thrown.
     91  *
     92  *
     93  * <h2> Invariants </h2>
     94  *
     95  * <p> The following invariant holds for the mark, position, limit, and
     96  * capacity values:
     97  *
     98  * <blockquote>
     99  * <tt>0</tt> <tt>&lt;=</tt>
    100  * <i>mark</i> <tt>&lt;=</tt>
    101  * <i>position</i> <tt>&lt;=</tt>
    102  * <i>limit</i> <tt>&lt;=</tt>
    103  * <i>capacity</i>
    104  * </blockquote>
    105  *
    106  * <p> A newly-created buffer always has a position of zero and a mark that is
    107  * undefined.  The initial limit may be zero, or it may be some other value
    108  * that depends upon the type of the buffer and the manner in which it is
    109  * constructed.  Each element of a newly-allocated buffer is initialized
    110  * to zero.
    111  *
    112  *
    113  * <h2> Clearing, flipping, and rewinding </h2>
    114  *
    115  * <p> In addition to methods for accessing the position, limit, and capacity
    116  * values and for marking and resetting, this class also defines the following
    117  * operations upon buffers:
    118  *
    119  * <ul>
    120  *
    121  * <li><p> {@link #clear} makes a buffer ready for a new sequence of
    122  * channel-read or relative <i>put</i> operations: It sets the limit to the
    123  * capacity and the position to zero.  </p></li>
    124  *
    125  * <li><p> {@link #flip} makes a buffer ready for a new sequence of
    126  * channel-write or relative <i>get</i> operations: It sets the limit to the
    127  * current position and then sets the position to zero.  </p></li>
    128  *
    129  * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
    130  * it already contains: It leaves the limit unchanged and sets the position
    131  * to zero.  </p></li>
    132  *
    133  * </ul>
    134  *
    135  *
    136  * <h2> Read-only buffers </h2>
    137  *
    138  * <p> Every buffer is readable, but not every buffer is writable.  The
    139  * mutation methods of each buffer class are specified as <i>optional
    140  * operations</i> that will throw a {@link ReadOnlyBufferException} when
    141  * invoked upon a read-only buffer.  A read-only buffer does not allow its
    142  * content to be changed, but its mark, position, and limit values are mutable.
    143  * Whether or not a buffer is read-only may be determined by invoking its
    144  * {@link #isReadOnly isReadOnly} method.
    145  *
    146  *
    147  * <h2> Thread safety </h2>
    148  *
    149  * <p> Buffers are not safe for use by multiple concurrent threads.  If a
    150  * buffer is to be used by more than one thread then access to the buffer
    151  * should be controlled by appropriate synchronization.
    152  *
    153  *
    154  * <h2> Invocation chaining </h2>
    155  *
    156  * <p> Methods in this class that do not otherwise have a value to return are
    157  * specified to return the buffer upon which they are invoked.  This allows
    158  * method invocations to be chained; for example, the sequence of statements
    159  *
    160  * <blockquote><pre>
    161  * b.flip();
    162  * b.position(23);
    163  * b.limit(42);</pre></blockquote>
    164  *
    165  * can be replaced by the single, more compact statement
    166  *
    167  * <blockquote><pre>
    168  * b.flip().position(23).limit(42);</pre></blockquote>
    169  *
    170  * @author Mark Reinhold
    171  * @author JSR-51 Expert Group
    172  * @since 1.4
    173  */
    174 
    175 public abstract class Buffer {
    176 
    177     /**
    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     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     /**
    195      * The log base 2 of the element size of this buffer.  Each typed subclass
    196      * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
    197      * value.  The value is used by JNI code in frameworks/base/ to avoid the
    198      * need for costly 'instanceof' tests.
    199      */
    200     final int _elementSizeShift;
    201 
    202     // Creates a new buffer with the given mark, position, limit, and capacity,
    203     // after checking invariants.
    204     //
    205     Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) {       // package-private
    206         if (cap < 0)
    207             throw new IllegalArgumentException("Negative capacity: " + cap);
    208         this.capacity = cap;
    209         limit(lim);
    210         position(pos);
    211         if (mark >= 0) {
    212             if (mark > pos)
    213                 throw new IllegalArgumentException("mark > position: ("
    214                         + mark + " > " + pos + ")");
    215             this.mark = mark;
    216         }
    217         _elementSizeShift = elementSizeShift;
    218     }
    219 
    220     /**
    221      * Returns this buffer's capacity.
    222      *
    223      * @return The capacity of this buffer
    224      */
    225     public final int capacity() {
    226         return capacity;
    227     }
    228 
    229     /**
    230      * Returns this buffer's position.
    231      *
    232      * @return The position of this buffer
    233      */
    234     public final int position() {
    235         return position;
    236     }
    237 
    238     /**
    239      * Sets this buffer's position.  If the mark is defined and larger than the
    240      * new position then it is discarded.
    241      *
    242      * @param newPosition The new position value; must be non-negative
    243      *                    and no larger than the current limit
    244      * @return This buffer
    245      * @throws IllegalArgumentException If the preconditions on <tt>newPosition</tt> do not hold
    246      */
    247     public final Buffer position(int newPosition) {
    248         if ((newPosition > limit) || (newPosition < 0))
    249             throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
    250         position = newPosition;
    251         if (mark > position) mark = -1;
    252         return this;
    253     }
    254 
    255     /**
    256      * Returns this buffer's limit.
    257      *
    258      * @return The limit of this buffer
    259      */
    260     public final int limit() {
    261         return limit;
    262     }
    263 
    264     /**
    265      * Sets this buffer's limit.  If the position is larger than the new limit
    266      * then it is set to the new limit.  If the mark is defined and larger than
    267      * the new limit then it is discarded.
    268      *
    269      * @param newLimit The new limit value; must be non-negative
    270      *                 and no larger than this buffer's capacity
    271      * @return This buffer
    272      * @throws IllegalArgumentException If the preconditions on <tt>newLimit</tt> do not hold
    273      */
    274     public final Buffer limit(int newLimit) {
    275         if ((newLimit > capacity) || (newLimit < 0))
    276             throw new IllegalArgumentException();
    277         limit = newLimit;
    278         if (position > limit) position = limit;
    279         if (mark > limit) mark = -1;
    280         return this;
    281     }
    282 
    283     /**
    284      * Sets this buffer's mark at its position.
    285      *
    286      * @return This buffer
    287      */
    288     public final Buffer mark() {
    289         mark = position;
    290         return this;
    291     }
    292 
    293     /**
    294      * Resets this buffer's position to the previously-marked position.
    295      *
    296      * <p> Invoking this method neither changes nor discards the mark's
    297      * value. </p>
    298      *
    299      * @return This buffer
    300      * @throws InvalidMarkException If the mark has not been set
    301      */
    302     public final Buffer reset() {
    303         int m = mark;
    304         if (m < 0)
    305             throw new InvalidMarkException();
    306         position = m;
    307         return this;
    308     }
    309 
    310     /**
    311      * Clears this buffer.  The position is set to zero, the limit is set to
    312      * the capacity, and the mark is discarded.
    313      *
    314      * <p> Invoke this method before using a sequence of channel-read or
    315      * <i>put</i> operations to fill this buffer.  For example:
    316      *
    317      * <blockquote><pre>
    318      * buf.clear();     // Prepare buffer for reading
    319      * in.read(buf);    // Read data</pre></blockquote>
    320      *
    321      * <p> This method does not actually erase the data in the buffer, but it
    322      * is named as if it did because it will most often be used in situations
    323      * in which that might as well be the case. </p>
    324      *
    325      * @return This buffer
    326      */
    327     public final Buffer clear() {
    328         position = 0;
    329         limit = capacity;
    330         mark = -1;
    331         return this;
    332     }
    333 
    334     /**
    335      * Flips this buffer.  The limit is set to the current position and then
    336      * the position is set to zero.  If the mark is defined then it is
    337      * discarded.
    338      *
    339      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
    340      * this method to prepare for a sequence of channel-write or relative
    341      * <i>get</i> operations.  For example:
    342      *
    343      * <blockquote><pre>
    344      * buf.put(magic);    // Prepend header
    345      * in.read(buf);      // Read data into rest of buffer
    346      * buf.flip();        // Flip buffer
    347      * out.write(buf);    // Write header + data to channel</pre></blockquote>
    348      *
    349      * <p> This method is often used in conjunction with the {@link
    350      * java.nio.ByteBuffer#compact compact} method when transferring data from
    351      * one place to another.  </p>
    352      *
    353      * @return This buffer
    354      */
    355     public final Buffer flip() {
    356         limit = position;
    357         position = 0;
    358         mark = -1;
    359         return this;
    360     }
    361 
    362     /**
    363      * Rewinds this buffer.  The position is set to zero and the mark is
    364      * discarded.
    365      *
    366      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
    367      * operations, assuming that the limit has already been set
    368      * appropriately.  For example:
    369      *
    370      * <blockquote><pre>
    371      * out.write(buf);    // Write remaining data
    372      * buf.rewind();      // Rewind buffer
    373      * buf.get(array);    // Copy data into array</pre></blockquote>
    374      *
    375      * @return This buffer
    376      */
    377     public final Buffer rewind() {
    378         position = 0;
    379         mark = -1;
    380         return this;
    381     }
    382 
    383     /**
    384      * Returns the number of elements between the current position and the
    385      * limit.
    386      *
    387      * @return The number of elements remaining in this buffer
    388      */
    389     public final int remaining() {
    390         return limit - position;
    391     }
    392 
    393     /**
    394      * Tells whether there are any elements between the current position and
    395      * the limit.
    396      *
    397      * @return <tt>true</tt> if, and only if, there is at least one element
    398      * remaining in this buffer
    399      */
    400     public final boolean hasRemaining() {
    401         return position < limit;
    402     }
    403 
    404     /**
    405      * Tells whether or not this buffer is read-only.
    406      *
    407      * @return <tt>true</tt> if, and only if, this buffer is read-only
    408      */
    409     public abstract boolean isReadOnly();
    410 
    411     /**
    412      * Tells whether or not this buffer is backed by an accessible
    413      * array.
    414      *
    415      * <p> If this method returns <tt>true</tt> then the {@link #array() array}
    416      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
    417      * </p>
    418      *
    419      * @return <tt>true</tt> if, and only if, this buffer
    420      * is backed by an array and is not read-only
    421      * @since 1.6
    422      */
    423     public abstract boolean hasArray();
    424 
    425     /**
    426      * Returns the array that backs this
    427      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
    428      *
    429      * <p> This method is intended to allow array-backed buffers to be
    430      * passed to native code more efficiently. Concrete subclasses
    431      * provide more strongly-typed return values for this method.
    432      *
    433      * <p> Modifications to this buffer's content will cause the returned
    434      * array's content to be modified, and vice versa.
    435      *
    436      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
    437      * method in order to ensure that this buffer has an accessible backing
    438      * array.  </p>
    439      *
    440      * @return The array that backs this buffer
    441      * @throws ReadOnlyBufferException       If this buffer is backed by an array but is read-only
    442      * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
    443      * @since 1.6
    444      */
    445     public abstract Object array();
    446 
    447     /**
    448      * Returns the offset within this buffer's backing array of the first
    449      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
    450      *
    451      * <p> If this buffer is backed by an array then buffer position <i>p</i>
    452      * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
    453      *
    454      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
    455      * method in order to ensure that this buffer has an accessible backing
    456      * array.  </p>
    457      *
    458      * @return The offset within this buffer's array
    459      * of the first element of the buffer
    460      * @throws ReadOnlyBufferException       If this buffer is backed by an array but is read-only
    461      * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
    462      * @since 1.6
    463      */
    464     public abstract int arrayOffset();
    465 
    466     /**
    467      * Tells whether or not this buffer is
    468      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
    469      *
    470      * @return <tt>true</tt> if, and only if, this buffer is direct
    471      * @since 1.6
    472      */
    473     public abstract boolean isDirect();
    474 
    475 
    476     // -- Package-private methods for bounds checking, etc. --
    477 
    478     /**
    479      * Checks the current position against the limit, throwing a {@link
    480      * BufferUnderflowException} if it is not smaller than the limit, and then
    481      * increments the position.
    482      *
    483      * @return The current position value, before it is incremented
    484      */
    485     final int nextGetIndex() {                          // package-private
    486         if (position >= limit)
    487             throw new BufferUnderflowException();
    488         return position++;
    489     }
    490 
    491     final int nextGetIndex(int nb) {                    // package-private
    492         if (limit - position < nb)
    493             throw new BufferUnderflowException();
    494         int p = position;
    495         position += nb;
    496         return p;
    497     }
    498 
    499     /**
    500      * Checks the current position against the limit, throwing a {@link
    501      * BufferOverflowException} if it is not smaller than the limit, and then
    502      * increments the position.
    503      *
    504      * @return The current position value, before it is incremented
    505      */
    506     final int nextPutIndex() {                          // package-private
    507         if (position >= limit)
    508             throw new BufferOverflowException();
    509         return position++;
    510     }
    511 
    512     final int nextPutIndex(int nb) {                    // package-private
    513         if (limit - position < nb)
    514             throw new BufferOverflowException();
    515         int p = position;
    516         position += nb;
    517         return p;
    518     }
    519 
    520     /**
    521      * Checks the given index against the limit, throwing an {@link
    522      * IndexOutOfBoundsException} if it is not smaller than the limit
    523      * or is smaller than zero.
    524      */
    525     final int checkIndex(int i) {                       // package-private
    526         if ((i < 0) || (i >= limit))
    527             // Android-changed: Add bounds details to exception.
    528             throw new IndexOutOfBoundsException(
    529                     "index=" + i + " out of bounds (limit=" + limit + ")");
    530         return i;
    531     }
    532 
    533     final int checkIndex(int i, int nb) {               // package-private
    534         if ((i < 0) || (nb > limit - i))
    535             // Android-changed: Add bounds details to exception.
    536             throw new IndexOutOfBoundsException(
    537                     "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")");
    538         return i;
    539     }
    540 
    541     final int markValue() {                             // package-private
    542         return mark;
    543     }
    544 
    545     final void truncate() {                             // package-private
    546         mark = -1;
    547         position = 0;
    548         limit = 0;
    549         capacity = 0;
    550     }
    551 
    552     final void discardMark() {                          // package-private
    553         mark = -1;
    554     }
    555 
    556     static void checkBounds(int off, int len, int size) { // package-private
    557         if ((off | len | (off + len) | (size - (off + len))) < 0)
    558             // Android-changed: Add bounds details to exception.
    559             throw new IndexOutOfBoundsException(
    560                     "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")");
    561     }
    562 
    563     /**
    564      * For testing only. This field is accessed directly via JNI from frameworks code.
    565      *
    566      * @hide
    567      */
    568     public int getElementSizeShift() {
    569         return _elementSizeShift;
    570     }
    571 
    572 }
    573