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
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
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
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
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
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 }
213