package com.it_jaros.networkScanner; import java.util.BitSet; import java.util.NoSuchElementException; public class PortRange { public static final int MIN_PORT = 1; public static final int MAX_PORT = 65535; private final BitSet specifiedPorts = new BitSet(MAX_PORT); private final BitSet availablePorts = new BitSet(MAX_PORT); private int cursor; private int done = 0; public PortRange(String ports) { if (ports == null || "".equals(ports)) { // keep defaults specifiedPorts.set(1, 1024 + 1); return; } String[] splitComma = ports.split(","); for (String commaValue : splitComma) { if (commaValue.contains("-")) { String[] rangeValue = commaValue.split("-"); if (rangeValue.length > 2) { throw new IllegalArgumentException(String.format("Argument contains too many '-'' %s", commaValue)); } int start = Integer.parseInt(rangeValue[0]); int end = Integer.parseInt(rangeValue[1]); checkValues(start, end); specifiedPorts.set(start, end + 1); } else { int port = Integer.parseInt(commaValue); checkValue(port); specifiedPorts.set(Integer.parseInt(commaValue)); } } availablePorts.or(specifiedPorts); cursor = availablePorts.nextSetBit(MIN_PORT); } private void checkValues(int start, int end) { checkValue(start); checkValue(end); if (start >= end) { throw new IllegalArgumentException( String.format("Start value cannot be equal or bigger than end value '%s >= %s'", start, end)); } } private void checkValue(int port) { if (port < MIN_PORT) { throw new IllegalArgumentException( String.format("Start value smaller than allowed range %s < %s", port, MIN_PORT)); } if (port > MAX_PORT) { throw new IllegalArgumentException( String.format("End value bigger than allowed range %s > %s", port, MAX_PORT)); } } public synchronized int next() { int p = availablePorts.nextSetBit(cursor); if (p > 0) { availablePorts.clear(p); cursor = p + 1; done++; return p; } throw new NoSuchElementException("Reached end of port range"); } public synchronized boolean hasNext() { return availablePorts.nextSetBit(cursor) > 0; } public int getTotal() { return specifiedPorts.cardinality(); } public int getDone() { return done; } }