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:
018: package org.apache.poi.util;
019:
020: /**
021: * Manage operations dealing with bit-mapped fields.
022: *
023: * @author Marc Johnson (mjohnson at apache dot org)
024: * @author Andrew C. Oliver (acoliver at apache dot org)
025: */
026:
027: public class BitField {
028: private final int _mask;
029: private final int _shift_count;
030:
031: /**
032: * Create a BitField instance
033: *
034: * @param mask the mask specifying which bits apply to this
035: * BitField. Bits that are set in this mask are the
036: * bits that this BitField operates on
037: */
038:
039: public BitField(final int mask) {
040: _mask = mask;
041: int count = 0;
042: int bit_pattern = mask;
043:
044: if (bit_pattern != 0) {
045: while ((bit_pattern & 1) == 0) {
046: count++;
047: bit_pattern >>= 1;
048: }
049: }
050: _shift_count = count;
051: }
052:
053: /**
054: * Obtain the value for the specified BitField, appropriately
055: * shifted right. Many users of a BitField will want to treat the
056: * specified bits as an int value, and will not want to be aware
057: * that the value is stored as a BitField (and so shifted left so
058: * many bits)
059: *
060: * @param holder the int data containing the bits we're interested
061: * in
062: *
063: * @return the selected bits, shifted right appropriately
064: */
065:
066: public int getValue(final int holder) {
067: return getRawValue(holder) >> _shift_count;
068: }
069:
070: /**
071: * Obtain the value for the specified BitField, appropriately
072: * shifted right, as a short. Many users of a BitField will want
073: * to treat the specified bits as an int value, and will not want
074: * to be aware that the value is stored as a BitField (and so
075: * shifted left so many bits)
076: *
077: * @param holder the short data containing the bits we're
078: * interested in
079: *
080: * @return the selected bits, shifted right appropriately
081: */
082:
083: public short getShortValue(final short holder) {
084: return (short) getValue(holder);
085: }
086:
087: /**
088: * Obtain the value for the specified BitField, unshifted
089: *
090: * @param holder the int data containing the bits we're interested
091: * in
092: *
093: * @return the selected bits
094: */
095:
096: public int getRawValue(final int holder) {
097: return (holder & _mask);
098: }
099:
100: /**
101: * Obtain the value for the specified BitField, unshifted
102: *
103: * @param holder the short data containing the bits we're
104: * interested in
105: *
106: * @return the selected bits
107: */
108:
109: public short getShortRawValue(final short holder) {
110: return (short) getRawValue(holder);
111: }
112:
113: /**
114: * Is the field set or not? This is most commonly used for a
115: * single-bit field, which is often used to represent a boolean
116: * value; the results of using it for a multi-bit field is to
117: * determine whether *any* of its bits are set
118: *
119: * @param holder the int data containing the bits we're interested
120: * in
121: *
122: * @return true if any of the bits are set, else false
123: */
124:
125: public boolean isSet(final int holder) {
126: return (holder & _mask) != 0;
127: }
128:
129: /**
130: * Are all of the bits set or not? This is a stricter test than
131: * isSet, in that all of the bits in a multi-bit set must be set
132: * for this method to return true
133: *
134: * @param holder the int data containing the bits we're interested
135: * in
136: *
137: * @return true if all of the bits are set, else false
138: */
139:
140: public boolean isAllSet(final int holder) {
141: return (holder & _mask) == _mask;
142: }
143:
144: /**
145: * Replace the bits with new values.
146: *
147: * @param holder the int data containint the bits we're interested
148: * in
149: * @param value the new value for the specified bits
150: *
151: * @return the value of holder with the bits from the value
152: * parameter replacing the old bits
153: */
154:
155: public int setValue(final int holder, final int value) {
156: return (holder & ~_mask) | ((value << _shift_count) & _mask);
157: }
158:
159: /**
160: * Replace the bits with new values.
161: *
162: * @param holder the short data containing the bits we're
163: * interested in
164: * @param value the new value for the specified bits
165: *
166: * @return the value of holder with the bits from the value
167: * parameter replacing the old bits
168: */
169:
170: public short setShortValue(final short holder, final short value) {
171: return (short) setValue(holder, value);
172: }
173:
174: /**
175: * Clear the bits.
176: *
177: * @param holder the int data containing the bits we're interested
178: * in
179: *
180: * @return the value of holder with the specified bits cleared
181: * (set to 0)
182: */
183:
184: public int clear(final int holder) {
185: return holder & ~_mask;
186: }
187:
188: /**
189: * Clear the bits.
190: *
191: * @param holder the short data containing the bits we're
192: * interested in
193: *
194: * @return the value of holder with the specified bits cleared
195: * (set to 0)
196: */
197:
198: public short clearShort(final short holder) {
199: return (short) clear(holder);
200: }
201:
202: /**
203: * Clear the bits.
204: *
205: * @param holder the byte data containing the bits we're
206: * interested in
207: *
208: * @return the value of holder with the specified bits cleared
209: * (set to 0)
210: */
211:
212: public byte clearByte(final byte holder) {
213: return (byte) clear(holder);
214: }
215:
216: /**
217: * Set the bits.
218: *
219: * @param holder the int data containing the bits we're interested
220: * in
221: *
222: * @return the value of holder with the specified bits set to 1
223: */
224:
225: public int set(final int holder) {
226: return holder | _mask;
227: }
228:
229: /**
230: * Set the bits.
231: *
232: * @param holder the short data containing the bits we're
233: * interested in
234: *
235: * @return the value of holder with the specified bits set to 1
236: */
237:
238: public short setShort(final short holder) {
239: return (short) set(holder);
240: }
241:
242: /**
243: * Set the bits.
244: *
245: * @param holder the byte data containing the bits we're
246: * interested in
247: *
248: * @return the value of holder with the specified bits set to 1
249: */
250:
251: public byte setByte(final byte holder) {
252: return (byte) set(holder);
253: }
254:
255: /**
256: * Set a boolean BitField
257: *
258: * @param holder the int data containing the bits we're interested
259: * in
260: * @param flag indicating whether to set or clear the bits
261: *
262: * @return the value of holder with the specified bits set or
263: * cleared
264: */
265:
266: public int setBoolean(final int holder, final boolean flag) {
267: return flag ? set(holder) : clear(holder);
268: }
269:
270: /**
271: * Set a boolean BitField
272: *
273: * @param holder the short data containing the bits we're
274: * interested in
275: * @param flag indicating whether to set or clear the bits
276: *
277: * @return the value of holder with the specified bits set or
278: * cleared
279: */
280:
281: public short setShortBoolean(final short holder, final boolean flag) {
282: return flag ? setShort(holder) : clearShort(holder);
283: }
284:
285: /**
286: * Set a boolean BitField
287: *
288: * @param holder the byte data containing the bits we're
289: * interested in
290: * @param flag indicating whether to set or clear the bits
291: *
292: * @return the value of holder with the specified bits set or
293: * cleared
294: */
295:
296: public byte setByteBoolean(final byte holder, final boolean flag) {
297: return flag ? setByte(holder) : clearByte(holder);
298: }
299: } // end public class BitField
|