View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.common;
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.nio.BufferOverflowException;
26  import java.nio.ByteBuffer;
27  import java.nio.ByteOrder;
28  import java.nio.CharBuffer;
29  import java.nio.DoubleBuffer;
30  import java.nio.FloatBuffer;
31  import java.nio.IntBuffer;
32  import java.nio.LongBuffer;
33  import java.nio.ReadOnlyBufferException;
34  import java.nio.ShortBuffer;
35  import java.nio.charset.CharacterCodingException;
36  import java.nio.charset.CharsetDecoder;
37  import java.nio.charset.CharsetEncoder;
38  import java.util.EnumSet;
39  import java.util.HashSet;
40  import java.util.Set;
41  
42  /**
43   * A byte buffer used by MINA applications.
44   * <p>
45   * This is a replacement for {@link ByteBuffer}. Please refer to
46   * {@link ByteBuffer} documentation for preliminary usage.  MINA does
47   * not use NIO {@link ByteBuffer} directly for two reasons:
48   * <ul>
49   * <li>It doesn't provide useful getters and putters such as
50   * <code>fill</code>, <code>get/putString</code>, and
51   * <code>get/putAsciiInt()</code> enough.</li>
52   * <li>It is difficult to write variable-length data due to its fixed
53   * capacity</li>
54   * </ul>
55   * </p>
56   *
57   * <h2>Allocation</h2>
58   * <p>
59   * You can allocate a new heap buffer.
60   * <pre>
61   * IoBuffer buf = IoBuffer.allocate(1024, false);
62   * </pre>
63   * you can also allocate a new direct buffer:
64   * <pre>
65   * IoBuffer buf = IoBuffer.allocate(1024, true);
66   * </pre>
67   * or you can set the default buffer type.
68   * <pre>
69   * // Allocate heap buffer by default.
70   * IoBuffer.setUseDirectBuffer(false);
71   * // A new heap buffer is returned.
72   * IoBuffer buf = IoBuffer.allocate(1024);
73   * </pre>
74   * </p>
75   *
76   * <h2>Wrapping existing NIO buffers and arrays</h2>
77   * <p>
78   * This class provides a few <tt>wrap(...)</tt> methods that wraps
79   * any NIO buffers and byte arrays.
80   *
81   * <h2>AutoExpand</h2>
82   * <p>
83   * Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really
84   * easy, and it is because its size is fixed.  {@link IoBuffer} introduces 
85   * <tt>autoExpand</tt> property.  If <tt>autoExpand</tt> property is true, you
86   * never get {@link BufferOverflowException} or
87   * {@link IndexOutOfBoundsException} (except when index is negative).
88   * It automatically expands its capacity and limit value.  For example:
89   * <pre>
90   * String greeting = messageBundle.getMessage( "hello" );
91   * IoBuffer buf = IoBuffer.allocate( 16 );
92   * // Turn on autoExpand (it is off by default)
93   * buf.setAutoExpand( true );
94   * buf.putString( greeting, utf8encoder );
95   * </pre>
96   * The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind
97   * the scene if the encoded data is larger than 16 bytes in the example above.
98   * Its capacity will double, and its limit will increase to the last position
99   * the string is written.
100  * </p>
101  * 
102  * <h2>AutoShrink</h2>
103  * <p>
104  * You might also want to decrease the capacity of the buffer when most
105  * of the allocated memory area is not being used.  {@link IoBuffer} provides
106  * <tt>autoShrink</tt> property to take care of this issue.  If 
107  * <tt>autoShrink</tt> is turned on, {@link IoBuffer} halves the capacity
108  * of the buffer when {@link #compact()} is invoked and only 1/4 or less of
109  * the current capacity is being used.
110  * <p>
111  * You can also {@link #shrink()} method manually to shrink the capacity of
112  * the buffer.
113  * <p> 
114  * The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind
115  * the scene, and therefore {@link #buf()} will return a different
116  * {@link ByteBuffer} instance once capacity changes.  Please also note
117  * {@link #compact()} or {@link #shrink()} will not decrease the capacity if
118  * the new capacity is less than the {@link #minimumCapacity()} of the buffer.
119  *
120  * <h2>Derived Buffers</h2>
121  * <p>
122  * Derived buffers are the buffers which were created by
123  * {@link #duplicate()}, {@link #slice()}, or {@link #asReadOnlyBuffer()}.
124  * They are useful especially when you broadcast the same messages to
125  * multiple {@link IoSession}s.  Please note that the buffer derived from and
126  * its derived buffers are not both auto-expandable neither auto-shrinkable.
127  * Trying to call {@link #setAutoExpand(boolean)} or {@link #setAutoShrink(boolean)}
128  * with <tt>true</tt> parameter will raise an {@link IllegalStateException}.
129  * </p>
130  *
131  * <h2>Changing Buffer Allocation Policy</h2>
132  * <p>
133  * {@link IoBufferAllocator} interface lets you override the default buffer
134  * management behavior.  There are two allocators provided out-of-the-box:
135  * <ul>
136  * <li>{@link SimpleBufferAllocator} (default)</li>
137  * <li>{@link CachedBufferAllocator}</li>
138  * </ul>
139  * You can implement your own allocator and use it by calling
140  * {@link #setAllocator(IoBufferAllocator)}.
141  * </p>
142  *
143  * @author The Apache MINA Project (dev@mina.apache.org)
144  * @version $Rev: 602109 $, $Date: 2007-12-07 07:40:41 -0700 (Fri, 07 Dec 2007) $
145  */
146 public abstract class IoBuffer implements Comparable<IoBuffer> {
147     private static IoBufferAllocator allocator = new SimpleBufferAllocator();
148 
149     private static final IoBuffer EMPTY_DIRECT_BUFFER = allocator.allocate(0,
150             true);
151 
152     private static final IoBuffer EMPTY_HEAP_BUFFER = allocator.allocate(0,
153             false);
154 
155     private static boolean useDirectBuffer = false;
156 
157     /**
158      * An immutable empty buffer.
159      */
160     public static final IoBuffer EMPTY_BUFFER = wrap(new byte[0]);
161 
162     /**
163      * Returns the allocator used by existing and new buffers
164      */
165     public static IoBufferAllocator getAllocator() {
166         return allocator;
167     }
168 
169     /**
170      * Sets the allocator used by existing and new buffers
171      */
172     public static void setAllocator(IoBufferAllocator newAllocator) {
173         if (newAllocator == null) {
174             throw new NullPointerException("allocator");
175         }
176 
177         IoBufferAllocator oldAllocator = allocator;
178 
179         allocator = newAllocator;
180 
181         if (null != oldAllocator) {
182             oldAllocator.dispose();
183         }
184     }
185 
186     /**
187      * Returns <tt>true</tt> if and only if a direct buffer is allocated
188      * by default when the type of the new buffer is not specified.  The
189      * default value is <tt>false</tt>.
190      */
191     public static boolean isUseDirectBuffer() {
192         return useDirectBuffer;
193     }
194 
195     /**
196      * Sets if a direct buffer should be allocated by default when the
197      * type of the new buffer is not specified.  The default value is
198      * <tt>false</tt>.
199      */
200     public static void setUseDirectBuffer(boolean useDirectBuffer) {
201         IoBuffer.useDirectBuffer = useDirectBuffer;
202     }
203 
204     /**
205      * Returns the direct or heap buffer which is capable to store the
206      * specified amount of bytes.
207      *
208      * @param capacity the capacity of the buffer
209      *
210      * @see #setUseDirectBuffer(boolean)
211      */
212     public static IoBuffer allocate(int capacity) {
213         return allocate(capacity, useDirectBuffer);
214     }
215 
216     /**
217      * Returns the buffer which is capable of the specified size.
218      *
219      * @param capacity the capacity of the buffer
220      * @param direct   <tt>true</tt> to get a direct buffer,
221      *                 <tt>false</tt> to get a heap buffer.
222      */
223     public static IoBuffer allocate(int capacity, boolean direct) {
224         if (capacity == 0) {
225             return direct ? EMPTY_DIRECT_BUFFER : EMPTY_HEAP_BUFFER;
226         }
227 
228         if (capacity < 0) {
229             throw new IllegalArgumentException("capacity: " + capacity);
230         }
231 
232         return allocator.allocate(capacity, direct);
233     }
234 
235     /**
236      * Wraps the specified NIO {@link ByteBuffer} into MINA buffer.
237      */
238     public static IoBuffer wrap(ByteBuffer nioBuffer) {
239         return allocator.wrap(nioBuffer);
240     }
241 
242     /**
243      * Wraps the specified byte array into MINA heap buffer.
244      */
245     public static IoBuffer wrap(byte[] byteArray) {
246         return wrap(ByteBuffer.wrap(byteArray));
247     }
248 
249     /**
250      * Wraps the specified byte array into MINA heap buffer.
251      */
252     public static IoBuffer wrap(byte[] byteArray, int offset, int length) {
253         return wrap(ByteBuffer.wrap(byteArray, offset, length));
254     }
255 
256     /**
257      * Normalizes the specified capacity of the buffer to power of 2,
258      * which is often helpful for optimal memory usage and performance. 
259      * If it is greater than or equal to {@link Integer#MAX_VALUE}, it
260      * returns {@link Integer#MAX_VALUE}.  If it is zero, it returns zero.
261      */
262     protected static int normalizeCapacity(int requestedCapacity) {
263         switch (requestedCapacity) {
264         case 0:
265         case 1 << 0:
266         case 1 << 1:
267         case 1 << 2:
268         case 1 << 3:
269         case 1 << 4:
270         case 1 << 5:
271         case 1 << 6:
272         case 1 << 7:
273         case 1 << 8:
274         case 1 << 9:
275         case 1 << 10:
276         case 1 << 11:
277         case 1 << 12:
278         case 1 << 13:
279         case 1 << 14:
280         case 1 << 15:
281         case 1 << 16:
282         case 1 << 17:
283         case 1 << 18:
284         case 1 << 19:
285         case 1 << 21:
286         case 1 << 22:
287         case 1 << 23:
288         case 1 << 24:
289         case 1 << 25:
290         case 1 << 26:
291         case 1 << 27:
292         case 1 << 28:
293         case 1 << 29:
294         case 1 << 30:
295         case Integer.MAX_VALUE:
296             return requestedCapacity;
297         }
298 
299         int newCapacity = 1;
300         while (newCapacity < requestedCapacity) {
301             newCapacity <<= 1;
302             if (newCapacity < 0) {
303                 return Integer.MAX_VALUE;
304             }
305         }
306         return newCapacity;
307     }
308     
309     protected static final Set<String> primitiveTypeNames = new HashSet<String>();
310     
311     static {
312         primitiveTypeNames.add("void");
313         primitiveTypeNames.add("boolean");
314         primitiveTypeNames.add("byte");
315         primitiveTypeNames.add("char");
316         primitiveTypeNames.add("short");
317         primitiveTypeNames.add("int");
318         primitiveTypeNames.add("long");
319         primitiveTypeNames.add("float");
320         primitiveTypeNames.add("double");
321     }
322 
323     /**
324      * Creates a new instance.  This is an empty constructor.
325      */
326     protected IoBuffer() {
327     }
328 
329     /**
330      * Declares this buffer and all its derived buffers are not used anymore
331      * so that it can be reused by some {@link IoBufferAllocator} implementations.
332      * It is not mandatory to call this method, but you might want to invoke this
333      * method for maximum performance. 
334      */
335     public abstract void free();
336 
337     /**
338      * Returns the underlying NIO buffer instance.
339      */
340     public abstract ByteBuffer buf();
341 
342     /**
343      * @see ByteBuffer#isDirect()
344      */
345     public abstract boolean isDirect();
346 
347     /**
348      * returns <tt>true</tt> if and only if this buffer is derived from other buffer
349      * via {@link #duplicate()}, {@link #slice()} or {@link #asReadOnlyBuffer()}.
350      */
351     public abstract boolean isDerived();
352 
353     /**
354      * @see ByteBuffer#isReadOnly()
355      */
356     public abstract boolean isReadOnly();
357 
358     /**
359      * Returns the minimum capacity of this buffer which is used to determine
360      * the new capacity of the buffer shrunk by {@link #compact()} and
361      * {@link #shrink()} operation.  The default value is the initial capacity
362      * of the buffer.
363      */
364     public abstract int minimumCapacity();
365 
366     /**
367      * Sets the minimum capacity of this buffer which is used to determine
368      * the new capacity of the buffer shrunk by {@link #compact()} and
369      * {@link #shrink()} operation.  The default value is the initial capacity
370      * of the buffer.
371      */
372     public abstract IoBuffer minimumCapacity(int minimumCapacity);
373 
374     /**
375      * @see ByteBuffer#capacity()
376      */
377     public abstract int capacity();
378 
379     /**
380      * Increases the capacity of this buffer.  If the new capacity is less than
381      * or equal to the current capacity, this method returns silently.  If the
382      * new capacity is greater than the current capacity, the buffer is
383      * reallocated while retaining the position, limit, mark and the content
384      * of the buffer.
385      */
386     public abstract IoBuffer capacity(int newCapacity);
387 
388     /**
389      * Returns <tt>true</tt> if and only if <tt>autoExpand</tt> is turned on.
390      */
391     public abstract boolean isAutoExpand();
392 
393     /**
394      * Turns on or off <tt>autoExpand</tt>.
395      */
396     public abstract IoBuffer setAutoExpand(boolean autoExpand);
397 
398     /**
399      * Returns <tt>true</tt> if and only if <tt>autoShrink</tt> is turned on.
400      */
401     public abstract boolean isAutoShrink();
402 
403     /**
404      * Turns on or off <tt>autoShrink</tt>.
405      */
406     public abstract IoBuffer setAutoShrink(boolean autoShrink);
407 
408     /**
409      * Changes the capacity and limit of this buffer so this buffer get
410      * the specified <tt>expectedRemaining</tt> room from the current position.
411      * This method works even if you didn't set <tt>autoExpand</tt> to
412      * <tt>true</tt>.
413      */
414     public abstract IoBuffer expand(int expectedRemaining);
415 
416     /**
417      * Changes the capacity and limit of this buffer so this buffer get
418      * the specified <tt>expectedRemaining</tt> room from the specified
419      * <tt>position</tt>.
420      * This method works even if you didn't set <tt>autoExpand</tt> to
421      * <tt>true</tt>.
422      */
423     public abstract IoBuffer expand(int position, int expectedRemaining);
424 
425     /**
426      * Changes the capacity of this buffer so this buffer occupies as less
427      * memory as possible while retaining the position, limit and the
428      * buffer content between the position and limit.  The capacity of the
429      * buffer never becomes less than {@link #minimumCapacity()}.
430      * The mark is discarded once the capacity changes.
431      */
432     public abstract IoBuffer shrink();
433 
434     /**
435      * @see java.nio.Buffer#position()
436      */
437     public abstract int position();
438 
439     /**
440      * @see java.nio.Buffer#position(int)
441      */
442     public abstract IoBuffer position(int newPosition);
443 
444     /**
445      * @see java.nio.Buffer#limit()
446      */
447     public abstract int limit();
448 
449     /**
450      * @see java.nio.Buffer#limit(int)
451      */
452     public abstract IoBuffer limit(int newLimit);
453 
454     /**
455      * @see java.nio.Buffer#mark()
456      */
457     public abstract IoBuffer mark();
458 
459     /**
460      * Returns the position of the current mark.  This method returns <tt>-1</tt> if no
461      * mark is set.
462      */
463     public abstract int markValue();
464 
465     /**
466      * @see java.nio.Buffer#reset()
467      */
468     public abstract IoBuffer reset();
469 
470     /**
471      * @see java.nio.Buffer#clear()
472      */
473     public abstract IoBuffer clear();
474 
475     /**
476      * Clears this buffer and fills its content with <tt>NUL</tt>.
477      * The position is set to zero, the limit is set to the capacity,
478      * and the mark is discarded.
479      */
480     public abstract IoBuffer sweep();
481 
482     /**
483      * Clears this buffer and fills its content with <tt>value</tt>.
484      * The position is set to zero, the limit is set to the capacity,
485      * and the mark is discarded.
486      */
487     public abstract IoBuffer sweep(byte value);
488 
489     /**
490      * @see java.nio.Buffer#flip()
491      */
492     public abstract IoBuffer flip();
493 
494     /**
495      * @see java.nio.Buffer#rewind()
496      */
497     public abstract IoBuffer rewind();
498 
499     /**
500      * @see java.nio.Buffer#remaining()
501      */
502     public abstract int remaining();
503 
504     /**
505      * @see java.nio.Buffer#hasRemaining()
506      */
507     public abstract boolean hasRemaining();
508 
509     /**
510      * @see ByteBuffer#duplicate()
511      */
512     public abstract IoBuffer duplicate();
513 
514     /**
515      * @see ByteBuffer#slice()
516      */
517     public abstract IoBuffer slice();
518     
519     /**
520      * @see ByteBuffer#asReadOnlyBuffer()
521      */
522     public abstract IoBuffer asReadOnlyBuffer();
523 
524     /**
525      * @see ByteBuffer#hasArray()
526      */
527     public abstract boolean hasArray();
528 
529     /**
530      * @see ByteBuffer#array()
531      */
532     public abstract byte[] array();
533 
534     /**
535      * @see ByteBuffer#arrayOffset()
536      */
537     public abstract int arrayOffset();
538 
539     /**
540      * @see ByteBuffer#get()
541      */
542     public abstract byte get();
543 
544     /**
545      * Reads one unsigned byte as a short integer.
546      */
547     public abstract short getUnsigned();
548 
549     /**
550      * @see ByteBuffer#put(byte)
551      */
552     public abstract IoBuffer put(byte b);
553 
554     /**
555      * @see ByteBuffer#get(int)
556      */
557     public abstract byte get(int index);
558 
559     /**
560      * Reads one byte as an unsigned short integer.
561      */
562     public abstract short getUnsigned(int index);
563 
564     /**
565      * @see ByteBuffer#put(int, byte)
566      */
567     public abstract IoBuffer put(int index, byte b);
568 
569     /**
570      * @see ByteBuffer#get(byte[], int, int)
571      */
572     public abstract IoBuffer get(byte[] dst, int offset, int length);
573 
574     /**
575      * @see ByteBuffer#get(byte[])
576      */
577     public abstract IoBuffer get(byte[] dst);
578 
579     /**
580      * TODO document me.
581      */
582     public abstract IoBuffer getSlice(int index, int length);
583 
584     /**
585      * TODO document me.
586      */
587     public abstract IoBuffer getSlice(int length);
588 
589     /**
590      * Writes the content of the specified <tt>src</tt> into this buffer.
591      */
592     public abstract IoBuffer put(ByteBuffer src);
593 
594     /**
595      * Writes the content of the specified <tt>src</tt> into this buffer.
596      */
597     public abstract IoBuffer put(IoBuffer src);
598 
599     /**
600      * @see ByteBuffer#put(byte[], int, int)
601      */
602     public abstract IoBuffer put(byte[] src, int offset, int length);
603 
604     /**
605      * @see ByteBuffer#put(byte[])
606      */
607     public abstract IoBuffer put(byte[] src);
608 
609     /**
610      * @see ByteBuffer#compact()
611      */
612     public abstract IoBuffer compact();
613 
614     /**
615      * @see ByteBuffer#order()
616      */
617     public abstract ByteOrder order();
618 
619     /**
620      * @see ByteBuffer#order(ByteOrder)
621      */
622     public abstract IoBuffer order(ByteOrder bo);
623 
624     /**
625      * @see ByteBuffer#getChar()
626      */
627     public abstract char getChar();
628 
629     /**
630      * @see ByteBuffer#putChar(char)
631      */
632     public abstract IoBuffer putChar(char value);
633 
634     /**
635      * @see ByteBuffer#getChar(int)
636      */
637     public abstract char getChar(int index);
638 
639     /**
640      * @see ByteBuffer#putChar(int, char)
641      */
642     public abstract IoBuffer putChar(int index, char value);
643 
644     /**
645      * @see ByteBuffer#asCharBuffer()
646      */
647     public abstract CharBuffer asCharBuffer();
648 
649     /**
650      * @see ByteBuffer#getShort()
651      */
652     public abstract short getShort();
653 
654     /**
655      * Reads two bytes unsigned integer.
656      */
657     public abstract int getUnsignedShort();
658 
659     /**
660      * @see ByteBuffer#putShort(short)
661      */
662     public abstract IoBuffer putShort(short value);
663 
664     /**
665      * @see ByteBuffer#getShort()
666      */
667     public abstract short getShort(int index);
668 
669     /**
670      * Reads two bytes unsigned integer.
671      */
672     public abstract int getUnsignedShort(int index);
673 
674     /**
675      * @see ByteBuffer#putShort(int, short)
676      */
677     public abstract IoBuffer putShort(int index, short value);
678 
679     /**
680      * @see ByteBuffer#asShortBuffer()
681      */
682     public abstract ShortBuffer asShortBuffer();
683 
684     /**
685      * @see ByteBuffer#getInt()
686      */
687     public abstract int getInt();
688 
689     /**
690      * Reads four bytes unsigned integer.
691      */
692     public abstract long getUnsignedInt();
693 
694     /**
695      * Relative <i>get</i> method for reading a medium int value.
696      *
697      * <p> Reads the next three bytes at this buffer's current position,
698      * composing them into an int value according to the current byte order,
699      * and then increments the position by three.</p>
700      *
701      * @return  The medium int value at the buffer's current position
702      */
703     public abstract int getMediumInt();
704 
705     /**
706      * Relative <i>get</i> method for reading an unsigned medium int value.
707      *
708      * <p> Reads the next three bytes at this buffer's current position,
709      * composing them into an int value according to the current byte order,
710      * and then increments the position by three.</p>
711      *
712      * @return  The unsigned medium int value at the buffer's current position
713      */
714     public abstract int getUnsignedMediumInt();
715 
716     /**
717      * Absolute <i>get</i> method for reading a medium int value.
718      *
719      * <p> Reads the next three bytes at this buffer's current position,
720      * composing them into an int value according to the current byte order.</p>
721      *
722      * @param index  The index from which the medium int will be read
723      * @return  The medium int value at the given index
724      *
725      * @throws  IndexOutOfBoundsException
726      *          If <tt>index</tt> is negative
727      *          or not smaller than the buffer's limit
728      */
729     public abstract int getMediumInt(int index);
730 
731     /**
732      * Absolute <i>get</i> method for reading an unsigned medium int value.
733      *
734      * <p> Reads the next three bytes at this buffer's current position,
735      * composing them into an int value according to the current byte order.</p>
736      *
737      * @param index  The index from which the unsigned medium int will be read
738      * @return  The unsigned medium int value at the given index
739      *
740      * @throws  IndexOutOfBoundsException
741      *          If <tt>index</tt> is negative
742      *          or not smaller than the buffer's limit
743      */
744     public abstract int getUnsignedMediumInt(int index);
745 
746     /**
747      * Relative <i>put</i> method for writing a medium int
748      * value.
749      *
750      * <p> Writes three bytes containing the given int value, in the
751      * current byte order, into this buffer at the current position, and then
752      * increments the position by three.</p>
753      *
754      * @param  value
755      *         The medium int value to be written
756      *
757      * @return  This buffer
758      *
759      * @throws  BufferOverflowException
760      *          If there are fewer than three bytes
761      *          remaining in this buffer
762      *
763      * @throws  ReadOnlyBufferException
764      *          If this buffer is read-only
765      */
766     public abstract IoBuffer putMediumInt(int value);
767 
768     /**
769      * Absolute <i>put</i> method for writing a medium int
770      * value.
771      *
772      * <p> Writes three bytes containing the given int value, in the
773      * current byte order, into this buffer at the given index.</p>
774      *
775      * @param  index
776      *         The index at which the bytes will be written
777      *
778      * @param  value
779      *         The medium int value to be written
780      *
781      * @return  This buffer
782      *
783      * @throws  IndexOutOfBoundsException
784      *          If <tt>index</tt> is negative
785      *          or not smaller than the buffer's limit,
786      *          minus three
787      *
788      * @throws  ReadOnlyBufferException
789      *          If this buffer is read-only
790      */
791     public abstract IoBuffer putMediumInt(int index, int value);
792 
793     /**
794      * @see ByteBuffer#putInt(int)
795      */
796     public abstract IoBuffer putInt(int value);
797 
798     /**
799      * @see ByteBuffer#getInt(int)
800      */
801     public abstract int getInt(int index);
802 
803     /**
804      * Reads four bytes unsigned integer.
805      */
806     public abstract long getUnsignedInt(int index);
807 
808     /**
809      * @see ByteBuffer#putInt(int, int)
810      */
811     public abstract IoBuffer putInt(int index, int value);
812 
813     /**
814      * @see ByteBuffer#asIntBuffer()
815      */
816     public abstract IntBuffer asIntBuffer();
817 
818     /**
819      * @see ByteBuffer#getLong()
820      */
821     public abstract long getLong();
822 
823     /**
824      * @see ByteBuffer#putLong(int, long)
825      */
826     public abstract IoBuffer putLong(long value);
827 
828     /**
829      * @see ByteBuffer#getLong(int)
830      */
831     public abstract long getLong(int index);
832 
833     /**
834      * @see ByteBuffer#putLong(int, long)
835      */
836     public abstract IoBuffer putLong(int index, long value);
837 
838     /**
839      * @see ByteBuffer#asLongBuffer()
840      */
841     public abstract LongBuffer asLongBuffer();
842 
843     /**
844      * @see ByteBuffer#getFloat()
845      */
846     public abstract float getFloat();
847 
848     /**
849      * @see ByteBuffer#putFloat(float)
850      */
851     public abstract IoBuffer putFloat(float value);
852 
853     /**
854      * @see ByteBuffer#getFloat(int)
855      */
856     public abstract float getFloat(int index);
857 
858     /**
859      * @see ByteBuffer#putFloat(int, float)
860      */
861     public abstract IoBuffer putFloat(int index, float value);
862 
863     /**
864      * @see ByteBuffer#asFloatBuffer()
865      */
866     public abstract FloatBuffer asFloatBuffer();
867 
868     /**
869      * @see ByteBuffer#getDouble()
870      */
871     public abstract double getDouble();
872 
873     /**
874      * @see ByteBuffer#putDouble(double)
875      */
876     public abstract IoBuffer putDouble(double value);
877 
878     /**
879      * @see ByteBuffer#getDouble(int)
880      */
881     public abstract double getDouble(int index);
882 
883     /**
884      * @see ByteBuffer#putDouble(int, double)
885      */
886     public abstract IoBuffer putDouble(int index, double value);
887 
888     /**
889      * @see ByteBuffer#asDoubleBuffer()
890      */
891     public abstract DoubleBuffer asDoubleBuffer();
892 
893     /**
894      * Returns an {@link InputStream} that reads the data from this buffer.
895      * {@link InputStream#read()} returns <tt>-1</tt> if the buffer position
896      * reaches to the limit.
897      */
898     public abstract InputStream asInputStream();
899 
900     /**
901      * Returns an {@link OutputStream} that appends the data into this buffer.
902      * Please note that the {@link OutputStream#write(int)} will throw a
903      * {@link BufferOverflowException} instead of an {@link IOException}
904      * in case of buffer overflow.  Please set <tt>autoExpand</tt> property by
905      * calling {@link #setAutoExpand(boolean)} to prevent the unexpected runtime
906      * exception.
907      */
908     public abstract OutputStream asOutputStream();
909 
910     /**
911      * Returns hexdump of this buffer.  The data and pointer are
912      * not changed as a result of this method call.
913      *
914      * @return
915      *  hexidecimal representation of this buffer
916      */
917     public abstract String getHexDump();
918 
919     /**
920      * Return hexdump of this buffer with limited length.
921      *
922      * @param lengthLimit The maximum number of bytes to dump from
923      *                    the current buffer position.
924      * @return
925      *  hexidecimal representation of this buffer
926      */
927     public abstract String getHexDump(int lengthLimit);
928 
929     ////////////////////////////////
930     // String getters and putters //
931     ////////////////////////////////
932 
933     /**
934      * Reads a <code>NUL</code>-terminated string from this buffer using the
935      * specified <code>decoder</code> and returns it.  This method reads
936      * until the limit of this buffer if no <tt>NUL</tt> is found.
937      */
938     public abstract String getString(CharsetDecoder decoder)
939             throws CharacterCodingException;
940 
941     /**
942      * Reads a <code>NUL</code>-terminated string from this buffer using the
943      * specified <code>decoder</code> and returns it.
944      *
945      * @param fieldSize the maximum number of bytes to read
946      */
947     public abstract String getString(int fieldSize, CharsetDecoder decoder)
948             throws CharacterCodingException;
949 
950     /**
951      * Writes the content of <code>in</code> into this buffer using the
952      * specified <code>encoder</code>.  This method doesn't terminate
953      * string with <tt>NUL</tt>.  You have to do it by yourself.
954      *
955      * @throws BufferOverflowException if the specified string doesn't fit
956      */
957     public abstract IoBuffer putString(CharSequence val, CharsetEncoder encoder)
958             throws CharacterCodingException;
959 
960     /**
961      * Writes the content of <code>in</code> into this buffer as a
962      * <code>NUL</code>-terminated string using the specified
963      * <code>encoder</code>.
964      * <p>
965      * If the charset name of the encoder is UTF-16, you cannot specify
966      * odd <code>fieldSize</code>, and this method will append two
967      * <code>NUL</code>s as a terminator.
968      * <p>
969      * Please note that this method doesn't terminate with <code>NUL</code>
970      * if the input string is longer than <tt>fieldSize</tt>.
971      *
972      * @param fieldSize the maximum number of bytes to write
973      */
974     public abstract IoBuffer putString(CharSequence val, int fieldSize,
975             CharsetEncoder encoder) throws CharacterCodingException;
976 
977     /**
978      * Reads a string which has a 16-bit length field before the actual
979      * encoded string, using the specified <code>decoder</code> and returns it.
980      * This method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>.
981      */
982     public abstract String getPrefixedString(CharsetDecoder decoder)
983             throws CharacterCodingException;
984 
985     /**
986      * Reads a string which has a length field before the actual
987      * encoded string, using the specified <code>decoder</code> and returns it.
988      *
989      * @param prefixLength the length of the length field (1, 2, or 4)
990      */
991     public abstract String getPrefixedString(int prefixLength, CharsetDecoder decoder)
992             throws CharacterCodingException;
993 
994     /**
995      * Writes the content of <code>in</code> into this buffer as a
996      * string which has a 16-bit length field before the actual
997      * encoded string, using the specified <code>encoder</code>.
998      * This method is a shortcut for <tt>putPrefixedString(in, 2, 0, encoder)</tt>.
999      *
1000      * @throws BufferOverflowException if the specified string doesn't fit
1001      */
1002     public abstract IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder)
1003             throws CharacterCodingException;
1004 
1005     /**
1006      * Writes the content of <code>in</code> into this buffer as a
1007      * string which has a 16-bit length field before the actual
1008      * encoded string, using the specified <code>encoder</code>.
1009      * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>.
1010      *
1011      * @param prefixLength the length of the length field (1, 2, or 4)
1012      *
1013      * @throws BufferOverflowException if the specified string doesn't fit
1014      */
1015     public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength,
1016             CharsetEncoder encoder) throws CharacterCodingException;
1017 
1018     /**
1019      * Writes the content of <code>in</code> into this buffer as a
1020      * string which has a 16-bit length field before the actual
1021      * encoded string, using the specified <code>encoder</code>.
1022      * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt>.
1023      *
1024      * @param prefixLength the length of the length field (1, 2, or 4)
1025      * @param padding      the number of padded <tt>NUL</tt>s (1 (or 0), 2, or 4)
1026      *
1027      * @throws BufferOverflowException if the specified string doesn't fit
1028      */
1029     public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength,
1030             int padding, CharsetEncoder encoder)
1031             throws CharacterCodingException;
1032 
1033     /**
1034      * Writes the content of <code>in</code> into this buffer as a
1035      * string which has a 16-bit length field before the actual
1036      * encoded string, using the specified <code>encoder</code>.
1037      *
1038      * @param prefixLength the length of the length field (1, 2, or 4)
1039      * @param padding      the number of padded bytes (1 (or 0), 2, or 4)
1040      * @param padValue     the value of padded bytes
1041      *
1042      * @throws BufferOverflowException if the specified string doesn't fit
1043      */
1044     public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength,
1045             int padding, byte padValue, CharsetEncoder encoder)
1046             throws CharacterCodingException;
1047 
1048     /**
1049      * Reads a Java object from the buffer using the context {@link ClassLoader}
1050      * of the current thread.
1051      */
1052     public abstract Object getObject() throws ClassNotFoundException;
1053 
1054     /**
1055      * Reads a Java object from the buffer using the specified <tt>classLoader</tt>.
1056      */
1057     public abstract Object getObject(final ClassLoader classLoader)
1058             throws ClassNotFoundException;
1059 
1060     /**
1061      * Writes the specified Java object to the buffer.
1062      */
1063     public abstract IoBuffer putObject(Object o);
1064 
1065     /**
1066      * Returns <tt>true</tt> if this buffer contains a data which has a data
1067      * length as a prefix and the buffer has remaining data as enough as
1068      * specified in the data length field.  This method is identical with
1069      * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>.
1070      * Please not that using this method can allow DoS (Denial of Service)
1071      * attack in case the remote peer sends too big data length value.
1072      * It is recommended to use {@link #prefixedDataAvailable(int, int)}
1073      * instead.
1074      *
1075      * @param prefixLength the length of the prefix field (1, 2, or 4)
1076      *
1077      * @throws IllegalArgumentException if prefixLength is wrong
1078      * @throws BufferDataException      if data length is negative
1079      */
1080     public abstract boolean prefixedDataAvailable(int prefixLength);
1081 
1082     /**
1083      * Returns <tt>true</tt> if this buffer contains a data which has a data
1084      * length as a prefix and the buffer has remaining data as enough as
1085      * specified in the data length field.
1086      *
1087      * @param prefixLength  the length of the prefix field (1, 2, or 4)
1088      * @param maxDataLength the allowed maximum of the read data length
1089      *
1090      * @throws IllegalArgumentException if prefixLength is wrong
1091      * @throws BufferDataException      if data length is negative or greater then <tt>maxDataLength</tt>
1092      */
1093     public abstract boolean prefixedDataAvailable(int prefixLength, int maxDataLength);
1094 
1095     /////////////////////
1096     // IndexOf methods //
1097     /////////////////////
1098 
1099     /**
1100      * Returns the first occurence position of the specified byte from the current position to
1101      * the current limit.
1102      *
1103      * @return <tt>-1</tt> if the specified byte is not found
1104      */
1105     public abstract int indexOf(byte b);
1106 
1107     //////////////////////////
1108     // Skip or fill methods //
1109     //////////////////////////
1110 
1111     /**
1112      * Forwards the position of this buffer as the specified <code>size</code>
1113      * bytes.
1114      */
1115     public abstract IoBuffer skip(int size);
1116 
1117     /**
1118      * Fills this buffer with the specified value.
1119      * This method moves buffer position forward.
1120      */
1121     public abstract IoBuffer fill(byte value, int size);
1122 
1123     /**
1124      * Fills this buffer with the specified value.
1125      * This method does not change buffer position.
1126      */
1127     public abstract IoBuffer fillAndReset(byte value, int size);
1128 
1129     /**
1130      * Fills this buffer with <code>NUL (0x00)</code>.
1131      * This method moves buffer position forward.
1132      */
1133     public abstract IoBuffer fill(int size);
1134 
1135     /**
1136      * Fills this buffer with <code>NUL (0x00)</code>.
1137      * This method does not change buffer position.
1138      */
1139     public abstract IoBuffer fillAndReset(int size);
1140 
1141     //////////////////////////
1142     // Enum methods         //
1143     //////////////////////////
1144 
1145     /**
1146      * Reads a byte from the buffer and returns the correlating enum constant defined
1147      * by the specified enum type.
1148      *
1149      * @param <E> The enum type to return
1150      * @param enumClass  The enum's class object
1151      */
1152     public abstract <E extends Enum<E>> E getEnum(Class<E> enumClass);
1153 
1154     /**
1155      * Reads a byte from the buffer and returns the correlating enum constant defined
1156      * by the specified enum type.
1157      *
1158      * @param <E> The enum type to return
1159      * @param index  the index from which the byte will be read
1160      * @param enumClass  The enum's class object
1161      */
1162     public abstract <E extends Enum<E>> E getEnum(int index, Class<E> enumClass);
1163 
1164     /**
1165      * Reads a short from the buffer and returns the correlating enum constant defined
1166      * by the specified enum type.
1167      *
1168      * @param <E> The enum type to return
1169      * @param enumClass  The enum's class object
1170      */
1171     public abstract <E extends Enum<E>> E getEnumShort(Class<E> enumClass);
1172 
1173     /**
1174      * Reads a short from the buffer and returns the correlating enum constant defined
1175      * by the specified enum type.
1176      *
1177      * @param <E> The enum type to return
1178      * @param index  the index from which the bytes will be read
1179      * @param enumClass  The enum's class object
1180      */
1181     public abstract <E extends Enum<E>> E getEnumShort(int index, Class<E> enumClass);
1182 
1183     /**
1184      * Reads an int from the buffer and returns the correlating enum constant defined
1185      * by the specified enum type.
1186      *
1187      * @param <E> The enum type to return
1188      * @param enumClass  The enum's class object
1189      */
1190     public abstract <E extends Enum<E>> E getEnumInt(Class<E> enumClass);
1191 
1192     /**
1193      * Reads an int from the buffer and returns the correlating enum constant defined
1194      * by the specified enum type.
1195      *
1196      * @param <E> The enum type to return
1197      * @param index  the index from which the bytes will be read
1198      * @param enumClass  The enum's class object
1199      */
1200     public abstract <E extends Enum<E>> E getEnumInt(int index, Class<E> enumClass);
1201 
1202     /**
1203      * Writes an enum's ordinal value to the buffer as a byte.
1204      *
1205      * @param e  The enum to write to the buffer
1206      */
1207     public abstract IoBuffer putEnum(Enum<?> e);
1208 
1209     /**
1210      * Writes an enum's ordinal value to the buffer as a byte.
1211      *
1212      * @param index The index at which the byte will be written
1213      * @param e  The enum to write to the buffer
1214      */
1215     public abstract IoBuffer putEnum(int index, Enum<?> e);
1216 
1217     /**
1218      * Writes an enum's ordinal value to the buffer as a short.
1219      *
1220      * @param e  The enum to write to the buffer
1221      */
1222     public abstract IoBuffer putEnumShort(Enum<?> e);
1223 
1224     /**
1225      * Writes an enum's ordinal value to the buffer as a short.
1226      *
1227      * @param index The index at which the bytes will be written
1228      * @param e  The enum to write to the buffer
1229      */
1230     public abstract IoBuffer putEnumShort(int index, Enum<?> e);
1231 
1232     /**
1233      * Writes an enum's ordinal value to the buffer as an integer.
1234      *
1235      * @param e  The enum to write to the buffer
1236      */
1237     public abstract IoBuffer putEnumInt(Enum<?> e);
1238 
1239     /**
1240      * Writes an enum's ordinal value to the buffer as an integer.
1241      *
1242      * @param index The index at which the bytes will be written
1243      * @param e  The enum to write to the buffer
1244      */
1245     public abstract IoBuffer putEnumInt(int index, Enum<?> e);
1246 
1247     //////////////////////////
1248     // EnumSet methods      //
1249     //////////////////////////
1250 
1251     /**
1252      * Reads a byte sized bit vector and converts it to an {@link EnumSet}.
1253      *
1254      * <p>Each bit is mapped to a value in the specified enum.  The least significant
1255      * bit maps to the first entry in the specified enum and each subsequent bit maps
1256      * to each subsequent bit as mapped to the subsequent enum value.</p>
1257      *
1258      * @param <E>  the enum type
1259      * @param enumClass  the enum class used to create the EnumSet
1260      * @return the EnumSet representation of the bit vector
1261      */
1262     public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(Class<E> enumClass);
1263 
1264     /**
1265      * Reads a byte sized bit vector and converts it to an {@link EnumSet}.
1266      *
1267      * @see #getEnumSet(Class)
1268      * @param <E>  the enum type
1269      * @param index  the index from which the byte will be read
1270      * @param enumClass  the enum class used to create the EnumSet
1271      * @return the EnumSet representation of the bit vector
1272      */
1273     public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(int index,
1274             Class<E> enumClass);
1275 
1276     /**
1277      * Reads a short sized bit vector and converts it to an {@link EnumSet}.
1278      *
1279      * @see #getEnumSet(Class)
1280      * @param <E>  the enum type
1281      * @param enumClass  the enum class used to create the EnumSet
1282      * @return the EnumSet representation of the bit vector
1283      */
1284     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(Class<E> enumClass);
1285 
1286     /**
1287      * Reads a short sized bit vector and converts it to an {@link EnumSet}.
1288      *
1289      * @see #getEnumSet(Class)
1290      * @param <E>  the enum type
1291      * @param index  the index from which the bytes will be read
1292      * @param enumClass  the enum class used to create the EnumSet
1293      * @return the EnumSet representation of the bit vector
1294      */
1295     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(int index,
1296             Class<E> enumClass);
1297 
1298     /**
1299      * Reads an int sized bit vector and converts it to an {@link EnumSet}.
1300      *
1301      * @see #getEnumSet(Class)
1302      * @param <E>  the enum type
1303      * @param enumClass  the enum class used to create the EnumSet
1304      * @return the EnumSet representation of the bit vector
1305      */
1306     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(Class<E> enumClass);
1307 
1308     /**
1309      * Reads an int sized bit vector and converts it to an {@link EnumSet}.
1310      *
1311      * @see #getEnumSet(Class)
1312      * @param <E>  the enum type
1313      * @param index  the index from which the bytes will be read
1314      * @param enumClass  the enum class used to create the EnumSet
1315      * @return the EnumSet representation of the bit vector
1316      */
1317     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(int index,
1318             Class<E> enumClass);
1319 
1320     /**
1321      * Reads a long sized bit vector and converts it to an {@link EnumSet}.
1322      *
1323      * @see #getEnumSet(Class)
1324      * @param <E>  the enum type
1325      * @param enumClass  the enum class used to create the EnumSet
1326      * @return the EnumSet representation of the bit vector
1327      */
1328     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(Class<E> enumClass);
1329 
1330     /**
1331      * Reads a long sized bit vector and converts it to an {@link EnumSet}.
1332      *
1333      * @see #getEnumSet(Class)
1334      * @param <E>  the enum type
1335      * @param index  the index from which the bytes will be read
1336      * @param enumClass  the enum class used to create the EnumSet
1337      * @return the EnumSet representation of the bit vector
1338      */
1339     public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(int index,
1340             Class<E> enumClass);
1341 
1342     /**
1343      * Writes the specified {@link Set} to the buffer as a byte sized bit vector.
1344      *
1345      * @param <E> the enum type of the Set
1346      * @param set  the enum set to write to the buffer
1347      */
1348     public abstract <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set);
1349 
1350     /**
1351      * Writes the specified {@link Set} to the buffer as a byte sized bit vector.
1352      *
1353      * @param <E> the enum type of the Set
1354      * @param index  the index at which the byte will be written
1355      * @param set  the enum set to write to the buffer
1356      */
1357     public abstract <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set);
1358 
1359     /**
1360      * Writes the specified {@link Set} to the buffer as a short sized bit vector.
1361      *
1362      * @param <E> the enum type of the Set
1363      * @param set  the enum set to write to the buffer
1364      */
1365     public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set);
1366 
1367     /**
1368      * Writes the specified {@link Set} to the buffer as a short sized bit vector.
1369      *
1370      * @param <E> the enum type of the Set
1371      * @param index  the index at which the bytes will be written
1372      * @param set  the enum set to write to the buffer
1373      */
1374     public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(int index, Set<E> set);
1375 
1376     /**
1377      * Writes the specified {@link Set} to the buffer as an int sized bit vector.
1378      *
1379      * @param <E> the enum type of the Set
1380      * @param set  the enum set to write to the buffer
1381      */
1382     public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set);
1383 
1384     /**
1385      * Writes the specified {@link Set} to the buffer as an int sized bit vector.
1386      *
1387      * @param <E> the enum type of the Set
1388      * @param index  the index at which the bytes will be written
1389      * @param set  the enum set to write to the buffer
1390      */
1391     public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(int index, Set<E> set);
1392 
1393     /**
1394      * Writes the specified {@link Set} to the buffer as a long sized bit vector.
1395      *
1396      * @param <E> the enum type of the Set
1397      * @param set  the enum set to write to the buffer
1398      */
1399     public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set);
1400 
1401     /**
1402      * Writes the specified {@link Set} to the buffer as a long sized bit vector.
1403      *
1404      * @param <E> the enum type of the Set
1405      * @param index  the index at which the bytes will be written
1406      * @param set  the enum set to write to the buffer
1407      */
1408     public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(int index, Set<E> set);
1409 }