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
014package org.hornetq.api.core;
015
016import java.nio.ByteBuffer;
017
018import 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 */
031public 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}