netty 字节buf定义

netty 通道接口定义:[url]http://donald-draper.iteye.com/blog/2392740[/url]
netty 抽象通道初始化:[url]http://donald-draper.iteye.com/blog/2392801[/url]
netty 抽象Unsafe定义:[url]http://donald-draper.iteye.com/blog/2393053[/url]
netty 通道Outbound缓冲区:[url]http://donald-draper.iteye.com/blog/2393098[/url]
netty 抽象通道后续:[url]http://donald-draper.iteye.com/blog/2393166[/url]
netty 抽象nio通道:[url]http://donald-draper.iteye.com/blog/2393269[/url]
netty 抽象nio字节通道:[url]http://donald-draper.iteye.com/blog/2393323[/url]
netty 抽象nio消息通道:[url]http://donald-draper.iteye.com/blog/2393364[/url]
netty NioServerSocketChannel解析:[url]http://donald-draper.iteye.com/blog/2393443[/url]
netty 通道配置接口定义:[url]http://donald-draper.iteye.com/blog/2393484[/url]
netty 默认通道配置初始化:[url]http://donald-draper.iteye.com/blog/2393504[/url]
netty 默认通道配置后续:[url]http://donald-draper.iteye.com/blog/2393510[/url]
[size=medium][b]引言[/b][/size]
前面两篇文章我们看了通道配置,先来简单回顾一下:
默认通道配置内部主要是配置消息大小估算器,字节buf分配器,接收字节buf分配器等属性。默认ServerSocket通道配置,与ServerSocket相关的配置委托给ServerSocket的相关方法,其他委托给父类默认通道配置。默认Socket通道配置,与Socket相关的配置委托给Socket的相关方法,其他委托给父类默认通道配置。

在上面的两篇文章中,我们有说过字节buf分配器,字节buf分配器可以创建direct和heap类型的ByteBuf,接下来的文章先看一下
字节buf接口的定义,再看字节buf分配器非配的direct和heap类型的字节buf实现。先从字节buf接口定义:
public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {


再看字节buf接口定义前,来看一下引用计数器接口的定义:
package io.netty.util;

/**
* A reference-counted object that requires explicit deallocation.
*
* When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}.
* {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count.
* If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing
* the deallocated object will usually result in an access violation.
*

*
* If an object that implements {@link ReferenceCounted} is a container of other objects that implement
* {@link ReferenceCounted}, the contained objects will also be released via {@link #release()} when the container's
* reference count becomes 0.
*

*/
public interface ReferenceCounted {
/**
* Returns the reference count of this object. If {@code 0}, it means this object has been deallocated.
返回对象的引用计数器,为0,表示对象可以被回收
*/
int refCnt();

/**
* Increases the reference count by {@code 1}.
对象引用计数器自增1
*/
ReferenceCounted retain();

/**
* Increases the reference count by the specified {@code increment}.
增加引用计数器,增量为increment
*/
ReferenceCounted retain(int increment);

/**
* Records the current access location of this object for debugging purposes.
* If this object is determined to be leaked, the information recorded by this operation will be provided to you
* via {@link ResourceLeakDetector}. This method is a shortcut to {@link #touch(Object) touch(null)}.
调试时,记录当前对象访问的位置。如果对象确定内存泄漏,可以通过ResourceLeakDetector获取操作的相关信息。
此方法为 #touch(Object) touch(null)的快捷方式
*/
ReferenceCounted touch();

/**
* Records the current access location of this object with an additional arbitrary information for debugging
* purposes. If this object is determined to be leaked, the information recorded by this operation will be
* provided to you via {@link ResourceLeakDetector}.
调试时,记录当前对象访问的位置。如果对象确定内存泄漏,可以通过ResourceLeakDetector获取操作的相关信息。
*/
ReferenceCounted touch(Object hint);

/**
* Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at
* {@code 0}.
*自减对象引用计数器,如果引用数为0,则回收对象。当且仅当对象引用计数器为0,回收对象,返回true
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
*/
boolean release();

/**
* Decreases the reference count by the specified {@code decrement} and deallocates this object if the reference
* count reaches at {@code 0}.
*减对象引用计数器,减量为decrement,如果引用数为0,则回收对象。当且仅当对象引用计数器为0,回收对象,返回true
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
*/
boolean release(int decrement);
}


从上面可以看出,对象引用计数器ReferenceCounted,主要记录对象的引用数量,当引用数量为0时,表示可以回收对象,在调试模式下,如果发现对象出现内存泄漏,可以用touch方法记录操作的相关信息,通过ResourceLeakDetector获取操作的相关信息,以便分析内存泄漏的原因。

再来看字节buf的接口定义:
package io.netty.buffer;

import io.netty.util.ByteProcessor;
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.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;

/**
* 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}.
*字节缓冲ByteBuf是一个可随机方法字节序列,字节数可以为0或更多。
这个方法提供了一个或更多原始字节数组和java nio ByteBuffer的抽象视图。
* <h3>Creation of a buffer</h3>
*创建buf
* It is recommended to create a new buffer using the helper methods in
* {@link Unpooled} rather than calling an individual implementation's
* constructor.
*强烈建议使用Unpooled的辅助方法创建一个字节buf,而不是调用buf具体实现的构造方法。
* <h3>Random Access Indexing</h3>
*随机访问索引
* Just like an ordinary primitive byte array, {@link ByteBuf} uses
* [url=http://en.wikipedia.org/wiki/Zero-based_numbering]zero-based indexing[/url].
* 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:
*如一般的字节数组一样,字节buf索引也是从0开始。意味着第一个字节的索引总是为0,最后一个字节的
索引总是为#capacity() capacity - 1。比如,遍历buf中的所有字节,忽略具体实现的情况下,
可以按如下code
* <pre>
* {@link ByteBuf} buffer = ...;
* for (int i = 0; i < 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:
*字节buf提供了两个索引支持顺序读写操作,#readerIndex返回读操作使用的读索引readerIndex,
#writerIndex返回写操作使用的写索引writerIndex。下图展示读写索引如何将buf分为三段。
* <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 #writerIndex() writerIndex} is increased together.
这段内容为实际存储的数据。任何以read和skip开头的操作方法,将会从当前的读索引开始,
并增加读索引,增量为读取的字节数。如果读操作的参数为字节buf,并且没有目的索引,
那么目的buf写索引也会增加。
* <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}.
*如果没有足够的内容,将会抛出IndexOutOfBoundsException异常。默认新分配,
copy,包装的字节buf的读索引为0。
* <pre>
* // Iterates the readable bytes of a buffer.
* {@link ByteBuf} buffer = ...;
* while (buffer.isReadable()) {
* 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 starts 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.
此段是需要填充的无定义空间。任何以write开头的操作方法,将会从当前的写索引开始写字节数据,
并增加写索引,增量为写的字节数。如果写操作的参数为字节buf,并且没有源索引,则源buf的读索引
将会增加
* <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.
*
如果没有足够的可写字节,将抛出IndexOutOfBoundsException异常。默认新分配的buf的写索引为0。
copy,包装的字节buf的写索引为#capacity() capacity
* <pre>
* // Fills the writable bytes of a buffer with random integers.
写随机整数到buf
* {@link ByteBuf} buffer = ...;
* 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:
*这段包含了读操作已经读取的字节。初始情况下,这段长度为0,但是这段的长度随着
读操作的执行,增加至写索引。这段数据可以调用#discardReadBytes方法丢弃,
并重新收回没用的区域,具体描述如下图:
* <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.
*需要注意的是,在丢弃已经读取的字节时,并不能保证可写字节的内容。可写字节在大多数情况下不会
移动,甚至可能填充不同的数据,这个依赖于具体的buf实现。
* <h4>Clearing the buffer indexes</h4>
*清除buf索引
* You can set both {@link #readerIndex() readerIndex} and
* {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}.
* 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()}.
*我们可以调用#clear方法,设置读写索引为0。clear方法不会清除buf中的数据,仅仅调整
读写索引。需要注意的是此方法不同于java nio 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, ByteProcessor)} with a {@link ByteProcessor}
* implementation.
对于简单的单个字节搜索,可是使用#indexOf和#bytesBefore方法。当需要处理一个空字节NUL(0x00)时,
#bytesBefore方法特别有用。 比如一些复杂的搜索,可以使用字节处理器ByteProcessor版的#forEachByte方法。
*
* <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}.
*在每个buf中有两个标记索引,一个是存储读索引的,一个是存储写索引的。你可以
调用reset方法,重置读、写索引到标记的位置。除了没有readlimit之外,与输入流中标记和重置方法
相似。
* <h3>Derived buffers</h3>
*衍生buf
* You can create a view of an existing buffer by calling one of the following methods:
你可通过如下方法,创建buf的视图:
* [list]
* [*]{@link #duplicate()}

* [*]{@link #slice()}

* [*]{@link #slice(int, int)}

* [*]{@link #readSlice(int)}

* [*]{@link #retainedDuplicate()}

* [*]{@link #retainedSlice()}

* [*]{@link #retainedSlice(int, int)}

* [*]{@link #readRetainedSlice(int)}

* [/list]
* 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.
衍生buf,拥有自己独立的读写索引的标记索引,共享其他内部数据,就像java nio ByteBuffer
* <p>
* In case a completely fresh copy of an existing buffer is required, please
* call {@link #copy()} method instead.
*假如需要当前buf的完全拷贝,可以使用copy方法。
* <h4>Non-retained and retained derived buffers</h4>
*非retained和retained衍生buf
* Note that the {@link #duplicate()}, {@link #slice()}, {@link #slice(int, int)} and {@link #readSlice(int)} does NOT
* call {@link #retain()} on the returned derived buffer, and thus its reference count will NOT be increased. If you
* need to create a derived buffer with increased reference count, consider using {@link #retainedDuplicate()},
* {@link #retainedSlice()}, {@link #retainedSlice(int, int)} and {@link #readRetainedSlice(int)} which may return
* a buffer implementation that produces less garbage.
*注意#duplicate,#slice,#slice,#readSlice方法不会在衍生buf中调用#retain方法,这样buf的引用计数器将不会增加。
如果需要创建衍生buf,需要增加引用计数器,可以考虑上述方法的#retained*版本方法,这样可能会产生一点内存垃圾。
* <h3>Conversion to existing JDK types</h3>
*转换ByteBuf为JDK 类型
* <h4>Byte array</h4>
*字节数组
* If a {@link ByteBuf} is backed by a byte array (i.e. {@code byte[]}),
* 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.
*如果字节是一个字节数组,你可以直接使用#array访问。判断一个方法是否为字节数组,可以
使用#hasArray方法
* <h4>NIO Buffers</h4>
*nio ByteBuffer
* 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
* if a buffer can be converted into an NIO buffer, use {@link #nioBufferCount()}.
*如果字节buf可以转换为java nio ByteBuffer,你可以调用#nioBuffer方法共享buf内容。
你可以使用#nioBufferCount来判断字节buf可不可以转换为java nio ByteBuffer
* <h4>Strings</h4>
*字符串
* Various {@link #toString(Charset)} methods convert a {@link ByteBuf}
* into a {@link String}. Please note that {@link #toString()} is not a
* conversion method.
*#toString(Charset)方法转换字节buf为字符串,注意#toString不是一个转换方法
* <h4>I/O Streams</h4>
*IO流
* Please refer to {@link ByteBufInputStream} and
* {@link ByteBufOutputStream}.
参考ByteBufInputStream和ByteBufOutputStream
*/
@SuppressWarnings("ClassMayBeInterface")
public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {

/**
* Returns the number of bytes (octets) this buffer can contain.
获取buf容量
*/
public abstract 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)}.
调整buf的容量,如果容量小于原始buf容量,则truncated buf的内容,如果新增量大于原始容量,
则buffer将会添加不确定的数,其长度为newCapacity - currentCapacity
*/
public abstract 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}.
返回buf的最大允许容量。如果用户尝试用 #capacity(int)和 #ensureWritable(int)方法,
增加buf容量超过最大容量,将会抛出非法参数异常
*/
public abstract int maxCapacity();

