001package org.apache.commons.ssl.org.bouncycastle.asn1;
002
003import java.io.ByteArrayOutputStream;
004import java.io.IOException;
005
006import org.bouncycastle.util.Arrays;
007
008/**
009 * DER UniversalString object.
010 */
011public class DERUniversalString
012    extends ASN1Primitive
013    implements ASN1String
014{
015    private static final char[]  table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
016    private byte[] string;
017    
018    /**
019     * return a Universal String from the passed in object.
020     *
021     * @param obj a DERUniversalString or an object that can be converted into one.
022     * @exception IllegalArgumentException if the object cannot be converted.
023     * @return a DERUniversalString instance, or null
024     */
025    public static DERUniversalString getInstance(
026        Object  obj)
027    {
028        if (obj == null || obj instanceof DERUniversalString)
029        {
030            return (DERUniversalString)obj;
031        }
032
033        if (obj instanceof byte[])
034        {
035            try
036            {
037                return (DERUniversalString)fromByteArray((byte[])obj);
038            }
039            catch (Exception e)
040            {
041                throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
042            }
043        }
044
045        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
046    }
047
048    /**
049     * return a Universal String from a tagged object.
050     *
051     * @param obj the tagged object holding the object we want
052     * @param explicit true if the object is meant to be explicitly
053     *              tagged false otherwise.
054     * @exception IllegalArgumentException if the tagged object cannot
055     *               be converted.
056     * @return a DERUniversalString instance, or null
057     */
058    public static DERUniversalString getInstance(
059        ASN1TaggedObject obj,
060        boolean          explicit)
061    {
062        ASN1Primitive o = obj.getObject();
063
064        if (explicit || o instanceof DERUniversalString)
065        {
066            return getInstance(o);
067        }
068        else
069        {
070            return new DERUniversalString(((ASN1OctetString)o).getOctets());
071        }
072    }
073
074    /**
075     * basic constructor - byte encoded string.
076     */
077    public DERUniversalString(
078        byte[]   string)
079    {
080        this.string = string;
081    }
082
083    public String getString()
084    {
085        StringBuffer    buf = new StringBuffer("#");
086        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
087        ASN1OutputStream            aOut = new ASN1OutputStream(bOut);
088        
089        try
090        {
091            aOut.writeObject(this);
092        }
093        catch (IOException e)
094        {
095           throw new RuntimeException("internal error encoding BitString");
096        }
097        
098        byte[]    string = bOut.toByteArray();
099        
100        for (int i = 0; i != string.length; i++)
101        {
102            buf.append(table[(string[i] >>> 4) & 0xf]);
103            buf.append(table[string[i] & 0xf]);
104        }
105        
106        return buf.toString();
107    }
108
109    public String toString()
110    {
111        return getString();
112    }
113
114    public byte[] getOctets()
115    {
116        return string;
117    }
118
119    boolean isConstructed()
120    {
121        return false;
122    }
123
124    int encodedLength()
125    {
126        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
127    }
128
129    void encode(
130        ASN1OutputStream out)
131        throws IOException
132    {
133        out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets());
134    }
135    
136    boolean asn1Equals(
137        ASN1Primitive o)
138    {
139        if (!(o instanceof DERUniversalString))
140        {
141            return false;
142        }
143
144        return Arrays.areEqual(string, ((DERUniversalString)o).string);
145    }
146    
147    public int hashCode()
148    {
149        return Arrays.hashCode(string);
150    }
151}