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      * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readBytes(int)} instead.
1093      */
1094     @Deprecated
1095     ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder);
1096 
1097     /**
1098      * Returns a new slice of this buffer's sub-region starting at the current
1099      * {@code readerIndex} and increases the {@code readerIndex} by the size
1100      * of the new slice (= {@code length}).
1101      *
1102      * @param length the size of the new slice
1103      *
1104      * @return the newly created slice
1105      *
1106      * @throws IndexOutOfBoundsException
1107      *         if {@code length} is greater than {@code this.readableBytes}
1108      */
1109     ChannelBuffer readSlice(int length);
1110 
1111     /**
1112      * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readSlice(int)} instead.
1113      */
1114     @Deprecated
1115     ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder);
1116 
1117     /**
1118      * Transfers this buffer's data to the specified destination starting at
1119      * the current {@code readerIndex} until the destination becomes
1120      * non-writable, and increases the {@code readerIndex} by the number of the
1121      * transferred bytes.  This method is basically same with
1122      * {@link #readBytes(ChannelBuffer, int, int)}, except that this method
1123      * increases the {@code writerIndex} of the destination by the number of
1124      * the transferred bytes while {@link #readBytes(ChannelBuffer, int, int)}
1125      * does not.
1126      *
1127      * @throws IndexOutOfBoundsException
1128      *         if {@code dst.writableBytes} is greater than
1129      *            {@code this.readableBytes}
1130      */
1131     void readBytes(ChannelBuffer dst);
1132 
1133     /**
1134      * Transfers this buffer's data to the specified destination starting at
1135      * the current {@code readerIndex} and increases the {@code readerIndex}
1136      * by the number of the transferred bytes (= {@code length}).  This method
1137      * is basically same with {@link #readBytes(ChannelBuffer, int, int)},
1138      * except that this method increases the {@code writerIndex} of the
1139      * destination by the number of the transferred bytes (= {@code length})
1140      * while {@link #readBytes(ChannelBuffer, int, int)} does not.
1141      *
1142      * @throws IndexOutOfBoundsException
1143      *         if {@code length} is greater than {@code this.readableBytes} or
1144      *         if {@code length} is greater than {@code dst.writableBytes}
1145      */
1146     void readBytes(ChannelBuffer dst, int length);
1147 
1148     /**
1149      * Transfers this buffer's data to the specified destination starting at
1150      * the current {@code readerIndex} and increases the {@code readerIndex}
1151      * by the number of the transferred bytes (= {@code length}).
1152      *
1153      * @param dstIndex the first index of the destination
1154      * @param length   the number of bytes to transfer
1155      *
1156      * @throws IndexOutOfBoundsException
1157      *         if the specified {@code dstIndex} is less than {@code 0},
1158      *         if {@code length} is greater than {@code this.readableBytes}, or
1159      *         if {@code dstIndex + length} is greater than
1160      *            {@code dst.capacity}
1161      */
1162     void readBytes(ChannelBuffer dst, int dstIndex, int length);
1163 
1164     /**
1165      * Transfers this buffer's data to the specified destination starting at
1166      * the current {@code readerIndex} and increases the {@code readerIndex}
1167      * by the number of the transferred bytes (= {@code dst.length}).
1168      *
1169      * @throws IndexOutOfBoundsException
1170      *         if {@code dst.length} is greater than {@code this.readableBytes}
1171      */
1172     void readBytes(byte[] dst);
1173 
1174     /**
1175      * Transfers this buffer's data to the specified destination starting at
1176      * the current {@code readerIndex} and increases the {@code readerIndex}
1177      * by the number of the transferred bytes (= {@code length}).
1178      *
1179      * @param dstIndex the first index of the destination
1180      * @param length   the number of bytes to transfer
1181      *
1182      * @throws IndexOutOfBoundsException
1183      *         if the specified {@code dstIndex} is less than {@code 0},
1184      *         if {@code length} is greater than {@code this.readableBytes}, or
1185      *         if {@code dstIndex + length} is greater than {@code dst.length}
1186      */
1187     void readBytes(byte[] dst, int dstIndex, int length);
1188 
1189     /**
1190      * Transfers this buffer's data to the specified destination starting at
1191      * the current {@code readerIndex} until the destination's position
1192      * reaches its limit, and increases the {@code readerIndex} by the
1193      * number of the transferred bytes.
1194      *
1195      * @throws IndexOutOfBoundsException
1196      *         if {@code dst.remaining()} is greater than
1197      *            {@code this.readableBytes}
1198      */
1199     void readBytes(ByteBuffer dst);
1200 
1201     /**
1202      * Transfers this buffer's data to the specified stream starting at the
1203      * current {@code readerIndex}.
1204      *
1205      * @param length the number of bytes to transfer
1206      *
1207      * @throws IndexOutOfBoundsException
1208      *         if {@code length} is greater than {@code this.readableBytes}
1209      * @throws IOException
1210      *         if the specified stream threw an exception during I/O
1211      */
1212     void readBytes(OutputStream out, int length) throws IOException;
1213 
1214     /**
1215      * Transfers this buffer's data to the specified stream starting at the
1216      * current {@code readerIndex}.
1217      *
1218      * @param length the maximum number of bytes to transfer
1219      *
1220      * @return the actual number of bytes written out to the specified channel
1221      *
1222      * @throws IndexOutOfBoundsException
1223      *         if {@code length} is greater than {@code this.readableBytes}
1224      * @throws IOException
1225      *         if the specified channel threw an exception during I/O
1226      */
1227     int  readBytes(GatheringByteChannel out, int length) throws IOException;
1228 
1229     /**
1230      * Increases the current {@code readerIndex} by the specified
1231      * {@code length} in this buffer.
1232      *
1233      * @throws IndexOutOfBoundsException
1234      *         if {@code length} is greater than {@code this.readableBytes}
1235      */
1236     void skipBytes(int length);
1237 
1238     /**
1239      * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #skipBytes(int)} instead.
1240      */
1241     @Deprecated
1242     int  skipBytes(ChannelBufferIndexFinder indexFinder);
1243 
1244     /**
1245      * Sets the specified byte at the current {@code writerIndex}
1246      * and increases the {@code writerIndex} by {@code 1} in this buffer.
1247      * The 24 high-order bits of the specified value are ignored.
1248      *
1249      * @throws IndexOutOfBoundsException
1250      *         if {@code this.writableBytes} is less than {@code 1}
1251      */
1252     void writeByte(int   value);
1253 
1254     /**
1255      * Sets the specified 16-bit short integer at the current
1256      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1257      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1258      *
1259      * @throws IndexOutOfBoundsException
1260      *         if {@code this.writableBytes} is less than {@code 2}
1261      */
1262     void writeShort(int value);
1263 
1264     /**
1265      * Sets the specified 24-bit medium integer at the current
1266      * {@code writerIndex} and increases the {@code writerIndex} by {@code 3}
1267      * in this buffer.
1268      *
1269      * @throws IndexOutOfBoundsException
1270      *         if {@code this.writableBytes} is less than {@code 3}
1271      */
1272     void writeMedium(int   value);
1273 
1274     /**
1275      * Sets the specified 32-bit integer at the current {@code writerIndex}
1276      * and increases the {@code writerIndex} by {@code 4} in this buffer.
1277      *
1278      * @throws IndexOutOfBoundsException
1279      *         if {@code this.writableBytes} is less than {@code 4}
1280      */
1281     void writeInt(int   value);
1282 
1283     /**
1284      * Sets the specified 64-bit long integer at the current
1285      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1286      * in this buffer.
1287      *
1288      * @throws IndexOutOfBoundsException
1289      *         if {@code this.writableBytes} is less than {@code 8}
1290      */
1291     void writeLong(long  value);
1292 
1293     /**
1294      * Sets the specified 2-byte UTF-16 character at the current
1295      * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
1296      * in this buffer.  The 16 high-order bits of the specified value are ignored.
1297      *
1298      * @throws IndexOutOfBoundsException
1299      *         if {@code this.writableBytes} is less than {@code 2}
1300      */
1301     void writeChar(int value);
1302 
1303     /**
1304      * Sets the specified 32-bit floating point number at the current
1305      * {@code writerIndex} and increases the {@code writerIndex} by {@code 4}
1306      * in this buffer.
1307      *
1308      * @throws IndexOutOfBoundsException
1309      *         if {@code this.writableBytes} is less than {@code 4}
1310      */
1311     void writeFloat(float value);
1312 
1313     /**
1314      * Sets the specified 64-bit floating point number at the current
1315      * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
1316      * in this buffer.
1317      *
1318      * @throws IndexOutOfBoundsException
1319      *         if {@code this.writableBytes} is less than {@code 8}
1320      */
1321     void writeDouble(double value);
1322 
1323     /**
1324      * Transfers the specified source buffer's data to this buffer starting at
1325      * the current {@code writerIndex} until the source buffer becomes
1326      * unreadable, and increases the {@code writerIndex} by the number of
1327      * the transferred bytes.  This method is basically same with
1328      * {@link #writeBytes(ChannelBuffer, int, int)}, except that this method
1329      * increases the {@code readerIndex} of the source buffer by the number of
1330      * the transferred bytes while {@link #writeBytes(ChannelBuffer, int, int)}
1331      * does not.
1332      *
1333      * @throws IndexOutOfBoundsException
1334      *         if {@code src.readableBytes} is greater than
1335      *            {@code this.writableBytes}
1336      */
1337     void writeBytes(ChannelBuffer src);
1338 
1339     /**
1340      * Transfers the specified source buffer's data to this buffer starting at
1341      * the current {@code writerIndex} and increases the {@code writerIndex}
1342      * by the number of the transferred bytes (= {@code length}).  This method
1343      * is basically same with {@link #writeBytes(ChannelBuffer, int, int)},
1344      * except that this method increases the {@code readerIndex} of the source
1345      * buffer by the number of the transferred bytes (= {@code length}) while
1346      * {@link #writeBytes(ChannelBuffer, int, int)} does not.
1347      *
1348      * @param length the number of bytes to transfer
1349      *
1350      * @throws IndexOutOfBoundsException
1351      *         if {@code length} is greater than {@code this.writableBytes} or
1352      *         if {@code length} is greater then {@code src.readableBytes}
1353      */
1354     void writeBytes(ChannelBuffer src, int length);
1355 
1356     /**
1357      * Transfers the specified source buffer's data to this buffer starting at
1358      * the current {@code writerIndex} and increases the {@code writerIndex}
1359      * by the number of the transferred bytes (= {@code length}).
1360      *
1361      * @param srcIndex the first index of the source
1362      * @param length   the number of bytes to transfer
1363      *
1364      * @throws IndexOutOfBoundsException
1365      *         if the specified {@code srcIndex} is less than {@code 0},
1366      *         if {@code srcIndex + length} is greater than
1367      *            {@code src.capacity}, or
1368      *         if {@code length} is greater than {@code this.writableBytes}
1369      */
1370     void writeBytes(ChannelBuffer src, int srcIndex, int length);
1371 
1372     /**
1373      * Transfers the specified source array's data to this buffer starting at
1374      * the current {@code writerIndex} and increases the {@code writerIndex}
1375      * by the number of the transferred bytes (= {@code src.length}).
1376      *
1377      * @throws IndexOutOfBoundsException
1378      *         if {@code src.length} is greater than {@code this.writableBytes}
1379      */
1380     void writeBytes(byte[] src);
1381 
1382     /**
1383      * Transfers the specified source array's data to this buffer starting at
1384      * the current {@code writerIndex} and increases the {@code writerIndex}
1385      * by the number of the transferred bytes (= {@code length}).
1386      *
1387      * @param srcIndex the first index of the source
1388      * @param length   the number of bytes to transfer
1389      *
1390      * @throws IndexOutOfBoundsException
1391      *         if the specified {@code srcIndex} is less than {@code 0},
1392      *         if {@code srcIndex + length} is greater than
1393      *            {@code src.length}, or
1394      *         if {@code length} is greater than {@code this.writableBytes}
1395      */
1396     void writeBytes(byte[] src, int srcIndex, int length);
1397 
1398     /**
1399      * Transfers the specified source buffer's data to this buffer starting at
1400      * the current {@code writerIndex} until the source buffer's position
1401      * reaches its limit, and increases the {@code writerIndex} by the
1402      * number of the transferred bytes.
1403      *
1404      * @throws IndexOutOfBoundsException
1405      *         if {@code src.remaining()} is greater than
1406      *            {@code this.writableBytes}
1407      */
1408     void writeBytes(ByteBuffer src);
1409 
1410     /**
1411      * Transfers the content of the specified stream to this buffer
1412      * starting at the current {@code writerIndex} and increases the
1413      * {@code writerIndex} by the number of the transferred bytes.
1414      *
1415      * @param length the number of bytes to transfer
1416      *
1417      * @return the actual number of bytes read in from the specified stream
1418      *
1419      * @throws IndexOutOfBoundsException
1420      *         if {@code length} is greater than {@code this.writableBytes}
1421      * @throws IOException
1422      *         if the specified stream threw an exception during I/O
1423      */
1424     int  writeBytes(InputStream in, int length) throws IOException;
1425 
1426     /**
1427      * Transfers the content of the specified channel to this buffer
1428      * starting at the current {@code writerIndex} and increases the
1429      * {@code writerIndex} by the number of the transferred bytes.
1430      *
1431      * @param length the maximum number of bytes to transfer
1432      *
1433      * @return the actual number of bytes read in from the specified channel
1434      *
1435      * @throws IndexOutOfBoundsException
1436      *         if {@code length} is greater than {@code this.writableBytes}
1437      * @throws IOException
1438      *         if the specified channel threw an exception during I/O
1439      */
1440     int  writeBytes(ScatteringByteChannel in, int length) throws IOException;
1441 
1442     /**
1443      * Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
1444      * {@code writerIndex} and increases the {@code writerIndex} by the
1445      * specified {@code length}.
1446      *
1447      * @param length the number of <tt>NUL</tt>s to write to the buffer
1448      *
1449      * @throws IndexOutOfBoundsException
1450      *         if {@code length} is greater than {@code this.writableBytes}
1451      */
1452     void writeZero(int length);
1453 
1454     /**
1455      * Locates the first occurrence of the specified {@code value} in this
1456      * buffer.  The search takes place from the specified {@code fromIndex}
1457      * (inclusive)  to the specified {@code toIndex} (exclusive).
1458      * <p>
1459      * If {@code fromIndex} is greater than {@code toIndex}, the search is
1460      * performed in a reversed order.
1461      * <p>
1462      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1463      * this buffer.
1464      *
1465      * @return the absolute index of the first occurrence if found.
1466      *         {@code -1} otherwise.
1467      */
1468     int indexOf(int fromIndex, int toIndex, byte value);
1469 
1470     /**
1471      * Locates the first place where the specified {@code indexFinder}
1472      * returns {@code true}.  The search takes place from the specified
1473      * {@code fromIndex} (inclusive) to the specified {@code toIndex}
1474      * (exclusive).
1475      * <p>
1476      * If {@code fromIndex} is greater than {@code toIndex}, the search is
1477      * performed in a reversed order.
1478      * <p>
1479      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1480      * this buffer.
1481      *
1482      * @return the absolute index where the specified {@code indexFinder}
1483      *         returned {@code true}.  {@code -1} if the {@code indexFinder}
1484      *         did not return {@code true} at all.
1485      */
1486     int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder);
1487 
1488     /**
1489      * Locates the first occurrence of the specified {@code value} in this
1490      * buffer.  The search takes place from the current {@code readerIndex}
1491      * (inclusive) to the current {@code writerIndex} (exclusive).
1492      * <p>
1493      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1494      * this buffer.
1495      *
1496      * @return the number of bytes between the current {@code readerIndex}
1497      *         and the first occurrence if found. {@code -1} otherwise.
1498      */
1499     int bytesBefore(byte value);
1500 
1501     /**
1502      * Locates the first place where the specified {@code indexFinder} returns
1503      * {@code true}.  The search takes place from the current {@code readerIndex}
1504      * (inclusive) to the current {@code writerIndex}.
1505      * <p>
1506      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1507      * this buffer.
1508      *
1509      * @return the number of bytes between the current {@code readerIndex}
1510      *         and the first place where the {@code indexFinder} returned
1511      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1512      *         return {@code true} at all.
1513      */
1514     int bytesBefore(ChannelBufferIndexFinder indexFinder);
1515 
1516     /**
1517      * Locates the first occurrence of the specified {@code value} in this
1518      * buffer.  The search starts from the current {@code readerIndex}
1519      * (inclusive) and lasts for the specified {@code length}.
1520      * <p>
1521      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1522      * this buffer.
1523      *
1524      * @return the number of bytes between the current {@code readerIndex}
1525      *         and the first occurrence if found. {@code -1} otherwise.
1526      *
1527      * @throws IndexOutOfBoundsException
1528      *         if {@code length} is greater than {@code this.readableBytes}
1529      */
1530     int bytesBefore(int length, byte value);
1531 
1532     /**
1533      * Locates the first place where the specified {@code indexFinder} returns
1534      * {@code true}.  The search starts the current {@code readerIndex}
1535      * (inclusive) 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 current {@code readerIndex}
1541      *         and the first place where the {@code indexFinder} returned
1542      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1543      *         return {@code true} at all.
1544      *
1545      * @throws IndexOutOfBoundsException
1546      *         if {@code length} is greater than {@code this.readableBytes}
1547      */
1548     int bytesBefore(int length, ChannelBufferIndexFinder indexFinder);
1549 
1550     /**
1551      * Locates the first occurrence of the specified {@code value} in this
1552      * buffer.  The search starts from the specified {@code index} (inclusive)
1553      * and lasts for the specified {@code length}.
1554      * <p>
1555      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1556      * this buffer.
1557      *
1558      * @return the number of bytes between the specified {@code index}
1559      *         and the first occurrence if found. {@code -1} otherwise.
1560      *
1561      * @throws IndexOutOfBoundsException
1562      *         if {@code index + length} is greater than {@code this.capacity}
1563      */
1564     int bytesBefore(int index, int length, byte value);
1565 
1566     /**
1567      * Locates the first place where the specified {@code indexFinder} returns
1568      * {@code true}.  The search starts the specified {@code index} (inclusive)
1569      * and lasts for the specified {@code length}.
1570      * <p>
1571      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1572      * this buffer.
1573      *
1574      * @return the number of bytes between the specified {@code index}
1575      *         and the first place where the {@code indexFinder} returned
1576      *         {@code true}.  {@code -1} if the {@code indexFinder} did not
1577      *         return {@code true} at all.
1578      *
1579      * @throws IndexOutOfBoundsException
1580      *         if {@code index + length} is greater than {@code this.capacity}
1581      */
1582     int bytesBefore(int index, int length, ChannelBufferIndexFinder indexFinder);
1583 
1584     /**
1585      * Returns a copy of this buffer's readable bytes.  Modifying the content
1586      * of the returned buffer or this buffer does not affect each other at all.
1587      * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
1588      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1589      * this buffer.
1590      */
1591     ChannelBuffer copy();
1592 
1593     /**
1594      * Returns a copy of this buffer's sub-region.  Modifying the content of
1595      * the returned buffer or this buffer does not affect each other at all.
1596      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1597      * this buffer.
1598      */
1599     ChannelBuffer copy(int index, int length);
1600 
1601     /**
1602      * Returns a slice of this buffer's readable bytes. Modifying the content
1603      * of the returned buffer or this buffer affects each other's content
1604      * while they maintain separate indexes and marks.  This method is
1605      * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
1606      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1607      * this buffer.
1608      */
1609     ChannelBuffer slice();
1610 
1611     /**
1612      * Returns a slice of this buffer's sub-region. Modifying the content of
1613      * the returned buffer or this buffer affects each other's content while
1614      * they maintain separate indexes and marks.
1615      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1616      * this buffer.
1617      */
1618     ChannelBuffer slice(int index, int length);
1619 
1620     /**
1621      * Returns a buffer which shares the whole region of this buffer.
1622      * Modifying the content of the returned buffer or this buffer affects
1623      * each other's content while they maintain separate indexes and marks.
1624      * This method is identical to {@code buf.slice(0, buf.capacity())}.
1625      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1626      * this buffer.
1627      */
1628     ChannelBuffer duplicate();
1629 
1630     /**
1631      * Converts this buffer's readable bytes into a NIO buffer.  The returned
1632      * buffer might or might not share the content with this buffer, while
1633      * they have separate indexes and marks.  This method is identical to
1634      * {@code buf.toByteBuffer(buf.readerIndex(), buf.readableBytes())}.
1635      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1636      * this buffer.
1637      */
1638     ByteBuffer toByteBuffer();
1639 
1640     /**
1641      * Converts this buffer's sub-region into a NIO buffer.  The returned
1642      * buffer might or might not share the content with this buffer, while
1643      * they have separate indexes and marks.
1644      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1645      * this buffer.
1646      */
1647     ByteBuffer toByteBuffer(int index, int length);
1648 
1649     /**
1650      * Converts this buffer's readable bytes into an array of NIO buffers.
1651      * The returned buffers might or might not share the content with this
1652      * buffer, while they have separate indexes and marks.  This method is
1653      * identical to {@code buf.toByteBuffers(buf.readerIndex(), buf.readableBytes())}.
1654      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1655      * this buffer.
1656      */
1657     ByteBuffer[] toByteBuffers();
1658 
1659     /**
1660      * Converts this buffer's sub-region into an array of NIO buffers.
1661      * The returned buffers might or might not share the content with this
1662      * buffer, while they have separate indexes and marks.
1663      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1664      * this buffer.
1665      */
1666     ByteBuffer[] toByteBuffers(int index, int length);
1667 
1668     /**
1669      * Returns {@code true} if and only if this buffer has a backing byte array.
1670      * If this method returns true, you can safely call {@link #array()} and
1671      * {@link #arrayOffset()}.
1672      */
1673     boolean hasArray();
1674 
1675     /**
1676      * Returns the backing byte array of this buffer.
1677      *
1678      * @throws UnsupportedOperationException
1679      *         if there no accessible backing byte array
1680      */
1681     byte[] array();
1682 
1683     /**
1684      * Returns the offset of the first byte within the backing byte array of
1685      * this buffer.
1686      *
1687      * @throws UnsupportedOperationException
1688      *         if there no accessible backing byte array
1689      */
1690     int arrayOffset();
1691 
1692     /**
1693      * Decodes this buffer's readable bytes into a string with the specified
1694      * character set name.  This method is identical to
1695      * {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}.
1696      * This method does not modify {@code readerIndex} or {@code writerIndex} of
1697      * this buffer.
1698      *
1699      * @throws UnsupportedCharsetException
1700      *         if the specified character set name is not supported by the
1701      *         current VM
1702      */
1703     String toString(Charset charset);
1704 
1705     /**
1706      * Decodes this buffer's sub-region into a string with the specified
1707      * character set.  This method does not modify {@code readerIndex} or
1708      * {@code writerIndex} of this buffer.
1709      */
1710     String toString(int index, int length, Charset charset);
1711 
1712     /**
1713      * @deprecated Use {@link #toString(Charset)} instead.
1714      */
1715     @Deprecated
1716     String toString(String charsetName);
1717 
1718     /**
1719      * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
1720      */
1721     @Deprecated
1722     String toString(
1723             String charsetName, ChannelBufferIndexFinder terminatorFinder);
1724 
1725     /**
1726      * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and
1727      * {@link #toString(int, int, Charset)} instead.
1728      */
1729     @Deprecated
1730     String toString(int index, int length, String charsetName);
1731 
1732     /**
1733      * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and
1734      * {@link #toString(int, int, Charset)} instead.
1735      */
1736     @Deprecated
1737     String toString(
1738             int index, int length, String charsetName,
1739             ChannelBufferIndexFinder terminatorFinder);
1740 
1741     /**
1742      * Returns a hash code which was calculated from the content of this
1743      * buffer.  If there's a byte array which is
1744      * {@linkplain #equals(Object) equal to} this array, both arrays should
1745      * return the same value.
1746      */
1747     int hashCode();
1748 
1749     /**
1750      * Determines if the content of the specified buffer is identical to the
1751      * content of this array.  'Identical' here means:
1752      * <ul>
1753      * <li>the size of the contents of the two buffers are same and</li>
1754      * <li>every single byte of the content of the two buffers are same.</li>
1755      * </ul>
1756      * Please note that it does not compare {@link #readerIndex()} nor
1757      * {@link #writerIndex()}.  This method also returns {@code false} for
1758      * {@code null} and an object which is not an instance of
1759      * {@link ChannelBuffer} type.
1760      */
1761     boolean equals(Object obj);
1762 
1763     /**
1764      * Compares the content of the specified buffer to the content of this
1765      * buffer.  Comparison is performed in the same manner with the string
1766      * comparison functions of various languages such as {@code strcmp},
1767      * {@code memcmp} and {@link String#compareTo(String)}.
1768      */
1769     int compareTo(ChannelBuffer buffer);
1770 
1771     /**
1772      * Returns the string representation of this buffer.  This method does not
1773      * necessarily return the whole content of the buffer but returns
1774      * the values of the key properties such as {@link #readerIndex()},
1775      * {@link #writerIndex()} and {@link #capacity()}.
1776      */
1777     String toString();
1778 }