DEREnumerated.java revision 4c111300c39cb2e27f07fc2ae3b00e23ed4443b2
1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4import java.math.BigInteger;
5
6import org.bouncycastle.util.Arrays;
7
8public class DEREnumerated
9    extends ASN1Primitive
10{
11    byte[]      bytes;
12
13    /**
14     * return an integer from the passed in object
15     *
16     * @exception IllegalArgumentException if the object cannot be converted.
17     */
18    public static ASN1Enumerated getInstance(
19        Object  obj)
20    {
21        if (obj == null || obj instanceof ASN1Enumerated)
22        {
23            return (ASN1Enumerated)obj;
24        }
25
26        if (obj instanceof DEREnumerated)
27        {
28            return new ASN1Enumerated(((DEREnumerated)obj).getValue());
29        }
30
31        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
32    }
33
34    /**
35     * return an Enumerated from a tagged object.
36     *
37     * @param obj the tagged object holding the object we want
38     * @param explicit true if the object is meant to be explicitly
39     *              tagged false otherwise.
40     * @exception IllegalArgumentException if the tagged object cannot
41     *               be converted.
42     */
43    public static DEREnumerated getInstance(
44        ASN1TaggedObject obj,
45        boolean          explicit)
46    {
47        ASN1Primitive o = obj.getObject();
48
49        if (explicit || o instanceof DEREnumerated)
50        {
51            return getInstance(o);
52        }
53        else
54        {
55            return fromOctetString(((ASN1OctetString)o).getOctets());
56        }
57    }
58
59    public DEREnumerated(
60        int         value)
61    {
62        bytes = BigInteger.valueOf(value).toByteArray();
63    }
64
65    public DEREnumerated(
66        BigInteger   value)
67    {
68        bytes = value.toByteArray();
69    }
70
71    public DEREnumerated(
72        byte[]   bytes)
73    {
74        this.bytes = bytes;
75    }
76
77    public BigInteger getValue()
78    {
79        return new BigInteger(bytes);
80    }
81
82    boolean isConstructed()
83    {
84        return false;
85    }
86
87    int encodedLength()
88    {
89        return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
90    }
91
92    void encode(
93        ASN1OutputStream out)
94        throws IOException
95    {
96        out.writeEncoded(BERTags.ENUMERATED, bytes);
97    }
98
99    boolean asn1Equals(
100        ASN1Primitive  o)
101    {
102        if (!(o instanceof DEREnumerated))
103        {
104            return false;
105        }
106
107        DEREnumerated other = (DEREnumerated)o;
108
109        return Arrays.areEqual(this.bytes, other.bytes);
110    }
111
112    public int hashCode()
113    {
114        return Arrays.hashCode(bytes);
115    }
116
117    private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
118
119    static ASN1Enumerated fromOctetString(byte[] enc)
120    {
121        if (enc.length > 1)
122        {
123            return new ASN1Enumerated(Arrays.clone(enc));
124        }
125
126        if (enc.length == 0)
127        {
128            throw new IllegalArgumentException("ENUMERATED has zero length");
129        }
130        int value = enc[0] & 0xff;
131
132        if (value >= cache.length)
133        {
134            return new ASN1Enumerated(Arrays.clone(enc));
135        }
136
137        ASN1Enumerated possibleMatch = cache[value];
138
139        if (possibleMatch == null)
140        {
141            possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
142        }
143
144        return possibleMatch;
145    }
146}
147