| package net.floodlightcontroller.util; |
| |
| import java.util.EnumSet; |
| import java.util.Set; |
| |
| /** |
| * A utility class to convert between integer based bitmaps for (OpenFlow) |
| * flags and Enum and EnumSet based representations. |
| * |
| * The enum used to represent individual flags needs to implement the |
| * BitmapableEnum interface. |
| * |
| * Example: |
| * {@code |
| * int bitmap = 0x11; // OFPPC_PORT_DOWN | OFPPC_NO_STP |
| * EnumSet<OFPortConfig> s = toEnumSet(OFPortConfig.class, bitmap); |
| * // s will contain OFPPC_PORT_DOWN and OFPPC_NO_STP |
| * } |
| * |
| * {@code |
| * EnumSet<OFPortConfig> s = EnumSet.of(OFPPC_NO_STP, OFPPC_PORT_DOWN); |
| * int bitmap = toBitmap(s); // returns 0x11 |
| * } |
| * @author gregor |
| * |
| */ |
| public class EnumBitmaps { |
| /** |
| * Enums used to represent individual flags needs to implement this |
| * interface |
| */ |
| public interface BitmapableEnum { |
| /** Return the value in the bitmap that the enum constant represents. |
| * The returned value must have only a single bit set. E.g.,1<<3 |
| */ |
| int getValue(); |
| } |
| |
| /** |
| * Convert an integer bitmap to an EnumSet. |
| * |
| * See class description for example |
| * @param type The Enum class to use. Must implement BitmapableEnum |
| * @param bitmap The integer bitmap |
| * @return A newly allocated EnumSet representing the bits set in the |
| * bitmap |
| * @throws NullPointerException if type is null |
| * @throws IllegalArgumentException if any enum constant from type has |
| * more than one bit set. |
| * @throws IllegalArgumentException if the bitmap has any bits set not |
| * represented by an enum constant. |
| */ |
| public static <E extends Enum<E> & BitmapableEnum> |
| EnumSet<E> toEnumSet(Class<E> type, int bitmap) { |
| if (type == null) |
| throw new NullPointerException("Given enum type must not be null"); |
| EnumSet<E> s = EnumSet.noneOf(type); |
| // allSetBitmap will eventually have all valid bits for the given |
| // type set. |
| int allSetBitmap = 0; |
| for (E element: type.getEnumConstants()) { |
| if (Integer.bitCount(element.getValue()) != 1) { |
| String msg = String.format("The %s (%x) constant of the " + |
| "enum %s is supposed to represent a bitmap entry but " + |
| "has more than one bit set.", |
| element.toString(), element.getValue(), type.getName()); |
| throw new IllegalArgumentException(msg); |
| } |
| allSetBitmap |= element.getValue(); |
| if ((bitmap & element.getValue()) != 0) |
| s.add(element); |
| } |
| if (((~allSetBitmap) & bitmap) != 0) { |
| // check if only valid flags are set in the given bitmap |
| String msg = String.format("The bitmap %x for enum %s has " + |
| "bits set that are presented by any enum constant", |
| bitmap, type.getName()); |
| throw new IllegalArgumentException(msg); |
| } |
| return s; |
| } |
| |
| /** |
| * Return the bitmap mask with all possible bits set. E.g., If a bitmap |
| * has the individual flags 0x1, 0x2, and 0x8 (note the missing 0x4) then |
| * the mask will be 0xb (1011 binary) |
| * |
| * @param type The Enum class to use. Must implement BitmapableEnum |
| * @throws NullPointerException if type is null |
| * @throws IllegalArgumentException if any enum constant from type has |
| * more than one bit set |
| * @return an integer with all possible bits for the given bitmap enum |
| * type set. |
| */ |
| public static <E extends Enum<E> & BitmapableEnum> |
| int getMask(Class<E> type) { |
| if (type == null) |
| throw new NullPointerException("Given enum type must not be null"); |
| // allSetBitmap will eventually have all valid bits for the given |
| // type set. |
| int allSetBitmap = 0; |
| for (E element: type.getEnumConstants()) { |
| if (Integer.bitCount(element.getValue()) != 1) { |
| String msg = String.format("The %s (%x) constant of the " + |
| "enum %s is supposed to represent a bitmap entry but " + |
| "has more than one bit set.", |
| element.toString(), element.getValue(), type.getName()); |
| throw new IllegalArgumentException(msg); |
| } |
| allSetBitmap |= element.getValue(); |
| } |
| return allSetBitmap; |
| } |
| |
| /** |
| * Convert the given EnumSet to the integer bitmap representation |
| * @param set The EnumSet to convert. The enum must implement |
| * BitmapableEnum |
| * @return the integer bitmap |
| * @throws IllegalArgumentException if an enum constant from the set (!) has |
| * more than one bit set |
| * @throws NullPointerException if the set is null |
| */ |
| public static <E extends Enum<E> & BitmapableEnum> |
| int toBitmap(Set<E> set) { |
| if (set == null) |
| throw new NullPointerException("Given set must not be null"); |
| int bitmap = 0; |
| for (E element: set) { |
| if (Integer.bitCount(element.getValue()) != 1) { |
| String msg = String.format("The %s (%x) constant in the set " + |
| "is supposed to represent a bitmap entry but " + |
| "has more than one bit set.", |
| element.toString(), element.getValue()); |
| throw new IllegalArgumentException(msg); |
| } |
| bitmap |= element.getValue(); |
| } |
| return bitmap; |
| } |
| } |