public int decompress()

in java/src/main/java/com/epam/deltix/zstd/ZstdFrameDecompressor.java [157:225]


    public int decompress(
            final ByteBuffer inputBase,
            final int inputAddress,
            final int inputLimit,
            final ByteBuffer outputBase,
            final int outputAddress,
            final int outputLimit) {
        if (outputAddress == outputLimit) {
            return 0;
        }

        reset();

        int input = inputAddress;
        int output = outputAddress;

        input += verifyMagic(inputBase, inputAddress, inputLimit);

        final FrameHeader frameHeader = readFrameHeader(inputBase, input, inputLimit);
        input += frameHeader.headerSize;

        boolean lastBlock;
        do {
            verify(input + SIZE_OF_BLOCK_HEADER <= inputLimit, input, "Not enough input bytes");

            // read block header
            final int header = inputBase.getInt(input) & 0xFF_FFFF;
            input += SIZE_OF_BLOCK_HEADER;

            lastBlock = (header & 1) != 0;
            final int blockType = (header >>> 1) & 0b11;
            final int blockSize = (header >>> 3) & 0x1F_FFFF; // 21 bits

            final int decodedSize;
            switch (blockType) {
                case RAW_BLOCK:
                    verify(inputAddress + blockSize <= inputLimit, input, "Not enough input bytes");
                    decodedSize = decodeRawBlock(inputBase, input, blockSize, outputBase, output, outputLimit);
                    input += blockSize;
                    break;
                case RLE_BLOCK:
                    verify(inputAddress + 1 <= inputLimit, input, "Not enough input bytes");
                    decodedSize = decodeRleBlock(blockSize, inputBase, input, outputBase, output, outputLimit);
                    input += 1;
                    break;
                case COMPRESSED_BLOCK:
                    verify(inputAddress + blockSize <= inputLimit, input, "Not enough input bytes");
                    decodedSize = decodeCompressedBlock(inputBase, input, blockSize, outputBase, output, outputLimit, frameHeader.windowSize);
                    input += blockSize;
                    break;
                default:
                    throw fail(input, "Invalid block type");
            }

            output += decodedSize;
        }
        while (!lastBlock);

        if (frameHeader.hasChecksum) {
            final long hash = XxHash64.hash(0, outputBase, outputAddress, (int) (outputLimit - outputAddress));

            final int checksum = inputBase.getInt(input);
            if (checksum != (int) hash) {
                throw new RuntimeException(String.format("Bad checksum. Expected: %s, actual: %s: offset=%d", Integer.toHexString(checksum), Integer.toHexString((int) hash), input));
            }
        }

        return (int) (output - outputAddress);
    }