1    
2    /* ====================================================================
3     * The Apache Software License, Version 1.1
4     *
5     * Copyright (c) 2002 The Apache Software Foundation.  All rights
6     * reserved.
7     *
8     * Redistribution and use in source and binary forms, with or without
9     * modification, are permitted provided that the following conditions
10    * are met:
11    *
12    * 1. Redistributions of source code must retain the above copyright
13    *    notice, this list of conditions and the following disclaimer.
14    *
15    * 2. Redistributions in binary form must reproduce the above copyright
16    *    notice, this list of conditions and the following disclaimer in
17    *    the documentation and/or other materials provided with the
18    *    distribution.
19    *
20    * 3. The end-user documentation included with the redistribution,
21    *    if any, must include the following acknowledgment:
22    *       "This product includes software developed by the
23    *        Apache Software Foundation (http://www.apache.org/)."
24    *    Alternately, this acknowledgment may appear in the software itself,
25    *    if and wherever such third-party acknowledgments normally appear.
26    *
27    * 4. The names "Apache" and "Apache Software Foundation" and
28    *    "Apache POI" must not be used to endorse or promote products
29    *    derived from this software without prior written permission. For
30    *    written permission, please contact apache@apache.org.
31    *
32    * 5. Products derived from this software may not be called "Apache",
33    *    "Apache POI", nor may "Apache" appear in their name, without
34    *    prior written permission of the Apache Software Foundation.
35    *
36    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    * SUCH DAMAGE.
48    * ====================================================================
49    *
50    * This software consists of voluntary contributions made by many
51    * individuals on behalf of the Apache Software Foundation.  For more
52    * information on the Apache Software Foundation, please see
53    * <http://www.apache.org/>.
54    */
55   
56   package org.apache.poi.util;
57   
58   /**
59    * Manage operations dealing with bit-mapped fields.
60    *
61    * @author Marc Johnson (mjohnson at apache dot org)
62    * @author Andrew C. Oliver (acoliver at apache dot org)
63    */
64   
65   public class BitField
66   {
67       private final int _mask;
68       private final int _shift_count;
69   
70       /**
71        * Create a BitField instance
72        *
73        * @param mask the mask specifying which bits apply to this
74        *             BitField. Bits that are set in this mask are the
75        *             bits that this BitField operates on
76        */
77   
78       public BitField(final int mask)
79       {
80           _mask = mask;
81           int count       = 0;
82           int bit_pattern = mask;
83   
84           if (bit_pattern != 0)
85           {
86               while ((bit_pattern & 1) == 0)
87               {
88                   count++;
89                   bit_pattern >>= 1;
90               }
91           }
92           _shift_count = count;
93       }
94   
95       /**
96        * Obtain the value for the specified BitField, appropriately
97        * shifted right. Many users of a BitField will want to treat the
98        * specified bits as an int value, and will not want to be aware
99        * that the value is stored as a BitField (and so shifted left so
100       * many bits)
101       *
102       * @param holder the int data containing the bits we're interested
103       *               in
104       *
105       * @return the selected bits, shifted right appropriately
106       */
107  
108      public int getValue(final int holder)
109      {
110          return getRawValue(holder) >> _shift_count;
111      }
112  
113      /**
114       * Obtain the value for the specified BitField, appropriately
115       * shifted right, as a short. Many users of a BitField will want
116       * to treat the specified bits as an int value, and will not want
117       * to be aware that the value is stored as a BitField (and so
118       * shifted left so many bits)
119       *
120       * @param holder the short data containing the bits we're
121       *               interested in
122       *
123       * @return the selected bits, shifted right appropriately
124       */
125  
126      public short getShortValue(final short holder)
127      {
128          return ( short ) getValue(holder);
129      }
130  
131      /**
132       * Obtain the value for the specified BitField, unshifted
133       *
134       * @param holder the int data containing the bits we're interested
135       *               in
136       *
137       * @return the selected bits
138       */
139  
140      public int getRawValue(final int holder)
141      {
142          return (holder & _mask);
143      }
144  
145      /**
146       * Obtain the value for the specified BitField, unshifted
147       *
148       * @param holder the short data containing the bits we're
149       *               interested in
150       *
151       * @return the selected bits
152       */
153  
154      public short getShortRawValue(final short holder)
155      {
156          return ( short ) getRawValue(holder);
157      }
158  
159      /**
160       * Is the field set or not? This is most commonly used for a
161       * single-bit field, which is often used to represent a boolean
162       * value; the results of using it for a multi-bit field is to
163       * determine whether *any* of its bits are set
164       *
165       * @param holder the int data containing the bits we're interested
166       *               in
167       *
168       * @return true if any of the bits are set, else false
169       */
170  
171      public boolean isSet(final int holder)
172      {
173          return (holder & _mask) != 0;
174      }
175  
176      /**
177       * Are all of the bits set or not? This is a stricter test than
178       * isSet, in that all of the bits in a multi-bit set must be set
179       * for this method to return true
180       *
181       * @param holder the int data containing the bits we're interested
182       *               in
183       *
184       * @return true if all of the bits are set, else false
185       */
186  
187      public boolean isAllSet(final int holder)
188      {
189          return (holder & _mask) == _mask;
190      }
191  
192      /**
193       * Replace the bits with new values.
194       *
195       * @param holder the int data containint the bits we're interested
196       *               in
197       * @param value the new value for the specified bits
198       *
199       * @return the value of holder with the bits from the value
200       *         parameter replacing the old bits
201       */
202  
203      public int setValue(final int holder, final int value)
204      {
205          return (holder & ~_mask) | ((value << _shift_count) & _mask);
206      }
207  
208      /**
209       * Replace the bits with new values.
210       *
211       * @param holder the short data containing the bits we're
212       *               interested in
213       * @param value the new value for the specified bits
214       *
215       * @return the value of holder with the bits from the value
216       *         parameter replacing the old bits
217       */
218  
219      public short setShortValue(final short holder, final short value)
220      {
221          return ( short ) setValue(holder, value);
222      }
223  
224      /**
225       * Clear the bits.
226       *
227       * @param holder the int data containing the bits we're interested
228       *               in
229       *
230       * @return the value of holder with the specified bits cleared
231       *         (set to 0)
232       */
233  
234      public int clear(final int holder)
235      {
236          return holder & ~_mask;
237      }
238  
239      /**
240       * Clear the bits.
241       *
242       * @param holder the short data containing the bits we're
243       *               interested in
244       *
245       * @return the value of holder with the specified bits cleared
246       *         (set to 0)
247       */
248  
249      public short clearShort(final short holder)
250      {
251          return ( short ) clear(holder);
252      }
253  
254      /**
255       * Clear the bits.
256       *
257       * @param holder the byte data containing the bits we're
258       *               interested in
259       *
260       * @return the value of holder with the specified bits cleared
261       *         (set to 0)
262       */
263  
264      public byte clearByte(final byte holder)
265      {
266          return ( byte ) clear(holder);
267      }
268  
269      /**
270       * Set the bits.
271       *
272       * @param holder the int data containing the bits we're interested
273       *               in
274       *
275       * @return the value of holder with the specified bits set to 1
276       */
277  
278      public int set(final int holder)
279      {
280          return holder | _mask;
281      }
282  
283      /**
284       * Set the bits.
285       *
286       * @param holder the short data containing the bits we're
287       *               interested in
288       *
289       * @return the value of holder with the specified bits set to 1
290       */
291  
292      public short setShort(final short holder)
293      {
294          return ( short ) set(holder);
295      }
296  
297      /**
298       * Set the bits.
299       *
300       * @param holder the byte data containing the bits we're
301       *               interested in
302       *
303       * @return the value of holder with the specified bits set to 1
304       */
305  
306      public byte setByte(final byte holder)
307      {
308          return ( byte ) set(holder);
309      }
310  
311      /**
312       * Set a boolean BitField
313       *
314       * @param holder the int data containing the bits we're interested
315       *               in
316       * @param flag indicating whether to set or clear the bits
317       *
318       * @return the value of holder with the specified bits set or
319       *         cleared
320       */
321  
322      public int setBoolean(final int holder, final boolean flag)
323      {
324          return flag ? set(holder)
325                      : clear(holder);
326      }
327  
328      /**
329       * Set a boolean BitField
330       *
331       * @param holder the short data containing the bits we're
332       *               interested in
333       * @param flag indicating whether to set or clear the bits
334       *
335       * @return the value of holder with the specified bits set or
336       *         cleared
337       */
338  
339      public short setShortBoolean(final short holder, final boolean flag)
340      {
341          return flag ? setShort(holder)
342                      : clearShort(holder);
343      }
344  
345      /**
346       * Set a boolean BitField
347       *
348       * @param holder the byte data containing the bits we're
349       *               interested in
350       * @param flag indicating whether to set or clear the bits
351       *
352       * @return the value of holder with the specified bits set or
353       *         cleared
354       */
355  
356      public byte setByteBoolean(final byte holder, final boolean flag)
357      {
358          return flag ? setByte(holder)
359                      : clearByte(holder);
360      }
361  }   // end public class BitField
362  
363