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