diff --git a/src/java/org/apache/commons/lang/util/BitField.java b/src/java/org/apache/commons/lang/util/BitField.java new file mode 100644 index 000000000..f91700e24 --- /dev/null +++ b/src/java/org/apache/commons/lang/util/BitField.java @@ -0,0 +1,340 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.util; + +/** + * Manage operations dealing with bit-mapped fields. + *

+ * Code originated from the POI project. + * + * @author Scott Sanders (sanders at apache dot org) + * @author Marc Johnson (mjohnson at apache dot org) + * @author Andrew C. Oliver (acoliver at apache dot org) + * @author Stephen Colebourne + * @version $Id: BitField.java,v 1.1 2002/12/18 02:50:36 bayard Exp $ + */ +public class BitField { + private final int _mask; + private final int _shift_count; + + /** + * Create a BitField instance + * + * @param mask the mask specifying which bits apply to this + * BitField. Bits that are set in this mask are the + * bits that this BitField operates on + */ + + public BitField(final int mask) { + _mask = mask; + int count = 0; + int bit_pattern = mask; + + if (bit_pattern != 0) { + while ((bit_pattern & 1) == 0) { + count++; + bit_pattern >>= 1; + } + } + _shift_count = count; + } + + /** + * Obtain the value for the specified BitField, appropriately + * shifted right. Many users of a BitField will want to treat the + * specified bits as an int value, and will not want to be aware + * that the value is stored as a BitField (and so shifted left so + * many bits) + * + * @param holder the int data containing the bits we're interested + * in + * + * @return the selected bits, shifted right appropriately + */ + + public int getValue(final int holder) { + return getRawValue(holder) >> _shift_count; + } + + /** + * Obtain the value for the specified BitField, appropriately + * shifted right, as a short. Many users of a BitField will want + * to treat the specified bits as an int value, and will not want + * to be aware that the value is stored as a BitField (and so + * shifted left so many bits) + * + * @param holder the short data containing the bits we're + * interested in + * + * @return the selected bits, shifted right appropriately + */ + + public short getShortValue(final short holder) { + return (short) getValue(holder); + } + + /** + * Obtain the value for the specified BitField, unshifted + * + * @param holder the int data containing the bits we're interested + * in + * + * @return the selected bits + */ + + public int getRawValue(final int holder) { + return (holder & _mask); + } + + /** + * Obtain the value for the specified BitField, unshifted + * + * @param holder the short data containing the bits we're + * interested in + * + * @return the selected bits + */ + + public short getShortRawValue(final short holder) { + return (short) getRawValue(holder); + } + + /** + * Is the field set or not? This is most commonly used for a + * single-bit field, which is often used to represent a boolean + * value; the results of using it for a multi-bit field is to + * determine whether *any* of its bits are set + * + * @param holder the int data containing the bits we're interested + * in + * + * @return true if any of the bits are set, else false + */ + + public boolean isSet(final int holder) { + return (holder & _mask) != 0; + } + + /** + * Are all of the bits set or not? This is a stricter test than + * isSet, in that all of the bits in a multi-bit set must be set + * for this method to return true + * + * @param holder the int data containing the bits we're interested + * in + * + * @return true if all of the bits are set, else false + */ + + public boolean isAllSet(final int holder) { + return (holder & _mask) == _mask; + } + + /** + * Replace the bits with new values. + * + * @param holder the int data containint the bits we're interested + * in + * @param value the new value for the specified bits + * + * @return the value of holder with the bits from the value + * parameter replacing the old bits + */ + + public int setValue(final int holder, final int value) { + return (holder & ~_mask) | ((value << _shift_count) & _mask); + } + + /** + * Replace the bits with new values. + * + * @param holder the short data containing the bits we're + * interested in + * @param value the new value for the specified bits + * + * @return the value of holder with the bits from the value + * parameter replacing the old bits + */ + + public short setShortValue(final short holder, final short value) { + return (short) setValue(holder, value); + } + + /** + * Clear the bits. + * + * @param holder the int data containing the bits we're interested + * in + * + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + + public int clear(final int holder) { + return holder & ~_mask; + } + + /** + * Clear the bits. + * + * @param holder the short data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + + public short clearShort(final short holder) { + return (short) clear(holder); + } + + /** + * Clear the bits. + * + * @param holder the byte data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits cleared + * (set to 0) + */ + + public byte clearByte(final byte holder) { + return (byte) clear(holder); + } + + /** + * Set the bits. + * + * @param holder the int data containing the bits we're interested + * in + * + * @return the value of holder with the specified bits set to 1 + */ + + public int set(final int holder) { + return holder | _mask; + } + + /** + * Set the bits. + * + * @param holder the short data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits set to 1 + */ + + public short setShort(final short holder) { + return (short) set(holder); + } + + /** + * Set the bits. + * + * @param holder the byte data containing the bits we're + * interested in + * + * @return the value of holder with the specified bits set to 1 + */ + + public byte setByte(final byte holder) { + return (byte) set(holder); + } + + /** + * Set a boolean BitField + * + * @param holder the int data containing the bits we're interested + * in + * @param flag indicating whether to set or clear the bits + * + * @return the value of holder with the specified bits set or + * cleared + */ + + public int setBoolean(final int holder, final boolean flag) { + return flag ? set(holder) : clear(holder); + } + + /** + * Set a boolean BitField + * + * @param holder the short data containing the bits we're + * interested in + * @param flag indicating whether to set or clear the bits + * + * @return the value of holder with the specified bits set or + * cleared + */ + + public short setShortBoolean(final short holder, final boolean flag) { + return flag ? setShort(holder) : clearShort(holder); + } + + /** + * Set a boolean BitField + * + * @param holder the byte data containing the bits we're + * interested in + * @param flag indicating whether to set or clear the bits + * + * @return the value of holder with the specified bits set or + * cleared + */ + + public byte setByteBoolean(final byte holder, final boolean flag) { + return flag ? setByte(holder) : clearByte(holder); + } + +} diff --git a/src/test/org/apache/commons/lang/util/BitFieldTest.java b/src/test/org/apache/commons/lang/util/BitFieldTest.java new file mode 100644 index 000000000..bd997b802 --- /dev/null +++ b/src/test/org/apache/commons/lang/util/BitFieldTest.java @@ -0,0 +1,337 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//lang/src/test/org/apache/commons/lang/util/Attic/BitFieldTest.java,v 1.1 2002/12/18 02:50:36 bayard Exp $ + * $Revision: 1.1 $ + * $Date: 2002/12/18 02:50:36 $ + * + * ==================================================================== + * + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.lang.util; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +/** + * Class to test BitField functionality + * + * @author Scott Sanders (sanders at apache dot org) + * @author Marc Johnson + * @author Glen Stampoultzis (gstamp@iprimus.com.au) + * @version $Id: BitFieldTest.java,v 1.1 2002/12/18 02:50:36 bayard Exp $ + */ + +public class BitFieldTest + extends TestCase +{ + + public static void main(String[] args) { + TestRunner.run(suite()); + } + + public static Test suite() { + TestSuite suite = new TestSuite(BitFieldTest.class); + suite.setName("BitField Tests"); + return suite; + } + + private static BitField bf_multi = new BitField(0x3F80); + private static BitField bf_single = new BitField(0x4000); + + /** + * Constructor BitFieldTest + * + * @param name + */ + + public BitFieldTest(String name) + { + super(name); + } + + /** + * test the getValue() method + */ + + public void testGetValue() + { + assertEquals(bf_multi.getValue(-1), 127); + assertEquals(bf_multi.getValue(0), 0); + assertEquals(bf_single.getValue(-1), 1); + assertEquals(bf_single.getValue(0), 0); + } + + /** + * test the getShortValue() method + */ + + public void testGetShortValue() + { + assertEquals(bf_multi.getShortValue(( short ) -1), ( short ) 127); + assertEquals(bf_multi.getShortValue(( short ) 0), ( short ) 0); + assertEquals(bf_single.getShortValue(( short ) -1), ( short ) 1); + assertEquals(bf_single.getShortValue(( short ) 0), ( short ) 0); + } + + /** + * test the getRawValue() method + */ + + public void testGetRawValue() + { + assertEquals(bf_multi.getRawValue(-1), 0x3F80); + assertEquals(bf_multi.getRawValue(0), 0); + assertEquals(bf_single.getRawValue(-1), 0x4000); + assertEquals(bf_single.getRawValue(0), 0); + } + + /** + * test the getShortRawValue() method + */ + + public void testGetShortRawValue() + { + assertEquals(bf_multi.getShortRawValue(( short ) -1), + ( short ) 0x3F80); + assertEquals(bf_multi.getShortRawValue(( short ) 0), ( short ) 0); + assertEquals(bf_single.getShortRawValue(( short ) -1), + ( short ) 0x4000); + assertEquals(bf_single.getShortRawValue(( short ) 0), ( short ) 0); + } + + /** + * test the isSet() method + */ + + public void testIsSet() + { + assertTrue(!bf_multi.isSet(0)); + for (int j = 0x80; j <= 0x3F80; j += 0x80) + { + assertTrue(bf_multi.isSet(j)); + } + assertTrue(!bf_single.isSet(0)); + assertTrue(bf_single.isSet(0x4000)); + } + + /** + * test the isAllSet() method + */ + + public void testIsAllSet() + { + for (int j = 0; j < 0x3F80; j += 0x80) + { + assertTrue(!bf_multi.isAllSet(j)); + } + assertTrue(bf_multi.isAllSet(0x3F80)); + assertTrue(!bf_single.isAllSet(0)); + assertTrue(bf_single.isAllSet(0x4000)); + } + + /** + * test the setValue() method + */ + + public void testSetValue() + { + for (int j = 0; j < 128; j++) + { + assertEquals(bf_multi.getValue(bf_multi.setValue(0, j)), j); + assertEquals(bf_multi.setValue(0, j), j << 7); + } + + // verify that excess bits are stripped off + assertEquals(bf_multi.setValue(0x3f80, 128), 0); + for (int j = 0; j < 2; j++) + { + assertEquals(bf_single.getValue(bf_single.setValue(0, j)), j); + assertEquals(bf_single.setValue(0, j), j << 14); + } + + // verify that excess bits are stripped off + assertEquals(bf_single.setValue(0x4000, 2), 0); + } + + /** + * test the setShortValue() method + */ + + public void testSetShortValue() + { + for (int j = 0; j < 128; j++) + { + assertEquals(bf_multi + .getShortValue(bf_multi + .setShortValue(( short ) 0, ( short ) j)), ( short ) j); + assertEquals(bf_multi.setShortValue(( short ) 0, ( short ) j), + ( short ) (j << 7)); + } + + // verify that excess bits are stripped off + assertEquals(bf_multi.setShortValue(( short ) 0x3f80, ( short ) 128), + ( short ) 0); + for (int j = 0; j < 2; j++) + { + assertEquals(bf_single + .getShortValue(bf_single + .setShortValue(( short ) 0, ( short ) j)), ( short ) j); + assertEquals(bf_single.setShortValue(( short ) 0, ( short ) j), + ( short ) (j << 14)); + } + + // verify that excess bits are stripped off + assertEquals(bf_single.setShortValue(( short ) 0x4000, ( short ) 2), + ( short ) 0); + } + + public void testByte() + { + assertEquals(1, new BitField(1).setByteBoolean(( byte ) 0, true)); + assertEquals(2, new BitField(2).setByteBoolean(( byte ) 0, true)); + assertEquals(4, new BitField(4).setByteBoolean(( byte ) 0, true)); + assertEquals(8, new BitField(8).setByteBoolean(( byte ) 0, true)); + assertEquals(16, new BitField(16).setByteBoolean(( byte ) 0, true)); + assertEquals(32, new BitField(32).setByteBoolean(( byte ) 0, true)); + assertEquals(64, new BitField(64).setByteBoolean(( byte ) 0, true)); + assertEquals(-128, + new BitField(128).setByteBoolean(( byte ) 0, true)); + assertEquals(0, new BitField(1).setByteBoolean(( byte ) 1, false)); + assertEquals(0, new BitField(2).setByteBoolean(( byte ) 2, false)); + assertEquals(0, new BitField(4).setByteBoolean(( byte ) 4, false)); + assertEquals(0, new BitField(8).setByteBoolean(( byte ) 8, false)); + assertEquals(0, new BitField(16).setByteBoolean(( byte ) 16, false)); + assertEquals(0, new BitField(32).setByteBoolean(( byte ) 32, false)); + assertEquals(0, new BitField(64).setByteBoolean(( byte ) 64, false)); + assertEquals(0, new BitField(128).setByteBoolean(( byte ) 128, + false)); + assertEquals(-2, new BitField(1).setByteBoolean(( byte ) 255, false)); + byte clearedBit = new BitField(0x40).setByteBoolean(( byte ) -63, + false); + + assertEquals(false, new BitField(0x40).isSet(clearedBit)); + } + + /** + * test the clear() method + */ + + public void testClear() + { + assertEquals(bf_multi.clear(-1), 0xFFFFC07F); + assertEquals(bf_single.clear(-1), 0xFFFFBFFF); + } + + /** + * test the clearShort() method + */ + + public void testClearShort() + { + assertEquals(bf_multi.clearShort(( short ) -1), ( short ) 0xC07F); + assertEquals(bf_single.clearShort(( short ) -1), ( short ) 0xBFFF); + } + + /** + * test the set() method + */ + + public void testSet() + { + assertEquals(bf_multi.set(0), 0x3F80); + assertEquals(bf_single.set(0), 0x4000); + } + + /** + * test the setShort() method + */ + + public void testSetShort() + { + assertEquals(bf_multi.setShort(( short ) 0), ( short ) 0x3F80); + assertEquals(bf_single.setShort(( short ) 0), ( short ) 0x4000); + } + + /** + * test the setBoolean() method + */ + + public void testSetBoolean() + { + assertEquals(bf_multi.set(0), bf_multi.setBoolean(0, true)); + assertEquals(bf_single.set(0), bf_single.setBoolean(0, true)); + assertEquals(bf_multi.clear(-1), bf_multi.setBoolean(-1, false)); + assertEquals(bf_single.clear(-1), bf_single.setBoolean(-1, false)); + } + + /** + * test the setShortBoolean() method + */ + + public void testSetShortBoolean() + { + assertEquals(bf_multi.setShort(( short ) 0), + bf_multi.setShortBoolean(( short ) 0, true)); + assertEquals(bf_single.setShort(( short ) 0), + bf_single.setShortBoolean(( short ) 0, true)); + assertEquals(bf_multi.clearShort(( short ) -1), + bf_multi.setShortBoolean(( short ) -1, false)); + assertEquals(bf_single.clearShort(( short ) -1), + bf_single.setShortBoolean(( short ) -1, false)); + } + +} diff --git a/src/test/org/apache/commons/lang/util/UtilTestSuite.java b/src/test/org/apache/commons/lang/util/UtilTestSuite.java new file mode 100644 index 000000000..07d1c1c04 --- /dev/null +++ b/src/test/org/apache/commons/lang/util/UtilTestSuite.java @@ -0,0 +1,91 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.util; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; +/** + * Test suite for the Util package. + * + * @author Henri Yandell + * @version $Id: UtilTestSuite.java,v 1.1 2002/12/18 02:50:36 bayard Exp $ + */ +public class UtilTestSuite extends TestCase { + + /** + * Construct a new instance. + */ + public UtilTestSuite(String name) { + super(name); + } + + /** + * Command-line interface. + */ + public static void main(String[] args) { + TestRunner.run(suite()); + } + + /** + * Get the suite of tests + */ + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.setName("Commons-Lang-Util Tests"); + suite.addTest(BitFieldTest.suite()); + return suite; + } +}