001package org.apache.commons.ssl.org.bouncycastle.asn1;
002
003import java.io.IOException;
004
005import org.bouncycastle.util.Arrays;
006import org.bouncycastle.util.Strings;
007
008/**
009 * DER T61String (also the teletex string) - a "modern" encapsulation that uses UTF-8. If at all possible, avoid this one! It's only for emergencies.
010 * Use UTF8String instead.
011 */
012public class DERT61UTF8String
013    extends ASN1Primitive
014    implements ASN1String
015{
016    private byte[] string;
017
018    /**
019     * return a T61 string from the passed in object. UTF-8 Encoding is assumed in this case.
020     *
021     * @param obj a DERT61UTF8String or an object that can be converted into one.
022     * @throws IllegalArgumentException if the object cannot be converted.
023     * @return a DERT61UTF8String instance, or null
024     */
025    public static DERT61UTF8String getInstance(
026        Object obj)
027    {
028        if (obj instanceof DERT61String)
029        {
030            return new DERT61UTF8String(((DERT61String)obj).getOctets());
031        }
032
033        if (obj == null || obj instanceof DERT61UTF8String)
034        {
035            return (DERT61UTF8String)obj;
036        }
037
038        if (obj instanceof byte[])
039        {
040            try
041            {
042                return new DERT61UTF8String(((DERT61String)fromByteArray((byte[])obj)).getOctets());
043            }
044            catch (Exception e)
045            {
046                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
047            }
048        }
049
050        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
051    }
052
053    /**
054     * return an T61 String from a tagged object. UTF-8 encoding is assumed in this case.
055     *
056     * @param obj      the tagged object holding the object we want
057     * @param explicit true if the object is meant to be explicitly
058     *                 tagged false otherwise.
059     * @throws IllegalArgumentException if the tagged object cannot
060     * be converted.
061     * @return a DERT61UTF8String instance, or null
062     */
063    public static DERT61UTF8String getInstance(
064        ASN1TaggedObject obj,
065        boolean explicit)
066    {
067        ASN1Primitive o = obj.getObject();
068
069        if (explicit || o instanceof DERT61String || o instanceof DERT61UTF8String)
070        {
071            return getInstance(o);
072        }
073        else
074        {
075            return new DERT61UTF8String(ASN1OctetString.getInstance(o).getOctets());
076        }
077    }
078
079    /**
080     * basic constructor - string encoded as a sequence of bytes.
081     */
082    public DERT61UTF8String(
083        byte[] string)
084    {
085        this.string = string;
086    }
087
088    /**
089     * basic constructor - with string UTF8 conversion assumed.
090     */
091    public DERT61UTF8String(
092        String string)
093    {
094        this(Strings.toUTF8ByteArray(string));
095    }
096
097    /**
098     * Decode the encoded string and return it, UTF8 assumed.
099     *
100     * @return the decoded String
101     */
102    public String getString()
103    {
104        return Strings.fromUTF8ByteArray(string);
105    }
106
107    public String toString()
108    {
109        return getString();
110    }
111
112    boolean isConstructed()
113    {
114        return false;
115    }
116
117    int encodedLength()
118    {
119        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
120    }
121
122    void encode(
123        ASN1OutputStream out)
124        throws IOException
125    {
126        out.writeEncoded(BERTags.T61_STRING, string);
127    }
128
129    /**
130     * Return the encoded string as a byte array.
131     *
132     * @return the actual bytes making up the encoded body of the T61 string.
133     */
134    public byte[] getOctets()
135    {
136        return Arrays.clone(string);
137    }
138
139    boolean asn1Equals(
140        ASN1Primitive o)
141    {
142        if (!(o instanceof DERT61UTF8String))
143        {
144            return false;
145        }
146
147        return Arrays.areEqual(string, ((DERT61UTF8String)o).string);
148    }
149
150    public int hashCode()
151    {
152        return Arrays.hashCode(string);
153    }
154}