1package org.bouncycastle.asn1;
2
3import java.io.ByteArrayOutputStream;
4import java.io.IOException;
5
6import org.bouncycastle.util.Arrays;
7
8/**
9 * DER UniversalString object.
10 */
11public class DERUniversalString
12    extends ASN1Primitive
13    implements ASN1String
14{
15    private static final char[]  table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
16    private final byte[] string;
17
18    /**
19     * return a Universal String from the passed in object.
20     *
21     * @param obj a DERUniversalString or an object that can be converted into one.
22     * @exception IllegalArgumentException if the object cannot be converted.
23     * @return a DERUniversalString instance, or null
24     */
25    public static DERUniversalString getInstance(
26        Object  obj)
27    {
28        if (obj == null || obj instanceof DERUniversalString)
29        {
30            return (DERUniversalString)obj;
31        }
32
33        if (obj instanceof byte[])
34        {
35            try
36            {
37                return (DERUniversalString)fromByteArray((byte[])obj);
38            }
39            catch (Exception e)
40            {
41                throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
42            }
43        }
44
45        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
46    }
47
48    /**
49     * return a Universal String from a tagged object.
50     *
51     * @param obj the tagged object holding the object we want
52     * @param explicit true if the object is meant to be explicitly
53     *              tagged false otherwise.
54     * @exception IllegalArgumentException if the tagged object cannot
55     *               be converted.
56     * @return a DERUniversalString instance, or null
57     */
58    public static DERUniversalString getInstance(
59        ASN1TaggedObject obj,
60        boolean          explicit)
61    {
62        ASN1Primitive o = obj.getObject();
63
64        if (explicit || o instanceof DERUniversalString)
65        {
66            return getInstance(o);
67        }
68        else
69        {
70            return new DERUniversalString(((ASN1OctetString)o).getOctets());
71        }
72    }
73
74    /**
75     * basic constructor - byte encoded string.
76     *
77     * @param string the byte encoding of the string to be carried in the UniversalString object,
78     */
79    public DERUniversalString(
80        byte[]   string)
81    {
82        this.string = string;
83    }
84
85    public String getString()
86    {
87        StringBuffer    buf = new StringBuffer("#");
88        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
89        ASN1OutputStream            aOut = new ASN1OutputStream(bOut);
90
91        try
92        {
93            aOut.writeObject(this);
94        }
95        catch (IOException e)
96        {
97           throw new RuntimeException("internal error encoding BitString");
98        }
99
100        byte[]    string = bOut.toByteArray();
101
102        for (int i = 0; i != string.length; i++)
103        {
104            buf.append(table[(string[i] >>> 4) & 0xf]);
105            buf.append(table[string[i] & 0xf]);
106        }
107
108        return buf.toString();
109    }
110
111    public String toString()
112    {
113        return getString();
114    }
115
116    public byte[] getOctets()
117    {
118        return string;
119    }
120
121    boolean isConstructed()
122    {
123        return false;
124    }
125
126    int encodedLength()
127    {
128        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
129    }
130
131    void encode(
132        ASN1OutputStream out)
133        throws IOException
134    {
135        out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets());
136    }
137
138    boolean asn1Equals(
139        ASN1Primitive o)
140    {
141        if (!(o instanceof DERUniversalString))
142        {
143            return false;
144        }
145
146        return Arrays.areEqual(string, ((DERUniversalString)o).string);
147    }
148
149    public int hashCode()
150    {
151        return Arrays.hashCode(string);
152    }
153}
154