blob: a7503eb48360180cafa961b4fbf923a62758e751 [file] [log] [blame]
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001package net.floodlightcontroller.util;
2
3import java.util.EnumSet;
4import java.util.Set;
5
6/**
7 * A utility class to convert between integer based bitmaps for (OpenFlow)
8 * flags and Enum and EnumSet based representations.
9 *
10 * The enum used to represent individual flags needs to implement the
11 * BitmapableEnum interface.
12 *
13 * Example:
14 * {@code
15 * int bitmap = 0x11; // OFPPC_PORT_DOWN | OFPPC_NO_STP
16 * EnumSet<OFPortConfig> s = toEnumSet(OFPortConfig.class, bitmap);
17 * // s will contain OFPPC_PORT_DOWN and OFPPC_NO_STP
18 * }
19 *
20 * {@code
21 * EnumSet<OFPortConfig> s = EnumSet.of(OFPPC_NO_STP, OFPPC_PORT_DOWN);
22 * int bitmap = toBitmap(s); // returns 0x11
23 * }
24 * @author gregor
25 *
26 */
27public class EnumBitmaps {
28 /**
29 * Enums used to represent individual flags needs to implement this
30 * interface
31 */
32 public interface BitmapableEnum {
33 /** Return the value in the bitmap that the enum constant represents.
34 * The returned value must have only a single bit set. E.g.,1<<3
35 */
36 int getValue();
37 }
38
39 /**
40 * Convert an integer bitmap to an EnumSet.
41 *
42 * See class description for example
43 * @param type The Enum class to use. Must implement BitmapableEnum
44 * @param bitmap The integer bitmap
45 * @return A newly allocated EnumSet representing the bits set in the
46 * bitmap
47 * @throws NullPointerException if type is null
48 * @throws IllegalArgumentException if any enum constant from type has
49 * more than one bit set.
50 * @throws IllegalArgumentException if the bitmap has any bits set not
51 * represented by an enum constant.
52 */
53 public static <E extends Enum<E> & BitmapableEnum>
54 EnumSet<E> toEnumSet(Class<E> type, int bitmap) {
55 if (type == null)
56 throw new NullPointerException("Given enum type must not be null");
57 EnumSet<E> s = EnumSet.noneOf(type);
58 // allSetBitmap will eventually have all valid bits for the given
59 // type set.
60 int allSetBitmap = 0;
61 for (E element: type.getEnumConstants()) {
62 if (Integer.bitCount(element.getValue()) != 1) {
63 String msg = String.format("The %s (%x) constant of the " +
64 "enum %s is supposed to represent a bitmap entry but " +
65 "has more than one bit set.",
66 element.toString(), element.getValue(), type.getName());
67 throw new IllegalArgumentException(msg);
68 }
69 allSetBitmap |= element.getValue();
70 if ((bitmap & element.getValue()) != 0)
71 s.add(element);
72 }
73 if (((~allSetBitmap) & bitmap) != 0) {
74 // check if only valid flags are set in the given bitmap
75 String msg = String.format("The bitmap %x for enum %s has " +
76 "bits set that are presented by any enum constant",
77 bitmap, type.getName());
78 throw new IllegalArgumentException(msg);
79 }
80 return s;
81 }
82
83 /**
84 * Return the bitmap mask with all possible bits set. E.g., If a bitmap
85 * has the individual flags 0x1, 0x2, and 0x8 (note the missing 0x4) then
86 * the mask will be 0xb (1011 binary)
87 *
88 * @param type The Enum class to use. Must implement BitmapableEnum
89 * @throws NullPointerException if type is null
90 * @throws IllegalArgumentException if any enum constant from type has
91 * more than one bit set
92 * @return an integer with all possible bits for the given bitmap enum
93 * type set.
94 */
95 public static <E extends Enum<E> & BitmapableEnum>
96 int getMask(Class<E> type) {
97 if (type == null)
98 throw new NullPointerException("Given enum type must not be null");
99 // allSetBitmap will eventually have all valid bits for the given
100 // type set.
101 int allSetBitmap = 0;
102 for (E element: type.getEnumConstants()) {
103 if (Integer.bitCount(element.getValue()) != 1) {
104 String msg = String.format("The %s (%x) constant of the " +
105 "enum %s is supposed to represent a bitmap entry but " +
106 "has more than one bit set.",
107 element.toString(), element.getValue(), type.getName());
108 throw new IllegalArgumentException(msg);
109 }
110 allSetBitmap |= element.getValue();
111 }
112 return allSetBitmap;
113 }
114
115 /**
116 * Convert the given EnumSet to the integer bitmap representation
117 * @param set The EnumSet to convert. The enum must implement
118 * BitmapableEnum
119 * @return the integer bitmap
120 * @throws IllegalArgumentException if an enum constant from the set (!) has
121 * more than one bit set
122 * @throws NullPointerException if the set is null
123 */
124 public static <E extends Enum<E> & BitmapableEnum>
125 int toBitmap(Set<E> set) {
126 if (set == null)
127 throw new NullPointerException("Given set must not be null");
128 int bitmap = 0;
129 for (E element: set) {
130 if (Integer.bitCount(element.getValue()) != 1) {
131 String msg = String.format("The %s (%x) constant in the set " +
132 "is supposed to represent a bitmap entry but " +
133 "has more than one bit set.",
134 element.toString(), element.getValue());
135 throw new IllegalArgumentException(msg);
136 }
137 bitmap |= element.getValue();
138 }
139 return bitmap;
140 }
141}