56046a79ffbaa1632fb9e26465685a5a20ac67e5
[org.ibex.core.git] / src / org / bouncycastle / asn1 / DERBitString.java
1 package org.bouncycastle.asn1;
2
3 import java.io.*;
4
5 public class DERBitString
6     extends DERObject
7 {
8     protected byte[]      data;
9     protected int         padBits;
10
11     /**
12      * return the correct number of pad bits for a bit string defined in
13      * a 16 bit constant
14      */
15     static protected int getPadBits(
16         int bitString)
17     {
18         int val;
19
20         if (bitString == 0)
21         {
22             return 7;
23         }
24
25         if (bitString > 255)
26         {
27             val = ((bitString >> 8) & 0xFF);
28         }
29         else
30         {
31             val = (bitString & 0xFF);
32         }
33
34         int bits = 1;
35
36         while (((val <<= 1) & 0xFF) != 0)
37         {
38             bits++;
39         }
40
41         return 8 - bits;
42     }
43
44     /**
45      * return the correct number of bytes for a bit string defined in
46      * a 16 bit constant
47      */
48     static protected byte[] getBytes(
49         int bitString)
50     {
51         if (bitString > 255)
52         {
53             byte[]  bytes = new byte[2];
54
55             bytes[0] = (byte)(bitString & 0xFF);
56             bytes[1] = (byte)((bitString >> 8) & 0xFF);
57
58             return bytes;
59         }
60         else
61         {
62             byte[]  bytes = new byte[1];
63
64             bytes[0] = (byte)(bitString & 0xFF);
65
66             return bytes;
67         }
68     }
69
70     /**
71      * return a Bit String from the passed in object
72      *
73      * @exception IllegalArgumentException if the object cannot be converted.
74      */
75     public static DERBitString getInstance(
76         Object  obj)
77     {
78         if (obj == null || obj instanceof DERBitString)
79         {
80             return (DERBitString)obj;
81         }
82
83         if (obj instanceof ASN1OctetString)
84         {
85             byte[]  bytes = ((ASN1OctetString)obj).getOctets();
86             int     padBits = bytes[0];
87             byte[]  data = new byte[bytes.length - 1];
88
89             System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
90
91             return new DERBitString(data, padBits);
92         }
93
94         if (obj instanceof ASN1TaggedObject)
95         {
96             return getInstance(((ASN1TaggedObject)obj).getObject());
97         }
98
99         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
100     }
101
102     /**
103      * return a Bit String from a tagged object.
104      *
105      * @param obj the tagged object holding the object we want
106      * @param explicit true if the object is meant to be explicitly
107      *              tagged false otherwise.
108      * @exception IllegalArgumentException if the tagged object cannot
109      *               be converted.
110      */
111     public static DERBitString getInstance(
112         ASN1TaggedObject obj,
113         boolean          explicit)
114     {
115         return getInstance(obj.getObject());
116     }
117     
118     protected DERBitString(
119         byte    data,
120         int     padBits)
121     {
122         this.data = new byte[1];
123         this.data[0] = data;
124         this.padBits = padBits;
125     }
126
127     /**
128      * @param data the octets making up the bit string.
129      * @param padBits the number of extra bits at the end of the string.
130      */
131     public DERBitString(
132         byte[]  data,
133         int     padBits)
134     {
135         this.data = data;
136         this.padBits = padBits;
137     }
138
139     public DERBitString(
140         byte[]  data)
141     {
142         this(data, 0);
143     }
144
145     public DERBitString(
146         DEREncodable  obj)
147     {
148         try
149         {
150             ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
151             DEROutputStream         dOut = new DEROutputStream(bOut);
152
153             dOut.writeObject(obj);
154             dOut.close();
155
156             this.data = bOut.toByteArray();
157             this.padBits = 0;
158         }
159         catch (IOException e)
160         {
161             throw new IllegalArgumentException("Error processing object : " + e.toString());
162         }
163     }
164
165     public byte[] getBytes()
166     {
167         return data;
168     }
169
170     public int getPadBits()
171     {
172         return padBits;
173     }
174
175     void encode(
176         DEROutputStream  out)
177         throws IOException
178     {
179         byte[]  bytes = new byte[getBytes().length + 1];
180
181         bytes[0] = (byte)getPadBits();
182         System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
183
184         out.writeEncoded(BIT_STRING, bytes);
185     }
186     
187     public boolean equals(
188         Object  o)
189     {
190         if (o == null || !(o instanceof DERBitString))
191         {
192             return false;
193         }
194
195         DERBitString  other = (DERBitString)o;
196
197         if (data.length != other.data.length)
198         {
199             return false;
200         }
201
202         for (int i = 0; i != data.length; i++)
203         {
204             if (data[i] != other.data[i])
205             {
206                 return false;
207             }
208         }
209
210         return (padBits == other.padBits);
211     }
212 }