Types: added 'matches' method to Masked<T>

+ IPv4 based unittest
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/Masked.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/Masked.java
index ea2317a..b5a995d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/Masked.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/Masked.java
@@ -5,8 +5,13 @@
 
 
 public class Masked<T extends OFValueType<T>> implements OFValueType<Masked<T>> {
-    protected T value;
-    protected T mask;
+    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);
@@ -38,6 +43,21 @@
         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;
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
index 38d60b3..c00fad4 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
@@ -1,5 +1,6 @@
 package org.projectfloodlight.openflow.types;
 
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
@@ -68,6 +69,53 @@
                              new byte[][] { new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 } }
     };
 
+    @Test
+    public void testMaskedMatchesCidr() {
+        IPv4AddressWithMask slash28 = IPv4AddressWithMask.of("10.0.42.16/28");
+
+        String[] notContained = {"0.0.0.0", "11.0.42.16", "10.0.41.1", "10.0.42.0", "10.0.42.15",
+                                 "10.0.42.32", "255.255.255.255" };
+
+        for(String n: notContained) {
+            assertThat(String.format("slash 28 %s should not contain address %s",
+                                     slash28, n),
+                    slash28.matches(IPv4Address.of(n)), equalTo(false));
+        }
+        for(int i=16; i < 32; i++) {
+            IPv4Address c = IPv4Address.of(String.format("10.0.42.%d", i));
+            assertThat(String.format("slash 28 %s should contain address %s",
+                                     slash28, c),
+                       slash28.matches(c), equalTo(true));
+        }
+    }
+
+    @Test
+    public void testMaskedMatchesArbitrary() {
+        // irregular octect on the 3rd bitmask requires '1'bit to be set
+        // 4 bit unset, all others arbitrary
+        IPv4AddressWithMask slash28 = IPv4AddressWithMask.of("1.2.1.4/255.255.5.255");
+
+        String[] notContained = {"0.0.0.0", "1.2.3.5", "1.2.3.3",
+                                 "1.2.0.4", "1.2.2.4", "1.2.4.4", "1.2.5.4", "1.2.6.4", "1.2.7.4",
+                                 "1.2.8.4", "1.2.12.4", "1.2.13.4"
+                                 };
+        String[] contained = {"1.2.1.4", "1.2.3.4", "1.2.9.4", "1.2.11.4", "1.2.251.4",
+                };
+
+        for(String n: notContained) {
+            assertThat(String.format("slash 28 %s should not contain address %s",
+                                     slash28, n),
+                    slash28.matches(IPv4Address.of(n)), equalTo(false));
+        }
+        for(String c: contained) {
+            IPv4Address addr = IPv4Address.of(c);
+            assertThat(String.format("slash 28 %s should contain address %s",
+                                     slash28, addr),
+                       slash28.matches(addr), equalTo(true));
+        }
+
+    }
+
 
     @Test
     public void testOfString() {