/**
* Returns the {@link ByteBufAllocator} which created this buffer.
返回创建buf的字节buf分配器
*/
public abstract ByteBufAllocator alloc();

/**
* Returns the [url=http://en.wikipedia.org/wiki/Endianness]endianness[/url]
* of this buffer.
*已丢弃
* @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
* instead of creating a buffer with swapped {@code endianness}.
*/
@Deprecated
public abstract 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.
*已丢弃
* @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
* instead of creating a buffer with swapped {@code endianness}.
*/
@Deprecated
public abstract ByteBuf order(ByteOrder endianness);

/**
* Return the underlying buffer instance if this buffer is a wrapper of another buffer.
*如果buf为另一个buf包装类,返回底层buf实例,即返回未包装的buf
* @return {@code null} if this buffer is not a wrapper
*/
public abstract ByteBuf unwrap();

/**
* Returns {@code true} if and only if this buffer is backed by an
* NIO direct buffer.
判断buf是否是direct类型
*/
public abstract boolean isDirect();

/**
* Returns {@code true} if and only if this buffer is read-only.
判断buf是否可读
*/
public abstract boolean isReadOnly();

/**
* Returns a read-only version of this buffer.
返回buf的只读版本
*/
public abstract ByteBuf asReadOnly();

/**
* Returns the {@code readerIndex} of this buffer.
获取buf的读索引
*/
public abstract int readerIndex();

/**
* Sets the {@code readerIndex} of this buffer.
*设置buf的读索引
* @throws IndexOutOfBoundsException
* if the specified {@code readerIndex} is
* less than {@code 0} or
* greater than {@code this.writerIndex}
*/
public abstract ByteBuf readerIndex(int readerIndex);

/**
* Returns the {@code writerIndex} of this buffer.
获取buf的写索引
*/
public abstract int writerIndex();

/**
* Sets the {@code writerIndex} of this buffer.
*设置buf的写索引
* @throws IndexOutOfBoundsException
* if the specified {@code writerIndex} is
* less than {@code this.readerIndex} or
* greater than {@code this.capacity}
*/
public abstract ByteBuf writerIndex(int writerIndex);

/**
* Sets the {@code readerIndex} and {@code writerIndex} of this buffer
* 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:
*设置buf读写索引的快捷方式。当你不得不关心读索引设置和写索引设置的顺序时,这个方法,非常有用。
以下代码将会失败:
* <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:
*相比之下,setIndex方法可以保证只要索引满足基本的约束,无论当前buf索引的值是什么,
索引越界异常不会抛出.
* <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的容量大于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
* greater than {@code this.capacity}
*/
public abstract ByteBuf setIndex(int readerIndex, int writerIndex);

