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 = array.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 }