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