1package org.bouncycastle.asn1;
2
3import java.io.ByteArrayInputStream;
4import java.io.IOException;
5import java.io.InputStream;
6
7import org.bouncycastle.util.Arrays;
8import org.bouncycastle.util.encoders.Hex;
9
10public abstract class ASN1OctetString
11    extends ASN1Primitive
12    implements ASN1OctetStringParser
13{
14    byte[]  string;
15
16    /**
17     * return an Octet String from a tagged object.
18     *
19     * @param obj the tagged object holding the object we want.
20     * @param explicit true if the object is meant to be explicitly
21     *              tagged false otherwise.
22     * @exception IllegalArgumentException if the tagged object cannot
23     *              be converted.
24     */
25    public static ASN1OctetString getInstance(
26        ASN1TaggedObject    obj,
27        boolean             explicit)
28    {
29        ASN1Primitive o = obj.getObject();
30
31        if (explicit || o instanceof ASN1OctetString)
32        {
33            return getInstance(o);
34        }
35        else
36        {
37            return BEROctetString.fromSequence(ASN1Sequence.getInstance(o));
38        }
39    }
40
41    /**
42     * return an Octet String from the given object.
43     *
44     * @param obj the object we want converted.
45     * @exception IllegalArgumentException if the object cannot be converted.
46     */
47    public static ASN1OctetString getInstance(
48        Object  obj)
49    {
50        if (obj == null || obj instanceof ASN1OctetString)
51        {
52            return (ASN1OctetString)obj;
53        }
54        else if (obj instanceof byte[])
55        {
56            try
57            {
58                return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
59            }
60            catch (IOException e)
61            {
62                throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
63            }
64        }
65        else if (obj instanceof ASN1Encodable)
66        {
67            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
68
69            if (primitive instanceof ASN1OctetString)
70            {
71                return (ASN1OctetString)primitive;
72            }
73        }
74
75        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
76    }
77
78    /**
79     * @param string the octets making up the octet string.
80     */
81    public ASN1OctetString(
82        byte[]  string)
83    {
84        if (string == null)
85        {
86            throw new NullPointerException("string cannot be null");
87        }
88        this.string = string;
89    }
90
91    public InputStream getOctetStream()
92    {
93        return new ByteArrayInputStream(string);
94    }
95
96    public ASN1OctetStringParser parser()
97    {
98        return this;
99    }
100
101    public byte[] getOctets()
102    {
103        return string;
104    }
105
106    public int hashCode()
107    {
108        return Arrays.hashCode(this.getOctets());
109    }
110
111    boolean asn1Equals(
112        ASN1Primitive o)
113    {
114        if (!(o instanceof ASN1OctetString))
115        {
116            return false;
117        }
118
119        ASN1OctetString  other = (ASN1OctetString)o;
120
121        return Arrays.areEqual(string, other.string);
122    }
123
124    public ASN1Primitive getLoadedObject()
125    {
126        return this.toASN1Primitive();
127    }
128
129    ASN1Primitive toDERObject()
130    {
131        return new DEROctetString(string);
132    }
133
134    ASN1Primitive toDLObject()
135    {
136        return new DEROctetString(string);
137    }
138
139    abstract void encode(ASN1OutputStream out)
140        throws IOException;
141
142    public String toString()
143    {
144      return "#"+new String(Hex.encode(string));
145    }
146}
147