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    }