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.lang;
18  
19  /**
20   * <p>Operations on bit-mapped fields.</p>
21   *
22   * @author Apache Jakarta POI
23   * @author Scott Sanders (sanders at apache dot org)
24   * @author Marc Johnson (mjohnson at apache dot org)
25   * @author Andrew C. Oliver (acoliver at apache dot org)
26   * @author Stephen Colebourne
27   * @author Pete Gieser
28   * @author Gary Gregory
29   * @since 2.0
30   * @version $Id: BitField.java 437554 2006-08-28 06:21:41Z bayard $
31   */
32  public class BitField {
33      
34      private final int _mask;
35      private final int _shift_count;
36  
37      /**
38       * <p>Creates a BitField instance.</p>
39       *
40       * @param mask the mask specifying which bits apply to this
41       *  BitField. Bits that are set in this mask are the bits
42       *  that this BitField operates on
43       */
44      public BitField(int mask) {
45          _mask = mask;
46          int count = 0;
47          int bit_pattern = mask;
48  
49          if (bit_pattern != 0) {
50              while ((bit_pattern & 1) == 0) {
51                  count++;
52                  bit_pattern >>= 1;
53              }
54          }
55          _shift_count = count;
56      }
57  
58      /**
59       * <p>Obtains the value for the specified BitField, appropriately
60       * shifted right.</p>
61       *
62       * <p>Many users of a BitField will want to treat the specified
63       * bits as an int value, and will not want to be aware that the
64       * value is stored as a BitField (and so shifted left so many
65       * bits).</p>
66       *
67       * @see #setValue(int,int)
68       * @param holder the int data containing the bits we're interested
69       *  in
70       * @return the selected bits, shifted right appropriately
71       */
72      public int getValue(int holder) {
73          return getRawValue(holder) >> _shift_count;
74      }
75  
76      /**
77       * <p>Obtains the value for the specified BitField, appropriately
78       * shifted right, as a short.</p>
79       *
80       * <p>Many users of a BitField will want to treat the specified
81       * bits as an int value, and will not want to be aware that the
82       * value is stored as a BitField (and so shifted left so many
83       * bits).</p>
84       *
85       * @see #setShortValue(short,short)
86       * @param holder the short data containing the bits we're
87       *  interested in
88       * @return the selected bits, shifted right appropriately
89       */
90      public short getShortValue(short holder) {
91          return (short) getValue(holder);
92      }
93  
94      /**
95       * <p>Obtains the value for the specified BitField, unshifted.</p>
96       *
97       * @param holder the int data containing the bits we're
98       *  interested in
99       * @return the selected bits
100      */
101     public int getRawValue(int holder) {
102         return holder & _mask;
103     }
104 
105     /**
106      * <p>Obtains the value for the specified BitField, unshifted.</p>
107      *
108      * @param holder the short data containing the bits we're
109      *  interested in
110      * @return the selected bits
111      */
112     public short getShortRawValue(short holder) {
113         return (short) getRawValue(holder);
114     }
115 
116     /**
117      * <p>Returns whether the field is set or not.</p>
118      *
119      * <p>This is most commonly used for a single-bit field, which is
120      * often used to represent a boolean value; the results of using
121      * it for a multi-bit field is to determine whether *any* of its
122      * bits are set.</p>
123      *
124      * @param holder the int data containing the bits we're interested
125      *  in
126      * @return <code>true</code> if any of the bits are set,
127      *  else <code>false</code>
128      */
129     public boolean isSet(int holder) {
130         return (holder & _mask) != 0;
131     }
132 
133     /**
134      * <p>Returns whether all of the bits are set or not.</p>
135      *
136      * <p>This is a stricter test than {@link #isSet(int)},
137      * in that all of the bits in a multi-bit set must be set
138      * for this method to return <code>true</code>.</p>
139      *
140      * @param holder the int data containing the bits we're
141      *  interested in
142      * @return <code>true</code> if all of the bits are set,
143      *  else <code>false</code>
144      */
145     public boolean isAllSet(int holder) {
146         return (holder & _mask) == _mask;
147     }
148 
149     /**
150      * <p>Replaces the bits with new values.</p>
151      *
152      * @see #getValue(int)
153      * @param holder the int data containing the bits we're
154      *  interested in
155      * @param value the new value for the specified bits
156      * @return the value of holder with the bits from the value
157      *  parameter replacing the old bits
158      */
159     public int setValue(int holder, int value) {
160         return (holder & ~_mask) | ((value << _shift_count) & _mask);
161     }
162 
163     /**
164      * <p>Replaces the bits with new values.</p>
165      *
166      * @see #getShortValue(short)
167      * @param holder the short data containing the bits we're
168      *  interested in
169      * @param value the new value for the specified bits
170      * @return the value of holder with the bits from the value
171      *  parameter replacing the old bits
172      */
173     public short setShortValue(short holder, short value) {
174         return (short) setValue(holder, value);
175     }
176 
177     /**
178      * <p>Clears the bits.</p>
179      *
180      * @param holder the int data containing the bits we're
181      *  interested in
182      * @return the value of holder with the specified bits cleared
183      *  (set to <code>0</code>)
184      */
185     public int clear(int holder) {
186         return holder & ~_mask;
187     }
188 
189     /**
190      * <p>Clears the bits.</p>
191      *
192      * @param holder the short data containing the bits we're
193      *  interested in
194      * @return the value of holder with the specified bits cleared
195      *  (set to <code>0</code>)
196      */
197     public short clearShort(short holder) {
198         return (short) clear(holder);
199     }
200 
201     /**
202      * <p>Clears the bits.</p>
203      *
204      * @param holder the byte data containing the bits we're
205      *  interested in
206      *
207      * @return the value of holder with the specified bits cleared
208      *  (set to <code>0</code>)
209      */
210     public byte clearByte(byte holder) {
211         return (byte) clear(holder);
212     }
213 
214     /**
215      * <p>Sets the bits.</p>
216      *
217      * @param holder the int data containing the bits we're
218      *  interested in
219      * @return the value of holder with the specified bits set
220      *  to <code>1</code>
221      */
222     public int set(int holder) {
223         return holder | _mask;
224     }
225 
226     /**
227      * <p>Sets the bits.</p>
228      *
229      * @param holder the short data containing the bits we're
230      *  interested in
231      * @return the value of holder with the specified bits set
232      *  to <code>1</code>
233      */
234     public short setShort(short holder) {
235         return (short) set(holder);
236     }
237 
238     /**
239      * <p>Sets the bits.</p>
240      *
241      * @param holder the byte data containing the bits we're
242      *  interested in
243      *
244      * @return the value of holder with the specified bits set
245      *  to <code>1</code>
246      */
247     public byte setByte(byte holder) {
248         return (byte) set(holder);
249     }
250 
251     /**
252      * <p>Sets a boolean BitField.</p>
253      *
254      * @param holder the int data containing the bits we're
255      *  interested in
256      * @param flag indicating whether to set or clear the bits
257      * @return the value of holder with the specified bits set or
258      *         cleared
259      */
260     public int setBoolean(int holder, boolean flag) {
261         return flag ? set(holder) : clear(holder);
262     }
263 
264     /**
265      * <p>Sets a boolean BitField.</p>
266      *
267      * @param holder the short data containing the bits we're
268      *  interested in
269      * @param flag indicating whether to set or clear the bits
270      * @return the value of holder with the specified bits set or
271      *  cleared
272      */
273     public short setShortBoolean(short holder, boolean flag) {
274         return flag ? setShort(holder) : clearShort(holder);
275     }
276 
277     /**
278      * <p>Sets a boolean BitField.</p>
279      *
280      * @param holder the byte data containing the bits we're
281      *  interested in
282      * @param flag indicating whether to set or clear the bits
283      * @return the value of holder with the specified bits set or
284      *  cleared
285      */
286     public byte setByteBoolean(byte holder, boolean flag) {
287         return flag ? setByte(holder) : clearByte(holder);
288     }
289 
290 }