/**
* Returns the number of readable bytes which is equal to
获取buf可读字节数为writerIndex - readerIndex
* {@code (this.writerIndex - this.readerIndex)}.
*/
public abstract int readableBytes();

/**
* Returns the number of writable bytes which is equal to
获取buf可写字节数为capacity - writerIndex
* {@code (this.capacity - this.writerIndex)}.
*/
public abstract int writableBytes();

/**
* Returns the maximum possible number of writable bytes, which is equal to
* {@code (this.maxCapacity - this.writerIndex)}.
当前buf可写的最大字节数为maxCapacity - writerIndex
*/
public abstract int maxWritableBytes();

/**
* Returns {@code true}
* if and only if {@code (this.writerIndex - this.readerIndex)} is greater
* than {@code 0}.
获取buf是否可读,如果当前可读字节数大于0,表示可读,返回true
*/
public abstract boolean isReadable();

/**
* Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements.
buf的可读字节数据是否大于size
*/
public abstract boolean isReadable(int size);

/**
* Returns {@code true}
* if and only if {@code (this.capacity - this.writerIndex)} is greater
* than {@code 0}.
buf是否可写,即this.capacity - this.writerIndex是否大于0
*/
public abstract boolean isWritable();

/**
* Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of
* elements.
判断当前buf是否可容下size字节
*/
public abstract boolean isWritable(int size);

/**
* Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
* {@code 0}.
重置buf的读写索引为0,等同于setIndex(0, 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
* the {@code capacity} of the buffer.
主要此方法,不同于Java nio buffer,设置buf的limit的位置为capacity
*/
public abstract ByteBuf clear();

/**
* 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}.
标记当前buf的读索引。我们可以调用#resetReaderIndex方法,重回标记的读索引位置。
初始标记位置为0。
*/
public abstract ByteBuf markReaderIndex();

/**
* 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}
*/
public abstract ByteBuf resetReaderIndex();

/**
* 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}.
标记当前buf的写索引。我们可以调用#resetWriterIndex方法,重回标记的写索引位置。
初始标记位置为0。
*/
public abstract ByteBuf markWriterIndex();

/**
* 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}
*/
public abstract 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.
丢弃0索引到当前读索引的数据。并移到读索引到写索引之间的数据,到0索引位置上,
重置读索引为0,写索引为oldWriterIndex - oldReaderIndex
* <p>
* Please refer to the class documentation for more detailed explanation.
更详细的扩展,请参考具体的class文档
*/
public abstract 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#discardReadBytes方法相似,此方可能会在内存出现负载时,丢弃一些或所有,
或不丢弃可读字节数据,具体依赖具体的实现,以减少内存的使用量。
*/
public abstract 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}.
确保当前buf可以容下minWritableBytes个字节数据,如果buf足够写,则方法返回没有任何影响,
否则抛出非法参数异常
*
* @param minWritableBytes
* the expected minimum number of writable bytes
* @throws IndexOutOfBoundsException
* if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
*/
public abstract 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.
*尝试确保buf可以写minWritableBytes字节数据。与#ensureWritable(int)方法不同的时,不会抛出异常
* @param minWritableBytes
* the expected minimum number of writable bytes
* @param force
* When {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}:
* [list]
* [*]{@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}

* [*]{@code false} - the capacity of the buffer is unchanged

当force为true,空间不足时,扩展buf容量为最大容量;
false表示,空间不足时,容量没有任何改变
* [/list]
* @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.
返回代码0,表示buf可以容下minWritableBytes个字节数据;
1表示,没有足够的空间可写,容量没有变化;
2表示,buf可以容下minWritableBytes个字节数据,容量扩展;
3表示,buf空间不够,容量扩展至最大值。
*/
public abstract int ensureWritable(int minWritableBytes, boolean force);



/**
* Gets a byte 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}
*/
public abstract byte getByte(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
* method increases the {@code writerIndex} of the destination by the
* number of the transferred bytes while
* {@link #getBytes(int, ByteBuf, int, int)} does not.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*从当前buf的index绝对索引开始,转移当前buf的数据到dst buf中。此方法与#getBytes(int, ByteBuf, int, int)方法相似,
不同的时,此方法将会改变dst buf的写索引,而#getBytes(int, ByteBuf, int, int)不会。此方法不会改变当前buf的
读写索引。
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + dst.writableBytes} is greater than
* {@code this.capacity}
*/
public abstract 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*与上面方法不同的是,转移的数据的长度为length
* @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}
*/
public abstract ByteBuf getBytes(int index, ByteBuf dst, int length);

/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of both the source (i.e. {@code this}) and the destination.
*从当前buf的绝对索引index开始,转移length长度的数据到dst buf中,dstIndex绝对索引开始,
此方法不会修改源buf和目的buf的读写索引位置。
* @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},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code dstIndex + length} is greater than
* {@code dst.capacity}
*/
public abstract 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}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer
*从当前buf的绝对index开始,转移数据到,目的dst 字节数据中,此方法不会修改当前buf的读写索引。
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + dst.length} is greater than
* {@code this.capacity}
*/
public abstract ByteBuf getBytes(int index, byte[] dst);

/**
* Transfers this buffer's data to the specified destination starting at
* the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of this buffer.
*与上面方法是,转移的字节长度为length,从目的字节数组的dstIndex索引开始
* @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},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code dstIndex + length} is greater than
* {@code dst.length}
*/
public abstract 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer while the destination's {@code position} will be increased.
*从当前buf的绝对索引index开始,转移数据到目的nio buf中,直至到达目的nio buf的limit的位置
,此方法不会修改当前buf的读写索引,会修改nio buf的位置索引position
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + dst.remaining()} is greater than
* {@code this.capacity}
*/
public abstract ByteBuf getBytes(int index, ByteBuffer dst);

/**
* Transfers this buffer's data to the specified stream starting at the
* specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*从当前buf的绝对索引index开始,转移数据到目的OutputStream中,直至到达目的nio buf的limit的位置
,此方法不会修改当前buf的读写索引
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + length} is greater than
* {@code this.capacity}
* @throws IOException
* if the specified stream threw an exception during I/O
*/
public abstract 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}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*从当前buf的绝对索引index开始,转移数据到目的聚集字节通道GatheringByteChannel中,
,此方法不会修改当前buf的读写索引
* @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
* if {@code index + length} is greater than
* {@code this.capacity}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int getBytes(int index, GatheringByteChannel out, int length) throws IOException;

/**
* Transfers this buffer's data starting at the specified absolute {@code index}
* to the specified channel starting at the given file position.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer. This method does not modify the channel's position.
*从当前buf的绝对索引index开始,转移数据到目的文件域FileChannel中,
此方法不会修改当前buf的读写索引,同时不会修改文件域的位置索引position
* @param position the file position at which the transfer is to begin
* @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
* if {@code index + length} is greater than
* {@code this.capacity}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int getBytes(int index, FileChannel out, long position, int length) throws IOException;

/**
* Gets a {@link CharSequence} with the given length at the given index.
*从buf的index索引开始,获取给定长度字符序列
* @param length the length to read
* @param charset that should be used
* @return the sequence
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
public abstract CharSequence getCharSequence(int index, int length, Charset charset);


/**
* Sets the specified byte at the specified absolute {@code index} in this
* buffer. The 24 high-order bits of the specified value are ignored.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*从buf的索引index开始,设置特殊的字节,一些特殊值的高24位将会被忽略,不会修改buf的读写索引
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 1} is greater than {@code this.capacity}
*/
public abstract ByteBuf setByte(int index, int value);


