View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3;
18  
19  /**
20   * <p>Operations on bit-mapped fields.</p>
21   *
22   * @since 2.0
23   * @version $Id: BitField.java 1436768 2013-01-22 07:07:42Z ggregory $
24   */
25  public class BitField {
26      
27      private final int _mask;
28      private final int _shift_count;
29  
30      /**
31       * <p>Creates a BitField instance.</p>
32       *
33       * @param mask the mask specifying which bits apply to this
34       *  BitField. Bits that are set in this mask are the bits
35       *  that this BitField operates on
36       */
37      public BitField(final int mask) {
38          _mask = mask;
39          int count = 0;
40          int bit_pattern = mask;
41  
42          if (bit_pattern != 0) {
43              while ((bit_pattern & 1) == 0) {
44                  count++;
45                  bit_pattern >>= 1;
46              }
47          }
48          _shift_count = count;
49      }
50  
51      /**
52       * <p>Obtains the value for the specified BitField, appropriately
53       * shifted right.</p>
54       *
55       * <p>Many users of a BitField will want to treat the specified
56       * bits as an int value, and will not want to be aware that the
57       * value is stored as a BitField (and so shifted left so many
58       * bits).</p>
59       *
60       * @see #setValue(int,int)
61       * @param holder the int data containing the bits we're interested
62       *  in
63       * @return the selected bits, shifted right appropriately
64       */
65      public int getValue(final int holder) {
66          return getRawValue(holder) >> _shift_count;
67      }
68  
69      /**
70       * <p>Obtains the value for the specified BitField, appropriately
71       * shifted right, as a short.</p>
72       *
73       * <p>Many users of a BitField will want to treat the specified
74       * bits as an int value, and will not want to be aware that the
75       * value is stored as a BitField (and so shifted left so many
76       * bits).</p>
77       *
78       * @see #setShortValue(short,short)
79       * @param holder the short data containing the bits we're
80       *  interested in
81       * @return the selected bits, shifted right appropriately
82       */
83      public short getShortValue(final short holder) {
84          return (short) getValue(holder);
85      }
86  
87      /**
88       * <p>Obtains the value for the specified BitField, unshifted.</p>
89       *
90       * @param holder the int data containing the bits we're
91       *  interested in
92       * @return the selected bits
93       */
94      public int getRawValue(final int holder) {
95          return holder & _mask;
96      }
97  
98      /**
99       * <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 }