All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.infoflow.android.axml.flags.BitwiseFlagSystem Maven / Gradle / Ivy

package soot.jimple.infoflow.android.axml.flags;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * In some cases, bitmasks might be used in a way where there is a precendence
 * of certain masks to save space. For "normal" bitmasks, the traditional way of
 * checking is much faster.
 * 
 * Simple Example: Option A (can be used alone or in combination with others):
 * 01 Option B (cannot be used with option A): 10 Option C (only valid when used
 * with Option A): 11
 * 
 * In this case, we could do checking of B via ((v & 10) == 1) && ((v & 1) != 1)
 * but sometimes there are a lot of options (e.g. inputType)
 * 
 * @param  the keys used to distinguish flags
 */
public class BitwiseFlagSystem {
	private List keys = new ArrayList();
	private List values = new ArrayList();

	/**
	 * Associate the given key with the bits set in set bits. The first registration
	 * wins.
	 * 
	 * @param key     the key
	 * @param setBits the bits set
	 */
	public void register(T key, int setBits) {
		keys.add(key);
		values.add(setBits);
	}

	/**
	 * Returns all matching flags
	 * 
	 * @param value input value
	 */
	public final Collection getFlags(int value) {
		List matchedResults = new ArrayList<>(4);
		List matchedValues = new ArrayList<>(4);
		for (int i = 0; i < keys.size(); i++) {
			int v = values.get(i);
			if ((v & value) == v) {
				if (!hadAnyMatch(v, matchedValues)) {
					matchedResults.add(keys.get(i));
					matchedValues.add(v);
				}

			}
		}
		return matchedResults;
	}

	private static boolean hadAnyMatch(int value, List matchedValues) {
		for (int c : matchedValues) {
			if ((c & value) == value) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks whether all the given flags are set
	 * 
	 * @param inputValue input value
	 * @param flag       the flags to check
	 */
	@SafeVarargs
	public final boolean isSet(int inputValue, T... flag) {
		List flagsLeft = new ArrayList(flag.length);
		for (T i : flag)
			flagsLeft.add(i);

		for (T t : getFlags(inputValue)) {
			Iterator it = flagsLeft.iterator();
			while (it.hasNext()) {
				if (it.next().equals(t)) {
					it.remove();
					if (flagsLeft.isEmpty())
						return true;
				}
			}
		}
		return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy