for(;;) {
int read = Math.min(readable, bytes.length - limit); // 取bytes缓存空闲区,和可读取新数据,的最小值,即:此次最多读写数据的大小
buffer.get(bytes, limit, read); // 从可读取新数据中,读取数据,尽量填满bytes缓存空闲区
limit += read; // 有效数据变长
readable -= read; // 可读数据变少
UnsafeByteArrayInputStream input = new UnsafeByteArrayInputStream(bytes, offset, limit - offset); // 将bytes缓存转成InputStream,不需要关闭
Object msg = upstreamCodec.decode(channel, input); // 调用Codec接口,解码数据
if (msg == Codec.NEED_MORE_INPUT) { // 如果Codec觉得数据不够,不足以解码成一个对象
if (readable == 0) { // 如果没有更多可读数据
channel.setAttribute(BUFFER_KEY, new Object[] { bytes, offset, limit }); // 放入通道属性中,等待下一个Buffer的到来
return context.getStopAction();
} else { // 扩充或挪出空闲区,并循环,直到可读数据都加载到bytes缓存
if (offset == 0) { // 如果bytes缓存全部没有被使用,如果这时数据还不够
bytes = Bytes.copyOf(bytes, bytes.length << 1); // 将bytes缓存扩大一倍
} else { // 如果bytes缓存有一段数据已被使用
int len = limit - offset; // 计算有效数据长度
System.arraycopy(bytes, offset, bytes, 0, len); // 将数据向前移到,压缩到已使用的部分,这样limit后面就会多出一些空闲,可以放数据
offset = 0; // 移到后,bytes缓存没有数据被使用
limit = len; // 移到后,有效数据都在bytes缓存最前面
}
}
} else { // 如果解析出一个结果
int position = input.position(); // 记录InputStream用了多少
if (position == offset) { // 如果InputStream没有被读过,就返回了数据,直接报错,否则InputStream永远读不完,会死递归
throw new IOException("Decode without read data.");
}
offset = position; // 记录已读数据
context.setMessage(msg); // 将消息改为解码后的对象,以便被后面的Filter使用。