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