/**
* Transfers the specified source buffer's data to this buffer starting at
* the specified absolute {@code index} until the source buffer becomes
* 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
* the number of the transferred bytes while
* {@link #setBytes(int, ByteBuf, int, int)} does not.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*从源buf转移数据到当前buf的绝对索引index上,直到源buf不可读。此方法与setBytes(int, ByteBuf, int, int)
相同,不同的时此方法会增加源buf的索引,而setBytes(int, ByteBuf, int, int)不会。
此方法不为修改源buf的读写索引
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + src.readableBytes} is greater than
* {@code this.capacity}
*/
public abstract ByteBuf setBytes(int index, ByteBuf src);

/**
* 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* the source buffer (i.e. {@code this}).
*与上面不同的时,从源buf转移指定长度的数据
* @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}
*/
public abstract ByteBuf setBytes(int index, ByteBuf src, int length);

/**
* Transfers the specified source buffer's data to this buffer starting at
* the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex}
* of both the source (i.e. {@code this}) and the destination.
*与上面个方法不同的是,此方法是从源buf的srcIndex索引开始读数据,并且不会修改源buf和
目的buf的索引。
* @param srcIndex the first index of the source
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code srcIndex} is less than {@code 0},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code srcIndex + length} is greater than
* {@code src.capacity}
*/
public abstract ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length);

/**
* Transfers the specified source array's data to this buffer starting at
* the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*转移源字节数组中的数据到当前buf的index位置,不会修改当前buf的索引。
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + src.length} is greater than
* {@code this.capacity}
*/
public abstract ByteBuf setBytes(int index, byte[] src);

/**
* Transfers the specified source array's data to this buffer starting at
* the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*与上面不同的是此方法是从源buf的srcIndex索引开始读数据,并且字节长度为length
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0},
* if the specified {@code srcIndex} is less than {@code 0},
* if {@code index + length} is greater than
* {@code this.capacity}, or
* if {@code srcIndex + length} is greater than {@code src.length}
*/
public abstract ByteBuf setBytes(int index, byte[] src, int srcIndex, int length);

/**
* 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*转移nio ByteBuffer中的数据到当前buf,直到位置索引到达limit位置,此方法不会修改读写索引
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + src.remaining()} is greater than
* {@code this.capacity}
*/
public abstract ByteBuf setBytes(int index, ByteBuffer src);

/**
* Transfers the content of the specified source stream to this buffer
* starting at the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*转移目的输入流的数据到当前buf,,此方法不会修改读写索引
* @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.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + length} is greater than {@code this.capacity}
* @throws IOException
* if the specified stream threw an exception during I/O
*/
public abstract int setBytes(int index, InputStream in, int length) throws IOException;

/**
* Transfers the content of the specified source channel to this buffer
* starting at the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*转移目的分散字节通道的数据到当前buf,,此方法不会修改读写索引
* @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.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + length} is greater than {@code this.capacity}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int setBytes(int index, ScatteringByteChannel in, int length) throws IOException;

/**
* Transfers the content of the specified source channel starting at the given file position
* to this buffer starting at the specified absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer. This method does not modify the channel's position.
*转移目的文件通道的数据到当前buf,,此方法不会修改读写索引
* @param position the file position at which the transfer is to begin
* @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.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* if {@code index + length} is greater than {@code this.capacity}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int setBytes(int index, FileChannel in, long position, int length) throws IOException;

/**
* Fills this buffer with <tt>NUL (0x00)</tt> starting at the specified
* absolute {@code index}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*从buf的index位置,填充字节buf为NUL (0x00),此方法不会修改当前buf中的索引位置
* @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
* if {@code index + length} is greater than {@code this.capacity}
*/
public abstract ByteBuf setZero(int index, int length);

/**
* Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
* the {@code writerIndex} by the written bytes.
*从当前写索引位置开始,写字符序列到当前buf,并更新写索引
* @param index on which the sequence should be written
* @param sequence to write
* @param charset that should be used.
* @return the written number of bytes.
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is not large enough to write the whole sequence
*/
public abstract int setCharSequence(int index, CharSequence sequence, Charset charset);



/**
* Gets a byte at the current {@code readerIndex} and increases
* the {@code readerIndex} by {@code 1} in this buffer.
* 从buf当前的读索引开始,读取一个字节数据,读索引向前移一位
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 1}
*/
public abstract byte readByte();



/**
* 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.
*从当前buf的读索引开始转移length字节数据到新创建的buf中,并增加当前buf的读索引,
新创建的buf的读索引为0,写索引为length
* @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}
*/
public abstract ByteBuf readBytes(int length);

/**
* 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}).
返回当前buf的读索引开始,长度为length的字节切片
* <p>
* Also be aware that this method will NOT call {@link #retain()} and so the
* reference count will NOT be increased.
* 注意此方法不会调用retain方法,索引buf的引用计数器不会变
* @param length the size of the new slice
*
* @return the newly created slice
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
public abstract ByteBuf readSlice(int length);

/**
* Returns a new retained 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}).
* <p>
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #readSlice(int)}.
* This method behaves similarly to {@code readSlice(...).retain()} except that this method may return
* a buffer implementation that produces less garbage.
*与上面方法不同的时,会增加buf的引用计数器,会产生少量的垃圾
* @param length the size of the new slice
*
* @return the newly created slice
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
public abstract ByteBuf readRetainedSlice(int length);

/**
* 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
* transferred bytes. This method is basically same with
* {@link #readBytes(ByteBuf, int, int)}, except that this method
* increases the {@code writerIndex} of the destination by the number of
* the transferred bytes while {@link #readBytes(ByteBuf, int, int)}
* does not.
*从当前buf的读索引开始,转移数据到目的buf,直到当前buf不可读,同时更新当前buf的读索引。
此方法,与#readBytes(ByteBuf, int, int)基本相同,不同的是此方法会增加目的字节buf的写索引,
而#readBytes(ByteBuf, int, int)不会。
* @throws IndexOutOfBoundsException
* if {@code dst.writableBytes} is greater than
* {@code this.readableBytes}
*/
public abstract ByteBuf readBytes(ByteBuf dst);

/**
* 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)},
* 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.
*与上面方法不同到的是,从当前buf读取指定长度的字节数据
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes} or
* if {@code length} is greater than {@code dst.writableBytes}
*/
public abstract ByteBuf readBytes(ByteBuf dst, int length);

/**
* 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}).
*此方法,与上面方法不同的是,将当前buf的数据放到目的buf的dstIndex位置,同时,
此方法不会修改目的buf的写索引
* @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
* if {@code dstIndex + length} is greater than
* {@code dst.capacity}
*/
public abstract ByteBuf readBytes(ByteBuf dst, int dstIndex, int length);

/**
* 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}).
*从当前buf的读索引开始,转移数据到目的字节数组中
* @throws IndexOutOfBoundsException
* if {@code dst.length} is greater than {@code this.readableBytes}
*/
public abstract ByteBuf readBytes(byte[] dst);

