/*
* BitField - Container of a byte array representing set and unset bits.
* Copyright (C) 2003 Mark J. Wielaard
*
* This file is part of Snark.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.klomp.snark;
/**
* Container of a byte array representing set and unset bits.
*/
public class BitField
{
private final byte[] bitfield;
private final int size;
/**
* Creates a new BitField that represents <code>size</code> unset bits.
*/
public BitField (int size)
{
this.size = size;
int arraysize = ((size - 1) / 8) + 1;
bitfield = new byte[arraysize];
}
/**
* Creates a new BitField that represents <code>size</code> bits as set by
* the given byte array. This will make a copy of the array. Extra bytes
* will be ignored.
*
* @exception ArrayOutOfBoundsException
* if give byte array is not large enough.
*/
public BitField (byte[] bitfield, int size)
{
this.size = size;
int arraysize = ((size - 1) / 8) + 1;
this.bitfield = new byte[arraysize];
// XXX - More correct would be to check that unused bits are
// cleared or clear them explicitly ourselves.
System.arraycopy(bitfield, 0, this.bitfield, 0, arraysize);
}
/**
* This returns the actual byte array used. Changes to this array effect
* this BitField. Note that some bits at the end of the byte array are
* supposed to be always unset if they represent bits bigger then the size
* of the bitfield.
*/
public byte[] getFieldBytes ()
{
return bitfield;
}
/**
* Return the size of the BitField. The returned value is one bigger then
* the last valid bit number (since bit numbers are counted from zero).
*/
public int size ()
{
return size;
}
/**
* Sets the given bit to true.
*
* @exception IndexOutOfBoundsException
* if bit is smaller then zero bigger then size (inclusive).
*/
public void set (int bit)
{
if (bit < 0 || bit >= size) {
throw new IndexOutOfBoundsException(Integer.toString(bit));
}
int index = bit / 8;
int mask = 128 >> (bit % 8);
bitfield[index] |= mask;
}
/**
* Return true if the bit is set or false if it is not.
*
* @exception IndexOutOfBoundsException
* if bit is smaller then zero bigger then size (inclusive).
*/
public boolean get (int bit)
{
if (bit < 0 || bit >= size) {
throw new IndexOutOfBoundsException(Integer.toString(bit));
}
int index = bit / 8;
int mask = 128 >> (bit % 8);
return (bitfield[index] & mask) != 0;
}
@Override
public String toString ()
{
// Not very efficient
StringBuffer sb = new StringBuffer("BitField[");
for (int i = 0; i < size; i++) {
if (get(i)) {
sb.append(' ');
sb.append(i);
}
}
sb.append(" ]");
return sb.toString();
}
public String getHumanReadable()
{
StringBuffer sb = new StringBuffer();
for (int i = 0; i < size; i++) {
if (get(i)) {
sb.append('+');
} else {
sb.append('-');
}
}
return sb.toString();
}
}