netty5/buffer/src/main/java/io/netty/buffer/ByteBuf.java

1960 lines
78 KiB
Java
Raw Normal View History

/*
2012-06-04 22:31:44 +02:00
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
2012-06-04 22:31:44 +02:00
* http://www.apache.org/licenses/LICENSE-2.0
*
2009-08-28 09:15:49 +02:00
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2009-08-28 09:15:49 +02:00
* License for the specific language governing permissions and limitations
* under the License.
*/
2011-12-09 04:38:59 +01:00
package io.netty.buffer;
import io.netty.util.ReferenceCounted;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
2008-08-10 16:25:13 +02:00
import java.nio.charset.UnsupportedCharsetException;
/**
2008-09-02 09:13:20 +02:00
* A random and sequential accessible sequence of zero or more bytes (octets).
* This interface provides an abstract view for one or more primitive byte
* arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}.
*
* <h3>Creation of a buffer</h3>
*
2008-09-03 03:04:33 +02:00
* It is recommended to create a new buffer using the helper methods in
* {@link Unpooled} rather than calling an individual implementation's
2008-09-03 03:04:33 +02:00
* constructor.
*
* <h3>Random Access Indexing</h3>
*
* Just like an ordinary primitive byte array, {@link ByteBuf} uses
2012-06-08 12:28:12 +02:00
* <a href="http://en.wikipedia.org/wiki/Zero-based_numbering">zero-based indexing</a>.
* It means the index of the first byte is always {@code 0} and the index of the last byte is
* always {@link #capacity() capacity - 1}. For example, to iterate all bytes of a buffer, you
* can do the following, regardless of its internal implementation:
*
* <pre>
* {@link ByteBuf} buffer = ...;
* for (int i = 0; i &lt; buffer.capacity(); i ++) {
* byte b = buffer.getByte(i);
* System.out.println((char) b);
* }
* </pre>
*
* <h3>Sequential Access Indexing</h3>
*
* {@link ByteBuf} provides two pointer variables to support sequential
* read and write operations - {@link #readerIndex() readerIndex} for a read
* operation and {@link #writerIndex() writerIndex} for a write operation
* respectively. The following diagram shows how a buffer is segmented into
* three areas by the two pointers:
*
* <pre>
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* | | (CONTENT) | |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
* </pre>
*
* <h4>Readable bytes (the actual content)</h4>
*
* This segment is where the actual data is stored. Any operation whose name
* starts with {@code read} or {@code skip} will get or skip the data at the
* current {@link #readerIndex() readerIndex} and increase it by the number of
* read bytes. If the argument of the read operation is also a
* {@link ByteBuf} and no destination index is specified, the specified
* buffer's {@link #readerIndex() readerIndex} is increased together.
* <p>
* If there's not enough content left, {@link IndexOutOfBoundsException} is
* raised. The default value of newly allocated, wrapped or copied buffer's
* {@link #readerIndex() readerIndex} is {@code 0}.
*
* <pre>
* // Iterates the readable bytes of a buffer.
* {@link ByteBuf} buffer = ...;
* while (buffer.readable()) {
* System.out.println(buffer.readByte());
* }
* </pre>
*
* <h4>Writable bytes</h4>
*
* This segment is a undefined space which needs to be filled. Any operation
* whose name ends with {@code write} will write the data at the current
* {@link #writerIndex() writerIndex} and increase it by the number of written
* bytes. If the argument of the write operation is also a {@link ByteBuf},
* and no source index is specified, the specified buffer's
* {@link #readerIndex() readerIndex} is increased together.
* <p>
* If there's not enough writable bytes left, {@link IndexOutOfBoundsException}
* is raised. The default value of newly allocated buffer's
* {@link #writerIndex() writerIndex} is {@code 0}. The default value of
* wrapped or copied buffer's {@link #writerIndex() writerIndex} is the
* {@link #capacity() capacity} of the buffer.
*
* <pre>
* // Fills the writable bytes of a buffer with random integers.
* {@link ByteBuf} buffer = ...;
2013-04-03 15:18:38 +02:00
* while (buffer.maxWritableBytes() >= 4) {
* buffer.writeInt(random.nextInt());
* }
* </pre>
*
* <h4>Discardable bytes</h4>
*
* This segment contains the bytes which were read already by a read operation.
* Initially, the size of this segment is {@code 0}, but its size increases up
* to the {@link #writerIndex() writerIndex} as read operations are executed.
* The read bytes can be discarded by calling {@link #discardReadBytes()} to
* reclaim unused area as depicted by the following diagram:
*
* <pre>
* BEFORE discardReadBytes()
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
*
* AFTER discardReadBytes()
*
* +------------------+--------------------------------------+
* | readable bytes | writable bytes (got more space) |
* +------------------+--------------------------------------+
* | | |
* readerIndex (0) <= writerIndex (decreased) <= capacity
* </pre>
*
* Please note that there is no guarantee about the content of writable bytes
* after calling {@link #discardReadBytes()}. The writable bytes will not be
* moved in most cases and could even be filled with completely different data
* depending on the underlying buffer implementation.
*
* <h4>Clearing the buffer indexes</h4>
*
* You can set both {@link #readerIndex() readerIndex} and
* {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}.
2008-11-14 08:45:53 +01:00
* It does not clear the buffer content (e.g. filling with {@code 0}) but just
* clears the two pointers. Please also note that the semantic of this
* operation is different from {@link ByteBuffer#clear()}.
*
* <pre>
* BEFORE clear()
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
*
* AFTER clear()
*
* +---------------------------------------------------------+
* | writable bytes (got more space) |
* +---------------------------------------------------------+
* | |
* 0 = readerIndex = writerIndex <= capacity
* </pre>
*
* <h3>Search operations</h3>
*
* For simple single-byte searches, use {@link #indexOf(int, int, byte)} and {@link #bytesBefore(int, int, byte)}.
* {@link #bytesBefore(byte)} is especially useful when you deal with a {@code NUL}-terminated string.
* For complicated searches, use {@link #forEachByte(int, int, ByteBufProcessor)} with a {@link ByteBufProcessor}
* implementation.
*
* <h3>Mark and reset</h3>
*
* There are two marker indexes in every buffer. One is for storing
* {@link #readerIndex() readerIndex} and the other is for storing
* {@link #writerIndex() writerIndex}. You can always reposition one of the
* two indexes by calling a reset method. It works in a similar fashion to
* the mark and reset methods in {@link InputStream} except that there's no
* {@code readlimit}.
*
* <h3>Derived buffers</h3>
*
* You can create a view of an existing buffer by calling either
* {@link #duplicate()}, {@link #slice()} or {@link #slice(int, int)}.
* A derived buffer will have an independent {@link #readerIndex() readerIndex},
* {@link #writerIndex() writerIndex} and marker indexes, while it shares
* other internal data representation, just like a NIO buffer does.
* <p>
* In case a completely fresh copy of an existing buffer is required, please
* call {@link #copy()} method instead.
*
* <h3>Conversion to existing JDK types</h3>
*
2010-05-06 09:33:26 +02:00
* <h4>Byte array</h4>
*
* If a {@link ByteBuf} is backed by a byte array (i.e. {@code byte[]}),
2010-05-06 09:33:26 +02:00
* you can access it directly via the {@link #array()} method. To determine
* if a buffer is backed by a byte array, {@link #hasArray()} should be used.
*
* <h4>NIO Buffers</h4>
2008-08-10 07:09:55 +02:00
*
* If a {@link ByteBuf} can be converted into an NIO {@link ByteBuffer} which shares its
* content (i.e. view buffer), you can get it via the {@link #nioBuffer()} method. To determine
2013-03-28 10:01:26 +01:00
* if a buffer can be converted into an NIO buffer, use {@link #nioBufferCount()}.
2008-08-10 07:09:55 +02:00
*
* <h4>Strings</h4>
2008-08-10 07:09:55 +02:00
*
* Various {@link #toString(Charset)} methods convert a {@link ByteBuf}
* into a {@link String}. Please note that {@link #toString()} is not a
2008-08-10 07:09:55 +02:00
* conversion method.
*
* <h4>I/O Streams</h4>
2008-08-10 07:09:55 +02:00
*
* Please refer to {@link ByteBufInputStream} and
* {@link ByteBufOutputStream}.
*/
Revamp the core API to reduce memory footprint and consumption The API changes made so far turned out to increase the memory footprint and consumption while our intention was actually decreasing them. Memory consumption issue: When there are many connections which does not exchange data frequently, the old Netty 4 API spent a lot more memory than 3 because it always allocates per-handler buffer for each connection unless otherwise explicitly stated by a user. In a usual real world load, a client doesn't always send requests without pausing, so the idea of having a buffer whose life cycle if bound to the life cycle of a connection didn't work as expected. Memory footprint issue: The old Netty 4 API decreased overall memory footprint by a great deal in many cases. It was mainly because the old Netty 4 API did not allocate a new buffer and event object for each read. Instead, it created a new buffer for each handler in a pipeline. This works pretty well as long as the number of handlers in a pipeline is only a few. However, for a highly modular application with many handlers which handles connections which lasts for relatively short period, it actually makes the memory footprint issue much worse. Changes: All in all, this is about retaining all the good changes we made in 4 so far such as better thread model and going back to the way how we dealt with message events in 3. To fix the memory consumption/footprint issue mentioned above, we made a hard decision to break the backward compatibility again with the following changes: - Remove MessageBuf - Merge Buf into ByteBuf - Merge ChannelInboundByte/MessageHandler and ChannelStateHandler into ChannelInboundHandler - Similar changes were made to the adapter classes - Merge ChannelOutboundByte/MessageHandler and ChannelOperationHandler into ChannelOutboundHandler - Similar changes were made to the adapter classes - Introduce MessageList which is similar to `MessageEvent` in Netty 3 - Replace inboundBufferUpdated(ctx) with messageReceived(ctx, MessageList) - Replace flush(ctx, promise) with write(ctx, MessageList, promise) - Remove ByteToByteEncoder/Decoder/Codec - Replaced by MessageToByteEncoder<ByteBuf>, ByteToMessageDecoder<ByteBuf>, and ByteMessageCodec<ByteBuf> - Merge EmbeddedByteChannel and EmbeddedMessageChannel into EmbeddedChannel - Add SimpleChannelInboundHandler which is sometimes more useful than ChannelInboundHandlerAdapter - Bring back Channel.isWritable() from Netty 3 - Add ChannelInboundHandler.channelWritabilityChanges() event - Add RecvByteBufAllocator configuration property - Similar to ReceiveBufferSizePredictor in Netty 3 - Some existing configuration properties such as DatagramChannelConfig.receivePacketSize is gone now. - Remove suspend/resumeIntermediaryDeallocation() in ByteBuf This change would have been impossible without @normanmaurer's help. He fixed, ported, and improved many parts of the changes.
2013-05-28 13:40:19 +02:00
public interface ByteBuf extends ReferenceCounted, Comparable<ByteBuf> {
/**
* Returns the number of bytes (octets) this buffer can contain.
*/
int capacity();
/**
* Adjusts the capacity of this buffer. If the {@code newCapacity} is less than the current
* capacity, the content of this buffer is truncated. If the {@code newCapacity} is greater
* than the current capacity, the buffer is appended with unspecified data whose length is
* {@code (newCapacity - currentCapacity)}.
*/
ByteBuf capacity(int newCapacity);
/**
* Returns the maximum allowed capacity of this buffer. If a user attempts to increase the
* capacity of this buffer beyond the maximum capacity using {@link #capacity(int)} or
* {@link #ensureWritable(int)}, those methods will raise an
* {@link IllegalArgumentException}.
*/
int maxCapacity();
ByteBufAllocator API w/ ByteBuf perf improvements This commit introduces a new API for ByteBuf allocation which fixes issue #643 along with refactoring of ByteBuf for simplicity and better performance. (see #62) A user can configure the ByteBufAllocator of a Channel via ChannelOption.ALLOCATOR or ChannelConfig.get/setAllocator(). The default allocator is currently UnpooledByteBufAllocator.HEAP_BY_DEFAULT. To allocate a buffer, do not use Unpooled anymore. do the following: ctx.alloc().buffer(...); // allocator chooses the buffer type. ctx.alloc().heapBuffer(...); ctx.alloc().directBuffer(...); To deallocate a buffer, use the unsafe free() operation: ((UnsafeByteBuf) buf).free(); The following is the list of the relevant changes: - Add ChannelInboundHandler.freeInboundBuffer() and ChannelOutboundHandler.freeOutboundBuffer() to let a user free the buffer he or she allocated. ChannelHandler adapter classes implement is already, so most users won't need to call free() by themselves. freeIn/OutboundBuffer() methods are invoked when a Channel is closed and deregistered. - All ByteBuf by contract must implement UnsafeByteBuf. To access an unsafe operation: ((UnsafeByteBuf) buf).internalNioBuffer() - Replace WrappedByteBuf and ByteBuf.Unsafe with UnsafeByteBuf to simplify overall class hierarchy and to avoid unnecesary instantiation of Unsafe instances on an unsafe operation. - Remove buffer reference counting which is confusing - Instantiate SwappedByteBuf lazily to avoid instantiation cost - Rename ChannelFutureFactory to ChannelPropertyAccess and move common methods between Channel and ChannelHandlerContext there. Also made it package-private to hide it from a user. - Remove unused unsafe operations such as newBuffer() - Add DetectionUtil.canFreeDirectBuffer() so that an allocator decides which buffer type to use safely
2012-11-15 22:04:37 +01:00
/**
* Returns the {@link ByteBufAllocator} which created this buffer.
*/
ByteBufAllocator alloc();
/**
* Returns the <a href="http://en.wikipedia.org/wiki/Endianness">endianness</a>
* of this buffer.
*/
ByteOrder order();
/**
* Returns a buffer with the specified {@code endianness} which shares the whole region,
* indexes, and marks of this buffer. Modifying the content, the indexes, or the marks of the
* returned buffer or this buffer affects each other's content, indexes, and marks. If the
* specified {@code endianness} is identical to this buffer's byte order, this method can
* return {@code this}. This method does not modify {@code readerIndex} or {@code writerIndex}
* of this buffer.
*/
ByteBuf order(ByteOrder endianness);
/**
* Return the underlying buffer instance if this buffer is a wrapper of another buffer.
*
* @return {@code null} if this buffer is not a wrapper
*/
ByteBuf unwrap();
/**
* Returns {@code true} if and only if this buffer is backed by an
* NIO direct buffer.
*/
boolean isDirect();
/**
* Returns the {@code readerIndex} of this buffer.
*/
int readerIndex();
/**
* Sets the {@code readerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code readerIndex} is
* less than {@code 0} or
* greater than {@code this.writerIndex}
*/
ByteBuf readerIndex(int readerIndex);
/**
* Returns the {@code writerIndex} of this buffer.
*/
int writerIndex();
/**
* Sets the {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code writerIndex} is
* less than {@code this.readerIndex} or
* greater than {@code this.capacity}
*/
ByteBuf writerIndex(int writerIndex);
/**
* Sets the {@code readerIndex} and {@code writerIndex} of this buffer
2008-08-10 16:25:13 +02:00
* in one shot. This method is useful when you have to worry about the
* invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)}
* methods. For example, the following code will fail:
*
* <pre>
* // Create a buffer whose readerIndex, writerIndex and capacity are
* // 0, 0 and 8 respectively.
* {@link ByteBuf} buf = {@link Unpooled}.buffer(8);
*
* // IndexOutOfBoundsException is thrown because the specified
* // readerIndex (2) cannot be greater than the current writerIndex (0).
* buf.readerIndex(2);
* buf.writerIndex(4);
* </pre>
*
* The following code will also fail:
*
* <pre>
* // Create a buffer whose readerIndex, writerIndex and capacity are
* // 0, 8 and 8 respectively.
* {@link ByteBuf} buf = {@link Unpooled}.wrappedBuffer(new byte[8]);
*
* // readerIndex becomes 8.
* buf.readLong();
*
* // IndexOutOfBoundsException is thrown because the specified
* // writerIndex (4) cannot be less than the current readerIndex (8).
* buf.writerIndex(4);
* buf.readerIndex(2);
* </pre>
*
* By contrast, this method guarantees that it never
* throws an {@link IndexOutOfBoundsException} as long as the specified
* indexes meet basic constraints, regardless what the current index
* values of the buffer are:
*
* <pre>
* // No matter what the current state of the buffer is, the following
* // call always succeeds as long as the capacity of the buffer is not
* // less than 4.
* buf.setIndex(2, 4);
* </pre>
*
* @throws IndexOutOfBoundsException
* if the specified {@code readerIndex} is less than 0,
* if the specified {@code writerIndex} is less than the specified
* {@code readerIndex} or if the specified {@code writerIndex} is
2008-08-10 16:25:13 +02:00
* greater than {@code this.capacity}
*/
ByteBuf setIndex(int readerIndex, int writerIndex);
/**
* Returns the number of readable bytes which is equal to
2008-08-10 16:25:13 +02:00
* {@code (this.writerIndex - this.readerIndex)}.
*/
int readableBytes();
/**
* Returns the number of writable bytes which is equal to
2008-08-10 16:25:13 +02:00
* {@code (this.capacity - this.writerIndex)}.
*/
int writableBytes();
/**
* Returns the maximum possible number of writable bytes, which is equal to
* {@code (this.maxCapacity - this.writerIndex)}.
*/
int maxWritableBytes();
/**
2008-08-10 16:25:13 +02:00
* Returns {@code true}
* if and only if {@code (this.writerIndex - this.readerIndex)} is greater
* than {@code 0}.
*/
boolean isReadable();
Revamp the core API to reduce memory footprint and consumption The API changes made so far turned out to increase the memory footprint and consumption while our intention was actually decreasing them. Memory consumption issue: When there are many connections which does not exchange data frequently, the old Netty 4 API spent a lot more memory than 3 because it always allocates per-handler buffer for each connection unless otherwise explicitly stated by a user. In a usual real world load, a client doesn't always send requests without pausing, so the idea of having a buffer whose life cycle if bound to the life cycle of a connection didn't work as expected. Memory footprint issue: The old Netty 4 API decreased overall memory footprint by a great deal in many cases. It was mainly because the old Netty 4 API did not allocate a new buffer and event object for each read. Instead, it created a new buffer for each handler in a pipeline. This works pretty well as long as the number of handlers in a pipeline is only a few. However, for a highly modular application with many handlers which handles connections which lasts for relatively short period, it actually makes the memory footprint issue much worse. Changes: All in all, this is about retaining all the good changes we made in 4 so far such as better thread model and going back to the way how we dealt with message events in 3. To fix the memory consumption/footprint issue mentioned above, we made a hard decision to break the backward compatibility again with the following changes: - Remove MessageBuf - Merge Buf into ByteBuf - Merge ChannelInboundByte/MessageHandler and ChannelStateHandler into ChannelInboundHandler - Similar changes were made to the adapter classes - Merge ChannelOutboundByte/MessageHandler and ChannelOperationHandler into ChannelOutboundHandler - Similar changes were made to the adapter classes - Introduce MessageList which is similar to `MessageEvent` in Netty 3 - Replace inboundBufferUpdated(ctx) with messageReceived(ctx, MessageList) - Replace flush(ctx, promise) with write(ctx, MessageList, promise) - Remove ByteToByteEncoder/Decoder/Codec - Replaced by MessageToByteEncoder<ByteBuf>, ByteToMessageDecoder<ByteBuf>, and ByteMessageCodec<ByteBuf> - Merge EmbeddedByteChannel and EmbeddedMessageChannel into EmbeddedChannel - Add SimpleChannelInboundHandler which is sometimes more useful than ChannelInboundHandlerAdapter - Bring back Channel.isWritable() from Netty 3 - Add ChannelInboundHandler.channelWritabilityChanges() event - Add RecvByteBufAllocator configuration property - Similar to ReceiveBufferSizePredictor in Netty 3 - Some existing configuration properties such as DatagramChannelConfig.receivePacketSize is gone now. - Remove suspend/resumeIntermediaryDeallocation() in ByteBuf This change would have been impossible without @normanmaurer's help. He fixed, ported, and improved many parts of the changes.
2013-05-28 13:40:19 +02:00
/**
* Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements.
*/
boolean isReadable(int size);
/**
2008-08-10 16:25:13 +02:00
* Returns {@code true}
* if and only if {@code (this.capacity - this.writerIndex)} is greater
* than {@code 0}.
*/
boolean isWritable();
Revamp the core API to reduce memory footprint and consumption The API changes made so far turned out to increase the memory footprint and consumption while our intention was actually decreasing them. Memory consumption issue: When there are many connections which does not exchange data frequently, the old Netty 4 API spent a lot more memory than 3 because it always allocates per-handler buffer for each connection unless otherwise explicitly stated by a user. In a usual real world load, a client doesn't always send requests without pausing, so the idea of having a buffer whose life cycle if bound to the life cycle of a connection didn't work as expected. Memory footprint issue: The old Netty 4 API decreased overall memory footprint by a great deal in many cases. It was mainly because the old Netty 4 API did not allocate a new buffer and event object for each read. Instead, it created a new buffer for each handler in a pipeline. This works pretty well as long as the number of handlers in a pipeline is only a few. However, for a highly modular application with many handlers which handles connections which lasts for relatively short period, it actually makes the memory footprint issue much worse. Changes: All in all, this is about retaining all the good changes we made in 4 so far such as better thread model and going back to the way how we dealt with message events in 3. To fix the memory consumption/footprint issue mentioned above, we made a hard decision to break the backward compatibility again with the following changes: - Remove MessageBuf - Merge Buf into ByteBuf - Merge ChannelInboundByte/MessageHandler and ChannelStateHandler into ChannelInboundHandler - Similar changes were made to the adapter classes - Merge ChannelOutboundByte/MessageHandler and ChannelOperationHandler into ChannelOutboundHandler - Similar changes were made to the adapter classes - Introduce MessageList which is similar to `MessageEvent` in Netty 3 - Replace inboundBufferUpdated(ctx) with messageReceived(ctx, MessageList) - Replace flush(ctx, promise) with write(ctx, MessageList, promise) - Remove ByteToByteEncoder/Decoder/Codec - Replaced by MessageToByteEncoder<ByteBuf>, ByteToMessageDecoder<ByteBuf>, and ByteMessageCodec<ByteBuf> - Merge EmbeddedByteChannel and EmbeddedMessageChannel into EmbeddedChannel - Add SimpleChannelInboundHandler which is sometimes more useful than ChannelInboundHandlerAdapter - Bring back Channel.isWritable() from Netty 3 - Add ChannelInboundHandler.channelWritabilityChanges() event - Add RecvByteBufAllocator configuration property - Similar to ReceiveBufferSizePredictor in Netty 3 - Some existing configuration properties such as DatagramChannelConfig.receivePacketSize is gone now. - Remove suspend/resumeIntermediaryDeallocation() in ByteBuf This change would have been impossible without @normanmaurer's help. He fixed, ported, and improved many parts of the changes.
2013-05-28 13:40:19 +02:00
/**
* Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of
* elements.
*/
boolean isWritable(int size);
/**
* Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
* {@code 0}.
* This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}.
* <p>
* Please note that the behavior of this method is different
* from that of NIO buffer, which sets the {@code limit} to
2008-08-10 16:25:13 +02:00
* the {@code capacity} of the buffer.
*/
ByteBuf clear();
/**
2008-08-10 16:25:13 +02:00
* Marks the current {@code readerIndex} in this buffer. You can
* reposition the current {@code readerIndex} to the marked
* {@code readerIndex} by calling {@link #resetReaderIndex()}.
* The initial value of the marked {@code readerIndex} is {@code 0}.
*/
ByteBuf markReaderIndex();
/**
2008-08-10 16:25:13 +02:00
* Repositions the current {@code readerIndex} to the marked
* {@code readerIndex} in this buffer.
*
* @throws IndexOutOfBoundsException
* if the current {@code writerIndex} is less than the marked
* {@code readerIndex}
*/
ByteBuf resetReaderIndex();
/**
2008-08-10 16:25:13 +02:00
* Marks the current {@code writerIndex} in this buffer. You can
* reposition the current {@code writerIndex} to the marked
* {@code writerIndex} by calling {@link #resetWriterIndex()}.
* The initial value of the marked {@code writerIndex} is {@code 0}.
*/
ByteBuf markWriterIndex();
/**
2008-08-10 16:25:13 +02:00
* Repositions the current {@code writerIndex} to the marked
* {@code writerIndex} in this buffer.
*
* @throws IndexOutOfBoundsException
* if the current {@code readerIndex} is greater than the marked
* {@code writerIndex}
*/
ByteBuf resetWriterIndex();
/**
* Discards the bytes between the 0th index and {@code readerIndex}.
* It moves the bytes between {@code readerIndex} and {@code writerIndex}
* to the 0th index, and sets {@code readerIndex} and {@code writerIndex}
* to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively.
* <p>
2008-08-10 16:25:13 +02:00
* Please refer to the class documentation for more detailed explanation.
*/
ByteBuf discardReadBytes();
/**
* Similar to {@link ByteBuf#discardReadBytes()} except that this method might discard
* some, all, or none of read bytes depending on its internal implementation to reduce
* overall memory bandwidth consumption at the cost of potentially additional memory
* consumption.
*/
ByteBuf discardSomeReadBytes();
/**
* Makes sure the number of {@linkplain #writableBytes() the writable bytes}
* is equal to or greater than the specified value. If there is enough
* writable bytes in this buffer, this method returns with no side effect.
* Otherwise, it raises an {@link IllegalArgumentException}.
*
* @param minWritableBytes
* the expected minimum number of writable bytes
* @throws IndexOutOfBoundsException
* if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
*/
ByteBuf ensureWritable(int minWritableBytes);
/**
* Tries to make sure the number of {@linkplain #writableBytes() the writable bytes}
* is equal to or greater than the specified value. Unlike {@link #ensureWritable(int)},
* this method does not raise an exception but returns a code.
*
* @param minWritableBytes
* the expected minimum number of writable bytes
* @param force
* When {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}:
* <ul>
* <li>{@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}</li>
* <li>{@code false} - the capacity of the buffer is unchanged</li>
* </ul>
* @return {@code 0} if the buffer has enough writable bytes, and its capacity is unchanged.
* {@code 1} if the buffer does not have enough bytes, and its capacity is unchanged.
* {@code 2} if the buffer has enough writable bytes, and its capacity has been increased.
* {@code 3} if the buffer does not have enough bytes, but its capacity has been
* increased to its maximum.
*/
int ensureWritable(int minWritableBytes, boolean force);
2012-05-31 21:03:01 +02:00
/**
* Gets a boolean at the specified absolute (@code index) in this buffer.
* This method does not modify the {@code readerIndex} or {@code writerIndex}
* of this buffer.
2012-05-31 21:03:01 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 1} is greater than {@code this.capacity}
*/
boolean getBoolean(int index);
/**
* Gets a byte at the specified absolute {@code index} in this buffer.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 1} is greater than {@code this.capacity}
*/
byte getByte(int index);
2008-08-10 02:52:59 +02:00
/**
* Gets an unsigned byte at the specified absolute {@code index} in this
2009-04-24 15:56:35 +02:00
* buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
2008-08-10 02:52:59 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 1} is greater than {@code this.capacity}
2008-08-10 02:52:59 +02:00
*/
short getUnsignedByte(int index);
/**
* Gets a 16-bit short integer at the specified absolute {@code index} in
2009-04-24 15:56:35 +02:00
* this buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 2} is greater than {@code this.capacity}
*/
short getShort(int index);
2008-08-10 02:52:59 +02:00
/**
* Gets an unsigned 16-bit short integer at the specified absolute
2009-04-24 15:56:35 +02:00
* {@code index} in this buffer. This method does not modify
* {@code readerIndex} or {@code writerIndex} of this buffer.
2008-08-10 02:52:59 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 2} is greater than {@code this.capacity}
2008-08-10 02:52:59 +02:00
*/
int getUnsignedShort(int index);
/**
* Gets a 24-bit medium integer at the specified absolute {@code index} in
2009-04-24 15:56:35 +02:00
* this buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 3} is greater than {@code this.capacity}
*/
int getMedium(int index);
2008-08-10 02:52:59 +02:00
/**
* Gets an unsigned 24-bit medium integer at the specified absolute
2009-04-24 15:56:35 +02:00
* {@code index} in this buffer. This method does not modify
* {@code readerIndex} or {@code writerIndex} of this buffer.
2008-08-10 02:52:59 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 3} is greater than {@code this.capacity}
2008-08-10 02:52:59 +02:00
*/
int getUnsignedMedium(int index);
/**
* Gets a 32-bit integer at the specified absolute {@code index} in
2009-04-24 15:56:35 +02:00
* this buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 4} is greater than {@code this.capacity}
*/
int getInt(int index);
2008-08-10 02:52:59 +02:00
/**
* Gets an unsigned 32-bit integer at the specified absolute {@code index}
2009-04-24 15:56:35 +02:00
* in this buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
2008-08-10 02:52:59 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 4} is greater than {@code this.capacity}
2008-08-10 02:52:59 +02:00
*/
long getUnsignedInt(int index);
/**
* Gets a 64-bit long integer at the specified absolute {@code index} in
2009-04-24 15:56:35 +02:00
* this buffer. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 8} is greater than {@code this.capacity}
*/
long getLong(int index);
/**
* Gets a 2-byte UTF-16 character at the specified absolute
* {@code index} in this buffer. This method does not modify
* {@code readerIndex} or {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 2} is greater than {@code this.capacity}
*/
char getChar(int index);
/**
* Gets a 32-bit floating point number at the specified absolute
* {@code index} in this buffer. This method does not modify
* {@code readerIndex} or {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 4} is greater than {@code this.capacity}
*/
float getFloat(int index);
/**
* Gets a 64-bit floating point number at the specified absolute
* {@code index} in this buffer. This method does not modify
* {@code readerIndex} or {@code writerIndex} of this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 8} is greater than {@code this.capacity}
*/
double getDouble(int index);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index} until the destination becomes
* non-writable. This method is basically same with
* {@link #getBytes(int, ByteBuf, int, int)}, except that this
2008-08-10 16:25:13 +02:00
* method increases the {@code writerIndex} of the destination by the
* number of the transferred bytes while
* {@link #getBytes(int, ByteBuf, int, int)} does not.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + dst.writableBytes} is greater than
* {@code this.capacity}
*/
ByteBuf getBytes(int index, ByteBuf dst);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}. This method is basically same
* with {@link #getBytes(int, ByteBuf, int, int)}, except that this
* method increases the {@code writerIndex} of the destination by the
* number of the transferred bytes while
* {@link #getBytes(int, ByteBuf, int, int)} does not.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code length} is greater than {@code dst.writableBytes}
*/
ByteBuf getBytes(int index, ByteBuf dst, int length);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of both the source (i.e. {@code this}) and the destination.
*
2008-08-10 16:25:13 +02:00
* @param dstIndex the first index of the destination
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code dstIndex} is less than {@code 0},
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code dstIndex + length} is greater than
* {@code dst.capacity}
*/
ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + dst.length} is greater than
* {@code this.capacity}
*/
ByteBuf getBytes(int index, byte[] dst);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of this buffer.
*
2008-08-10 16:25:13 +02:00
* @param dstIndex the first index of the destination
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code dstIndex} is less than {@code 0},
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code dstIndex + length} is greater than
* {@code dst.length}
*/
ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length);
/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index} until the destination's position
* reaches its limit.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer while the destination's {@code position} will be increased.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + dst.remaining()} is greater than
* {@code this.capacity}
*/
ByteBuf getBytes(int index, ByteBuffer dst);
/**
* Transfers this buffer's data to the specified stream starting at the
* specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
2008-08-10 16:25:13 +02:00
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}
* @throws IOException
* if the specified stream threw an exception during I/O
*/
ByteBuf getBytes(int index, OutputStream out, int length) throws IOException;
/**
* Transfers this buffer's data to the specified channel starting at the
* specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
2008-08-10 16:25:13 +02:00
* @param length the maximum number of bytes to transfer
*
* @return the actual number of bytes written out to the specified channel
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
int getBytes(int index, GatheringByteChannel out, int length) throws IOException;
/**
* Sets the specified boolean at the specified absolute {@code index} in this
* buffer.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 1} is greater than {@code this.capacity}
*/
ByteBuf setBoolean(int index, boolean value);
2012-05-31 21:03:01 +02:00
/**
* Sets the specified byte at the specified absolute {@code index} in this
* buffer. The 24 high-order bits of the specified value are ignored.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 1} is greater than {@code this.capacity}
*/
ByteBuf setByte(int index, int value);
/**
* Sets the specified 16-bit short integer at the specified absolute
* {@code index} in this buffer. The 16 high-order bits of the specified
* value are ignored.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 2} is greater than {@code this.capacity}
*/
ByteBuf setShort(int index, int value);
/**
* Sets the specified 24-bit medium integer at the specified absolute
* {@code index} in this buffer. Please note that the most significant
* byte is ignored in the specified value.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 3} is greater than {@code this.capacity}
*/
ByteBuf setMedium(int index, int value);
/**
* Sets the specified 32-bit integer at the specified absolute
* {@code index} in this buffer.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 4} is greater than {@code this.capacity}
*/
ByteBuf setInt(int index, int value);
/**
* Sets the specified 64-bit long integer at the specified absolute
* {@code index} in this buffer.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* {@code index + 8} is greater than {@code this.capacity}
*/
ByteBuf setLong(int index, long value);
/**
* Sets the specified 2-byte UTF-16 character at the specified absolute
* {@code index} in this buffer.
* The 16 high-order bits of the specified value are ignored.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 2} is greater than {@code this.capacity}
*/
ByteBuf setChar(int index, int value);
/**
* Sets the specified 32-bit floating-point number at the specified
* absolute {@code index} in this buffer.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 4} is greater than {@code this.capacity}
*/
ByteBuf setFloat(int index, float value);
/**
* Sets the specified 64-bit floating-point number at the specified
* absolute {@code index} in this buffer.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 8} is greater than {@code this.capacity}
*/
ByteBuf setDouble(int index, double value);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
2010-05-06 09:33:26 +02:00
* the specified absolute {@code index} until the source buffer becomes
2008-08-10 16:25:13 +02:00
* unreadable. This method is basically same with
* {@link #setBytes(int, ByteBuf, int, int)}, except that this
* method increases the {@code readerIndex} of the source buffer by
2008-08-10 16:25:13 +02:00
* the number of the transferred bytes while
* {@link #setBytes(int, ByteBuf, int, int)} does not.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
2008-08-10 07:09:55 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + src.readableBytes} is greater than
* {@code this.capacity}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setBytes(int index, ByteBuf src);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the specified absolute {@code index}. This method is basically same
* with {@link #setBytes(int, ByteBuf, int, int)}, except that this
* method increases the {@code readerIndex} of the source buffer by
* the number of the transferred bytes while
* {@link #setBytes(int, ByteBuf, int, int)} does not.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code length} is greater than {@code src.readableBytes}
*/
ByteBuf setBytes(int index, ByteBuf src, int length);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of both the source (i.e. {@code this}) and the destination.
2008-08-10 07:09:55 +02:00
*
2008-08-10 16:25:13 +02:00
* @param srcIndex the first index of the source
* @param length the number of bytes to transfer
*
2008-08-10 07:09:55 +02:00
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code srcIndex} is less than {@code 0},
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code srcIndex + length} is greater than
* {@code src.capacity}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source array's data to this buffer starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + src.length} is greater than
* {@code this.capacity}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setBytes(int index, byte[] src);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source array's data to this buffer starting at
* the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code srcIndex} is less than {@code 0},
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code srcIndex + length} is greater than {@code src.length}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setBytes(int index, byte[] src, int srcIndex, int length);
2008-08-10 07:09:55 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the specified absolute {@code index} until the source buffer's position
* reaches its limit.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + src.remaining()} is greater than
* {@code this.capacity}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setBytes(int index, ByteBuffer src);
2008-08-10 07:09:55 +02:00
/**
* Transfers the content of the specified source stream to this buffer
* starting at the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
2008-08-10 16:25:13 +02:00
* @param length the number of bytes to transfer
*
* @return the actual number of bytes read in from the specified channel.
* {@code -1} if the specified channel is closed.
*
2008-08-10 07:09:55 +02:00
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than {@code this.capacity}
2008-08-10 07:09:55 +02:00
* @throws IOException
* if the specified stream threw an exception during I/O
*/
int setBytes(int index, InputStream in, int length) throws IOException;
2008-08-10 07:09:55 +02:00
/**
* Transfers the content of the specified source channel to this buffer
* starting at the specified absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
2008-08-10 16:25:13 +02:00
* @param length the maximum number of bytes to transfer
*
* @return the actual number of bytes read in from the specified channel.
* {@code -1} if the specified channel is closed.
2008-08-10 07:09:55 +02:00
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than {@code this.capacity}
2008-08-10 07:09:55 +02:00
* @throws IOException
* if the specified channel threw an exception during I/O
*/
int setBytes(int index, ScatteringByteChannel in, int length) throws IOException;
2008-08-10 07:09:55 +02:00
/**
* Fills this buffer with <tt>NUL (0x00)</tt> starting at the specified
* absolute {@code index}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 07:09:55 +02:00
*
* @param length the number of <tt>NUL</tt>s to write to the buffer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
2008-08-10 16:25:13 +02:00
* if {@code index + length} is greater than {@code this.capacity}
2008-08-10 07:09:55 +02:00
*/
ByteBuf setZero(int index, int length);
2012-05-31 21:03:01 +02:00
/**
* Gets a boolean at the current {@code readerIndex} and increases
* the {@code readerIndex} by {@code 1} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 1}
*/
boolean readBoolean();
2008-08-10 07:09:55 +02:00
/**
* Gets a byte at the current {@code readerIndex} and increases
* the {@code readerIndex} by {@code 1} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 1}
2008-08-10 07:09:55 +02:00
*/
byte readByte();
2008-08-10 07:09:55 +02:00
/**
* Gets an unsigned byte at the current {@code readerIndex} and increases
2008-08-10 07:09:55 +02:00
* the {@code readerIndex} by {@code 1} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 1}
2008-08-10 07:09:55 +02:00
*/
2008-08-10 02:52:59 +02:00
short readUnsignedByte();
2008-08-10 07:09:55 +02:00
/**
* Gets a 16-bit short integer at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 2} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 2}
2008-08-10 07:09:55 +02:00
*/
short readShort();
2008-08-10 07:09:55 +02:00
/**
* Gets an unsigned 16-bit short integer at the current {@code readerIndex}
2008-08-10 07:09:55 +02:00
* and increases the {@code readerIndex} by {@code 2} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 2}
2008-08-10 07:09:55 +02:00
*/
2008-08-10 02:52:59 +02:00
int readUnsignedShort();
2008-08-10 07:09:55 +02:00
/**
* Gets a 24-bit medium integer at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 3} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 3}
2008-08-10 07:09:55 +02:00
*/
int readMedium();
2008-08-10 07:09:55 +02:00
/**
* Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
2008-08-10 07:09:55 +02:00
* and increases the {@code readerIndex} by {@code 3} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 3}
2008-08-10 07:09:55 +02:00
*/
2008-08-10 02:52:59 +02:00
int readUnsignedMedium();
2008-08-10 07:09:55 +02:00
/**
* Gets a 32-bit integer at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 4}
2008-08-10 07:09:55 +02:00
*/
int readInt();
2008-08-10 07:09:55 +02:00
/**
* Gets an unsigned 32-bit integer at the current {@code readerIndex}
2008-08-10 07:09:55 +02:00
* and increases the {@code readerIndex} by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 4}
2008-08-10 07:09:55 +02:00
*/
2008-08-10 02:52:59 +02:00
long readUnsignedInt();
2008-08-10 07:09:55 +02:00
/**
* Gets a 64-bit integer at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 8} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 8}
2008-08-10 07:09:55 +02:00
*/
long readLong();
/**
* Gets a 2-byte UTF-16 character at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 2} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 2}
*/
char readChar();
/**
* Gets a 32-bit floating point number at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 4}
*/
float readFloat();
/**
* Gets a 64-bit floating point number at the current {@code readerIndex}
* and increases the {@code readerIndex} by {@code 8} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 8}
*/
double readDouble();
2008-08-11 06:08:41 +02:00
/**
* Transfers this buffer's data to a newly created buffer starting at
* the current {@code readerIndex} and increases the {@code readerIndex}
* by the number of the transferred bytes (= {@code length}).
* The returned buffer's {@code readerIndex} and {@code writerIndex} are
* {@code 0} and {@code length} respectively.
*
* @param length the number of bytes to transfer
*
* @return the newly created buffer which contains the transferred bytes
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
ByteBuf readBytes(int length);
2008-08-11 06:08:41 +02:00
/**
* Returns a new slice of this buffer's sub-region starting at the current
* {@code readerIndex} and increases the {@code readerIndex} by the size
* of the new slice (= {@code length}).
*
* @param length the size of the new slice
*
* @return the newly created slice
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
ByteBuf readSlice(int length);
2008-08-11 06:08:41 +02:00
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} until the destination becomes
* non-writable, and increases the {@code readerIndex} by the number of the
2008-08-10 16:25:13 +02:00
* transferred bytes. This method is basically same with
* {@link #readBytes(ByteBuf, int, int)}, except that this method
2008-08-10 16:25:13 +02:00
* increases the {@code writerIndex} of the destination by the number of
* the transferred bytes while {@link #readBytes(ByteBuf, int, int)}
2008-11-14 08:45:53 +01:00
* does not.
2008-08-10 16:25:13 +02:00
*
* @throws IndexOutOfBoundsException
* if {@code dst.writableBytes} is greater than
* {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf readBytes(ByteBuf dst);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} and increases the {@code readerIndex}
* by the number of the transferred bytes (= {@code length}). This method
* is basically same with {@link #readBytes(ByteBuf, int, int)},
2008-08-10 16:25:13 +02:00
* except that this method increases the {@code writerIndex} of the
* destination by the number of the transferred bytes (= {@code length})
* while {@link #readBytes(ByteBuf, int, int)} does not.
2008-08-10 16:25:13 +02:00
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes} or
* if {@code length} is greater than {@code dst.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf readBytes(ByteBuf dst, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} and increases the {@code readerIndex}
* by the number of the transferred bytes (= {@code length}).
*
* @param dstIndex the first index of the destination
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code dstIndex} is less than {@code 0},
* if {@code length} is greater than {@code this.readableBytes}, or
2008-08-10 16:25:13 +02:00
* if {@code dstIndex + length} is greater than
* {@code dst.capacity}
*/
ByteBuf readBytes(ByteBuf dst, int dstIndex, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} and increases the {@code readerIndex}
* by the number of the transferred bytes (= {@code dst.length}).
*
* @throws IndexOutOfBoundsException
* if {@code dst.length} is greater than {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf readBytes(byte[] dst);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} and increases the {@code readerIndex}
* by the number of the transferred bytes (= {@code length}).
*
* @param dstIndex the first index of the destination
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code dstIndex} is less than {@code 0},
* if {@code length} is greater than {@code this.readableBytes}, or
2008-08-10 16:25:13 +02:00
* if {@code dstIndex + length} is greater than {@code dst.length}
*/
ByteBuf readBytes(byte[] dst, int dstIndex, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified destination starting at
* the current {@code readerIndex} until the destination's position
* reaches its limit, and increases the {@code readerIndex} by the
2008-08-10 16:25:13 +02:00
* number of the transferred bytes.
*
* @throws IndexOutOfBoundsException
* if {@code dst.remaining()} is greater than
* {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf readBytes(ByteBuffer dst);
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified stream starting at the
* current {@code readerIndex}.
*
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
* @throws IOException
* if the specified stream threw an exception during I/O
*/
ByteBuf readBytes(OutputStream out, int length) throws IOException;
2008-08-10 16:25:13 +02:00
/**
* Transfers this buffer's data to the specified stream starting at the
* current {@code readerIndex}.
*
* @param length the maximum number of bytes to transfer
*
* @return the actual number of bytes written out to the specified channel
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
* @throws IOException
* if the specified channel threw an exception during I/O
*/
int readBytes(GatheringByteChannel out, int length) throws IOException;
2008-08-10 16:25:13 +02:00
/**
* Increases the current {@code readerIndex} by the specified
* {@code length} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf skipBytes(int length);
2008-08-10 16:25:13 +02:00
/**
* Sets the specified boolean at the current {@code writerIndex}
* and increases the {@code writerIndex} by {@code 1} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 1}
*/
ByteBuf writeBoolean(boolean value);
2012-05-31 21:03:01 +02:00
2008-08-10 16:25:13 +02:00
/**
* Sets the specified byte at the current {@code writerIndex}
* and increases the {@code writerIndex} by {@code 1} in this buffer.
* The 24 high-order bits of the specified value are ignored.
2008-08-10 16:25:13 +02:00
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 1}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeByte(int value);
2008-08-10 16:25:13 +02:00
/**
* Sets the specified 16-bit short integer at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
* in this buffer. The 16 high-order bits of the specified value are ignored.
2008-08-10 16:25:13 +02:00
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 2}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeShort(int value);
2008-08-10 16:25:13 +02:00
/**
* Sets the specified 24-bit medium integer at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 3}
* in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 3}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeMedium(int value);
2008-08-10 16:25:13 +02:00
/**
* Sets the specified 32-bit integer at the current {@code writerIndex}
* and increases the {@code writerIndex} by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 4}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeInt(int value);
2008-08-10 16:25:13 +02:00
/**
* Sets the specified 64-bit long integer at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
* in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 8}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeLong(long value);
/**
* Sets the specified 2-byte UTF-16 character at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
* in this buffer. The 16 high-order bits of the specified value are ignored.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 2}
*/
ByteBuf writeChar(int value);
/**
* Sets the specified 32-bit floating point number at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 4}
* in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 4}
*/
ByteBuf writeFloat(float value);
/**
* Sets the specified 64-bit floating point number at the current
* {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
* in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 8}
*/
ByteBuf writeDouble(double value);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the current {@code writerIndex} until the source buffer becomes
* unreadable, and increases the {@code writerIndex} by the number of
* the transferred bytes. This method is basically same with
* {@link #writeBytes(ByteBuf, int, int)}, except that this method
2008-08-10 16:25:13 +02:00
* increases the {@code readerIndex} of the source buffer by the number of
* the transferred bytes while {@link #writeBytes(ByteBuf, int, int)}
2008-11-14 08:45:53 +01:00
* does not.
2008-08-10 16:25:13 +02:00
*
* @throws IndexOutOfBoundsException
* if {@code src.readableBytes} is greater than
* {@code this.writableBytes}
*/
ByteBuf writeBytes(ByteBuf src);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the current {@code writerIndex} and increases the {@code writerIndex}
* by the number of the transferred bytes (= {@code length}). This method
* is basically same with {@link #writeBytes(ByteBuf, int, int)},
2008-08-10 16:25:13 +02:00
* except that this method increases the {@code readerIndex} of the source
* buffer by the number of the transferred bytes (= {@code length}) while
* {@link #writeBytes(ByteBuf, int, int)} does not.
2008-08-10 16:25:13 +02:00
*
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.writableBytes} or
* if {@code length} is greater then {@code src.readableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeBytes(ByteBuf src, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the current {@code writerIndex} and increases the {@code writerIndex}
* by the number of the transferred bytes (= {@code length}).
*
* @param srcIndex the first index of the source
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code srcIndex} is less than {@code 0},
* if {@code srcIndex + length} is greater than
* {@code src.capacity}, or
* if {@code length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeBytes(ByteBuf src, int srcIndex, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source array's data to this buffer starting at
* the current {@code writerIndex} and increases the {@code writerIndex}
* by the number of the transferred bytes (= {@code src.length}).
*
* @throws IndexOutOfBoundsException
* if {@code src.length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeBytes(byte[] src);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source array's data to this buffer starting at
* the current {@code writerIndex} and increases the {@code writerIndex}
* by the number of the transferred bytes (= {@code length}).
*
* @param srcIndex the first index of the source
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code srcIndex} is less than {@code 0},
* if {@code srcIndex + length} is greater than
* {@code src.length}, or
* if {@code length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeBytes(byte[] src, int srcIndex, int length);
2008-08-10 16:25:13 +02:00
/**
* Transfers the specified source buffer's data to this buffer starting at
* the current {@code writerIndex} until the source buffer's position
* reaches its limit, and increases the {@code writerIndex} by the
2008-08-10 16:25:13 +02:00
* number of the transferred bytes.
*
* @throws IndexOutOfBoundsException
* if {@code src.remaining()} is greater than
* {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeBytes(ByteBuffer src);
2008-08-10 16:25:13 +02:00
/**
* Transfers the content of the specified stream to this buffer
* starting at the current {@code writerIndex} and increases the
* {@code writerIndex} by the number of the transferred bytes.
*
* @param length the number of bytes to transfer
*
* @return the actual number of bytes read in from the specified stream
*
2008-08-10 16:25:13 +02:00
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
* @throws IOException
* if the specified stream threw an exception during I/O
*/
int writeBytes(InputStream in, int length) throws IOException;
2008-08-10 16:25:13 +02:00
/**
* Transfers the content of the specified channel to this buffer
* starting at the current {@code writerIndex} and increases the
* {@code writerIndex} by the number of the transferred bytes.
*
* @param length the maximum number of bytes to transfer
*
* @return the actual number of bytes read in from the specified channel
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
* @throws IOException
* if the specified channel threw an exception during I/O
*/
int writeBytes(ScatteringByteChannel in, int length) throws IOException;
2008-08-10 16:25:13 +02:00
/**
* Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
* {@code writerIndex} and increases the {@code writerIndex} by the
* specified {@code length}.
*
* @param length the number of <tt>NUL</tt>s to write to the buffer
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.writableBytes}
2008-08-10 16:25:13 +02:00
*/
ByteBuf writeZero(int length);
2008-08-11 06:08:41 +02:00
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search takes place from the specified {@code fromIndex}
* (inclusive) to the specified {@code toIndex} (exclusive).
* <p>
* If {@code fromIndex} is greater than {@code toIndex}, the search is
* performed in a reversed order.
2009-04-24 15:56:35 +02:00
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-11 06:08:41 +02:00
*
* @return the absolute index of the first occurrence if found.
* {@code -1} otherwise.
*/
int indexOf(int fromIndex, int toIndex, byte value);
2008-08-11 06:08:41 +02:00
/**
* @deprecated Use {@link #forEachByte(int, int, ByteBufProcessor)} instead.
*
* Locates the first place where the specified {@code indexFinder}
2008-08-11 06:08:41 +02:00
* returns {@code true}. The search takes place from the specified
* {@code fromIndex} (inclusive) to the specified {@code toIndex}
* (exclusive).
* <p>
* If {@code fromIndex} is greater than {@code toIndex}, the search is
* performed in a reversed order.
2009-04-24 15:56:35 +02:00
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-11 06:08:41 +02:00
*
* @return the absolute index where the specified {@code indexFinder}
* returned {@code true}. {@code -1} if the {@code indexFinder}
* did not return {@code true} at all.
2008-08-11 06:08:41 +02:00
*/
@Deprecated
int indexOf(int fromIndex, int toIndex, ByteBufIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search takes place from the current {@code readerIndex}
* (inclusive) to the current {@code writerIndex} (exclusive).
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first occurrence if found. {@code -1} otherwise.
*/
int bytesBefore(byte value);
/**
* @deprecated Use {@link #forEachByte(ByteBufProcessor)} instead.
*
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search takes place from the current {@code readerIndex}
* (inclusive) to the current {@code writerIndex}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*/
@Deprecated
int bytesBefore(ByteBufIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search starts from the current {@code readerIndex}
* (inclusive) and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first occurrence if found. {@code -1} otherwise.
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
int bytesBefore(int length, byte value);
/**
* @deprecated Use {@link #forEachByte(int, int, ByteBufProcessor)} instead.
*
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search starts the current {@code readerIndex}
* (inclusive) and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
@Deprecated
int bytesBefore(int length, ByteBufIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search starts from the specified {@code index} (inclusive)
* and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the specified {@code index}
* and the first occurrence if found. {@code -1} otherwise.
*
* @throws IndexOutOfBoundsException
* if {@code index + length} is greater than {@code this.capacity}
*/
int bytesBefore(int index, int length, byte value);
/**
* @deprecated Use {@link #forEachByte(int, int, ByteBufProcessor)} instead.
*
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search starts the specified {@code index} (inclusive)
* and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the specified {@code index}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*
* @throws IndexOutOfBoundsException
* if {@code index + length} is greater than {@code this.capacity}
*/
@Deprecated
int bytesBefore(int index, int length, ByteBufIndexFinder indexFinder);
/**
* Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order.
*
* @return {@code -1} if the processor iterated to or beyond the end of the readable bytes.
* If the {@code processor} raised {@link ByteBufProcessor#ABORT}, the last-visited index will be returned.
*/
int forEachByte(ByteBufProcessor processor);
/**
* Iterates over the specified area of this buffer with the specified {@code processor} in ascending order.
* (i.e. {@code index}, {@code (index + 1)}, .. {@code (index + length - 1)})
*
* @return {@code -1} if the processor iterated to or beyond the end of the specified area.
* If the {@code processor} raised {@link ByteBufProcessor#ABORT}, the last-visited index will be returned.
*/
int forEachByte(int index, int length, ByteBufProcessor processor);
/**
* Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order.
*
* @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes.
* If the {@code processor} raised {@link ByteBufProcessor#ABORT}, the last-visited index will be returned.
*/
int forEachByteDesc(ByteBufProcessor processor);
/**
* Iterates over the specified area of this buffer with the specified {@code processor} in descending order.
* (i.e. {@code (index + length - 1)}, {@code (index + length - 2)}, ... {@code index})
*
* @return {@code -1} if the processor iterated to or beyond the beginning of the specified area.
* If the {@code processor} raised {@link ByteBufProcessor#ABORT}, the last-visited index will be returned.
*/
int forEachByteDesc(int index, int length, ByteBufProcessor processor);
2008-08-10 16:25:13 +02:00
/**
* Returns a copy of this buffer's readable bytes. Modifying the content
2008-11-14 08:45:53 +01:00
* of the returned buffer or this buffer does not affect each other at all.
2008-08-10 16:25:13 +02:00
* This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*/
ByteBuf copy();
2008-08-10 16:25:13 +02:00
/**
* Returns a copy of this buffer's sub-region. Modifying the content of
2008-11-14 08:45:53 +01:00
* the returned buffer or this buffer does not affect each other at all.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 16:25:13 +02:00
*/
ByteBuf copy(int index, int length);
2008-08-10 16:25:13 +02:00
/**
* Returns a slice of this buffer's readable bytes. Modifying the content
* of the returned buffer or this buffer affects each other's content
* while they maintain separate indexes and marks. This method is
* identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 16:25:13 +02:00
*/
ByteBuf slice();
2008-08-10 16:25:13 +02:00
/**
* Returns a slice of this buffer's sub-region. Modifying the content of
* the returned buffer or this buffer affects each other's content while
* they maintain separate indexes and marks.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 16:25:13 +02:00
*/
ByteBuf slice(int index, int length);
2008-08-10 16:25:13 +02:00
/**
* Returns a buffer which shares the whole region of this buffer.
* Modifying the content of the returned buffer or this buffer affects
* each other's content while they maintain separate indexes and marks.
* This method is identical to {@code buf.slice(0, buf.capacity())}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 16:25:13 +02:00
*/
ByteBuf duplicate();
2008-08-10 16:25:13 +02:00
/**
* Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer. Note that {@link #nioBuffers()}
* or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
*
* @return {@code -1} if this buffer has no underlying {@link ByteBuffer}.
* the number of the underlying {@link ByteBuffer}s if this buffer has at least one undelying
* {@link ByteBuffer}. Note that this method does not return {@code 0} to avoid confusion.
*
* @see #nioBuffer()
* @see #nioBuffer(int, int)
* @see #nioBuffers()
* @see #nioBuffers(int, int)
2008-08-10 16:25:13 +02:00
*/
int nioBufferCount();
2008-08-10 16:25:13 +02:00
/**
* Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method is identical
* to {@code buf.nioBuffer(buf.readerIndex(), buf.readableBytes())}. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
2008-08-10 16:25:13 +02:00
*/
ByteBuffer nioBuffer();
2008-08-10 16:25:13 +02:00
/**
* Exposes this buffer's sub-region as an NIO {@link ByteBuffer}. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
2008-08-10 16:25:13 +02:00
*/
ByteBuffer nioBuffer(int index, int length);
/**
* Internal use only: Exposes the internal NIO buffer.
*/
ByteBuffer internalNioBuffer(int index, int length);
/**
* Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}'s. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
ByteBuffer[] nioBuffers();
/**
* Exposes this buffer's bytes as an NIO {@link ByteBuffer}'s for the specified index and length
* The returned buffer shares the content with this buffer, while changing the position and limit
* of the returned NIO buffer does not affect the indexes and marks of this buffer. This method does
* not modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
ByteBuffer[] nioBuffers(int index, int length);
/**
* Returns {@code true} if and only if this buffer has a backing byte array.
* If this method returns true, you can safely call {@link #array()} and
* {@link #arrayOffset()}.
*/
boolean hasArray();
/**
* Returns the backing byte array of this buffer.
*
* @throws UnsupportedOperationException
* if there no accessible backing byte array
*/
byte[] array();
/**
* Returns the offset of the first byte within the backing byte array of
* this buffer.
*
* @throws UnsupportedOperationException
* if there no accessible backing byte array
*/
int arrayOffset();
/**
* Returns {@code true} if and only if this buffer has a reference to the low-level memory address that points
* to the backing data.
*/
boolean hasMemoryAddress();
/**
* Returns the low-level memory address that point to the first byte of ths backing data.
*
* @throws UnsupportedOperationException
* if this buffer does not support accessing the low-level memory address
*/
long memoryAddress();
2008-08-10 16:25:13 +02:00
/**
* Decodes this buffer's readable bytes into a string with the specified
* character set name. This method is identical to
* {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}.
2009-04-24 15:56:35 +02:00
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
2008-08-10 16:25:13 +02:00
*
* @throws UnsupportedCharsetException
* if the specified character set name is not supported by the
* current VM
*/
String toString(Charset charset);
/**
* Decodes this buffer's sub-region into a string with the specified
* character set. This method does not modify {@code readerIndex} or
* {@code writerIndex} of this buffer.
*/
String toString(int index, int length, Charset charset);
/**
* Returns a hash code which was calculated from the content of this
* buffer. If there's a byte array which is
* {@linkplain #equals(Object) equal to} this array, both arrays should
* return the same value.
*/
@Override
int hashCode();
/**
* Determines if the content of the specified buffer is identical to the
* content of this array. 'Identical' here means:
* <ul>
* <li>the size of the contents of the two buffers are same and</li>
* <li>every single byte of the content of the two buffers are same.</li>
* </ul>
2008-11-14 08:45:53 +01:00
* Please note that it does not compare {@link #readerIndex()} nor
* {@link #writerIndex()}. This method also returns {@code false} for
* {@code null} and an object which is not an instance of
* {@link ByteBuf} type.
*/
@Override
boolean equals(Object obj);
/**
* Compares the content of the specified buffer to the content of this
* buffer. Comparison is performed in the same manner with the string
* comparison functions of various languages such as {@code strcmp},
* {@code memcmp} and {@link String#compareTo(String)}.
*/
@Override
int compareTo(ByteBuf buffer);
/**
2008-11-14 08:45:53 +01:00
* Returns the string representation of this buffer. This method does not
* necessarily return the whole content of the buffer but returns
* the values of the key properties such as {@link #readerIndex()},
2008-08-10 17:43:04 +02:00
* {@link #writerIndex()} and {@link #capacity()}.
*/
@Override
String toString();
@Override
ByteBuf retain(int increment);
@Override
ByteBuf retain();
}