android: Implement Iterable interface and addAll() for range set

This commit is contained in:
Tobias Brunner
2017-07-03 10:27:52 +02:00
parent 54714331e4
commit 1e26483167
2 changed files with 129 additions and 49 deletions
@@ -16,7 +16,7 @@
package org.strongswan.android.utils;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
@@ -25,7 +25,7 @@ import java.util.TreeSet;
* Class that represents a set of IP address ranges (not necessarily proper subnets) and allows
* modifying the set and enumerating the resulting subnets.
*/
public class IPRangeSet
public class IPRangeSet implements Iterable<IPRange>
{
private TreeSet<IPRange> mRanges = new TreeSet<>();
@@ -84,6 +84,17 @@ public class IPRangeSet
}
}
/**
* Add all ranges from the given collection to this set.
*/
public void addAll(Collection<? extends IPRange> coll)
{
for (IPRange range : coll)
{
add(range);
}
}
/**
* Remove the given range from this set. Existing ranges are automatically adjusted.
*/
@@ -125,34 +136,53 @@ public class IPRangeSet
}
/**
* Returns the subnets derived from all the ranges in this set.
* Get all the subnets derived from all the ranges in this set.
*/
public Enumeration<IPRange> getSubnets()
public Iterable<IPRange> subnets()
{
return new Enumeration<IPRange>()
return new Iterable<IPRange>()
{
private Iterator<IPRange> mIterator = mRanges.iterator();
private List<IPRange> mSubnets;
@Override
public boolean hasMoreElements()
public Iterator<IPRange> iterator()
{
return (mSubnets != null && mSubnets.size() > 0) || mIterator.hasNext();
}
@Override
public IPRange nextElement()
{
if (mSubnets == null || mSubnets.size() == 0)
return new Iterator<IPRange>()
{
IPRange range = mIterator.next();
mSubnets = range.toSubnets();
}
return mSubnets.remove(0);
private Iterator<IPRange> mIterator = mRanges.iterator();
private List<IPRange> mSubnets;
@Override
public boolean hasNext()
{
return (mSubnets != null && mSubnets.size() > 0) || mIterator.hasNext();
}
@Override
public IPRange next()
{
if (mSubnets == null || mSubnets.size() == 0)
{
IPRange range = mIterator.next();
mSubnets = range.toSubnets();
}
return mSubnets.remove(0);
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
};
}
@Override
public Iterator<IPRange> iterator()
{
return mRanges.iterator();
}
/**
* Returns the number of ranges, not subnets.
*/
@@ -20,25 +20,28 @@ import org.strongswan.android.utils.IPRange;
import org.strongswan.android.utils.IPRangeSet;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class IPRangeSetTest
{
private void assertSubnets(Enumeration<IPRange> subnets, IPRange...exp)
private void assertSubnets(IPRangeSet set, IPRange...exp)
{
Iterator<IPRange> subnets = set.subnets().iterator();
if (exp.length == 0)
{
assertEquals("no subnets", false, subnets.hasMoreElements());
assertEquals("no subnets", false, subnets.hasNext());
return;
}
for (int i = 0; i < exp.length; i++)
for (IPRange e : exp)
{
assertEquals("has subnet", true, subnets.hasMoreElements());
assertEquals("range", exp[i], subnets.nextElement());
assertEquals("has subnet", true, subnets.hasNext());
assertEquals("range", e, subnets.next());
}
assertEquals("done", false, subnets.hasMoreElements());
assertEquals("done", false, subnets.hasNext());
}
@Test
@@ -46,7 +49,7 @@ public class IPRangeSetTest
{
IPRangeSet set = new IPRangeSet();
assertEquals("size", 0, set.size());
assertSubnets(set.getSubnets());
assertSubnets(set);
}
@Test
@@ -55,10 +58,10 @@ public class IPRangeSetTest
IPRangeSet set = new IPRangeSet();
set.add(new IPRange("192.168.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
set.add(new IPRange("10.0.1.0/24"));
assertEquals("size", 2, set.size());
assertSubnets(set.getSubnets(), new IPRange("10.0.1.0/24"), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("10.0.1.0/24"), new IPRange("192.168.1.0/24"));
}
@Test
@@ -67,10 +70,10 @@ public class IPRangeSetTest
IPRangeSet set = new IPRangeSet();
set.add(new IPRange("192.168.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
set.add(new IPRange("192.168.2.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"), new IPRange("192.168.2.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"), new IPRange("192.168.2.0/24"));
}
@Test
@@ -82,7 +85,7 @@ public class IPRangeSetTest
assertEquals("size", 2, set.size());
set.add(new IPRange("192.168.2.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"), new IPRange("192.168.2.0/23"));
assertSubnets(set, new IPRange("192.168.1.0/24"), new IPRange("192.168.2.0/23"));
}
@Test
@@ -91,10 +94,10 @@ public class IPRangeSetTest
IPRangeSet set = new IPRangeSet();
set.add(new IPRange("192.168.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
set.add(new IPRange("192.168.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
}
@Test
@@ -103,13 +106,13 @@ public class IPRangeSetTest
IPRangeSet set = new IPRangeSet();
set.add(new IPRange("192.168.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
set.add(new IPRange("192.168.0.0/16"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.0.0/16"));
assertSubnets(set, new IPRange("192.168.0.0/16"));
set.add(new IPRange("0.0.0.0/0"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("0.0.0.0/0"));
assertSubnets(set, new IPRange("0.0.0.0/0"));
}
@Test
@@ -122,7 +125,21 @@ public class IPRangeSetTest
assertEquals("size", 3, set.size());
set.add(new IPRange("0.0.0.0/0"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("0.0.0.0/0"));
assertSubnets(set, new IPRange("0.0.0.0/0"));
}
@Test
public void testAddAll() throws UnknownHostException
{
IPRangeSet set = new IPRangeSet();
List<IPRange> list = new ArrayList<>();
list.add(new IPRange("192.168.1.0/24"));
list.add(new IPRange("10.0.1.0/24"));
list.add(new IPRange("255.255.255.255/32"));
set.addAll(list);
assertEquals("size", 3, set.size());
assertSubnets(set, new IPRange("10.0.1.0/24"), new IPRange("192.168.1.0/24"),
new IPRange("255.255.255.255/32"));
}
@Test
@@ -132,10 +149,10 @@ public class IPRangeSetTest
set.add(new IPRange("192.168.1.0/24"));
set.remove(new IPRange("192.168.2.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
set.remove(new IPRange("10.0.1.0/24"));
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
}
@Test
@@ -145,14 +162,14 @@ public class IPRangeSetTest
set.add(new IPRange("192.168.1.0/24"));
set.remove(new IPRange("192.168.0.0/16"));
assertEquals("size", 0, set.size());
assertSubnets(set.getSubnets());
assertSubnets(set);
set.add(new IPRange("192.168.1.0/24"));
set.add(new IPRange("10.0.1.0/24"));
set.add(new IPRange("255.255.255.255/32"));
assertEquals("size", 3, set.size());
set.remove(new IPRange("0.0.0.0/0"));
assertEquals("size", 0, set.size());
assertSubnets(set.getSubnets());
assertSubnets(set);
}
@Test
@@ -163,7 +180,7 @@ public class IPRangeSetTest
set.add(new IPRange("192.168.2.0/24"));
set.remove(new IPRange("192.168.1.128", "192.168.2.127"));
assertEquals("size", 2, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/25"), new IPRange("192.168.2.128/25"));
assertSubnets(set, new IPRange("192.168.1.0/25"), new IPRange("192.168.2.128/25"));
}
@Test
@@ -172,7 +189,7 @@ public class IPRangeSetTest
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24 192.168.4.0/24");
set.remove(set);
assertEquals("size", 0, set.size());
assertSubnets(set.getSubnets());
assertSubnets(set);
}
@Test
@@ -182,7 +199,7 @@ public class IPRangeSetTest
IPRangeSet remove = IPRangeSet.fromString("192.168.1.0/24 192.168.3.0/24 192.168.16.0-192.168.255.255");
set.remove(remove);
assertEquals("size", 3, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.0.0/24"), new IPRange("192.168.2.0/24"),
assertSubnets(set, new IPRange("192.168.0.0/24"), new IPRange("192.168.2.0/24"),
new IPRange("192.168.4.0/22"), new IPRange("192.168.8.0/21"));
}
@@ -191,7 +208,7 @@ public class IPRangeSetTest
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24");
assertEquals("size", 1, set.size());
assertSubnets(set.getSubnets(), new IPRange("192.168.1.0/24"));
assertSubnets(set, new IPRange("192.168.1.0/24"));
}
@Test
@@ -199,7 +216,7 @@ public class IPRangeSetTest
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24 fec1::/64 10.0.1.0/24 255.255.255.255");
assertEquals("size", 4, set.size());
assertSubnets(set.getSubnets(), new IPRange("10.0.1.0/24"), new IPRange("192.168.1.0/24"),
assertSubnets(set, new IPRange("10.0.1.0/24"), new IPRange("192.168.1.0/24"),
new IPRange("255.255.255.255/32"), new IPRange("fec1::/64"));
}
@@ -208,7 +225,7 @@ public class IPRangeSetTest
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24 10.0.1.0-10.0.1.16");
assertEquals("size", 2, set.size());
assertSubnets(set.getSubnets(), new IPRange("10.0.1.0/28"), new IPRange("10.0.1.16/32"),
assertSubnets(set, new IPRange("10.0.1.0/28"), new IPRange("10.0.1.16/32"),
new IPRange("192.168.1.0/24"));
}
@@ -225,4 +242,37 @@ public class IPRangeSetTest
IPRangeSet set = IPRangeSet.fromString("192.168.1.1 - 192.168.1.10");
assertEquals("failed", null, set);
}
@Test
public void testIteratorRanges() throws UnknownHostException
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24 192.168.2.0/24");
assertSubnets(set, new IPRange("192.168.1.0/24"), new IPRange("192.168.2.0/24"));
Iterator<IPRange> iterator = set.iterator();
assertEquals("hasNext", true, iterator.hasNext());
assertEquals("next", new IPRange("192.168.1.0-192.168.2.255"), iterator.next());
assertEquals("hasNext", false, iterator.hasNext());
}
@Test
public void testIteratorRemove() throws UnknownHostException
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24");
assertSubnets(set, new IPRange("192.168.1.0/24"));
Iterator<IPRange> iterator = set.iterator();
assertEquals("next", new IPRange("192.168.1.0/24"), iterator.next());
iterator.remove();
assertEquals("hasNext", false, iterator.hasNext());
assertEquals("size", 0, set.size());
}
@Test(expected = UnsupportedOperationException.class)
public void testIteratorSubnetRemove() throws UnknownHostException
{
IPRangeSet set = IPRangeSet.fromString("192.168.1.0/24");
Iterator<IPRange> iterator = set.subnets().iterator();
assertEquals("hasNext", true, iterator.hasNext());
assertEquals("next", new IPRange("192.168.1.0/24"), iterator.next());
iterator.remove();
}
}