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