package com.onionnetworks.util; import java.text.ParseException; /** * This class represents a range of integers (incuding positive and negative * infinity). */ public class Range { private boolean negInf, posInf; private long min,max; /** * Creates a new Range that is only one number, both min and max will * equal that number. * @param num The number that this range will encompass. */ public Range(long num) { this(num,num,false,false); } /** * Creates a new Range from min and max (inclusive) * @param min The min value of the range. * @param max The max value of the range. */ public Range(long min, long max) { this(min,max,false,false); } /** * Creates a new Range from min to postive infinity * @param min The min value of the range. * @param posInf Must be true to specify max == positive infinity */ public Range(long min, boolean posInf) { this(min,Long.MAX_VALUE,false,posInf); if (!posInf) { throw new IllegalArgumentException("posInf must be true"); } } /** * Creates a new Range from negative infinity to max. * @param negInf Must be true to specify min == negative infinity * @param max The max value of the range. */ public Range(boolean negInf, long max) { this(Long.MIN_VALUE,max,negInf,false); if (!negInf) { throw new IllegalArgumentException("negInf must be true"); } } /** * Creates a new Range from negative infinity to positive infinity. * @param negInf must be true. * @param posInf must be true. */ public Range(boolean negInf, boolean posInf) { this(Long.MIN_VALUE,Long.MAX_VALUE,negInf,posInf); if (!negInf || !posInf) { throw new IllegalArgumentException ("negInf && posInf must be true"); } } private Range(long min, long max, boolean negInf, boolean posInf) { if (min > max) { throw new IllegalArgumentException ("min cannot be greater than max"); } // very common bug, its worth reporting for now. if (min == 0 && max == 0) { System.err.println("Range.debug: 0-0 range detected. "+ "Did you intend to this? :"); new Exception().printStackTrace(); } this.min = min; this.max = max; this.negInf = negInf; this.posInf = posInf; } /** * @return true if min is negative infinity. */ public boolean isMinNegInf() { return negInf; } /** * @return true if max is positive infinity. */ public boolean isMaxPosInf() { return posInf; } /** * @return the min value of the range. */ public long getMin() { return min; } /** * @return the max value of the range. */ public long getMax() { return max; } /** * @return The size of the range (min and max inclusive) or -1 if the range * is infinitly long. */ public long size() { if (negInf || posInf) { return -1; } return max-min+1; } /** * @param i The integer to check to see if it is in the range. * @return true if i is in the range (min and max inclusive) */ public boolean contains(long i) { return i >= min && i <= max; } /** * @param r The range to check to see if it is in this range. * @return true if this range contains the entirety of the passed range. */ public boolean contains(Range r) { return r.min >= min && r.max <= max; } public int hashCode() { return (int) (min + 23 * max); } public boolean equals(Object obj) { if (obj instanceof Range && ((Range) obj).min == min && ((Range) obj).max == max && ((Range) obj).negInf == negInf && ((Range) obj).posInf == posInf) { return true; } else { return false; } } public String toString() { if (!negInf && !posInf && min == max) { return new Long(min).toString(); } else { return (negInf ? "(" : ""+min) + "-" + (posInf ? ")" : ""+max); } } /** * This method creates a new range from a String. * Allowable characters are all integer values, "-", ")", and "(". The * open and closed parens indicate positive and negative infinity. * <pre> * Example strings would be: * "11" is the range that only includes 11 * "-6" is the range that only includes -6 * "10-20" is the range 10 through 20 (inclusive) * "-10--5" is the range -10 through -5 * "(-20" is the range negative infinity through 20 * "30-)" is the range 30 through positive infinity. * </pre> * @param s The String to parse * @return The resulting range * @throws ParseException, */ public static final Range parse(String s) throws ParseException { try { long min=0,max=0; boolean negInf=false,posInf=false; // search from the 1 pos because it may be a negative number. int dashPos = s.indexOf("-",1); if (dashPos == -1) { // no dash, one value. min = max = Long.parseLong(s); } else { if (s.indexOf("(") != -1) { negInf = true; } else { min = Long.parseLong(s.substring(0,dashPos)); } if (s.indexOf(")") != -1) { posInf = true; } else { max = Long.parseLong(s.substring(dashPos+1,s.length())); } } if (negInf) { if (posInf) { return new Range(true,true); } else { return new Range(true,max); } } else if (posInf) { return new Range(min,true); } else { return new Range(min,max); } } catch (RuntimeException e) { throw new ParseException(e.getMessage(),-1); } } }