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

package org.bouncycastle.asn1;

import org.bouncycastle.util.io.Streams;
import java.io.IOException;
import java.io.EOFException;
import java.io.InputStream;

class DefiniteLengthInputStream extends LimitedInputStream
{
    private static final byte[] EMPTY_BYTES;
    private final int _originalLength;
    private int _remaining;
    
    DefiniteLengthInputStream(final InputStream inputStream, final int n, final int n2) {
        super(inputStream, n2);
        if (n <= 0) {
            if (n < 0) {
                throw new IllegalArgumentException("negative lengths not allowed");
            }
            this.setParentEofDetect(true);
        }
        this._originalLength = n;
        this._remaining = n;
    }
    
    int getRemaining() {
        return this._remaining;
    }
    
    @Override
    public int read() throws IOException {
        if (this._remaining == 0) {
            return -1;
        }
        final int read = this._in.read();
        if (read < 0) {
            throw new EOFException("DEF length " + this._originalLength + " object truncated by " + this._remaining);
        }
        if (--this._remaining == 0) {
            this.setParentEofDetect(true);
        }
        return read;
    }
    
    @Override
    public int read(final byte[] b, final int off, final int a) throws IOException {
        if (this._remaining == 0) {
            return -1;
        }
        final int read = this._in.read(b, off, Math.min(a, this._remaining));
        if (read < 0) {
            throw new EOFException("DEF length " + this._originalLength + " object truncated by " + this._remaining);
        }
        if ((this._remaining -= read) == 0) {
            this.setParentEofDetect(true);
        }
        return read;
    }
    
    void readAllIntoByteArray(final byte[] array) throws IOException {
        if (this._remaining != array.length) {
            throw new IllegalArgumentException("buffer length not right for data");
        }
        if (this._remaining == 0) {
            return;
        }
        final int limit = this.getLimit();
        if (this._remaining >= limit) {
            throw new IOException("corrupted stream - out of bounds length found: " + this._remaining + " >= " + limit);
        }
        if ((this._remaining -= Streams.readFully(this._in, array, 0, array.length)) != 0) {
            throw new EOFException("DEF length " + this._originalLength + " object truncated by " + this._remaining);
        }
        this.setParentEofDetect(true);
    }
    
    byte[] toByteArray() throws IOException {
        if (this._remaining == 0) {
            return DefiniteLengthInputStream.EMPTY_BYTES;
        }
        final int limit = this.getLimit();
        if (this._remaining >= limit) {
            throw new IOException("corrupted stream - out of bounds length found: " + this._remaining + " >= " + limit);
        }
        final byte[] array = new byte[this._remaining];
        if ((this._remaining -= Streams.readFully(this._in, array, 0, array.length)) != 0) {
            throw new EOFException("DEF length " + this._originalLength + " object truncated by " + this._remaining);
        }
        this.setParentEofDetect(true);
        return array;
    }
    
    static {
        EMPTY_BYTES = new byte[0];
    }
}
