ByteBuffer.java revision 934767b07d94041390785d8fe66c86b2379730bc
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        return orderImpl(byteOrder);
656    }
657
658    ByteBuffer orderImpl(ByteOrder byteOrder) {
659        if (byteOrder == null) {
660            byteOrder = ByteOrder.LITTLE_ENDIAN;
661        }
662        order = byteOrder;
663        return this;
664    }
665
666    /**
667     * Child class implements this method to realize {@code array()}.
668     *
669     * @see #array()
670     */
671    abstract byte[] protectedArray();
672
673    /**
674     * Child class implements this method to realize {@code arrayOffset()}.
675     *
676     * @see #arrayOffset()
677     */
678    abstract int protectedArrayOffset();
679
680    /**
681     * Child class implements this method to realize {@code hasArray()}.
682     *
683     * @see #hasArray()
684     */
685    abstract boolean protectedHasArray();
686
687    /**
688     * Writes the given byte to the current position and increases the position
689     * by 1.
690     *
691     * @param b
692     *            the byte to write.
693     * @return this buffer.
694     * @exception BufferOverflowException
695     *                if position is equal or greater than limit.
696     * @exception ReadOnlyBufferException
697     *                if no changes may be made to the contents of this buffer.
698     */
699    public abstract ByteBuffer put(byte b);
700
701    /**
702     * Writes bytes in the given byte array to the current position and
703     * increases the position by the number of bytes written.
704     * <p>
705     * Calling this method has the same effect as
706     * {@code put(src, 0, src.length)}.
707     *
708     * @param src
709     *            the source byte array.
710     * @return this buffer.
711     * @exception BufferOverflowException
712     *                if {@code remaining()} is less than {@code src.length}.
713     * @exception ReadOnlyBufferException
714     *                if no changes may be made to the contents of this buffer.
715     */
716    public final ByteBuffer put(byte[] src) {
717        return put(src, 0, src.length);
718    }
719
720    /**
721     * Writes bytes in the given byte array, starting from the specified offset,
722     * to the current position and increases the position by the number of bytes
723     * written.
724     *
725     * @param src
726     *            the source byte array.
727     * @param off
728     *            the offset of byte array, must not be negative and not greater
729     *            than {@code src.length}.
730     * @param len
731     *            the number of bytes to write, must not be negative and not
732     *            greater than {@code src.length - off}.
733     * @return this buffer.
734     * @exception BufferOverflowException
735     *                if {@code remaining()} is less than {@code len}.
736     * @exception IndexOutOfBoundsException
737     *                if either {@code off} or {@code len} is invalid.
738     * @exception ReadOnlyBufferException
739     *                if no changes may be made to the contents of this buffer.
740     */
741    public ByteBuffer put(byte[] src, int off, int len) {
742        int length = src.length;
743        if ((off < 0 ) || (len < 0) || ((long)off + (long)len > length)) {
744            throw new IndexOutOfBoundsException();
745        }
746
747        if (len > remaining()) {
748            throw new BufferOverflowException();
749        }
750        for (int i = off; i < off + len; i++) {
751            put(src[i]);
752        }
753        return this;
754    }
755
756    /**
757     * Writes all the remaining bytes of the {@code src} byte buffer to this
758     * buffer's current position, and increases both buffers' position by the
759     * number of bytes copied.
760     *
761     * @param src
762     *            the source byte buffer.
763     * @return this buffer.
764     * @exception BufferOverflowException
765     *                if {@code src.remaining()} is greater than this buffer's
766     *                {@code remaining()}.
767     * @exception IllegalArgumentException
768     *                if {@code src} is this buffer.
769     * @exception ReadOnlyBufferException
770     *                if no changes may be made to the contents of this buffer.
771     */
772    public ByteBuffer put(ByteBuffer src) {
773        if (src == this) {
774            throw new IllegalArgumentException();
775        }
776        if (src.remaining() > remaining()) {
777            throw new BufferOverflowException();
778        }
779        byte[] contents = new byte[src.remaining()];
780        src.get(contents);
781        put(contents);
782        return this;
783    }
784
785    /**
786     * Write a byte to the specified index of this buffer without changing the
787     * position.
788     *
789     * @param index
790     *            the index, must not be negative and less than the limit.
791     * @param b
792     *            the byte to write.
793     * @return this buffer.
794     * @exception IndexOutOfBoundsException
795     *                if {@code index} is invalid.
796     * @exception ReadOnlyBufferException
797     *                if no changes may be made to the contents of this buffer.
798     */
799    public abstract ByteBuffer put(int index, byte b);
800
801    /**
802     * Writes the given char to the current position and increases the position
803     * by 2.
804     * <p>
805     * The char is converted to bytes using the current byte order.
806     *
807     * @param value
808     *            the char to write.
809     * @return this buffer.
810     * @exception BufferOverflowException
811     *                if position is greater than {@code limit - 2}.
812     * @exception ReadOnlyBufferException
813     *                if no changes may be made to the contents of this buffer.
814     */
815    public abstract ByteBuffer putChar(char value);
816
817    /**
818     * Writes the given char to the specified index of this buffer.
819     * <p>
820     * The char is converted to bytes using the current byte order. The position
821     * is not changed.
822     *
823     * @param index
824     *            the index, must not be negative and equal or less than
825     *            {@code limit - 2}.
826     * @param value
827     *            the char to write.
828     * @return this buffer.
829     * @exception IndexOutOfBoundsException
830     *                if {@code index} is invalid.
831     * @exception ReadOnlyBufferException
832     *                if no changes may be made to the contents of this buffer.
833     */
834    public abstract ByteBuffer putChar(int index, char value);
835
836    /**
837     * Writes the given double to the current position and increases the position
838     * by 8.
839     * <p>
840     * The double is converted to bytes using the current byte order.
841     *
842     * @param value
843     *            the double to write.
844     * @return this buffer.
845     * @exception BufferOverflowException
846     *                if position is greater than {@code limit - 8}.
847     * @exception ReadOnlyBufferException
848     *                if no changes may be made to the contents of this buffer.
849     */
850    public abstract ByteBuffer putDouble(double value);
851
852    /**
853     * Writes the given double to the specified index of this buffer.
854     * <p>
855     * The double is converted to bytes using the current byte order. The
856     * position is not changed.
857     *
858     * @param index
859     *            the index, must not be negative and equal or less than
860     *            {@code limit - 8}.
861     * @param value
862     *            the double to write.
863     * @return this buffer.
864     * @exception IndexOutOfBoundsException
865     *                if {@code index} is invalid.
866     * @exception ReadOnlyBufferException
867     *                if no changes may be made to the contents of this buffer.
868     */
869    public abstract ByteBuffer putDouble(int index, double value);
870
871    /**
872     * Writes the given float to the current position and increases the position
873     * by 4.
874     * <p>
875     * The float is converted to bytes using the current byte order.
876     *
877     * @param value
878     *            the float to write.
879     * @return this buffer.
880     * @exception BufferOverflowException
881     *                if position is greater than {@code limit - 4}.
882     * @exception ReadOnlyBufferException
883     *                if no changes may be made to the contents of this buffer.
884     */
885    public abstract ByteBuffer putFloat(float value);
886
887    /**
888     * Writes the given float to the specified index of this buffer.
889     * <p>
890     * The float is converted to bytes using the current byte order. The
891     * position is not changed.
892     *
893     * @param index
894     *            the index, must not be negative and equal or less than
895     *            {@code limit - 4}.
896     * @param value
897     *            the float to write.
898     * @return this buffer.
899     * @exception IndexOutOfBoundsException
900     *                if {@code index} is invalid.
901     * @exception ReadOnlyBufferException
902     *                if no changes may be made to the contents of this buffer.
903     */
904    public abstract ByteBuffer putFloat(int index, float value);
905
906    /**
907     * Writes the given int to the current position and increases the position by
908     * 4.
909     * <p>
910     * The int is converted to bytes using the current byte order.
911     *
912     * @param value
913     *            the int to write.
914     * @return this buffer.
915     * @exception BufferOverflowException
916     *                if position is greater than {@code limit - 4}.
917     * @exception ReadOnlyBufferException
918     *                if no changes may be made to the contents of this buffer.
919     */
920    public abstract ByteBuffer putInt(int value);
921
922    /**
923     * Writes the given int to the specified index of this buffer.
924     * <p>
925     * The int is converted to bytes using the current byte order. The position
926     * is not changed.
927     *
928     * @param index
929     *            the index, must not be negative and equal or less than
930     *            {@code limit - 4}.
931     * @param value
932     *            the int to write.
933     * @return this buffer.
934     * @exception IndexOutOfBoundsException
935     *                if {@code index} is invalid.
936     * @exception ReadOnlyBufferException
937     *                if no changes may be made to the contents of this buffer.
938     */
939    public abstract ByteBuffer putInt(int index, int value);
940
941    /**
942     * Writes the given long to the current position and increases the position
943     * by 8.
944     * <p>
945     * The long is converted to bytes using the current byte order.
946     *
947     * @param value
948     *            the long to write.
949     * @return this buffer.
950     * @exception BufferOverflowException
951     *                if position is greater than {@code limit - 8}.
952     * @exception ReadOnlyBufferException
953     *                if no changes may be made to the contents of this buffer.
954     */
955    public abstract ByteBuffer putLong(long value);
956
957    /**
958     * Writes the given long to the specified index of this buffer.
959     * <p>
960     * The long is converted to bytes using the current byte order. The position
961     * is not changed.
962     *
963     * @param index
964     *            the index, must not be negative and equal or less than
965     *            {@code limit - 8}.
966     * @param value
967     *            the long to write.
968     * @return this buffer.
969     * @exception IndexOutOfBoundsException
970     *                if {@code index} is invalid.
971     * @exception ReadOnlyBufferException
972     *                if no changes may be made to the contents of this buffer.
973     */
974    public abstract ByteBuffer putLong(int index, long value);
975
976    /**
977     * Writes the given short to the current position and increases the position
978     * by 2.
979     * <p>
980     * The short is converted to bytes using the current byte order.
981     *
982     * @param value
983     *            the short to write.
984     * @return this buffer.
985     * @exception BufferOverflowException
986     *                if position is greater than {@code limit - 2}.
987     * @exception ReadOnlyBufferException
988     *                if no changes may be made to the contents of this buffer.
989     */
990    public abstract ByteBuffer putShort(short value);
991
992    /**
993     * Writes the given short to the specified index of this buffer.
994     * <p>
995     * The short is converted to bytes using the current byte order. The
996     * position is not changed.
997     *
998     * @param index
999     *            the index, must not be negative and equal or less than
1000     *            {@code limit - 2}.
1001     * @param value
1002     *            the short to write.
1003     * @return this buffer.
1004     * @exception IndexOutOfBoundsException
1005     *                if {@code index} is invalid.
1006     * @exception ReadOnlyBufferException
1007     *                if no changes may be made to the contents of this buffer.
1008     */
1009    public abstract ByteBuffer putShort(int index, short value);
1010
1011    /**
1012     * Returns a sliced buffer that shares its content with this buffer.
1013     * <p>
1014     * The sliced buffer's capacity will be this buffer's
1015     * {@code remaining()}, and it's zero position will correspond to
1016     * this buffer's current position. The new buffer's position will be 0,
1017     * limit will be its capacity, and its mark is cleared. The new buffer's
1018     * read-only property and byte order are the same as this buffer's.
1019     * <p>
1020     * The new buffer shares its content with this buffer, which means either
1021     * buffer's change of content will be visible to the other. The two buffer's
1022     * position, limit and mark are independent.
1023     *
1024     * @return a sliced buffer that shares its content with this buffer.
1025     */
1026    public abstract ByteBuffer slice();
1027
1028    /**
1029     * Returns a string representing the state of this byte buffer.
1030     *
1031     * @return a string representing the state of this byte buffer.
1032     */
1033    @Override
1034    public String toString() {
1035        StringBuilder buf = new StringBuilder();
1036        buf.append(getClass().getName());
1037        buf.append(", status: capacity=");
1038        buf.append(capacity());
1039        buf.append(" position=");
1040        buf.append(position());
1041        buf.append(" limit=");
1042        buf.append(limit());
1043        return buf.toString();
1044    }
1045}
1046