001package org.apache.commons.ssl.org.bouncycastle.asn1; 002 003import java.io.IOException; 004import java.math.BigInteger; 005 006import org.bouncycastle.util.Arrays; 007 008/** 009 * Class representing the ASN.1 ENUMERATED type. 010 */ 011public class ASN1Enumerated 012 extends ASN1Primitive 013{ 014 byte[] bytes; 015 016 /** 017 * return an enumerated from the passed in object 018 * 019 * @param obj an ASN1Enumerated or an object that can be converted into one. 020 * @exception IllegalArgumentException if the object cannot be converted. 021 * @return an ASN1Enumerated instance, or null. 022 */ 023 public static ASN1Enumerated getInstance( 024 Object obj) 025 { 026 if (obj == null || obj instanceof ASN1Enumerated) 027 { 028 return (ASN1Enumerated)obj; 029 } 030 031 if (obj instanceof byte[]) 032 { 033 try 034 { 035 return (ASN1Enumerated)fromByteArray((byte[])obj); 036 } 037 catch (Exception e) 038 { 039 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); 040 } 041 } 042 043 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 044 } 045 046 /** 047 * return an Enumerated from a tagged object. 048 * 049 * @param obj the tagged object holding the object we want 050 * @param explicit true if the object is meant to be explicitly 051 * tagged false otherwise. 052 * @exception IllegalArgumentException if the tagged object cannot 053 * be converted. 054 * @return an ASN1Enumerated instance, or null. 055 */ 056 public static ASN1Enumerated getInstance( 057 ASN1TaggedObject obj, 058 boolean explicit) 059 { 060 ASN1Primitive o = obj.getObject(); 061 062 if (explicit || o instanceof ASN1Enumerated) 063 { 064 return getInstance(o); 065 } 066 else 067 { 068 return fromOctetString(((ASN1OctetString)o).getOctets()); 069 } 070 } 071 072 /** 073 * Constructor from int. 074 * 075 * @param value the value of this enumerated. 076 */ 077 public ASN1Enumerated( 078 int value) 079 { 080 bytes = BigInteger.valueOf(value).toByteArray(); 081 } 082 083 /** 084 * Constructor from BigInteger 085 * 086 * @param value the value of this enumerated. 087 */ 088 public ASN1Enumerated( 089 BigInteger value) 090 { 091 bytes = value.toByteArray(); 092 } 093 094 /** 095 * Constructor from encoded BigInteger. 096 * 097 * @param bytes the value of this enumerated as an encoded BigInteger (signed). 098 */ 099 public ASN1Enumerated( 100 byte[] bytes) 101 { 102 this.bytes = bytes; 103 } 104 105 public BigInteger getValue() 106 { 107 return new BigInteger(bytes); 108 } 109 110 boolean isConstructed() 111 { 112 return false; 113 } 114 115 int encodedLength() 116 { 117 return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; 118 } 119 120 void encode( 121 ASN1OutputStream out) 122 throws IOException 123 { 124 out.writeEncoded(BERTags.ENUMERATED, bytes); 125 } 126 127 boolean asn1Equals( 128 ASN1Primitive o) 129 { 130 if (!(o instanceof ASN1Enumerated)) 131 { 132 return false; 133 } 134 135 ASN1Enumerated other = (ASN1Enumerated)o; 136 137 return Arrays.areEqual(this.bytes, other.bytes); 138 } 139 140 public int hashCode() 141 { 142 return Arrays.hashCode(bytes); 143 } 144 145 private static ASN1Enumerated[] cache = new ASN1Enumerated[12]; 146 147 static ASN1Enumerated fromOctetString(byte[] enc) 148 { 149 if (enc.length > 1) 150 { 151 return new ASN1Enumerated(Arrays.clone(enc)); 152 } 153 154 if (enc.length == 0) 155 { 156 throw new IllegalArgumentException("ENUMERATED has zero length"); 157 } 158 int value = enc[0] & 0xff; 159 160 if (value >= cache.length) 161 { 162 return new ASN1Enumerated(Arrays.clone(enc)); 163 } 164 165 ASN1Enumerated possibleMatch = cache[value]; 166 167 if (possibleMatch == null) 168 { 169 possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc)); 170 } 171 172 return possibleMatch; 173 } 174}