View Javadoc
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  package org.jboss.netty.buffer;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.io.OutputStream;
21  import java.nio.ByteBuffer;
22  import java.nio.ByteOrder;
23  import java.nio.channels.GatheringByteChannel;
24  import java.nio.channels.ScatteringByteChannel;
25  import java.nio.charset.Charset;
26  import java.nio.charset.UnsupportedCharsetException;
27  
28  /**
29   * A random and sequential accessible sequence of zero or more bytes (octets).
30   * This interface provides an abstract view for one or more primitive byte
31   * arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}.
32   *
33   * <h3>Creation of a buffer</h3>
34   *
35   * It is recommended to create a new buffer using the helper methods in
36   * {@link ChannelBuffers} rather than calling an individual implementation's
37   * constructor.
38   *
39   * <h3>Random Access Indexing</h3>
40   *
41   * Just like an ordinary primitive byte array, {@link ChannelBuffer} uses
42   * <a href="http://en.wikipedia.org/wiki/Zero-based_numbering">zero-based indexing</a>.
43   * It means the index of the first byte is always {@code 0} and the index of the last byte is
44   * always {@link #capacity() capacity - 1}.  For example, to iterate all bytes of a buffer, you
45   * can do the following, regardless of its internal implementation:
46   *
47   * <pre>
48   * {@link ChannelBuffer} buffer = ...;
49   * for (int i = 0; i &lt; buffer.capacity(); i ++) {
50   *     byte b = buffer.getByte(i);
51   *     System.out.println((char) b);
52   * }
53   * </pre>
54   *
55   * <h3>Sequential Access Indexing</h3>
56   *
57   * {@link ChannelBuffer} provides two pointer variables to support sequential
58   * read and write operations - {@link #readerIndex() readerIndex} for a read
59   * operation and {@link #writerIndex() writerIndex} for a write operation
60   * respectively.  The following diagram shows how a buffer is segmented into
61   * three areas by the two pointers:
62   *
63   * <pre>
64   *      +-------------------+------------------+------------------+
65   *      | discardable bytes |  readable bytes  |  writable bytes  |
66   *      |                   |     (CONTENT)    |                  |
67   *      +-------------------+------------------+------------------+
68   *      |                   |                  |                  |
69   *      0      <=      readerIndex   <=   writerIndex    <=    capacity
70   * </pre>
71   *
72   * <h4>Readable bytes (the actual content)</h4>
73   *
74   * This segment is where the actual data is stored.  Any operation whose name
75   * starts with {@code read} or {@code skip} will get or skip the data at the
76   * current {@link #readerIndex() readerIndex} and increase it by the number of
77   * read bytes.  If the argument of the read operation is also a
78   * {@link ChannelBuffer} and no destination index is specified, the specified
79   * buffer's {@link #readerIndex() readerIndex} is increased together.
80   * <p>
81   * If there's not enough content left, {@link IndexOutOfBoundsException} is
82   * raised.  The default value of newly allocated, wrapped or copied buffer's
83   * {@link #readerIndex() readerIndex} is {@code 0}.
84   *
85   * <pre>
86   * // Iterates the readable bytes of a buffer.
87   * {@link ChannelBuffer} buffer = ...;
88   * while (buffer.readable()) {
89   *     System.out.println(buffer.readByte());
90   * }
91   * </pre>
92   *
93   * <h4>Writable bytes</h4>
94   *
95   * This segment is a undefined space which needs to be filled.  Any operation
96   * whose name ends with {@code write} will write the data at the current
97   * {@link #writerIndex() writerIndex} and increase it by the number of written
98   * bytes.  If the argument of the write operation is also a {@link ChannelBuffer},
99   * and no source index is specified, the specified buffer's
100  * {@link #readerIndex() readerIndex} is increased together.
101  * <p>
102  * If there's not enough writable bytes left, {@link IndexOutOfBoundsException}
103  * is raised.  The default value of newly allocated buffer's
104  * {@link #writerIndex() writerIndex} is {@code 0}.  The default value of
105  * wrapped or copied buffer's {@link #writerIndex() writerIndex} is the
106  * {@link #capacity() capacity} of the buffer.
107  *
108  * <pre>
109  * // Fills the writable bytes of a buffer with random integers.
110  * {@link ChannelBuffer} buffer = ...;
111  * while (buffer.writableBytes() >= 4) {
112  *     buffer.writeInt(random.nextInt());
113  * }
114  * </pre>
115  *
116  * <h4>Discardable bytes</h4>
117  *
118  * This segment contains the bytes which were read already by a read operation.
119  * Initially, the size of this segment is {@code 0}, but its size increases up
120  * to the {@link #writerIndex() writerIndex} as read operations are executed.
121  * The read bytes can be discarded by calling {@link #discardReadBytes()} to
122  * reclaim unused area as depicted by the following diagram:
123  *
124  * <pre>
125  *  BEFORE discardReadBytes()
126  *
127  *      +-------------------+------------------+------------------+
128  *      | discardable bytes |  readable bytes  |  writable bytes  |
129  *      +-------------------+------------------+------------------+
130  *      |                   |                  |                  |
131  *      0      <=      readerIndex   <=   writerIndex    <=    capacity
132  *
133  *
134  *  AFTER discardReadBytes()
135  *
136  *      +------------------+--------------------------------------+
137  *      |  readable bytes  |    writable bytes (got more space)   |
138  *      +------------------+--------------------------------------+
139  *      |                  |                                      |
140  * readerIndex (0) <= writerIndex (decreased)        <=        capacity
141  * </pre>
142  *
143  * Please note that there is no guarantee about the content of writable bytes
144  * after calling {@link #discardReadBytes()}.  The writable bytes will not be
145  * moved in most cases and could even be filled with completely different data
146  * depending on the underlying buffer implementation.
147  *
148  * <h4>Clearing the buffer indexes</h4>
149  *
150  * You can set both {@link #readerIndex() readerIndex} and
151  * {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}.
152  * It does not clear the buffer content (e.g. filling with {@code 0}) but just
153  * clears the two pointers.  Please also note that the semantic of this
154  * operation is different from {@link ByteBuffer#clear()}.
155  *
156  * <pre>
157  *  BEFORE clear()
158  *
159  *      +-------------------+------------------+------------------+
160  *      | discardable bytes |  readable bytes  |  writable bytes  |
161  *      +-------------------+------------------+------------------+
162  *      |                   |                  |                  |
163  *      0      <=      readerIndex   <=   writerIndex    <=    capacity
164  *
165  *
166  *  AFTER clear()
167  *
168  *      +---------------------------------------------------------+
169  *      |             writable bytes (got more space)             |
170  *      +---------------------------------------------------------+
171  *      |                                                         |
172  *      0 = readerIndex = writerIndex            <=            capacity
173  * </pre>
174  *
175  * <h3>Search operations</h3>
176  *
177  * Various {@link #indexOf(int, int, byte)} methods help you locate an index of
178  * a value which meets a certain criteria.  Complicated dynamic sequential
179  * search can be done with {@link ChannelBufferIndexFinder} as well as simple
180  * static single byte search.
181  * <p>
182  * If you are decoding variable length data such as NUL-terminated string, you
183  * will find {@link #bytesBefore(byte)} also useful.
184  *
185  * <h3>Mark and reset</h3>
186  *
187  * There are two marker indexes in every buffer. One is for storing
188  * {@link #readerIndex() readerIndex} and the other is for storing
189  * {@link #writerIndex() writerIndex}.  You can always reposition one of the
190  * two indexes by calling a reset method.  It works in a similar fashion to
191  * the mark and reset methods in {@link InputStream} except that there's no
192  * {@code readlimit}.
193  *
194  * <h3>Derived buffers</h3>
195  *
196  * You can create a view of an existing buffer by calling either
197  * {@link #duplicate()}, {@link #slice()} or {@link #slice(int, int)}.
198  * A derived buffer will have an independent {@link #readerIndex() readerIndex},
199  * {@link #writerIndex() writerIndex} and marker indexes, while it shares
200  * other internal data representation, just like a NIO buffer does.
201  * <p>
202  * In case a completely fresh copy of an existing buffer is required, please
203  * call {@link #copy()} method instead.
204  *
205  * <h3>Conversion to existing JDK types</h3>
206  *
207  * <h4>Byte array</h4>
208  *
209  * If a {@link ChannelBuffer} is backed by a byte array (i.e. {@code byte[]}),
210  * you can access it directly via the {@link #array()} method.  To determine
211  * if a buffer is backed by a byte array, {@link #hasArray()} should be used.
212  *
213  * <h4>NIO Buffers</h4>
214  *
215  * Various {@link #toByteBuffer()} and {@link #toByteBuffers()} methods convert
216  * a {@link ChannelBuffer} into one or more NIO buffers.  These methods avoid
217  * buffer allocation and memory copy whenever possible, but there's no
218  * guarantee that memory copy will not be involved.
219  *
220  * <h4>Strings</h4>
221  *
222  * Various {@link #toString(String)} methods convert a {@link ChannelBuffer}
223  * into a {@link String}.  Please note that {@link #toString()} is not a
224  * conversion method.
225  *
226  * <h4>I/O Streams</h4>
227  *
228  * Please refer to {@link ChannelBufferInputStream} and
229  * {@link ChannelBufferOutputStream}.
230  *
231  * @apiviz.landmark
232  */
233 public interface ChannelBuffer extends Comparable<ChannelBuffer> {
234 
235     /**
236      * Returns the factory which creates a {@link ChannelBuffer} whose
237      * type and default {@link ByteOrder} are same with this buffer.
238      */
239     ChannelBufferFactory factory();
240 
241     /**
242      * Returns the number of bytes (octets) this buffer can contain.
243      */
244     int capacity();
245 
246     /**
247      * Returns the <a href="http://en.wikipedia.org/wiki/Endianness">endianness</a>
248      * of this buffer.
249      */
250     ByteOrder order();
251 
252     /**
253      * Returns {@code true} if and only if this buffer is backed by an
254      * NIO direct buffer.
255      */
256     boolean isDirect();
257 
258     /**
259      * Returns the {@code readerIndex} of this buffer.
260      */
261     int readerIndex();
262 
263     /**
264      * Sets the {@code readerIndex} of this buffer.
265      *
266      * @throws IndexOutOfBoundsException
267      *         if the specified {@code readerIndex} is
268      *            less than {@code 0} or
269      *            greater than {@code this.writerIndex}
270      */
271     void readerIndex(int readerIndex);
272 
273     /**
274      * Returns the {@code writerIndex} of this buffer.
275      */
276     int writerIndex();
277 
278     /**
279      * Sets the {@code writerIndex} of this buffer.
280      *
281      * @throws IndexOutOfBoundsException
282      *         if the specified {@code writerIndex} is
283      *            less than {@code this.readerIndex} or
284      *            greater than {@code this.capacity}
285      */
286     void writerIndex(int writerIndex);
287 
288     /**
289      * Sets the {@code readerIndex} and {@code writerIndex} of this buffer
290      * in one shot.  This method is useful when you have to worry about the
291      * invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)}
292      * methods.  For example, the following code will fail:
293      *
294      * <pre>
295      * // Create a buffer whose readerIndex, writerIndex and capacity are
296      * // 0, 0 and 8 respectively.
297      * {@link ChannelBuffer} buf = {@link ChannelBuffers}.buffer(8);
298      *
299      * // IndexOutOfBoundsException is thrown because the specified
300      * // readerIndex (2) cannot be greater than the current writerIndex (0).
301      * buf.readerIndex(2);
302      * buf.writerIndex(4);
303      * </pre>
304      *
305      * The following code will also fail:
306      *
307      * <pre>
308      * // Create a buffer whose readerIndex, writerIndex and capacity are
309      * // 0, 8 and 8 respectively.
310      * {@link ChannelBuffer} buf = {@link ChannelBuffers}.wrappedBuffer(new byte[8]);
311      *
312      * // readerIndex becomes 8.
313      * buf.readLong();
314      *
315      * // IndexOutOfBoundsException is thrown because the specified
316      * // writerIndex (4) cannot be less than the current readerIndex (8).
317      * buf.writerIndex(4);
318      * buf.readerIndex(2);
319      * </pre>
320      *
321      * By contrast, this method guarantees that it never
322      * throws an {@link IndexOutOfBoundsException} as long as the specified
323      * indexes meet basic constraints, regardless what the current index
324      * values of the buffer are:
325      *
326      * <pre>
327      * // No matter what the current state of the buffer is, the following
328      * // call always succeeds as long as the capacity of the buffer is not
329      * // less than 4.
330      * buf.setIndex(2, 4);
331      * </pre>
332      *
333      * @throws IndexOutOfBoundsException
334      *         if the specified {@code readerIndex} is less than 0,
335      *         if the specified {@code writerIndex} is less than the specified
336      *         {@code readerIndex} or if the specified {@code writerIndex} is
337      *         greater than {@code this.capacity}
338      */
339     void setIndex(int readerIndex, int writerIndex);
340 
341     /**
342      * Returns the number of readable bytes which is equal to
343      * {@code (this.writerIndex - this.readerIndex)}.
344      */
345     int readableBytes();
346 
347     /**
348      * Returns the number of writable bytes which is equal to
349      * {@code (this.capacity - this.writerIndex)}.
350      */
351     int writableBytes();
352 
353     /**
354      * Returns {@code true}
355      * if and only if {@code (this.writerIndex - this.readerIndex)} is greater
356      * than {@code 0}.
357      */
358     boolean readable();
359 
360     /**
361      * Returns {@code true}
362      * if and only if {@code (this.capacity - this.writerIndex)} is greater
363      * than {@code 0}.
364      */
365     boolean writable();
366 
367     /**
368      * Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
369      * {@code 0}.
370      * This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}.
371      * <p>
372      * Please note that the behavior of this method is different
373      * from that of NIO buffer, which sets the {@code limit} to
374      * the {@code capacity} of the buffer.
375      */
376     void clear();
377 
378     /**
379      * Marks the current {@code readerIndex} in this buffer.  You can
380      * reposition the current {@code readerIndex} to the marked
381      * {@code readerIndex} by calling {@link #resetReaderIndex()}.
382      * The initial value of the marked {@code readerIndex} is {@code 0}.
383      */
384     void markReaderIndex();
385 
386     /**
387      * Repositions the current {@code readerIndex} to the marked
388      * {@code readerIndex} in this buffer.
389      *
390      * @throws IndexOutOfBoundsException
391      *         if the current {@code writerIndex} is less than the marked
392      *         {@code readerIndex}
393      */
394     void resetReaderIndex();
395 
396     /**
397      * Marks the current {@code writerIndex} in this buffer.  You can
398      * reposition the current {@code writerIndex} to the marked
399      * {@code writerIndex} by calling {@link #resetWriterIndex()}.
400      * The initial value of the marked {@code writerIndex} is {@code 0}.
401      */
402     void markWriterIndex();
403 
404     /**
405      * Repositions the current {@code writerIndex} to the marked
406      * {@code writerIndex} in this buffer.
407      *
408      * @throws IndexOutOfBoundsException
409      *         if the current {@code readerIndex} is greater than the marked
410      *         {@code writerIndex}
411      */
412     void resetWriterIndex();
413 
414     /**
415      * Discards the bytes between the 0th index and {@code readerIndex}.
416      * It moves the bytes between {@code readerIndex} and {@code writerIndex}
417      * to the 0th index, and sets {@code readerIndex} and {@code writerIndex}
418      * to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively.
419      * <p>
420      * Please refer to the class documentation for more detailed explanation.
421      */
422     void discardReadBytes();
423 
424     /**
425      * Makes sure the number of {@linkplain #writableBytes() the writable bytes}
426      * is equal to or greater than the specified value.  If there is enough
427      * writable bytes in this buffer, this method returns with no side effect.
428      * Otherwise:
429      * <ul>
430      * <li>a non-dynamic buffer will throw an {@link IndexOutOfBoundsException}.</li>
431      * <li>a dynamic buffer will expand its capacity so that the number of the
432      *     {@link #writableBytes() writable bytes} becomes equal to or greater
433      *     than the specified value. The expansion involves the reallocation of
434      *     the internal buffer and consequently memory copy.</li>
435      * </ul>
436      *
437      * @param writableBytes
438      *        the expected minimum number of writable bytes
439      * @throws IndexOutOfBoundsException
440      *         if {@linkplain #writableBytes() the writable bytes} of this
441      *         buffer is less than the specified value and if this buffer is
442      *         not a dynamic buffer
443      */
444     void ensureWritableBytes(int writableBytes);
445 
446     /**
447      * Gets a byte at the specified absolute {@code index} in this buffer.
448      * This method does not modify {@code readerIndex} or {@code writerIndex} of
449      * this buffer.
450      *
451      * @throws IndexOutOfBoundsException
452      *         if the specified {@code index} is less than {@code 0} or
453      *         {@code index + 1} is greater than {@code this.capacity}
454      */
455     byte  getByte(int index);
456 
457     /**
458      * Gets an unsigned byte at the specified absolute {@code index} in this
459      * buffer.  This method does not modify {@code readerIndex} or
460      * {@code writerIndex} of this buffer.
461      *
462      * @throws IndexOutOfBoundsException
463      *         if the specified {@code index} is less than {@code 0} or
464      *         {@code index + 1} is greater than {@code this.capacity}
465      */
466     short getUnsignedByte(int index);
467 
468     /**
469      * Gets a 16-bit short integer at the specified absolute {@code index} in
470      * this buffer.  This method does not modify {@code readerIndex} or
471      * {@code writerIndex} of this buffer.
472      *
473      * @throws IndexOutOfBoundsException
474      *         if the specified {@code index} is less than {@code 0} or
475      *         {@code index + 2} is greater than {@code this.capacity}
476      */
477     short getShort(int index);
478 
479     /**
480      * Gets an unsigned 16-bit short integer at the specified absolute
481      * {@code index} in this buffer.  This method does not modify
482      * {@code readerIndex} or {@code writerIndex} of this buffer.
483      *
484      * @throws IndexOutOfBoundsException
485      *         if the specified {@code index} is less than {@code 0} or
486      *         {@code index + 2} is greater than {@code this.capacity}
487      */
488     int getUnsignedShort(int index);
489 
490     /**
491      * Gets a 24-bit medium integer at the specified absolute {@code index} in
492      * this buffer.  This method does not modify {@code readerIndex} or
493      * {@code writerIndex} of this buffer.
494      *
495      * @throws IndexOutOfBoundsException
496      *         if the specified {@code index} is less than {@code 0} or
497      *         {@code index + 3} is greater than {@code this.capacity}
498      */
499     int   getMedium(int index);
500 
501     /**
502      * Gets an unsigned 24-bit medium integer at the specified absolute
503      * {@code index} in this buffer.  This method does not modify
504      * {@code readerIndex} or {@code writerIndex} of this buffer.
505      *
506      * @throws IndexOutOfBoundsException
507      *         if the specified {@code index} is less than {@code 0} or
508      *         {@code index + 3} is greater than {@code this.capacity}
509      */
510     int   getUnsignedMedium(int index);
511 
512     /**
513      * Gets a 32-bit integer at the specified absolute {@code index} in
514      * this buffer.  This method does not modify {@code readerIndex} or
515      * {@code writerIndex} of this buffer.
516      *
517      * @throws IndexOutOfBoundsException
518      *         if the specified {@code index} is less than {@code 0} or
519      *         {@code index + 4} is greater than {@code this.capacity}
520      */
521     int   getInt(int index);
522 
523     /**
524      * Gets an unsigned 32-bit integer at the specified absolute {@code index}
525      * in this buffer.  This method does not modify {@code readerIndex} or
526      * {@code writerIndex} of this buffer.
527      *
528      * @throws IndexOutOfBoundsException
529      *         if the specified {@code index} is less than {@code 0} or
530      *         {@code index + 4} is greater than {@code this.capacity}
531      */
532     long  getUnsignedInt(int index);
533 
534     /**
535      * Gets a 64-bit long integer at the specified absolute {@code index} in
536      * this buffer.  This method does not modify {@code readerIndex} or
537      * {@code writerIndex} of this buffer.
538      *
539      * @throws IndexOutOfBoundsException
540      *         if the specified {@code index} is less than {@code 0} or
541      *         {@code index + 8} is greater than {@code this.capacity}
542      */
543     long  getLong(int index);
544 
545     /**
546      * Gets a 2-byte UTF-16 character at the specified absolute
547      * {@code index} in this buffer.  This method does not modify
548      * {@code readerIndex} or {@code writerIndex} of this buffer.
549      *
550      * @throws IndexOutOfBoundsException
551      *         if the specified {@code index} is less than {@code 0} or
552      *         {@code index + 2} is greater than {@code this.capacity}
553      */
554     char  getChar(int index);
555 
556     /**
557      * Gets a 32-bit floating point number at the specified absolute
558      * {@code index} in this buffer.  This method does not modify
559      * {@code readerIndex} or {@code writerIndex} of this buffer.
560      *
561      * @throws IndexOutOfBoundsException
562      *         if the specified {@code index} is less than {@code 0} or
563      *         {@code index + 4} is greater than {@code this.capacity}
564      */
565     float getFloat(int index);
566 
567     /**
568      * Gets a 64-bit floating point number at the specified absolute
569      * {@code index} in this buffer.  This method does not modify
570      * {@code readerIndex} or {@code writerIndex} of this buffer.
571      *
572      * @throws IndexOutOfBoundsException
573      *         if the specified {@code index} is less than {@code 0} or
574      *         {@code index + 8} is greater than {@code this.capacity}
575      */
576     double getDouble(int index);
577 
578     /**
579      * Transfers this buffer's data to the specified destination starting at
580      * the specified absolute {@code index} until the destination becomes
581      * non-writable.  This method is basically same with
582      * {@link #getBytes(int, ChannelBuffer, int, int)}, except that this
583      * method increases the {@code writerIndex} of the destination by the
584      * number of the transferred bytes while
585      * {@link #getBytes(int, ChannelBuffer, int, int)} does not.
586      * This method does not modify {@code readerIndex} or {@code writerIndex} of
587      * the source buffer (i.e. {@code this}).
588      *
589      * @throws IndexOutOfBoundsException
590      *         if the specified {@code index} is less than {@code 0} or
591      *         if {@code index + dst.writableBytes} is greater than
592      *            {@code this.capacity}
593      */
594     void  getBytes(int index, ChannelBuffer dst);
595 
596     /**
597      * Transfers this buffer's data to the specified destination starting at
598      * the specified absolute {@code index}.  This method is basically same
599      * with {@link #getBytes(int, ChannelBuffer, int, int)}, except that this
600      * method increases the {@code writerIndex} of the destination by the
601      * number of the transferred bytes while
602      * {@link #getBytes(int, ChannelBuffer, int, int)} does not.
603      * This method does not modify {@code readerIndex} or {@code writerIndex} of
604      * the source buffer (i.e. {@code this}).
605      *
606      * @param length the number of bytes to transfer
607      *
608      * @throws IndexOutOfBoundsException
609      *         if the specified {@code index} is less than {@code 0},
610      *         if {@code index + length} is greater than
611      *            {@code this.capacity}, or
612      *         if {@code length} is greater than {@code dst.writableBytes}
613      */
614     void  getBytes(int index, ChannelBuffer dst, int length);
615 
616     /**
617      * Transfers this buffer's data to the specified destination starting at
618      * the specified absolute {@code index}.
619      * This method does not modify {@code readerIndex} or {@code writerIndex}
620      * of both the source (i.e. {@code this}) and the destination.
621      *
622      * @param dstIndex the first index of the destination
623      * @param length   the number of bytes to transfer
624      *
625      * @throws IndexOutOfBoundsException
626      *         if the specified {@code index} is less than {@code 0},
627      *         if the specified {@code dstIndex} is less than {@code 0},
628      *         if {@code index + length} is greater than
629      *            {@code this.capacity}, or
630      *         if {@code dstIndex + length} is greater than
631      *            {@code dst.capacity}
632      */
633     void  getBytes(int index, ChannelBuffer dst, int dstIndex, int length);
634 
635     /**
636      * Transfers this buffer's data to the specified destination starting at
637      * the specified absolute {@code index}.
638      * This method does not modify {@code readerIndex} or {@code writerIndex} of
639      * this buffer
640      *
641      * @throws IndexOutOfBoundsException
642      *         if the specified {@code index} is less than {@code 0} or
643      *         if {@code index + dst.length} is greater than
644      *            {@code this.capacity}
645      */
646     void  getBytes(int index, byte[] dst);
647 
648     /**
649      * Transfers this buffer's data to the specified destination starting at
650      * the specified absolute {@code index}.
651      * This method does not modify {@code readerIndex} or {@code writerIndex}
652      * of this buffer.
653      *
654      * @param dstIndex the first index of the destination
655      * @param length   the number of bytes to transfer
656      *
657      * @throws IndexOutOfBoundsException
658      *         if the specified {@code index} is less than {@code 0},
659      *         if the specified {@code dstIndex} is less than {@code 0},
660      *         if {@code index + length} is greater than
661      *            {@code this.capacity}, or
662      *         if {@code dstIndex + length} is greater than
663      *            {@code dst.length}
664      */
665     void  getBytes(int index, byte[] dst, int dstIndex, int length);
666 
667     /**
668      * Transfers this buffer's data to the specified destination starting at
669      * the specified absolute {@code index} until the destination's position
670      * reaches its limit.
671      * This method does not modify {@code readerIndex} or {@code writerIndex} of
672      * this buffer while the destination's {@code position} will be increased.
673      *
674      * @throws IndexOutOfBoundsException
675      *         if the specified {@code index} is less than {@code 0} or
676      *         if {@code index + dst.remaining()} is greater than
677      *            {@code this.capacity}
678      */
679     void  getBytes(int index, ByteBuffer dst);
680 
681     /**
682      * Transfers this buffer's data to the specified stream starting at the
683      * specified absolute {@code index}.
684      * This method does not modify {@code readerIndex} or {@code writerIndex} of
685      * this buffer.
686      *
687      * @param length the number of bytes to transfer
688      *
689      * @throws IndexOutOfBoundsException
690      *         if the specified {@code index} is less than {@code 0} or
691      *         if {@code index + length} is greater than
692      *            {@code this.capacity}
693      * @throws IOException
694      *         if the specified stream threw an exception during I/O
695      */
696     void  getBytes(int index, OutputStream out, int length) throws IOException;
697 
698     /**
699      * Transfers this buffer's data to the specified channel starting at the
700      * specified absolute {@code index}.
701      * This method does not modify {@code readerIndex} or {@code writerIndex} of
702      * this buffer.
703      *
704      * @param length the maximum number of bytes to transfer
705      *
706      * @return the actual number of bytes written out to the specified channel
707      *
708      * @throws IndexOutOfBoundsException
709      *         if the specified {@code index} is less than {@code 0} or
710      *         if {@code index + length} is greater than
711      *            {@code this.capacity}
712      * @throws IOException
713      *         if the specified channel threw an exception during I/O
714      */
715     int   getBytes(int index, GatheringByteChannel out, int length) throws IOException;
716 
717     /**
718      * Sets the specified byte at the specified absolute {@code index} in this
719      * buffer.  The 24 high-order bits of the specified value are ignored.
720      * This method does not modify {@code readerIndex} or {@code writerIndex} of
721      * this buffer.
722      *
723      * @throws IndexOutOfBoundsException
724      *         if the specified {@code index} is less than {@code 0} or
725      *         {@code index + 1} is greater than {@code this.capacity}
726      */
727     void setByte(int index, int   value);
728 
729     /**
730      * Sets the specified 16-bit short integer at the specified absolute
731      * {@code index} in this buffer.  The 16 high-order bits of the specified
732      * value are ignored.
733      * This method does not modify {@code readerIndex} or {@code writerIndex} of
734      * this buffer.
735      *
736      * @throws IndexOutOfBoundsException
737      *         if the specified {@code index} is less than {@code 0} or
738      *         {@code index + 2} is greater than {@code this.capacity}
739      */
740     void setShort(int index, int value);
741 
742     /**
743      * Sets the specified 24-bit medium integer at the specified absolute
744      * {@code index} in this buffer.  Please note that the most significant
745      * byte is ignored in the specified value.
746      * This method does not modify {@code readerIndex} or {@code writerIndex} of
747      * this buffer.
748      *
749      * @throws IndexOutOfBoundsException
750      *         if the specified {@code index} is less than {@code 0} or
751      *         {@code index + 3} is greater than {@code this.capacity}
752      */
753     void setMedium(int index, int   value);
754 
755     /**
756      * Sets the specified 32-bit integer at the specified absolute
757      * {@code index} in this buffer.
758      * This method does not modify {@code readerIndex} or {@code writerIndex} of
759      * this buffer.
760      *
761      * @throws IndexOutOfBoundsException
762      *         if the specified {@code index} is less than {@code 0} or
763      *         {@code index + 4} is greater than {@code this.capacity}
764      */
765     void setInt(int index, int   value);
766 
767     /**
768      * Sets the specified 64-bit long integer at the specified absolute
769      * {@code index} in this buffer.
770      * This method does not modify {@code readerIndex} or {@code writerIndex} of
771      * this buffer.
772      *
773      * @throws IndexOutOfBoundsException
774      *         if the specified {@code index} is less than {@code 0} or
775      *         {@code index + 8} is greater than {@code this.capacity}
776      */
777     void setLong(int index, long  value);
778 
779     /**
780      * Sets the specified 2-byte UTF-16 character at the specified absolute
781      * {@code index} in this buffer.
782      * The 16 high-order bits of the specified value are ignored.
783      * This method does not modify {@code readerIndex} or {@code writerIndex} of
784      * this buffer.
785      *
786      * @throws IndexOutOfBoundsException
787      *         if the specified {@code index} is less than {@code 0} or
788      *         {@code index + 2} is greater than {@code this.capacity}
789      */
790     void setChar(int index, int value);
791 
792     /**
793      * Sets the specified 32-bit floating-point number at the specified
794      * absolute {@code index} in this buffer.
795      * This method does not modify {@code readerIndex} or {@code writerIndex} of
796      * this buffer.
797      *
798      * @throws IndexOutOfBoundsException
799      *         if the specified {@code index} is less than {@code 0} or
800      *         {@code index + 4} is greater than {@code this.capacity}
801      */
802     void setFloat(int index, float value);
803 
804     /**
805      * Sets the specified 64-bit floating-point number at the specified
806      * absolute {@code index} in this buffer.
807      * This method does not modify {@code readerIndex} or {@code writerIndex} of
808      * this buffer.
809      *
810      * @throws IndexOutOfBoundsException
811      *         if the specified {@code index} is less than {@code 0} or
812      *         {@code index + 8} is greater than {@code this.capacity}
813      */
814     void setDouble(int index, double value);
815 
816     /**
817      * Transfers the specified source buffer's data to this buffer starting at
818      * the specified absolute {@code index} until the source buffer becomes
819      * unreadable.  This method is basically same with
820      * {@link #setBytes(int, ChannelBuffer, int, int)}, except that this
821      * method increases the {@code readerIndex} of the source buffer by
822      * the number of the transferred bytes while
823      * {@link #setBytes(int, ChannelBuffer, int, int)} does not.
824      * This method does not modify {@code readerIndex} or {@code writerIndex} of
825      * the source buffer (i.e. {@code this}).
826      *
827      * @throws IndexOutOfBoundsException
828      *         if the specified {@code index} is less than {@code 0} or
829      *         if {@code index + src.readableBytes} is greater than
830      *            {@code this.capacity}
831      */
832     void setBytes(int index, ChannelBuffer src);
833 
834     /**
835      * Transfers the specified source buffer's data to this buffer starting at
836      * the specified absolute {@code index}.  This method is basically same
837      * with {@link #setBytes(int, ChannelBuffer, int, int)}, except that this
838      * method increases the {@code readerIndex} of the source buffer by
839      * the number of the transferred bytes while
840      * {@link #setBytes(int, ChannelBuffer, int, int)} does not.
841      * This method does not modify {@code readerIndex} or {@code writerIndex} of
842      * the source buffer (i.e. {@code this}).
843      *
844      * @param length the number of bytes to transfer
845      *
846      * @throws IndexOutOfBoundsException
847      *         if the specified {@code index} is less than {@code 0},
848      *         if {@code index + length} is greater than
849      *            {@code this.capacity}, or
850      *         if {@code length} is greater than {@code src.readableBytes}
851      */
852     void setBytes(int index, ChannelBuffer src, int length);
853 
854     /**
855      * Transfers the specified source buffer's data to this buffer starting at
856      * the specified absolute {@code index}.
857      * This method does not modify {@code readerIndex} or {@code writerIndex}
858      * of both the source (i.e. {@code this}) and the destination.
859      *
860      * @param srcIndex the first index of the source
861      * @param length   the number of bytes to transfer
862      *
863      * @throws IndexOutOfBoundsException
864      *         if the specified {@code index} is less than {@code 0},
865      *         if the specified {@code srcIndex} is less than {@code 0},
866      *         if {@code index + length} is greater than
867      *            {@code this.capacity}, or
868      *         if {@code srcIndex + length} is greater than
869      *            {@code src.capacity}
870      */
871     void setBytes(int index, ChannelBuffer src, int srcIndex, int length);
872 
873     /**
874      * Transfers the specified source array's data to this buffer starting at
875      * the specified absolute {@code index}.
876      * This method does not modify {@code readerIndex} or {@code writerIndex} of
877      * this buffer.
878      *
879      * @throws IndexOutOfBoundsException
880      *         if the specified {@code index} is less than {@code 0} or
881      *         if {@code index + src.length} is greater than
882      *            {@code this.capacity}
883      */
884     void setBytes(int index, byte[] src);
885 
886     /**
887      * Transfers the specified source array's data to this buffer starting at
888      * the specified absolute {@code index}.
889      * This method does not modify {@code readerIndex} or {@code writerIndex} of
890      * this buffer.
891      *
892      * @throws IndexOutOfBoundsException
893      *         if the specified {@code index} is less than {@code 0},
894      *         if the specified {@code srcIndex} is less than {@code 0},
895      *         if {@code index + length} is greater than
896      *            {@code this.capacity}, or
897      *         if {@code srcIndex + length} is greater than {@code src.length}
898      */
899     void setBytes(int index, byte[] src, int srcIndex, int length);
900 
901     /**
902      * Transfers the specified source buffer's data to this buffer starting at
903      * the specified absolute {@code index} until the source buffer's position
904      * reaches its limit.
905      * This method does not modify {@code readerIndex} or {@code writerIndex} of
906      * this buffer.
907      *
908      * @throws IndexOutOfBoundsException
909      *         if the specified {@code index} is less than {@code 0} or
910      *         if {@code index + src.remaining()} is greater than
911      *            {@code this.capacity}
912      */
913     void setBytes(int index, ByteBuffer src);
914 
915     /**
916      * Transfers the content of the specified source stream to this buffer
917      * starting at the specified absolute {@code index}.
918      * This method does not modify {@code readerIndex} or {@code writerIndex} of
919      * this buffer.
920      *
921      * @param length the number of bytes to transfer
922      *
923      * @return the actual number of bytes read in from the specified channel.
924      *         {@code -1} if the specified channel is closed.
925      *
926      * @throws IndexOutOfBoundsException
927      *         if the specified {@code index} is less than {@code 0} or
928      *         if {@code index + length} is greater than {@code this.capacity}
929      * @throws IOException
930      *         if the specified stream threw an exception during I/O
931      */
932     int setBytes(int index, InputStream in, int length) throws IOException;
933 
934     /**
935      * Transfers the content of the specified source channel to this buffer
936      * starting at the specified absolute {@code index}.
937      * This method does not modify {@code readerIndex} or {@code writerIndex} of
938      * this buffer.
939      *
940      * @param length the maximum number of bytes to transfer
941      *
942      * @return the actual number of bytes read in from the specified channel.
943      *         {@code -1} if the specified channel is closed.
944      *
945      * @throws IndexOutOfBoundsException
946      *         if the specified {@code index} is less than {@code 0} or
947      *         if {@code index + length} is greater than {@code this.capacity}
948      * @throws IOException
949      *         if the specified channel threw an exception during I/O
950      */
951     int  setBytes(int index, ScatteringByteChannel in, int length) throws IOException;
952 
953     /**
954      * Fills this buffer with <tt>NUL (0x00)</tt> starting at the specified
955      * absolute {@code index}.
956      * This method does not modify {@code readerIndex} or {@code writerIndex} of
957      * this buffer.
958      *
959      * @param length the number of <tt>NUL</tt>s to write to the buffer
960      *
961      * @throws IndexOutOfBoundsException
962      *         if the specified {@code index} is less than {@code 0} or
963      *         if {@code index + length} is greater than {@code this.capacity}
964      */
965     void setZero(int index, int length);
966 
967     /**
968      * Gets a byte at the current {@code readerIndex} and increases
969      * the {@code readerIndex} by {@code 1} in this buffer.
970      *
971      * @throws IndexOutOfBoundsException
972      *         if {@code this.readableBytes} is less than {@code 1}
973      */
974     byte  readByte();
975 
976     /**
977      * Gets an unsigned byte at the current {@code readerIndex} and increases
978      * the {@code readerIndex} by {@code 1} in this buffer.
979      *
980      * @throws IndexOutOfBoundsException
981      *         if {@code this.readableBytes} is less than {@code 1}
982      */
983     short readUnsignedByte();
984 
985     /**
986      * Gets a 16-bit short integer at the current {@code readerIndex}
987      * and increases the {@code readerIndex} by {@code 2} in this buffer.
988      *
989      * @throws IndexOutOfBoundsException
990      *         if {@code this.readableBytes} is less than {@code 2}
991      */
992     short readShort();
993 
994     /**
995      * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
996      * and increases the {@code readerIndex} by {@code 2} in this buffer.
997      *
998      * @throws IndexOutOfBoundsException
999      *         if {@code this.readableBytes} is less than {@code 2}
1000      */
1001     int   readUnsignedShort();
1002 
1003     /**
1004      * Gets a 24-bit medium integer at the current {@code readerIndex}
1005      * and increases the {@code readerIndex} by {@code 3} in this buffer.
1006      *
1007      * @throws IndexOutOfBoundsException
1008      *         if {@code this.readableBytes} is less than {@code 3}
1009      */
1010     int   readMedium();
1011 
1012     /**
1013      * Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
1014      * and increases the {@code readerIndex} by {@code 3} in this buffer.
1015      *
1016      * @throws IndexOutOfBoundsException
1017      *         if {@code this.readableBytes} is less than {@code 3}
1018      */
1019     int   readUnsignedMedium();
1020 
1021     /**
1022      * Gets a 32-bit integer at the current {@code readerIndex}
1023      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1024      *
1025      * @throws IndexOutOfBoundsException
1026      *         if {@code this.readableBytes} is less than {@code 4}
1027      */
1028     int   readInt();
1029 
1030     /**
1031      * Gets an unsigned 32-bit integer at the current {@code readerIndex}
1032      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1033      *
1034      * @throws IndexOutOfBoundsException
1035      *         if {@code this.readableBytes} is less than {@code 4}
1036      */
1037     long  readUnsignedInt();
1038 
1039     /**
1040      * Gets a 64-bit integer at the current {@code readerIndex}
1041      * and increases the {@code readerIndex} by {@code 8} in this buffer.
1042      *
1043      * @throws IndexOutOfBoundsException
1044      *         if {@code this.readableBytes} is less than {@code 8}
1045      */
1046     long  readLong();
1047 
1048     /**
1049      * Gets a 2-byte UTF-16 character at the current {@code readerIndex}
1050      * and increases the {@code readerIndex} by {@code 2} in this buffer.
1051      *
1052      * @throws IndexOutOfBoundsException
1053      *         if {@code this.readableBytes} is less than {@code 2}
1054      */
1055     char  readChar();
1056 
1057     /**
1058      * Gets a 32-bit floating point number at the current {@code readerIndex}
1059      * and increases the {@code readerIndex} by {@code 4} in this buffer.
1060      *
1061      * @throws IndexOutOfBoundsException
1062      *         if {@code this.readableBytes} is less than {@code 4}
1063      */
1064     float readFloat();
1065 
1066     /**
1067      * Gets a 64-bit floating point number at the current {@code readerIndex}
1068      * and increases the {@code readerIndex} by {@code 8} in this buffer.
1069      *
1070      * @throws IndexOutOfBoundsException
1071      *         if {@code this.readableBytes} is less than {@code 8}
1072      */
1073     double readDouble();
1074 
1075     /**
1076      * Transfers this buffer's data to a newly created buffer starting at
1077      * the current {@code readerIndex} and increases the {@code readerIndex}
1078      * by the number of the transferred bytes (= {@code length}).
1079      * The returned buffer's {@code readerIndex} and {@code writerIndex} are
1080      * {@code 0} and {@code length} respectively.
1081      *
1082      * @param length the number of bytes to transfer
1083      *
1084      * @return the newly created buffer which contains the transferred bytes
1085      *
1086      * @throws IndexOutOfBoundsException
1087      *         if {@code length} is greater than {@code this.readableBytes}
1088      */
1089     ChannelBuffer readBytes(int length);
1090 
1091     /**
1092      * Returns a new slice of this buffer's sub-region starting at the current
1093      * {@code readerIndex} and increases the {@code readerIndex} by the size
1094      * of the new slice (= {@code length}).
1095      *
1096      * @param length the size of the new slice
1097      *
1098      * @return the newly created slice
1099      *
1100      * @throws IndexOutOfBoundsException
1101      *         if {@code length} is greater than {@code this.readableBytes}
1102      */
1103     ChannelBuffer readSlice(int length);
1104 
1105     /**
1106      * Transfers this buffer's data to the specified destination starting at
1107      * the current {@code readerIndex} until the destination becomes
1108      * non-writable, and increases the {@code readerIndex} by the number of the
1109      * transferred bytes.  This method is basically same with
1110      * {@link #readBytes(ChannelBuffer, int, int)}, except that this method
1111      * increases the {@code writerIndex} of the destination by the number of
1112      * the transferred bytes while {@link #readBytes(ChannelBuffer, int, int)}
1113      * does not.
1114      *
1115      * @throws IndexOutOfBoundsException
1116      *         if {@code dst.writableBytes} is greater than
1117      *            {@code this.readableBytes}
1118      */
1119     void readBytes(ChannelBuffer dst);
1120 
1121     /**
1122      * Transfers this buffer's data to the specified destination starting at
1123      * the current {@code readerIndex} and increases the {@code readerIndex}
1124      * by the number of the transferred bytes (= {@code length}).  This method
1125      * is basically same with {@link #readBytes(ChannelBuffer, int, int)},
1126      * except that this method increases the {@code writerIndex} of the
1127      * destination by the number of the transferred bytes (= {@code length})
1128      * while {@link #readBytes(ChannelBuffer, int, int)} does not.
1129      *
1130      * @throws IndexOutOfBoundsException
1131      *         if {@code length} is greater than {@code this.readableBytes} or
1132      *         if {@code length} is greater than {@code dst.writableBytes}
1133      */
1134     void readBytes(ChannelBuffer dst, int length);
1135 
1136     /**
1137      * Transfers this buffer's data to the specified destination starting at
1138      * the current {@code readerIndex} and increases the {@code readerIndex}
1139      * by the number of the transferred bytes (= {@code length}).
1140      *
1141      * @param dstIndex the first index of the destination
1142      * @param length   the number of bytes to transfer
1143      *
1144      * @throws IndexOutOfBoundsException
1145      *         if the specified {@code dstIndex} is less than {@code 0},
1146      *         if {@code length} is greater than {@code this.readableBytes}, or
1147      *         if {@code dstIndex + length} is greater than
1148      *            {@code dst.capacity}
1149      */
1150     void readBytes(ChannelBuffer dst, int dstIndex, int length);
1151 
1152     /**
1153      * Transfers this buffer's data to the specified destination starting at
1154      * the current {@code readerIndex} and increases the {@code readerIndex}
1155      * by the number of the transferred bytes (= {@code dst.length}).
1156      *
1157      * @throws IndexOutOfBoundsException
1158      *         if {@code dst.length} is greater than {@code this.readableBytes}
1159      */
1160     void readBytes(byte[] dst);
1161 
1162     /**
1163      * Transfers this buffer's data to the specified destination starting at
1164      * the current {@code readerIndex} and increases the {@code readerIndex}
1165      * by the number of the transferred bytes (= {@code length}).
1166      *
1167      * @param dstIndex the first index of the destination
1168      * @param length   the number of bytes to transfer
1169      *
1170      * @throws IndexOutOfBoundsException
1171      *         if the specified {@code dstIndex} is less than {@code 0},
1172      *         if {@code length} is greater than {@code this.readableBytes}, or
1173      *         if {@code dstIndex + length} is greater than {@code dst.length}
1174      */
1175     void readBytes(byte[] dst, int dstIndex, int length);
1176 
1177     /**
1178      * Transfers this buffer's data to the specified destination starting at
1179      * the current {@code readerIndex} until the destination's position
1180      * reaches its limit, and increases the {@code readerIndex} by the
1181      * number of the transferred bytes.
1182      *
1183      * @throws IndexOutOfBoundsException
1184      *         if {@code dst.remaining()} is greater than
1185      *            {@code this.readableBytes}
1186      */
1187     void readBytes(ByteBuffer dst);
1188 
1189     /**
1190      * Transfers this buffer's data to the specified stream starting at the
1191      * current {@code readerIndex}.
1192      *
1193      * @param length the number of bytes to transfer
1194      *
1195      * @throws IndexOutOfBoundsException
1196      *         if {@code length} is greater than {@code this.readableBytes}
1197      * @throws IOException
1198      *         if the specified stream threw an exception during I/O
1199      */
1200     void readBytes(OutputStream out, int length) throws IOException;
1201 
1202     /**
1203      * Transfers this buffer's data to the specified stream starting at the
1204      * current {@code readerIndex}.
1205      *
1206      * @param length the maximum number of bytes to transfer
1207      *
1208      * @return the actual number of bytes written out to the specified channel
1209      *
1210      * @throws IndexOutOfBoundsException
1211      *         if {@code length} is greater than {@code this.readableBytes}
1212      * @throws IOException
1213      *         if the specified channel threw an exception during I/O
1214      */
1215     int  readBytes(GatheringByteChannel out, int length) throws IOException;
1216 
1217     /**
1218      * Increases the current {@code readerIndex} by the specified
1219      * {@code length} in this buffer.
1220      *
1221      * @throws IndexOutOfBoundsException
1222      *         if {@code length} is greater than {@code this.readableBytes}
1223      */
1224     void skipBytes(int length);
1225 
1226     /**
1227      * Sets the specified byte at the current {@code writerIndex}
1228      * and increases the {@code writerIndex} by {@code 1} in this buffer.
1229      * The 24 high-order bits of the specified value are ignored.
1230      *
1231      * @throws IndexOutOfBoundsException
1232      *         if {@code this.writableBytes} is less than {@code 1}
1233      */
1234     void writeByte(int   value);
1235 
1236     /**
1237      * Sets the specified 16-bit short integer at the current
1238      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1239      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1240      *
1241      * @throws IndexOutOfBoundsException
1242      *         if {@code this.writableBytes} is less than {@code 2}
1243      */
1244     void writeShort(int value);
1245 
1246     /**
1247      * Sets the specified 24-bit medium integer at the current
1248      * {@code writerIndex} and increases the {@code writerIndex} by {@code 3}
1249      * in this buffer.
1250      *
1251      * @throws IndexOutOfBoundsException
1252      *         if {@code this.writableBytes} is less than {@code 3}
1253      */
1254     void writeMedium(int   value);
1255 
1256     /**
1257      * Sets the specified 32-bit integer at the current {@code writerIndex}
1258      * and increases the {@code writerIndex} by {@code 4} in this buffer.
1259      *
1260      * @throws IndexOutOfBoundsException
1261      *         if {@code this.writableBytes} is less than {@code 4}
1262      */
1263     void writeInt(int   value);
1264 
1265     /**
1266      * Sets the specified 64-bit long integer at the current
1267      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1268      * in this buffer.
1269      *
1270      * @throws IndexOutOfBoundsException
1271      *         if {@code this.writableBytes} is less than {@code 8}
1272      */
1273     void writeLong(long  value);
1274 
1275     /**
1276      * Sets the specified 2-byte UTF-16 character at the current
1277      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1278      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1279      *
1280      * @throws IndexOutOfBoundsException
1281      *         if {@code this.writableBytes} is less than {@code 2}
1282      */
1283     void writeChar(int value);
1284 
1285     /**
1286      * Sets the specified 32-bit floating point number at the current
1287      * {@code writerIndex} and increases the {@code writerIndex} by {@code 4}
1288      * in this buffer.
1289      *
1290      * @throws IndexOutOfBoundsException
1291      *         if {@code this.writableBytes} is less than {@code 4}
1292      */
1293     void writeFloat(float value);
1294 
1295     /**
1296      * Sets the specified 64-bit floating point number at the current
1297      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1298      * in this buffer.
1299      *
1300      * @throws IndexOutOfBoundsException
1301      *         if {@code this.writableBytes} is less than {@code 8}
1302      */
1303     void writeDouble(double value);
1304 
1305     /**
1306      * Transfers the specified source buffer's data to this buffer starting at
1307      * the current {@code writerIndex} until the source buffer becomes
1308      * unreadable, and increases the {@code writerIndex} by the number of
1309      * the transferred bytes.  This method is basically same with
1310      * {@link #writeBytes(ChannelBuffer, int, int)}, except that this method
1311      * increases the {@code readerIndex} of the source buffer by the number of
1312      * the transferred bytes while {@link #writeBytes(ChannelBuffer, int, int)}
1313      * does not.
1314      *
1315      * @throws IndexOutOfBoundsException
1316      *         if {@code src.readableBytes} is greater than
1317      *            {@code this.writableBytes}
1318      */
1319     void writeBytes(ChannelBuffer src);
1320 
1321     /**
1322      * Transfers the specified source buffer's data to this buffer starting at
1323      * the current {@code writerIndex} and increases the {@code writerIndex}
1324      * by the number of the transferred bytes (= {@code length}).  This method
1325      * is basically same with {@link #writeBytes(ChannelBuffer, int, int)},
1326      * except that this method increases the {@code readerIndex} of the source
1327      * buffer by the number of the transferred bytes (= {@code length}) while
1328      * {@link #writeBytes(ChannelBuffer, int, int)} does not.
1329      *
1330      * @param length the number of bytes to transfer
1331      *
1332      * @throws IndexOutOfBoundsException
1333      *         if {@code length} is greater than {@code this.writableBytes} or
1334      *         if {@code length} is greater then {@code src.readableBytes}
1335      */
1336     void writeBytes(ChannelBuffer src, int length);
1337 
1338     /**
1339      * Transfers the specified source buffer's data to this buffer starting at
1340      * the current {@code writerIndex} and increases the {@code writerIndex}
1341      * by the number of the transferred bytes (= {@code length}).
1342      *
1343      * @param srcIndex the first index of the source
1344      * @param length   the number of bytes to transfer
1345      *
1346      * @throws IndexOutOfBoundsException
1347      *         if the specified {@code srcIndex} is less than {@code 0},
1348      *         if {@code srcIndex + length} is greater than
1349      *            {@code src.capacity}, or
1350      *         if {@code length} is greater than {@code this.writableBytes}
1351      */
1352     void writeBytes(ChannelBuffer src, int srcIndex, int length);
1353 
1354     /**
1355      * Transfers the specified source array's data to this buffer starting at
1356      * the current {@code writerIndex} and increases the {@code writerIndex}
1357      * by the number of the transferred bytes (= {@code src.length}).
1358      *
1359      * @throws IndexOutOfBoundsException
1360      *         if {@code src.length} is greater than {@code this.writableBytes}
1361      */
1362     void writeBytes(byte[] src);
1363 
1364     /**
1365      * Transfers the specified source array's data to this buffer starting at
1366      * the current {@code writerIndex} and increases the {@code writerIndex}
1367      * by the number of the transferred bytes (= {@code length}).
1368      *
1369      * @param srcIndex the first index of the source
1370      * @param length   the number of bytes to transfer
1371      *
1372      * @throws IndexOutOfBoundsException
1373      *         if the specified {@code srcIndex} is less than {@code 0},
1374      *         if {@code srcIndex + length} is greater than
1375      *            {@code src.length}, or
1376      *         if {@code length} is greater than {@code this.writableBytes}
1377      */
1378     void writeBytes(byte[] src, int srcIndex, int length);
1379 
1380     /**
1381      * Transfers the specified source buffer's data to this buffer starting at
1382      * the current {@code writerIndex} until the source buffer's position
1383      * reaches its limit, and increases the {@code writerIndex} by the
1384      * number of the transferred bytes.
1385      *
1386      * @throws IndexOutOfBoundsException
1387      *         if {@code src.remaining()} is greater than
1388      *            {@code this.writableBytes}
1389      */
1390     void writeBytes(ByteBuffer src);
1391 
1392     /**
1393      * Transfers the content of the specified stream to this buffer
1394      * starting at the current {@code writerIndex} and increases the
1395      * {@code writerIndex} by the number of the transferred bytes.
1396      *
1397      * @param length the number of bytes to transfer
1398      *
1399      * @return the actual number of bytes read in from the specified stream
1400      *
1401      * @throws IndexOutOfBoundsException
1402      *         if {@code length} is greater than {@code this.writableBytes}
1403      * @throws IOException
1404      *         if the specified stream threw an exception during I/O
1405      */
1406     int  writeBytes(InputStream in, int length) throws IOException;
1407 
1408     /**
1409      * Transfers the content of the specified channel to this buffer
1410      * starting at the current {@code writerIndex} and increases the
1411      * {@code writerIndex} by the number of the transferred bytes.
1412      *
1413      * @param length the maximum number of bytes to transfer
1414      *
1415      * @return the actual number of bytes read in from the specified channel
1416      *
1417      * @throws IndexOutOfBoundsException
1418      *         if {@code length} is greater than {@code this.writableBytes}
1419      * @throws IOException
1420      *         if the specified channel threw an exception during I/O
1421      */
1422     int  writeBytes(ScatteringByteChannel in, int length) throws IOException;
1423 
1424     /**
1425      * Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
1426      * {@code writerIndex} and increases the {@code writerIndex} by the
1427      * specified {@code length}.
1428      *
1429      * @param length the number of <tt>NUL</tt>s to write to the buffer
1430      *
1431      * @throws IndexOutOfBoundsException
1432      *         if {@code length} is greater than {@code this.writableBytes}
1433      */
1434     void writeZero(int length);
1435 
1436     /**
1437      * Locates the first occurrence of the specified {@code value} in this
1438      * buffer.  The search takes place from the specified {@code fromIndex}
1439      * (inclusive)  to the specified {@code toIndex} (exclusive).
1440      * <p>
1441      * If {@code fromIndex} is greater than {@code toIndex}, the search is
1442      * performed in a reversed order.
1443      * <p>
1444      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1445      * this buffer.
1446      *
1447      * @return the absolute index of the first occurrence if found.
1448      *         {@code -1} otherwise.
1449      */
1450     int indexOf(int fromIndex, int toIndex, byte value);
1451 
1452     /**
1453      * Locates the first place where the specified {@code indexFinder}
1454      * returns {@code true}.  The search takes place from the specified
1455      * {@code fromIndex} (inclusive) to the specified {@code toIndex}
1456      * (exclusive).
1457      * <p>
1458      * If {@code fromIndex} is greater than {@code toIndex}, the search is
1459      * performed in a reversed order.
1460      * <p>
1461      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1462      * this buffer.
1463      *
1464      * @return the absolute index where the specified {@code indexFinder}
1465      *         returned {@code true}.  {@code -1} if the {@code indexFinder}
1466      *         did not return {@code true} at all.
1467      */
1468     int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder);
1469 
1470     /**
1471      * Locates the first occurrence of the specified {@code value} in this
1472      * buffer.  The search takes place from the current {@code readerIndex}
1473      * (inclusive) to the current {@code writerIndex} (exclusive).
1474      * <p>
1475      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1476      * this buffer.
1477      *
1478      * @return the number of bytes between the current {@code readerIndex}
1479      *         and the first occurrence if found. {@code -1} otherwise.
1480      */
1481     int bytesBefore(byte value);
1482 
1483     /**
1484      * Locates the first place where the specified {@code indexFinder} returns
1485      * {@code true}.  The search takes place from the current {@code readerIndex}
1486      * (inclusive) to the current {@code writerIndex}.
1487      * <p>
1488      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1489      * this buffer.
1490      *
1491      * @return the number of bytes between the current {@code readerIndex}
1492      *         and the first place where the {@code indexFinder} returned
1493      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1494      *         return {@code true} at all.
1495      */
1496     int bytesBefore(ChannelBufferIndexFinder indexFinder);
1497 
1498     /**
1499      * Locates the first occurrence of the specified {@code value} in this
1500      * buffer.  The search starts from the current {@code readerIndex}
1501      * (inclusive) and lasts for the specified {@code length}.
1502      * <p>
1503      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1504      * this buffer.
1505      *
1506      * @return the number of bytes between the current {@code readerIndex}
1507      *         and the first occurrence if found. {@code -1} otherwise.
1508      *
1509      * @throws IndexOutOfBoundsException
1510      *         if {@code length} is greater than {@code this.readableBytes}
1511      */
1512     int bytesBefore(int length, byte value);
1513 
1514     /**
1515      * Locates the first place where the specified {@code indexFinder} returns
1516      * {@code true}.  The search starts the current {@code readerIndex}
1517      * (inclusive) and lasts for the specified {@code length}.
1518      * <p>
1519      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1520      * this buffer.
1521      *
1522      * @return the number of bytes between the current {@code readerIndex}
1523      *         and the first place where the {@code indexFinder} returned
1524      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1525      *         return {@code true} at all.
1526      *
1527      * @throws IndexOutOfBoundsException
1528      *         if {@code length} is greater than {@code this.readableBytes}
1529      */
1530     int bytesBefore(int length, ChannelBufferIndexFinder indexFinder);
1531 
1532     /**
1533      * Locates the first occurrence of the specified {@code value} in this
1534      * buffer.  The search starts from the specified {@code index} (inclusive)
1535      * and lasts for the specified {@code length}.
1536      * <p>
1537      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1538      * this buffer.
1539      *
1540      * @return the number of bytes between the specified {@code index}
1541      *         and the first occurrence if found. {@code -1} otherwise.
1542      *
1543      * @throws IndexOutOfBoundsException
1544      *         if {@code index + length} is greater than {@code this.capacity}
1545      */
1546     int bytesBefore(int index, int length, byte value);
1547 
1548     /**
1549      * Locates the first place where the specified {@code indexFinder} returns
1550      * {@code true}.  The search starts the specified {@code index} (inclusive)
1551      * and lasts for the specified {@code length}.
1552      * <p>
1553      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1554      * this buffer.
1555      *
1556      * @return the number of bytes between the specified {@code index}
1557      *         and the first place where the {@code indexFinder} returned
1558      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1559      *         return {@code true} at all.
1560      *
1561      * @throws IndexOutOfBoundsException
1562      *         if {@code index + length} is greater than {@code this.capacity}
1563      */
1564     int bytesBefore(int index, int length, ChannelBufferIndexFinder indexFinder);
1565 
1566     /**
1567      * Returns a copy of this buffer's readable bytes.  Modifying the content
1568      * of the returned buffer or this buffer does not affect each other at all.
1569      * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
1570      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1571      * this buffer.
1572      */
1573     ChannelBuffer copy();
1574 
1575     /**
1576      * Returns a copy of this buffer's sub-region.  Modifying the content of
1577      * the returned buffer or this buffer does not affect each other at all.
1578      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1579      * this buffer.
1580      */
1581     ChannelBuffer copy(int index, int length);
1582 
1583     /**
1584      * Returns a slice of this buffer's readable bytes. Modifying the content
1585      * of the returned buffer or this buffer affects each other's content
1586      * while they maintain separate indexes and marks.  This method is
1587      * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
1588      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1589      * this buffer.
1590      */
1591     ChannelBuffer slice();
1592 
1593     /**
1594      * Returns a slice of this buffer's sub-region. Modifying the content of
1595      * the returned buffer or this buffer affects each other's content while
1596      * they maintain separate indexes and marks.
1597      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1598      * this buffer.
1599      */
1600     ChannelBuffer slice(int index, int length);
1601 
1602     /**
1603      * Returns a buffer which shares the whole region of this buffer.
1604      * Modifying the content of the returned buffer or this buffer affects
1605      * each other's content while they maintain separate indexes and marks.
1606      * This method is identical to {@code buf.slice(0, buf.capacity())}.
1607      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1608      * this buffer.
1609      */
1610     ChannelBuffer duplicate();
1611 
1612     /**
1613      * Converts this buffer's readable bytes into a NIO buffer.  The returned
1614      * buffer might or might not share the content with this buffer, while
1615      * they have separate indexes and marks.  This method is identical to
1616      * {@code buf.toByteBuffer(buf.readerIndex(), buf.readableBytes())}.
1617      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1618      * this buffer.
1619      */
1620     ByteBuffer toByteBuffer();
1621 
1622     /**
1623      * Converts this buffer's sub-region into a NIO buffer.  The returned
1624      * buffer might or might not share the content with this buffer, while
1625      * they have separate indexes and marks.
1626      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1627      * this buffer.
1628      */
1629     ByteBuffer toByteBuffer(int index, int length);
1630 
1631     /**
1632      * Converts this buffer's readable bytes into an array of NIO buffers.
1633      * The returned buffers might or might not share the content with this
1634      * buffer, while they have separate indexes and marks.  This method is
1635      * identical to {@code buf.toByteBuffers(buf.readerIndex(), buf.readableBytes())}.
1636      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1637      * this buffer.
1638      */
1639     ByteBuffer[] toByteBuffers();
1640 
1641     /**
1642      * Converts this buffer's sub-region into an array of NIO buffers.
1643      * The returned buffers might or might not share the content with this
1644      * buffer, while they have separate indexes and marks.
1645      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1646      * this buffer.
1647      */
1648     ByteBuffer[] toByteBuffers(int index, int length);
1649 
1650     /**
1651      * Returns {@code true} if and only if this buffer has a backing byte array.
1652      * If this method returns true, you can safely call {@link #array()} and
1653      * {@link #arrayOffset()}.
1654      */
1655     boolean hasArray();
1656 
1657     /**
1658      * Returns the backing byte array of this buffer.
1659      *
1660      * @throws UnsupportedOperationException
1661      *         if there no accessible backing byte array
1662      */
1663     byte[] array();
1664 
1665     /**
1666      * Returns the offset of the first byte within the backing byte array of
1667      * this buffer.
1668      *
1669      * @throws UnsupportedOperationException
1670      *         if there no accessible backing byte array
1671      */
1672     int arrayOffset();
1673 
1674     /**
1675      * Decodes this buffer's readable bytes into a string with the specified
1676      * character set name.  This method is identical to
1677      * {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}.
1678      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1679      * this buffer.
1680      *
1681      * @throws UnsupportedCharsetException
1682      *         if the specified character set name is not supported by the
1683      *         current VM
1684      */
1685     String toString(Charset charset);
1686 
1687     /**
1688      * Decodes this buffer's sub-region into a string with the specified
1689      * character set.  This method does not modify {@code readerIndex} or
1690      * {@code writerIndex} of this buffer.
1691      */
1692     String toString(int index, int length, Charset charset);
1693 
1694     /**
1695      * Returns a hash code which was calculated from the content of this
1696      * buffer.  If there's a byte array which is
1697      * {@linkplain #equals(Object) equal to} this array, both arrays should
1698      * return the same value.
1699      */
1700     int hashCode();
1701 
1702     /**
1703      * Determines if the content of the specified buffer is identical to the
1704      * content of this array.  'Identical' here means:
1705      * <ul>
1706      * <li>the size of the contents of the two buffers are same and</li>
1707      * <li>every single byte of the content of the two buffers are same.</li>
1708      * </ul>
1709      * Please note that it does not compare {@link #readerIndex()} nor
1710      * {@link #writerIndex()}.  This method also returns {@code false} for
1711      * {@code null} and an object which is not an instance of
1712      * {@link ChannelBuffer} type.
1713      */
1714     boolean equals(Object obj);
1715 
1716     /**
1717      * Compares the content of the specified buffer to the content of this
1718      * buffer.  Comparison is performed in the same manner with the string
1719      * comparison functions of various languages such as {@code strcmp},
1720      * {@code memcmp} and {@link String#compareTo(String)}.
1721      */
1722     int compareTo(ChannelBuffer buffer);
1723 
1724     /**
1725      * Returns the string representation of this buffer.  This method does not
1726      * necessarily return the whole content of the buffer but returns
1727      * the values of the key properties such as {@link #readerIndex()},
1728      * {@link #writerIndex()} and {@link #capacity()}.
1729      */
1730     String toString();
1731 }