// Copyright (c) 2002 Dustin Sallings <dustin@spy.net> package net.spy.util; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * An array of bits. * * The initial version of this is not intended to be efficient. */ public class BitArray extends Object { private final List<Integer> bitList; /** * Get an instance of BitArray with storage for a given number of bits. */ public BitArray(int size) { super(); bitList=new ArrayList<Integer>(size); } /** * Get an intance of BitArray. */ public BitArray() { super(); bitList=new ArrayList<Integer>(); } /** * Get a BitArray by parsing a string. * * The string must only contain the characters 0 (zero), 1 (one), and * whitespace. * * @param bitString the string containing zeros and ones */ public BitArray(String bitString) { this(bitString.length()); char[] acters=bitString.toCharArray(); for(char c : acters) { if(!Character.isWhitespace(c)) { switch(c) { case '0': add(false); break; case '1': add(true); break; default: throw new IllegalArgumentException( "Only 0, 1, and whitespace is allowed."); } // switch - My name is Dustin Sallings, and I'm a programmer } // Ignore whitespace } // All characters } /** * Add a bit. * * @param value if true, add a one bit. */ public void add(boolean value) { if(value) { bitList.add(1); } else { bitList.add(0); } } /** * Add a set of bits from an integer. * * @param bitSet the integer containing the bits * @param numBits the number of bits to add. */ public void addBits(int bitSet, int numBits) { List<Integer> bitsToAdd=new ArrayList<Integer>(numBits); for(int i=0; i<numBits; i++) { if( (bitSet&0x1) == 0) { bitsToAdd.add(0); } else { bitsToAdd.add(1); } bitSet>>=1; } Collections.reverse(bitsToAdd); bitList.addAll(bitsToAdd); } /** * Remove a give number of bits from the MSB side. * * @param howMany bits to remove */ public void removeMSBBits(int howMany) { removeBits(0, howMany); } /** * Remove a give number of bits from the LSB side. * * @param howMany bits to remove */ public void removeLSBBits(int howMany) { removeBits(bitList.size()-howMany, howMany); } /** * Remove a specific number of bits from a specific location. * * @param from starting point * @param howMany number of bits to remove. */ public void removeBits(int from, int howMany) { bitList.subList(from, from+howMany).clear(); } /** * Get a given number of bits from a given offset. * * @param from starting offset (from MSB side). * @param number number of bits to retrieve * * @return an integer containing those bits * @exception IllegalArgumentException if number > 32 * @exception IndexOutOfBoundsException if the bit range would specify * bits we don't have */ public int getBits(int from, int number) { if(number > 31) { throw new IllegalArgumentException( "Bits requested would exceed integer precision."); } int rv=0; // Get a sublist to walk List<Integer> l=bitList.subList(from, from+number); for(int iTmp : l) { // Make room for the new bit rv<<=1; // Add it rv|=iTmp; } return(rv); } /** * Get a given number of the most significant bits. * * @param numBits number of bits to get * @return an int representing the bits requested * * @exception IllegalArgumentException if numBits greater than 31 or * the number of bits remaining in the bit list */ public int getMSBBits(int numBits) { return(getBits(0, numBits)); } /** * Get a given number of the least significant bits. * * @param numBits number of bits to get * @return an int representing the bits requested * * @exception IllegalArgumentException if numBits greater than 31 or * the number of bits remaining in the bit list */ public int getLSBBits(int numBits) { return(getBits((bitList.size()-numBits), numBits)); } /** * Get the number of bits remaining in the bit set. */ public int size() { return(bitList.size()); } /** * String me. */ @Override public String toString() { StringBuilder sb=new StringBuilder(bitList.size()); for(int i : bitList) { sb.append(i); } return(sb.toString()); } }