/**
* 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}).
*与上面方法不同的是,转移字节长度为length,并方法目的字节数组的dstIndex上
* @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
* if {@code dstIndex + length} is greater than {@code dst.length}
*/
public abstract ByteBuf readBytes(byte[] dst, int dstIndex, int length);

/**
* 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
* number of the transferred bytes.
*从当前buf的读索引开始,转移数据到java nio ByteBuffer中,同时会更新当前buf的读索引
* @throws IndexOutOfBoundsException
* if {@code dst.remaining()} is greater than
* {@code this.readableBytes}
*/
public abstract ByteBuf readBytes(ByteBuffer dst);

/**
* Transfers this buffer's data to the specified stream starting at the
* current {@code readerIndex}.
*从当前buf的读索引开始,转移数据到输出流OutputStream中
* @param length the number of bytes to transfer
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
* @throws IOException
* if the specified stream threw an exception during I/O
*/
public abstract ByteBuf readBytes(OutputStream out, int length) throws IOException;

/**
* Transfers this buffer's data to the specified stream starting at the
* current {@code readerIndex}.
*从当前buf的读索引开始,转移数据到目的聚集通道中
* @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}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int readBytes(GatheringByteChannel out, int length) throws IOException;

/**
* Gets a {@link CharSequence} with the given length at the current {@code readerIndex}
* and increases the {@code readerIndex} by the given length.
*从当前buf的读索引开始,转移length长度的字节数据到目的字符序列中,同时会更新当前buf的读索引
* @param length the length to read
* @param charset that should be used
* @return the sequence
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
public abstract CharSequence readCharSequence(int length, Charset charset);

/**
* Transfers this buffer's data starting at the current {@code readerIndex}
* to the specified channel starting at the given file position.
* This method does not modify the channel's position.
*从当前buf的读索引开始,转移数据到目的文件通道中,不会修改文件通道的位置
* @param position the file position at which the transfer is to begin
* @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}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int readBytes(FileChannel out, long position, int length) throws IOException;

/**
* Increases the current {@code readerIndex} by the specified
* {@code length} in this buffer.
*增加读索引位置length长度,向前移动length位置
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
public abstract ByteBuf skipBytes(int length);

/**
* Sets the specified boolean at the current {@code writerIndex}
* and increases the {@code writerIndex} by {@code 1} in this buffer.
* 从buf当前写索引位置写一个布尔值,写索引向前移一位
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 1}
*/
public abstract ByteBuf writeBoolean(boolean value);

/**
* 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.
* 从buf当前写索引位置写一个字节,写索引向前移一位。
一些特殊值的高24位将会被忽略
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 1}
*/
public abstract ByteBuf writeByte(int value);



/**
* 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
* increases the {@code readerIndex} of the source buffer by the number of
* the transferred bytes while {@link #writeBytes(ByteBuf, int, int)}
* does not.
*从当前buf写索引开始,转移源buf中的数据到当前buf的中,直到源buf不可读,同时更新当前buf的写索引,
此方法与#writeBytes(ByteBuf, int, int)基本相同,除了此方法回修改源buf的读索引,而#writeBytes(ByteBuf, int, int)
不会。

* @throws IndexOutOfBoundsException
* if {@code src.readableBytes} is greater than
* {@code this.writableBytes}
*/
public abstract ByteBuf writeBytes(ByteBuf src);

/**
* 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)},
* 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.
* 与上面方法不同的时,限制源buf转移数据的长度
* @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}
*/
public abstract ByteBuf writeBytes(ByteBuf src, int length);

/**
* 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}).
* 与上面方法不同的是,转移数据从指定索引开始srcIndex
* @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}
*/
public abstract ByteBuf writeBytes(ByteBuf src, int srcIndex, int length);

/**
* 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}).
* 写字节数组中的数据到当前buf,并更新当前buf的写索引
* @throws IndexOutOfBoundsException
* if {@code src.length} is greater than {@code this.writableBytes}
*/
public abstract ByteBuf writeBytes(byte[] src);

/**
* 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}
*/
public abstract ByteBuf writeBytes(byte[] src, int srcIndex, int length);

/**
* 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
* number of the transferred bytes.
写java nio ByteBuffer中的数据到当前buf,直到ByteBuffer的位置索引到limit位置,同时更新写索引
*
* @throws IndexOutOfBoundsException
* if {@code src.remaining()} is greater than
* {@code this.writableBytes}
*/
public abstract ByteBuf writeBytes(ByteBuffer src);

/**
* 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.
*写输入流InputStream中的length个字节数据到当前buf,同时更新写索引
* @param length the number of bytes to transfer
*
* @return the actual number of bytes read in from the specified stream
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.writableBytes}
* @throws IOException
* if the specified stream threw an exception during I/O
*/
public abstract int writeBytes(InputStream in, int length) throws IOException;

/**
* 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.
*写分散字节通道ScatteringByteChannel中的length个字节数据到当前buf,同时更新写索引
* @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}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int writeBytes(ScatteringByteChannel in, int length) throws IOException;

/**
* Transfers the content of the specified channel starting at the given file position
* to this buffer starting at the current {@code writerIndex} and increases the
* {@code writerIndex} by the number of the transferred bytes.
* This method does not modify the channel's position.
*写文件FileChannel中的length个字节数据到当前buf,同时更新写索引,不会修改通道的位置索引
* @param position the file position at which the transfer is to begin
* @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}
* @throws IOException
* if the specified channel threw an exception during I/O
*/
public abstract int writeBytes(FileChannel in, long position, int length) throws IOException;

/**
* Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
* {@code writerIndex} and increases the {@code writerIndex} by the
* specified {@code length}.
*从当前写索引开始,填充length个NUL (0x00)
* @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}
*/
public abstract ByteBuf writeZero(int length);

/**
* Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
* the {@code writerIndex} by the written bytes.
* in this buffer.
*从当前写索引,写字符序列到当前buf
* @param sequence to write
* @param charset that should be used
* @return the written number of bytes
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is not large enough to write the whole sequence
*/
public abstract int writeCharSequence(CharSequence sequence, Charset charset);



/**
* Returns a copy of this buffer's readable bytes. Modifying the content
* of the returned buffer or this buffer does not affect each other at all.
* This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
返回当前buf 可读字节的拷贝。修改返回的copy buf,不会影响当前buf。此方法与
buf.copy(buf.readerIndex(), buf.readableBytes())方法相同,不会修改读写索引
*/
public abstract ByteBuf copy();

/**
* Returns a copy of this buffer's sub-region. Modifying the content of
* the returned buffer or this buffer does not affect each other at all.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
此方法与上面方法,不同的是,限定了读数据开始索引和读取字节的长度
*/
public abstract ByteBuf copy(int index, int length);

/**
* 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())}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
返回当前buf的可读字节数据的切片slice,当他们维护各自的索引和标记时,
修改返回的切片buf或当前buf,会相互影响buf数据,此方法等同于
buf.slice(buf.readerIndex(), buf.readableBytes()),此方法不会修改读写索引

* <p>
* Also be aware that this method will NOT call {@link #retain()} and so the
* reference count will NOT be increased.
注意,此方法不会调用retain方法,即不会增加buf的引用计数器
*/
public abstract ByteBuf slice();

/**
* 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
此方法与上面方法,不同的是,限定了切片数据开始索引和字节的长度
* <p>
* Also be aware that this method will NOT call {@link #retain()} and so the
* reference count will NOT be increased.
*/
public abstract ByteBuf slice(int index, int length);

