in Arriba/Arriba/Structures/IpRange.cs [35:125]
public static bool TryParse(string value, out IpRange result)
{
result = new IpRange(0, 0);
if (string.IsNullOrEmpty(value)) return true;
// If the text doesn't contain IP address parts (digits, '.', '-'), return
Match m = s_ipPartsExpression.Match(value);
if (!m.Success) return false;
// Get the first group (containing a capture for each 'token')
Group g = m.Groups[1];
int index = 0;
uint startAddress, endAddress;
// Try to parse one IP address
int bitsFound = ParseIP(g, ref index, out startAddress);
if (bitsFound == -1)
{
// Invalid address, stop
return false;
}
else if (bitsFound == 32)
{
// Whole address and nothing left, return as a single IP
if (index >= g.Captures.Count)
{
result = new IpRange(startAddress, startAddress);
return true;
}
// '-', address range
if (g.Captures[index].Value == "-")
{
++index;
bitsFound = ParseIP(g, ref index, out endAddress);
// If the second address was incomplete, stop
if (bitsFound < 32) return false;
// If the second address is smaller, stop
if (startAddress > endAddress) return false;
// Otherwise, we found a valid range
result = new IpRange(startAddress, endAddress);
return true;
}
// '/', prefix bit count
if (g.Captures[index].Value == "/")
{
++index;
// Get the prefix bit count
if (!int.TryParse(g.Captures[index].Value, out bitsFound)) return false;
++index;
// Clear the suffix bits on the sample address
startAddress = startAddress & (uint.MaxValue << (32 - bitsFound));
// Compute the end address
endAddress = startAddress + (uint)((1 << (32 - bitsFound)) - 1);
result = new IpRange(startAddress, endAddress);
return true;
}
// Otherwise, invalid
return false;
}
else
{
// Partial IP address - make a range with the remaining unfound bits
// If this isn't everything, stop
if (index < g.Captures.Count) return false;
// Otherwise, end address is start plus the remaining octets
if (bitsFound == 0)
{
endAddress = uint.MaxValue;
}
else
{
endAddress = startAddress + (uint)((1 << (32 - bitsFound)) - 1);
}
result = new IpRange(startAddress, endAddress);
return true;
}
}