jellyfin-server/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs

130 lines
3.2 KiB
C#
Raw Normal View History

using System;
using System.Collections;
2018-09-12 17:26:21 +00:00
using System.Collections.Generic;
using System.Numerics;
namespace Emby.Server.Implementations.Networking.IPNetwork
2018-09-12 17:26:21 +00:00
{
public class IPNetworkCollection : IEnumerable<IPNetwork>, IEnumerator<IPNetwork>
{
private BigInteger _enumerator;
private byte _cidrSubnet;
private IPNetwork _ipnetwork;
private byte _cidr => this._ipnetwork.Cidr;
private BigInteger _broadcast => IPNetwork.ToBigInteger(this._ipnetwork.Broadcast);
private BigInteger _lastUsable => IPNetwork.ToBigInteger(this._ipnetwork.LastUsable);
private BigInteger _network => IPNetwork.ToBigInteger(this._ipnetwork.Network);
2018-09-12 17:26:21 +00:00
#if TRAVISCI
public
#else
internal
#endif
IPNetworkCollection(IPNetwork ipnetwork, byte cidrSubnet)
{
int maxCidr = ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
2018-09-12 17:26:21 +00:00
if (cidrSubnet > maxCidr)
{
throw new ArgumentOutOfRangeException(nameof(cidrSubnet));
2018-09-12 17:26:21 +00:00
}
if (cidrSubnet < ipnetwork.Cidr)
{
throw new ArgumentException("cidr");
}
this._cidrSubnet = cidrSubnet;
this._ipnetwork = ipnetwork;
this._enumerator = -1;
}
#region Count, Array, Enumerator
public BigInteger Count
{
get
{
2019-01-13 20:37:13 +00:00
var count = BigInteger.Pow(2, this._cidrSubnet - this._cidr);
2018-09-12 17:26:21 +00:00
return count;
}
}
public IPNetwork this[BigInteger i]
{
get
{
if (i >= this.Count)
{
throw new ArgumentOutOfRangeException(nameof(i));
2018-09-12 17:26:21 +00:00
}
var last = this._ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6
2018-09-12 17:26:21 +00:00
? this._lastUsable : this._broadcast;
2019-01-13 20:37:13 +00:00
var increment = (last - this._network) / this.Count;
var uintNetwork = this._network + ((increment + 1) * i);
var ipn = new IPNetwork(uintNetwork, this._ipnetwork.AddressFamily, this._cidrSubnet);
2018-09-12 17:26:21 +00:00
return ipn;
}
}
#endregion
#region IEnumerable Members
IEnumerator<IPNetwork> IEnumerable<IPNetwork>.GetEnumerator()
{
return this;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
#region IEnumerator<IPNetwork> Members
public IPNetwork Current => this[this._enumerator];
2018-09-12 17:26:21 +00:00
#endregion
#region IDisposable Members
public void Dispose()
{
// nothing to dispose
return;
}
#endregion
#region IEnumerator Members
object IEnumerator.Current => this.Current;
2018-09-12 17:26:21 +00:00
public bool MoveNext()
{
this._enumerator++;
if (this._enumerator >= this.Count)
{
return false;
}
return true;
}
public void Reset()
{
this._enumerator = -1;
}
#endregion
#endregion
}
}