/**
* Returns a retained 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())}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
* <p>
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice()}.
* This method behaves similarly to {@code slice().retain()} except that this method may return
* a buffer implementation that produces less garbage.
与#slice方法不同的是,会调用retain方法,即增加buf的引用计数器,同时可能会产生一些内存垃圾
*/
public abstract ByteBuf retainedSlice();


/**
* Returns a retained 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.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
* <p>
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
* This method behaves similarly to {@code slice(...).retain()} except that this method may return
* a buffer implementation that produces less garbage.
此方法与上面方法,不同的是,限定了切片数据开始索引和字节的长度
*/
public abstract ByteBuf retainedSlice(int index, int length);

/**
* 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 does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
返回buf的整个共享域,当他们维护各自的索引和标记时,
修改返回的buf或当前buf,会相互影响buf数据,此方法不会修改读写索引
* <p>
* The reader and writer marks will not be duplicated. Also be aware that this method will
* NOT call {@link #retain()} and so the reference count will NOT be increased.
* @return A buffer whose readable content is equivalent to the buffer returned by {@link #slice()}.
* However this buffer will share the capacity of the underlying buffer, and therefore allows access to all of the
* underlying content if necessary.
读写标记不会复制。同时此方法不会调用retain方法,即不会增加buf的引用计数器,
返回的buf的可读内容相当于#slice方法返回的buf。不同的是,此方法返回的buf与底层buf共享容量,
因此如果需要,运行方法底层的数据内容
*/
public abstract ByteBuf duplicate();

/**
* Returns a retained 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())}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
* <p>
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
* This method behaves similarly to {@code duplicate().retain()} except that this method may return
* a buffer implementation that produces less garbage.
与上述方法不同的是,会调用retain方法,即增加buf的引用计数器,同时可能会产生一些内存垃圾
*/
public abstract ByteBuf retainedDuplicate();

/**
* 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.
*返回包含当前buf的最大java nio ByteBuffer数量。注意#nioBuffers和#nioBuffers(int, int)方法,可能
返回更少数量的ByteBuffer
* @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 underlying
* {@link ByteBuffer}. Note that this method does not return {@code 0} to avoid confusion.
* 如果当前buf没有底层ByteBuffer,则返回-1。如果当前buf至少有一个ByteBuffer,则返回数量。注意为了避免
冲突,此方法不会返回0。
* @see #nioBuffer()
* @see #nioBuffer(int, int)
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract int nioBufferCount();

/**
* 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.
* 暴露当前buf的可读数据到一个java nio ByteBuffer中。返回的java nio ByteBuffer与当前buf共享数据,
但修改java nio ByteBuffer的位置和limit,不会修改当前buf的索引和标记。
此方法与buf.nioBuffer(buf.readerIndex(), buf.readableBytes()相同。此方法不会修改当前buf的读写索引。
如果当前buf是一个动态的buf,调整buf容量时,java nio ByteBuffer 是看不到容量的改变的。
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract ByteBuffer nioBuffer();

/**
* 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.
*与上面不同的时,限定了共享region的开始索引和数据长度
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract ByteBuffer nioBuffer(int index, int length);

/**
* Internal use only: Exposes the internal NIO buffer.
内部使用,暴露一个内部的nio buf
*/
public abstract 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.
*
*与#nioBuffer方法不同的是返回的是一个nio buf数组
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
public abstract 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.
*与上面不同的时,限定了共享region的开始索引和数据长度
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
public abstract 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()}.
当前仅当,buf由于有一个backing 字节数组,返回true。如果方法返回true,则可以调用
#array() 和 #arrayOffset()方法.
*/
public abstract boolean hasArray();

/**
* Returns the backing byte array of this buffer.
*返回当前buf的backing字节数组
* @throws UnsupportedOperationException
* if there no accessible backing byte array
*/
public abstract byte[] array();

/**
* Returns the offset of the first byte within the backing byte array of
* this buffer.
*返回当前buf backing数组第一个字节在buf中的位置
* @throws UnsupportedOperationException
* if there no accessible backing byte array
*/
public abstract 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.
当且仅当,当前buf有一个指向backing数据的低位内存地址引用时,返回true
*/
public abstract boolean hasMemoryAddress();

/**
* Returns the low-level memory address that point to the first byte of ths backing data.
* 返回buf中第一个字节的低位内存地址
* @throws UnsupportedOperationException
* if this buffer does not support accessing the low-level memory address
*/
public abstract long memoryAddress();

/**
* 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)}.
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*解码可读字节数据为,更定字符编码的字符串,此方法相当与
buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName),
此方法不会修改读写索引。
* @throws UnsupportedCharsetException
* if the specified character set name is not supported by the
* current VM
*/
public abstract 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.
此方法与上面方法,不同的是,限定了buf数据开始索引和字节的长度
*/
public abstract 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.
返回buf内容的hash code。如果buf的字节数组相等,则返回相同hash code
*/
@Override
public abstract int hashCode();

/**
* Determines if the content of the specified buffer is identical to the
* content of this array. 'Identical' here means:
* [list]
* [*]the size of the contents of the two buffers are same and

* [*]every single byte of the content of the two buffers are same.

* [/list]
* 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.
判断对象是否想定,当且仅当两个buf中的所有的字节相等,则对象相等,不比较索引,
如果对象不是字节buf,则返回false
*/
@Override
public abstract 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)}.
比较buf,以字符串的比较形式
*/
@Override
public abstract int compareTo(ByteBuf buffer);

/**
* 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()},
* {@link #writerIndex()} and {@link #capacity()}.
返回buf所表示的字符串,从读索引到写索引位置
*/
@Override
public abstract String toString();
//增加字节buf引用计数器,增量为increment
@Override
public abstract ByteBuf retain(int increment);
//自增字节buf引用计数器
@Override
public abstract ByteBuf retain();

@Override
public abstract ByteBuf touch();
//调试时,记录buf操作的相关信息,以便分析内存泄漏问题
@Override
public abstract ByteBuf touch(Object hint);
}


[size=medium][b]
总结:[/b][/size]

[color=blue]对象引用计数器ReferenceCounted,主要记录对象的引用数量,当引用数量为0时,表示可以回收对象,在调试模式下,如果发现对象出现内存泄漏,可以用touch方法记录操作的相关信息,通过ResourceLeakDetector获取操作的相关信息,以便分析内存泄漏的原因。

字节缓存ByteBuf继承了对象引用计数器ReferenceCounted,拥有一个最大容量限制,如果用户尝试用 #capacity(int)和 #ensureWritable(int)方法,增加buf容量超过最大容量,将会抛出非法参数异常;字节buf有两个索引,一个为读索引readerIndex,一个为写索引writerIndex,读索引不能大于写索引,写索引不能小于读索引,buf可读字节数为writerIndex - readerIndex,buf可写字节数为capacity - writerIndex,buf可写的最大字节数为maxCapacity - writerIndex;

可以使用markReader/WriterIndex标记当前buf读写索引位置,resetReader/WriterIndex方法可以重回先前标记的索引位置;

当内存空间负载过度时,我们可以使用discardReadBytes丢弃一些数据,以节省空间;

我们可以使用ensureWritable检测当buf是否有足够的空间写数据;

