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.core.buffer;
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.Set;
40  
41  import org.apache.mina.core.session.IoSession;
42  
43  /**
44   * A byte buffer used by MINA applications.
45   * <p>
46   * This is a replacement for {@link ByteBuffer}. Please refer to
47   * {@link ByteBuffer} documentation for preliminary usage. MINA does not use NIO
48   * {@link ByteBuffer} directly for two reasons:
49   * <ul>
50   *   <li>It doesn't provide useful getters and putters such as <code>fill</code>,
51   *       <code>get/putString</code>, and <code>get/putAsciiInt()</code> enough.</li>
52   *   <li>It is difficult to write variable-length data due to its fixed capacity</li>
53   * </ul>
54   * 
55   * <h2>Allocation</h2>
56   * <p>
57   *   You can allocate a new heap buffer.
58   * 
59   *   <pre>
60   *     IoBuffer buf = IoBuffer.allocate(1024, false);
61   *   </pre>
62   * 
63   *   You can also allocate a new direct buffer:
64   * 
65   *   <pre>
66   *     IoBuffer buf = IoBuffer.allocate(1024, true);
67   *   </pre>
68   * 
69   *   or you can set the default buffer type.
70   * 
71   *   <pre>
72   *     // Allocate heap buffer by default.
73   *     IoBuffer.setUseDirectBuffer(false);
74   * 
75   *     // A new heap buffer is returned.
76   *     IoBuffer buf = IoBuffer.allocate(1024);
77   *   </pre>
78   * 
79   * <h2>Wrapping existing NIO buffers and arrays</h2>
80   * <p>
81   *   This class provides a few <tt>wrap(...)</tt> methods that wraps any NIO
82   *   buffers and byte arrays.
83   * 
84   * <h2>AutoExpand</h2>
85   * <p>
86   *   Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really
87   *   easy, and it is because its size is fixed at allocation. {@link IoBuffer} introduces
88   *   the <tt>autoExpand</tt> property. If <tt>autoExpand</tt> property is set to true, 
89   *   you never get a {@link BufferOverflowException} or
90   *   an {@link IndexOutOfBoundsException} (except when index is negative). It
91   *   automatically expands its capacity. For instance:
92   * 
93   *   <pre>
94   *     String greeting = messageBundle.getMessage(&quot;hello&quot;);
95   *     IoBuffer buf = IoBuffer.allocate(16);
96   *     // Turn on autoExpand (it is off by default)
97   *     buf.setAutoExpand(true);
98   *     buf.putString(greeting, utf8encoder);
99   *   </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  */
148 public 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 }