/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.styling.css.util; import java.util.BitSet; /** * The binary signature for a list of values, indicates which objects of the list have been selected * using 1s, those that have not using 0s * * @author Andrea Aime - GeoSolutions */ public abstract class Signature implements Cloneable { /** * Increments the binary signature, that is, adds 1 to it */ public abstract void increment(); /** * Checks if this signature contains another * * @param other * @param k * @return */ public abstract boolean contains(Signature other, int k); /** * Returns the flag at the i-th position * * @param i * @return */ public abstract boolean get(int i); /** * Sets the flag at the i-th position * * @param idx * @param b */ public abstract void set(int idx, boolean b); /** * The size of the signature, in number of bits * * @return */ public abstract int size(); /** * Clones the signature */ public abstract Object clone(); @Override public String toString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < size(); i++) { if (get(i)) { sb.append("1"); } else { sb.append("0"); } } return sb.toString(); } public static Signature newSignature(int size) { return new BitsetSignature(size); } /** * An implementation of signature based on a Java {@link BitSet} */ public static class BitsetSignature extends Signature { BitSet bs; private int size; public BitsetSignature(int size) { this.size = size; bs = new BitSet(size); } public BitsetSignature(BitsetSignature other) { this.bs = (BitSet) other.bs.clone(); this.size = other.size; } public void increment() { for (int i = 0; i < bs.size(); i++) { if (bs.get(i)) { bs.clear(i); } else { bs.set(i); return; } } } public boolean contains(Signature otherSignature, int k) { BitsetSignature other = (BitsetSignature) otherSignature; final int max = Math.min(bs.size(), k + 1); int found = 0; for (int i = 0; i < max; i++) { boolean ob = other.bs.get(i); boolean b = bs.get(i); found += ob ? 1 : 0; if (ob && !b) { return false; } } return found > 0; } @Override public boolean get(int i) { return bs.get(i); } @Override public void set(int idx, boolean b) { bs.set(idx, b); } @Override public int size() { return size; } public Object clone() { return new BitsetSignature(this); } } }