1 /*
2  * Copyright 2012 The Netty Project
3  *
4  * The Netty Project licenses this file to you under the Apache License,
5  * version 2.0 (the "License"); you may not use this file except in compliance
6  * with the License. You may obtain a copy of the License at:
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */
16 module hunt.net.buffer.ByteBuf;
17 
18 
19 import hunt.net.buffer.ByteBufAllocator;
20 import hunt.net.buffer.ByteProcessor;
21 import hunt.net.buffer.ReferenceCounted;
22 
23 import hunt.Byte;
24 import hunt.io.ByteBuffer;
25 import hunt.Double;
26 import hunt.Exceptions;
27 import hunt.Float;
28 import hunt.stream.Common;
29 import hunt.logging;
30 import hunt.text.Charset;
31 import hunt.util.ByteOrder;
32 
33 import std.conv;
34 
35 alias CharSequence = string;
36 
37 /**
38  * Checks that the given argument is not null. If it is, throws {@link NullPointerException}.
39  * Otherwise, returns the argument.
40  */
41 static T checkNotNull(T)(T arg, string text) {
42     if (arg is null) {
43         throw new NullPointerException(text);
44     }
45     return arg;
46 }
47 
48 /**
49  * Checks that the given argument is strictly positive. If it is not, throws {@link IllegalArgumentException}.
50  * Otherwise, returns the argument.
51  */
52 int checkPositive(int i, string name) {
53     if (i <= 0) {
54         throw new IllegalArgumentException(name ~ ": " ~ i.to!string() ~ " (expected: > 0)");
55     }
56     return i;
57 }
58 
59 
60 /**
61  * Checks that the given argument is strictly positive. If it is not, throws {@link IllegalArgumentException}.
62  * Otherwise, returns the argument.
63  */
64 long checkPositive(long i, string name) {
65     if (i <= 0) {
66         throw new IllegalArgumentException(name ~ ": " ~ i.to!string() ~ " (expected: > 0)");
67     }
68     return i;
69 }
70 
71 /**
72  * Checks that the given argument is positive or zero. If it is not , throws {@link IllegalArgumentException}.
73  * Otherwise, returns the argument.
74  */
75 int checkPositiveOrZero(int i, string name) {
76     if (i < 0) {
77         throw new IllegalArgumentException(name ~ ": " ~ i.to!string() ~ " (expected: >= 0)");
78     }
79     return i;
80 }
81 
82 
83 /**
84  * Determine if the requested {@code index} and {@code length} will fit within {@code capacity}.
85  * @param index The starting index.
86  * @param length The length which will be utilized (starting from {@code index}).
87  * @param capacity The capacity that {@code index + length} is allowed to be within.
88  * @return {@code true} if the requested {@code index} and {@code length} will fit within {@code capacity}.
89  * {@code false} if this would result in an index out of bounds exception.
90  */
91 bool isOutOfBounds(int index, int length, int capacity) {
92     return (index | length | (index + length) | (capacity - (index + length))) < 0;
93 }
94 
95 void throwException(Throwable ex) {
96     // 
97     version(HUNT_DEBUG){
98         warning(ex);
99     } else {
100         warning(ex.msg);
101     }
102 }
103 
104 /**
105  * A random and sequential accessible sequence of zero or more bytes (octets).
106  * This interface provides an abstract view for one or more primitive byte
107  * arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}.
108  *
109  * <h3>Creation of a buffer</h3>
110  *
111  * It is recommended to create a new buffer using the helper methods in
112  * {@link Unpooled} rather than calling an individual implementation's
113  * constructor.
114  *
115  * <h3>Random Access Indexing</h3>
116  *
117  * Just like an ordinary primitive byte array, {@link ByteBuf} uses
118  * <a href="http://en.wikipedia.org/wiki/Zero-based_numbering">zero-based indexing</a>.
119  * It means the index of the first byte is always {@code 0} and the index of the last byte is
120  * always {@link #capacity() capacity - 1}.  For example, to iterate all bytes of a buffer, you
121  * can do the following, regardless of its internal implementation:
122  *
123  * <pre>
124  * {@link ByteBuf} buffer = ...;
125  * for (int i = 0; i &lt; buffer.capacity(); i ++) {
126  *     byte b = buffer.getByte(i);
127  *     System.out.println((char) b);
128  * }
129  * </pre>
130  *
131  * <h3>Sequential Access Indexing</h3>
132  *
133  * {@link ByteBuf} provides two pointer variables to support sequential
134  * read and write operations - {@link #readerIndex() readerIndex} for a read
135  * operation and {@link #writerIndex() writerIndex} for a write operation
136  * respectively.  The following diagram shows how a buffer is segmented into
137  * three areas by the two pointers:
138  *
139  * <pre>
140  *      +-------------------+------------------+------------------+
141  *      | discardable bytes |  readable bytes  |  writable bytes  |
142  *      |                   |     (CONTENT)    |                  |
143  *      +-------------------+------------------+------------------+
144  *      |                   |                  |                  |
145  *      0      <=      readerIndex   <=   writerIndex    <=    capacity
146  * </pre>
147  *
148  * <h4>Readable bytes (the actual content)</h4>
149  *
150  * This segment is where the actual data is stored.  Any operation whose name
151  * starts with {@code read} or {@code skip} will get or skip the data at the
152  * current {@link #readerIndex() readerIndex} and increase it by the number of
153  * read bytes.  If the argument of the read operation is also a
154  * {@link ByteBuf} and no destination index is specified, the specified
155  * buffer's {@link #writerIndex() writerIndex} is increased together.
156  * <p>
157  * If there's not enough content left, {@link IndexOutOfBoundsException} is
158  * raised.  The default value of newly allocated, wrapped or copied buffer's
159  * {@link #readerIndex() readerIndex} is {@code 0}.
160  *
161  * <pre>
162  * // Iterates the readable bytes of a buffer.
163  * {@link ByteBuf} buffer = ...;
164  * while (buffer.isReadable()) {
165  *     System.out.println(buffer.readByte());
166  * }
167  * </pre>
168  *
169  * <h4>Writable bytes</h4>
170  *
171  * This segment is a undefined space which needs to be filled.  Any operation
172  * whose name starts with {@code write} will write the data at the current
173  * {@link #writerIndex() writerIndex} and increase it by the number of written
174  * bytes.  If the argument of the write operation is also a {@link ByteBuf},
175  * and no source index is specified, the specified buffer's
176  * {@link #readerIndex() readerIndex} is increased together.
177  * <p>
178  * If there's not enough writable bytes left, {@link IndexOutOfBoundsException}
179  * is raised.  The default value of newly allocated buffer's
180  * {@link #writerIndex() writerIndex} is {@code 0}.  The default value of
181  * wrapped or copied buffer's {@link #writerIndex() writerIndex} is the
182  * {@link #capacity() capacity} of the buffer.
183  *
184  * <pre>
185  * // Fills the writable bytes of a buffer with random integers.
186  * {@link ByteBuf} buffer = ...;
187  * while (buffer.maxWritableBytes() >= 4) {
188  *     buffer.writeInt(random.nextInt());
189  * }
190  * </pre>
191  *
192  * <h4>Discardable bytes</h4>
193  *
194  * This segment contains the bytes which were read already by a read operation.
195  * Initially, the size of this segment is {@code 0}, but its size increases up
196  * to the {@link #writerIndex() writerIndex} as read operations are executed.
197  * The read bytes can be discarded by calling {@link #discardReadBytes()} to
198  * reclaim unused area as depicted by the following diagram:
199  *
200  * <pre>
201  *  BEFORE discardReadBytes()
202  *
203  *      +-------------------+------------------+------------------+
204  *      | discardable bytes |  readable bytes  |  writable bytes  |
205  *      +-------------------+------------------+------------------+
206  *      |                   |                  |                  |
207  *      0      <=      readerIndex   <=   writerIndex    <=    capacity
208  *
209  *
210  *  AFTER discardReadBytes()
211  *
212  *      +------------------+--------------------------------------+
213  *      |  readable bytes  |    writable bytes (got more space)   |
214  *      +------------------+--------------------------------------+
215  *      |                  |                                      |
216  * readerIndex (0) <= writerIndex (decreased)        <=        capacity
217  * </pre>
218  *
219  * Please note that there is no guarantee about the content of writable bytes
220  * after calling {@link #discardReadBytes()}.  The writable bytes will not be
221  * moved in most cases and could even be filled with completely different data
222  * depending on the underlying buffer implementation.
223  *
224  * <h4>Clearing the buffer indexes</h4>
225  *
226  * You can set both {@link #readerIndex() readerIndex} and
227  * {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}.
228  * It does not clear the buffer content (e.g. filling with {@code 0}) but just
229  * clears the two pointers.  Please also note that the semantic of this
230  * operation is different from {@link ByteBuffer#clear()}.
231  *
232  * <pre>
233  *  BEFORE clear()
234  *
235  *      +-------------------+------------------+------------------+
236  *      | discardable bytes |  readable bytes  |  writable bytes  |
237  *      +-------------------+------------------+------------------+
238  *      |                   |                  |                  |
239  *      0      <=      readerIndex   <=   writerIndex    <=    capacity
240  *
241  *
242  *  AFTER clear()
243  *
244  *      +---------------------------------------------------------+
245  *      |             writable bytes (got more space)             |
246  *      +---------------------------------------------------------+
247  *      |                                                         |
248  *      0 = readerIndex = writerIndex            <=            capacity
249  * </pre>
250  *
251  * <h3>Search operations</h3>
252  *
253  * For simple single-byte searches, use {@link #indexOf(int, int, byte)} and {@link #bytesBefore(int, int, byte)}.
254  * {@link #bytesBefore(byte)} is especially useful when you deal with a {@code NUL}-terminated string.
255  * For complicated searches, use {@link #forEachByte(int, int, ByteProcessor)} with a {@link ByteProcessor}
256  * implementation.
257  *
258  * <h3>Mark and reset</h3>
259  *
260  * There are two marker indexes in every buffer. One is for storing
261  * {@link #readerIndex() readerIndex} and the other is for storing
262  * {@link #writerIndex() writerIndex}.  You can always reposition one of the
263  * two indexes by calling a reset method.  It works in a similar fashion to
264  * the mark and reset methods in {@link InputStream} except that there's no
265  * {@code readlimit}.
266  *
267  * <h3>Derived buffers</h3>
268  *
269  * You can create a view of an existing buffer by calling one of the following methods:
270  * <ul>
271  *   <li>{@link #duplicate()}</li>
272  *   <li>{@link #slice()}</li>
273  *   <li>{@link #slice(int, int)}</li>
274  *   <li>{@link #readSlice(int)}</li>
275  *   <li>{@link #retainedDuplicate()}</li>
276  *   <li>{@link #retainedSlice()}</li>
277  *   <li>{@link #retainedSlice(int, int)}</li>
278  *   <li>{@link #readRetainedSlice(int)}</li>
279  * </ul>
280  * A derived buffer will have an independent {@link #readerIndex() readerIndex},
281  * {@link #writerIndex() writerIndex} and marker indexes, while it shares
282  * other internal data representation, just like a NIO buffer does.
283  * <p>
284  * In case a completely fresh copy of an existing buffer is required, please
285  * call {@link #copy()} method instead.
286  *
287  * <h4>Non-retained and retained derived buffers</h4>
288  *
289  * Note that the {@link #duplicate()}, {@link #slice()}, {@link #slice(int, int)} and {@link #readSlice(int)} does NOT
290  * call {@link #retain()} on the returned derived buffer, and thus its reference count will NOT be increased. If you
291  * need to create a derived buffer with increased reference count, consider using {@link #retainedDuplicate()},
292  * {@link #retainedSlice()}, {@link #retainedSlice(int, int)} and {@link #readRetainedSlice(int)} which may return
293  * a buffer implementation that produces less garbage.
294  *
295  * <h3>Conversion to existing JDK types</h3>
296  *
297  * <h4>Byte array</h4>
298  *
299  * If a {@link ByteBuf} is backed by a byte array (i.e. {@code byte[]}),
300  * you can access it directly via the {@link #array()} method.  To determine
301  * if a buffer is backed by a byte array, {@link #hasArray()} should be used.
302  *
303  * <h4>NIO Buffers</h4>
304  *
305  * If a {@link ByteBuf} can be converted into an NIO {@link ByteBuffer} which shares its
306  * content (i.e. view buffer), you can get it via the {@link #nioBuffer()} method.  To determine
307  * if a buffer can be converted into an NIO buffer, use {@link #nioBufferCount()}.
308  *
309  * <h4>Strings</h4>
310  *
311  * Various {@link #toString(Charset)} methods convert a {@link ByteBuf}
312  * into a {@link string}.  Please note that {@link #toString()} is not a
313  * conversion method.
314  *
315  * <h4>I/O Streams</h4>
316  *
317  * Please refer to {@link ByteBufInputStream} and
318  * {@link ByteBufOutputStream}.
319  */
320 abstract class ByteBuf : ReferenceCounted { // implements ReferenceCounted, Comparable<ByteBuf>
321 
322     /**
323      * Returns the number of bytes (octets) this buffer can contain.
324      */
325     abstract int capacity();
326 
327     /**
328      * Adjusts the capacity of this buffer.  If the {@code newCapacity} is less than the current
329      * capacity, the content of this buffer is truncated.  If the {@code newCapacity} is greater
330      * than the current capacity, the buffer is appended with unspecified data whose length is
331      * {@code (newCapacity - currentCapacity)}.
332      *
333      * @throws IllegalArgumentException if the {@code newCapacity} is greater than {@link #maxCapacity()}
334      */
335     abstract ByteBuf capacity(int newCapacity);
336 
337     /**
338      * Returns the maximum allowed capacity of this buffer. This value provides an upper
339      * bound on {@link #capacity()}.
340      */
341     abstract int maxCapacity();
342 
343     /**
344      * Returns the {@link ByteBufAllocator} which created this buffer.
345      */
346     abstract ByteBufAllocator alloc();
347 
348     /**
349      * Returns the <a href="http://en.wikipedia.org/wiki/Endianness">endianness</a>
350      * of this buffer.
351      *
352      * @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
353      * instead of creating a buffer with swapped {@code endianness}.
354      */
355     // @Deprecated
356     abstract ByteOrder order();
357 
358     /**
359      * Returns a buffer with the specified {@code endianness} which shares the whole region,
360      * indexes, and marks of this buffer.  Modifying the content, the indexes, or the marks of the
361      * returned buffer or this buffer affects each other's content, indexes, and marks.  If the
362      * specified {@code endianness} is identical to this buffer's byte order, this method can
363      * return {@code this}.  This method does not modify {@code readerIndex} or {@code writerIndex}
364      * of this buffer.
365      *
366      * @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
367      * instead of creating a buffer with swapped {@code endianness}.
368      */
369     // @Deprecated
370     // abstract ByteBuf order(ByteOrder endianness);
371 
372     /**
373      * Return the underlying buffer instance if this buffer is a wrapper of another buffer.
374      *
375      * @return {@code null} if this buffer is not a wrapper
376      */
377     abstract ByteBuf unwrap();
378 
379     /**
380      * Returns {@code true} if and only if this buffer is backed by an
381      * NIO direct buffer.
382      */
383     abstract bool isDirect();
384 
385     /**
386      * Returns {@code true} if and only if this buffer is read-only.
387      */
388     abstract bool isReadOnly();
389 
390     /**
391      * Returns a read-only version of this buffer.
392      */
393     abstract ByteBuf asReadOnly();
394 
395     /**
396      * Returns the {@code readerIndex} of this buffer.
397      */
398     abstract int readerIndex();
399 
400     /**
401      * Sets the {@code readerIndex} of this buffer.
402      *
403      * @throws IndexOutOfBoundsException
404      *         if the specified {@code readerIndex} is
405      *            less than {@code 0} or
406      *            greater than {@code this.writerIndex}
407      */
408     abstract ByteBuf readerIndex(int readerIndex);
409 
410     /**
411      * Returns the {@code writerIndex} of this buffer.
412      */
413     abstract int writerIndex();
414 
415     /**
416      * Sets the {@code writerIndex} of this buffer.
417      *
418      * @throws IndexOutOfBoundsException
419      *         if the specified {@code writerIndex} is
420      *            less than {@code this.readerIndex} or
421      *            greater than {@code this.capacity}
422      */
423     abstract ByteBuf writerIndex(int writerIndex);
424 
425     /**
426      * Sets the {@code readerIndex} and {@code writerIndex} of this buffer
427      * in one shot.  This method is useful when you have to worry about the
428      * invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)}
429      * methods.  For example, the following code will fail:
430      *
431      * <pre>
432      * // Create a buffer whose readerIndex, writerIndex and capacity are
433      * // 0, 0 and 8 respectively.
434      * {@link ByteBuf} buf = {@link Unpooled}.buffer(8);
435      *
436      * // IndexOutOfBoundsException is thrown because the specified
437      * // readerIndex (2) cannot be greater than the current writerIndex (0).
438      * buf.readerIndex(2);
439      * buf.writerIndex(4);
440      * </pre>
441      *
442      * The following code will also fail:
443      *
444      * <pre>
445      * // Create a buffer whose readerIndex, writerIndex and capacity are
446      * // 0, 8 and 8 respectively.
447      * {@link ByteBuf} buf = {@link Unpooled}.wrappedBuffer(new byte[8]);
448      *
449      * // readerIndex becomes 8.
450      * buf.readLong();
451      *
452      * // IndexOutOfBoundsException is thrown because the specified
453      * // writerIndex (4) cannot be less than the current readerIndex (8).
454      * buf.writerIndex(4);
455      * buf.readerIndex(2);
456      * </pre>
457      *
458      * By contrast, this method guarantees that it never
459      * throws an {@link IndexOutOfBoundsException} as long as the specified
460      * indexes meet basic constraints, regardless what the current index
461      * values of the buffer are:
462      *
463      * <pre>
464      * // No matter what the current state of the buffer is, the following
465      * // call always succeeds as long as the capacity of the buffer is not
466      * // less than 4.
467      * buf.setIndex(2, 4);
468      * </pre>
469      *
470      * @throws IndexOutOfBoundsException
471      *         if the specified {@code readerIndex} is less than 0,
472      *         if the specified {@code writerIndex} is less than the specified
473      *         {@code readerIndex} or if the specified {@code writerIndex} is
474      *         greater than {@code this.capacity}
475      */
476     abstract ByteBuf setIndex(int readerIndex, int writerIndex);
477 
478     /**
479      * Returns the number of readable bytes which is equal to
480      * {@code (this.writerIndex - this.readerIndex)}.
481      */
482     abstract int readableBytes();
483 
484     /**
485      * Returns the number of writable bytes which is equal to
486      * {@code (this.capacity - this.writerIndex)}.
487      */
488     abstract int writableBytes();
489 
490     /**
491      * Returns the maximum possible number of writable bytes, which is equal to
492      * {@code (this.maxCapacity - this.writerIndex)}.
493      */
494     abstract int maxWritableBytes();
495 
496     /**
497      * Returns the maximum number of bytes which can be written for certain without involving
498      * an internal reallocation or data-copy. The returned value will be &ge; {@link #writableBytes()}
499      * and &le; {@link #maxWritableBytes()}.
500      */
501     int maxFastWritableBytes() {
502         return writableBytes();
503     }
504 
505     /**
506      * Returns {@code true}
507      * if and only if {@code (this.writerIndex - this.readerIndex)} is greater
508      * than {@code 0}.
509      */
510     abstract bool isReadable();
511 
512     /**
513      * Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements.
514      */
515     abstract bool isReadable(int size);
516 
517     /**
518      * Returns {@code true}
519      * if and only if {@code (this.capacity - this.writerIndex)} is greater
520      * than {@code 0}.
521      */
522     abstract bool isWritable();
523 
524     /**
525      * Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of
526      * elements.
527      */
528     abstract bool isWritable(int size);
529 
530     /**
531      * Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
532      * {@code 0}.
533      * This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}.
534      * <p>
535      * Please note that the behavior of this method is different
536      * from that of NIO buffer, which sets the {@code limit} to
537      * the {@code capacity} of the buffer.
538      */
539     abstract ByteBuf clear();
540 
541     /**
542      * Marks the current {@code readerIndex} in this buffer.  You can
543      * reposition the current {@code readerIndex} to the marked
544      * {@code readerIndex} by calling {@link #resetReaderIndex()}.
545      * The initial value of the marked {@code readerIndex} is {@code 0}.
546      */
547     abstract ByteBuf markReaderIndex();
548 
549     /**
550      * Repositions the current {@code readerIndex} to the marked
551      * {@code readerIndex} in this buffer.
552      *
553      * @throws IndexOutOfBoundsException
554      *         if the current {@code writerIndex} is less than the marked
555      *         {@code readerIndex}
556      */
557     abstract ByteBuf resetReaderIndex();
558 
559     /**
560      * Marks the current {@code writerIndex} in this buffer.  You can
561      * reposition the current {@code writerIndex} to the marked
562      * {@code writerIndex} by calling {@link #resetWriterIndex()}.
563      * The initial value of the marked {@code writerIndex} is {@code 0}.
564      */
565     abstract ByteBuf markWriterIndex();
566 
567     /**
568      * Repositions the current {@code writerIndex} to the marked
569      * {@code writerIndex} in this buffer.
570      *
571      * @throws IndexOutOfBoundsException
572      *         if the current {@code readerIndex} is greater than the marked
573      *         {@code writerIndex}
574      */
575     abstract ByteBuf resetWriterIndex();
576 
577     /**
578      * Discards the bytes between the 0th index and {@code readerIndex}.
579      * It moves the bytes between {@code readerIndex} and {@code writerIndex}
580      * to the 0th index, and sets {@code readerIndex} and {@code writerIndex}
581      * to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively.
582      * <p>
583      * Please refer to the class documentation for more detailed explanation.
584      */
585     abstract ByteBuf discardReadBytes();
586 
587     /**
588      * Similar to {@link ByteBuf#discardReadBytes()} except that this method might discard
589      * some, all, or none of read bytes depending on its internal implementation to reduce
590      * overall memory bandwidth consumption at the cost of potentially additional memory
591      * consumption.
592      */
593     abstract ByteBuf discardSomeReadBytes();
594 
595     /**
596      * Expands the buffer {@link #capacity()} to make sure the number of
597      * {@linkplain #writableBytes() writable bytes} is equal to or greater than the
598      * specified value.  If there are enough writable bytes in this buffer, this method
599      * returns with no side effect.
600      *
601      * @param minWritableBytes
602      *        the expected minimum number of writable bytes
603      * @throws IndexOutOfBoundsException
604      *         if {@link #writerIndex()} + {@code minWritableBytes} &gt; {@link #maxCapacity()}.
605      * @see #capacity(int)
606      */
607     abstract ByteBuf ensureWritable(int minWritableBytes);
608 
609     /**
610      * Expands the buffer {@link #capacity()} to make sure the number of
611      * {@linkplain #writableBytes() writable bytes} is equal to or greater than the
612      * specified value. Unlike {@link #ensureWritable(int)}, this method returns a status code.
613      *
614      * @param minWritableBytes
615      *        the expected minimum number of writable bytes
616      * @param force
617      *        When {@link #writerIndex()} + {@code minWritableBytes} &gt; {@link #maxCapacity()}:
618      *        <ul>
619      *        <li>{@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}</li>
620      *        <li>{@code false} - the capacity of the buffer is unchanged</li>
621      *        </ul>
622      * @return {@code 0} if the buffer has enough writable bytes, and its capacity is unchanged.
623      *         {@code 1} if the buffer does not have enough bytes, and its capacity is unchanged.
624      *         {@code 2} if the buffer has enough writable bytes, and its capacity has been increased.
625      *         {@code 3} if the buffer does not have enough bytes, but its capacity has been
626      *                   increased to its maximum.
627      */
628     abstract int ensureWritable(int minWritableBytes, bool force);
629 
630     /**
631      * Gets a bool at the specified absolute (@code index) in this buffer.
632      * This method does not modify the {@code readerIndex} or {@code writerIndex}
633      * of this buffer.
634      *
635      * @throws IndexOutOfBoundsException
636      *         if the specified {@code index} is less than {@code 0} or
637      *         {@code index + 1} is greater than {@code this.capacity}
638      */
639     abstract bool getBoolean(int index);
640 
641     /**
642      * Gets a byte at the specified absolute {@code index} in this buffer.
643      * This method does not modify {@code readerIndex} or {@code writerIndex} of
644      * this buffer.
645      *
646      * @throws IndexOutOfBoundsException
647      *         if the specified {@code index} is less than {@code 0} or
648      *         {@code index + 1} is greater than {@code this.capacity}
649      */
650     abstract byte  getByte(int index);
651 
652     /**
653      * Gets an unsigned byte at the specified absolute {@code index} in this
654      * buffer.  This method does not modify {@code readerIndex} or
655      * {@code writerIndex} of this buffer.
656      *
657      * @throws IndexOutOfBoundsException
658      *         if the specified {@code index} is less than {@code 0} or
659      *         {@code index + 1} is greater than {@code this.capacity}
660      */
661     abstract short getUnsignedByte(int index);
662 
663     /**
664      * Gets a 16-bit short integer at the specified absolute {@code index} in
665      * this buffer.  This method does not modify {@code readerIndex} or
666      * {@code writerIndex} of this buffer.
667      *
668      * @throws IndexOutOfBoundsException
669      *         if the specified {@code index} is less than {@code 0} or
670      *         {@code index + 2} is greater than {@code this.capacity}
671      */
672     abstract short getShort(int index);
673 
674     /**
675      * Gets a 16-bit short integer at the specified absolute {@code index} in
676      * this buffer in Little Endian Byte Order. This method does not modify
677      * {@code readerIndex} or {@code writerIndex} of this buffer.
678      *
679      * @throws IndexOutOfBoundsException
680      *         if the specified {@code index} is less than {@code 0} or
681      *         {@code index + 2} is greater than {@code this.capacity}
682      */
683     abstract short getShortLE(int index);
684 
685     /**
686      * Gets an unsigned 16-bit short integer at the specified absolute
687      * {@code index} in this buffer.  This method does not modify
688      * {@code readerIndex} or {@code writerIndex} of this buffer.
689      *
690      * @throws IndexOutOfBoundsException
691      *         if the specified {@code index} is less than {@code 0} or
692      *         {@code index + 2} is greater than {@code this.capacity}
693      */
694     abstract int getUnsignedShort(int index);
695 
696     /**
697      * Gets an unsigned 16-bit short integer at the specified absolute
698      * {@code index} in this buffer in Little Endian Byte Order.
699      * This method does not modify {@code readerIndex} or
700      * {@code writerIndex} of this buffer.
701      *
702      * @throws IndexOutOfBoundsException
703      *         if the specified {@code index} is less than {@code 0} or
704      *         {@code index + 2} is greater than {@code this.capacity}
705      */
706     abstract int getUnsignedShortLE(int index);
707 
708     /**
709      * Gets a 24-bit medium integer at the specified absolute {@code index} in
710      * this buffer.  This method does not modify {@code readerIndex} or
711      * {@code writerIndex} of this buffer.
712      *
713      * @throws IndexOutOfBoundsException
714      *         if the specified {@code index} is less than {@code 0} or
715      *         {@code index + 3} is greater than {@code this.capacity}
716      */
717     abstract int   getMedium(int index);
718 
719     /**
720      * Gets a 24-bit medium integer at the specified absolute {@code index} in
721      * this buffer in the Little Endian Byte Order. This method does not
722      * modify {@code readerIndex} or {@code writerIndex} of this buffer.
723      *
724      * @throws IndexOutOfBoundsException
725      *         if the specified {@code index} is less than {@code 0} or
726      *         {@code index + 3} is greater than {@code this.capacity}
727      */
728     abstract int getMediumLE(int index);
729 
730     /**
731      * Gets an unsigned 24-bit medium integer at the specified absolute
732      * {@code index} in this buffer.  This method does not modify
733      * {@code readerIndex} or {@code writerIndex} of this buffer.
734      *
735      * @throws IndexOutOfBoundsException
736      *         if the specified {@code index} is less than {@code 0} or
737      *         {@code index + 3} is greater than {@code this.capacity}
738      */
739     abstract int   getUnsignedMedium(int index);
740 
741     /**
742      * Gets an unsigned 24-bit medium integer at the specified absolute
743      * {@code index} in this buffer in Little Endian Byte Order.
744      * This method does not modify {@code readerIndex} or
745      * {@code writerIndex} of this buffer.
746      *
747      * @throws IndexOutOfBoundsException
748      *         if the specified {@code index} is less than {@code 0} or
749      *         {@code index + 3} is greater than {@code this.capacity}
750      */
751     abstract int   getUnsignedMediumLE(int index);
752 
753     /**
754      * Gets a 32-bit integer at the specified absolute {@code index} in
755      * this buffer.  This method does not modify {@code readerIndex} or
756      * {@code writerIndex} of this buffer.
757      *
758      * @throws IndexOutOfBoundsException
759      *         if the specified {@code index} is less than {@code 0} or
760      *         {@code index + 4} is greater than {@code this.capacity}
761      */
762     abstract int   getInt(int index);
763 
764     /**
765      * Gets a 32-bit integer at the specified absolute {@code index} in
766      * this buffer with Little Endian Byte Order. This method does not
767      * modify {@code readerIndex} or {@code writerIndex} of this buffer.
768      *
769      * @throws IndexOutOfBoundsException
770      *         if the specified {@code index} is less than {@code 0} or
771      *         {@code index + 4} is greater than {@code this.capacity}
772      */
773     abstract int   getIntLE(int index);
774 
775     /**
776      * Gets an unsigned 32-bit integer at the specified absolute {@code index}
777      * in this buffer.  This method does not modify {@code readerIndex} or
778      * {@code writerIndex} of this buffer.
779      *
780      * @throws IndexOutOfBoundsException
781      *         if the specified {@code index} is less than {@code 0} or
782      *         {@code index + 4} is greater than {@code this.capacity}
783      */
784     abstract long  getUnsignedInt(int index);
785 
786     /**
787      * Gets an unsigned 32-bit integer at the specified absolute {@code index}
788      * in this buffer in Little Endian Byte Order. This method does not
789      * modify {@code readerIndex} or {@code writerIndex} of this buffer.
790      *
791      * @throws IndexOutOfBoundsException
792      *         if the specified {@code index} is less than {@code 0} or
793      *         {@code index + 4} is greater than {@code this.capacity}
794      */
795     abstract long  getUnsignedIntLE(int index);
796 
797     /**
798      * Gets a 64-bit long integer at the specified absolute {@code index} in
799      * this buffer.  This method does not modify {@code readerIndex} or
800      * {@code writerIndex} of this buffer.
801      *
802      * @throws IndexOutOfBoundsException
803      *         if the specified {@code index} is less than {@code 0} or
804      *         {@code index + 8} is greater than {@code this.capacity}
805      */
806     abstract long  getLong(int index);
807 
808     /**
809      * Gets a 64-bit long integer at the specified absolute {@code index} in
810      * this buffer in Little Endian Byte Order. This method does not
811      * modify {@code readerIndex} or {@code writerIndex} of this buffer.
812      *
813      * @throws IndexOutOfBoundsException
814      *         if the specified {@code index} is less than {@code 0} or
815      *         {@code index + 8} is greater than {@code this.capacity}
816      */
817     abstract long  getLongLE(int index);
818 
819     /**
820      * Gets a 2-byte UTF-16 character at the specified absolute
821      * {@code index} in this buffer.  This method does not modify
822      * {@code readerIndex} or {@code writerIndex} of this buffer.
823      *
824      * @throws IndexOutOfBoundsException
825      *         if the specified {@code index} is less than {@code 0} or
826      *         {@code index + 2} is greater than {@code this.capacity}
827      */
828     abstract char  getChar(int index);
829 
830     /**
831      * Gets a 32-bit floating point number at the specified absolute
832      * {@code index} in this buffer.  This method does not modify
833      * {@code readerIndex} or {@code writerIndex} of this buffer.
834      *
835      * @throws IndexOutOfBoundsException
836      *         if the specified {@code index} is less than {@code 0} or
837      *         {@code index + 4} is greater than {@code this.capacity}
838      */
839     abstract float getFloat(int index);
840 
841     /**
842      * Gets a 32-bit floating point number at the specified absolute
843      * {@code index} in this buffer in Little Endian Byte Order.
844      * This method does not modify {@code readerIndex} or
845      * {@code writerIndex} of this buffer.
846      *
847      * @throws IndexOutOfBoundsException
848      *         if the specified {@code index} is less than {@code 0} or
849      *         {@code index + 4} is greater than {@code this.capacity}
850      */
851     float getFloatLE(int index) {
852         return Float.intBitsToFloat(getIntLE(index));
853     }
854 
855     /**
856      * Gets a 64-bit floating point number at the specified absolute
857      * {@code index} in this buffer.  This method does not modify
858      * {@code readerIndex} or {@code writerIndex} of this buffer.
859      *
860      * @throws IndexOutOfBoundsException
861      *         if the specified {@code index} is less than {@code 0} or
862      *         {@code index + 8} is greater than {@code this.capacity}
863      */
864     abstract double getDouble(int index);
865 
866     /**
867      * Gets a 64-bit floating point number at the specified absolute
868      * {@code index} in this buffer in Little Endian Byte Order.
869      * This method does not modify {@code readerIndex} or
870      * {@code writerIndex} of this buffer.
871      *
872      * @throws IndexOutOfBoundsException
873      *         if the specified {@code index} is less than {@code 0} or
874      *         {@code index + 8} is greater than {@code this.capacity}
875      */
876     double getDoubleLE(int index) {
877         return Double.longBitsToDouble(getLongLE(index));
878     }
879 
880     /**
881      * Transfers this buffer's data to the specified destination starting at
882      * the specified absolute {@code index} until the destination becomes
883      * non-writable.  This method is basically same with
884      * {@link #getBytes(int, ByteBuf, int, int)}, except that this
885      * method increases the {@code writerIndex} of the destination by the
886      * number of the transferred bytes while
887      * {@link #getBytes(int, ByteBuf, int, int)} does not.
888      * This method does not modify {@code readerIndex} or {@code writerIndex} of
889      * the source buffer (i.e. {@code this}).
890      *
891      * @throws IndexOutOfBoundsException
892      *         if the specified {@code index} is less than {@code 0} or
893      *         if {@code index + dst.writableBytes} is greater than
894      *            {@code this.capacity}
895      */
896     abstract ByteBuf getBytes(int index, ByteBuf dst);
897 
898     /**
899      * Transfers this buffer's data to the specified destination starting at
900      * the specified absolute {@code index}.  This method is basically same
901      * with {@link #getBytes(int, ByteBuf, int, int)}, except that this
902      * method increases the {@code writerIndex} of the destination by the
903      * number of the transferred bytes while
904      * {@link #getBytes(int, ByteBuf, int, int)} does not.
905      * This method does not modify {@code readerIndex} or {@code writerIndex} of
906      * the source buffer (i.e. {@code this}).
907      *
908      * @param length the number of bytes to transfer
909      *
910      * @throws IndexOutOfBoundsException
911      *         if the specified {@code index} is less than {@code 0},
912      *         if {@code index + length} is greater than
913      *            {@code this.capacity}, or
914      *         if {@code length} is greater than {@code dst.writableBytes}
915      */
916     abstract ByteBuf getBytes(int index, ByteBuf dst, int length);
917 
918     /**
919      * Transfers this buffer's data to the specified destination starting at
920      * the specified absolute {@code index}.
921      * This method does not modify {@code readerIndex} or {@code writerIndex}
922      * of both the source (i.e. {@code this}) and the destination.
923      *
924      * @param dstIndex the first index of the destination
925      * @param length   the number of bytes to transfer
926      *
927      * @throws IndexOutOfBoundsException
928      *         if the specified {@code index} is less than {@code 0},
929      *         if the specified {@code dstIndex} is less than {@code 0},
930      *         if {@code index + length} is greater than
931      *            {@code this.capacity}, or
932      *         if {@code dstIndex + length} is greater than
933      *            {@code dst.capacity}
934      */
935     abstract ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length);
936 
937     /**
938      * Transfers this buffer's data to the specified destination starting at
939      * the specified absolute {@code index}.
940      * This method does not modify {@code readerIndex} or {@code writerIndex} of
941      * this buffer
942      *
943      * @throws IndexOutOfBoundsException
944      *         if the specified {@code index} is less than {@code 0} or
945      *         if {@code index + dst.length} is greater than
946      *            {@code this.capacity}
947      */
948     abstract ByteBuf getBytes(int index, byte[] dst);
949 
950     /**
951      * Transfers this buffer's data to the specified destination starting at
952      * the specified absolute {@code index}.
953      * This method does not modify {@code readerIndex} or {@code writerIndex}
954      * of this buffer.
955      *
956      * @param dstIndex the first index of the destination
957      * @param length   the number of bytes to transfer
958      *
959      * @throws IndexOutOfBoundsException
960      *         if the specified {@code index} is less than {@code 0},
961      *         if the specified {@code dstIndex} is less than {@code 0},
962      *         if {@code index + length} is greater than
963      *            {@code this.capacity}, or
964      *         if {@code dstIndex + length} is greater than
965      *            {@code dst.length}
966      */
967     abstract ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length);
968 
969     /**
970      * Transfers this buffer's data to the specified destination starting at
971      * the specified absolute {@code index} until the destination's position
972      * reaches its limit.
973      * This method does not modify {@code readerIndex} or {@code writerIndex} of
974      * this buffer while the destination's {@code position} will be increased.
975      *
976      * @throws IndexOutOfBoundsException
977      *         if the specified {@code index} is less than {@code 0} or
978      *         if {@code index + dst.remaining()} is greater than
979      *            {@code this.capacity}
980      */
981     abstract ByteBuf getBytes(int index, ByteBuffer dst);
982 
983     /**
984      * Transfers this buffer's data to the specified stream starting at the
985      * specified absolute {@code index}.
986      * This method does not modify {@code readerIndex} or {@code writerIndex} of
987      * this buffer.
988      *
989      * @param length the number of bytes to transfer
990      *
991      * @throws IndexOutOfBoundsException
992      *         if the specified {@code index} is less than {@code 0} or
993      *         if {@code index + length} is greater than
994      *            {@code this.capacity}
995      * @throws IOException
996      *         if the specified stream threw an exception during I/O
997      */
998     abstract ByteBuf getBytes(int index, OutputStream outStream, int length);
999 
1000     /**
1001      * Transfers this buffer's data to the specified channel starting at the
1002      * specified absolute {@code index}.
1003      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1004      * this buffer.
1005      *
1006      * @param length the maximum number of bytes to transfer
1007      *
1008      * @return the actual number of bytes written out to the specified channel
1009      *
1010      * @throws IndexOutOfBoundsException
1011      *         if the specified {@code index} is less than {@code 0} or
1012      *         if {@code index + length} is greater than
1013      *            {@code this.capacity}
1014      * @throws IOException
1015      *         if the specified channel threw an exception during I/O
1016      */
1017     // abstract int getBytes(int index, GatheringByteChannel out, int length);
1018 
1019     /**
1020      * Transfers this buffer's data starting at the specified absolute {@code index}
1021      * to the specified channel starting at the given file position.
1022      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1023      * this buffer. This method does not modify the channel's position.
1024      *
1025      * @param position the file position at which the transfer is to begin
1026      * @param length the maximum number of bytes to transfer
1027      *
1028      * @return the actual number of bytes written out to the specified channel
1029      *
1030      * @throws IndexOutOfBoundsException
1031      *         if the specified {@code index} is less than {@code 0} or
1032      *         if {@code index + length} is greater than
1033      *            {@code this.capacity}
1034      * @throws IOException
1035      *         if the specified channel threw an exception during I/O
1036      */
1037     // abstract int getBytes(int index, FileChannel out, long position, int length);
1038 
1039     /**
1040      * Gets a {@link CharSequence} with the given length at the given index.
1041      *
1042      * @param length the length to read
1043      * @param charset that should be used
1044      * @return the sequence
1045      * @throws IndexOutOfBoundsException
1046      *         if {@code length} is greater than {@code this.readableBytes}
1047      */
1048     abstract CharSequence getCharSequence(int index, int length, Charset charset);
1049 
1050     /**
1051      * Sets the specified bool at the specified absolute {@code index} in this
1052      * buffer.
1053      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1054      * this buffer.
1055      *
1056      * @throws IndexOutOfBoundsException
1057      *         if the specified {@code index} is less than {@code 0} or
1058      *         {@code index + 1} is greater than {@code this.capacity}
1059      */
1060     abstract ByteBuf setBoolean(int index, bool value);
1061 
1062     /**
1063      * Sets the specified byte at the specified absolute {@code index} in this
1064      * buffer.  The 24 high-order bits of the specified value are ignored.
1065      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1066      * this buffer.
1067      *
1068      * @throws IndexOutOfBoundsException
1069      *         if the specified {@code index} is less than {@code 0} or
1070      *         {@code index + 1} is greater than {@code this.capacity}
1071      */
1072     abstract ByteBuf setByte(int index, int value);
1073 
1074     /**
1075      * Sets the specified 16-bit short integer at the specified absolute
1076      * {@code index} in this buffer.  The 16 high-order bits of the specified
1077      * value are ignored.
1078      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1079      * this buffer.
1080      *
1081      * @throws IndexOutOfBoundsException
1082      *         if the specified {@code index} is less than {@code 0} or
1083      *         {@code index + 2} is greater than {@code this.capacity}
1084      */
1085     abstract ByteBuf setShort(int index, int value);
1086 
1087     /**
1088      * Sets the specified 16-bit short integer at the specified absolute
1089      * {@code index} in this buffer with the Little Endian Byte Order.
1090      * The 16 high-order bits of the specified value are ignored.
1091      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1092      * this buffer.
1093      *
1094      * @throws IndexOutOfBoundsException
1095      *         if the specified {@code index} is less than {@code 0} or
1096      *         {@code index + 2} is greater than {@code this.capacity}
1097      */
1098     abstract ByteBuf setShortLE(int index, int value);
1099 
1100     /**
1101      * Sets the specified 24-bit medium integer at the specified absolute
1102      * {@code index} in this buffer.  Please note that the most significant
1103      * byte is ignored in the specified value.
1104      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1105      * this buffer.
1106      *
1107      * @throws IndexOutOfBoundsException
1108      *         if the specified {@code index} is less than {@code 0} or
1109      *         {@code index + 3} is greater than {@code this.capacity}
1110      */
1111     abstract ByteBuf setMedium(int index, int value);
1112 
1113     /**
1114      * Sets the specified 24-bit medium integer at the specified absolute
1115      * {@code index} in this buffer in the Little Endian Byte Order.
1116      * Please note that the most significant byte is ignored in the
1117      * specified value.
1118      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1119      * this buffer.
1120      *
1121      * @throws IndexOutOfBoundsException
1122      *         if the specified {@code index} is less than {@code 0} or
1123      *         {@code index + 3} is greater than {@code this.capacity}
1124      */
1125     abstract ByteBuf setMediumLE(int index, int value);
1126 
1127     /**
1128      * Sets the specified 32-bit integer at the specified absolute
1129      * {@code index} in this buffer.
1130      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1131      * this buffer.
1132      *
1133      * @throws IndexOutOfBoundsException
1134      *         if the specified {@code index} is less than {@code 0} or
1135      *         {@code index + 4} is greater than {@code this.capacity}
1136      */
1137     abstract ByteBuf setInt(int index, int value);
1138 
1139     /**
1140      * Sets the specified 32-bit integer at the specified absolute
1141      * {@code index} in this buffer with Little Endian byte order
1142      * .
1143      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1144      * this buffer.
1145      *
1146      * @throws IndexOutOfBoundsException
1147      *         if the specified {@code index} is less than {@code 0} or
1148      *         {@code index + 4} is greater than {@code this.capacity}
1149      */
1150     abstract ByteBuf setIntLE(int index, int value);
1151 
1152     /**
1153      * Sets the specified 64-bit long integer at the specified absolute
1154      * {@code index} in this buffer.
1155      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1156      * this buffer.
1157      *
1158      * @throws IndexOutOfBoundsException
1159      *         if the specified {@code index} is less than {@code 0} or
1160      *         {@code index + 8} is greater than {@code this.capacity}
1161      */
1162     abstract ByteBuf setLong(int index, long value);
1163 
1164     /**
1165      * Sets the specified 64-bit long integer at the specified absolute
1166      * {@code index} in this buffer in Little Endian Byte Order.
1167      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1168      * this buffer.
1169      *
1170      * @throws IndexOutOfBoundsException
1171      *         if the specified {@code index} is less than {@code 0} or
1172      *         {@code index + 8} is greater than {@code this.capacity}
1173      */
1174     abstract ByteBuf setLongLE(int index, long value);
1175 
1176     /**
1177      * Sets the specified 2-byte UTF-16 character at the specified absolute
1178      * {@code index} in this buffer.
1179      * The 16 high-order bits of the specified value are ignored.
1180      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1181      * this buffer.
1182      *
1183      * @throws IndexOutOfBoundsException
1184      *         if the specified {@code index} is less than {@code 0} or
1185      *         {@code index + 2} is greater than {@code this.capacity}
1186      */
1187     abstract ByteBuf setChar(int index, int value);
1188 
1189     /**
1190      * Sets the specified 32-bit floating-point number at the specified
1191      * absolute {@code index} in this buffer.
1192      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1193      * this buffer.
1194      *
1195      * @throws IndexOutOfBoundsException
1196      *         if the specified {@code index} is less than {@code 0} or
1197      *         {@code index + 4} is greater than {@code this.capacity}
1198      */
1199     abstract ByteBuf setFloat(int index, float value);
1200 
1201     /**
1202      * Sets the specified 32-bit floating-point number at the specified
1203      * absolute {@code index} in this buffer in Little Endian Byte Order.
1204      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1205      * this buffer.
1206      *
1207      * @throws IndexOutOfBoundsException
1208      *         if the specified {@code index} is less than {@code 0} or
1209      *         {@code index + 4} is greater than {@code this.capacity}
1210      */
1211     ByteBuf setFloatLE(int index, float value) {
1212         return setIntLE(index, Float.floatToRawIntBits(value));
1213     }
1214 
1215     /**
1216      * Sets the specified 64-bit floating-point number at the specified
1217      * absolute {@code index} in this buffer.
1218      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1219      * this buffer.
1220      *
1221      * @throws IndexOutOfBoundsException
1222      *         if the specified {@code index} is less than {@code 0} or
1223      *         {@code index + 8} is greater than {@code this.capacity}
1224      */
1225     abstract ByteBuf setDouble(int index, double value);
1226 
1227     /**
1228      * Sets the specified 64-bit floating-point number at the specified
1229      * absolute {@code index} in this buffer in Little Endian Byte Order.
1230      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1231      * this buffer.
1232      *
1233      * @throws IndexOutOfBoundsException
1234      *         if the specified {@code index} is less than {@code 0} or
1235      *         {@code index + 8} is greater than {@code this.capacity}
1236      */
1237     ByteBuf setDoubleLE(int index, double value) {
1238         return setLongLE(index, Double.doubleToRawLongBits(value));
1239     }
1240 
1241     /**
1242      * Transfers the specified source buffer's data to this buffer starting at
1243      * the specified absolute {@code index} until the source buffer becomes
1244      * unreadable.  This method is basically same with
1245      * {@link #setBytes(int, ByteBuf, int, int)}, except that this
1246      * method increases the {@code readerIndex} of the source buffer by
1247      * the number of the transferred bytes while
1248      * {@link #setBytes(int, ByteBuf, int, int)} does not.
1249      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1250      * the source buffer (i.e. {@code this}).
1251      *
1252      * @throws IndexOutOfBoundsException
1253      *         if the specified {@code index} is less than {@code 0} or
1254      *         if {@code index + src.readableBytes} is greater than
1255      *            {@code this.capacity}
1256      */
1257     abstract ByteBuf setBytes(int index, ByteBuf src);
1258 
1259     /**
1260      * Transfers the specified source buffer's data to this buffer starting at
1261      * the specified absolute {@code index}.  This method is basically same
1262      * with {@link #setBytes(int, ByteBuf, int, int)}, except that this
1263      * method increases the {@code readerIndex} of the source buffer by
1264      * the number of the transferred bytes while
1265      * {@link #setBytes(int, ByteBuf, int, int)} does not.
1266      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1267      * the source buffer (i.e. {@code this}).
1268      *
1269      * @param length the number of bytes to transfer
1270      *
1271      * @throws IndexOutOfBoundsException
1272      *         if the specified {@code index} is less than {@code 0},
1273      *         if {@code index + length} is greater than
1274      *            {@code this.capacity}, or
1275      *         if {@code length} is greater than {@code src.readableBytes}
1276      */
1277     abstract ByteBuf setBytes(int index, ByteBuf src, int length);
1278 
1279     /**
1280      * Transfers the specified source buffer's data to this buffer starting at
1281      * the specified absolute {@code index}.
1282      * This method does not modify {@code readerIndex} or {@code writerIndex}
1283      * of both the source (i.e. {@code this}) and the destination.
1284      *
1285      * @param srcIndex the first index of the source
1286      * @param length   the number of bytes to transfer
1287      *
1288      * @throws IndexOutOfBoundsException
1289      *         if the specified {@code index} is less than {@code 0},
1290      *         if the specified {@code srcIndex} is less than {@code 0},
1291      *         if {@code index + length} is greater than
1292      *            {@code this.capacity}, or
1293      *         if {@code srcIndex + length} is greater than
1294      *            {@code src.capacity}
1295      */
1296     abstract ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length);
1297 
1298     /**
1299      * Transfers the specified source array's data to this buffer starting at
1300      * the specified absolute {@code index}.
1301      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1302      * this buffer.
1303      *
1304      * @throws IndexOutOfBoundsException
1305      *         if the specified {@code index} is less than {@code 0} or
1306      *         if {@code index + src.length} is greater than
1307      *            {@code this.capacity}
1308      */
1309     abstract ByteBuf setBytes(int index, byte[] src);
1310 
1311     /**
1312      * Transfers the specified source array's data to this buffer starting at
1313      * the specified absolute {@code index}.
1314      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1315      * this buffer.
1316      *
1317      * @throws IndexOutOfBoundsException
1318      *         if the specified {@code index} is less than {@code 0},
1319      *         if the specified {@code srcIndex} is less than {@code 0},
1320      *         if {@code index + length} is greater than
1321      *            {@code this.capacity}, or
1322      *         if {@code srcIndex + length} is greater than {@code src.length}
1323      */
1324     abstract ByteBuf setBytes(int index, byte[] src, int srcIndex, int length);
1325 
1326     /**
1327      * Transfers the specified source buffer's data to this buffer starting at
1328      * the specified absolute {@code index} until the source buffer's position
1329      * reaches its limit.
1330      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1331      * this buffer.
1332      *
1333      * @throws IndexOutOfBoundsException
1334      *         if the specified {@code index} is less than {@code 0} or
1335      *         if {@code index + src.remaining()} is greater than
1336      *            {@code this.capacity}
1337      */
1338     abstract ByteBuf setBytes(int index, ByteBuffer src);
1339 
1340     /**
1341      * Transfers the content of the specified source stream to this buffer
1342      * starting at the specified absolute {@code index}.
1343      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1344      * this buffer.
1345      *
1346      * @param length the number of bytes to transfer
1347      *
1348      * @return the actual number of bytes read in from the specified channel.
1349      *         {@code -1} if the specified channel is closed.
1350      *
1351      * @throws IndexOutOfBoundsException
1352      *         if the specified {@code index} is less than {@code 0} or
1353      *         if {@code index + length} is greater than {@code this.capacity}
1354      * @throws IOException
1355      *         if the specified stream threw an exception during I/O
1356      */
1357     abstract int setBytes(int index, InputStream inStream, int length);
1358 
1359     /**
1360      * Transfers the content of the specified source channel to this buffer
1361      * starting at the specified absolute {@code index}.
1362      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1363      * this buffer.
1364      *
1365      * @param length the maximum number of bytes to transfer
1366      *
1367      * @return the actual number of bytes read in from the specified channel.
1368      *         {@code -1} if the specified channel is closed.
1369      *
1370      * @throws IndexOutOfBoundsException
1371      *         if the specified {@code index} is less than {@code 0} or
1372      *         if {@code index + length} is greater than {@code this.capacity}
1373      * @throws IOException
1374      *         if the specified channel threw an exception during I/O
1375      */
1376     // abstract int setBytes(int index, ScatteringByteChannel in, int length);
1377 
1378     /**
1379      * Transfers the content of the specified source channel starting at the given file position
1380      * to this buffer starting at the specified absolute {@code index}.
1381      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1382      * this buffer. This method does not modify the channel's position.
1383      *
1384      * @param position the file position at which the transfer is to begin
1385      * @param length the maximum number of bytes to transfer
1386      *
1387      * @return the actual number of bytes read in from the specified channel.
1388      *         {@code -1} if the specified channel is closed.
1389      *
1390      * @throws IndexOutOfBoundsException
1391      *         if the specified {@code index} is less than {@code 0} or
1392      *         if {@code index + length} is greater than {@code this.capacity}
1393      * @throws IOException
1394      *         if the specified channel threw an exception during I/O
1395      */
1396     // abstract int setBytes(int index, FileChannel in, long position, int length);
1397 
1398     /**
1399      * Fills this buffer with <tt>NUL (0x00)</tt> starting at the specified
1400      * absolute {@code index}.
1401      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1402      * this buffer.
1403      *
1404      * @param length the number of <tt>NUL</tt>s to write to the buffer
1405      *
1406      * @throws IndexOutOfBoundsException
1407      *         if the specified {@code index} is less than {@code 0} or
1408      *         if {@code index + length} is greater than {@code this.capacity}
1409      */
1410     abstract ByteBuf setZero(int index, int length);
1411 
1412     /**
1413      * Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
1414      * the {@code writerIndex} by the written bytes.
1415      *
1416      * @param index on which the sequence should be written
1417      * @param sequence to write
1418      * @param charset that should be used.
1419      * @return the written number of bytes.
1420      * @throws IndexOutOfBoundsException
1421      *         if {@code this.writableBytes} is not large enough to write the whole sequence
1422      */
1423     abstract int setCharSequence(int index, CharSequence sequence, Charset charset);
1424 
1425     /**
1426      * Gets a bool at the current {@code readerIndex} and increases
1427      * the {@code readerIndex} by {@code 1} in this buffer.
1428      *
1429      * @throws IndexOutOfBoundsException
1430      *         if {@code this.readableBytes} is less than {@code 1}
1431      */
1432     abstract bool readBoolean();
1433 
1434     /**
1435      * Gets a byte at the current {@code readerIndex} and increases
1436      * the {@code readerIndex} by {@code 1} in this buffer.
1437      *
1438      * @throws IndexOutOfBoundsException
1439      *         if {@code this.readableBytes} is less than {@code 1}
1440      */
1441     abstract byte  readByte();
1442 
1443     /**
1444      * Gets an unsigned byte at the current {@code readerIndex} and increases
1445      * the {@code readerIndex} by {@code 1} in this buffer.
1446      *
1447      * @throws IndexOutOfBoundsException
1448      *         if {@code this.readableBytes} is less than {@code 1}
1449      */
1450     abstract short readUnsignedByte();
1451 
1452     /**
1453      * Gets a 16-bit short integer at the current {@code readerIndex}
1454      * and increases the {@code readerIndex} by {@code 2} in this buffer.
1455      *
1456      * @throws IndexOutOfBoundsException
1457      *         if {@code this.readableBytes} is less than {@code 2}
1458      */
1459     abstract short readShort();
1460 
1461     /**
1462      * Gets a 16-bit short integer at the current {@code readerIndex}
1463      * in the Little Endian Byte Order and increases the {@code readerIndex}
1464      * by {@code 2} in this buffer.
1465      *
1466      * @throws IndexOutOfBoundsException
1467      *         if {@code this.readableBytes} is less than {@code 2}
1468      */
1469     abstract short readShortLE();
1470 
1471     /**
1472      * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
1473      * and increases the {@code readerIndex} by {@code 2} in this buffer.
1474      *
1475      * @throws IndexOutOfBoundsException
1476      *         if {@code this.readableBytes} is less than {@code 2}
1477      */
1478     abstract int   readUnsignedShort();
1479 
1480     /**
1481      * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
1482      * in the Little Endian Byte Order and increases the {@code readerIndex}
1483      * by {@code 2} in this buffer.
1484      *
1485      * @throws IndexOutOfBoundsException
1486      *         if {@code this.readableBytes} is less than {@code 2}
1487      */
1488     abstract int   readUnsignedShortLE();
1489 
1490     /**
1491      * Gets a 24-bit medium integer at the current {@code readerIndex}
1492      * and increases the {@code readerIndex} by {@code 3} in this buffer.
1493      *
1494      * @throws IndexOutOfBoundsException
1495      *         if {@code this.readableBytes} is less than {@code 3}
1496      */
1497     abstract int   readMedium();
1498 
1499     /**
1500      * Gets a 24-bit medium integer at the current {@code readerIndex}
1501      * in the Little Endian Byte Order and increases the
1502      * {@code readerIndex} by {@code 3} in this buffer.
1503      *
1504      * @throws IndexOutOfBoundsException
1505      *         if {@code this.readableBytes} is less than {@code 3}
1506      */
1507     abstract int   readMediumLE();
1508 
1509     /**
1510      * Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
1511      * and increases the {@code readerIndex} by {@code 3} in this buffer.
1512      *
1513      * @throws IndexOutOfBoundsException
1514      *         if {@code this.readableBytes} is less than {@code 3}
1515      */
1516     abstract int   readUnsignedMedium();
1517 
1518     /**
1519      * Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
1520      * in the Little Endian Byte Order and increases the {@code readerIndex}
1521      * by {@code 3} in this buffer.
1522      *
1523      * @throws IndexOutOfBoundsException
1524      *         if {@code this.readableBytes} is less than {@code 3}
1525      */
1526     abstract int   readUnsignedMediumLE();
1527 
1528     /**
1529      * Gets a 32-bit integer at the current {@code readerIndex}
1530      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1531      *
1532      * @throws IndexOutOfBoundsException
1533      *         if {@code this.readableBytes} is less than {@code 4}
1534      */
1535     abstract int   readInt();
1536 
1537     /**
1538      * Gets a 32-bit integer at the current {@code readerIndex}
1539      * in the Little Endian Byte Order and increases the {@code readerIndex}
1540      * by {@code 4} in this buffer.
1541      *
1542      * @throws IndexOutOfBoundsException
1543      *         if {@code this.readableBytes} is less than {@code 4}
1544      */
1545     abstract int   readIntLE();
1546 
1547     /**
1548      * Gets an unsigned 32-bit integer at the current {@code readerIndex}
1549      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1550      *
1551      * @throws IndexOutOfBoundsException
1552      *         if {@code this.readableBytes} is less than {@code 4}
1553      */
1554     abstract long  readUnsignedInt();
1555 
1556     /**
1557      * Gets an unsigned 32-bit integer at the current {@code readerIndex}
1558      * in the Little Endian Byte Order and increases the {@code readerIndex}
1559      * by {@code 4} in this buffer.
1560      *
1561      * @throws IndexOutOfBoundsException
1562      *         if {@code this.readableBytes} is less than {@code 4}
1563      */
1564     abstract long  readUnsignedIntLE();
1565 
1566     /**
1567      * Gets a 64-bit integer at the current {@code readerIndex}
1568      * and increases the {@code readerIndex} by {@code 8} in this buffer.
1569      *
1570      * @throws IndexOutOfBoundsException
1571      *         if {@code this.readableBytes} is less than {@code 8}
1572      */
1573     abstract long  readLong();
1574 
1575     /**
1576      * Gets a 64-bit integer at the current {@code readerIndex}
1577      * in the Little Endian Byte Order and increases the {@code readerIndex}
1578      * by {@code 8} in this buffer.
1579      *
1580      * @throws IndexOutOfBoundsException
1581      *         if {@code this.readableBytes} is less than {@code 8}
1582      */
1583     abstract long  readLongLE();
1584 
1585     /**
1586      * Gets a 2-byte UTF-16 character at the current {@code readerIndex}
1587      * and increases the {@code readerIndex} by {@code 2} in this buffer.
1588      *
1589      * @throws IndexOutOfBoundsException
1590      *         if {@code this.readableBytes} is less than {@code 2}
1591      */
1592     abstract char  readChar();
1593 
1594     /**
1595      * Gets a 32-bit floating point number at the current {@code readerIndex}
1596      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1597      *
1598      * @throws IndexOutOfBoundsException
1599      *         if {@code this.readableBytes} is less than {@code 4}
1600      */
1601     abstract float readFloat();
1602 
1603     /**
1604      * Gets a 32-bit floating point number at the current {@code readerIndex}
1605      * in Little Endian Byte Order and increases the {@code readerIndex}
1606      * by {@code 4} in this buffer.
1607      *
1608      * @throws IndexOutOfBoundsException
1609      *         if {@code this.readableBytes} is less than {@code 4}
1610      */
1611     float readFloatLE() {
1612         return Float.intBitsToFloat(readIntLE());
1613     }
1614 
1615     /**
1616      * Gets a 64-bit floating point number at the current {@code readerIndex}
1617      * and increases the {@code readerIndex} by {@code 8} in this buffer.
1618      *
1619      * @throws IndexOutOfBoundsException
1620      *         if {@code this.readableBytes} is less than {@code 8}
1621      */
1622     abstract double readDouble();
1623 
1624     /**
1625      * Gets a 64-bit floating point number at the current {@code readerIndex}
1626      * in Little Endian Byte Order and increases the {@code readerIndex}
1627      * by {@code 8} in this buffer.
1628      *
1629      * @throws IndexOutOfBoundsException
1630      *         if {@code this.readableBytes} is less than {@code 8}
1631      */
1632     double readDoubleLE() {
1633         return Double.longBitsToDouble(readLongLE());
1634     }
1635 
1636     /**
1637      * Transfers this buffer's data to a newly created buffer starting at
1638      * the current {@code readerIndex} and increases the {@code readerIndex}
1639      * by the number of the transferred bytes (= {@code length}).
1640      * The returned buffer's {@code readerIndex} and {@code writerIndex} are
1641      * {@code 0} and {@code length} respectively.
1642      *
1643      * @param length the number of bytes to transfer
1644      *
1645      * @return the newly created buffer which contains the transferred bytes
1646      *
1647      * @throws IndexOutOfBoundsException
1648      *         if {@code length} is greater than {@code this.readableBytes}
1649      */
1650     abstract ByteBuf readBytes(int length);
1651 
1652     /**
1653      * Returns a new slice of this buffer's sub-region starting at the current
1654      * {@code readerIndex} and increases the {@code readerIndex} by the size
1655      * of the new slice (= {@code length}).
1656      * <p>
1657      * Also be aware that this method will NOT call {@link #retain()} and so the
1658      * reference count will NOT be increased.
1659      *
1660      * @param length the size of the new slice
1661      *
1662      * @return the newly created slice
1663      *
1664      * @throws IndexOutOfBoundsException
1665      *         if {@code length} is greater than {@code this.readableBytes}
1666      */
1667     abstract ByteBuf readSlice(int length);
1668 
1669     /**
1670      * Returns a new retained slice of this buffer's sub-region starting at the current
1671      * {@code readerIndex} and increases the {@code readerIndex} by the size
1672      * of the new slice (= {@code length}).
1673      * <p>
1674      * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #readSlice(int)}.
1675      * This method behaves similarly to {@code readSlice(...).retain()} except that this method may return
1676      * a buffer implementation that produces less garbage.
1677      *
1678      * @param length the size of the new slice
1679      *
1680      * @return the newly created slice
1681      *
1682      * @throws IndexOutOfBoundsException
1683      *         if {@code length} is greater than {@code this.readableBytes}
1684      */
1685     abstract ByteBuf readRetainedSlice(int length);
1686 
1687     /**
1688      * Transfers this buffer's data to the specified destination starting at
1689      * the current {@code readerIndex} until the destination becomes
1690      * non-writable, and increases the {@code readerIndex} by the number of the
1691      * transferred bytes.  This method is basically same with
1692      * {@link #readBytes(ByteBuf, int, int)}, except that this method
1693      * increases the {@code writerIndex} of the destination by the number of
1694      * the transferred bytes while {@link #readBytes(ByteBuf, int, int)}
1695      * does not.
1696      *
1697      * @throws IndexOutOfBoundsException
1698      *         if {@code dst.writableBytes} is greater than
1699      *            {@code this.readableBytes}
1700      */
1701     abstract ByteBuf readBytes(ByteBuf dst);
1702 
1703     /**
1704      * Transfers this buffer's data to the specified destination starting at
1705      * the current {@code readerIndex} and increases the {@code readerIndex}
1706      * by the number of the transferred bytes (= {@code length}).  This method
1707      * is basically same with {@link #readBytes(ByteBuf, int, int)},
1708      * except that this method increases the {@code writerIndex} of the
1709      * destination by the number of the transferred bytes (= {@code length})
1710      * while {@link #readBytes(ByteBuf, int, int)} does not.
1711      *
1712      * @throws IndexOutOfBoundsException
1713      *         if {@code length} is greater than {@code this.readableBytes} or
1714      *         if {@code length} is greater than {@code dst.writableBytes}
1715      */
1716     abstract ByteBuf readBytes(ByteBuf dst, int length);
1717 
1718     /**
1719      * Transfers this buffer's data to the specified destination starting at
1720      * the current {@code readerIndex} and increases the {@code readerIndex}
1721      * by the number of the transferred bytes (= {@code length}).
1722      *
1723      * @param dstIndex the first index of the destination
1724      * @param length   the number of bytes to transfer
1725      *
1726      * @throws IndexOutOfBoundsException
1727      *         if the specified {@code dstIndex} is less than {@code 0},
1728      *         if {@code length} is greater than {@code this.readableBytes}, or
1729      *         if {@code dstIndex + length} is greater than
1730      *            {@code dst.capacity}
1731      */
1732     abstract ByteBuf readBytes(ByteBuf dst, int dstIndex, int length);
1733 
1734     /**
1735      * Transfers this buffer's data to the specified destination starting at
1736      * the current {@code readerIndex} and increases the {@code readerIndex}
1737      * by the number of the transferred bytes (= {@code dst.length}).
1738      *
1739      * @throws IndexOutOfBoundsException
1740      *         if {@code dst.length} is greater than {@code this.readableBytes}
1741      */
1742     abstract ByteBuf readBytes(byte[] dst);
1743 
1744     /**
1745      * Transfers this buffer's data to the specified destination starting at
1746      * the current {@code readerIndex} and increases the {@code readerIndex}
1747      * by the number of the transferred bytes (= {@code length}).
1748      *
1749      * @param dstIndex the first index of the destination
1750      * @param length   the number of bytes to transfer
1751      *
1752      * @throws IndexOutOfBoundsException
1753      *         if the specified {@code dstIndex} is less than {@code 0},
1754      *         if {@code length} is greater than {@code this.readableBytes}, or
1755      *         if {@code dstIndex + length} is greater than {@code dst.length}
1756      */
1757     abstract ByteBuf readBytes(byte[] dst, int dstIndex, int length);
1758 
1759     /**
1760      * Transfers this buffer's data to the specified destination starting at
1761      * the current {@code readerIndex} until the destination's position
1762      * reaches its limit, and increases the {@code readerIndex} by the
1763      * number of the transferred bytes.
1764      *
1765      * @throws IndexOutOfBoundsException
1766      *         if {@code dst.remaining()} is greater than
1767      *            {@code this.readableBytes}
1768      */
1769     abstract ByteBuf readBytes(ByteBuffer dst);
1770 
1771     /**
1772      * Transfers this buffer's data to the specified stream starting at the
1773      * current {@code readerIndex}.
1774      *
1775      * @param length the number of bytes to transfer
1776      *
1777      * @throws IndexOutOfBoundsException
1778      *         if {@code length} is greater than {@code this.readableBytes}
1779      * @throws IOException
1780      *         if the specified stream threw an exception during I/O
1781      */
1782     abstract ByteBuf readBytes(OutputStream outStream, int length);
1783 
1784     /**
1785      * Transfers this buffer's data to the specified stream starting at the
1786      * current {@code readerIndex}.
1787      *
1788      * @param length the maximum number of bytes to transfer
1789      *
1790      * @return the actual number of bytes written out to the specified channel
1791      *
1792      * @throws IndexOutOfBoundsException
1793      *         if {@code length} is greater than {@code this.readableBytes}
1794      * @throws IOException
1795      *         if the specified channel threw an exception during I/O
1796      */
1797     // abstract int readBytes(GatheringByteChannel out, int length);
1798 
1799     /**
1800      * Gets a {@link CharSequence} with the given length at the current {@code readerIndex}
1801      * and increases the {@code readerIndex} by the given length.
1802      *
1803      * @param length the length to read
1804      * @param charset that should be used
1805      * @return the sequence
1806      * @throws IndexOutOfBoundsException
1807      *         if {@code length} is greater than {@code this.readableBytes}
1808      */
1809     abstract CharSequence readCharSequence(int length, Charset charset);
1810 
1811     /**
1812      * Transfers this buffer's data starting at the current {@code readerIndex}
1813      * to the specified channel starting at the given file position.
1814      * This method does not modify the channel's position.
1815      *
1816      * @param position the file position at which the transfer is to begin
1817      * @param length the maximum number of bytes to transfer
1818      *
1819      * @return the actual number of bytes written out to the specified channel
1820      *
1821      * @throws IndexOutOfBoundsException
1822      *         if {@code length} is greater than {@code this.readableBytes}
1823      * @throws IOException
1824      *         if the specified channel threw an exception during I/O
1825      */
1826     // abstract int readBytes(FileChannel out, long position, int length);
1827 
1828     /**
1829      * Increases the current {@code readerIndex} by the specified
1830      * {@code length} in this buffer.
1831      *
1832      * @throws IndexOutOfBoundsException
1833      *         if {@code length} is greater than {@code this.readableBytes}
1834      */
1835     abstract ByteBuf skipBytes(int length);
1836 
1837     /**
1838      * Sets the specified bool at the current {@code writerIndex}
1839      * and increases the {@code writerIndex} by {@code 1} in this buffer.
1840      * If {@code this.writableBytes} is less than {@code 1}, {@link #ensureWritable(int)}
1841      * will be called in an attempt to expand capacity to accommodate.
1842      */
1843     abstract ByteBuf writeBoolean(bool value);
1844 
1845     /**
1846      * Sets the specified byte at the current {@code writerIndex}
1847      * and increases the {@code writerIndex} by {@code 1} in this buffer.
1848      * The 24 high-order bits of the specified value are ignored.
1849      * If {@code this.writableBytes} is less than {@code 1}, {@link #ensureWritable(int)}
1850      * will be called in an attempt to expand capacity to accommodate.
1851      */
1852     abstract ByteBuf writeByte(int value);
1853 
1854     /**
1855      * Sets the specified 16-bit short integer at the current
1856      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1857      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1858      * If {@code this.writableBytes} is less than {@code 2}, {@link #ensureWritable(int)}
1859      * will be called in an attempt to expand capacity to accommodate.
1860      */
1861     abstract ByteBuf writeShort(int value);
1862 
1863     /**
1864      * Sets the specified 16-bit short integer in the Little Endian Byte
1865      * Order at the current {@code writerIndex} and increases the
1866      * {@code writerIndex} by {@code 2} in this buffer.
1867      * The 16 high-order bits of the specified value are ignored.
1868      * If {@code this.writableBytes} is less than {@code 2}, {@link #ensureWritable(int)}
1869      * will be called in an attempt to expand capacity to accommodate.
1870      */
1871     abstract ByteBuf writeShortLE(int value);
1872 
1873     /**
1874      * Sets the specified 24-bit medium integer at the current
1875      * {@code writerIndex} and increases the {@code writerIndex} by {@code 3}
1876      * in this buffer.
1877      * If {@code this.writableBytes} is less than {@code 3}, {@link #ensureWritable(int)}
1878      * will be called in an attempt to expand capacity to accommodate.
1879      */
1880     abstract ByteBuf writeMedium(int value);
1881 
1882     /**
1883      * Sets the specified 24-bit medium integer at the current
1884      * {@code writerIndex} in the Little Endian Byte Order and
1885      * increases the {@code writerIndex} by {@code 3} in this
1886      * buffer.
1887      * If {@code this.writableBytes} is less than {@code 3}, {@link #ensureWritable(int)}
1888      * will be called in an attempt to expand capacity to accommodate.
1889      */
1890     abstract ByteBuf writeMediumLE(int value);
1891 
1892     /**
1893      * Sets the specified 32-bit integer at the current {@code writerIndex}
1894      * and increases the {@code writerIndex} by {@code 4} in this buffer.
1895      * If {@code this.writableBytes} is less than {@code 4}, {@link #ensureWritable(int)}
1896      * will be called in an attempt to expand capacity to accommodate.
1897      */
1898     abstract ByteBuf writeInt(int value);
1899 
1900     /**
1901      * Sets the specified 32-bit integer at the current {@code writerIndex}
1902      * in the Little Endian Byte Order and increases the {@code writerIndex}
1903      * by {@code 4} in this buffer.
1904      * If {@code this.writableBytes} is less than {@code 4}, {@link #ensureWritable(int)}
1905      * will be called in an attempt to expand capacity to accommodate.
1906      */
1907     abstract ByteBuf writeIntLE(int value);
1908 
1909     /**
1910      * Sets the specified 64-bit long integer at the current
1911      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1912      * in this buffer.
1913      * If {@code this.writableBytes} is less than {@code 8}, {@link #ensureWritable(int)}
1914      * will be called in an attempt to expand capacity to accommodate.
1915      */
1916     abstract ByteBuf writeLong(long value);
1917 
1918     /**
1919      * Sets the specified 64-bit long integer at the current
1920      * {@code writerIndex} in the Little Endian Byte Order and
1921      * increases the {@code writerIndex} by {@code 8}
1922      * in this buffer.
1923      * If {@code this.writableBytes} is less than {@code 8}, {@link #ensureWritable(int)}
1924      * will be called in an attempt to expand capacity to accommodate.
1925      */
1926     abstract ByteBuf writeLongLE(long value);
1927 
1928     /**
1929      * Sets the specified 2-byte UTF-16 character at the current
1930      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1931      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1932      * If {@code this.writableBytes} is less than {@code 2}, {@link #ensureWritable(int)}
1933      * will be called in an attempt to expand capacity to accommodate.
1934      */
1935     abstract ByteBuf writeChar(int value);
1936 
1937     /**
1938      * Sets the specified 32-bit floating point number at the current
1939      * {@code writerIndex} and increases the {@code writerIndex} by {@code 4}
1940      * in this buffer.
1941      * If {@code this.writableBytes} is less than {@code 4}, {@link #ensureWritable(int)}
1942      * will be called in an attempt to expand capacity to accommodate.
1943      */
1944     abstract ByteBuf writeFloat(float value);
1945 
1946     /**
1947      * Sets the specified 32-bit floating point number at the current
1948      * {@code writerIndex} in Little Endian Byte Order and increases
1949      * the {@code writerIndex} by {@code 4} in this buffer.
1950      * If {@code this.writableBytes} is less than {@code 4}, {@link #ensureWritable(int)}
1951      * will be called in an attempt to expand capacity to accommodate.
1952      */
1953     ByteBuf writeFloatLE(float value) {
1954         return writeIntLE(Float.floatToRawIntBits(value));
1955     }
1956 
1957     /**
1958      * Sets the specified 64-bit floating point number at the current
1959      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1960      * in this buffer.
1961      * If {@code this.writableBytes} is less than {@code 8}, {@link #ensureWritable(int)}
1962      * will be called in an attempt to expand capacity to accommodate.
1963      */
1964     abstract ByteBuf writeDouble(double value);
1965 
1966     /**
1967      * Sets the specified 64-bit floating point number at the current
1968      * {@code writerIndex} in Little Endian Byte Order and increases
1969      * the {@code writerIndex} by {@code 8} in this buffer.
1970      * If {@code this.writableBytes} is less than {@code 8}, {@link #ensureWritable(int)}
1971      * will be called in an attempt to expand capacity to accommodate.
1972      */
1973     ByteBuf writeDoubleLE(double value) {
1974         return writeLongLE(Double.doubleToRawLongBits(value));
1975     }
1976 
1977     /**
1978      * Transfers the specified source buffer's data to this buffer starting at
1979      * the current {@code writerIndex} until the source buffer becomes
1980      * unreadable, and increases the {@code writerIndex} by the number of
1981      * the transferred bytes.  This method is basically same with
1982      * {@link #writeBytes(ByteBuf, int, int)}, except that this method
1983      * increases the {@code readerIndex} of the source buffer by the number of
1984      * the transferred bytes while {@link #writeBytes(ByteBuf, int, int)}
1985      * does not.
1986      * If {@code this.writableBytes} is less than {@code src.readableBytes},
1987      * {@link #ensureWritable(int)} will be called in an attempt to expand
1988      * capacity to accommodate.
1989      */
1990     abstract ByteBuf writeBytes(ByteBuf src);
1991 
1992     /**
1993      * Transfers the specified source buffer's data to this buffer starting at
1994      * the current {@code writerIndex} and increases the {@code writerIndex}
1995      * by the number of the transferred bytes (= {@code length}).  This method
1996      * is basically same with {@link #writeBytes(ByteBuf, int, int)},
1997      * except that this method increases the {@code readerIndex} of the source
1998      * buffer by the number of the transferred bytes (= {@code length}) while
1999      * {@link #writeBytes(ByteBuf, int, int)} does not.
2000      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2001      * will be called in an attempt to expand capacity to accommodate.
2002      *
2003      * @param length the number of bytes to transfer
2004      * @throws IndexOutOfBoundsException if {@code length} is greater then {@code src.readableBytes}
2005      */
2006     abstract ByteBuf writeBytes(ByteBuf src, int length);
2007 
2008     /**
2009      * Transfers the specified source buffer's data to this buffer starting at
2010      * the current {@code writerIndex} and increases the {@code writerIndex}
2011      * by the number of the transferred bytes (= {@code length}).
2012      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2013      * will be called in an attempt to expand capacity to accommodate.
2014      *
2015      * @param srcIndex the first index of the source
2016      * @param length   the number of bytes to transfer
2017      *
2018      * @throws IndexOutOfBoundsException
2019      *         if the specified {@code srcIndex} is less than {@code 0}, or
2020      *         if {@code srcIndex + length} is greater than {@code src.capacity}
2021      */
2022     abstract ByteBuf writeBytes(ByteBuf src, int srcIndex, int length);
2023 
2024     /**
2025      * Transfers the specified source array's data to this buffer starting at
2026      * the current {@code writerIndex} and increases the {@code writerIndex}
2027      * by the number of the transferred bytes (= {@code src.length}).
2028      * If {@code this.writableBytes} is less than {@code src.length}, {@link #ensureWritable(int)}
2029      * will be called in an attempt to expand capacity to accommodate.
2030      */
2031     abstract ByteBuf writeBytes(byte[] src);
2032 
2033     /**
2034      * Transfers the specified source array's data to this buffer starting at
2035      * the current {@code writerIndex} and increases the {@code writerIndex}
2036      * by the number of the transferred bytes (= {@code length}).
2037      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2038      * will be called in an attempt to expand capacity to accommodate.
2039      *
2040      * @param srcIndex the first index of the source
2041      * @param length   the number of bytes to transfer
2042      *
2043      * @throws IndexOutOfBoundsException
2044      *         if the specified {@code srcIndex} is less than {@code 0}, or
2045      *         if {@code srcIndex + length} is greater than {@code src.length}
2046      */
2047     abstract ByteBuf writeBytes(byte[] src, int srcIndex, int length);
2048 
2049     /**
2050      * Transfers the specified source buffer's data to this buffer starting at
2051      * the current {@code writerIndex} until the source buffer's position
2052      * reaches its limit, and increases the {@code writerIndex} by the
2053      * number of the transferred bytes.
2054      * If {@code this.writableBytes} is less than {@code src.remaining()},
2055      * {@link #ensureWritable(int)} will be called in an attempt to expand
2056      * capacity to accommodate.
2057      */
2058     abstract ByteBuf writeBytes(ByteBuffer src);
2059 
2060     /**
2061      * Transfers the content of the specified stream to this buffer
2062      * starting at the current {@code writerIndex} and increases the
2063      * {@code writerIndex} by the number of the transferred bytes.
2064      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2065      * will be called in an attempt to expand capacity to accommodate.
2066      *
2067      * @param length the number of bytes to transfer
2068      *
2069      * @return the actual number of bytes read in from the specified stream
2070      *
2071      * @throws IOException if the specified stream threw an exception during I/O
2072      */
2073     abstract int writeBytes(InputStream inStream, int length);
2074 
2075     /**
2076      * Transfers the content of the specified channel to this buffer
2077      * starting at the current {@code writerIndex} and increases the
2078      * {@code writerIndex} by the number of the transferred bytes.
2079      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2080      * will be called in an attempt to expand capacity to accommodate.
2081      *
2082      * @param length the maximum number of bytes to transfer
2083      *
2084      * @return the actual number of bytes read in from the specified channel
2085      *
2086      * @throws IOException
2087      *         if the specified channel threw an exception during I/O
2088      */
2089     // abstract int writeBytes(ScatteringByteChannel in, int length);
2090 
2091     /**
2092      * Transfers the content of the specified channel starting at the given file position
2093      * to this buffer starting at the current {@code writerIndex} and increases the
2094      * {@code writerIndex} by the number of the transferred bytes.
2095      * This method does not modify the channel's position.
2096      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2097      * will be called in an attempt to expand capacity to accommodate.
2098      *
2099      * @param position the file position at which the transfer is to begin
2100      * @param length the maximum number of bytes to transfer
2101      *
2102      * @return the actual number of bytes read in from the specified channel
2103      *
2104      * @throws IOException
2105      *         if the specified channel threw an exception during I/O
2106      */
2107     // abstract int writeBytes(FileChannel in, long position, int length);
2108 
2109     /**
2110      * Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
2111      * {@code writerIndex} and increases the {@code writerIndex} by the
2112      * specified {@code length}.
2113      * If {@code this.writableBytes} is less than {@code length}, {@link #ensureWritable(int)}
2114      * will be called in an attempt to expand capacity to accommodate.
2115      *
2116      * @param length the number of <tt>NUL</tt>s to write to the buffer
2117      */
2118     abstract ByteBuf writeZero(int length);
2119 
2120     /**
2121      * Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
2122      * the {@code writerIndex} by the written bytes.
2123      * in this buffer.
2124      * If {@code this.writableBytes} is not large enough to write the whole sequence,
2125      * {@link #ensureWritable(int)} will be called in an attempt to expand capacity to accommodate.
2126      *
2127      * @param sequence to write
2128      * @param charset that should be used
2129      * @return the written number of bytes
2130      */
2131     abstract int writeCharSequence(CharSequence sequence, Charset charset);
2132 
2133     /**
2134      * Locates the first occurrence of the specified {@code value} in this
2135      * buffer.  The search takes place from the specified {@code fromIndex}
2136      * (inclusive)  to the specified {@code toIndex} (exclusive).
2137      * <p>
2138      * If {@code fromIndex} is greater than {@code toIndex}, the search is
2139      * performed in a reversed order.
2140      * <p>
2141      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2142      * this buffer.
2143      *
2144      * @return the absolute index of the first occurrence if found.
2145      *         {@code -1} otherwise.
2146      */
2147     abstract int indexOf(int fromIndex, int toIndex, byte value);
2148 
2149     /**
2150      * Locates the first occurrence of the specified {@code value} in this
2151      * buffer.  The search takes place from the current {@code readerIndex}
2152      * (inclusive) to the current {@code writerIndex} (exclusive).
2153      * <p>
2154      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2155      * this buffer.
2156      *
2157      * @return the number of bytes between the current {@code readerIndex}
2158      *         and the first occurrence if found. {@code -1} otherwise.
2159      */
2160     abstract int bytesBefore(byte value);
2161 
2162     /**
2163      * Locates the first occurrence of the specified {@code value} in this
2164      * buffer.  The search starts from the current {@code readerIndex}
2165      * (inclusive) and lasts for the specified {@code length}.
2166      * <p>
2167      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2168      * this buffer.
2169      *
2170      * @return the number of bytes between the current {@code readerIndex}
2171      *         and the first occurrence if found. {@code -1} otherwise.
2172      *
2173      * @throws IndexOutOfBoundsException
2174      *         if {@code length} is greater than {@code this.readableBytes}
2175      */
2176     abstract int bytesBefore(int length, byte value);
2177 
2178     /**
2179      * Locates the first occurrence of the specified {@code value} in this
2180      * buffer.  The search starts from the specified {@code index} (inclusive)
2181      * and lasts for the specified {@code length}.
2182      * <p>
2183      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2184      * this buffer.
2185      *
2186      * @return the number of bytes between the specified {@code index}
2187      *         and the first occurrence if found. {@code -1} otherwise.
2188      *
2189      * @throws IndexOutOfBoundsException
2190      *         if {@code index + length} is greater than {@code this.capacity}
2191      */
2192     abstract int bytesBefore(int index, int length, byte value);
2193 
2194     /**
2195      * Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order.
2196      *
2197      * @return {@code -1} if the processor iterated to or beyond the end of the readable bytes.
2198      *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
2199      */
2200     abstract int forEachByte(ByteProcessor processor);
2201 
2202     /**
2203      * Iterates over the specified area of this buffer with the specified {@code processor} in ascending order.
2204      * (i.e. {@code index}, {@code (index + 1)},  .. {@code (index + length - 1)})
2205      *
2206      * @return {@code -1} if the processor iterated to or beyond the end of the specified area.
2207      *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
2208      */
2209     abstract int forEachByte(int index, int length, ByteProcessor processor);
2210 
2211     /**
2212      * Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order.
2213      *
2214      * @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes.
2215      *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
2216      */
2217     abstract int forEachByteDesc(ByteProcessor processor);
2218 
2219     /**
2220      * Iterates over the specified area of this buffer with the specified {@code processor} in descending order.
2221      * (i.e. {@code (index + length - 1)}, {@code (index + length - 2)}, ... {@code index})
2222      *
2223      *
2224      * @return {@code -1} if the processor iterated to or beyond the beginning of the specified area.
2225      *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
2226      */
2227     abstract int forEachByteDesc(int index, int length, ByteProcessor processor);
2228 
2229     /**
2230      * Returns a copy of this buffer's readable bytes.  Modifying the content
2231      * of the returned buffer or this buffer does not affect each other at all.
2232      * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
2233      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2234      * this buffer.
2235      */
2236     abstract ByteBuf copy();
2237 
2238     /**
2239      * Returns a copy of this buffer's sub-region.  Modifying the content of
2240      * the returned buffer or this buffer does not affect each other at all.
2241      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2242      * this buffer.
2243      */
2244     abstract ByteBuf copy(int index, int length);
2245 
2246     /**
2247      * Returns a slice of this buffer's readable bytes. Modifying the content
2248      * of the returned buffer or this buffer affects each other's content
2249      * while they maintain separate indexes and marks.  This method is
2250      * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
2251      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2252      * this buffer.
2253      * <p>
2254      * Also be aware that this method will NOT call {@link #retain()} and so the
2255      * reference count will NOT be increased.
2256      */
2257     abstract ByteBuf slice();
2258 
2259     /**
2260      * Returns a retained slice of this buffer's readable bytes. Modifying the content
2261      * of the returned buffer or this buffer affects each other's content
2262      * while they maintain separate indexes and marks.  This method is
2263      * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
2264      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2265      * this buffer.
2266      * <p>
2267      * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice()}.
2268      * This method behaves similarly to {@code slice().retain()} except that this method may return
2269      * a buffer implementation that produces less garbage.
2270      */
2271     abstract ByteBuf retainedSlice();
2272 
2273     /**
2274      * Returns a slice of this buffer's sub-region. Modifying the content of
2275      * the returned buffer or this buffer affects each other's content while
2276      * they maintain separate indexes and marks.
2277      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2278      * this buffer.
2279      * <p>
2280      * Also be aware that this method will NOT call {@link #retain()} and so the
2281      * reference count will NOT be increased.
2282      */
2283     abstract ByteBuf slice(int index, int length);
2284 
2285     /**
2286      * Returns a retained slice of this buffer's sub-region. Modifying the content of
2287      * the returned buffer or this buffer affects each other's content while
2288      * they maintain separate indexes and marks.
2289      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2290      * this buffer.
2291      * <p>
2292      * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
2293      * This method behaves similarly to {@code slice(...).retain()} except that this method may return
2294      * a buffer implementation that produces less garbage.
2295      */
2296     abstract ByteBuf retainedSlice(int index, int length);
2297 
2298     /**
2299      * Returns a buffer which shares the whole region of this buffer.
2300      * Modifying the content of the returned buffer or this buffer affects
2301      * each other's content while they maintain separate indexes and marks.
2302      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2303      * this buffer.
2304      * <p>
2305      * The reader and writer marks will not be duplicated. Also be aware that this method will
2306      * NOT call {@link #retain()} and so the reference count will NOT be increased.
2307      * @return A buffer whose readable content is equivalent to the buffer returned by {@link #slice()}.
2308      * However this buffer will share the capacity of the underlying buffer, and therefore allows access to all of the
2309      * underlying content if necessary.
2310      */
2311     abstract ByteBuf duplicate();
2312 
2313     /**
2314      * Returns a retained buffer which shares the whole region of this buffer.
2315      * Modifying the content of the returned buffer or this buffer affects
2316      * each other's content while they maintain separate indexes and marks.
2317      * This method is identical to {@code buf.slice(0, buf.capacity())}.
2318      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2319      * this buffer.
2320      * <p>
2321      * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
2322      * This method behaves similarly to {@code duplicate().retain()} except that this method may return
2323      * a buffer implementation that produces less garbage.
2324      */
2325     abstract ByteBuf retainedDuplicate();
2326 
2327     /**
2328      * Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer.  Note that {@link #nioBuffers()}
2329      * or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
2330      *
2331      * @return {@code -1} if this buffer has no underlying {@link ByteBuffer}.
2332      *         the number of the underlying {@link ByteBuffer}s if this buffer has at least one underlying
2333      *         {@link ByteBuffer}.  Note that this method does not return {@code 0} to avoid confusion.
2334      *
2335      * @see #nioBuffer()
2336      * @see #nioBuffer(int, int)
2337      * @see #nioBuffers()
2338      * @see #nioBuffers(int, int)
2339      */
2340     abstract int nioBufferCount();
2341 
2342     /**
2343      * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}. The returned buffer
2344      * either share or contains the copied content of this buffer, while changing the position
2345      * and limit of the returned NIO buffer does not affect the indexes and marks of this buffer.
2346      * This method is identical to {@code buf.nioBuffer(buf.readerIndex(), buf.readableBytes())}.
2347      * This method does not modify {@code readerIndex} or {@code writerIndex} of this buffer.
2348      * Please note that the returned NIO buffer will not see the changes of this buffer if this buffer
2349      * is a dynamic buffer and it adjusted its capacity.
2350      *
2351      * @throws UnsupportedOperationException
2352      *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
2353      *
2354      * @see #nioBufferCount()
2355      * @see #nioBuffers()
2356      * @see #nioBuffers(int, int)
2357      */
2358     abstract ByteBuffer nioBuffer();
2359 
2360     /**
2361      * Exposes this buffer's sub-region as an NIO {@link ByteBuffer}. The returned buffer
2362      * either share or contains the copied content of this buffer, while changing the position
2363      * and limit of the returned NIO buffer does not affect the indexes and marks of this buffer.
2364      * This method does not modify {@code readerIndex} or {@code writerIndex} of this buffer.
2365      * Please note that the returned NIO buffer will not see the changes of this buffer if this buffer
2366      * is a dynamic buffer and it adjusted its capacity.
2367      *
2368      * @throws UnsupportedOperationException
2369      *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
2370      *
2371      * @see #nioBufferCount()
2372      * @see #nioBuffers()
2373      * @see #nioBuffers(int, int)
2374      */
2375     abstract ByteBuffer nioBuffer(int index, int length);
2376 
2377     /**
2378      * Internal use only: Exposes the internal NIO buffer.
2379      */
2380     abstract ByteBuffer internalNioBuffer(int index, int length);
2381 
2382     /**
2383      * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}'s. The returned buffer
2384      * either share or contains the copied content of this buffer, while changing the position
2385      * and limit of the returned NIO buffer does not affect the indexes and marks of this buffer.
2386      * This method does not modify {@code readerIndex} or {@code writerIndex} of this buffer.
2387      * Please note that the returned NIO buffer will not see the changes of this buffer if this buffer
2388      * is a dynamic buffer and it adjusted its capacity.
2389      *
2390      *
2391      * @throws UnsupportedOperationException
2392      *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
2393      *
2394      * @see #nioBufferCount()
2395      * @see #nioBuffer()
2396      * @see #nioBuffer(int, int)
2397      */
2398     abstract ByteBuffer[] nioBuffers();
2399 
2400     /**
2401      * Exposes this buffer's bytes as an NIO {@link ByteBuffer}'s for the specified index and length
2402      * The returned buffer either share or contains the copied content of this buffer, while changing
2403      * the position and limit of the returned NIO buffer does not affect the indexes and marks of this buffer.
2404      * This method does not modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
2405      * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
2406      * buffer and it adjusted its capacity.
2407      *
2408      * @throws UnsupportedOperationException
2409      *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
2410      *
2411      * @see #nioBufferCount()
2412      * @see #nioBuffer()
2413      * @see #nioBuffer(int, int)
2414      */
2415     abstract ByteBuffer[] nioBuffers(int index, int length);
2416 
2417     /**
2418      * Returns {@code true} if and only if this buffer has a backing byte array.
2419      * If this method returns true, you can safely call {@link #array()} and
2420      * {@link #arrayOffset()}.
2421      */
2422     abstract bool hasArray();
2423 
2424     /**
2425      * Returns the backing byte array of this buffer.
2426      *
2427      * @throws UnsupportedOperationException
2428      *         if there no accessible backing byte array
2429      */
2430     abstract byte[] array();
2431 
2432     abstract byte[] getReadableBytes();
2433 
2434     /**
2435      * Returns the offset of the first byte within the backing byte array of
2436      * this buffer.
2437      *
2438      * @throws UnsupportedOperationException
2439      *         if there no accessible backing byte array
2440      */
2441     abstract int arrayOffset();
2442 
2443     /**
2444      * Returns {@code true} if and only if this buffer has a reference to the low-level memory address that points
2445      * to the backing data.
2446      */
2447     abstract bool hasMemoryAddress();
2448 
2449     /**
2450      * Returns the low-level memory address that point to the first byte of ths backing data.
2451      *
2452      * @throws UnsupportedOperationException
2453      *         if this buffer does not support accessing the low-level memory address
2454      */
2455     abstract long memoryAddress();
2456 
2457     /**
2458      * Decodes this buffer's readable bytes into a string with the specified
2459      * character set name.  This method is identical to
2460      * {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}.
2461      * This method does not modify {@code readerIndex} or {@code writerIndex} of
2462      * this buffer.
2463      *
2464      * @throws UnsupportedCharsetException
2465      *         if the specified character set name is not supported by the
2466      *         current VM
2467      */
2468     abstract string toString(Charset charset);
2469 
2470     /**
2471      * Decodes this buffer's sub-region into a string with the specified
2472      * character set.  This method does not modify {@code readerIndex} or
2473      * {@code writerIndex} of this buffer.
2474      */
2475     abstract string toString(int index, int length, Charset charset);
2476 
2477     /**
2478      * Returns a hash code which was calculated from the content of this
2479      * buffer.  If there's a byte array which is
2480      * {@linkplain #equals(Object) equal to} this array, both arrays should
2481      * return the same value.
2482      */
2483     override
2484     abstract size_t toHash() @trusted nothrow;
2485 
2486     /**
2487      * Determines if the content of the specified buffer is identical to the
2488      * content of this array.  'Identical' here means:
2489      * <ul>
2490      * <li>the size of the contents of the two buffers are same and</li>
2491      * <li>every single byte of the content of the two buffers are same.</li>
2492      * </ul>
2493      * Please note that it does not compare {@link #readerIndex()} nor
2494      * {@link #writerIndex()}.  This method also returns {@code false} for
2495      * {@code null} and an object which is not an instance of
2496      * {@link ByteBuf} type.
2497      */
2498     override
2499     abstract bool opEquals(Object obj);
2500 
2501     /**
2502      * Compares the content of the specified buffer to the content of this
2503      * buffer. Comparison is performed in the same manner with the string
2504      * comparison functions of various languages such as {@code strcmp},
2505      * {@code memcmp} and {@link string#compareTo(string)}.
2506      */
2507     // override
2508     abstract int compareTo(ByteBuf buffer);
2509 
2510     /**
2511      * Returns the string representation of this buffer.  This method does not
2512      * necessarily return the whole content of the buffer but returns
2513      * the values of the key properties such as {@link #readerIndex()},
2514      * {@link #writerIndex()} and {@link #capacity()}.
2515      */
2516     override abstract string toString();
2517 
2518     abstract ByteBuf retain(int increment);
2519 
2520     abstract ByteBuf retain();
2521 
2522     abstract ByteBuf touch();
2523 
2524     abstract ByteBuf touch(Object hint);
2525 
2526     /**
2527      * Used internally by {@link AbstractByteBuf#ensureAccessible()} to try to guard
2528      * against using the buffer after it was released (best-effort).
2529      */
2530     bool isAccessible() {
2531         return refCnt() != 0;
2532     }
2533 }