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