提供了getBytes方法,可以将buf中的数据转移到目的ByteBuf,Byte数组,Nio字节buf ByteBuffer,OutputStream,聚集字节通道
GatheringByteChannel和文件通道FileChannel中,这些方法不会修改当前buf读写索引,具体是否修改目的对象索引或位置,见java doc 描述。

提供了setBytes方法,可以将源ByteBuf,Byte数组,Nio字节buf ByteBuffer,InputputStream,分散字节通道ScatteringByteChannel和文件通道FileChannel中的数据转移到当前buf中,这些方法不会修改当前buf的读写索引,至于源对象索引或位置,见java doc 描述。

提供了readBytes方法,可以将buf中的数据转移到目的ByteBuf,Byte数组,Nio字节buf ByteBuffer,OutputStream,聚集字节通道GatheringByteChannel和文件通道FileChannel中,这些方法具体会会修改当前buf读索引,至于会不会修改源对象索引或位置,见java doc 描述。

提供了writeBytes方法,可以将源ByteBuf,Byte数组,Nio字节buf ByteBuffer,
InputputStream,分散字节通道ScatteringByteChannel和文件通道FileChannel中的数据写到当前buf中,这些方法会修改当前buf的写索引,至于会不会修改源对象索引或位置,见java
doc 描述。


set*原始类型方法不会修改读写索引;
get*原始类型方法不会修改读写索引;

write*原始类型方法会修改写索引;
read*原始类型方法,会修改读索引;

字节buf中的set/get*方法不会修改当前buf的读写索引,而write*修改写索引,read*会修改读索引;

提供了copy,slice和retainSlice,duplicate和retainedDuplicate方法,用于拷贝,切割,复制当前buf数据,retained*方法会增加buf的引用计数器;

提供nioBuffer和nioBuffers方法,用于包装当前buf可读数据为java nio ByteBuffer和ByteBuffer数组。
[/color]
[b]
附:[/b]
下面是字节buf的get*原始类型方法的定义,简单看一下:
下面的方法不会修改读写索引
 /**
* 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.
*
* @throws IndexOutOfBoundsException
* if the specified {@code index} is less than {@code 0} or
* {@code index + 1} is greater than {@code this.capacity}
*/
public abstract boolean getBoolean(int index);
/**
* Gets an unsigned byte 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}
*/
public abstract short getUnsignedByte(int index);

/**
* Gets a 16-bit short integer 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}
*/
public abstract short getShort(int index);

/**
* Gets a 16-bit short integer at the specified absolute {@code index} in
* this buffer in Little Endian Byte Order. 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}
*/
public abstract short getShortLE(int index);

/**
* Gets an unsigned 16-bit short integer 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}
*/
public abstract int getUnsignedShort(int index);

/**
* Gets an unsigned 16-bit short integer at the specified absolute
* {@code index} in this buffer in Little Endian Byte Order.
* 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}
*/
public abstract int getUnsignedShortLE(int index);

/**
* Gets a 24-bit medium integer 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 + 3} is greater than {@code this.capacity}
*/
public abstract int getMedium(int index);

/**
* Gets a 24-bit medium integer at the specified absolute {@code index} in
* this buffer in the Little Endian Byte Order. 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 + 3} is greater than {@code this.capacity}
*/
public abstract int getMediumLE(int index);

/**
* Gets an unsigned 24-bit medium integer 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 + 3} is greater than {@code this.capacity}
*/
public abstract int getUnsignedMedium(int index);

/**
* Gets an unsigned 24-bit medium integer at the specified absolute
* {@code index} in this buffer in Little Endian Byte Order.
* 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 + 3} is greater than {@code this.capacity}
*/
public abstract int getUnsignedMediumLE(int index);

/**
* Gets a 32-bit integer 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}
*/
public abstract int getInt(int index);

/**
* Gets a 32-bit integer at the specified absolute {@code index} in
* this buffer with Little Endian Byte Order. 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}
*/
public abstract int getIntLE(int index);

/**
* Gets an unsigned 32-bit integer 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}
*/
public abstract long getUnsignedInt(int index);

/**
* Gets an unsigned 32-bit integer at the specified absolute {@code index}
* in this buffer in Little Endian Byte Order. 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}
*/
public abstract long getUnsignedIntLE(int index);

/**
* Gets a 64-bit long integer 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}
*/
public abstract long getLong(int index);

/**
* Gets a 64-bit long integer at the specified absolute {@code index} in
* this buffer in Little Endian Byte Order. 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}
*/
public abstract long getLongLE(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}
*/
public abstract 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}
*/
public abstract 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}
*/
public abstract double getDouble(int index);



下面一些set*原始类型方法从索引index开始,设置原始类型,不会修改读写索引
/**
* 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}
*/
public abstract ByteBuf setBoolean(int index, boolean 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.
* 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}
*/
public abstract ByteBuf setShort(int index, int value);

/**
* Sets the specified 16-bit short integer at the specified absolute
* {@code index} in this buffer with the Little Endian Byte Order.
* 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}
*/
public abstract ByteBuf setShortLE(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.
* 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 + 3} is greater than {@code this.capacity}
*/
public abstract ByteBuf setMedium(int index, int value);

/**
* Sets the specified 24-bit medium integer at the specified absolute
* {@code index} in this buffer in the Little Endian Byte Order.
* Please note that the most significant byte is ignored in the
* specified value.
* 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 + 3} is greater than {@code this.capacity}
*/
public abstract ByteBuf setMediumLE(int index, int value);

/**
* Sets the specified 32-bit integer 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}
*/
public abstract ByteBuf setInt(int index, int value);

/**
* Sets the specified 32-bit integer at the specified absolute
* {@code index} in this buffer with Little Endian byte order
* .
* 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}
*/
public abstract ByteBuf setIntLE(int index, int value);

/**
* Sets the specified 64-bit long integer 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}
*/
public abstract ByteBuf setLong(int index, long value);

/**
* Sets the specified 64-bit long integer at the specified absolute
* {@code index} in this buffer in Little Endian Byte Order.
* 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}
*/
public abstract ByteBuf setLongLE(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}
*/
public abstract 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}
*/
public abstract 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}
*/
public abstract ByteBuf setDouble(int index, double value);


以下一些read*原始类型方法,会修改读索引
/**
* 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}
*/
public abstract boolean readBoolean();
/**
* Gets an unsigned 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}
*/
public abstract short readUnsignedByte();

/**
* 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}
*/
public abstract short readShort();

/**
* Gets a 16-bit short integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 2} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 2}
*/
public abstract short readShortLE();

/**
* Gets an unsigned 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}
*/
public abstract int readUnsignedShort();

/**
* Gets an unsigned 16-bit short integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 2} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 2}
*/
public abstract int readUnsignedShortLE();

/**
* 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}
*/
public abstract int readMedium();

/**
* Gets a 24-bit medium integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the
* {@code readerIndex} by {@code 3} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 3}
*/
public abstract int readMediumLE();

/**
* Gets an unsigned 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}
*/
public abstract int readUnsignedMedium();

/**
* Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 3} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 3}
*/
public abstract int readUnsignedMediumLE();

/**
* 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}
*/
public abstract int readInt();

/**
* Gets a 32-bit integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 4}
*/
public abstract int readIntLE();

/**
* Gets an unsigned 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}
*/
public abstract long readUnsignedInt();

