@Override
    protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
        if (finished) {
            if (!out.isWritable(in.readableBytes())) {
                // out should be EMPTY_BUFFER because we should have allocated enough space above in allocateBuffer.
                throw ENCODE_FINSHED_EXCEPTION;
            }
            out.writeBytes(in);
            return;
        }

        final ByteBuf buffer = this.buffer;
        int length;
        while ((length = in.readableBytes()) > 0) {
            final int nextChunkSize = Math.min(length, buffer.writableBytes());
            in.readBytes(buffer, nextChunkSize);

            if (!buffer.isWritable()) {
                flushBufferedData(out);
            }
        }
    }
@ Override protected void encode ( ChannelHandlerContext ctx , ByteBuf in , ByteBuf out ) throws Exception { if ( finished ) { if ( ! out . isWritable ( in . readableBytes ( ) ) ) { throw ENCODE_FINSHED_EXCEPTION ; } out . writeBytes ( in ) ; return ; } final ByteBuf buffer = this . buffer ; int length ; while ( ( length = in . readableBytes ( ) ) > 0 ) { final int nextChunkSize = Math . min ( length , buffer . writableBytes ( ) ) ; in . readBytes ( buffer , nextChunkSize ) ; if ( ! buffer . isWritable ( ) ) { flushBufferedData ( out ) ; } } }
{@inheritDoc}

Encodes the input buffer into {@link #blockSize} chunks in the output buffer. Data is only compressed and
written once we hit the {@link #blockSize}; else, it is copied into the backing {@link #buffer} to await
more data.