/* * Copyright (c) 2006-2007 Graz University of Technology. 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 names "Graz University of Technology" and "IAIK of Graz University of * Technology" must not be used to endorse or promote products derived from * this software without prior written permission. * * 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 LICENSOR 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. */ package ejip.jtcpip.util; /** * Class to handle Bitmaps * * @author Ulrich Feichter * @author Tobias Kellner * @author Christof Rath * @version $Rev: 939 $ $Date: 2007/01/24 19:36:48 $ */ public class Bitmap { /** Size of the bitmap in bits */ int size; /** Bit pool */ byte[] bitmap; /** * Initalizes the bitmap. * * @param size * Desired number of bits in the bitmap */ public Bitmap(int size) { this.size = size; bitmap = new byte[NumFunctions.divRoundUp(size, 8)]; // if the size doesn't fall onto a byte boundary add another byte } /** * Clears the complete bitmap. */ public void clearBitmap() { for (int i = 0; i < bitmap.length; i++) bitmap[i] = 0; } /** * Sets a single bit in the bitmap. * * @param pos * Position of the bit to set */ public void setBit(int pos) { if (pos < size) bitmap[pos / 8] |= (byte) (1 << (pos % 8)); } /** * Clears a single bit in the bitmap * * @param pos */ public void clearBit(int pos) { if (pos < size) bitmap[pos / 8] &= ~(byte) (1 << (pos % 8)); } /** * Sets multiple bits. Set <code>count</code> bits, starting at * <code>pos</code>. * * @param pos * Position of the first bit to set * @param count * Number of bits to set */ public void setBits(int pos, int count) { if (pos >= size) return; if ((pos + count) >= size) count = (size - pos); if (pos % 8 > 0) // pos doesn'f fall on a byte boundary { // => handle the first bits bit per bit int i; for (i = pos; i < (pos + Math.min(8 - (pos % 8), count)); i++) setBit(i); count -= (i - pos); pos = i; } if (count == 0) return; if (count % 8 > 0) // the last bits do not fall on a byte boundary { // => handle the last bits bit per bit for (int i = (pos + count - (count % 8)); i < (pos + count); i++) setBit(i); count -= (pos + count) % 8; } if (count == 0) return; for (int i = (pos / 8); i < (pos / 8) + (count / 8); i++) // handle the rest (whole bytes in the middle) bitmap[i] = (byte) 0xFF; } /** * Clears multiple bits. Clear <code>count</code> bits, starting at * <code>pos</code>. * * @param pos * Position of the first bit to clear * @param count * Number of bits to clear */ public void clearBits(int pos, int count) { if (pos >= size) return; if ((pos + count) >= size) count = (size - pos); if (pos % 8 > 0) // pos doesn'f fall on a byte boundary { // => handle the first bits bit per bit int i; for (i = pos; i < (pos + Math.min(8 - (pos % 8), count)); i++) clearBit(i); count -= (i - pos); pos = i; } if (count == 0) return; if (count % 8 > 0) // the last bits do not fall on a byte boundary { // => handle the last bits bit per bit for (int i = (pos + count - (count % 8)); i < (pos + count); i++) clearBit(i); count -= (pos + count) % 8; } if (count == 0) return; for (int i = (pos / 8); i < (pos / 8) + (count / 8); i++) // handle the rest (whole bytes in the middle) bitmap[i] = 0; } /** * Check whether a bit at a given position is set. * * @param pos * Position of the bit to check * @return Whether the bit is set */ public boolean isSet(int pos) { if (pos >= size) return false; int i = (byte) (1 << (pos % 8)) & bitmap[pos / 8]; return i != 0; } /** * Tests if all bits of the bitmap are set. * * @return True if all bits are set */ public boolean allSet() { if (size % 8 > 0) // the last byte is not filled by the bitmap { // Set all bits that exceed the bitmap to 1 int i = 0xFF << (size % 8); bitmap[bitmap.length - 1] |= i; } for (int i = 0; i < bitmap.length; i++) if (bitmap[i] != (byte) 0xFF) return false; return true; } /** * Tests if all bits of the bitmap until a certain position are set. * * @param until * Number of bits to check from the start * @return True if all bits until <code>until</code> are set */ public boolean allSet(int until) { if (until >= size) return allSet(); for (int i = 0; i < until / 8; i++) if (bitmap[i] != (byte) 0xFF) return false; if (until % 8 > 0) // the last byte is not filled by the bitmap { // Set all bits that ecxeed the bitmap to 1 byte b = bitmap[until / 8]; int m = 0xFF << (until % 8); b |= m; if (b != (byte) 0xFF) return false; } return true; } /** * Returns a string that shows every bit in the given byte. * * @param b * The byte * @return string representation of a byte */ public String byteToBitString(byte b) { String res = "|"; for (byte j = 0; j < 8; j++) res += ((b >> j) & (byte) 1) == 1 ? "1|" : "0|"; return res; } /** * Prints the content of the bitmap to {@link System#out}. */ public void print() { System.out.println("+---------------+"); for (int i = 0; i < bitmap.length; i++) if ((i == bitmap.length - 1) && (size % 8 > 0)) { char[] s = byteToBitString(bitmap[i]).toCharArray(); for (byte b = (byte) (size % 8); b < 8; b++) s[b * 2 + 1] = 'x'; System.out.println(s); } else System.out.println(byteToBitString(bitmap[i])); System.out.println("+---------------+"); } }