Repository: netty/netty
File: codec/src/main/java/io/netty/handler/codec/compression/ZstdDecoder.java (Java)

Code before:
                in.skipBytes(in.readableBytes());
                return;
            }
            final int compressedLength = in.readableBytes();

            inputStream.current = in;

            ByteBuf outBuffer = null;
            try {
                int w = -1;
                do {
                    if (outBuffer == null) {
                        // Let's start with the compressedLength * 2 as often we will not have everything
                        // we need in the in buffer and don't want to reserve too much memory.
                        outBuffer = ctx.alloc().heapBuffer(compressedLength * 2);
                    }
                    byte[] array = outBuffer.array();
                    int writerOffset = outBuffer.arrayOffset() + outBuffer.writerIndex();
                    int writableBytes = outBuffer.writableBytes();
                    int written = 0;
                    while (writableBytes > 0 && (w = zstdIs.read(array, writerOffset, writableBytes)) != -1) {
                        writerOffset += w;
                        writableBytes -= w;
                        written += w;
                    }
                    outBuffer.writerIndex(outBuffer.writerIndex() + written);
                    if (outBuffer.isReadable()) {
                        out.add(outBuffer);
                        outBuffer = null;
                    }
                } while (w != -1);
            } finally {
                if (outBuffer != null) {
                    outBuffer.release();
                }
            }
        } catch (Exception e) {
            currentState = State.CORRUPTED;
            throw new DecompressionException(e);
        } finally {
            inputStream.current = null;
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        zstdIs = new ZstdInputStreamNoFinalizer(inputStream);
        zstdIs.setContinuous(true);
    }


Review comment (suggestion):
This can also be written like this:
```suggestion
                    do {
                        w = outBuffer.writeBytes(zstdIs, outBuffer.writableBytes());
                    } while (w != -1 && outBuffer.isWritable());
```

Code after:
    private enum State {
        DECOMPRESS_DATA,
        CORRUPTED
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        try {
            if (currentState == State.CORRUPTED) {
                in.skipBytes(in.readableBytes());
                return;
            }
            final int compressedLength = in.readableBytes();

            inputStream.current = in;

            ByteBuf outBuffer = null;
            try {
                int w;
                do {
                    if (outBuffer == null) {
                        // Let's start with the compressedLength * 2 as often we will not have everything
                        // we need in the in buffer and don't want to reserve too much memory.
                        outBuffer = ctx.alloc().heapBuffer(compressedLength * 2);
                    }
                    do {
                        w = outBuffer.writeBytes(zstdIs, outBuffer.writableBytes());
                    } while (w != -1 && outBuffer.isWritable());
                    if (outBuffer.isReadable()) {
                        out.add(outBuffer);
                        outBuffer = null;
                    }
                } while (w != -1);
            } finally {
                if (outBuffer != null) {
                    outBuffer.release();
                }
            }
        } catch (Exception e) {
            currentState = State.CORRUPTED;
            throw new DecompressionException(e);
        } finally {
            inputStream.current = null;
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        zstdIs = new ZstdInputStreamNoFinalizer(inputStream);
        zstdIs.setContinuous(true);