/**
* Gets an unsigned 32-bit integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 4}
*/
public abstract long readUnsignedIntLE();

/**
* 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}
*/
public abstract long readLong();

/**
* Gets a 64-bit integer at the current {@code readerIndex}
* in the Little Endian Byte Order and increases the {@code readerIndex}
* by {@code 8} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.readableBytes} is less than {@code 8}
*/
public abstract long readLongLE();

/**
* 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}
*/
public abstract 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}
*/
public abstract 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}
*/
public abstract double readDouble();


下面是一些write*原始类型的方法,会增加写索引

/**
* 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.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 2}
*/
public abstract ByteBuf writeShort(int value);

/**
* Sets the specified 16-bit short integer in the Little Endian Byte
* Order 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}
*/
public abstract ByteBuf writeShortLE(int value);

/**
* 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}
*/
public abstract ByteBuf writeMedium(int value);

/**
* Sets the specified 24-bit medium integer at the current
* {@code writerIndex} in the Little Endian Byte Order and
* increases the {@code writerIndex} by {@code 3} in this
* buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 3}
*/
public abstract ByteBuf writeMediumLE(int value);

/**
* 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}
*/
public abstract ByteBuf writeInt(int value);

/**
* Sets the specified 32-bit integer at the current {@code writerIndex}
* in the Little Endian Byte Order and increases the {@code writerIndex}
* by {@code 4} in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 4}
*/
public abstract ByteBuf writeIntLE(int value);

/**
* 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}
*/
public abstract ByteBuf writeLong(long value);

/**
* Sets the specified 64-bit long integer at the current
* {@code writerIndex} in the Little Endian Byte Order and
* increases the {@code writerIndex} by {@code 8}
* in this buffer.
*
* @throws IndexOutOfBoundsException
* if {@code this.writableBytes} is less than {@code 8}
*/
public abstract ByteBuf writeLongLE(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}
*/
public abstract 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}
*/
public abstract 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}
*/
public abstract ByteBuf writeDouble(double value);


下面是一些字节搜索定位方法:
/**
* 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).
查找在当buf的fromIndex(inclusive)和toIndex(exclusive),之间是否存在指定的字节,
找到返回对应的索引,否则返回-1
* <p>
* If {@code fromIndex} is greater than {@code toIndex}, the search is
* performed in a reversed order.
如果fromIndex大于toIndex,则反向执行搜索
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
此方法不会修改读写索引
*
* @return the absolute index of the first occurrence if found.
* {@code -1} otherwise.
*/
public abstract int indexOf(int fromIndex, int toIndex, byte value);

/**
* 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>
从当前buf的读索引开始,到写索引之间,搜索是否存在指定字节,存在则返回第一次发生的索引,
否则返回-1
* 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.
*/
public abstract int bytesBefore(byte value);

/**
* 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}.
与上面方法不同的是,不是到写索引,而是指定了搜索返回即[readerIndex,readerIndex+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}
*/
public abstract int bytesBefore(int length, byte value);

/**
* 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}
*/
public abstract int bytesBefore(int index, int length, byte value);

再来遍历buf,处理字节:
/**
* Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order.
* 遍历buf,以升序ByteProcessor#process处理字节
* @return {@code -1} if the processor iterated to or beyond the end of the readable bytes.
* The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
如果迭代器超过可读索引位置,则返回-1,否则返回上次ByteProcessor#process(byte)方法,返回false的索引位置
*/
public abstract int forEachByte(ByteProcessor 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)})
*与上面的不同的多了开始索引,和范围控制length
* @return {@code -1} if the processor iterated to or beyond the end of the specified area.
* The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
*/
public abstract int forEachByte(int index, int length, ByteProcessor processor);

/**
* Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order.
*降序方式ByteProcessor#process处理字节
* @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes.
* The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
*/
public abstract int forEachByteDesc(ByteProcessor 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})
*与上面的不同的多了开始索引,和范围控制length
*
* @return {@code -1} if the processor iterated to or beyond the beginning of the specified area.
* The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
*/
public abstract int forEachByteDesc(int index, int length, ByteProcessor processor);



//ByteProcessor
 package io.netty.util;

/**
* Provides a mechanism to iterate over a collection of bytes.
*/
public interface ByteProcessor {
/**
* A {@link ByteProcessor} which finds the first appearance of a specific byte.
*/
class IndexOfProcessor implements ByteProcessor {
private final byte byteToFind;

public IndexOfProcessor(byte byteToFind) {
this.byteToFind = byteToFind;
}

@Override
public boolean process(byte value) {
return value != byteToFind;
}
}

/**
* A {@link ByteProcessor} which finds the first appearance which is not of a specific byte.
*/
class IndexNotOfProcessor implements ByteProcessor {
private final byte byteToNotFind;

public IndexNotOfProcessor(byte byteToNotFind) {
this.byteToNotFind = byteToNotFind;
}

@Override
public boolean process(byte value) {
return value == byteToNotFind;
}
}

/**
* Aborts on a {@code NUL (0x00)}.
*/
ByteProcessor FIND_NUL = new IndexOfProcessor((byte) 0);

/**
* Aborts on a non-{@code NUL (0x00)}.
*/
ByteProcessor FIND_NON_NUL = new IndexNotOfProcessor((byte) 0);

/**
* Aborts on a {@code CR ('\r')}.
*/
ByteProcessor FIND_CR = new IndexOfProcessor((byte) '\r');

/**
* Aborts on a non-{@code CR ('\r')}.
*/
ByteProcessor FIND_NON_CR = new IndexNotOfProcessor((byte) '\r');

/**
* Aborts on a {@code LF ('\n')}.
*/
ByteProcessor FIND_LF = new IndexOfProcessor((byte) '\n');

/**
* Aborts on a non-{@code LF ('\n')}.
*/
ByteProcessor FIND_NON_LF = new IndexNotOfProcessor((byte) '\n');

/**
* Aborts on a {@code CR (';')}.
*/
ByteProcessor FIND_SEMI_COLON = new IndexOfProcessor((byte) ';');

/**
* Aborts on a {@code CR ('\r')} or a {@code LF ('\n')}.
*/
ByteProcessor FIND_CRLF = new ByteProcessor() {
@Override
public boolean process(byte value) {
return value != '\r' && value != '\n';
}
};

/**
* Aborts on a byte which is neither a {@code CR ('\r')} nor a {@code LF ('\n')}.
*/
ByteProcessor FIND_NON_CRLF = new ByteProcessor() {
@Override
public boolean process(byte value) {
return value == '\r' || value == '\n';
}
};

/**
* Aborts on a linear whitespace (a ({@code ' '} or a {@code '\t'}).
*/
ByteProcessor FIND_LINEAR_WHITESPACE = new ByteProcessor() {
@Override
public boolean process(byte value) {
return value != ' ' && value != '\t';
}
};

/**
* Aborts on a byte which is not a linear whitespace (neither {@code ' '} nor {@code '\t'}).
*/
ByteProcessor FIND_NON_LINEAR_WHITESPACE = new ByteProcessor() {
@Override
public boolean process(byte value) {
return value == ' ' || value == '\t';
}
};

/**
* @return {@code true} if the processor wants to continue the loop and handle the next byte in the buffer.
* {@code false} if the processor wants to stop handling bytes and abort the loop.
*/
boolean process(byte value) throws Exception;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值