Files
2016-08-08 02:37:18 +08:00

233 lines
6.4 KiB
C#

#if !DISABLE_DHT
//
// NodeId.cs
//
// Authors:
// Jérémie Laval <jeremie.laval@gmail.com>
// Alan McGovern <alan.mcgovern@gmail.com>
//
// Copyright (C) 2008 Jérémie Laval, Alan McGovern
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Text;
using Tancoder.Torrent.BEncoding;
namespace Tancoder.Torrent.Dht
{
public class NodeId : IEquatable<NodeId>, IComparable<NodeId>, IComparable
{
static readonly Random random = new Random();
BigInteger value;
private byte[] bytes;
public byte[] Bytes
{
get { return bytes; }
}
public NodeId(byte[] value)
: this(new BigInteger(value))
{
this.bytes = value;
}
public NodeId(InfoHash infoHash)
: this(infoHash.ToArray ())
{
}
private NodeId(BigInteger value)
{
this.value = value;
}
public NodeId(BEncodedString value)
: this(new BigInteger(value.TextBytes))
{
this.bytes = value.TextBytes;
}
public override bool Equals(object obj)
{
return Equals(obj as NodeId);
}
public bool Equals(NodeId other)
{
if ((object)other == null)
return false;
return value.Equals(other.value);
}
public override int GetHashCode()
{
return value.GetHashCode();
}
public override string ToString()
{
return value.ToString();
}
public int CompareTo(object obj)
{
return CompareTo(obj as NodeId);
}
public int CompareTo(NodeId other)
{
if ((object)other == null)
return 1;
BigInteger.Sign s = value.Compare(other.value);
if (s == BigInteger.Sign.Zero)
return 0;
else if (s == BigInteger.Sign.Positive)
return 1;
else return -1;
}
public NodeId Xor(NodeId right)
{
return new NodeId(value.Xor(right.value));
}
public static implicit operator NodeId(int value)
{
return new NodeId(new BigInteger((uint)value));
}
public static NodeId operator -(NodeId first)
{
CheckArguments(first);
return new NodeId(first.value);
}
public static NodeId operator -(NodeId first, NodeId second)
{
CheckArguments(first, second);
return new NodeId(first.value - second.value);
}
public static bool operator >(NodeId first, NodeId second)
{
CheckArguments(first, second);
return first.value > second.value;
}
public static bool operator <(NodeId first, NodeId second)
{
CheckArguments(first, second);
return first.value < second.value;
}
public static bool operator <=(NodeId first, NodeId second)
{
CheckArguments(first, second);
return first < second || first == second;
}
public static bool operator >=(NodeId first, NodeId second)
{
CheckArguments(first, second);
return first > second || first == second;
}
public static NodeId operator +(NodeId first, NodeId second)
{
CheckArguments(first, second);
return new NodeId(first.value + second.value);
}
public static NodeId operator *(NodeId first, NodeId second)
{
CheckArguments(first, second);
return new NodeId(first.value * second.value);
}
public static NodeId operator /(NodeId first, NodeId second)
{
CheckArguments(first, second);
return new NodeId(first.value / second.value);
}
public static NodeId operator %(NodeId first, NodeId second)
{
CheckArguments(first, second);
return new NodeId(first.value % second.value);
}
private static void CheckArguments(NodeId first)
{
if (first == null)
throw new ArgumentNullException("first");
}
private static void CheckArguments(NodeId first, NodeId second)
{
if (first == null)
throw new ArgumentNullException("first");
if (second == null)
throw new ArgumentNullException("second");
}
public static bool operator ==(NodeId first, NodeId second)
{
if ((object)first == null)
return (object)second == null;
if ((object)second == null)
return false;
return first.value == second.value;
}
public static bool operator !=(NodeId first, NodeId second)
{
return first.value != second.value;
}
public BEncodedString BencodedString()
{
return new BEncodedString(value.GetBytes());
}
public NodeId Pow(uint p)
{
value = BigInteger.Pow(value, p);
return this;
}
public static NodeId Create()
{
byte[] b = new byte[20];
lock (random)
random.NextBytes(b);
return new NodeId(b);
}
}
}
#endif