View Javadoc

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