001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3; 018 019/** 020 * <p>Operations on bit-mapped fields.</p> 021 * 022 * @since 2.0 023 * @version $Id: BitField.java 1436768 2013-01-22 07:07:42Z ggregory $ 024 */ 025public class BitField { 026 027 private final int _mask; 028 private final int _shift_count; 029 030 /** 031 * <p>Creates a BitField instance.</p> 032 * 033 * @param mask the mask specifying which bits apply to this 034 * BitField. Bits that are set in this mask are the bits 035 * that this BitField operates on 036 */ 037 public BitField(final int mask) { 038 _mask = mask; 039 int count = 0; 040 int bit_pattern = mask; 041 042 if (bit_pattern != 0) { 043 while ((bit_pattern & 1) == 0) { 044 count++; 045 bit_pattern >>= 1; 046 } 047 } 048 _shift_count = count; 049 } 050 051 /** 052 * <p>Obtains the value for the specified BitField, appropriately 053 * shifted right.</p> 054 * 055 * <p>Many users of a BitField will want to treat the specified 056 * bits as an int value, and will not want to be aware that the 057 * value is stored as a BitField (and so shifted left so many 058 * bits).</p> 059 * 060 * @see #setValue(int,int) 061 * @param holder the int data containing the bits we're interested 062 * in 063 * @return the selected bits, shifted right appropriately 064 */ 065 public int getValue(final int holder) { 066 return getRawValue(holder) >> _shift_count; 067 } 068 069 /** 070 * <p>Obtains the value for the specified BitField, appropriately 071 * shifted right, as a short.</p> 072 * 073 * <p>Many users of a BitField will want to treat the specified 074 * bits as an int value, and will not want to be aware that the 075 * value is stored as a BitField (and so shifted left so many 076 * bits).</p> 077 * 078 * @see #setShortValue(short,short) 079 * @param holder the short data containing the bits we're 080 * interested in 081 * @return the selected bits, shifted right appropriately 082 */ 083 public short getShortValue(final short holder) { 084 return (short) getValue(holder); 085 } 086 087 /** 088 * <p>Obtains the value for the specified BitField, unshifted.</p> 089 * 090 * @param holder the int data containing the bits we're 091 * interested in 092 * @return the selected bits 093 */ 094 public int getRawValue(final int holder) { 095 return holder & _mask; 096 } 097 098 /** 099 * <p>Obtains the value for the specified BitField, unshifted.</p> 100 * 101 * @param holder the short data containing the bits we're 102 * interested in 103 * @return the selected bits 104 */ 105 public short getShortRawValue(final short holder) { 106 return (short) getRawValue(holder); 107 } 108 109 /** 110 * <p>Returns whether the field is set or not.</p> 111 * 112 * <p>This is most commonly used for a single-bit field, which is 113 * often used to represent a boolean value; the results of using 114 * it for a multi-bit field is to determine whether *any* of its 115 * bits are set.</p> 116 * 117 * @param holder the int data containing the bits we're interested 118 * in 119 * @return {@code true} if any of the bits are set, 120 * else {@code false} 121 */ 122 public boolean isSet(final int holder) { 123 return (holder & _mask) != 0; 124 } 125 126 /** 127 * <p>Returns whether all of the bits are set or not.</p> 128 * 129 * <p>This is a stricter test than {@link #isSet(int)}, 130 * in that all of the bits in a multi-bit set must be set 131 * for this method to return {@code true}.</p> 132 * 133 * @param holder the int data containing the bits we're 134 * interested in 135 * @return {@code true} if all of the bits are set, 136 * else {@code false} 137 */ 138 public boolean isAllSet(final int holder) { 139 return (holder & _mask) == _mask; 140 } 141 142 /** 143 * <p>Replaces the bits with new values.</p> 144 * 145 * @see #getValue(int) 146 * @param holder the int data containing the bits we're 147 * interested in 148 * @param value the new value for the specified bits 149 * @return the value of holder with the bits from the value 150 * parameter replacing the old bits 151 */ 152 public int setValue(final int holder, final int value) { 153 return (holder & ~_mask) | ((value << _shift_count) & _mask); 154 } 155 156 /** 157 * <p>Replaces the bits with new values.</p> 158 * 159 * @see #getShortValue(short) 160 * @param holder the short data containing the bits we're 161 * interested in 162 * @param value the new value for the specified bits 163 * @return the value of holder with the bits from the value 164 * parameter replacing the old bits 165 */ 166 public short setShortValue(final short holder, final short value) { 167 return (short) setValue(holder, value); 168 } 169 170 /** 171 * <p>Clears the bits.</p> 172 * 173 * @param holder the int data containing the bits we're 174 * interested in 175 * @return the value of holder with the specified bits cleared 176 * (set to {@code 0}) 177 */ 178 public int clear(final int holder) { 179 return holder & ~_mask; 180 } 181 182 /** 183 * <p>Clears the bits.</p> 184 * 185 * @param holder the short data containing the bits we're 186 * interested in 187 * @return the value of holder with the specified bits cleared 188 * (set to {@code 0}) 189 */ 190 public short clearShort(final short holder) { 191 return (short) clear(holder); 192 } 193 194 /** 195 * <p>Clears the bits.</p> 196 * 197 * @param holder the byte data containing the bits we're 198 * interested in 199 * 200 * @return the value of holder with the specified bits cleared 201 * (set to {@code 0}) 202 */ 203 public byte clearByte(final byte holder) { 204 return (byte) clear(holder); 205 } 206 207 /** 208 * <p>Sets the bits.</p> 209 * 210 * @param holder the int data containing the bits we're 211 * interested in 212 * @return the value of holder with the specified bits set 213 * to {@code 1} 214 */ 215 public int set(final int holder) { 216 return holder | _mask; 217 } 218 219 /** 220 * <p>Sets the bits.</p> 221 * 222 * @param holder the short data containing the bits we're 223 * interested in 224 * @return the value of holder with the specified bits set 225 * to {@code 1} 226 */ 227 public short setShort(final short holder) { 228 return (short) set(holder); 229 } 230 231 /** 232 * <p>Sets the bits.</p> 233 * 234 * @param holder the byte data containing the bits we're 235 * interested in 236 * 237 * @return the value of holder with the specified bits set 238 * to {@code 1} 239 */ 240 public byte setByte(final byte holder) { 241 return (byte) set(holder); 242 } 243 244 /** 245 * <p>Sets a boolean BitField.</p> 246 * 247 * @param holder the int data containing the bits we're 248 * interested in 249 * @param flag indicating whether to set or clear the bits 250 * @return the value of holder with the specified bits set or 251 * cleared 252 */ 253 public int setBoolean(final int holder, final boolean flag) { 254 return flag ? set(holder) : clear(holder); 255 } 256 257 /** 258 * <p>Sets a boolean BitField.</p> 259 * 260 * @param holder the short data containing the bits we're 261 * interested in 262 * @param flag indicating whether to set or clear the bits 263 * @return the value of holder with the specified bits set or 264 * cleared 265 */ 266 public short setShortBoolean(final short holder, final boolean flag) { 267 return flag ? setShort(holder) : clearShort(holder); 268 } 269 270 /** 271 * <p>Sets a boolean BitField.</p> 272 * 273 * @param holder the byte data containing the bits we're 274 * interested in 275 * @param flag indicating whether to set or clear the bits 276 * @return the value of holder with the specified bits set or 277 * cleared 278 */ 279 public byte setByteBoolean(final byte holder, final boolean flag) { 280 return flag ? setByte(holder) : clearByte(holder); 281 } 282 283}