001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.protocols.asn1; 028 import org.opends.messages.Message; 029 030 031 032 import static org.opends.messages.ProtocolMessages.*; 033 import static org.opends.server.protocols.asn1.ASN1Constants.*; 034 import static org.opends.server.util.ServerConstants.*; 035 import static org.opends.server.util.StaticUtils.*; 036 037 038 039 /** 040 * This class defines the data structures and methods to use when interacting 041 * with ASN.1 Boolean elements. 042 */ 043 @org.opends.server.types.PublicAPI( 044 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 045 mayInstantiate=true, 046 mayExtend=false, 047 mayInvoke=true) 048 public final class ASN1Boolean 049 extends ASN1Element 050 { 051 /** 052 * The serial version identifier required to satisfy the compiler because this 053 * class implements the <CODE>java.io.Serializable</CODE> interface. This 054 * value was generated using the <CODE>serialver</CODE> command-line utility 055 * included with the Java SDK. 056 */ 057 private static final long serialVersionUID = -3352160557662933000L; 058 059 060 061 // The boolean value for this element. 062 private boolean booleanValue; 063 064 065 066 067 /** 068 * Creates a new ASN.1 Boolean element with the default type and the provided 069 * value. 070 * 071 * @param booleanValue The value for this ASN.1 Boolean element. 072 */ 073 public ASN1Boolean(boolean booleanValue) 074 { 075 super(UNIVERSAL_BOOLEAN_TYPE, encodeValue(booleanValue)); 076 077 078 this.booleanValue = booleanValue; 079 } 080 081 082 083 /** 084 * Creates a new ASN.1 Boolean element with the specified type and value. 085 * 086 * @param type The BER type for this ASN.1 Boolean element. 087 * @param booleanValue The value for this ASN.1 Boolean element. 088 */ 089 public ASN1Boolean(byte type, boolean booleanValue) 090 { 091 super(type, encodeValue(booleanValue)); 092 093 094 this.booleanValue = booleanValue; 095 } 096 097 098 099 /** 100 * Creates a new ASN.1 Boolean element with the specified type and value. 101 * 102 * @param type The BER type for this ASN.1 Boolean element. 103 * @param value The encoded value for this ASN.1 Boolean element. 104 * @param booleanValue The boolean value for this ASN.1 Boolean element. 105 */ 106 private ASN1Boolean(byte type, byte[] value, boolean booleanValue) 107 { 108 super(type, value); 109 110 111 this.booleanValue = booleanValue; 112 } 113 114 115 116 /** 117 * Retrieves the boolean value for this ASN.1 Boolean element. 118 * 119 * @return The boolean value for this ASN.1 Boolean element. 120 */ 121 public boolean booleanValue() 122 { 123 return booleanValue; 124 } 125 126 127 128 /** 129 * Specifies the boolean value for this ASN.1 Boolean element. 130 * 131 * @param booleanValue The boolean value for this ASN.1 Boolean element. 132 */ 133 public void setValue(boolean booleanValue) 134 { 135 this.booleanValue = booleanValue; 136 setValueInternal(encodeValue(booleanValue)); 137 } 138 139 140 141 /** 142 * Specifies the value for this ASN.1 Boolean element. 143 * 144 * @param value The encoded value for this ASN.1 Boolean element. 145 * 146 * @throws ASN1Exception If the provided array is null or does not contain 147 * a single byte. 148 */ 149 public void setValue(byte[] value) 150 throws ASN1Exception 151 { 152 if (value == null) 153 { 154 Message message = ERR_ASN1_BOOLEAN_SET_VALUE_NULL.get(); 155 throw new ASN1Exception(message); 156 } 157 158 if (value.length != 1) 159 { 160 Message message = 161 ERR_ASN1_BOOLEAN_SET_VALUE_INVALID_LENGTH.get(value.length); 162 throw new ASN1Exception(message); 163 } 164 165 booleanValue = (value[0] != 0x00); 166 setValueInternal(value); 167 } 168 169 170 171 /** 172 * Decodes the provided ASN.1 element as a Boolean element. 173 * 174 * @param element The ASN.1 element to decode as a Boolean element. 175 * 176 * @return The decoded ASN.1 Boolean element. 177 * 178 * @throws ASN1Exception If the provided ASN.1 element cannot be decoded as 179 * a Boolean element. 180 */ 181 public static ASN1Boolean decodeAsBoolean(ASN1Element element) 182 throws ASN1Exception 183 { 184 if (element == null) 185 { 186 Message message = ERR_ASN1_BOOLEAN_DECODE_ELEMENT_NULL.get(); 187 throw new ASN1Exception(message); 188 } 189 190 byte[] value = element.value(); 191 if (value.length != 1) 192 { 193 Message message = 194 ERR_ASN1_BOOLEAN_DECODE_ELEMENT_INVALID_LENGTH.get(value.length); 195 throw new ASN1Exception(message); 196 } 197 198 boolean booleanValue = (value[0] != 0x00); 199 return new ASN1Boolean(element.getType(), value, booleanValue); 200 } 201 202 203 204 /** 205 * Decodes the provided byte array as an ASN.1 Boolean element. 206 * 207 * @param encodedElement The byte array to decode as an ASN.1 Boolean 208 * element. 209 * 210 * @return The decoded ASN.1 Boolean element. 211 * 212 * @throws ASN1Exception If the provided byte array cannot be decoded as an 213 * ASN.1 Boolean element. 214 */ 215 public static ASN1Boolean decodeAsBoolean(byte[] encodedElement) 216 throws ASN1Exception 217 { 218 // First make sure that the array is not null and long enough to contain 219 // a valid ASN.1 Boolean element. 220 if (encodedElement == null) 221 { 222 Message message = ERR_ASN1_BOOLEAN_DECODE_ARRAY_NULL.get(); 223 throw new ASN1Exception(message); 224 } 225 226 if (encodedElement.length < 3) 227 { 228 Message message = 229 ERR_ASN1_BOOLEAN_SHORT_ELEMENT.get(encodedElement.length); 230 throw new ASN1Exception(message); 231 } 232 233 234 // Next, decode the length. This allows multi-byte lengths with up to four 235 // bytes used to indicate how many bytes are in the length. 236 byte type = encodedElement[0]; 237 int length = (encodedElement[1] & 0x7F); 238 int valueStartPos = 2; 239 if (length != encodedElement[1]) 240 { 241 int numLengthBytes = length; 242 if (numLengthBytes > 4) 243 { 244 Message message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES.get(numLengthBytes); 245 throw new ASN1Exception(message); 246 } 247 else if (encodedElement.length < (2 + numLengthBytes)) 248 { 249 Message message = ERR_ASN1_TRUNCATED_LENGTH.get(numLengthBytes); 250 throw new ASN1Exception(message); 251 } 252 253 length = 0x00; 254 valueStartPos = 2 + numLengthBytes; 255 for (int i=0; i < numLengthBytes; i++) 256 { 257 length = (length << 8) | (encodedElement[i+2] & 0xFF); 258 } 259 } 260 261 262 // Make sure that the number of bytes left is equal to the number of bytes 263 // in the value. 264 if ((encodedElement.length - valueStartPos) != length) 265 { 266 Message message = ERR_ASN1_LENGTH_MISMATCH.get( 267 length, (encodedElement.length - valueStartPos)); 268 throw new ASN1Exception(message); 269 } 270 271 272 // Make sure that the decoded length is exactly one byte. 273 if (length != 1) 274 { 275 Message message = 276 ERR_ASN1_BOOLEAN_DECODE_ARRAY_INVALID_LENGTH.get(length); 277 throw new ASN1Exception(message); 278 } 279 280 281 // Copy the value and construct the element to return. 282 byte[] value = new byte[] { encodedElement[valueStartPos] }; 283 boolean booleanValue = (value[0] != 0x00); 284 return new ASN1Boolean(type, value, booleanValue); 285 } 286 287 288 289 /** 290 * Appends a string representation of this ASN.1 Boolean element to the 291 * provided buffer. 292 * 293 * @param buffer The buffer to which the information should be appended. 294 */ 295 public void toString(StringBuilder buffer) 296 { 297 buffer.append("ASN1Boolean(type="); 298 buffer.append(byteToHex(getType())); 299 buffer.append(", value="); 300 buffer.append(booleanValue); 301 buffer.append(")"); 302 } 303 304 305 306 /** 307 * Appends a string representation of this protocol element to the provided 308 * buffer. 309 * 310 * @param buffer The buffer into which the string representation should be 311 * written. 312 * @param indent The number of spaces that should be used to indent the 313 * resulting string representation. 314 */ 315 public void toString(StringBuilder buffer, int indent) 316 { 317 StringBuilder indentBuf = new StringBuilder(indent); 318 for (int i=0 ; i < indent; i++) 319 { 320 indentBuf.append(' '); 321 } 322 323 buffer.append(indentBuf); 324 buffer.append("ASN.1 Boolean"); 325 buffer.append(EOL); 326 327 buffer.append(indentBuf); 328 buffer.append(" BER Type: "); 329 buffer.append(byteToHex(getType())); 330 buffer.append(EOL); 331 332 buffer.append(indentBuf); 333 buffer.append(" Value: "); 334 buffer.append(booleanValue); 335 buffer.append(" ("); 336 buffer.append(byteToHex(value()[0])); 337 buffer.append(")"); 338 buffer.append(EOL); 339 } 340 } 341