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

package com.github.luben.zstd;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.io.Closeable;

public abstract class BaseZstdBufferDecompressingStreamNoFinalizer implements Closeable
{
    protected long stream;
    protected ByteBuffer source;
    protected boolean closed;
    private boolean finishedFrame;
    private boolean streamEnd;
    private int consumed;
    private int produced;
    
    BaseZstdBufferDecompressingStreamNoFinalizer(final ByteBuffer source) {
        this.closed = false;
        this.finishedFrame = false;
        this.streamEnd = false;
        this.source = source;
    }
    
    protected ByteBuffer refill(final ByteBuffer byteBuffer) {
        return byteBuffer;
    }
    
    public boolean hasRemaining() {
        return !this.streamEnd && (this.source.hasRemaining() || !this.finishedFrame);
    }
    
    public BaseZstdBufferDecompressingStreamNoFinalizer setDict(final byte[] array) throws IOException {
        final long n = Zstd.loadDictDecompress(this.stream, array, array.length);
        if (Zstd.isError(n)) {
            throw new ZstdIOException(n);
        }
        return this;
    }
    
    public BaseZstdBufferDecompressingStreamNoFinalizer setDict(final ZstdDictDecompress zstdDictDecompress) throws IOException {
        zstdDictDecompress.acquireSharedLock();
        try {
            final long n = Zstd.loadFastDictDecompress(this.stream, zstdDictDecompress);
            if (Zstd.isError(n)) {
                throw new ZstdIOException(n);
            }
        }
        finally {
            zstdDictDecompress.releaseSharedLock();
        }
        return this;
    }
    
    public BaseZstdBufferDecompressingStreamNoFinalizer setLongMax(final int n) throws IOException {
        final long n2 = Zstd.setDecompressionLongMax(this.stream, n);
        if (Zstd.isError(n2)) {
            throw new ZstdIOException(n2);
        }
        return this;
    }
    
    int readInternal(final ByteBuffer byteBuffer, final boolean b) throws IOException {
        if (this.closed) {
            throw new IOException("Stream closed");
        }
        if (this.streamEnd) {
            return 0;
        }
        final long decompressStream = this.decompressStream(this.stream, byteBuffer, byteBuffer.position(), byteBuffer.remaining(), this.source, this.source.position(), this.source.remaining());
        if (Zstd.isError(decompressStream)) {
            throw new ZstdIOException(decompressStream);
        }
        this.source.position();
        byteBuffer.position();
        if (!this.source.hasRemaining()) {
            this.source = this.refill(this.source);
            if (!b && this.source.isDirect()) {
                throw new IllegalArgumentException("Source buffer should be a non-direct buffer");
            }
            if (b && !this.source.isDirect()) {
                throw new IllegalArgumentException("Source buffer should be a direct buffer");
            }
        }
        this.finishedFrame = (decompressStream == 0L);
        if (this.finishedFrame) {
            this.streamEnd = !this.source.hasRemaining();
        }
        return this.produced;
    }
    
    @Override
    public void close() {
        if (!this.closed) {
            try {
                this.freeDStream(this.stream);
            }
            finally {
                this.closed = true;
                this.source = null;
            }
        }
    }
    
    public abstract int read(final ByteBuffer p0) throws IOException;
    
    abstract long createDStream();
    
    abstract long freeDStream(final long p0);
    
    abstract long initDStream(final long p0);
    
    abstract long decompressStream(final long p0, final ByteBuffer p1, final int p2, final int p3, final ByteBuffer p4, final int p5, final int p6);
}
