initial import
Change-Id: Ief25aef0066ea96bd2c329ccef974c072b3a5a73
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/Masked.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/Masked.java
new file mode 100644
index 0000000..b5a995d
--- /dev/null
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/Masked.java
@@ -0,0 +1,97 @@
+package org.projectfloodlight.openflow.types;
+
+import com.google.common.hash.PrimitiveSink;
+
+
+
+public class Masked<T extends OFValueType<T>> implements OFValueType<Masked<T>> {
+ protected final T value;
+
+ /** bitmask of the value. Note: a set (1) bit in this mask means 'match on this value'.
+ * This the natural mask represenation as in IPv[46] netmasks. It is the inverse of the
+ * OpenFlow 1.0 'wildcard' meaning.
+ */
+ protected final T mask;
+
+ protected Masked(T value, T mask) {
+ this.value = value.applyMask(mask);
+ this.mask = mask;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public T getMask() {
+ return mask;
+ }
+
+ public static <T extends OFValueType<T>> Masked<T> of(T value, T mask) {
+ return new Masked<T>(value, mask);
+ }
+
+ @Override
+ public int getLength() {
+ return this.value.getLength() + this.mask.getLength();
+ }
+
+ @Override
+ public String toString() {
+ // General representation: value/mask
+ StringBuilder sb = new StringBuilder();
+ sb.append(value.toString()).append('/').append(mask.toString());
+ return sb.toString();
+ }
+
+ /** Determine whether candidate value is matched by this masked value
+ * (i.e., does candiate lie in the 'network/range' specified by this masked
+ * value).
+ *
+ * @param candidate the candidate value to test
+ * @return true iff the candidate lies in the area specified by this masked
+ * value.
+ */
+ public boolean matches(T candidate) {
+ // candidate lies in the area of this masked value if its
+ // value with the masked bit zero'ed out equals this's value
+ // (e.g., our 'network address' for networks)
+ return candidate.applyMask(this.mask).equals(this.value);
+ }
+
+ @Override
+ public Masked<T> applyMask(Masked<T> mask) {
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Masked<?>))
+ return false;
+ Masked<?> mobj = (Masked<?>)obj;
+ return this.value.equals(mobj.value) && this.mask.equals(mobj.mask);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 59;
+ int result = 1;
+ result = prime * result + this.value.hashCode();
+ result = prime * result + this.mask.hashCode();
+ return result;
+ }
+
+ @Override
+ public int compareTo(Masked<T> o) {
+ int res = value.compareTo(o.value);
+ if(res != 0)
+ return res;
+ else
+ return mask.compareTo(o.mask);
+ }
+
+ @Override
+ public void putTo(PrimitiveSink sink) {
+ value.putTo(sink);
+ mask.putTo(sink);
+ }
+}