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: */
017: package org.apache.commons.lang;
018:
019: /**
020: * <p>Operations on bit-mapped fields.</p>
021: *
022: * @author Apache Jakarta POI
023: * @author Scott Sanders (sanders at apache dot org)
024: * @author Marc Johnson (mjohnson at apache dot org)
025: * @author Andrew C. Oliver (acoliver at apache dot org)
026: * @author Stephen Colebourne
027: * @author Pete Gieser
028: * @author Gary Gregory
029: * @since 2.0
030: * @version $Id: BitField.java 437554 2006-08-28 06:21:41Z bayard $
031: */
032: public class BitField {
033:
034: private final int _mask;
035: private final int _shift_count;
036:
037: /**
038: * <p>Creates a BitField instance.</p>
039: *
040: * @param mask the mask specifying which bits apply to this
041: * BitField. Bits that are set in this mask are the bits
042: * that this BitField operates on
043: */
044: public BitField(int mask) {
045: _mask = mask;
046: int count = 0;
047: int bit_pattern = mask;
048:
049: if (bit_pattern != 0) {
050: while ((bit_pattern & 1) == 0) {
051: count++;
052: bit_pattern >>= 1;
053: }
054: }
055: _shift_count = count;
056: }
057:
058: /**
059: * <p>Obtains the value for the specified BitField, appropriately
060: * shifted right.</p>
061: *
062: * <p>Many users of a BitField will want to treat the specified
063: * bits as an int value, and will not want to be aware that the
064: * value is stored as a BitField (and so shifted left so many
065: * bits).</p>
066: *
067: * @see #setValue(int,int)
068: * @param holder the int data containing the bits we're interested
069: * in
070: * @return the selected bits, shifted right appropriately
071: */
072: public int getValue(int holder) {
073: return getRawValue(holder) >> _shift_count;
074: }
075:
076: /**
077: * <p>Obtains the value for the specified BitField, appropriately
078: * shifted right, as a short.</p>
079: *
080: * <p>Many users of a BitField will want to treat the specified
081: * bits as an int value, and will not want to be aware that the
082: * value is stored as a BitField (and so shifted left so many
083: * bits).</p>
084: *
085: * @see #setShortValue(short,short)
086: * @param holder the short data containing the bits we're
087: * interested in
088: * @return the selected bits, shifted right appropriately
089: */
090: public short getShortValue(short holder) {
091: return (short) getValue(holder);
092: }
093:
094: /**
095: * <p>Obtains the value for the specified BitField, unshifted.</p>
096: *
097: * @param holder the int data containing the bits we're
098: * interested in
099: * @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: }
|