@Override protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(1024); com.antrou.dubbo.remoting.netty4.NettyChannel channel = com.antrou.dubbo.remoting.netty4.NettyChannel.getOrAddChannel( ctx.channel(), url, handler); try { codec.encode(channel, os, msg); } finally { com.antrou.dubbo.remoting.netty4.NettyChannel.removeChannelIfDisconnected(ctx.channel()); } out.writeBytes(os.toByteBuffer()); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception { int readable = input.readableBytes(); if (readable <= 0) { return; } int off, limit; byte[] buf = mBuffer; if (buf == null) { buf = new byte[bufferSize]; off = limit = 0; } else { off = mOffset; limit = mLimit; } com.antrou.dubbo.remoting.netty4.NettyChannel channel = com.antrou.dubbo.remoting.netty4.NettyChannel.getOrAddChannel( ctx.channel(), 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 = codec.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) { out.add(msg); } off = pos; } } while (bis.available() > 0); } while (readable > 0); } finally { if (remaining) { int len = limit - off; if (len < buf.length / 2) { System.arraycopy(buf, off, buf, 0, len); off = 0; limit = len; } mBuffer = buf; mOffset = off; mLimit = limit; } else { mBuffer = null; mOffset = mLimit = 0; } com.antrou.dubbo.remoting.netty4.NettyChannel.removeChannelIfDisconnected(ctx.channel()); } }