    001    /*
    002     * Copyright 2009 Red Hat, Inc.
    003     * Red Hat licenses this file to you under the Apache License, version
    004     * 2.0 (the "License"); you may not use this file except in compliance
    005     * with the License.  You may obtain a copy of the License at
    006     *    http://www.apache.org/licenses/LICENSE-2.0
    007     * Unless required by applicable law or agreed to in writing, software
    008     * distributed under the License is distributed on an "AS IS" BASIS,
    009     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    010     * implied.  See the License for the specific language governing
    011     * permissions and limitations under the License.
    012     */
    013
    014    package org.hornetq.api.core;
    015
    016    import java.nio.ByteBuffer;
    017
    018    import org.jboss.netty.buffer.ChannelBuffer;
    019
    020    /**
    021     *
    022     * A HornetQBuffer wraps a Netty's ChannelBuffer and is used throughout HornetQ code base.
    023     *
    024     * Much of it derived from Netty ChannelBuffer by Trustin Lee
    025     *
    026     * @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
    027     *
    028     * @see HornetQBuffers
    029     *
    030     */
    031    public interface HornetQBuffer
    032    {
    033       /**
    034        * Returns the underlying Netty's ChannelBuffer
    035        *
    036        * @return the underlying Netty's ChannelBuffer
    037        */
    038       ChannelBuffer channelBuffer();
    039
    040       /**
    041        * Returns the number of bytes this buffer can contain.
    042        */
    043       int capacity();
    044
    045       /**
    046        * Returns the {@code readerIndex} of this buffer.
    047        */
    048       int readerIndex();
    049
    050       /**
    051        * Sets the {@code readerIndex} of this buffer.
    052        *
    053        * @throws IndexOutOfBoundsException
    054        *         if the specified {@code readerIndex} is
    055        *            less than {@code 0} or
    056        *            greater than {@code this.writerIndex}
    057        */
    058       void readerIndex(int readerIndex);
    059
    060       /**
    061        * Returns the {@code writerIndex} of this buffer.
    062        */
    063       int writerIndex();
    064
    065       /**
    066        * Sets the {@code writerIndex} of this buffer.
    067        *
    068        * @throws IndexOutOfBoundsException
    069        *         if the specified {@code writerIndex} is
    070        *            less than {@code this.readerIndex} or
    071        *            greater than {@code this.capacity}
    072        */
    073       void writerIndex(int writerIndex);
    074
    075       /**
    076        * Sets the {@code readerIndex} and {@code writerIndex} of this buffer
    077        * in one shot.  This method is useful when you have to worry about the
    078        * invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)}
    079        * methods.  For example, the following code will fail:
    080        *
    081        * <pre>
    082        * // Create a buffer whose readerIndex, writerIndex and capacity are
    083        * // 0, 0 and 8 respectively.
    084        * ChannelBuffer buf = ChannelBuffers.buffer(8);
    085        *
    086        * // IndexOutOfBoundsException is thrown because the specified
    087        * // readerIndex (2) cannot be greater than the current writerIndex (0).
    088        * buf.readerIndex(2);
    089        * buf.writerIndex(4);
    090        * </pre>
    091        *
    092        * The following code will also fail:
    093        *
    094        * <pre>
    095        * // Create a buffer whose readerIndex, writerIndex and capacity are
    096        * // 0, 8 and 8 respectively.
    097        * ChannelBuffer buf = ChannelBuffers.wrappedBuffer(new byte[8]);
    098        *
    099        * // readerIndex becomes 8.
    100        * buf.readLong();
    101        *
    102        * // IndexOutOfBoundsException is thrown because the specified
    103        * // writerIndex (4) cannot be less than the current readerIndex (8).
    104        * buf.writerIndex(4);
    105        * buf.readerIndex(2);
    106        * </pre>
    107        *
    108        * By contrast, {@link #setIndex(int, int)} guarantees that it never
    109        * throws an {@link IndexOutOfBoundsException} as long as the specified
    110        * indexes meet basic constraints, regardless what the current index
    111        * values of the buffer are:
    112        *
    113        * <pre>
    114        * // No matter what the current state of the buffer is, the following
    115        * // call always succeeds as long as the capacity of the buffer is not
    116        * // less than 4.
    117        * buf.setIndex(2, 4);
    118        * </pre>
    119        *
    120        * @throws IndexOutOfBoundsException
    121        *         if the specified {@code readerIndex} is less than 0,
    122        *         if the specified {@code writerIndex} is less than the specified
    123        *         {@code readerIndex} or if the specified {@code writerIndex} is
    124        *         greater than {@code this.capacity}
    125        */
    126       void setIndex(int readerIndex, int writerIndex);
    127
    128       /**
    129        * Returns the number of readable bytes which is equal to
    130        * {@code (this.writerIndex - this.readerIndex)}.
    131        */
    132       int readableBytes();
    133
    134       /**
    135        * Returns the number of writable bytes which is equal to
    136        * {@code (this.capacity - this.writerIndex)}.
    137        */
    138       int writableBytes();
    139
    140       /**
    141        * Returns {@code true}
    142        * if and only if {@code (this.writerIndex - this.readerIndex)} is greater
    143        * than {@code 0}.
    144        */
    145       boolean readable();
    146
    147       /**
    148        * Returns {@code true}
    149        * if and only if {@code (this.capacity - this.writerIndex)} is greater
    150        * than {@code 0}.
    151        */
    152       boolean writable();
    153
    154       /**
    155        * Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
    156        * {@code 0}.
    157        * This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}.
    158        * <p>
    159        * Please note that the behavior of this method is different
    160        * from that of NIO buffer, which sets the {@code limit} to
    161        * the {@code capacity} of the buffer.
    162        */
    163       void clear();
    164
    165       /**
    166        * Marks the current {@code readerIndex} in this buffer.  You can
    167        * reposition the current {@code readerIndex} to the marked
    168        * {@code readerIndex} by calling {@link #resetReaderIndex()}.
    169        * The initial value of the marked {@code readerIndex} is {@code 0}.
    170        */
    171       void markReaderIndex();
    172
    173       /**
    174        * Repositions the current {@code readerIndex} to the marked
    175        * {@code readerIndex} in this buffer.
    176        *
    177        * @throws IndexOutOfBoundsException
    178        *         if the current {@code writerIndex} is less than the marked
    179        *         {@code readerIndex}
    180        */
    181       void resetReaderIndex();
    182
    183       /**
    184        * Marks the current {@code writerIndex} in this buffer.  You can
    185        * reposition the current {@code writerIndex} to the marked
    186        * {@code writerIndex} by calling {@link #resetWriterIndex()}.
    187        * The initial value of the marked {@code writerIndex} is {@code 0}.
    188        */
    189       void markWriterIndex();
    190
    191       /**
    192        * Repositions the current {@code writerIndex} to the marked
    193        * {@code writerIndex} in this buffer.
    194        *
    195        * @throws IndexOutOfBoundsException
    196        *         if the current {@code readerIndex} is greater than the marked
    197        *         {@code writerIndex}
    198        */
    199       void resetWriterIndex();
    200
    201       /**
    202        * Discards the bytes between the 0th index and {@code readerIndex}.
    203        * It moves the bytes between {@code readerIndex} and {@code writerIndex}
    204        * to the 0th index, and sets {@code readerIndex} and {@code writerIndex}
    205        * to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively.
    206        * <p>
    207        * Please refer to the class documentation for more detailed explanation.
    208        */
    209       void discardReadBytes();
    210
    211       /**
    212        * Gets a byte at the specified absolute {@code index} in this buffer.
    213        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    214        * this buffer.
    215        *
    216        * @throws IndexOutOfBoundsException
    217        *         if the specified {@code index} is less than {@code 0} or
    218        *         {@code index + 1} is greater than {@code this.capacity}
    219        */
    220       byte  getByte(int index);
    221
    222       /**
    223        * Gets an unsigned byte at the specified absolute {@code index} in this
    224        * buffer.  This method does not modify {@code readerIndex} or
    225        * {@code writerIndex} of this buffer.
    226        *
    227        * @throws IndexOutOfBoundsException
    228        *         if the specified {@code index} is less than {@code 0} or
    229        *         {@code index + 1} is greater than {@code this.capacity}
    230        */
    231       short getUnsignedByte(int index);
    232
    233       /**
    234        * Gets a 16-bit short integer at the specified absolute {@code index} in
    235        * this buffer.  This method does not modify {@code readerIndex} or
    236        * {@code writerIndex} of this buffer.
    237        *
    238        * @throws IndexOutOfBoundsException
    239        *         if the specified {@code index} is less than {@code 0} or
    240        *         {@code index + 2} is greater than {@code this.capacity}
    241        */
    242       short getShort(int index);
    243
    244       /**
    245        * Gets an unsigned 16-bit short integer at the specified absolute
    246        * {@code index} in this buffer.  This method does not modify
    247        * {@code readerIndex} or {@code writerIndex} of this buffer.
    248        *
    249        * @throws IndexOutOfBoundsException
    250        *         if the specified {@code index} is less than {@code 0} or
    251        *         {@code index + 2} is greater than {@code this.capacity}
    252        */
    253       int getUnsignedShort(int index);
    254
    255       /**
    256        * Gets a 32-bit integer at the specified absolute {@code index} in
    257        * this buffer.  This method does not modify {@code readerIndex} or
    258        * {@code writerIndex} of this buffer.
    259        *
    260        * @throws IndexOutOfBoundsException
    261        *         if the specified {@code index} is less than {@code 0} or
    262        *         {@code index + 4} is greater than {@code this.capacity}
    263        */
    264       int   getInt(int index);
    265
    266       /**
    267        * Gets an unsigned 32-bit integer at the specified absolute {@code index}
    268        * in this buffer.  This method does not modify {@code readerIndex} or
    269        * {@code writerIndex} of this buffer.
    270        *
    271        * @throws IndexOutOfBoundsException
    272        *         if the specified {@code index} is less than {@code 0} or
    273        *         {@code index + 4} is greater than {@code this.capacity}
    274        */
    275       long  getUnsignedInt(int index);
    276
    277       /**
    278        * Gets a 64-bit long integer at the specified absolute {@code index} in
    279        * this buffer.  This method does not modify {@code readerIndex} or
    280        * {@code writerIndex} of this buffer.
    281        *
    282        * @throws IndexOutOfBoundsException
    283        *         if the specified {@code index} is less than {@code 0} or
    284        *         {@code index + 8} is greater than {@code this.capacity}
    285        */
    286       long  getLong(int index);
    287
    288       /**
    289        * Transfers this buffer's data to the specified destination starting at
    290        * the specified absolute {@code index} until the destination becomes
    291        * non-writable.  This method is basically same with
    292        * {@link #getBytes(int, HornetQBuffer, int, int)}, except that this
    293        * method increases the {@code writerIndex} of the destination by the
    294        * number of the transferred bytes while
    295        * {@link #getBytes(int, HornetQBuffer, int, int)} does not.
    296        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    297        * the source buffer (i.e. {@code this}).
    298        *
    299        * @throws IndexOutOfBoundsException
    300        *         if the specified {@code index} is less than {@code 0} or
    301        *         if {@code index + dst.writableBytes} is greater than
    302        *            {@code this.capacity}
    303        */
    304       void getBytes(int index, HornetQBuffer dst);
    305
    306       /**
    307        * Transfers this buffer's data to the specified destination starting at
    308        * the specified absolute {@code index}.  This method is basically same
    309        * with {@link #getBytes(int, HornetQBuffer, int, int)}, except that this
    310        * method increases the {@code writerIndex} of the destination by the
    311        * number of the transferred bytes while
    312        * {@link #getBytes(int, HornetQBuffer, int, int)} does not.
    313        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    314        * the source buffer (i.e. {@code this}).
    315        *
    316        * @param length the number of bytes to transfer
    317        *
    318        * @throws IndexOutOfBoundsException
    319        *         if the specified {@code index} is less than {@code 0},
    320        *         if {@code index + length} is greater than
    321        *            {@code this.capacity}, or
    322        *         if {@code length} is greater than {@code dst.writableBytes}
    323        */
    324       void getBytes(int index, HornetQBuffer dst, int length);
    325
    326       /**
    327        * Transfers this buffer's data to the specified destination starting at
    328        * the specified absolute {@code index}.
    329        * This method does not modify {@code readerIndex} or {@code writerIndex}
    330        * of both the source (i.e. {@code this}) and the destination.
    331        *
    332        * @param dstIndex the first index of the destination
    333        * @param length   the number of bytes to transfer
    334        *
    335        * @throws IndexOutOfBoundsException
    336        *         if the specified {@code index} is less than {@code 0},
    337        *         if the specified {@code dstIndex} is less than {@code 0},
    338        *         if {@code index + length} is greater than
    339        *            {@code this.capacity}, or
    340        *         if {@code dstIndex + length} is greater than
    341        *            {@code dst.capacity}
    342        */
    343       void getBytes(int index, HornetQBuffer dst, int dstIndex, int length);
    344
    345       /**
    346        * Transfers this buffer's data to the specified destination starting at
    347        * the specified absolute {@code index}.
    348        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    349        * this buffer
    350        *
    351        * @throws IndexOutOfBoundsException
    352        *         if the specified {@code index} is less than {@code 0} or
    353        *         if {@code index + dst.length} is greater than
    354        *            {@code this.capacity}
    355        */
    356       void getBytes(int index, byte[] dst);
    357
    358       /**
    359        * Transfers this buffer's data to the specified destination starting at
    360        * the specified absolute {@code index}.
    361        * This method does not modify {@code readerIndex} or {@code writerIndex}
    362        * of this buffer.
    363        *
    364        * @param dstIndex the first index of the destination
    365        * @param length   the number of bytes to transfer
    366        *
    367        * @throws IndexOutOfBoundsException
    368        *         if the specified {@code index} is less than {@code 0},
    369        *         if the specified {@code dstIndex} is less than {@code 0},
    370        *         if {@code index + length} is greater than
    371        *            {@code this.capacity}, or
    372        *         if {@code dstIndex + length} is greater than
    373        *            {@code dst.length}
    374        */
    375       void getBytes(int index, byte[] dst, int dstIndex, int length);
    376
    377       /**
    378        * Transfers this buffer's data to the specified destination starting at
    379        * the specified absolute {@code index} until the destination's position
    380        * reaches its limit.
    381        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    382        * this buffer while the destination's {@code position} will be increased.
    383        *
    384        * @throws IndexOutOfBoundsException
    385        *         if the specified {@code index} is less than {@code 0} or
    386        *         if {@code index + dst.remaining()} is greater than
    387        *            {@code this.capacity}
    388        */
    389       void getBytes(int index, ByteBuffer dst);
    390
    391       /**
    392        * Gets a char at the specified absolute {@code index} in
    393        * this buffer.  This method does not modify {@code readerIndex} or
    394        * {@code writerIndex} of this buffer.
    395        *
    396        * @throws IndexOutOfBoundsException
    397        *         if the specified {@code index} is less than {@code 0} or
    398        *         {@code index + 2} is greater than {@code this.capacity}
    399        */
    400       char getChar(int index);
    401
    402       /**
    403        * Gets a float at the specified absolute {@code index} in
    404        * this buffer.  This method does not modify {@code readerIndex} or
    405        * {@code writerIndex} of this buffer.
    406        *
    407        * @throws IndexOutOfBoundsException
    408        *         if the specified {@code index} is less than {@code 0} or
    409        *         {@code index + 4} is greater than {@code this.capacity}
    410        */
    411       float getFloat(int index);
    412
    413       /**
    414        * Gets a double at the specified absolute {@code index} in
    415        * this buffer.  This method does not modify {@code readerIndex} or
    416        * {@code writerIndex} of this buffer.
    417        *
    418        * @throws IndexOutOfBoundsException
    419        *         if the specified {@code index} is less than {@code 0} or
    420        *         {@code index + 8} is greater than {@code this.capacity}
    421        */
    422       double getDouble(int index);
    423
    424       /**
    425        * Sets the specified byte at the specified absolute {@code index} in this
    426        * buffer.
    427        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    428        * this buffer.
    429        *
    430        * @throws IndexOutOfBoundsException
    431        *         if the specified {@code index} is less than {@code 0} or
    432        *         {@code index + 1} is greater than {@code this.capacity}
    433        */
    434       void setByte(int index, byte value);
    435
    436       /**
    437        * Sets the specified 16-bit short integer at the specified absolute
    438        * {@code index} in this buffer.
    439        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    440        * this buffer.
    441        *
    442        * @throws IndexOutOfBoundsException
    443        *         if the specified {@code index} is less than {@code 0} or
    444        *         {@code index + 2} is greater than {@code this.capacity}
    445        */
    446       void setShort(int index, short value);
    447
    448       /**
    449        * Sets the specified 32-bit integer at the specified absolute
    450        * {@code index} in this buffer.
    451        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    452        * this buffer.
    453        *
    454        * @throws IndexOutOfBoundsException
    455        *         if the specified {@code index} is less than {@code 0} or
    456        *         {@code index + 4} is greater than {@code this.capacity}
    457        */
    458       void setInt(int index, int value);
    459
    460       /**
    461        * Sets the specified 64-bit long integer at the specified absolute
    462        * {@code index} in this buffer.
    463        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    464        * this buffer.
    465        *
    466        * @throws IndexOutOfBoundsException
    467        *         if the specified {@code index} is less than {@code 0} or
    468        *         {@code index + 8} is greater than {@code this.capacity}
    469        */
    470       void setLong(int index, long value);
    471
    472       /**
    473        * Transfers the specified source buffer's data to this buffer starting at
    474        * the specified absolute {@code index} until the destination becomes
    475        * unreadable.  This method is basically same with
    476        * {@link #setBytes(int, HornetQBuffer, int, int)}, except that this
    477        * method increases the {@code readerIndex} of the source buffer by
    478        * the number of the transferred bytes while
    479        * {@link #getBytes(int, HornetQBuffer, int, int)} does not.
    480        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    481        * the source buffer (i.e. {@code this}).
    482        *
    483        * @throws IndexOutOfBoundsException
    484        *         if the specified {@code index} is less than {@code 0} or
    485        *         if {@code index + src.readableBytes} is greater than
    486        *            {@code this.capacity}
    487        */
    488       void setBytes(int index, HornetQBuffer src);
    489
    490       /**
    491        * Transfers the specified source buffer's data to this buffer starting at
    492        * the specified absolute {@code index}.  This method is basically same
    493        * with {@link #setBytes(int, HornetQBuffer, int, int)}, except that this
    494        * method increases the {@code readerIndex} of the source buffer by
    495        * the number of the transferred bytes while
    496        * {@link #getBytes(int, HornetQBuffer, int, int)} does not.
    497        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    498        * the source buffer (i.e. {@code this}).
    499        *
    500        * @param length the number of bytes to transfer
    501        *
    502        * @throws IndexOutOfBoundsException
    503        *         if the specified {@code index} is less than {@code 0},
    504        *         if {@code index + length} is greater than
    505        *            {@code this.capacity}, or
    506        *         if {@code length} is greater than {@code src.readableBytes}
    507        */
    508       void setBytes(int index, HornetQBuffer src, int length);
    509
    510       /**
    511        * Transfers the specified source buffer's data to this buffer starting at
    512        * the specified absolute {@code index}.
    513        * This method does not modify {@code readerIndex} or {@code writerIndex}
    514        * of both the source (i.e. {@code this}) and the destination.
    515        *
    516        * @param srcIndex the first index of the source
    517        * @param length   the number of bytes to transfer
    518        *
    519        * @throws IndexOutOfBoundsException
    520        *         if the specified {@code index} is less than {@code 0},
    521        *         if the specified {@code srcIndex} is less than {@code 0},
    522        *         if {@code index + length} is greater than
    523        *            {@code this.capacity}, or
    524        *         if {@code srcIndex + length} is greater than
    525        *            {@code src.capacity}
    526        */
    527       void setBytes(int index, HornetQBuffer src, int srcIndex, int length);
    528
    529       /**
    530        * Transfers the specified source array's data to this buffer starting at
    531        * the specified absolute {@code index}.
    532        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    533        * this buffer.
    534        *
    535        * @throws IndexOutOfBoundsException
    536        *         if the specified {@code index} is less than {@code 0} or
    537        *         if {@code index + src.length} is greater than
    538        *            {@code this.capacity}
    539        */
    540       void setBytes(int index, byte[] src);
    541
    542       /**
    543        * Transfers the specified source array's data to this buffer starting at
    544        * the specified absolute {@code index}.
    545        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    546        * this buffer.
    547        *
    548        * @throws IndexOutOfBoundsException
    549        *         if the specified {@code index} is less than {@code 0},
    550        *         if the specified {@code srcIndex} is less than {@code 0},
    551        *         if {@code index + length} is greater than
    552        *            {@code this.capacity}, or
    553        *         if {@code srcIndex + length} is greater than {@code src.length}
    554        */
    555       void setBytes(int index, byte[] src, int srcIndex, int length);
    556
    557       /**
    558        * Transfers the specified source buffer's data to this buffer starting at
    559        * the specified absolute {@code index} until the source buffer's position
    560        * reaches its limit.
    561        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    562        * this buffer.
    563        *
    564        * @throws IndexOutOfBoundsException
    565        *         if the specified {@code index} is less than {@code 0} or
    566        *         if {@code index + src.remaining()} is greater than
    567        *            {@code this.capacity}
    568        */
    569       void setBytes(int index, ByteBuffer src);
    570
    571       /**
    572        * Sets the specified char at the specified absolute
    573        * {@code index} in this buffer.
    574        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    575        * this buffer.
    576        *
    577        * @throws IndexOutOfBoundsException
    578        *         if the specified {@code index} is less than {@code 0} or
    579        *         {@code index + 2} is greater than {@code this.capacity}
    580        */
    581       void setChar(int index, char value);
    582
    583       /**
    584        * Sets the specified float at the specified absolute
    585        * {@code index} in this buffer.
    586        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    587        * this buffer.
    588        *
    589        * @throws IndexOutOfBoundsException
    590        *         if the specified {@code index} is less than {@code 0} or
    591        *         {@code index + 4} is greater than {@code this.capacity}
    592        */
    593       void setFloat(int index, float value);
    594
    595       /**
    596        * Sets the specified double at the specified absolute
    597        * {@code index} in this buffer.
    598        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    599        * this buffer.
    600        *
    601        * @throws IndexOutOfBoundsException
    602        *         if the specified {@code index} is less than {@code 0} or
    603        *         {@code index + 8} is greater than {@code this.capacity}
    604        */
    605       void setDouble(int index, double value);
    606
    607       /**
    608        * Gets a byte at the current {@code readerIndex} and increases
    609        * the {@code readerIndex} by {@code 1} in this buffer.
    610        *
    611        * @throws IndexOutOfBoundsException
    612        *         if {@code this.readableBytes} is less than {@code 1}
    613        */
    614       byte readByte();
    615
    616       /**
    617        * Gets an unsigned byte at the current {@code readerIndex} and increases
    618        * the {@code readerIndex} by {@code 1} in this buffer.
    619        *
    620        * @throws IndexOutOfBoundsException
    621        *         if {@code this.readableBytes} is less than {@code 1}
    622        */
    623       short readUnsignedByte();
    624
    625       /**
    626        * Gets a 16-bit short integer at the current {@code readerIndex}
    627        * and increases the {@code readerIndex} by {@code 2} in this buffer.
    628        *
    629        * @throws IndexOutOfBoundsException
    630        *         if {@code this.readableBytes} is less than {@code 2}
    631        */
    632       short readShort();
    633
    634       /**
    635        * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
    636        * and increases the {@code readerIndex} by {@code 2} in this buffer.
    637        *
    638        * @throws IndexOutOfBoundsException
    639        *         if {@code this.readableBytes} is less than {@code 2}
    640        */
    641       int   readUnsignedShort();
    642
    643       /**
    644        * Gets a 32-bit integer at the current {@code readerIndex}
    645        * and increases the {@code readerIndex} by {@code 4} in this buffer.
    646        *
    647        * @throws IndexOutOfBoundsException
    648        *         if {@code this.readableBytes} is less than {@code 4}
    649        */
    650       int   readInt();
    651
    652       /**
    653        * Gets an unsigned 32-bit integer at the current {@code readerIndex}
    654        * and increases the {@code readerIndex} by {@code 4} in this buffer.
    655        *
    656        * @throws IndexOutOfBoundsException
    657        *         if {@code this.readableBytes} is less than {@code 4}
    658        */
    659       long  readUnsignedInt();
    660
    661       /**
    662        * Gets a 64-bit integer at the current {@code readerIndex}
    663        * and increases the {@code readerIndex} by {@code 8} in this buffer.
    664        *
    665        * @throws IndexOutOfBoundsException
    666        *         if {@code this.readableBytes} is less than {@code 8}
    667        */
    668       long  readLong();
    669
    670       /**
    671        * Gets a char at the current {@code readerIndex}
    672        * and increases the {@code readerIndex} by {@code 2} in this buffer.
    673        *
    674        * @throws IndexOutOfBoundsException
    675        *         if {@code this.readableBytes} is less than {@code 2}
    676        */
    677       char readChar();
    678
    679       /**
    680        * Gets a float at the current {@code readerIndex}
    681        * and increases the {@code readerIndex} by {@code 4} in this buffer.
    682        *
    683        * @throws IndexOutOfBoundsException
    684        *         if {@code this.readableBytes} is less than {@code 4}
    685        */
    686       float readFloat();
    687
    688       /**
    689        * Gets a double at the current {@code readerIndex}
    690        * and increases the {@code readerIndex} by {@code 8} in this buffer.
    691        *
    692        * @throws IndexOutOfBoundsException
    693        *         if {@code this.readableBytes} is less than {@code 8}
    694        */
    695       double readDouble();
    696
    697       /**
    698        * Gets a boolean at the current {@code readerIndex}
    699        * and increases the {@code readerIndex} by {@code 1} in this buffer.
    700        *
    701        * @throws IndexOutOfBoundsException
    702        *         if {@code this.readableBytes} is less than {@code 1}
    703        */
    704       boolean readBoolean();
    705
    706       /**
    707        * Gets a SimpleString (potentially {@code null}) at the current {@code readerIndex}
    708        */
    709       SimpleString readNullableSimpleString();
    710
    711       /**
    712        * Gets a String (potentially {@code null}) at the current {@code readerIndex}
    713        */
    714       String readNullableString();
    715
    716       /**
    717        * Gets a non-null SimpleString at the current {@code readerIndex}
    718        */
    719       SimpleString readSimpleString();
    720
    721       /**
    722        * Gets a non-null String at the current {@code readerIndex}
    723        */
    724       String readString();
    725
    726       /**
    727        * Gets a UTF-8 String at the current {@code readerIndex}
    728        */
    729       String readUTF();
    730
    731       /**
    732        * Transfers this buffer's data to a newly created buffer starting at
    733        * the current {@code readerIndex} and increases the {@code readerIndex}
    734        * by the number of the transferred bytes (= {@code length}).
    735        * The returned buffer's {@code readerIndex} and {@code writerIndex} are
    736        * {@code 0} and {@code length} respectively.
    737        *
    738        * @param length the number of bytes to transfer
    739        *
    740        * @return the newly created buffer which contains the transferred bytes
    741        *
    742        * @throws IndexOutOfBoundsException
    743        *         if {@code length} is greater than {@code this.readableBytes}
    744        */
    745       HornetQBuffer readBytes(int length);
    746
    747       /**
    748        * Returns a new slice of this buffer's sub-region starting at the current
    749        * {@code readerIndex} and increases the {@code readerIndex} by the size
    750        * of the new slice (= {@code length}).
    751        *
    752        * @param length the size of the new slice
    753        *
    754        * @return the newly created slice
    755        *
    756        * @throws IndexOutOfBoundsException
    757        *         if {@code length} is greater than {@code this.readableBytes}
    758        */
    759       HornetQBuffer readSlice(int length);
    760
    761       /**
    762        * Transfers this buffer's data to the specified destination starting at
    763        * the current {@code readerIndex} until the destination becomes
    764        * non-writable, and increases the {@code readerIndex} by the number of the
    765        * transferred bytes.  This method is basically same with
    766        * {@link #readBytes(HornetQBuffer, int, int)}, except that this method
    767        * increases the {@code writerIndex} of the destination by the number of
    768        * the transferred bytes while {@link #readBytes(HornetQBuffer, int, int)}
    769        * does not.
    770        *
    771        * @throws IndexOutOfBoundsException
    772        *         if {@code dst.writableBytes} is greater than
    773        *            {@code this.readableBytes}
    774        */
    775       void readBytes(HornetQBuffer dst);
    776
    777       /**
    778        * Transfers this buffer's data to the specified destination starting at
    779        * the current {@code readerIndex} and increases the {@code readerIndex}
    780        * by the number of the transferred bytes (= {@code length}).  This method
    781        * is basically same with {@link #readBytes(HornetQBuffer, int, int)},
    782        * except that this method increases the {@code writerIndex} of the
    783        * destination by the number of the transferred bytes (= {@code length})
    784        * while {@link #readBytes(HornetQBuffer, int, int)} does not.
    785        *
    786        * @throws IndexOutOfBoundsException
    787        *         if {@code length} is greater than {@code this.readableBytes} or
    788        *         if {@code length} is greater than {@code dst.writableBytes}
    789        */
    790       void readBytes(HornetQBuffer dst, int length);
    791
    792       /**
    793        * Transfers this buffer's data to the specified destination starting at
    794        * the current {@code readerIndex} and increases the {@code readerIndex}
    795        * by the number of the transferred bytes (= {@code length}).
    796        *
    797        * @param dstIndex the first index of the destination
    798        * @param length   the number of bytes to transfer
    799        *
    800        * @throws IndexOutOfBoundsException
    801        *         if the specified {@code dstIndex} is less than {@code 0},
    802        *         if {@code length} is greater than {@code this.readableBytes}, or
    803        *         if {@code dstIndex + length} is greater than
    804        *            {@code dst.capacity}
    805        */
    806       void readBytes(HornetQBuffer dst, int dstIndex, int length);
    807
    808       /**
    809        * Transfers this buffer's data to the specified destination starting at
    810        * the current {@code readerIndex} and increases the {@code readerIndex}
    811        * by the number of the transferred bytes (= {@code dst.length}).
    812        *
    813        * @throws IndexOutOfBoundsException
    814        *         if {@code dst.length} is greater than {@code this.readableBytes}
    815        */
    816       void readBytes(byte[] dst);
    817
    818       /**
    819        * Transfers this buffer's data to the specified destination starting at
    820        * the current {@code readerIndex} and increases the {@code readerIndex}
    821        * by the number of the transferred bytes (= {@code length}).
    822        *
    823        * @param dstIndex the first index of the destination
    824        * @param length   the number of bytes to transfer
    825        *
    826        * @throws IndexOutOfBoundsException
    827        *         if the specified {@code dstIndex} is less than {@code 0},
    828        *         if {@code length} is greater than {@code this.readableBytes}, or
    829        *         if {@code dstIndex + length} is greater than {@code dst.length}
    830        */
    831       void readBytes(byte[] dst, int dstIndex, int length);
    832
    833       /**
    834        * Transfers this buffer's data to the specified destination starting at
    835        * the current {@code readerIndex} until the destination's position
    836        * reaches its limit, and increases the {@code readerIndex} by the
    837        * number of the transferred bytes.
    838        *
    839        * @throws IndexOutOfBoundsException
    840        *         if {@code dst.remaining()} is greater than
    841        *            {@code this.readableBytes}
    842        */
    843       void readBytes(ByteBuffer dst);
    844
    845       /**
    846        * Increases the current {@code readerIndex} by the specified
    847        * {@code length} in this buffer.
    848        *
    849        * @throws IndexOutOfBoundsException
    850        *         if {@code length} is greater than {@code this.readableBytes}
    851        */
    852       void skipBytes(int length);
    853
    854       /**
    855        * Sets the specified byte at the current {@code writerIndex}
    856        * and increases the {@code writerIndex} by {@code 1} in this buffer.
    857        *
    858        * @throws IndexOutOfBoundsException
    859        *         if {@code this.writableBytes} is less than {@code 1}
    860        */
    861       void writeByte(byte  value);
    862
    863       /**
    864        * Sets the specified 16-bit short integer at the current
    865        * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
    866        * in this buffer.
    867        *
    868        * @throws IndexOutOfBoundsException
    869        *         if {@code this.writableBytes} is less than {@code 2}
    870        */
    871       void writeShort(short value);
    872
    873       /**
    874        * Sets the specified 32-bit integer at the current {@code writerIndex}
    875        * and increases the {@code writerIndex} by {@code 4} in this buffer.
    876        *
    877        * @throws IndexOutOfBoundsException
    878        *         if {@code this.writableBytes} is less than {@code 4}
    879        */
    880       void writeInt(int   value);
    881
    882       /**
    883        * Sets the specified 64-bit long integer at the current
    884        * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
    885        * in this buffer.
    886        *
    887        * @throws IndexOutOfBoundsException
    888        *         if {@code this.writableBytes} is less than {@code 8}
    889        */
    890       void writeLong(long  value);
    891
    892       /**
    893        * Sets the specified char at the current {@code writerIndex}
    894        * and increases the {@code writerIndex} by {@code 2} in this buffer.
    895        *
    896        * @throws IndexOutOfBoundsException
    897        *         if {@code this.writableBytes} is less than {@code 2}
    898        */
    899       void writeChar(char chr);
    900
    901       /**
    902        * Sets the specified float at the current {@code writerIndex}
    903        * and increases the {@code writerIndex} by {@code 4} in this buffer.
    904        *
    905        * @throws IndexOutOfBoundsException
    906        *         if {@code this.writableBytes} is less than {@code 4}
    907        */
    908       void writeFloat(float value);
    909
    910       /**
    911        * Sets the specified double at the current {@code writerIndex}
    912        * and increases the {@code writerIndex} by {@code 8} in this buffer.
    913        *
    914        * @throws IndexOutOfBoundsException
    915        *         if {@code this.writableBytes} is less than {@code 8}
    916        */
    917       void writeDouble(double value);
    918
    919       /**
    920        * Sets the specified boolean at the current {@code writerIndex}
    921        */
    922       void writeBoolean(boolean val);
    923
    924       /**
    925        * Sets the specified SimpleString (potentially {@code null}) at the current {@code writerIndex}
    926        */
    927       void writeNullableSimpleString(SimpleString val);
    928
    929       /**
    930        * Sets the specified String (potentially {@code null}) at the current {@code writerIndex}
    931        */
    932       void writeNullableString(String val);
    933
    934       /**
    935        * Sets the specified non-null SimpleString at the current {@code writerIndex}
    936        */
    937       void writeSimpleString(SimpleString val);
    938
    939       /**
    940        * Sets the specified non-null String at the current {@code writerIndex}
    941        */
    942       void writeString(String val);
    943
    944       /**
    945        * Sets the specified UTF-8 String at the current {@code writerIndex}
    946        */
    947
    948       void writeUTF(String utf);
    949
    950       /**
    951        * Transfers the specified source buffer's data to this buffer starting at
    952        * the current {@code writerIndex} and increases the {@code writerIndex}
    953        * by the number of the transferred bytes (= {@code length}).  This method
    954        * is basically same with {@link #writeBytes(HornetQBuffer, int, int)},
    955        * except that this method increases the {@code readerIndex} of the source
    956        * buffer by the number of the transferred bytes (= {@code length}) while
    957        * {@link #writeBytes(HornetQBuffer, int, int)} does not.
    958        *
    959        * @param length the number of bytes to transfer
    960        *
    961        * @throws IndexOutOfBoundsException
    962        *         if {@code length} is greater than {@code this.writableBytes} or
    963        *         if {@code length} is greater then {@code src.readableBytes}
    964        */
    965       void writeBytes(HornetQBuffer src, int length);
    966
    967       /**
    968        * Transfers the specified source buffer's data to this buffer starting at
    969        * the current {@code writerIndex} and increases the {@code writerIndex}
    970        * by the number of the transferred bytes (= {@code length}).
    971        *
    972        * @param srcIndex the first index of the source
    973        * @param length   the number of bytes to transfer
    974        *
    975        * @throws IndexOutOfBoundsException
    976        *         if the specified {@code srcIndex} is less than {@code 0},
    977        *         if {@code srcIndex + length} is greater than
    978        *            {@code src.capacity}, or
    979        *         if {@code length} is greater than {@code this.writableBytes}
    980        */
    981       void writeBytes(HornetQBuffer src, int srcIndex, int length);
    982
    983       /**
    984        * Transfers the specified source array's data to this buffer starting at
    985        * the current {@code writerIndex} and increases the {@code writerIndex}
    986        * by the number of the transferred bytes (= {@code src.length}).
    987        *
    988        * @throws IndexOutOfBoundsException
    989        *         if {@code src.length} is greater than {@code this.writableBytes}
    990        */
    991       void writeBytes(byte[] src);
    992
    993       /**
    994        * Transfers the specified source array's data to this buffer starting at
    995        * the current {@code writerIndex} and increases the {@code writerIndex}
    996        * by the number of the transferred bytes (= {@code length}).
    997        *
    998        * @param srcIndex the first index of the source
    999        * @param length   the number of bytes to transfer
    1000        *
    1001        * @throws IndexOutOfBoundsException
    1002        *         if the specified {@code srcIndex} is less than {@code 0},
    1003        *         if {@code srcIndex + length} is greater than
    1004        *            {@code src.length}, or
    1005        *         if {@code length} is greater than {@code this.writableBytes}
    1006        */
    1007       void writeBytes(byte[] src, int srcIndex, int length);
    1008
    1009       /**
    1010        * Transfers the specified source buffer's data to this buffer starting at
    1011        * the current {@code writerIndex} until the source buffer's position
    1012        * reaches its limit, and increases the {@code writerIndex} by the
    1013        * number of the transferred bytes.
    1014        *
    1015        * @throws IndexOutOfBoundsException
    1016        *         if {@code src.remaining()} is greater than
    1017        *            {@code this.writableBytes}
    1018        */
    1019       void writeBytes(ByteBuffer src);
    1020
    1021       /**
    1022        * Returns a copy of this buffer's readable bytes.  Modifying the content
    1023        * of the returned buffer or this buffer does not affect each other at all.
    1024        * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
    1025        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1026        * this buffer.
    1027        *
    1028        */
    1029       HornetQBuffer copy();
    1030
    1031       /**
    1032        * Returns a copy of this buffer's sub-region.  Modifying the content of
    1033        * the returned buffer or this buffer does not affect each other at all.
    1034        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1035        * this buffer.
    1036        */
    1037       HornetQBuffer copy(int index, int length);
    1038
    1039       /**
    1040        * Returns a slice of this buffer's readable bytes. Modifying the content
    1041        * of the returned buffer or this buffer affects each other's content
    1042        * while they maintain separate indexes and marks.  This method is
    1043        * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
    1044        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1045        * this buffer.
    1046        */
    1047       HornetQBuffer slice();
    1048
    1049       /**
    1050        * Returns a slice of this buffer's sub-region. Modifying the content of
    1051        * the returned buffer or this buffer affects each other's content while
    1052        * they maintain separate indexes and marks.
    1053        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1054        * this buffer.
    1055        */
    1056       HornetQBuffer slice(int index, int length);
    1057
    1058       /**
    1059        * Returns a buffer which shares the whole region of this buffer.
    1060        * Modifying the content of the returned buffer or this buffer affects
    1061        * each other's content while they maintain separate indexes and marks.
    1062        * This method is identical to {@code buf.slice(0, buf.capacity())}.
    1063        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1064        * this buffer.
    1065        */
    1066       HornetQBuffer duplicate();
    1067
    1068       /**
    1069        * Converts this buffer's readable bytes into a NIO buffer.  The returned
    1070        * buffer might or might not share the content with this buffer, while
    1071        * they have separate indexes and marks.  This method is identical to
    1072        * {@code buf.toByteBuffer(buf.readerIndex(), buf.readableBytes())}.
    1073        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1074        * this buffer.
    1075        */
    1076       ByteBuffer toByteBuffer();
    1077
    1078       /**
    1079        * Converts this buffer's sub-region into a NIO buffer.  The returned
    1080        * buffer might or might not share the content with this buffer, while
    1081        * they have separate indexes and marks.
    1082        * This method does not modify {@code readerIndex} or {@code writerIndex} of
    1083        * this buffer.
    1084        */
    1085       ByteBuffer toByteBuffer(int index, int length);
    1086    }