1package org.bouncycastle.asn1; 2 3import java.io.IOException; 4 5/** 6 * A Definite length BIT STRING 7 */ 8public class DLBitString 9 extends ASN1BitString 10{ 11 /** 12 * return a Bit String that can be definite-length encoded from the passed in object. 13 * 14 * @param obj a DL or DER BitString or an object that can be converted into one. 15 * @exception IllegalArgumentException if the object cannot be converted. 16 * @return an ASN1BitString instance, or null. 17 */ 18 public static ASN1BitString getInstance( 19 Object obj) 20 { 21 if (obj == null || obj instanceof DLBitString) 22 { 23 return (DLBitString)obj; 24 } 25 if (obj instanceof DERBitString) 26 { 27 return (DERBitString)obj; 28 } 29 30 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 31 } 32 33 /** 34 * return a Bit String from a tagged object. 35 * 36 * @param obj the tagged object holding the object we want 37 * @param explicit true if the object is meant to be explicitly 38 * tagged false otherwise. 39 * @exception IllegalArgumentException if the tagged object cannot 40 * be converted. 41 * @return an ASN1BitString instance, or null. 42 */ 43 public static ASN1BitString getInstance( 44 ASN1TaggedObject obj, 45 boolean explicit) 46 { 47 ASN1Primitive o = obj.getObject(); 48 49 if (explicit || o instanceof DLBitString) 50 { 51 return getInstance(o); 52 } 53 else 54 { 55 return fromOctetString(((ASN1OctetString)o).getOctets()); 56 } 57 } 58 59 protected DLBitString( 60 byte data, 61 int padBits) 62 { 63 this(toByteArray(data), padBits); 64 } 65 66 private static byte[] toByteArray(byte data) 67 { 68 byte[] rv = new byte[1]; 69 70 rv[0] = data; 71 72 return rv; 73 } 74 75 /** 76 * @param data the octets making up the bit string. 77 * @param padBits the number of extra bits at the end of the string. 78 */ 79 public DLBitString( 80 byte[] data, 81 int padBits) 82 { 83 super(data, padBits); 84 } 85 86 public DLBitString( 87 byte[] data) 88 { 89 this(data, 0); 90 } 91 92 public DLBitString( 93 int value) 94 { 95 super(getBytes(value), getPadBits(value)); 96 } 97 98 public DLBitString( 99 ASN1Encodable obj) 100 throws IOException 101 { 102 super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0); 103 } 104 105 boolean isConstructed() 106 { 107 return false; 108 } 109 110 int encodedLength() 111 { 112 return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; 113 } 114 115 void encode( 116 ASN1OutputStream out) 117 throws IOException 118 { 119 byte[] string = data; 120 byte[] bytes = new byte[string.length + 1]; 121 122 bytes[0] = (byte)getPadBits(); 123 System.arraycopy(string, 0, bytes, 1, bytes.length - 1); 124 125 out.writeEncoded(BERTags.BIT_STRING, bytes); 126 } 127 128 static DLBitString fromOctetString(byte[] bytes) 129 { 130 if (bytes.length < 1) 131 { 132 throw new IllegalArgumentException("truncated BIT STRING detected"); 133 } 134 135 int padBits = bytes[0]; 136 byte[] data = new byte[bytes.length - 1]; 137 138 if (data.length != 0) 139 { 140 System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 141 } 142 143 return new DLBitString(data, padBits); 144 } 145} 146