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

package org.bouncycastle.asn1;

import java.io.IOException;
import org.bouncycastle.util.Arrays;

public abstract class ASN1UniversalString extends ASN1Primitive implements ASN1String
{
    static final ASN1UniversalType TYPE;
    private static final char[] table;
    final byte[] contents;
    
    public static ASN1UniversalString getInstance(final Object o) {
        if (o == null || o instanceof ASN1UniversalString) {
            return (ASN1UniversalString)o;
        }
        if (o instanceof ASN1Encodable) {
            final ASN1Primitive asn1Primitive = ((ASN1Encodable)o).toASN1Primitive();
            if (asn1Primitive instanceof ASN1UniversalString) {
                return (ASN1UniversalString)asn1Primitive;
            }
        }
        if (o instanceof byte[]) {
            try {
                return (ASN1UniversalString)ASN1UniversalString.TYPE.fromByteArray((byte[])o);
            }
            catch (final Exception ex) {
                throw new IllegalArgumentException("encoding error getInstance: " + ex.toString());
            }
        }
        throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
    }
    
    public static ASN1UniversalString getInstance(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return (ASN1UniversalString)ASN1UniversalString.TYPE.getContextTagged(asn1TaggedObject, b);
    }
    
    public static ASN1UniversalString getTagged(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return (ASN1UniversalString)ASN1UniversalString.TYPE.getTagged(asn1TaggedObject, b);
    }
    
    ASN1UniversalString(final byte[] array, final boolean b) {
        this.contents = (b ? Arrays.clone(array) : array);
    }
    
    @Override
    public final String getString() {
        final int length = this.contents.length;
        final StringBuilder sb = new StringBuilder(3 + 2 * (ASN1OutputStream.getLengthOfDL(length) + length));
        sb.append("#1C");
        encodeHexDL(sb, length);
        for (int i = 0; i < length; ++i) {
            encodeHexByte(sb, this.contents[i]);
        }
        return sb.toString();
    }
    
    @Override
    public String toString() {
        return this.getString();
    }
    
    public final byte[] getOctets() {
        return Arrays.clone(this.contents);
    }
    
    @Override
    final boolean encodeConstructed() {
        return false;
    }
    
    @Override
    final int encodedLength(final boolean b) {
        return ASN1OutputStream.getLengthOfEncodingDL(b, this.contents.length);
    }
    
    @Override
    final void encode(final ASN1OutputStream asn1OutputStream, final boolean b) throws IOException {
        asn1OutputStream.writeEncodingDL(b, 28, this.contents);
    }
    
    @Override
    final boolean asn1Equals(final ASN1Primitive asn1Primitive) {
        return asn1Primitive instanceof ASN1UniversalString && Arrays.areEqual(this.contents, ((ASN1UniversalString)asn1Primitive).contents);
    }
    
    @Override
    public final int hashCode() {
        return Arrays.hashCode(this.contents);
    }
    
    static ASN1UniversalString createPrimitive(final byte[] array) {
        return new DERUniversalString(array, false);
    }
    
    private static void encodeHexByte(final StringBuilder sb, final int n) {
        sb.append(ASN1UniversalString.table[n >>> 4 & 0xF]);
        sb.append(ASN1UniversalString.table[n & 0xF]);
    }
    
    private static void encodeHexDL(final StringBuilder sb, int i) {
        if (i < 128) {
            encodeHexByte(sb, i);
            return;
        }
        final byte[] array = new byte[5];
        int j = 5;
        do {
            array[--j] = (byte)i;
            i >>>= 8;
        } while (i != 0);
        array[--j] = (byte)(0x80 | array.length - j);
        do {
            encodeHexByte(sb, array[j++]);
        } while (j < array.length);
    }
    
    static {
        TYPE = new ASN1UniversalType(28) {
            @Override
            ASN1Primitive fromImplicitPrimitive(final DEROctetString derOctetString) {
                return ASN1UniversalString.createPrimitive(derOctetString.getOctets());
            }
        };
        table = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    }
}
