ByteBuffer.java revision 0568a63ba1086a78ffb4cff68dd2eac4f9908e13
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
18package java.nio;
19
20import java.util.Arrays;
21import 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 */
37public 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();
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();
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