/*
* Copyright 2004 - 2008 Christian Sprajc, Dennis Waldherr. All rights reserved.
*
* This file is part of PowerFolder.
*
* PowerFolder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* PowerFolder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PowerFolder. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
package de.dal33t.powerfolder.util.net;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class represents an IP range in a subnet.
* Instances are immutable.
*
* @author Dennis "Dante" Waldherr
* @version $Revision$
*/
public final class AddressRange {
private static Pattern addressPattern = Pattern
.compile("\\s*((?:\\d{1,3})(?:\\.(?:\\d){1,3}){3})\\s*(?:-\\s*((?:\\d{1,3})(?:\\.(?:\\d){1,3}){3}))?\\s*");
private Inet4Address start;
private Inet4Address end;
public AddressRange(Inet4Address start, Inet4Address end) {
super();
this.start = start;
this.end = end;
}
public static AddressRange parseRange(String s) throws ParseException {
try {
Matcher m = addressPattern.matcher(s);
m.matches();
String ipEnd = m.group(2);
if (ipEnd == null) {
ipEnd = m.group(1);
}
return new AddressRange((Inet4Address) InetAddress.getByName(m.group(1)),
(Inet4Address) InetAddress.getByName(ipEnd));
} catch (Throwable e) {
throw new ParseException(s, 0);
}
}
public Inet4Address getEnd() {
return end;
}
/**
* Checks if the given address is in range of the interval [start, end].
* @param addr the address to check
* @return true if the address is contained in this range
*/
public boolean contains(Inet4Address addr) {
byte[] s = start.getAddress(), e = end.getAddress(), a = addr.getAddress();
// Lexicographic compare
for (int i = 0; i < s.length; i++) {
int av = a[i] & 0xff, sv = s[i] & 0xff, ev = e[i] & 0xff;
if (av > ev || av < sv) {
return false;
}
if (av > sv && av < ev) {
return true;
} // else av == ev or av == sv=> continue
}
return true;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((end == null) ? 0 : end.hashCode());
result = PRIME * result + ((start == null) ? 0 : start.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final AddressRange other = (AddressRange) obj;
if (end == null) {
if (other.end != null)
return false;
} else if (!end.equals(other.end))
return false;
if (start == null) {
if (other.start != null)
return false;
} else if (!start.equals(other.start))
return false;
return true;
}
public Inet4Address getStart() {
return start;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
String t = start.toString();
b.append(t.substring(t.indexOf('/') + 1));
if (!end.equals(start)) {
b.append('-');
t = end.toString();
b.append(t.substring(t.indexOf('/') + 1));
}
return b.toString();
}
}