001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.core.buffer;
021
022import java.io.IOException;
023import java.io.InputStream;
024import java.io.OutputStream;
025import java.nio.BufferOverflowException;
026import java.nio.ByteBuffer;
027import java.nio.ByteOrder;
028import java.nio.CharBuffer;
029import java.nio.DoubleBuffer;
030import java.nio.FloatBuffer;
031import java.nio.IntBuffer;
032import java.nio.LongBuffer;
033import java.nio.ReadOnlyBufferException;
034import java.nio.ShortBuffer;
035import java.nio.charset.CharacterCodingException;
036import java.nio.charset.CharsetDecoder;
037import java.nio.charset.CharsetEncoder;
038import java.util.EnumSet;
039import java.util.Set;
040
041import org.apache.mina.core.session.IoSession;
042
043/**
044 * A byte buffer used by MINA applications.
045 * <p>
046 * This is a replacement for {@link ByteBuffer}. Please refer to
047 * {@link ByteBuffer} documentation for preliminary usage. MINA does not use NIO
048 * {@link ByteBuffer} directly for two reasons:
049 * <ul>
050 *   <li>It doesn't provide useful getters and putters such as <code>fill</code>,
051 *       <code>get/putString</code>, and <code>get/putAsciiInt()</code> enough.</li>
052 *   <li>It is difficult to write variable-length data due to its fixed capacity</li>
053 * </ul>
054 * 
055 * <h2>Allocation</h2>
056 * <p>
057 *   You can allocate a new heap buffer.
058 * 
059 *   <pre>
060 *     IoBuffer buf = IoBuffer.allocate(1024, false);
061 *   </pre>
062 * 
063 *   You can also allocate a new direct buffer:
064 * 
065 *   <pre>
066 *     IoBuffer buf = IoBuffer.allocate(1024, true);
067 *   </pre>
068 * 
069 *   or you can set the default buffer type.
070 * 
071 *   <pre>
072 *     // Allocate heap buffer by default.
073 *     IoBuffer.setUseDirectBuffer(false);
074 * 
075 *     // A new heap buffer is returned.
076 *     IoBuffer buf = IoBuffer.allocate(1024);
077 *   </pre>
078 * 
079 * <h2>Wrapping existing NIO buffers and arrays</h2>
080 * <p>
081 *   This class provides a few <tt>wrap(...)</tt> methods that wraps any NIO
082 *   buffers and byte arrays.
083 * 
084 * <h2>AutoExpand</h2>
085 * <p>
086 *   Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really
087 *   easy, and it is because its size is fixed at allocation. {@link IoBuffer} introduces
088 *   the <tt>autoExpand</tt> property. If <tt>autoExpand</tt> property is set to true, 
089 *   you never get a {@link BufferOverflowException} or
090 *   an {@link IndexOutOfBoundsException} (except when index is negative). It
091 *   automatically expands its capacity. For instance:
092 * 
093 *   <pre>
094 *     String greeting = messageBundle.getMessage(&quot;hello&quot;);
095 *     IoBuffer buf = IoBuffer.allocate(16);
096 *     // Turn on autoExpand (it is off by default)
097 *     buf.setAutoExpand(true);
098 *     buf.putString(greeting, utf8encoder);
099 *   </pre>
100 * 
101 *   The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind
102 *   the scene if the encoded data is larger than 16 bytes in the example above.
103 *   Its capacity will double, and its limit will increase to the last position
104 *   the string is written.
105 * 
106 * <h2>AutoShrink</h2>
107 * <p>
108 *   You might also want to decrease the capacity of the buffer when most of the
109 *   allocated memory area is not being used. {@link IoBuffer} provides
110 *   <tt>autoShrink</tt> property to take care of this issue. If
111 *   <tt>autoShrink</tt> is turned on, {@link IoBuffer} halves the capacity of the
112 *   buffer when {@link #compact()} is invoked and only 1/4 or less of the current
113 *   capacity is being used.
114 * <p>
115 *   You can also call the {@link #shrink()} method manually to shrink the capacity of the
116 *   buffer.
117 * <p>
118 *   The underlying {@link ByteBuffer} is reallocated by the {@link IoBuffer} behind
119 *   the scene, and therefore {@link #buf()} will return a different
120 *   {@link ByteBuffer} instance once capacity changes. Please also note
121 *   that the {@link #compact()} method or the {@link #shrink()} method
122 *   will not decrease the capacity if the new capacity is less than the 
123 *   {@link #minimumCapacity()} of the buffer.
124 * 
125 * <h2>Derived Buffers</h2>
126 * <p>
127 *   Derived buffers are the buffers which were created by the {@link #duplicate()},
128 *   {@link #slice()}, or {@link #asReadOnlyBuffer()} methods. They are useful especially
129 *   when you broadcast the same messages to multiple {@link IoSession}s. Please
130 *   note that the buffer derived from and its derived buffers are not 
131 *   auto-expandable nor auto-shrinkable. Trying to call
132 *   {@link #setAutoExpand(boolean)} or {@link #setAutoShrink(boolean)} with
133 *   <tt>true</tt> parameter will raise an {@link IllegalStateException}.
134 * 
135 * <h2>Changing Buffer Allocation Policy</h2>
136 * <p>
137 *   The {@link IoBufferAllocator} interface lets you override the default buffer
138 *   management behavior. There are two allocators provided out-of-the-box:
139 *   <ul>
140 *     <li>{@link SimpleBufferAllocator} (default)</li>
141 *     <li>{@link CachedBufferAllocator}</li>
142 *   </ul>
143 *   You can implement your own allocator and use it by calling
144 *   {@link #setAllocator(IoBufferAllocator)}.
145 * 
146 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
147 */
148public abstract class IoBuffer implements Comparable<IoBuffer> {
149    /** The allocator used to create new buffers */
150    private static IoBufferAllocator allocator = new SimpleBufferAllocator();
151
152    /** A flag indicating which type of buffer we are using : heap or direct */
153    private static boolean useDirectBuffer = false;
154
155    /**
156     * @return the allocator used by existing and new buffers
157     */
158    public static IoBufferAllocator getAllocator() {
159        return allocator;
160    }
161
162    /**
163     * Sets the allocator used by existing and new buffers
164     * 
165     * @param newAllocator the new allocator to use
166     */
167    public static void setAllocator(IoBufferAllocator newAllocator) {
168        if (newAllocator == null) {
169            throw new IllegalArgumentException("allocator");
170        }
171
172        IoBufferAllocator oldAllocator = allocator;
173
174        allocator = newAllocator;
175
176        if (null != oldAllocator) {
177            oldAllocator.dispose();
178        }
179    }
180
181    /**
182     * @return <tt>true</tt> if and only if a direct buffer is allocated by
183     * default when the type of the new buffer is not specified. The default
184     * value is <tt>false</tt>.
185     */
186    public static boolean isUseDirectBuffer() {
187        return useDirectBuffer;
188    }
189
190    /**
191     * Sets if a direct buffer should be allocated by default when the type of
192     * the new buffer is not specified. The default value is <tt>false</tt>.
193     * 
194     * @param useDirectBuffer Tells if direct buffers should be allocated
195     */
196    public static void setUseDirectBuffer(boolean useDirectBuffer) {
197        IoBuffer.useDirectBuffer = useDirectBuffer;
198    }
199
200    /**
201     * Returns the direct or heap buffer which is capable to store the specified
202     * amount of bytes.
203     * 
204     * @param capacity the capacity of the buffer
205     * @return a IoBuffer which can hold up to capacity bytes
206     * 
207     * @see #setUseDirectBuffer(boolean)
208     */
209    public static IoBuffer allocate(int capacity) {
210        return allocate(capacity, useDirectBuffer);
211    }
212
213    /**
214     * Returns a direct or heap IoBuffer which can contain the specified number of bytes.
215     * 
216     * @param capacity the capacity of the buffer
217     * @param useDirectBuffer <tt>true</tt> to get a direct buffer, <tt>false</tt> to get a
218     *            heap buffer.
219     * @return a direct or heap  IoBuffer which can hold up to capacity bytes
220     */
221    public static IoBuffer allocate(int capacity, boolean useDirectBuffer) {
222        if (capacity < 0) {
223            throw new IllegalArgumentException("capacity: " + capacity);
224        }
225
226        return allocator.allocate(capacity, useDirectBuffer);
227    }
228
229    /**
230     * Wraps the specified NIO {@link ByteBuffer} into a MINA buffer (either direct or heap).
231     * 
232     * @param nioBuffer The {@link ByteBuffer} to wrap
233     * @return a IoBuffer containing the bytes stored in the {@link ByteBuffer}
234     */
235    public static IoBuffer wrap(ByteBuffer nioBuffer) {
236        return allocator.wrap(nioBuffer);
237    }
238
239    /**
240     * Wraps the specified byte array into a MINA heap buffer. Note that
241     * the byte array is not copied, so any modification done on it will
242     * be visible by both sides.
243     * 
244     * @param byteArray The byte array to wrap
245     * @return a heap IoBuffer containing the byte array
246     */
247    public static IoBuffer wrap(byte[] byteArray) {
248        return wrap(ByteBuffer.wrap(byteArray));
249    }
250
251    /**
252     * Wraps the specified byte array into MINA heap buffer. We just wrap the 
253     * bytes starting from offset up to offset + length.  Note that
254     * the byte array is not copied, so any modification done on it will
255     * be visible by both sides.
256     * 
257     * @param byteArray The byte array to wrap
258     * @param offset The starting point in the byte array
259     * @param length The number of bytes to store
260     * @return a heap IoBuffer containing the selected part of the byte array
261     */
262    public static IoBuffer wrap(byte[] byteArray, int offset, int length) {
263        return wrap(ByteBuffer.wrap(byteArray, offset, length));
264    }
265
266    /**
267     * Normalizes the specified capacity of the buffer to power of 2, which is
268     * often helpful for optimal memory usage and performance. If it is greater
269     * than or equal to {@link Integer#MAX_VALUE}, it returns
270     * {@link Integer#MAX_VALUE}. If it is zero, it returns zero.
271     * 
272     * @param requestedCapacity The IoBuffer capacity we want to be able to store
273     * @return The  power of 2 strictly superior to the requested capacity
274     */
275    protected static int normalizeCapacity(int requestedCapacity) {
276        if (requestedCapacity < 0) {
277            return Integer.MAX_VALUE;
278        }
279
280        int newCapacity = Integer.highestOneBit(requestedCapacity);
281        newCapacity <<= (newCapacity < requestedCapacity ? 1 : 0);
282        
283        return newCapacity < 0 ? Integer.MAX_VALUE : newCapacity;
284    }
285
286    /**
287     * Creates a new instance. This is an empty constructor. It's protected, 
288     * to forbid its usage by the users.
289     */
290    protected IoBuffer() {
291        // Do nothing
292    }
293
294    /**
295     * Declares this buffer and all its derived buffers are not used anymore so
296     * that it can be reused by some {@link IoBufferAllocator} implementations.
297     * It is not mandatory to call this method, but you might want to invoke
298     * this method for maximum performance.
299     */
300    public abstract void free();
301
302    /**
303     * @return the underlying NIO {@link ByteBuffer} instance.
304     */
305    public abstract ByteBuffer buf();
306
307    /**
308     * @see ByteBuffer#isDirect()
309     * 
310     * @return <tt>True</tt> if this is a direct buffer
311     */
312    public abstract boolean isDirect();
313
314    /**
315     * @return <tt>true</tt> if and only if this buffer is derived from another
316     * buffer via one of the {@link #duplicate()}, {@link #slice()} or
317     * {@link #asReadOnlyBuffer()} methods.
318     */
319    public abstract boolean isDerived();
320
321    /**
322     * @see ByteBuffer#isReadOnly()
323     * 
324     * @return <tt>true</tt> if the buffer is readOnly
325     */
326    public abstract boolean isReadOnly();
327
328    /**
329     * @return the minimum capacity of this buffer which is used to determine
330     * the new capacity of the buffer shrunk by the {@link #compact()} and
331     * {@link #shrink()} operation. The default value is the initial capacity of
332     * the buffer.
333     */
334    public abstract int minimumCapacity();
335
336    /**
337     * Sets the minimum capacity of this buffer which is used to determine the
338     * new capacity of the buffer shrunk by {@link #compact()} and
339     * {@link #shrink()} operation. The default value is the initial capacity of
340     * the buffer.
341     * 
342     * @param minimumCapacity the wanted minimum capacity
343     * @return the underlying NIO {@link ByteBuffer} instance.
344     */
345    public abstract IoBuffer minimumCapacity(int minimumCapacity);
346
347    /**
348     * @see ByteBuffer#capacity()
349     * 
350     * @return the buffer capacity
351     */
352    public abstract int capacity();
353
354    /**
355     * Increases the capacity of this buffer. If the new capacity is less than
356     * or equal to the current capacity, this method returns the original buffer. 
357     * If the new capacity is greater than the current capacity, the buffer is
358     * reallocated while retaining the position, limit, mark and the content of
359     * the buffer.
360     * <br>
361     * Note that the IoBuffer is replaced, it's not copied.
362     * <br>
363     * Assuming a buffer contains N bytes, its position is 0 and its current capacity is C, 
364     * here are the resulting buffer if we set the new capacity to a value V &lt; C and V &gt; C :
365     * 
366     * <pre>
367     *  Initial buffer :
368     *   
369     *   0       L          C
370     *  +--------+----------+
371     *  |XXXXXXXX|          |
372     *  +--------+----------+
373     *   ^       ^          ^
374     *   |       |          |
375     *  pos    limit     capacity
376     *  
377     * V &lt;= C :
378     * 
379     *   0       L          C
380     *  +--------+----------+
381     *  |XXXXXXXX|          |
382     *  +--------+----------+
383     *   ^       ^          ^
384     *   |       |          |
385     *  pos    limit   newCapacity
386     *  
387     * V &gt; C :
388     * 
389     *   0       L          C            V
390     *  +--------+-----------------------+
391     *  |XXXXXXXX|          :            |
392     *  +--------+-----------------------+
393     *   ^       ^          ^            ^
394     *   |       |          |            |
395     *  pos    limit   oldCapacity  newCapacity
396     *  
397     *  The buffer has been increased.
398     *  
399     * </pre>
400     * 
401     * @param newCapacity the wanted capacity
402     * @return the underlying NIO {@link ByteBuffer} instance.
403     */
404    public abstract IoBuffer capacity(int newCapacity);
405
406    /**
407     * @return <tt>true</tt> if and only if <tt>autoExpand</tt> is turned on.
408     */
409    public abstract boolean isAutoExpand();
410
411    /**
412     * Turns on or off <tt>autoExpand</tt>.
413     * 
414     * @param autoExpand The flag value to set
415     * @return The modified IoBuffer instance
416     */
417    public abstract IoBuffer setAutoExpand(boolean autoExpand);
418
419    /**
420     * @return <tt>true</tt> if and only if <tt>autoShrink</tt> is turned on.
421     */
422    public abstract boolean isAutoShrink();
423
424    /**
425     * Turns on or off <tt>autoShrink</tt>.
426     * 
427     * @param autoShrink The flag value to set
428     * @return The modified IoBuffer instance
429     */
430    public abstract IoBuffer setAutoShrink(boolean autoShrink);
431
432    /**
433     * Changes the capacity and limit of this buffer so this buffer get the
434     * specified <tt>expectedRemaining</tt> room from the current position. This
435     * method works even if you didn't set <tt>autoExpand</tt> to <tt>true</tt>.
436     * <br>
437     * Assuming a buffer contains N bytes, its position is P and its current capacity is C, 
438     * here are the resulting buffer if we call the expand method with a expectedRemaining
439     * value V :
440     * 
441     * <pre>
442     *  Initial buffer :
443     *   
444     *   0       L          C
445     *  +--------+----------+
446     *  |XXXXXXXX|          |
447     *  +--------+----------+
448     *   ^       ^          ^
449     *   |       |          |
450     *  pos    limit     capacity
451     *  
452     * ( pos + V )  &lt;= L, no change :
453     * 
454     *   0       L          C
455     *  +--------+----------+
456     *  |XXXXXXXX|          |
457     *  +--------+----------+
458     *   ^       ^          ^
459     *   |       |          |
460     *  pos    limit   newCapacity
461     *  
462     * You can still put ( L - pos ) bytes in the buffer
463     *  
464     * ( pos + V ) &gt; L &amp; ( pos + V ) &lt;= C :
465     * 
466     *  0        L          C
467     *  +------------+------+
468     *  |XXXXXXXX:...|      |
469     *  +------------+------+
470     *   ^           ^      ^
471     *   |           |      |
472     *  pos       newlimit  newCapacity
473     *  
474     *  You can now put ( L - pos + V )  bytes in the buffer.
475     *  
476     *  
477     *  ( pos + V ) &gt; C
478     * 
479     *   0       L          C
480     *  +-------------------+----+
481     *  |XXXXXXXX:..........:....|
482     *  +------------------------+
483     *   ^                       ^
484     *   |                       |
485     *  pos                      +-- newlimit
486     *                           |
487     *                           +-- newCapacity
488     *                           
489     * You can now put ( L - pos + V ) bytes in the buffer, which limit is now
490     * equals to the capacity.
491     * </pre>
492     *
493     * Note that the expecting remaining bytes starts at the current position. In all
494     * those examples, the position is 0.
495     *  
496     * @param expectedRemaining The expected remaining bytes in the buffer
497     * @return The modified IoBuffer instance
498     */
499    public abstract IoBuffer expand(int expectedRemaining);
500
501    /**
502     * Changes the capacity and limit of this buffer so this buffer get the
503     * specified <tt>expectedRemaining</tt> room from the specified
504     * <tt>position</tt>. This method works even if you didn't set
505     * <tt>autoExpand</tt> to <tt>true</tt>.
506     * Assuming a buffer contains N bytes, its position is P and its current capacity is C, 
507     * here are the resulting buffer if we call the expand method with a expectedRemaining
508     * value V :
509     * 
510     * <pre>
511     *  Initial buffer :
512     *   
513     *      P    L          C
514     *  +--------+----------+
515     *  |XXXXXXXX|          |
516     *  +--------+----------+
517     *      ^    ^          ^
518     *      |    |          |
519     *     pos limit     capacity
520     *  
521     * ( pos + V )  &lt;= L, no change :
522     * 
523     *      P    L          C
524     *  +--------+----------+
525     *  |XXXXXXXX|          |
526     *  +--------+----------+
527     *      ^    ^          ^
528     *      |    |          |
529     *     pos limit   newCapacity
530     *  
531     * You can still put ( L - pos ) bytes in the buffer
532     *  
533     * ( pos + V ) &gt; L &amp; ( pos + V ) &lt;= C :
534     * 
535     *      P    L          C
536     *  +------------+------+
537     *  |XXXXXXXX:...|      |
538     *  +------------+------+
539     *      ^        ^      ^
540     *      |        |      |
541     *     pos    newlimit  newCapacity
542     *  
543     *  You can now put ( L - pos + V)  bytes in the buffer.
544     *  
545     *  
546     *  ( pos + V ) &gt; C
547     * 
548     *      P       L          C
549     *  +-------------------+----+
550     *  |XXXXXXXX:..........:....|
551     *  +------------------------+
552     *      ^                    ^
553     *      |                    |
554     *     pos                   +-- newlimit
555     *                           |
556     *                           +-- newCapacity
557     *                           
558     * You can now put ( L - pos + V ) bytes in the buffer, which limit is now
559     * equals to the capacity.
560     * </pre>
561     *
562     * Note that the expecting remaining bytes starts at the current position. In all
563     * those examples, the position is P.
564     * 
565     * @param position The starting position from which we want to define a remaining 
566     * number of bytes
567     * @param expectedRemaining The expected remaining bytes in the buffer
568     * @return The modified IoBuffer instance
569     */
570    public abstract IoBuffer expand(int position, int expectedRemaining);
571
572    /**
573     * Changes the capacity of this buffer so this buffer occupies as less
574     * memory as possible while retaining the position, limit and the buffer
575     * content between the position and limit. 
576     * <br>
577     * <b>The capacity of the buffer never becomes less than {@link #minimumCapacity()}</b>
578     * <br>. 
579     * The mark is discarded once the capacity changes.
580     * <br>
581     * Typically, a call to this method tries to remove as much unused bytes
582     * as possible, dividing by two the initial capacity until it can't without
583     * obtaining a new capacity lower than the {@link #minimumCapacity()}. For instance, if 
584     * the limit is 7 and the capacity is 36, with a minimum capacity of 8, 
585     * shrinking the buffer will left a capacity of 9 (we go down from 36 to 18, then from 18 to 9).  
586     * 
587     * <pre>
588     *  Initial buffer :
589     *   
590     *  +--------+----------+
591     *  |XXXXXXXX|          |
592     *  +--------+----------+
593     *      ^    ^  ^       ^
594     *      |    |  |       |
595     *     pos   |  |    capacity
596     *           |  |
597     *           |  +-- minimumCapacity
598     *           |
599     *           +-- limit
600     * 
601     * Resulting buffer :
602     * 
603     *  +--------+--+-+
604     *  |XXXXXXXX|  | |
605     *  +--------+--+-+
606     *      ^    ^  ^ ^
607     *      |    |  | |
608     *      |    |  | +-- new capacity
609     *      |    |  |
610     *     pos   |  +-- minimum capacity
611     *           |
612     *           +-- limit
613     * </pre>
614     *           
615     * @return The modified IoBuffer instance
616     */
617    public abstract IoBuffer shrink();
618
619    /**
620     * @see java.nio.Buffer#position()
621     * @return The current position in the buffer
622     */
623    public abstract int position();
624
625    /**
626     * @see java.nio.Buffer#position(int)
627     * 
628     * @param newPosition Sets the new position in the buffer
629     * @return the modified IoBuffer
630
631     */
632    public abstract IoBuffer position(int newPosition);
633
634    /**
635     * @see java.nio.Buffer#limit()
636     * 
637     * @return the modified IoBuffer
638's limit
639     */
640    public abstract int limit();
641
642    /**
643     * @see java.nio.Buffer#limit(int)
644     * 
645     * @param newLimit The new buffer's limit
646     * @return the modified IoBuffer
647
648     */
649    public abstract IoBuffer limit(int newLimit);
650
651    /**
652     * @see java.nio.Buffer#mark()
653     * 
654     * @return the modified IoBuffer
655
656     */
657    public abstract IoBuffer mark();
658
659    /**
660     * @return the position of the current mark. This method returns <tt>-1</tt>
661     * if no mark is set.
662     */
663    public abstract int markValue();
664
665    /**
666     * @see java.nio.Buffer#reset()
667     * 
668     * @return the modified IoBuffer
669
670     */
671    public abstract IoBuffer reset();
672
673    /**
674     * @see java.nio.Buffer#clear()
675     * 
676     * @return the modified IoBuffer
677
678     */
679    public abstract IoBuffer clear();
680
681    /**
682     * Clears this buffer and fills its content with <tt>NUL</tt>. The position
683     * is set to zero, the limit is set to the capacity, and the mark is
684     * discarded.
685     * 
686     * @return the modified IoBuffer
687
688     */
689    public abstract IoBuffer sweep();
690
691    /**
692     * double Clears this buffer and fills its content with <tt>value</tt>. The
693     * position is set to zero, the limit is set to the capacity, and the mark
694     * is discarded.
695     *
696     * @param value The value to put in the buffer
697     * @return the modified IoBuffer
698
699     */
700    public abstract IoBuffer sweep(byte value);
701
702    /**
703     * @see java.nio.Buffer#flip()
704     * 
705     * @return the modified IoBuffer
706
707     */
708    public abstract IoBuffer flip();
709
710    /**
711     * @see java.nio.Buffer#rewind()
712     * 
713     * @return the modified IoBuffer
714
715     */
716    public abstract IoBuffer rewind();
717
718    /**
719     * @see java.nio.Buffer#remaining()
720     * 
721     * @return The remaining bytes in the buffer
722     */
723    public abstract int remaining();
724
725    /**
726     * @see java.nio.Buffer#hasRemaining()
727     * 
728     * @return <tt>true</tt> if there are some remaining bytes in the buffer
729     */
730    public abstract boolean hasRemaining();
731
732    /**
733     * @see ByteBuffer#duplicate()
734     * 
735     * @return the modified IoBuffer
736
737     */
738    public abstract IoBuffer duplicate();
739
740    /**
741     * @see ByteBuffer#slice()
742     * 
743     * @return the modified IoBuffer
744
745     */
746    public abstract IoBuffer slice();
747
748    /**
749     * @see ByteBuffer#asReadOnlyBuffer()
750     * 
751     * @return the modified IoBuffer
752
753     */
754    public abstract IoBuffer asReadOnlyBuffer();
755
756    /**
757     * @see ByteBuffer#hasArray()
758     * 
759     * @return <tt>true</tt> if the {@link #array()} method will return a byte[]
760     */
761    public abstract boolean hasArray();
762
763    /**
764     * @see ByteBuffer#array()
765     * 
766     * @return A byte[] if this IoBuffer supports it
767     */
768    public abstract byte[] array();
769
770    /**
771     * @see ByteBuffer#arrayOffset()
772     * 
773     * @return The offset in the returned byte[] when the {@link #array()} method is called
774     */
775    public abstract int arrayOffset();
776
777    /**
778     * @see ByteBuffer#get()
779     * 
780     * @return The byte at the current position
781     */
782    public abstract byte get();
783
784    /**
785     * Reads one unsigned byte as a short integer.
786     * 
787     * @return the unsigned short at the current position
788     */
789    public abstract short getUnsigned();
790
791    /**
792     * @see ByteBuffer#put(byte)
793     * 
794     * @param b The byte to put in the buffer
795     * @return the modified IoBuffer
796
797     */
798    public abstract IoBuffer put(byte b);
799
800    /**
801     * @see ByteBuffer#get(int)
802     * 
803     * @param index The position for which we want to read a byte
804     * @return the byte at the given position
805     */
806    public abstract byte get(int index);
807
808    /**
809     * Reads one byte as an unsigned short integer.
810     * 
811     * @param index The position for which we want to read an unsigned byte
812     * @return the unsigned byte at the given position
813     */
814    public abstract short getUnsigned(int index);
815
816    /**
817     * @see ByteBuffer#put(int, byte)
818     * 
819     * @param index The position where the byte will be put
820     * @param b The byte to put
821     * @return the modified IoBuffer
822
823     */
824    public abstract IoBuffer put(int index, byte b);
825
826    /**
827     * @see ByteBuffer#get(byte[], int, int)
828     * 
829     * @param dst The destination buffer
830     * @param offset The position in the original buffer
831     * @param length The number of bytes to copy
832     * @return the modified IoBuffer
833     */
834    public abstract IoBuffer get(byte[] dst, int offset, int length);
835
836    /**
837     * @see ByteBuffer#get(byte[])
838     *
839     * @param dst The byte[] that will contain the read bytes
840     * @return the IoBuffer
841     */
842    public abstract IoBuffer get(byte[] dst);
843
844    /**
845     * Get a new IoBuffer containing a slice of the current buffer
846     * 
847     * @param index The position in the buffer 
848     * @param length The number of bytes to copy
849     * @return the new IoBuffer
850     */
851    public abstract IoBuffer getSlice(int index, int length);
852
853    /**
854     * Get a new IoBuffer containing a slice of the current buffer
855     * 
856     * @param length The number of bytes to copy
857     * @return the new IoBuffer
858     */
859    public abstract IoBuffer getSlice(int length);
860
861    /**
862     * Writes the content of the specified <tt>src</tt> into this buffer.
863     * 
864     * @param src The source ByteBuffer
865     * @return the modified IoBuffer
866     */
867    public abstract IoBuffer put(ByteBuffer src);
868
869    /**
870     * Writes the content of the specified <tt>src</tt> into this buffer.
871     * 
872     * @param src The source IoBuffer
873     * @return the modified IoBuffer
874     */
875    public abstract IoBuffer put(IoBuffer src);
876
877    /**
878     * @see ByteBuffer#put(byte[], int, int)
879     * 
880     * @param src The byte[] to put
881     * @param offset The position in the source
882     * @param length The number of bytes to copy
883     * @return the modified IoBuffer
884     */
885    public abstract IoBuffer put(byte[] src, int offset, int length);
886
887    /**
888     * @see ByteBuffer#put(byte[])
889     * 
890     * @param src The byte[] to put
891     * @return the modified IoBuffer
892     */
893    public abstract IoBuffer put(byte[] src);
894
895    /**
896     * @see ByteBuffer#compact()
897     * 
898     * @return the modified IoBuffer
899     */
900    public abstract IoBuffer compact();
901
902    /**
903     * @see ByteBuffer#order()
904     * 
905     * @return the IoBuffer ByteOrder
906     */
907    public abstract ByteOrder order();
908
909    /**
910     * @see ByteBuffer#order(ByteOrder)
911     * 
912     * @param bo The new ByteBuffer to use for this IoBuffer
913     * @return the modified IoBuffer
914     */
915    public abstract IoBuffer order(ByteOrder bo);
916
917    /**
918     * @see ByteBuffer#getChar()
919     * 
920     * @return The char at the current position
921     */
922    public abstract char getChar();
923
924    /**
925     * @see ByteBuffer#putChar(char)
926     * 
927     * @param value The char to put at the current position
928     * @return the modified IoBuffer
929     */
930    public abstract IoBuffer putChar(char value);
931
932    /**
933     * @see ByteBuffer#getChar(int)
934     * 
935     * @param index The index in the IoBuffer where we will read a char from
936     * @return the char at 'index' position
937     */
938    public abstract char getChar(int index);
939
940    /**
941     * @see ByteBuffer#putChar(int, char)
942     * 
943     * @param index The index in the IoBuffer where we will put a char in
944     * @param value The char to put at the current position
945     * @return the modified IoBuffer
946     */
947    public abstract IoBuffer putChar(int index, char value);
948
949    /**
950     * @see ByteBuffer#asCharBuffer()
951     * 
952     * @return a new CharBuffer
953     */
954    public abstract CharBuffer asCharBuffer();
955
956    /**
957     * @see ByteBuffer#getShort()
958     * 
959     * @return The read short
960     */
961    public abstract short getShort();
962
963    /**
964     * Reads two bytes unsigned integer.
965     * 
966     * @return The read unsigned short
967     */
968    public abstract int getUnsignedShort();
969
970    /**
971     * @see ByteBuffer#putShort(short)
972     * 
973     * @param value The short to put at the current position
974     * @return the modified IoBuffer
975     */
976    public abstract IoBuffer putShort(short value);
977
978    /**
979     * @see ByteBuffer#getShort()
980     * 
981     * @param index The index in the IoBuffer where we will read a short from
982     * @return The read short
983     */
984    public abstract short getShort(int index);
985
986    /**
987     * Reads two bytes unsigned integer.
988     * 
989     * @param index The index in the IoBuffer where we will read an unsigned short from
990     * @return the unsigned short at the given position
991     */
992    public abstract int getUnsignedShort(int index);
993
994    /**
995     * @see ByteBuffer#putShort(int, short)
996     * 
997     * @param index The position at which the short should be written
998     * @param value The short to put at the current position
999     * @return the modified IoBuffer
1000     */
1001    public abstract IoBuffer putShort(int index, short value);
1002
1003    /**
1004     * @see ByteBuffer#asShortBuffer()
1005     * 
1006     * @return A ShortBuffer from this IoBuffer
1007     */
1008    public abstract ShortBuffer asShortBuffer();
1009
1010    /**
1011     * @see ByteBuffer#getInt()
1012     * 
1013     * @return The int read
1014     */
1015    public abstract int getInt();
1016
1017    /**
1018     * Reads four bytes unsigned integer.
1019     * 
1020     * @return The unsigned int read
1021     */
1022    public abstract long getUnsignedInt();
1023
1024    /**
1025     * Relative <i>get</i> method for reading a medium int value.
1026     * 
1027     * <p>
1028     * Reads the next three bytes at this buffer's current position, composing
1029     * them into an int value according to the current byte order, and then
1030     * increments the position by three.
1031     * 
1032     * @return The medium int value at the buffer's current position
1033     */
1034    public abstract int getMediumInt();
1035
1036    /**
1037     * Relative <i>get</i> method for reading an unsigned medium int value.
1038     * 
1039     * <p>
1040     * Reads the next three bytes at this buffer's current position, composing
1041     * them into an int value according to the current byte order, and then
1042     * increments the position by three.
1043     * 
1044     * @return The unsigned medium int value at the buffer's current position
1045     */
1046    public abstract int getUnsignedMediumInt();
1047
1048    /**
1049     * Absolute <i>get</i> method for reading a medium int value.
1050     * 
1051     * <p>
1052     * Reads the next three bytes at this buffer's current position, composing
1053     * them into an int value according to the current byte order.
1054     * 
1055     * @param index The index from which the medium int will be read
1056     * @return The medium int value at the given index
1057     * 
1058     * @throws IndexOutOfBoundsException
1059     *             If <tt>index</tt> is negative or not smaller than the
1060     *             buffer's limit
1061     */
1062    public abstract int getMediumInt(int index);
1063
1064    /**
1065     * Absolute <i>get</i> method for reading an unsigned medium int value.
1066     * 
1067     * <p>
1068     * Reads the next three bytes at this buffer's current position, composing
1069     * them into an int value according to the current byte order.
1070     * 
1071     * @param index The index from which the unsigned medium int will be read
1072     * @return The unsigned medium int value at the given index
1073     * 
1074     * @throws IndexOutOfBoundsException
1075     *             If <tt>index</tt> is negative or not smaller than the
1076     *             buffer's limit
1077     */
1078    public abstract int getUnsignedMediumInt(int index);
1079
1080    /**
1081     * Relative <i>put</i> method for writing a medium int value.
1082     * 
1083     * <p>
1084     * Writes three bytes containing the given int value, in the current byte
1085     * order, into this buffer at the current position, and then increments the
1086     * position by three.
1087     * 
1088     * @param value The medium int value to be written
1089     * 
1090     * @return the modified IoBuffer
1091     * 
1092     * @throws BufferOverflowException If there are fewer than three bytes remaining in this buffer
1093     * @throws ReadOnlyBufferException If this buffer is read-only
1094     */
1095    public abstract IoBuffer putMediumInt(int value);
1096
1097    /**
1098     * Absolute <i>put</i> method for writing a medium int value.
1099     * 
1100     * <p>
1101     * Writes three bytes containing the given int value, in the current byte
1102     * order, into this buffer at the given index.
1103     * 
1104     * @param index The index at which the bytes will be written
1105     * 
1106     * @param value The medium int value to be written
1107     * 
1108     * @return the modified IoBuffer
1109     * 
1110     * @throws IndexOutOfBoundsException
1111     *             If <tt>index</tt> is negative or not smaller than the
1112     *             buffer's limit, minus three
1113     * 
1114     * @throws ReadOnlyBufferException If this buffer is read-only
1115     */
1116    public abstract IoBuffer putMediumInt(int index, int value);
1117
1118    /**
1119     * @see ByteBuffer#putInt(int)
1120     * 
1121     * @param value The int to put at the current position
1122     * @return the modified IoBuffer
1123     */
1124    public abstract IoBuffer putInt(int value);
1125
1126    /**
1127     * Writes an unsigned byte into the ByteBuffer
1128     * 
1129     * @param value the byte to write
1130     * 
1131     * @return the modified IoBuffer
1132     */
1133    public abstract IoBuffer putUnsigned(byte value);
1134
1135    /**
1136     * Writes an unsigned byte into the ByteBuffer at a specified position
1137     * 
1138     * @param index the position in the buffer to write the value
1139     * @param value the byte to write
1140     * 
1141     * @return the modified IoBuffer
1142     */
1143    public abstract IoBuffer putUnsigned(int index, byte value);
1144
1145    /**
1146     * Writes an unsigned byte into the ByteBuffer
1147     * 
1148     * @param value the short to write
1149     * 
1150     * @return the modified IoBuffer
1151     */
1152    public abstract IoBuffer putUnsigned(short value);
1153
1154    /**
1155     * Writes an unsigned byte into the ByteBuffer at a specified position
1156     * 
1157     * @param index the position in the buffer to write the value
1158     * @param value the short to write
1159     * 
1160     * @return the modified IoBuffer
1161     */
1162    public abstract IoBuffer putUnsigned(int index, short value);
1163
1164    /**
1165     * Writes an unsigned byte into the ByteBuffer
1166     * 
1167     * @param value the int to write
1168     * 
1169     * @return the modified IoBuffer
1170     */
1171    public abstract IoBuffer putUnsigned(int value);
1172
1173    /**
1174     * Writes an unsigned byte into the ByteBuffer at a specified position
1175     * 
1176     * @param index the position in the buffer to write the value
1177     * @param value the int to write
1178     * 
1179     * @return the modified IoBuffer
1180     */
1181    public abstract IoBuffer putUnsigned(int index, int value);
1182
1183    /**
1184     * Writes an unsigned byte into the ByteBuffer
1185     * 
1186     * @param value the long to write
1187     * 
1188     * @return the modified IoBuffer
1189     */
1190    public abstract IoBuffer putUnsigned(long value);
1191
1192    /**
1193     * Writes an unsigned byte into the ByteBuffer at a specified position
1194     * 
1195     * @param index the position in the buffer to write the value
1196     * @param value the long to write
1197     * 
1198     * @return the modified IoBuffer
1199     */
1200    public abstract IoBuffer putUnsigned(int index, long value);
1201
1202    /**
1203     * Writes an unsigned int into the ByteBuffer
1204     * @param value the byte to write
1205     * 
1206     * @return the modified IoBuffer
1207     */
1208    public abstract IoBuffer putUnsignedInt(byte value);
1209
1210    /**
1211     * Writes an unsigned int into the ByteBuffer at a specified position
1212     * 
1213     * @param index the position in the buffer to write the value
1214     * @param value the byte to write
1215     * 
1216     * @return the modified IoBuffer
1217     */
1218    public abstract IoBuffer putUnsignedInt(int index, byte value);
1219
1220    /**
1221     * Writes an unsigned int into the ByteBuffer
1222     * 
1223     * @param value the short to write
1224     * 
1225     * @return the modified IoBuffer
1226     */
1227    public abstract IoBuffer putUnsignedInt(short value);
1228
1229    /**
1230     * Writes an unsigned int into the ByteBuffer at a specified position
1231     * 
1232     * @param index the position in the buffer to write the value
1233     * @param value the short to write
1234     * 
1235     * @return the modified IoBuffer
1236     */
1237    public abstract IoBuffer putUnsignedInt(int index, short value);
1238
1239    /**
1240     * Writes an unsigned int into the ByteBuffer
1241     * 
1242     * @param value the int to write
1243     * 
1244     * @return the modified IoBuffer
1245     */
1246    public abstract IoBuffer putUnsignedInt(int value);
1247
1248    /**
1249     * Writes an unsigned int into the ByteBuffer at a specified position
1250     * 
1251     * @param index the position in the buffer to write the value
1252     * @param value the int to write
1253     * 
1254     * @return the modified IoBuffer
1255     */
1256    public abstract IoBuffer putUnsignedInt(int index, int value);
1257
1258    /**
1259     * Writes an unsigned int into the ByteBuffer
1260     * 
1261     * @param value the long to write
1262     * 
1263     * @return the modified IoBuffer
1264     */
1265    public abstract IoBuffer putUnsignedInt(long value);
1266
1267    /**
1268     * Writes an unsigned int into the ByteBuffer at a specified position
1269     * 
1270     * @param index the position in the buffer to write the value
1271     * @param value the long to write
1272     * 
1273     * @return the modified IoBuffer
1274     */
1275    public abstract IoBuffer putUnsignedInt(int index, long value);
1276
1277    /**
1278     * Writes an unsigned short into the ByteBuffer
1279     * 
1280     * @param value the byte to write
1281     * 
1282     * @return the modified IoBuffer
1283     */
1284    public abstract IoBuffer putUnsignedShort(byte value);
1285
1286    /**
1287     * Writes an unsigned Short into the ByteBuffer at a specified position
1288     * 
1289     * @param index the position in the buffer to write the value
1290     * @param value the byte to write
1291     * 
1292     * @return the modified IoBuffer
1293     */
1294    public abstract IoBuffer putUnsignedShort(int index, byte value);
1295
1296    /**
1297     * Writes an unsigned Short into the ByteBuffer
1298     * 
1299     * @param value the short to write
1300     * 
1301     * @return the modified IoBuffer
1302     */
1303    public abstract IoBuffer putUnsignedShort(short value);
1304
1305    /**
1306     * Writes an unsigned Short into the ByteBuffer at a specified position
1307     * 
1308     * @param index the position in the buffer to write the unsigned short
1309     * @param value the unsigned short to write
1310     * 
1311     * @return the modified IoBuffer
1312     */
1313    public abstract IoBuffer putUnsignedShort(int index, short value);
1314
1315    /**
1316     * Writes an unsigned Short into the ByteBuffer
1317     * 
1318     * @param value the int to write
1319     * 
1320     * @return the modified IoBuffer
1321     */
1322    public abstract IoBuffer putUnsignedShort(int value);
1323
1324    /**
1325     * Writes an unsigned Short into the ByteBuffer at a specified position
1326     * 
1327     * @param index the position in the buffer to write the value
1328     * @param value the int to write
1329     * 
1330     * @param index The position where to put the unsigned short
1331     * @param value The unsigned short to put in the IoBuffer
1332     * @return the modified IoBuffer
1333     */
1334    public abstract IoBuffer putUnsignedShort(int index, int value);
1335
1336    /**
1337     * Writes an unsigned Short into the ByteBuffer
1338     * 
1339     * @param value the long to write
1340     * 
1341     * @return the modified IoBuffer
1342     */
1343    public abstract IoBuffer putUnsignedShort(long value);
1344
1345    /**
1346     * Writes an unsigned Short into the ByteBuffer at a specified position
1347     * 
1348     * @param index the position in the buffer to write the short
1349     * @param value the long to write
1350     * 
1351     * @return the modified IoBuffer
1352     */
1353    public abstract IoBuffer putUnsignedShort(int index, long value);
1354
1355    /**
1356     * @see ByteBuffer#getInt(int)
1357     * @param index The index in the IoBuffer where we will read an int from
1358     * @return the int at the given position
1359     */
1360    public abstract int getInt(int index);
1361
1362    /**
1363     * Reads four bytes unsigned integer.
1364     * @param index The index in the IoBuffer where we will read an unsigned int from
1365     * @return The long at the given position
1366     */
1367    public abstract long getUnsignedInt(int index);
1368
1369    /**
1370     * @see ByteBuffer#putInt(int, int)
1371     * 
1372     * @param index The position where to put the int
1373     * @param value The int to put in the IoBuffer
1374     * @return the modified IoBuffer
1375     * @return the modified IoBuffer
1376     */
1377    public abstract IoBuffer putInt(int index, int value);
1378
1379    /**
1380     * @see ByteBuffer#asIntBuffer()
1381     * 
1382     * @return the modified IoBuffer
1383     */
1384    public abstract IntBuffer asIntBuffer();
1385
1386    /**
1387     * @see ByteBuffer#getLong()
1388     * 
1389     * @return The long at the current position
1390     */
1391    public abstract long getLong();
1392
1393    /**
1394     * @see ByteBuffer#putLong(int, long)
1395     * 
1396     * @param value The log to put in the IoBuffer
1397     * @return the modified IoBuffer
1398     */
1399    public abstract IoBuffer putLong(long value);
1400
1401    /**
1402     * @see ByteBuffer#getLong(int)
1403     * 
1404     * @param index The index in the IoBuffer where we will read a long from
1405     * @return the long at the given position
1406     */
1407    public abstract long getLong(int index);
1408
1409    /**
1410     * @see ByteBuffer#putLong(int, long)
1411     * 
1412     * @param index The position where to put the long
1413     * @param value The long to put in the IoBuffer
1414     * @return the modified IoBuffer
1415     * @return the modified IoBuffer
1416     */
1417    public abstract IoBuffer putLong(int index, long value);
1418
1419    /**
1420     * @see ByteBuffer#asLongBuffer()
1421     * 
1422     * @return a LongBuffer from this IoBffer
1423     */
1424    public abstract LongBuffer asLongBuffer();
1425
1426    /**
1427     * @see ByteBuffer#getFloat()
1428     * 
1429     * @return the float at the current position
1430     */
1431    public abstract float getFloat();
1432
1433    /**
1434     * @see ByteBuffer#putFloat(float)
1435     *
1436     * @param value The float to put in the IoBuffer
1437     * @return the modified IoBuffer
1438     */
1439    public abstract IoBuffer putFloat(float value);
1440
1441    /**
1442     * @see ByteBuffer#getFloat(int)
1443     * 
1444     * @param index The index in the IoBuffer where we will read a float from
1445     * @return The float at the given position
1446     */
1447    public abstract float getFloat(int index);
1448
1449    /**
1450     * @see ByteBuffer#putFloat(int, float)
1451     * 
1452     * @param index The position where to put the float
1453     * @param value The float to put in the IoBuffer
1454     * @return the modified IoBuffer
1455     */
1456    public abstract IoBuffer putFloat(int index, float value);
1457
1458    /**
1459     * @see ByteBuffer#asFloatBuffer()
1460     * 
1461     * @return A FloatBuffer from this IoBuffer
1462     */
1463    public abstract FloatBuffer asFloatBuffer();
1464
1465    /**
1466     * @see ByteBuffer#getDouble()
1467     * 
1468     * @return the double at the current position
1469     */
1470    public abstract double getDouble();
1471
1472    /**
1473     * @see ByteBuffer#putDouble(double)
1474     * 
1475     * @param value The double to put at the IoBuffer current position
1476     * @return the modified IoBuffer
1477     */
1478    public abstract IoBuffer putDouble(double value);
1479
1480    /**
1481     * @see ByteBuffer#getDouble(int)
1482     * 
1483     * @param index The position where to get the double from
1484     * @return The double at the given position
1485     */
1486    public abstract double getDouble(int index);
1487
1488    /**
1489     * @see ByteBuffer#putDouble(int, double)
1490     * 
1491     * @param index The position where to put the double
1492     * @param value The double to put in the IoBuffer
1493     * @return the modified IoBuffer
1494     */
1495    public abstract IoBuffer putDouble(int index, double value);
1496
1497    /**
1498     * @see ByteBuffer#asDoubleBuffer()
1499     * 
1500     * @return A buffer containing Double
1501     */
1502    public abstract DoubleBuffer asDoubleBuffer();
1503
1504    /**
1505     * @return an {@link InputStream} that reads the data from this buffer.
1506     * {@link InputStream#read()} returns <tt>-1</tt> if the buffer position
1507     * reaches to the limit.
1508     */
1509    public abstract InputStream asInputStream();
1510
1511    /**
1512     * @return an {@link OutputStream} that appends the data into this buffer.
1513     * Please note that the {@link OutputStream#write(int)} will throw a
1514     * {@link BufferOverflowException} instead of an {@link IOException} in case
1515     * of buffer overflow. Please set <tt>autoExpand</tt> property by calling
1516     * {@link #setAutoExpand(boolean)} to prevent the unexpected runtime
1517     * exception.
1518     */
1519    public abstract OutputStream asOutputStream();
1520
1521    /**
1522     * Returns hexdump of this buffer. The data and pointer are not changed as a
1523     * result of this method call.
1524     * 
1525     * @return hexidecimal representation of this buffer
1526     */
1527    public abstract String getHexDump();
1528
1529    /**
1530     * Return hexdump of this buffer with limited length.
1531     * 
1532     * @param lengthLimit
1533     *            The maximum number of bytes to dump from the current buffer
1534     *            position.
1535     * @return hexidecimal representation of this buffer
1536     */
1537    public abstract String getHexDump(int lengthLimit);
1538
1539    // //////////////////////////////
1540    // String getters and putters //
1541    // //////////////////////////////
1542
1543    /**
1544     * Reads a <code>NUL</code>-terminated string from this buffer using the
1545     * specified <code>decoder</code> and returns it. This method reads until
1546     * the limit of this buffer if no <tt>NUL</tt> is found.
1547     * 
1548     * @param decoder The {@link CharsetDecoder} to use
1549     * @return the read String
1550     * @exception CharacterCodingException Thrown when an error occurred while decoding the buffer
1551     */
1552    public abstract String getString(CharsetDecoder decoder) throws CharacterCodingException;
1553
1554    /**
1555     * Reads a <code>NUL</code>-terminated string from this buffer using the
1556     * specified <code>decoder</code> and returns it.
1557     * 
1558     * @param fieldSize the maximum number of bytes to read
1559     * @param decoder The {@link CharsetDecoder} to use
1560     * @return the read String
1561     * @exception CharacterCodingException Thrown when an error occurred while decoding the buffer
1562     */
1563    public abstract String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException;
1564
1565    /**
1566     * Writes the content of <code>in</code> into this buffer using the
1567     * specified <code>encoder</code>. This method doesn't terminate string with
1568     * <tt>NUL</tt>. You have to do it by yourself.
1569     * 
1570     * @param val The CharSequence to put in the IoBuffer
1571     * @param encoder The CharsetEncoder to use
1572     * @return The modified IoBuffer
1573     * @throws CharacterCodingException When we have an error while decoding the String
1574     */
1575    public abstract IoBuffer putString(CharSequence val, CharsetEncoder encoder) throws CharacterCodingException;
1576
1577    /**
1578     * Writes the content of <code>in</code> into this buffer as a
1579     * <code>NUL</code>-terminated string using the specified
1580     * <code>encoder</code>.
1581     * <p>
1582     * If the charset name of the encoder is UTF-16, you cannot specify odd
1583     * <code>fieldSize</code>, and this method will append two <code>NUL</code>s
1584     * as a terminator.
1585     * <p>
1586     * Please note that this method doesn't terminate with <code>NUL</code> if
1587     * the input string is longer than <tt>fieldSize</tt>.
1588     * 
1589     * @param val The CharSequence to put in the IoBuffer
1590     * @param fieldSize the maximum number of bytes to write
1591     * @param encoder The CharsetEncoder to use
1592     * @return The modified IoBuffer
1593     * @throws CharacterCodingException When we have an error while decoding the String
1594     */
1595    public abstract IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder)
1596            throws CharacterCodingException;
1597
1598    /**
1599     * Reads a string which has a 16-bit length field before the actual encoded
1600     * string, using the specified <code>decoder</code> and returns it. This
1601     * method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>.
1602     * 
1603     * @param decoder The CharsetDecoder to use
1604     * @return The read String
1605     * 
1606     * @throws CharacterCodingException When we have an error while decoding the String
1607     */
1608    public abstract String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException;
1609
1610    /**
1611     * Reads a string which has a length field before the actual encoded string,
1612     * using the specified <code>decoder</code> and returns it.
1613     * 
1614     * @param prefixLength the length of the length field (1, 2, or 4)
1615     * @param decoder The CharsetDecoder to use
1616     * @return The read String
1617     * 
1618     * @throws CharacterCodingException When we have an error while decoding the String
1619     */
1620    public abstract String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException;
1621
1622    /**
1623     * Writes the content of <code>in</code> into this buffer as a string which
1624     * has a 16-bit length field before the actual encoded string, using the
1625     * specified <code>encoder</code>. This method is a shortcut for
1626     * <tt>putPrefixedString(in, 2, 0, encoder)</tt>.
1627     * 
1628     * @param in The CharSequence to put in the IoBuffer
1629     * @param encoder The CharsetEncoder to use
1630     * @return The modified IoBuffer
1631     * 
1632     * @throws CharacterCodingException When we have an error while decoding the CharSequence
1633     */
1634    public abstract IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException;
1635
1636    /**
1637     * Writes the content of <code>in</code> into this buffer as a string which
1638     * has a 16-bit length field before the actual encoded string, using the
1639     * specified <code>encoder</code>. This method is a shortcut for
1640     * <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>.
1641     * 
1642     * @param in The CharSequence to put in the IoBuffer
1643     * @param prefixLength the length of the length field (1, 2, or 4)
1644     * @param encoder The CharsetEncoder to use
1645     * @return The modified IoBuffer
1646     * 
1647     * @throws CharacterCodingException When we have an error while decoding the CharSequence
1648     */
1649    public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder)
1650            throws CharacterCodingException;
1651
1652    /**
1653     * Writes the content of <code>in</code> into this buffer as a string which
1654     * has a 16-bit length field before the actual encoded string, using the
1655     * specified <code>encoder</code>. This method is a shortcut for
1656     * <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt>
1657     * 
1658     * @param in The CharSequence to put in the IoBuffer
1659     * @param prefixLength the length of the length field (1, 2, or 4)
1660     * @param padding the number of padded <tt>NUL</tt>s (1 (or 0), 2, or 4)
1661     * @param encoder The CharsetEncoder to use
1662     * @return The modified IoBuffer
1663     * 
1664     * @throws CharacterCodingException When we have an error while decoding the CharSequence
1665     */
1666    public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
1667            throws CharacterCodingException;
1668
1669    /**
1670     * Writes the content of <code>val</code> into this buffer as a string which
1671     * has a 16-bit length field before the actual encoded string, using the
1672     * specified <code>encoder</code>.
1673     * 
1674     * @param val The CharSequence to put in teh IoBuffer
1675     * @param prefixLength the length of the length field (1, 2, or 4)
1676     * @param padding the number of padded bytes (1 (or 0), 2, or 4)
1677     * @param padValue the value of padded bytes
1678     * @param encoder The CharsetEncoder to use
1679     * @return The modified IoBuffer
1680     * @throws CharacterCodingException When we have an error while decoding the CharSequence
1681     */
1682    public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue,
1683            CharsetEncoder encoder) throws CharacterCodingException;
1684
1685    /**
1686     * Reads a Java object from the buffer using the context {@link ClassLoader}
1687     * of the current thread.
1688     * 
1689     * @return The read Object
1690     * @throws ClassNotFoundException thrown when we can't find the Class to use
1691     */
1692    public abstract Object getObject() throws ClassNotFoundException;
1693
1694    /**
1695     * Reads a Java object from the buffer using the specified
1696     * <tt>classLoader</tt>.
1697     * 
1698     * @param classLoader The classLoader to use to read an Object from the IoBuffer
1699     * @return The read Object
1700     * @throws ClassNotFoundException thrown when we can't find the Class to use
1701     */
1702    public abstract Object getObject(final ClassLoader classLoader) throws ClassNotFoundException;
1703
1704    /**
1705     * Writes the specified Java object to the buffer.
1706     * 
1707     * @param o The Object to write in the IoBuffer
1708     * @return The modified IoBuffer
1709     */
1710    public abstract IoBuffer putObject(Object o);
1711
1712    /**
1713     * 
1714     * @param prefixLength the length of the prefix field (1, 2, or 4)
1715     * @return <tt>true</tt> if this buffer contains a data which has a data
1716     * length as a prefix and the buffer has remaining data as enough as
1717     * specified in the data length field. This method is identical with
1718     * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>. Please
1719     * not that using this method can allow DoS (Denial of Service) attack in
1720     * case the remote peer sends too big data length value. It is recommended
1721     * to use {@link #prefixedDataAvailable(int, int)} instead.
1722     * @throws IllegalArgumentException if prefixLength is wrong
1723     * @throws BufferDataException if data length is negative
1724     */
1725    public abstract boolean prefixedDataAvailable(int prefixLength);
1726
1727    /**
1728     * @param prefixLength the length of the prefix field (1, 2, or 4)
1729     * @param maxDataLength the allowed maximum of the read data length
1730     * @return <tt>true</tt> if this buffer contains a data which has a data
1731     * length as a prefix and the buffer has remaining data as enough as
1732     * specified in the data length field.
1733     * @throws IllegalArgumentException
1734     *             if prefixLength is wrong
1735     * @throws BufferDataException
1736     *             if data length is negative or greater then
1737     *             <tt>maxDataLength</tt>
1738     */
1739    public abstract boolean prefixedDataAvailable(int prefixLength, int maxDataLength);
1740
1741    // ///////////////////
1742    // IndexOf methods //
1743    // ///////////////////
1744
1745    /**
1746     * Returns the first occurrence position of the specified byte from the
1747     * current position to the current limit.
1748     *
1749     * @param b The byte we are looking for
1750     * @return <tt>-1</tt> if the specified byte is not found
1751     */
1752    public abstract int indexOf(byte b);
1753
1754    // ////////////////////////
1755    // Skip or fill methods //
1756    // ////////////////////////
1757
1758    /**
1759     * Forwards the position of this buffer as the specified <code>size</code>
1760     * bytes.
1761     * 
1762     * @param size The added size
1763     * @return The modified IoBuffer
1764     */
1765    public abstract IoBuffer skip(int size);
1766
1767    /**
1768     * Fills this buffer with the specified value. This method moves buffer
1769     * position forward.
1770     * 
1771     * @param value The value to fill the IoBuffer with
1772     * @param size The added size
1773     * @return The modified IoBuffer
1774     */
1775    public abstract IoBuffer fill(byte value, int size);
1776
1777    /**
1778     * Fills this buffer with the specified value. This method does not change
1779     * buffer position.
1780     *
1781     * @param value The value to fill the IoBuffer with
1782     * @param size The added size
1783     * @return The modified IoBuffer
1784     */
1785    public abstract IoBuffer fillAndReset(byte value, int size);
1786
1787    /**
1788     * Fills this buffer with <code>NUL (0x00)</code>. This method moves buffer
1789     * position forward.
1790     * 
1791     * @param size The added size
1792     * @return The modified IoBuffer
1793     */
1794    public abstract IoBuffer fill(int size);
1795
1796    /**
1797     * Fills this buffer with <code>NUL (0x00)</code>. This method does not
1798     * change buffer position.
1799     * 
1800     * @param size The added size
1801     * @return The modified IoBuffer
1802     */
1803    public abstract IoBuffer fillAndReset(int size);
1804
1805    // ////////////////////////
1806    // Enum methods //
1807    // ////////////////////////
1808
1809    /**
1810     * Reads a byte from the buffer and returns the correlating enum constant
1811     * defined by the specified enum type.
1812     * 
1813     * @param <E> The enum type to return
1814     * @param enumClass The enum's class object
1815     * @return The correlated enum constant
1816     */
1817    public abstract <E extends Enum<E>> E getEnum(Class<E> enumClass);
1818
1819    /**
1820     * Reads a byte from the buffer and returns the correlating enum constant
1821     * defined by the specified enum type.
1822     * 
1823     * @param <E> The enum type to return
1824     * @param index the index from which the byte will be read
1825     * @param enumClass The enum's class object
1826     * @return The correlated enum constant
1827     */
1828    public abstract <E extends Enum<E>> E getEnum(int index, Class<E> enumClass);
1829
1830    /**
1831     * Reads a short from the buffer and returns the correlating enum constant
1832     * defined by the specified enum type.
1833     * 
1834     * @param <E> The enum type to return
1835     * @param enumClass The enum's class object
1836     * @return The correlated enum constant
1837     */
1838    public abstract <E extends Enum<E>> E getEnumShort(Class<E> enumClass);
1839
1840    /**
1841     * Reads a short from the buffer and returns the correlating enum constant
1842     * defined by the specified enum type.
1843     * 
1844     * @param <E> The enum type to return
1845     * @param index the index from which the bytes will be read
1846     * @param enumClass The enum's class object
1847     * @return The correlated enum constant
1848     */
1849    public abstract <E extends Enum<E>> E getEnumShort(int index, Class<E> enumClass);
1850
1851    /**
1852     * Reads an int from the buffer and returns the correlating enum constant
1853     * defined by the specified enum type.
1854     * 
1855     * @param <E> The enum type to return
1856     * @param enumClass The enum's class object
1857     * @return The correlated enum constant
1858     */
1859    public abstract <E extends Enum<E>> E getEnumInt(Class<E> enumClass);
1860
1861    /**
1862     * Reads an int from the buffer and returns the correlating enum constant
1863     * defined by the specified enum type.
1864     * 
1865     * @param <E> The enum type to return
1866     * @param index the index from which the bytes will be read
1867     * @param enumClass The enum's class object
1868     * @return The correlated enum constant
1869     */
1870    public abstract <E extends Enum<E>> E getEnumInt(int index, Class<E> enumClass);
1871
1872    /**
1873     * Writes an enum's ordinal value to the buffer as a byte.
1874     * 
1875     * @param e The enum to write to the buffer
1876     * @return The modified IoBuffer
1877     */
1878    public abstract IoBuffer putEnum(Enum<?> e);
1879
1880    /**
1881     * Writes an enum's ordinal value to the buffer as a byte.
1882     * 
1883     * @param index The index at which the byte will be written
1884     * @param e The enum to write to the buffer
1885     * @return The modified IoBuffer
1886     */
1887    public abstract IoBuffer putEnum(int index, Enum<?> e);
1888
1889    /**
1890     * Writes an enum's ordinal value to the buffer as a short.
1891     * 
1892     * @param e The enum to write to the buffer
1893     * @return The modified IoBuffer
1894     */
1895    public abstract IoBuffer putEnumShort(Enum<?> e);
1896
1897    /**
1898     * Writes an enum's ordinal value to the buffer as a short.
1899     * 
1900     * @param index The index at which the bytes will be written
1901     * @param e The enum to write to the buffer
1902     * @return The modified IoBuffer
1903     */
1904    public abstract IoBuffer putEnumShort(int index, Enum<?> e);
1905
1906    /**
1907     * Writes an enum's ordinal value to the buffer as an integer.
1908     * 
1909     * @param e The enum to write to the buffer
1910     * @return The modified IoBuffer
1911     */
1912    public abstract IoBuffer putEnumInt(Enum<?> e);
1913
1914    /**
1915     * Writes an enum's ordinal value to the buffer as an integer.
1916     * 
1917     * @param index The index at which the bytes will be written
1918     * @param e The enum to write to the buffer
1919     * @return The modified IoBuffer
1920     */
1921    public abstract IoBuffer putEnumInt(int index, Enum<?> e);
1922
1923    // ////////////////////////
1924    // EnumSet methods //
1925    // ////////////////////////
1926
1927    /**
1928     * Reads a byte sized bit vector and converts it to an {@link EnumSet}.
1929     * 
1930     * <p>
1931     * Each bit is mapped to a value in the specified enum. The least
1932     * significant bit maps to the first entry in the specified enum and each
1933     * subsequent bit maps to each subsequent bit as mapped to the subsequent
1934     * enum value.
1935     * 
1936     * @param <E> the enum type
1937     * @param enumClass the enum class used to create the EnumSet
1938     * @return the EnumSet representation of the bit vector
1939     */
1940    public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(Class<E> enumClass);
1941
1942    /**
1943     * Reads a byte sized bit vector and converts it to an {@link EnumSet}.
1944     * 
1945     * @see #getEnumSet(Class)
1946     * @param <E> the enum type
1947     * @param index the index from which the byte will be read
1948     * @param enumClass the enum class used to create the EnumSet
1949     * @return the EnumSet representation of the bit vector
1950     */
1951    public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(int index, Class<E> enumClass);
1952
1953    /**
1954     * Reads a short sized bit vector and converts it to an {@link EnumSet}.
1955     * 
1956     * @see #getEnumSet(Class)
1957     * @param <E> the enum type
1958     * @param enumClass the enum class used to create the EnumSet
1959     * @return the EnumSet representation of the bit vector
1960     */
1961    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(Class<E> enumClass);
1962
1963    /**
1964     * Reads a short sized bit vector and converts it to an {@link EnumSet}.
1965     * 
1966     * @see #getEnumSet(Class)
1967     * @param <E> the enum type
1968     * @param index the index from which the bytes will be read
1969     * @param enumClass the enum class used to create the EnumSet
1970     * @return the EnumSet representation of the bit vector
1971     */
1972    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(int index, Class<E> enumClass);
1973
1974    /**
1975     * Reads an int sized bit vector and converts it to an {@link EnumSet}.
1976     * 
1977     * @see #getEnumSet(Class)
1978     * @param <E> the enum type
1979     * @param enumClass the enum class used to create the EnumSet
1980     * @return the EnumSet representation of the bit vector
1981     */
1982    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(Class<E> enumClass);
1983
1984    /**
1985     * Reads an int sized bit vector and converts it to an {@link EnumSet}.
1986     * 
1987     * @see #getEnumSet(Class)
1988     * @param <E> the enum type
1989     * @param index the index from which the bytes will be read
1990     * @param enumClass the enum class used to create the EnumSet
1991     * @return the EnumSet representation of the bit vector
1992     */
1993    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(int index, Class<E> enumClass);
1994
1995    /**
1996     * Reads a long sized bit vector and converts it to an {@link EnumSet}.
1997     * 
1998     * @see #getEnumSet(Class)
1999     * @param <E> the enum type
2000     * @param enumClass the enum class used to create the EnumSet
2001     * @return the EnumSet representation of the bit vector
2002     */
2003    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(Class<E> enumClass);
2004
2005    /**
2006     * Reads a long sized bit vector and converts it to an {@link EnumSet}.
2007     * 
2008     * @see #getEnumSet(Class)
2009     * @param <E> the enum type
2010     * @param index the index from which the bytes will be read
2011     * @param enumClass the enum class used to create the EnumSet
2012     * @return the EnumSet representation of the bit vector
2013     */
2014    public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(int index, Class<E> enumClass);
2015
2016    /**
2017     * Writes the specified {@link Set} to the buffer as a byte sized bit
2018     * vector.
2019     * 
2020     * @param <E> the enum type of the Set
2021     * @param set the enum set to write to the buffer
2022     * @return the modified IoBuffer
2023     */
2024    public abstract <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set);
2025
2026    /**
2027     * Writes the specified {@link Set} to the buffer as a byte sized bit
2028     * vector.
2029     * 
2030     * @param <E> the enum type of the Set
2031     * @param index the index at which the byte will be written
2032     * @param set the enum set to write to the buffer
2033     * @return the modified IoBuffer
2034     */
2035    public abstract <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set);
2036
2037    /**
2038     * Writes the specified {@link Set} to the buffer as a short sized bit
2039     * vector.
2040     * 
2041     * @param <E> the enum type of the Set
2042     * @param set the enum set to write to the buffer
2043     * @return the modified IoBuffer
2044     */
2045    public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set);
2046
2047    /**
2048     * Writes the specified {@link Set} to the buffer as a short sized bit
2049     * vector.
2050     * 
2051     * @param <E> the enum type of the Set
2052     * @param index the index at which the bytes will be written
2053     * @param set the enum set to write to the buffer
2054     * @return the modified IoBuffer
2055     */
2056    public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(int index, Set<E> set);
2057
2058    /**
2059     * Writes the specified {@link Set} to the buffer as an int sized bit
2060     * vector.
2061     * 
2062     * @param <E> the enum type of the Set
2063     * @param set the enum set to write to the buffer
2064     * @return the modified IoBuffer
2065     */
2066    public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set);
2067
2068    /**
2069     * Writes the specified {@link Set} to the buffer as an int sized bit
2070     * vector.
2071     * 
2072     * @param <E> the enum type of the Set
2073     * @param index the index at which the bytes will be written
2074     * @param set the enum set to write to the buffer
2075     * @return the modified IoBuffer
2076     */
2077    public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(int index, Set<E> set);
2078
2079    /**
2080     * Writes the specified {@link Set} to the buffer as a long sized bit
2081     * vector.
2082     * 
2083     * @param <E> the enum type of the Set
2084     * @param set the enum set to write to the buffer
2085     * @return the modified IoBuffer
2086     */
2087    public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set);
2088
2089    /**
2090     * Writes the specified {@link Set} to the buffer as a long sized bit
2091     * vector.
2092     * 
2093     * @param <E> the enum type of the Set
2094     * @param index the index at which the bytes will be written
2095     * @param set the enum set to write to the buffer
2096     * @return the modified IoBuffer
2097     */
2098    public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(int index, Set<E> set);
2099}