Home | History | Annotate | Download | only in nio
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.nio;
     19 
     20 import java.util.Arrays;
     21 import libcore.io.Memory;
     22 
     23 /**
     24  * A buffer for bytes.
     25  * <p>
     26  * A byte buffer can be created in either one of the following ways:
     27  * <ul>
     28  * <li>{@link #allocate(int) Allocate} a new byte array and create a buffer
     29  * based on it;</li>
     30  * <li>{@link #allocateDirect(int) Allocate} a memory block and create a direct
     31  * buffer based on it;</li>
     32  * <li>{@link #wrap(byte[]) Wrap} an existing byte array to create a new
     33  * buffer.</li>
     34  * </ul>
     35  *
     36  */
     37 public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
     38 
     39     /**
     40      * Creates a byte buffer based on a newly allocated byte array.
     41      *
     42      * @param capacity
     43      *            the capacity of the new buffer
     44      * @return the created byte buffer.
     45      * @throws IllegalArgumentException
     46      *             if {@code capacity < 0}.
     47      */
     48     public static ByteBuffer allocate(int capacity) {
     49         if (capacity < 0) {
     50             throw new IllegalArgumentException("capacity < 0: " + capacity);
     51         }
     52         return new ReadWriteHeapByteBuffer(capacity);
     53     }
     54 
     55     /**
     56      * Creates a direct byte buffer based on a newly allocated memory block.
     57      *
     58      * @param capacity
     59      *            the capacity of the new buffer
     60      * @return the created byte buffer.
     61      * @throws IllegalArgumentException
     62      *             if {@code capacity < 0}.
     63      */
     64     public static ByteBuffer allocateDirect(int capacity) {
     65         if (capacity < 0) {
     66             throw new IllegalArgumentException("capacity < 0: " + capacity);
     67         }
     68         return new ReadWriteDirectByteBuffer(capacity);
     69     }
     70 
     71     /**
     72      * Creates a new byte buffer by wrapping the given byte array.
     73      * <p>
     74      * Calling this method has the same effect as
     75      * {@code wrap(array, 0, array.length)}.
     76      *
     77      * @param array
     78      *            the byte array which the new buffer will be based on
     79      * @return the created byte buffer.
     80      */
     81     public static ByteBuffer wrap(byte[] array) {
     82         return new ReadWriteHeapByteBuffer(array);
     83     }
     84 
     85     /**
     86      * Creates a new byte buffer by wrapping the given byte array.
     87      * <p>
     88      * The new buffer's position will be {@code start}, limit will be
     89      * {@code start + byteCount}, capacity will be the length of the array.
     90      *
     91      * @param array
     92      *            the byte array which the new buffer will be based on.
     93      * @param start
     94      *            the start index, must not be negative and not greater than
     95      *            {@code array.length}.
     96      * @param byteCount
     97      *            the length, must not be negative and not greater than
     98      *            {@code array.length - start}.
     99      * @return the created byte buffer.
    100      * @exception IndexOutOfBoundsException
    101      *                if either {@code start} or {@code byteCount} is invalid.
    102      */
    103     public static ByteBuffer wrap(byte[] array, int start, int byteCount) {
    104         Arrays.checkOffsetAndCount(array.length, start, byteCount);
    105         ByteBuffer buf = new ReadWriteHeapByteBuffer(array);
    106         buf.position = start;
    107         buf.limit = start + byteCount;
    108         return buf;
    109     }
    110 
    111     /**
    112      * The byte order of this buffer, default is {@code BIG_ENDIAN}.
    113      */
    114     ByteOrder order = ByteOrder.BIG_ENDIAN;
    115 
    116     ByteBuffer(int capacity, MemoryBlock block) {
    117         super(0, capacity, block);
    118     }
    119 
    120     /**
    121      * Returns the byte array which this buffer is based on, if there is one.
    122      *
    123      * @return the byte array which this buffer is based on.
    124      * @exception ReadOnlyBufferException
    125      *                if this buffer is based on a read-only array.
    126      * @exception UnsupportedOperationException
    127      *                if this buffer is not based on an array.
    128      */
    129     public final byte[] array() {
    130         return protectedArray();
    131     }
    132 
    133     /**
    134      * Returns the offset of the byte array which this buffer is based on, if
    135      * there is one.
    136      * <p>
    137      * The offset is the index of the array which corresponds to the zero
    138      * position of the buffer.
    139      *
    140      * @return the offset of the byte array which this buffer is based on.
    141      * @exception ReadOnlyBufferException
    142      *                if this buffer is based on a read-only array.
    143      * @exception UnsupportedOperationException
    144      *                if this buffer is not based on an array.
    145      */
    146     public final int arrayOffset() {
    147         return protectedArrayOffset();
    148     }
    149 
    150     /**
    151      * Returns a char buffer which is based on the remaining content of this
    152      * byte buffer.
    153      * <p>
    154      * The new buffer's position is zero, its limit and capacity is the number
    155      * of remaining bytes divided by two, and its mark is not set. The new
    156      * buffer's read-only property and byte order are the same as this buffer's.
    157      * The new buffer is direct if this byte buffer is direct.
    158      * <p>
    159      * The new buffer shares its content with this buffer, which means either
    160      * buffer's change of content will be visible to the other. The two buffer's
    161      * position, limit and mark are independent.
    162      *
    163      * @return a char buffer which is based on the content of this byte buffer.
    164      */
    165     public abstract CharBuffer asCharBuffer();
    166 
    167     /**
    168      * Returns a double buffer which is based on the remaining content of this
    169      * byte buffer.
    170      * <p>
    171      * The new buffer's position is zero, its limit and capacity is the number
    172      * of remaining bytes divided by eight, and its mark is not set. The new
    173      * buffer's read-only property and byte order are the same as this buffer's.
    174      * The new buffer is direct if this byte buffer is direct.
    175      * <p>
    176      * The new buffer shares its content with this buffer, which means either
    177      * buffer's change of content will be visible to the other. The two buffer's
    178      * position, limit and mark are independent.
    179      *
    180      * @return a double buffer which is based on the content of this byte
    181      *         buffer.
    182      */
    183     public abstract DoubleBuffer asDoubleBuffer();
    184 
    185     /**
    186      * Returns a float buffer which is based on the remaining content of this
    187      * byte buffer.
    188      * <p>
    189      * The new buffer's position is zero, its limit and capacity is the number
    190      * of remaining bytes divided by four, and its mark is not set. The new
    191      * buffer's read-only property and byte order are the same as this buffer's.
    192      * The new buffer is direct if this byte buffer is direct.
    193      * <p>
    194      * The new buffer shares its content with this buffer, which means either
    195      * buffer's change of content will be visible to the other. The two buffer's
    196      * position, limit and mark are independent.
    197      *
    198      * @return a float buffer which is based on the content of this byte buffer.
    199      */
    200     public abstract FloatBuffer asFloatBuffer();
    201 
    202     /**
    203      * Returns a int buffer which is based on the remaining content of this byte
    204      * buffer.
    205      * <p>
    206      * The new buffer's position is zero, its limit and capacity is the number
    207      * of remaining bytes divided by four, and its mark is not set. The new
    208      * buffer's read-only property and byte order are the same as this buffer's.
    209      * The new buffer is direct if this byte buffer is direct.
    210      * <p>
    211      * The new buffer shares its content with this buffer, which means either
    212      * buffer's change of content will be visible to the other. The two buffer's
    213      * position, limit and mark are independent.
    214      *
    215      * @return a int buffer which is based on the content of this byte buffer.
    216      */
    217     public abstract IntBuffer asIntBuffer();
    218 
    219     /**
    220      * Returns a long buffer which is based on the remaining content of this
    221      * byte buffer.
    222      * <p>
    223      * The new buffer's position is zero, its limit and capacity is the number
    224      * of remaining bytes divided by eight, and its mark is not set. The new
    225      * buffer's read-only property and byte order are the same as this buffer's.
    226      * The new buffer is direct if this byte buffer is direct.
    227      * <p>
    228      * The new buffer shares its content with this buffer, which means either
    229      * buffer's change of content will be visible to the other. The two buffer's
    230      * position, limit and mark are independent.
    231      *
    232      * @return a long buffer which is based on the content of this byte buffer.
    233      */
    234     public abstract LongBuffer asLongBuffer();
    235 
    236     /**
    237      * Returns a read-only buffer that shares its content with this buffer.
    238      * <p>
    239      * The returned buffer is guaranteed to be a new instance, even if this
    240      * buffer is read-only itself. The new buffer's position, limit, capacity
    241      * and mark are the same as this buffer.
    242      * <p>
    243      * The new buffer shares its content with this buffer, which means this
    244      * buffer's change of content will be visible to the new buffer. The two
    245      * buffer's position, limit and mark are independent.
    246      *
    247      * @return a read-only version of this buffer.
    248      */
    249     public abstract ByteBuffer asReadOnlyBuffer();
    250 
    251     /**
    252      * Returns a short buffer which is based on the remaining content of this
    253      * byte buffer.
    254      * <p>
    255      * The new buffer's position is zero, its limit and capacity is the number
    256      * of remaining bytes divided by two, and its mark is not set. The new
    257      * buffer's read-only property and byte order are the same as this buffer's.
    258      * The new buffer is direct if this byte buffer is direct.
    259      * <p>
    260      * The new buffer shares its content with this buffer, which means either
    261      * buffer's change of content will be visible to the other. The two buffer's
    262      * position, limit and mark are independent.
    263      *
    264      * @return a short buffer which is based on the content of this byte buffer.
    265      */
    266     public abstract ShortBuffer asShortBuffer();
    267 
    268     /**
    269      * Compacts this byte buffer.
    270      * <p>
    271      * The remaining bytes will be moved to the head of the
    272      * buffer, starting from position zero. Then the position is set to
    273      * {@code remaining()}; the limit is set to capacity; the mark is
    274      * cleared.
    275      *
    276      * @return {@code this}
    277      * @exception ReadOnlyBufferException
    278      *                if no changes may be made to the contents of this buffer.
    279      */
    280     public abstract ByteBuffer compact();
    281 
    282     /**
    283      * Compares the remaining bytes of this buffer to another byte buffer's
    284      * remaining bytes.
    285      *
    286      * @param otherBuffer
    287      *            another byte buffer.
    288      * @return a negative value if this is less than {@code other}; 0 if this
    289      *         equals to {@code other}; a positive value if this is greater
    290      *         than {@code other}.
    291      * @exception ClassCastException
    292      *                if {@code other} is not a byte buffer.
    293      */
    294     public int compareTo(ByteBuffer otherBuffer) {
    295         int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
    296                 : otherBuffer.remaining();
    297         int thisPos = position;
    298         int otherPos = otherBuffer.position;
    299         byte thisByte, otherByte;
    300         while (compareRemaining > 0) {
    301             thisByte = get(thisPos);
    302             otherByte = otherBuffer.get(otherPos);
    303             if (thisByte != otherByte) {
    304                 return thisByte < otherByte ? -1 : 1;
    305             }
    306             thisPos++;
    307             otherPos++;
    308             compareRemaining--;
    309         }
    310         return remaining() - otherBuffer.remaining();
    311     }
    312 
    313     /**
    314      * Returns a duplicated buffer that shares its content with this buffer.
    315      * <p>
    316      * The duplicated buffer's position, limit, capacity and mark are the same
    317      * as this buffer's. The duplicated buffer's read-only property and byte
    318      * order are the same as this buffer's too.
    319      * <p>
    320      * The new buffer shares its content with this buffer, which means either
    321      * buffer's change of content will be visible to the other. The two buffer's
    322      * position, limit and mark are independent.
    323      *
    324      * @return a duplicated buffer that shares its content with this buffer.
    325      */
    326     public abstract ByteBuffer duplicate();
    327 
    328     /**
    329      * Checks whether this byte buffer is equal to another object.
    330      * <p>
    331      * If {@code other} is not a byte buffer then {@code false} is returned. Two
    332      * byte buffers are equal if and only if their remaining bytes are exactly
    333      * the same. Position, limit, capacity and mark are not considered.
    334      *
    335      * @param other
    336      *            the object to compare with this byte buffer.
    337      * @return {@code true} if this byte buffer is equal to {@code other},
    338      *         {@code false} otherwise.
    339      */
    340     @Override
    341     public boolean equals(Object other) {
    342         if (!(other instanceof ByteBuffer)) {
    343             return false;
    344         }
    345         ByteBuffer otherBuffer = (ByteBuffer) other;
    346 
    347         if (remaining() != otherBuffer.remaining()) {
    348             return false;
    349         }
    350 
    351         int myPosition = position;
    352         int otherPosition = otherBuffer.position;
    353         boolean equalSoFar = true;
    354         while (equalSoFar && (myPosition < limit)) {
    355             equalSoFar = get(myPosition++) == otherBuffer.get(otherPosition++);
    356         }
    357 
    358         return equalSoFar;
    359     }
    360 
    361     /**
    362      * Returns the byte at the current position and increases the position by 1.
    363      *
    364      * @return the byte at the current position.
    365      * @exception BufferUnderflowException
    366      *                if the position is equal or greater than limit.
    367      */
    368     public abstract byte get();
    369 
    370     /**
    371      * Reads bytes from the current position into the specified byte array and
    372      * increases the position by the number of bytes read.
    373      * <p>
    374      * Calling this method has the same effect as
    375      * {@code get(dst, 0, dst.length)}.
    376      *
    377      * @param dst
    378      *            the destination byte array.
    379      * @return {@code this}
    380      * @exception BufferUnderflowException
    381      *                if {@code dst.length} is greater than {@code remaining()}.
    382      */
    383     public ByteBuffer get(byte[] dst) {
    384         return get(dst, 0, dst.length);
    385     }
    386 
    387     /**
    388      * Reads bytes from the current position into the specified byte array,
    389      * starting at the specified offset, and increases the position by the
    390      * number of bytes read.
    391      *
    392      * @param dst
    393      *            the target byte array.
    394      * @param dstOffset
    395      *            the offset of the byte array, must not be negative and
    396      *            not greater than {@code dst.length}.
    397      * @param byteCount
    398      *            the number of bytes to read, must not be negative and not
    399      *            greater than {@code dst.length - dstOffset}
    400      * @return {@code this}
    401      * @exception IndexOutOfBoundsException if {@code dstOffset < 0 ||  byteCount < 0}
    402      * @exception BufferUnderflowException if {@code byteCount > remaining()}
    403      */
    404     public ByteBuffer get(byte[] dst, int dstOffset, int byteCount) {
    405         Arrays.checkOffsetAndCount(dst.length, dstOffset, byteCount);
    406         if (byteCount > remaining()) {
    407             throw new BufferUnderflowException();
    408         }
    409         for (int i = dstOffset; i < dstOffset + byteCount; ++i) {
    410             dst[i] = get();
    411         }
    412         return this;
    413     }
    414 
    415     /**
    416      * Returns the byte at the specified index and does not change the position.
    417      *
    418      * @param index
    419      *            the index, must not be negative and less than limit.
    420      * @return the byte at the specified index.
    421      * @exception IndexOutOfBoundsException
    422      *                if index is invalid.
    423      */
    424     public abstract byte get(int index);
    425 
    426     /**
    427      * Returns the char at the current position and increases the position by 2.
    428      * <p>
    429      * The 2 bytes starting at the current position are composed into a char
    430      * according to the current byte order and returned.
    431      *
    432      * @return the char at the current position.
    433      * @exception BufferUnderflowException
    434      *                if the position is greater than {@code limit - 2}.
    435      */
    436     public abstract char getChar();
    437 
    438     /**
    439      * Returns the char at the specified index.
    440      * <p>
    441      * The 2 bytes starting from the specified index are composed into a char
    442      * according to the current byte order and returned. The position is not
    443      * changed.
    444      *
    445      * @param index
    446      *            the index, must not be negative and equal or less than
    447      *            {@code limit - 2}.
    448      * @return the char at the specified index.
    449      * @exception IndexOutOfBoundsException
    450      *                if {@code index} is invalid.
    451      */
    452     public abstract char getChar(int index);
    453 
    454     /**
    455      * Returns the double at the current position and increases the position by
    456      * 8.
    457      * <p>
    458      * The 8 bytes starting from the current position are composed into a double
    459      * according to the current byte order and returned.
    460      *
    461      * @return the double at the current position.
    462      * @exception BufferUnderflowException
    463      *                if the position is greater than {@code limit - 8}.
    464      */
    465     public abstract double getDouble();
    466 
    467     /**
    468      * Returns the double at the specified index.
    469      * <p>
    470      * The 8 bytes starting at the specified index are composed into a double
    471      * according to the current byte order and returned. The position is not
    472      * changed.
    473      *
    474      * @param index
    475      *            the index, must not be negative and equal or less than
    476      *            {@code limit - 8}.
    477      * @return the double at the specified index.
    478      * @exception IndexOutOfBoundsException
    479      *                if {@code index} is invalid.
    480      */
    481     public abstract double getDouble(int index);
    482 
    483     /**
    484      * Returns the float at the current position and increases the position by
    485      * 4.
    486      * <p>
    487      * The 4 bytes starting at the current position are composed into a float
    488      * according to the current byte order and returned.
    489      *
    490      * @return the float at the current position.
    491      * @exception BufferUnderflowException
    492      *                if the position is greater than {@code limit - 4}.
    493      */
    494     public abstract float getFloat();
    495 
    496     /**
    497      * Returns the float at the specified index.
    498      * <p>
    499      * The 4 bytes starting at the specified index are composed into a float
    500      * according to the current byte order and returned. The position is not
    501      * changed.
    502      *
    503      * @param index
    504      *            the index, must not be negative and equal or less than
    505      *            {@code limit - 4}.
    506      * @return the float at the specified index.
    507      * @exception IndexOutOfBoundsException
    508      *                if {@code index} is invalid.
    509      */
    510     public abstract float getFloat(int index);
    511 
    512     /**
    513      * Returns the int at the current position and increases the position by 4.
    514      * <p>
    515      * The 4 bytes starting at the current position are composed into a int
    516      * according to the current byte order and returned.
    517      *
    518      * @return the int at the current position.
    519      * @exception BufferUnderflowException
    520      *                if the position is greater than {@code limit - 4}.
    521      */
    522     public abstract int getInt();
    523 
    524     /**
    525      * Returns the int at the specified index.
    526      * <p>
    527      * The 4 bytes starting at the specified index are composed into a int
    528      * according to the current byte order and returned. The position is not
    529      * changed.
    530      *
    531      * @param index
    532      *            the index, must not be negative and equal or less than
    533      *            {@code limit - 4}.
    534      * @return the int at the specified index.
    535      * @exception IndexOutOfBoundsException
    536      *                if {@code index} is invalid.
    537      */
    538     public abstract int getInt(int index);
    539 
    540     /**
    541      * Returns the long at the current position and increases the position by 8.
    542      * <p>
    543      * The 8 bytes starting at the current position are composed into a long
    544      * according to the current byte order and returned.
    545      *
    546      * @return the long at the current position.
    547      * @exception BufferUnderflowException
    548      *                if the position is greater than {@code limit - 8}.
    549      */
    550     public abstract long getLong();
    551 
    552     /**
    553      * Returns the long at the specified index.
    554      * <p>
    555      * The 8 bytes starting at the specified index are composed into a long
    556      * according to the current byte order and returned. The position is not
    557      * changed.
    558      *
    559      * @param index
    560      *            the index, must not be negative and equal or less than
    561      *            {@code limit - 8}.
    562      * @return the long at the specified index.
    563      * @exception IndexOutOfBoundsException
    564      *                if {@code index} is invalid.
    565      */
    566     public abstract long getLong(int index);
    567 
    568     /**
    569      * Returns the short at the current position and increases the position by 2.
    570      * <p>
    571      * The 2 bytes starting at the current position are composed into a short
    572      * according to the current byte order and returned.
    573      *
    574      * @return the short at the current position.
    575      * @exception BufferUnderflowException
    576      *                if the position is greater than {@code limit - 2}.
    577      */
    578     public abstract short getShort();
    579 
    580     /**
    581      * Returns the short at the specified index.
    582      * <p>
    583      * The 2 bytes starting at the specified index are composed into a short
    584      * according to the current byte order and returned. The position is not
    585      * changed.
    586      *
    587      * @param index
    588      *            the index, must not be negative and equal or less than
    589      *            {@code limit - 2}.
    590      * @return the short at the specified index.
    591      * @exception IndexOutOfBoundsException
    592      *                if {@code index} is invalid.
    593      */
    594     public abstract short getShort(int index);
    595 
    596     public final boolean hasArray() {
    597         return protectedHasArray();
    598     }
    599 
    600     /**
    601      * Calculates this buffer's hash code from the remaining chars. The
    602      * position, limit, capacity and mark don't affect the hash code.
    603      *
    604      * @return the hash code calculated from the remaining bytes.
    605      */
    606     @Override
    607     public int hashCode() {
    608         int myPosition = position;
    609         int hash = 0;
    610         while (myPosition < limit) {
    611             hash = hash + get(myPosition++);
    612         }
    613         return hash;
    614     }
    615 
    616     /**
    617      * Indicates whether this buffer is direct.
    618      *
    619      * @return {@code true} if this buffer is direct, {@code false} otherwise.
    620      */
    621     public abstract boolean isDirect();
    622 
    623     /**
    624      * Returns the byte order used by this buffer when converting bytes from/to
    625      * other primitive types.
    626      * <p>
    627      * The default byte order of byte buffer is always
    628      * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
    629      *
    630      * @return the byte order used by this buffer when converting bytes from/to
    631      *         other primitive types.
    632      */
    633     public final ByteOrder order() {
    634         return order;
    635     }
    636 
    637     /**
    638      * Sets the byte order of this buffer.
    639      *
    640      * @param byteOrder
    641      *            the byte order to set. If {@code null} then the order
    642      *            will be {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}.
    643      * @return {@code this}
    644      * @see ByteOrder
    645      */
    646     public final ByteBuffer order(ByteOrder byteOrder) {
    647         orderImpl(byteOrder);
    648         return this;
    649     }
    650 
    651     /**
    652      * Subverts the fact that order(ByteOrder) is final, for the benefit of MappedByteBufferAdapter.
    653      */
    654     void orderImpl(ByteOrder byteOrder) {
    655         if (byteOrder == null) {
    656             byteOrder = ByteOrder.LITTLE_ENDIAN;
    657         }
    658         order = byteOrder;
    659     }
    660 
    661     /**
    662      * Child class implements this method to realize {@code array()}.
    663      *
    664      * @see #array()
    665      */
    666     abstract byte[] protectedArray();
    667 
    668     /**
    669      * Child class implements this method to realize {@code arrayOffset()}.
    670      *
    671      * @see #arrayOffset()
    672      */
    673     abstract int protectedArrayOffset();
    674 
    675     /**
    676      * Child class implements this method to realize {@code hasArray()}.
    677      *
    678      * @see #hasArray()
    679      */
    680     abstract boolean protectedHasArray();
    681 
    682     /**
    683      * Writes the given byte to the current position and increases the position
    684      * by 1.
    685      *
    686      * @param b
    687      *            the byte to write.
    688      * @return {@code this}
    689      * @exception BufferOverflowException
    690      *                if position is equal or greater than limit.
    691      * @exception ReadOnlyBufferException
    692      *                if no changes may be made to the contents of this buffer.
    693      */
    694     public abstract ByteBuffer put(byte b);
    695 
    696     /**
    697      * Writes bytes in the given byte array to the current position and
    698      * increases the position by the number of bytes written.
    699      * <p>
    700      * Calling this method has the same effect as
    701      * {@code put(src, 0, src.length)}.
    702      *
    703      * @param src
    704      *            the source byte array.
    705      * @return {@code this}
    706      * @exception BufferOverflowException
    707      *                if {@code remaining()} is less than {@code src.length}.
    708      * @exception ReadOnlyBufferException
    709      *                if no changes may be made to the contents of this buffer.
    710      */
    711     public final ByteBuffer put(byte[] src) {
    712         return put(src, 0, src.length);
    713     }
    714 
    715     /**
    716      * Writes bytes in the given byte array, starting from the specified offset,
    717      * to the current position and increases the position by the number of bytes
    718      * written.
    719      *
    720      * @param src
    721      *            the source byte array.
    722      * @param srcOffset
    723      *            the offset of byte array, must not be negative and not greater
    724      *            than {@code src.length}.
    725      * @param byteCount
    726      *            the number of bytes to write, must not be negative and not
    727      *            greater than {@code src.length - srcOffset}.
    728      * @return {@code this}
    729      * @exception BufferOverflowException
    730      *                if {@code remaining()} is less than {@code byteCount}.
    731      * @exception IndexOutOfBoundsException
    732      *                if either {@code srcOffset} or {@code byteCount} is invalid.
    733      * @exception ReadOnlyBufferException
    734      *                if no changes may be made to the contents of this buffer.
    735      */
    736     public ByteBuffer put(byte[] src, int srcOffset, int byteCount) {
    737         Arrays.checkOffsetAndCount(src.length, srcOffset, byteCount);
    738         if (byteCount > remaining()) {
    739             throw new BufferOverflowException();
    740         }
    741         for (int i = srcOffset; i < srcOffset + byteCount; ++i) {
    742             put(src[i]);
    743         }
    744         return this;
    745     }
    746 
    747     /**
    748      * Writes all the remaining bytes of the {@code src} byte buffer to this
    749      * buffer's current position, and increases both buffers' position by the
    750      * number of bytes copied.
    751      *
    752      * @param src
    753      *            the source byte buffer.
    754      * @return {@code this}
    755      * @exception BufferOverflowException
    756      *                if {@code src.remaining()} is greater than this buffer's
    757      *                {@code remaining()}.
    758      * @exception IllegalArgumentException
    759      *                if {@code src} is this buffer.
    760      * @exception ReadOnlyBufferException
    761      *                if no changes may be made to the contents of this buffer.
    762      */
    763     public ByteBuffer put(ByteBuffer src) {
    764         if (src == this) {
    765             throw new IllegalArgumentException("src == this");
    766         }
    767         int srcByteCount = src.remaining();
    768         if (srcByteCount > remaining()) {
    769             throw new BufferOverflowException();
    770         }
    771 
    772         Object srcObject = src.isDirect() ? src : NioUtils.unsafeArray(src);
    773         int srcOffset = src.position();
    774         if (!src.isDirect()) {
    775             srcOffset += NioUtils.unsafeArrayOffset(src);
    776         }
    777 
    778         ByteBuffer dst = this;
    779         Object dstObject = dst.isDirect() ? dst : NioUtils.unsafeArray(dst);
    780         int dstOffset = dst.position();
    781         if (!dst.isDirect()) {
    782             dstOffset += NioUtils.unsafeArrayOffset(dst);
    783         }
    784 
    785         Memory.memmove(dstObject, dstOffset, srcObject, srcOffset, srcByteCount);
    786         src.position(src.limit());
    787         dst.position(dst.position() + srcByteCount);
    788 
    789         return this;
    790     }
    791 
    792     /**
    793      * Write a byte to the specified index of this buffer without changing the
    794      * position.
    795      *
    796      * @param index
    797      *            the index, must not be negative and less than the limit.
    798      * @param b
    799      *            the byte to write.
    800      * @return {@code this}
    801      * @exception IndexOutOfBoundsException
    802      *                if {@code index} is invalid.
    803      * @exception ReadOnlyBufferException
    804      *                if no changes may be made to the contents of this buffer.
    805      */
    806     public abstract ByteBuffer put(int index, byte b);
    807 
    808     /**
    809      * Writes the given char to the current position and increases the position
    810      * by 2.
    811      * <p>
    812      * The char is converted to bytes using the current byte order.
    813      *
    814      * @param value
    815      *            the char to write.
    816      * @return {@code this}
    817      * @exception BufferOverflowException
    818      *                if position is greater than {@code limit - 2}.
    819      * @exception ReadOnlyBufferException
    820      *                if no changes may be made to the contents of this buffer.
    821      */
    822     public abstract ByteBuffer putChar(char value);
    823 
    824     /**
    825      * Writes the given char to the specified index of this buffer.
    826      * <p>
    827      * The char is converted to bytes using the current byte order. The position
    828      * is not changed.
    829      *
    830      * @param index
    831      *            the index, must not be negative and equal or less than
    832      *            {@code limit - 2}.
    833      * @param value
    834      *            the char to write.
    835      * @return {@code this}
    836      * @exception IndexOutOfBoundsException
    837      *                if {@code index} is invalid.
    838      * @exception ReadOnlyBufferException
    839      *                if no changes may be made to the contents of this buffer.
    840      */
    841     public abstract ByteBuffer putChar(int index, char value);
    842 
    843     /**
    844      * Writes the given double to the current position and increases the position
    845      * by 8.
    846      * <p>
    847      * The double is converted to bytes using the current byte order.
    848      *
    849      * @param value
    850      *            the double to write.
    851      * @return {@code this}
    852      * @exception BufferOverflowException
    853      *                if position is greater than {@code limit - 8}.
    854      * @exception ReadOnlyBufferException
    855      *                if no changes may be made to the contents of this buffer.
    856      */
    857     public abstract ByteBuffer putDouble(double value);
    858 
    859     /**
    860      * Writes the given double to the specified index of this buffer.
    861      * <p>
    862      * The double is converted to bytes using the current byte order. The
    863      * position is not changed.
    864      *
    865      * @param index
    866      *            the index, must not be negative and equal or less than
    867      *            {@code limit - 8}.
    868      * @param value
    869      *            the double to write.
    870      * @return {@code this}
    871      * @exception IndexOutOfBoundsException
    872      *                if {@code index} is invalid.
    873      * @exception ReadOnlyBufferException
    874      *                if no changes may be made to the contents of this buffer.
    875      */
    876     public abstract ByteBuffer putDouble(int index, double value);
    877 
    878     /**
    879      * Writes the given float to the current position and increases the position
    880      * by 4.
    881      * <p>
    882      * The float is converted to bytes using the current byte order.
    883      *
    884      * @param value
    885      *            the float to write.
    886      * @return {@code this}
    887      * @exception BufferOverflowException
    888      *                if position is greater than {@code limit - 4}.
    889      * @exception ReadOnlyBufferException
    890      *                if no changes may be made to the contents of this buffer.
    891      */
    892     public abstract ByteBuffer putFloat(float value);
    893 
    894     /**
    895      * Writes the given float to the specified index of this buffer.
    896      * <p>
    897      * The float is converted to bytes using the current byte order. The
    898      * position is not changed.
    899      *
    900      * @param index
    901      *            the index, must not be negative and equal or less than
    902      *            {@code limit - 4}.
    903      * @param value
    904      *            the float to write.
    905      * @return {@code this}
    906      * @exception IndexOutOfBoundsException
    907      *                if {@code index} is invalid.
    908      * @exception ReadOnlyBufferException
    909      *                if no changes may be made to the contents of this buffer.
    910      */
    911     public abstract ByteBuffer putFloat(int index, float value);
    912 
    913     /**
    914      * Writes the given int to the current position and increases the position by
    915      * 4.
    916      * <p>
    917      * The int is converted to bytes using the current byte order.
    918      *
    919      * @param value
    920      *            the int to write.
    921      * @return {@code this}
    922      * @exception BufferOverflowException
    923      *                if position is greater than {@code limit - 4}.
    924      * @exception ReadOnlyBufferException
    925      *                if no changes may be made to the contents of this buffer.
    926      */
    927     public abstract ByteBuffer putInt(int value);
    928 
    929     /**
    930      * Writes the given int to the specified index of this buffer.
    931      * <p>
    932      * The int is converted to bytes using the current byte order. The position
    933      * is not changed.
    934      *
    935      * @param index
    936      *            the index, must not be negative and equal or less than
    937      *            {@code limit - 4}.
    938      * @param value
    939      *            the int to write.
    940      * @return {@code this}
    941      * @exception IndexOutOfBoundsException
    942      *                if {@code index} is invalid.
    943      * @exception ReadOnlyBufferException
    944      *                if no changes may be made to the contents of this buffer.
    945      */
    946     public abstract ByteBuffer putInt(int index, int value);
    947 
    948     /**
    949      * Writes the given long to the current position and increases the position
    950      * by 8.
    951      * <p>
    952      * The long is converted to bytes using the current byte order.
    953      *
    954      * @param value
    955      *            the long to write.
    956      * @return {@code this}
    957      * @exception BufferOverflowException
    958      *                if position is greater than {@code limit - 8}.
    959      * @exception ReadOnlyBufferException
    960      *                if no changes may be made to the contents of this buffer.
    961      */
    962     public abstract ByteBuffer putLong(long value);
    963 
    964     /**
    965      * Writes the given long to the specified index of this buffer.
    966      * <p>
    967      * The long is converted to bytes using the current byte order. The position
    968      * is not changed.
    969      *
    970      * @param index
    971      *            the index, must not be negative and equal or less than
    972      *            {@code limit - 8}.
    973      * @param value
    974      *            the long to write.
    975      * @return {@code this}
    976      * @exception IndexOutOfBoundsException
    977      *                if {@code index} is invalid.
    978      * @exception ReadOnlyBufferException
    979      *                if no changes may be made to the contents of this buffer.
    980      */
    981     public abstract ByteBuffer putLong(int index, long value);
    982 
    983     /**
    984      * Writes the given short to the current position and increases the position
    985      * by 2.
    986      * <p>
    987      * The short is converted to bytes using the current byte order.
    988      *
    989      * @param value
    990      *            the short to write.
    991      * @return {@code this}
    992      * @exception BufferOverflowException
    993      *                if position is greater than {@code limit - 2}.
    994      * @exception ReadOnlyBufferException
    995      *                if no changes may be made to the contents of this buffer.
    996      */
    997     public abstract ByteBuffer putShort(short value);
    998 
    999     /**
   1000      * Writes the given short to the specified index of this buffer.
   1001      * <p>
   1002      * The short is converted to bytes using the current byte order. The
   1003      * position is not changed.
   1004      *
   1005      * @param index
   1006      *            the index, must not be negative and equal or less than
   1007      *            {@code limit - 2}.
   1008      * @param value
   1009      *            the short to write.
   1010      * @return {@code this}
   1011      * @exception IndexOutOfBoundsException
   1012      *                if {@code index} is invalid.
   1013      * @exception ReadOnlyBufferException
   1014      *                if no changes may be made to the contents of this buffer.
   1015      */
   1016     public abstract ByteBuffer putShort(int index, short value);
   1017 
   1018     /**
   1019      * Returns a sliced buffer that shares its content with this buffer.
   1020      * <p>
   1021      * The sliced buffer's capacity will be this buffer's
   1022      * {@code remaining()}, and it's zero position will correspond to
   1023      * this buffer's current position. The new buffer's position will be 0,
   1024      * limit will be its capacity, and its mark is cleared. The new buffer's
   1025      * read-only property and byte order are the same as this buffer's.
   1026      * <p>
   1027      * The new buffer shares its content with this buffer, which means either
   1028      * buffer's change of content will be visible to the other. The two buffer's
   1029      * position, limit and mark are independent.
   1030      *
   1031      * @return a sliced buffer that shares its content with this buffer.
   1032      */
   1033     public abstract ByteBuffer slice();
   1034 }
   1035