/* * Copyright 2015 MiLaboratory.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.milaboratory.util; import java.util.Arrays; import java.util.List; public class BitArray implements java.io.Serializable { private static final long serialVersionUID = 1L; byte[] data; int size; public BitArray(List<Boolean> booleans) { this(booleans.size()); for (int i = booleans.size() - 1; i >= 0; --i) if (booleans.get(i)) set(i); } public BitArray(boolean... array) { this(array.length); for (int i = array.length - 1; i >= 0; --i) if (array[i]) set(i); } public BitArray(int size) { this.size = size; this.data = new byte[(size + 7) >> 3]; } BitArray(byte[] data, int size) { //if(data.length != ((size + 7) >> 3)) // throw new IllegalStateException(); this.data = data; this.size = size; } public boolean get(int i) { return (data[i >> 3] & (1 << (i & 7))) != 0; } public void set(int i) { data[i >> 3] |= (1 << (i & 7)); } public void clear(int i) { data[i >> 3] &= ~(1 << (i & 7)); } public void set(int i, boolean value) { if (value) set(i); else clear(i); } public BitArray getRange(int from, int to) { BitArray ret = new BitArray(to - from); for (int i = 0; i < ret.size(); ++i) ret.set(i, get(i + from)); return ret; } //TODO Equals to load values public void set(BitArray ba) { if (ba.size != this.size) throw new IllegalArgumentException(); for (int i = 0; i < this.data.length; ++i) this.data[i] = ba.data[i]; } public void setAll() { //for (int i = 0; i < data.length; ++i) // data[i] = 0xFFFFFFFF; Arrays.fill(data, (byte) 0xFF); if ((size & 7) != 0) data[data.length - 1] = (byte) (0xFF >>> (8 - (size & 0x7))); } public boolean intersects(BitArray bitArray) { if (bitArray.size != this.size) throw new IllegalArgumentException(); for (int i = 0; i < this.data.length; ++i) if ((this.data[i] & bitArray.data[i]) != 0) return true; return false; } public int bitCount() { int count = 0; for (int i = 0; i < data.length; ++i) count += Integer.bitCount(0xFF & data[i]); return count; } public void or(BitArray bitArray) { if (size != bitArray.size) throw new IllegalArgumentException(); for (int i = 0; i < data.length; ++i) data[i] |= bitArray.data[i]; } public void xor(BitArray bitArray) { if (size != bitArray.size) throw new IllegalArgumentException(); for (int i = 0; i < data.length; ++i) data[i] ^= bitArray.data[i]; } public void and(BitArray bitArray) { if (size != bitArray.size) throw new IllegalArgumentException(); for (int i = 0; i < data.length; ++i) data[i] &= bitArray.data[i]; } public void loadValueFrom(BitArray bitArray) { if (size != bitArray.size) throw new IllegalArgumentException(); System.arraycopy(bitArray.data, 0, data, 0, bitArray.data.length); } /** * Returns false if some bits in array are set. * * @return false if some bits are set */ public boolean isClean() { for (byte d : data) if (d != 0) return false; return true; } public void clearAll() { //for (int i = 0; i < data.length; ++i) // data[i] = 0; Arrays.fill(data, (byte) 0); } public int[] getBits() { int[] bits = new int[bitCount()]; int n = 0; for (int i = 0; i < size; ++i) if (get(i)) bits[n++] = i; return bits; } public int size() { return size; } public BitArray clone() { return new BitArray(Arrays.copyOf(data, data.length), size); } public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; final BitArray other = (BitArray) obj; if (!Arrays.equals(this.data, other.data)) return false; if (this.size != other.size) return false; return true; } public int hashCode() { int hash = 5; hash = 19 * hash + Arrays.hashCode(this.data); hash = 19 * hash + this.size; return hash; } @Override public String toString() { char[] c = new char[size]; for (int i = 0; i < size; ++i) if (get(i)) c[i] = '1'; else c[i] = '0'; return new String(c); } public static byte[] extractRawDataArray(BitArray array) { return array.data; } public static BitArray construct(byte[] data, int size) { return new BitArray(data, size); } }