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

package org.bouncycastle.asn1;

public class ASN1EncodableVector
{
    static final ASN1Encodable[] EMPTY_ELEMENTS;
    private static final int DEFAULT_CAPACITY = 10;
    private ASN1Encodable[] elements;
    private int elementCount;
    private boolean copyOnWrite;
    
    public ASN1EncodableVector() {
        this(10);
    }
    
    public ASN1EncodableVector(final int n) {
        if (n < 0) {
            throw new IllegalArgumentException("'initialCapacity' must not be negative");
        }
        this.elements = ((n == 0) ? ASN1EncodableVector.EMPTY_ELEMENTS : new ASN1Encodable[n]);
        this.elementCount = 0;
        this.copyOnWrite = false;
    }
    
    public void add(final ASN1Encodable asn1Encodable) {
        if (null == asn1Encodable) {
            throw new NullPointerException("'element' cannot be null");
        }
        final int length = this.elements.length;
        final int elementCount = this.elementCount + 1;
        if (elementCount > length | this.copyOnWrite) {
            this.reallocate(elementCount);
        }
        this.elements[this.elementCount] = asn1Encodable;
        this.elementCount = elementCount;
    }
    
    public void addOptional(final ASN1Encodable asn1Encodable) {
        if (asn1Encodable != null) {
            this.add(asn1Encodable);
        }
    }
    
    public void addAll(final ASN1Encodable[] array) {
        if (null == array) {
            throw new NullPointerException("'others' cannot be null");
        }
        this.doAddAll(array, "'others' elements cannot be null");
    }
    
    public void addAll(final ASN1EncodableVector asn1EncodableVector) {
        if (null == asn1EncodableVector) {
            throw new NullPointerException("'other' cannot be null");
        }
        this.doAddAll(asn1EncodableVector.elements, "'other' elements cannot be null");
    }
    
    private void doAddAll(final ASN1Encodable[] array, final String s) {
        final int length = array.length;
        if (length < 1) {
            return;
        }
        final int length2 = this.elements.length;
        final int elementCount = this.elementCount + length;
        if (elementCount > length2 | this.copyOnWrite) {
            this.reallocate(elementCount);
        }
        int n = 0;
        do {
            final ASN1Encodable asn1Encodable = array[n];
            if (null == asn1Encodable) {
                throw new NullPointerException(s);
            }
            this.elements[this.elementCount + n] = asn1Encodable;
        } while (++n < length);
        this.elementCount = elementCount;
    }
    
    public ASN1Encodable get(final int i) {
        if (i >= this.elementCount) {
            throw new ArrayIndexOutOfBoundsException(i + " >= " + this.elementCount);
        }
        return this.elements[i];
    }
    
    public int size() {
        return this.elementCount;
    }
    
    ASN1Encodable[] copyElements() {
        if (0 == this.elementCount) {
            return ASN1EncodableVector.EMPTY_ELEMENTS;
        }
        final ASN1Encodable[] array = new ASN1Encodable[this.elementCount];
        System.arraycopy(this.elements, 0, array, 0, this.elementCount);
        return array;
    }
    
    ASN1Encodable[] takeElements() {
        if (0 == this.elementCount) {
            return ASN1EncodableVector.EMPTY_ELEMENTS;
        }
        if (this.elements.length == this.elementCount) {
            this.copyOnWrite = true;
            return this.elements;
        }
        final ASN1Encodable[] array = new ASN1Encodable[this.elementCount];
        System.arraycopy(this.elements, 0, array, 0, this.elementCount);
        return array;
    }
    
    private void reallocate(final int n) {
        final ASN1Encodable[] elements = new ASN1Encodable[Math.max(this.elements.length, n + (n >> 1))];
        System.arraycopy(this.elements, 0, elements, 0, this.elementCount);
        this.elements = elements;
        this.copyOnWrite = false;
    }
    
    static ASN1Encodable[] cloneElements(final ASN1Encodable[] array) {
        return (array.length < 1) ? ASN1EncodableVector.EMPTY_ELEMENTS : array.clone();
    }
    
    static {
        EMPTY_ELEMENTS = new ASN1Encodable[0];
    }
}
