// 
// Decompiled by Procyon v0.6.0
// 

package com.github.luben.zstd;

import com.github.luben.zstd.util.Native;
import java.util.List;
import java.util.ArrayList;
import java.nio.ByteBuffer;

public class Zstd
{
    public static long compress(final byte[] array, final byte[] array2, final int level, final boolean checksum) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.setChecksum(checksum);
            return zstdCompressCtx.compress(array, array2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compress(final byte[] array, final byte[] array2, final int n) {
        return compress(array, array2, n, false);
    }
    
    public static long compressByteArray(final byte[] array, final int n, final int n2, final byte[] array2, final int n3, final int n4, final int level, final boolean checksum) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.setChecksum(checksum);
            return zstdCompressCtx.compressByteArray(array, n, n2, array2, n3, n4);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressByteArray(final byte[] array, final int n, final int n2, final byte[] array2, final int n3, final int n4, final int n5) {
        return compressByteArray(array, n, n2, array2, n3, n4, n5, false);
    }
    
    public static long compressDirectByteBuffer(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final int level, final boolean checksum) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.setChecksum(checksum);
            return zstdCompressCtx.compressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressDirectByteBuffer(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final int n5) {
        return compressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4, n5, false);
    }
    
    public static native long compressUnsafe(final long p0, final long p1, final long p2, final long p3, final int p4, final boolean p5);
    
    public static long compressUnsafe(final long n, final long n2, final long n3, final long n4, final int n5) {
        return compressUnsafe(n, n2, n3, n4, n5, false);
    }
    
