KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > bc > asn1 > DERBitString


1 package com.lowagie.bc.asn1;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5
6 public class DERBitString
7     extends DERObject
8     implements DERString
9 {
10     private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
11     
12     protected byte[] data;
13     protected int padBits;
14
15     /**
16      * return the correct number of pad bits for a bit string defined in
17      * a 32 bit constant
18      */

19     static protected int getPadBits(
20         int bitString)
21     {
22         int val = 0;
23         for (int i = 3; i >= 0; i--)
24         {
25             //
26
// this may look a little odd, but if it isn't done like this pre jdk1.2
27
// JVM's break!
28
//
29
if (i != 0)
30             {
31                 if ((bitString >> (i * 8)) != 0)
32                 {
33                     val = (bitString >> (i * 8)) & 0xFF;
34                     break;
35                 }
36             }
37             else
38             {
39                 if (bitString != 0)
40                 {
41                     val = bitString & 0xFF;
42                     break;
43                 }
44             }
45         }
46  
47         if (val == 0)
48         {
49             return 7;
50         }
51
52
53         int bits = 1;
54
55         while (((val <<= 1) & 0xFF) != 0)
56         {
57             bits++;
58         }
59
60         return 8 - bits;
61     }
62
63     /**
64      * return the correct number of bytes for a bit string defined in
65      * a 32 bit constant
66      */

67     static protected byte[] getBytes(int bitString)
68     {
69         int bytes = 4;
70         for (int i = 3; i >= 1; i--)
71         {
72             if ((bitString & (0xFF << (i * 8))) != 0)
73             {
74                 break;
75             }
76             bytes--;
77         }
78         
79         byte[] result = new byte[bytes];
80         for (int i = 0; i < bytes; i++)
81         {
82             result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
83         }
84
85         return result;
86     }
87
88     /**
89      * return a Bit String from the passed in object
90      *
91      * @exception IllegalArgumentException if the object cannot be converted.
92      */

93     public static DERBitString getInstance(
94         Object obj)
95     {
96         if (obj == null || obj instanceof DERBitString)
97         {
98             return (DERBitString)obj;
99         }
100
101         if (obj instanceof ASN1OctetString)
102         {
103             byte[] bytes = ((ASN1OctetString)obj).getOctets();
104             int padBits = bytes[0];
105             byte[] data = new byte[bytes.length - 1];
106
107             System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
108
109             return new DERBitString(data, padBits);
110         }
111
112         if (obj instanceof ASN1TaggedObject)
113         {
114             return getInstance(((ASN1TaggedObject)obj).getObject());
115         }
116
117         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
118     }
119
120     /**
121      * return a Bit String from a tagged object.
122      *
123      * @param obj the tagged object holding the object we want
124      * @param explicit true if the object is meant to be explicitly
125      * tagged false otherwise.
126      * @exception IllegalArgumentException if the tagged object cannot
127      * be converted.
128      */

129     public static DERBitString getInstance(
130         ASN1TaggedObject obj,
131         boolean explicit)
132     {
133         return getInstance(obj.getObject());
134     }
135     
136     protected DERBitString(
137         byte data,
138         int padBits)
139     {
140         this.data = new byte[1];
141         this.data[0] = data;
142         this.padBits = padBits;
143     }
144
145     /**
146      * @param data the octets making up the bit string.
147      * @param padBits the number of extra bits at the end of the string.
148      */

149     public DERBitString(
150         byte[] data,
151         int padBits)
152     {
153         this.data = data;
154         this.padBits = padBits;
155     }
156
157     public DERBitString(
158         byte[] data)
159     {
160         this(data, 0);
161     }
162
163     public DERBitString(
164         DEREncodable obj)
165     {
166         try
167         {
168             ByteArrayOutputStream bOut = new ByteArrayOutputStream();
169             DEROutputStream dOut = new DEROutputStream(bOut);
170
171             dOut.writeObject(obj);
172             dOut.close();
173
174             this.data = bOut.toByteArray();
175             this.padBits = 0;
176         }
177         catch (IOException e)
178         {
179             throw new IllegalArgumentException("Error processing object : " + e.toString());
180         }
181     }
182
183     public byte[] getBytes()
184     {
185         return data;
186     }
187
188     public int getPadBits()
189     {
190         return padBits;
191     }
192
193     void encode(
194         DEROutputStream out)
195         throws IOException
196     {
197         byte[] bytes = new byte[getBytes().length + 1];
198
199         bytes[0] = (byte)getPadBits();
200         System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
201
202         out.writeEncoded(BIT_STRING, bytes);
203     }
204
205     public int hashCode()
206     {
207         int value = 0;
208
209         for (int i = 0; i != data.length; i++)
210         {
211             value ^= (data[i] & 0xff) << (i % 4);
212         }
213
214         return value;
215     }
216     
217     public boolean equals(
218         Object o)
219     {
220         if (o == null || !(o instanceof DERBitString))
221         {
222             return false;
223         }
224
225         DERBitString other = (DERBitString)o;
226
227         if (data.length != other.data.length)
228         {
229             return false;
230         }
231
232         for (int i = 0; i != data.length; i++)
233         {
234             if (data[i] != other.data[i])
235             {
236                 return false;
237             }
238         }
239
240         return (padBits == other.padBits);
241     }
242
243     public String getString()
244     {
245         StringBuffer buf = new StringBuffer("#");
246         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
247         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
248         
249         try
250         {
251             aOut.writeObject(this);
252         }
253         catch (IOException e)
254         {
255            throw new RuntimeException("internal error encoding BitString");
256         }
257         
258         byte[] string = bOut.toByteArray();
259         
260         for (int i = 0; i != string.length; i++)
261         {
262             buf.append(table[(string[i] >>> 4) % 0xf]);
263             buf.append(table[string[i] & 0xf]);
264         }
265         
266         return buf.toString();
267     }
268 }
269
Popular Tags