class BrpcHttpObjectDecoder extends HttpObjectDecoder {

    public Object decode(ChannelHandlerContext ctx, ByteBuf in) {
        BrpcHttpObjectAggregator httpObjectAggregator = new BrpcHttpObjectAggregator(10 * 1024 * 1024);
        this.reset();
        List httpParts = new LinkedList();
        List httpResult = new LinkedList();
        try {
            while (in.isReadable()) {
                int outSize = httpParts.size();

                if (outSize > 0) {
                    for (int i = 0; i < outSize; i++) {
                        httpObjectAggregator.aggregate(ctx, httpParts.get(i), httpResult);
                        if (httpResult.size() > 0) {
                            return httpResult.get(0);
                        }
                    }
                    // fireChannelRead(ctx, out, outSize);
                    httpParts.clear();

                    // Check if this handler was removed before continuing with decoding.
                    // If it was removed, it is not safe to continue to operate on the buffer.
                    //
                    // See:
                    // - https://github.com/netty/netty/issues/4635
                    if (ctx.isRemoved()) {
                        break;
                    }
                    outSize = 0;
                }

                int oldInputLength = in.readableBytes();
                decode(ctx, in, httpParts);
                // decodeRemovalReentryProtection(ctx, in, out);

                // Check if this handler was removed before continuing the loop.
                // If it was removed, it is not safe to continue to operate on the buffer.
                //
                // See https://github.com/netty/netty/issues/1664
                if (ctx.isRemoved()) {
                    break;
                }

                if (outSize == httpParts.size()) {
                    if (oldInputLength == in.readableBytes()) {
                        break;
                    } else {
                        continue;
                    }
                }

                if (oldInputLength == in.readableBytes()) {
                    throw new DecoderException(
                            StringUtil.simpleClassName(getClass()) +
                                    ".decode() did not read anything but decoded a message.");
                }

                if (isSingleDecode()) {
                    break;
                }
            }
            int outSize = httpParts.size();
            if (outSize > 0) {
                for (int i = 0; i < outSize; i++) {
                    httpObjectAggregator.aggregate(ctx, httpParts.get(i), httpResult);
                    if (httpResult.size() > 0) {
                        return httpResult.get(0);
                    }
                }
            }
            // decode failed, there's not enough bytes
            httpObjectAggregator.abort();
            return null;
        } catch (DecoderException e) {
            throw e;
        } catch (Exception cause) {
            throw new DecoderException(cause);
        }
    }

    private  BrpcHttpObjectDecoder(boolean isDecodingRequest);

}