    public static long compressUsingDict(final byte[] array, final int n, final byte[] array2, final int n2, final int n3, final byte[] array3, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.loadDict(array3);
            return zstdCompressCtx.compressByteArray(array, n, array.length - n, array2, n2, n3);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressUsingDict(final byte[] array, final int n, final byte[] array2, final int n2, final byte[] array3, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.loadDict(array3);
            return zstdCompressCtx.compressByteArray(array, n, array.length - n, array2, n2, array2.length - n2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressDirectByteBufferUsingDict(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final byte[] array, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.loadDict(array);
            return zstdCompressCtx.compressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressFastDict(final byte[] array, final int n, final byte[] array2, final int n2, final int n3, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compressByteArray(array, n, array.length - n, array2, n2, n3);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressFastDict(final byte[] array, final int n, final byte[] array2, final int n2, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compressByteArray(array, n, array.length - n, array2, n2, array2.length - n2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compress(final byte[] array, final byte[] array2, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compress(array, array2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compressDirectByteBufferFastDict(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long decompress(final byte[] array, final byte[] array2) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(array, array2);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static int decompress(final byte[] array, final ByteBuffer byteBuffer) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(array, byteBuffer);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static long decompressByteArray(final byte[] array, final int n, final int n2, final byte[] array2, final int n3, final int n4) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompressByteArray(array, n, n2, array2, n3, n4);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static long decompressDirectByteBuffer(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static native long decompressUnsafe(final long p0, final long p1, final long p2, final long p3);
    
    public static long decompressUsingDict(final byte[] array, final int n, final byte[] array2, final int n2, final int n3, final byte[] array3) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(array3);
            return zstdDecompressCtx.decompressByteArray(array, n, array.length - n, array2, n2, n3);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static long decompressDirectByteBufferUsingDict(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final byte[] array) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(array);
            return zstdDecompressCtx.decompressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static long decompressFastDict(final byte[] array, final int n, final byte[] array2, final int n2, final int n3, final ZstdDictDecompress zstdDictDecompress) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(zstdDictDecompress);
            return zstdDecompressCtx.decompressByteArray(array, n, array.length - n, array2, n2, n3);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static long decompressDirectByteBufferFastDict(final ByteBuffer byteBuffer, final int n, final int n2, final ByteBuffer byteBuffer2, final int n3, final int n4, final ZstdDictDecompress zstdDictDecompress) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(zstdDictDecompress);
            return zstdDecompressCtx.decompressDirectByteBuffer(byteBuffer, n, n2, byteBuffer2, n3, n4);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static native int loadDictDecompress(final long p0, final byte[] p1, final int p2);
    
    public static native int loadFastDictDecompress(final long p0, final ZstdDictDecompress p1);
    
    public static native int loadDictCompress(final long p0, final byte[] p1, final int p2);
    
    public static native int loadFastDictCompress(final long p0, final ZstdDictCompress p1);
    
    public static native void registerSequenceProducer(final long p0, final long p1, final long p2);
    
    static native long getBuiltinSequenceProducer();
    
    static native void generateSequences(final long p0, final long p1, final long p2, final long p3, final long p4);
    
    static native long getStubSequenceProducer();
    
    public static native int setCompressionChecksums(final long p0, final boolean p1);
    
    public static native int setCompressionMagicless(final long p0, final boolean p1);
    
    public static native int setCompressionLevel(final long p0, final int p1);
    
    public static native int setCompressionLong(final long p0, final int p1);
    
    public static native int setCompressionWorkers(final long p0, final int p1);
    
    public static native int setCompressionOverlapLog(final long p0, final int p1);
    
    public static native int setCompressionJobSize(final long p0, final int p1);
    
    public static native int setCompressionTargetLength(final long p0, final int p1);
    
    public static native int setCompressionMinMatch(final long p0, final int p1);
    
    public static native int setCompressionSearchLog(final long p0, final int p1);
    
    public static native int setCompressionChainLog(final long p0, final int p1);
    
    public static native int setCompressionHashLog(final long p0, final int p1);
    
    public static native int setCompressionWindowLog(final long p0, final int p1);
    
    public static native int setCompressionStrategy(final long p0, final int p1);
    
    public static native int setDecompressionLongMax(final long p0, final int p1);
    
    public static native int setDecompressionMagicless(final long p0, final boolean p1);
    
    public static native int setRefMultipleDDicts(final long p0, final boolean p1);
    
    public static native int setValidateSequences(final long p0, final int p1);
    
    public static native int setSequenceProducerFallback(final long p0, final boolean p1);
    
    public static native int setSearchForExternalRepcodes(final long p0, final int p1);
    
    public static native int setEnableLongDistanceMatching(final long p0, final int p1);
    
    public static long findFrameCompressedSize(final byte[] array, final int index, final int n) {
        if (index >= array.length) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        if (index + n > array.length) {
            throw new ArrayIndexOutOfBoundsException(index + n);
        }
        final long frameCompressedSize0 = findFrameCompressedSize0(array, index, n);
        if (isError(frameCompressedSize0)) {
            throw new ZstdException(frameCompressedSize0);
        }
        return frameCompressedSize0;
    }
    
    private static native long findFrameCompressedSize0(final byte[] p0, final int p1, final int p2);
    
    public static long findFrameCompressedSize(final byte[] array, final int n) {
        return findFrameCompressedSize(array, n, array.length - n);
    }
    
    public static long findFrameCompressedSize(final byte[] array) {
        return findFrameCompressedSize(array, 0);
    }
    
    public static long findFrameCompressedSize(final ByteBuffer byteBuffer) {
        return findDirectByteBufferFrameCompressedSize(byteBuffer, byteBuffer.position(), byteBuffer.limit() - byteBuffer.position());
    }
    
    public static native long findDirectByteBufferFrameCompressedSize(final ByteBuffer p0, final int p1, final int p2);
    
    public static long getFrameContentSize(final byte[] array, final int index, final int n, final boolean b) {
        if (index >= array.length) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        if (index + n > array.length) {
            throw new ArrayIndexOutOfBoundsException(index + n);
        }
        return getFrameContentSize0(array, index, n, b);
    }
    
    private static native long getFrameContentSize0(final byte[] p0, final int p1, final int p2, final boolean p3);
    
    @Deprecated
    public static long decompressedSize(final byte[] array, final int index, final int n, final boolean b) {
        if (index >= array.length) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        if (index + n > array.length) {
            throw new ArrayIndexOutOfBoundsException(index + n);
        }
        return decompressedSize0(array, index, n, b);
    }
    
    private static native long decompressedSize0(final byte[] p0, final int p1, final int p2, final boolean p3);
    
    public static long getFrameContentSize(final byte[] array, final int n, final int n2) {
        return getFrameContentSize(array, n, n2, false);
    }
    
    @Deprecated
    public static long decompressedSize(final byte[] array, final int n, final int n2) {
        return decompressedSize(array, n, n2, false);
    }
    
    public static long getFrameContentSize(final byte[] array, final int n) {
        return getFrameContentSize(array, n, array.length - n);
    }
    
    @Deprecated
    public static long decompressedSize(final byte[] array, final int n) {
        return decompressedSize(array, n, array.length - n);
    }
    
    public static long getFrameContentSize(final byte[] array) {
        return getFrameContentSize(array, 0);
    }
    
    @Deprecated
    public static long decompressedSize(final byte[] array) {
        return decompressedSize(array, 0);
    }
    
    @Deprecated
    public static native long decompressedDirectByteBufferSize(final ByteBuffer p0, final int p1, final int p2, final boolean p3);
    
    public static native long getDirectByteBufferFrameContentSize(final ByteBuffer p0, final int p1, final int p2, final boolean p3);
    
    @Deprecated
    public static long decompressedDirectByteBufferSize(final ByteBuffer byteBuffer, final int n, final int n2) {
        return decompressedDirectByteBufferSize(byteBuffer, n, n2, false);
    }
    
    public static long getDirectByteBufferFrameContentSize(final ByteBuffer byteBuffer, final int n, final int n2) {
        return getDirectByteBufferFrameContentSize(byteBuffer, n, n2, false);
    }
    
    public static native long compressBound(final long p0);
    
    public static native boolean isError(final long p0);
    
    public static native String getErrorName(final long p0);
    
    public static native long getErrorCode(final long p0);
    
    public static native long errNoError();
    
    public static native long errGeneric();
    
    public static native long errPrefixUnknown();
    
    public static native long errVersionUnsupported();
    
    public static native long errFrameParameterUnsupported();
    
    public static native long errFrameParameterWindowTooLarge();
    
    public static native long errCorruptionDetected();
    
    public static native long errChecksumWrong();
    
    public static native long errDictionaryCorrupted();
    
    public static native long errDictionaryWrong();
    
    public static native long errDictionaryCreationFailed();
    
    public static native long errParameterUnsupported();
    
    public static native long errParameterOutOfBound();
    
    public static native long errTableLogTooLarge();
    
    public static native long errMaxSymbolValueTooLarge();
    
    public static native long errMaxSymbolValueTooSmall();
    
    public static native long errStageWrong();
    
    public static native long errInitMissing();
    
    public static native long errMemoryAllocation();
    
    public static native long errWorkSpaceTooSmall();
    
    public static native long errDstSizeTooSmall();
    
    public static native long errSrcSizeWrong();
    
    public static native long errDstBufferNull();
    
    public static long trainFromBuffer(final byte[][] array, final byte[] array2, final boolean b) {
        return trainFromBuffer(array, array2, b, defaultCompressionLevel());
    }
    
    public static long trainFromBuffer(final byte[][] array, final byte[] array2, final boolean b, final int n) {
        if (array.length <= 10) {
            throw new ZstdException(errGeneric(), "nb of samples too low");
        }
        return trainFromBuffer0(array, array2, b, n);
    }
    
    private static native long trainFromBuffer0(final byte[][] p0, final byte[] p1, final boolean p2, final int p3);
    
    public static long trainFromBufferDirect(final ByteBuffer byteBuffer, final int[] array, final ByteBuffer byteBuffer2, final boolean b) {
        return trainFromBufferDirect(byteBuffer, array, byteBuffer2, b, defaultCompressionLevel());
    }
    
    public static long trainFromBufferDirect(final ByteBuffer byteBuffer, final int[] array, final ByteBuffer byteBuffer2, final boolean b, final int n) {
        if (array.length <= 10) {
            throw new ZstdException(errGeneric(), "nb of samples too low");
        }
        return trainFromBufferDirect0(byteBuffer, array, byteBuffer2, b, n);
    }
    
    private static native long trainFromBufferDirect0(final ByteBuffer p0, final int[] p1, final ByteBuffer p2, final boolean p3, final int p4);
    
    public static native long getDictIdFromFrame(final byte[] p0);
    
    public static native long getDictIdFromFrameBuffer(final ByteBuffer p0);
    
    public static native long getDictIdFromDict(final byte[] p0);
    
    private static native long getDictIdFromDictDirect(final ByteBuffer p0, final int p1, final int p2);
    
    public static long getDictIdFromDictDirect(final ByteBuffer byteBuffer) {
        final int n = byteBuffer.limit() - byteBuffer.position();
        if (!byteBuffer.isDirect()) {
            throw new IllegalArgumentException("dict must be a direct buffer");
        }
        if (n < 0) {
            throw new IllegalArgumentException("dict cannot be empty.");
        }
        return getDictIdFromDictDirect(byteBuffer, byteBuffer.position(), n);
    }
    
    public static long trainFromBuffer(final byte[][] array, final byte[] array2) {
        return trainFromBuffer(array, array2, false);
    }
    
    public static long trainFromBufferDirect(final ByteBuffer byteBuffer, final int[] array, final ByteBuffer byteBuffer2) {
        return trainFromBufferDirect(byteBuffer, array, byteBuffer2, false);
    }
    
    public static native int magicNumber();
    
    public static native int windowLogMin();
    
    public static native int windowLogMax();
    
    public static native int chainLogMin();
    
    public static native int chainLogMax();
    
    public static native int hashLogMin();
    
    public static native int hashLogMax();
    
    public static native int searchLogMin();
    
    public static native int searchLogMax();
    
    public static native int searchLengthMin();
    
    public static native int searchLengthMax();
    
    public static native int blockSizeMax();
    
    public static native int defaultCompressionLevel();
    
    public static native int minCompressionLevel();
    
    public static native int maxCompressionLevel();
    
    public static byte[] compress(final byte[] array) {
        return compress(array, defaultCompressionLevel());
    }
    
    public static byte[] compress(final byte[] array, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            return zstdCompressCtx.compress(array);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static int compress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2) {
        return compress(byteBuffer, byteBuffer2, defaultCompressionLevel());
    }
    
    public static int compress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final int level, final boolean checksum) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            zstdCompressCtx.setChecksum(checksum);
            return zstdCompressCtx.compress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static int compress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final int n) {
        return compress(byteBuffer, byteBuffer2, n, false);
    }
    
    public static ByteBuffer compress(final ByteBuffer byteBuffer, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.setLevel(level);
            return zstdCompressCtx.compress(byteBuffer);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static byte[] compress(final byte[] array, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compress(array);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    @Deprecated
    public static long compressUsingDict(final byte[] array, final byte[] array2, final byte[] array3, final int n) {
        return compressUsingDict(array, 0, array2, 0, array2.length, array3, n);
    }
    
    public static byte[] compressUsingDict(final byte[] array, final byte[] array2, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(array2);
            zstdCompressCtx.setLevel(level);
            return zstdCompressCtx.compress(array);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static long compress(final byte[] array, final byte[] array2, final byte[] array3, final int n) {
        return compressUsingDict(array, 0, array2, 0, array2.length, array3, n);
    }
    
    public static int compress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final byte[] array, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(array);
            zstdCompressCtx.setLevel(level);
            return zstdCompressCtx.compress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static ByteBuffer compress(final ByteBuffer byteBuffer, final byte[] array, final int level) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(array);
            zstdCompressCtx.setLevel(level);
            return zstdCompressCtx.compress(byteBuffer);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static int compress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static ByteBuffer compress(final ByteBuffer byteBuffer, final ZstdDictCompress zstdDictCompress) {
        final ZstdCompressCtx zstdCompressCtx = new ZstdCompressCtx();
        try {
            zstdCompressCtx.loadDict(zstdDictCompress);
            zstdCompressCtx.setLevel(zstdDictCompress.level());
            return zstdCompressCtx.compress(byteBuffer);
        }
        finally {
            zstdCompressCtx.close();
        }
    }
    
    public static byte[] decompress(final byte[] array, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(array, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static byte[] decompress(final byte[] array) {
        final ArrayList list = new ArrayList();
        final byte[] array2 = new byte[calculateContentSizeAndFrames(array, list)];
        int n = 0;
        int n2 = 0;
        for (int i = 0; i < list.size(); ++i) {
            final FrameData frameData = (FrameData)list.get(i);
            final long decompressByteArray = decompressByteArray(array2, n2, (int)frameData.contentSize, array, n, (int)frameData.compressedSize);
            if (isError(decompressByteArray)) {
                throw new ZstdException(decompressByteArray, String.format("error %s while decompressing %d frame", getErrorName(decompressByteArray), i));
            }
            if (decompressByteArray != frameData.contentSize) {
                throw new IllegalStateException("decompressed size mismatch");
            }
            n += (int)frameData.compressedSize;
            n2 += (int)frameData.contentSize;
        }
        return array2;
    }
    
    private static int calculateContentSizeAndFrames(final byte[] array, final List<FrameData> list) {
        int n = 0;
        FrameData frameData;
        for (int i = 0; i < array.length; i += (int)frameData.compressedSize, n += (int)frameData.contentSize) {
            frameData = new FrameData(array, i);
            list.add(frameData);
        }
        return n;
    }
    
    public static byte[] decompressFrame(final byte[] array, final int n, final int n2, final int n3) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(array, n, n2, n3);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static byte[] decompressFrame(final byte[] array, final int n) {
        final int n2 = (int)findFrameCompressedSize(array, n);
        final long frameContentSize = getFrameContentSize(array, n, n2);
        if (!isError(frameContentSize)) {
            return decompressFrame(array, n, n2, (int)frameContentSize);
        }
        if (frameContentSize == -1L) {
            throw new ZstdException(frameContentSize, "Content size is unknown");
        }
        throw new ZstdException(frameContentSize);
    }
    
    public static byte[] decompressFrame(final byte[] array) {
        return decompressFrame(array, 0);
    }
    
    public static int decompress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static int decompress(final ByteBuffer byteBuffer, final byte[] array) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(byteBuffer, array);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static ByteBuffer decompress(final ByteBuffer byteBuffer, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            return zstdDecompressCtx.decompress(byteBuffer, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static byte[] decompress(final byte[] array, final ZstdDictDecompress zstdDictDecompress, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(zstdDictDecompress);
            return zstdDecompressCtx.decompress(array, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    @Deprecated
    public static long decompressUsingDict(final byte[] array, final byte[] array2, final byte[] array3) {
        return decompressUsingDict(array, 0, array2, 0, array2.length, array3);
    }
    
    public static long decompress(final byte[] array, final byte[] array2, final byte[] array3) {
        return decompressUsingDict(array, 0, array2, 0, array2.length, array3);
    }
    
    public static byte[] decompress(final byte[] array, final byte[] array2, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(array2);
            return zstdDecompressCtx.decompress(array, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    @Deprecated
    public static long decompressedSize(final ByteBuffer byteBuffer) {
        return decompressedDirectByteBufferSize(byteBuffer, byteBuffer.position(), byteBuffer.limit() - byteBuffer.position());
    }
    
    public static long getFrameContentSize(final ByteBuffer byteBuffer) {
        return getDirectByteBufferFrameContentSize(byteBuffer, byteBuffer.position(), byteBuffer.limit() - byteBuffer.position());
    }
    
    public static int decompress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final byte[] array) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(array);
            return zstdDecompressCtx.decompress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static ByteBuffer decompress(final ByteBuffer byteBuffer, final byte[] array, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(array);
            return zstdDecompressCtx.decompress(byteBuffer, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static int decompress(final ByteBuffer byteBuffer, final ByteBuffer byteBuffer2, final ZstdDictDecompress zstdDictDecompress) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(zstdDictDecompress);
            return zstdDecompressCtx.decompress(byteBuffer, byteBuffer2);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    public static ByteBuffer decompress(final ByteBuffer byteBuffer, final ZstdDictDecompress zstdDictDecompress, final int n) {
        final ZstdDecompressCtx zstdDecompressCtx = new ZstdDecompressCtx();
        try {
            zstdDecompressCtx.loadDict(zstdDictDecompress);
            return zstdDecompressCtx.decompress(byteBuffer, n);
        }
        finally {
            zstdDecompressCtx.close();
        }
    }
    
    static ByteBuffer getArrayBackedBuffer(final BufferPool bufferPool, final int i) throws ZstdIOException {
        final ByteBuffer value = bufferPool.get(i);
        if (value == null) {
            throw new ZstdIOException(errMemoryAllocation(), "Cannot get ByteBuffer of size " + i + " from the BufferPool");
        }
        if (!value.hasArray() || value.arrayOffset() != 0) {
            bufferPool.release(value);
            throw new IllegalArgumentException("provided ByteBuffer lacks array or has non-zero arrayOffset");
        }
        return value;
    }
    
    static {
        Native.load();
    }
    
    public enum ParamSwitch
    {
        AUTO(0), 
        ENABLE(1), 
        DISABLE(2);
        
        private int val;
        
        private ParamSwitch(final int val) {
            this.val = val;
        }
        
        public int getValue() {
            return this.val;
        }
    }
    
    private static class FrameData
    {
        final long contentSize;
        final long compressedSize;
        
        FrameData(final byte[] array, final int n) {
            this.compressedSize = Zstd.findFrameCompressedSize(array, n);
            this.contentSize = Zstd.getFrameContentSize(array, n, (int)this.compressedSize);
            if (!Zstd.isError(this.contentSize)) {
                return;
            }
            if (this.contentSize == -1L) {
                throw new ZstdException(this.contentSize, "Content size is unknown");
            }
            throw new ZstdException(this.contentSize);
        }
    }
}
