001/* 002 * Copyright 2007-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.asn1; 022 023 024 025import com.unboundid.util.Debug; 026import com.unboundid.util.NotMutable; 027import com.unboundid.util.ThreadSafety; 028import com.unboundid.util.ThreadSafetyLevel; 029 030import static com.unboundid.asn1.ASN1Messages.*; 031 032 033 034/** 035 * This class provides an ASN.1 Boolean element, whose value is a single byte 036 * and represents either "TRUE" or "FALSE". A value whose only byte is 0x00 is 037 * considered "false", while any other single-byte value is considered "true". 038 */ 039@NotMutable() 040@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 041public final class ASN1Boolean 042 extends ASN1Element 043{ 044 /** 045 * A pre-allocated ASN.1 Boolean element with the universal Boolean BER type 046 * and a value of "FALSE". 047 */ 048 public static final ASN1Boolean UNIVERSAL_BOOLEAN_FALSE_ELEMENT = 049 new ASN1Boolean(false); 050 051 052 053 /** 054 * A pre-allocated ASN.1 Boolean element with the universal Boolean BER type 055 * and a value of "TRUE". 056 */ 057 public static final ASN1Boolean UNIVERSAL_BOOLEAN_TRUE_ELEMENT = 058 new ASN1Boolean(true); 059 060 061 062 /** 063 * The serial version UID for this serializable class. 064 */ 065 private static final long serialVersionUID = 7131700816847855524L; 066 067 068 069 // The boolean value for this element. 070 private final boolean booleanValue; 071 072 073 074 /** 075 * Creates a new ASN.1 Boolean element with the default BER type and the 076 * provided boolean value. 077 * 078 * @param booleanValue The boolean value to use for this element. 079 */ 080 public ASN1Boolean(final boolean booleanValue) 081 { 082 super(ASN1Constants.UNIVERSAL_BOOLEAN_TYPE, 083 (booleanValue 084 ? ASN1Constants.BOOLEAN_VALUE_TRUE 085 : ASN1Constants.BOOLEAN_VALUE_FALSE)); 086 087 this.booleanValue = booleanValue; 088 } 089 090 091 092 /** 093 * Creates a new ASN.1 Boolean element with the specified BER type and the 094 * provided boolean value. 095 * 096 * @param type The BER type to use for this element. 097 * @param booleanValue The boolean value to use for this element. 098 */ 099 public ASN1Boolean(final byte type, final boolean booleanValue) 100 { 101 super(type, (booleanValue 102 ? ASN1Constants.BOOLEAN_VALUE_TRUE 103 : ASN1Constants.BOOLEAN_VALUE_FALSE)); 104 105 this.booleanValue = booleanValue; 106 } 107 108 109 110 /** 111 * Creates a new ASN.1 Boolean element with the provided information. 112 * 113 * @param type The BER type to use for this element. 114 * @param booleanValue The boolean value to use for this element. 115 * @param value The pre-encoded value to use for this element. 116 */ 117 private ASN1Boolean(final byte type, final boolean booleanValue, 118 final byte[] value) 119 { 120 super(type, value); 121 122 this.booleanValue = booleanValue; 123 } 124 125 126 127 /** 128 * Retrieves the boolean value for this element. 129 * 130 * @return {@code true} if this element has a value of "TRUE", or 131 * {@code false} if it has a value of "FALSE". 132 */ 133 public boolean booleanValue() 134 { 135 return booleanValue; 136 } 137 138 139 140 /** 141 * Decodes the contents of the provided byte array as a Boolean element. 142 * 143 * @param elementBytes The byte array to decode as an ASN.1 Boolean element. 144 * 145 * @return The decoded ASN.1 Boolean element. 146 * 147 * @throws ASN1Exception If the provided array cannot be decoded as a 148 * Boolean element. 149 */ 150 public static ASN1Boolean decodeAsBoolean(final byte[] elementBytes) 151 throws ASN1Exception 152 { 153 try 154 { 155 int valueStartPos = 2; 156 int length = (elementBytes[1] & 0x7F); 157 if (length != elementBytes[1]) 158 { 159 final int numLengthBytes = length; 160 161 length = 0; 162 for (int i=0; i < numLengthBytes; i++) 163 { 164 length <<= 8; 165 length |= (elementBytes[valueStartPos++] & 0xFF); 166 } 167 } 168 169 if ((elementBytes.length - valueStartPos) != length) 170 { 171 throw new ASN1Exception(ERR_ELEMENT_LENGTH_MISMATCH.get(length, 172 (elementBytes.length - valueStartPos))); 173 } 174 175 if (length != 1) 176 { 177 throw new ASN1Exception(ERR_BOOLEAN_INVALID_LENGTH.get()); 178 } 179 180 final byte[] value = { elementBytes[valueStartPos] }; 181 final boolean booleanValue = (value[0] != 0x00); 182 return new ASN1Boolean(elementBytes[0], booleanValue, value); 183 } 184 catch (final ASN1Exception ae) 185 { 186 Debug.debugException(ae); 187 throw ae; 188 } 189 catch (final Exception e) 190 { 191 Debug.debugException(e); 192 throw new ASN1Exception(ERR_ELEMENT_DECODE_EXCEPTION.get(e), e); 193 } 194 } 195 196 197 198 /** 199 * Decodes the provided ASN.1 element as a Boolean element. 200 * 201 * @param element The ASN.1 element to be decoded. 202 * 203 * @return The decoded ASN.1 Boolean element. 204 * 205 * @throws ASN1Exception If the provided element cannot be decoded as a 206 * Boolean element. 207 */ 208 public static ASN1Boolean decodeAsBoolean(final ASN1Element element) 209 throws ASN1Exception 210 { 211 final byte[] value = element.getValue(); 212 if (value.length != 1) 213 { 214 throw new ASN1Exception(ERR_BOOLEAN_INVALID_LENGTH.get()); 215 } 216 217 if (value[0] == 0x00) 218 { 219 return new ASN1Boolean(element.getType(), false, value); 220 } 221 else 222 { 223 return new ASN1Boolean(element.getType(), true, value); 224 } 225 } 226 227 228 229 /** 230 * {@inheritDoc} 231 */ 232 @Override() 233 public void toString(final StringBuilder buffer) 234 { 235 buffer.append(booleanValue); 236 } 237}