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