}
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), url, handler);
boolean remaining = true;
Object msg;
UnsafeByteArrayInputStream bis;
try {
do {
// read data into buffer.
int read = Math.min(readable, buf.length - limit);
input.readBytes(buf, limit, read);
limit += read;
readable -= read;
bis = new UnsafeByteArrayInputStream(buf, off, limit - off); // 不需要关闭
// decode object.
do {
try {
msg = upstreamCodec.decode(channel, bis);
} catch (IOException e) {
remaining = false;
throw e;
}
if (msg == Codec.NEED_MORE_INPUT) {
if (off == 0) {
if (readable > 0) {
buf = Bytes.copyOf(buf, buf.length << 1);
}
} else {
int len = limit - off;
System.arraycopy(buf, off, buf, 0, len); // adjust buffer.
off = 0;
limit = len;
}
break;
} else {
int pos = bis.position();
if (off == pos) {
remaining = false;
throw new IOException("Decode without read data.");
}
if (msg != null) {
Channels.fireMessageReceived(ctx, msg, event.getRemoteAddress());
}
off = pos;
}
} while (bis.available() > 0);
} while (readable > 0);
} finally {
if (remaining) {
int len = limit - off;
if (len < buf.length / 2) {