This commit is contained in:
2024-02-23 06:57:07 -05:00
commit 8fb7082f56
104 changed files with 284139 additions and 0 deletions

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tor.Helpers;
using System.ComponentModel;
using Tor.Converters;
namespace Tor
{
/// <summary>
/// A structure containing byte information, in a specified magnitude.
/// </summary>
[Serializable]
[TypeConverter(typeof(BytesTypeConverter))]
public struct Bytes
{
/// <summary>
/// Gets an empty <see cref="Bytes"/> structure.
/// </summary>
public static readonly Bytes Empty = new Bytes();
private Bits units;
private double value;
/// <summary>
/// Initializes a new instance of the <see cref="Bytes"/> struct.
/// </summary>
/// <param name="value">The value in bytes.</param>
public Bytes(double value)
{
this.units = Bits.B;
this.value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="Bytes"/> struct.
/// </summary>
/// <param name="value">The value relative to the specified units.</param>
/// <param name="units">The units of the bytes.</param>
public Bytes(double value, Bits units)
{
this.units = units;
this.value = value;
}
#region Properties
/// <summary>
/// Gets or sets the units of the bytes.
/// </summary>
public Bits Units
{
get { return units; }
set { units = value; }
}
/// <summary>
/// Gets or sets the value of bytes, relative to the units.
/// </summary>
public double Value
{
get { return value; }
set { this.value = value; }
}
#endregion
#region System.Object
/// <summary>
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
/// </summary>
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
return obj != null && obj is Bytes && ((Bytes)obj).units == units && ((Bytes)obj).value == value;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Convert.ToInt32(units);
hash = hash * 23 + Convert.ToInt32(value);
return hash;
}
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
string unit = "bytes";
String strBytes;
switch (units)
{
case Bits.KB:
unit = "KBytes";
strBytes=string.Format("{0} {1}",Convert.ToInt32(value),unit);
break;
case Bits.MB:
unit = "MBytes";
strBytes=string.Format("{0} {1}",Convert.ToInt32(value),unit);
break;
case Bits.GB:
unit = "GBytes";
strBytes=string.Format("{0} {1}",Utility.FormatNumber(value,1,false),unit);
break;
case Bits.TB:
unit = "TBytes";
strBytes=string.Format("{0} {1}",Utility.FormatNumber(value,1,false),unit);
break;
default :
strBytes=string.Format("{0} {1}",Convert.ToInt32(value),unit);
break;
}
return strBytes;
}
#endregion
/// <summary>
/// Normalizes the bytes by dividing the value into the nearest acceptable unit.
/// </summary>
/// <returns>A <see cref="Bytes"/> struct containing the normalized values.</returns>
public Bytes Normalize()
{
if (units == Bits.TB)
return this;
if (value == 0.00)
return this;
int max = (int)Bits.TB;
int unit = (int)units;
double absolute = Math.Abs(value);
while (1024 <= absolute && unit < max)
{
absolute = Math.Round(absolute / 1024.00, 4);
unit++;
}
if (value < 0.00)
absolute *= -1.0;
return new Bytes(absolute, (Bits)unit);
}
/// <summary>
/// Converts the units of the bytes into another unit.
/// </summary>
/// <param name="unit">The units to convert the bytes to.</param>
/// <returns>A <see cref="Bytes"/> structure containing the converted value.</returns>
public Bytes ToUnit(Bits unit)
{
if (units == unit)
return this;
if (value == 0.00)
return new Bytes(0.00, unit);
int from = 10 - (int)units;
int to = 10 - (int)unit;
double absolute = Math.Abs(value);
if (from < to)
{
while (from < to)
{
absolute = Math.Round(absolute * 1024.00, 4);
from++;
}
}
else
{
while (to < from)
{
absolute = Math.Round(absolute / 1024.00, 4);
from--;
}
}
if (value < 0.00)
absolute *= -1.0;
return new Bytes(absolute, unit);
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Globalization;
namespace Tor.Converters
{
/// <summary>
/// A class providing the methods necessary to convert between a <see cref="Bytes"/> object and <see cref="System.String"/> object.
/// </summary>
public sealed class BytesTypeConverter : TypeConverter
{
#region System.ComponentModel.TypeConverter
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="sourceType">A <see cref="T:System.Type" /> that represents the type you want to convert from.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType.Equals(typeof(double)))
return true;
if (sourceType.Equals(typeof(string)))
return true;
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is double)
return new Bytes((double)value);
if (value is string)
return new Bytes(Convert.ToDouble(value));
return base.ConvertFrom(context, culture, value);
}
/// <summary>
/// Converts the given value object to the specified type, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo" />. If null is passed, the current culture is assumed.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <param name="destinationType">The <see cref="T:System.Type" /> to convert the <paramref name="value" /> parameter to.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType.Equals(typeof(double)))
return ((Bytes)value).ToUnit(Bits.B).Value;
if (destinationType.Equals(typeof(string)))
return ((Bytes)value).ToString();
return base.ConvertTo(context, culture, value, destinationType);
}
#endregion
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Globalization;
namespace Tor.Converters
{
/// <summary>
/// A class providing the methods necessary to convert between a <see cref="HostAuth"/> object and <see cref="System.String"/> object.
/// </summary>
public sealed class HostAuthTypeConverter : TypeConverter
{
#region System.ComponentModel.TypeConverter
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="sourceType">A <see cref="T:System.Type" /> that represents the type you want to convert from.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType.Equals(typeof(string)))
return true;
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
/// <exception cref="InvalidCastException">A string must contain a username, or a username and password, format</exception>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value == null)
return HostAuth.Null;
if (value is string)
{
string actual = value as string;
if (actual.Contains(":"))
{
string[] parts = actual.Split(':');
if (parts.Length != 2)
throw new InvalidCastException("A string must contain a username, or a username and password, format");
return new HostAuth(parts[0], parts[1]);
}
return new HostAuth(actual, null);
}
return base.ConvertFrom(context, culture, value);
}
/// <summary>
/// Converts the given value object to the specified type, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo" />. If null is passed, the current culture is assumed.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <param name="destinationType">The <see cref="T:System.Type" /> to convert the <paramref name="value" /> parameter to.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType.Equals(typeof(string)))
{
HostAuth hostAuth = (HostAuth)value;
if (hostAuth.IsNull)
return "";
if (hostAuth.Password == null)
return hostAuth.Username;
return string.Format("{0}:{1}", hostAuth.Username, hostAuth.Password);
}
return base.ConvertTo(context, culture, value, destinationType);
}
#endregion
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Globalization;
namespace Tor.Converters
{
/// <summary>
/// A class providing the methods necessary to convert between a <see cref="Host"/> object and <see cref="System.String"/> object.
/// </summary>
public sealed class HostTypeConverter : TypeConverter
{
#region System.ComponentModel.TypeConverter
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="sourceType">A <see cref="T:System.Type" /> that represents the type you want to convert from.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType.Equals(typeof(string)))
return true;
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
/// <exception cref="InvalidCastException">
/// A string must contain an IP address, or an IP address and port number, format
/// or
/// A string containing an IP address and port must contain a valid port number
/// </exception>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value == null)
return Host.Null;
if (value is string)
{
string actual = value as string;
if (actual.Contains(":"))
{
int port;
string[] parts = actual.Split(':');
if (parts.Length != 2)
throw new InvalidCastException("A string must contain an IP address, or an IP address and port number, format");
if (!int.TryParse(parts[1], out port))
throw new InvalidCastException("A string containing an IP address and port must contain a valid port number");
return new Host(parts[0], port);
}
return new Host(actual);
}
return base.ConvertFrom(context, culture, value);
}
/// <summary>
/// Converts the given value object to the specified type, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo" />. If null is passed, the current culture is assumed.</param>
/// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
/// <param name="destinationType">The <see cref="T:System.Type" /> to convert the <paramref name="value" /> parameter to.</param>
/// <returns>
/// An <see cref="T:System.Object" /> that represents the converted value.
/// </returns>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType.Equals(typeof(string)))
{
Host host = (Host)value;
if (host.IsNull)
return "";
if (host.Port == -1)
return host.Address;
return string.Format("{0}:{1}", host.Address, host.Port);
}
return base.ConvertTo(context, culture, value, destinationType);
}
#endregion
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Tor
{
/// <summary>
/// An enumerator which extends the <see cref="Boolean"/> primitive type to accept an automatic state.
/// </summary>
public enum Auto : int
{
/// <summary>
/// The value should be determined automatically.
/// </summary>
[Description("auto")]
Auto = -1,
/// <summary>
/// The value is <c>false</c>.
/// </summary>
[Description("0")]
False = 0,
/// <summary>
/// The value is <c>true</c>.
/// </summary>
[Description("1")]
True = 1
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Tor
{
/// <summary>
/// An enumerator containing the different units of bytes.
/// </summary>
public enum Bits : int
{
/// <summary>
/// The unit is bytes.
/// </summary>
[Description("bytes")]
B = 0,
/// <summary>
/// The unit is kilo-bytes.
/// </summary>
[Description("KBytes")]
KB = 1,
/// <summary>
/// The unit is mega-bytes.
/// </summary>
[Description("MBytes")]
MB = 2,
/// <summary>
/// The unit is giga-bytes.
/// </summary>
[Description("GBytes")]
GB = 3,
/// <summary>
/// The unit is tera-bytes.
/// </summary>
[Description("TBytes")]
TB = 4
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Tor
{
/// <summary>
/// A class containing the details of an exception which occurred when processing a tor operation.
/// </summary>
public class TorException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="TorException"/> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public TorException(string message) : base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TorException"/> class.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public TorException(string message, Exception innerException) : base(message, innerException)
{
}
}
}

View File

@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Diagnostics;
namespace Tor.Helpers
{
/// <summary>
/// A class containing methods to assist with reflection-based processing.
/// </summary>
//[DebuggerStepThrough]
internal static class ReflectionHelper
{
/// <summary>
/// Converts a value into the destination type.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <param name="destinationType">The type to convert the value to.</param>
/// <returns>A <see cref="System.Object"/> matching the destination type.</returns>
public static object Convert(object value, Type destinationType)
{
if (value == null)
return destinationType.IsPrimitive || destinationType.IsValueType ? Activator.CreateInstance(destinationType) : null;
if (destinationType.IsEnum)
return GetEnumerator<DescriptionAttribute>(destinationType, attribute => attribute.Description.Equals(value.ToString(), StringComparison.CurrentCultureIgnoreCase));
if (value is bool && destinationType == typeof(string))
return ((bool)value) ? "1" : "0";
if (destinationType == typeof(bool) && ("0".Equals(value) || "1".Equals(value)))
return "1".Equals(value);
if (destinationType.IsValueType)
{
TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
if (value == null)
return Activator.CreateInstance(destinationType);
if (converter != null && converter.CanConvertFrom(value.GetType()))
return converter.ConvertFrom(value);
}
return System.Convert.ChangeType(value, destinationType);
}
/// <summary>
/// Gets an attribute from the value of an enumerator.
/// </summary>
/// <typeparam name="TEnum">The type of the enumerator.</typeparam>
/// <typeparam name="TAttribute">The attribute to retrieve.</typeparam>
/// <param name="value">The value of the enumerator.</param>
/// <returns>A <typeparamref name="TAttribute"/> object instance; otherwise, <c>null</c>.</returns>
public static TAttribute GetAttribute<TEnum, TAttribute>(TEnum value) where TAttribute : Attribute
{
MemberInfo member = typeof(TEnum).GetMember(System.Convert.ToString(value), BindingFlags.Public | BindingFlags.Static).FirstOrDefault();
if (member == null)
return null;
return Attribute.GetCustomAttribute(member, typeof(TAttribute)) as TAttribute;
}
/// <summary>
/// Gets the description value of an enumerator.
/// </summary>
/// <typeparam name="TEnum">The type of the enumerator.</typeparam>
/// <param name="value">The value of the enumerator.</param>
/// <returns>A <see cref="System.String"/> containing the description value; otherwise, <c>null</c>.</returns>
public static string GetDescription<TEnum>(TEnum value)
{
DescriptionAttribute attribute = GetAttribute<TEnum, DescriptionAttribute>(value);
if (attribute == null)
return null;
return attribute.Description;
}
/// <summary>
/// Gets an enumerator value by performing a specified selector against the matched attribute of the enumerator values.
/// </summary>
/// <typeparam name="TAttribute">The attribute to retrieve.</typeparam>
/// <param name="enumType">The type of the enumerator.</param>
/// <param name="selector">The selector to execute against the attribute.</param>
/// <returns>A <typeparamref name="TEnum"/> value matching the selector pattern.</returns>
public static object GetEnumerator<TAttribute>(Type enumType, Func<TAttribute, bool> selector) where TAttribute : Attribute
{
MemberInfo[] members = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (MemberInfo member in members)
{
TAttribute attribute = Attribute.GetCustomAttribute(member, typeof(TAttribute)) as TAttribute;
if (attribute == null)
continue;
if (selector(attribute))
return Enum.Parse(enumType, member.Name);
}
return Activator.CreateInstance(enumType);
}
/// <summary>
/// Gets an enumerator value by performing a specified selector against the matched attribute of the enumerator values.
/// </summary>
/// <typeparam name="TEnum">The type of the enumerator.</typeparam>
/// <typeparam name="TAttribute">The attribute to retrieve.</typeparam>
/// <param name="selector">The selector to execute against the attribute.</param>
/// <returns>A <typeparamref name="TEnum"/> value matching the selector pattern.</returns>
public static TEnum GetEnumerator<TEnum, TAttribute>(Func<TAttribute, bool> selector) where TAttribute : Attribute
{
MemberInfo[] members = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (MemberInfo member in members)
{
TAttribute attribute = Attribute.GetCustomAttribute(member, typeof(TAttribute)) as TAttribute;
if (attribute == null)
continue;
if (selector(attribute))
return (TEnum)Enum.Parse(typeof(TEnum), member.Name);
}
return default(TEnum);
}
/// <summary>
/// Gets a collection of attributes from all enumerator values.
/// </summary>
/// <typeparam name="TEnum">The type of the enumerator.</typeparam>
/// <typeparam name="TAttribute">The type of attribute to retrieve.</typeparam>
/// <returns>A <see cref="List{TAttribute}"/> containing the resulting attribute list.</returns>
public static List<TAttribute> GetEnumeratorAttributes<TEnum, TAttribute>() where TAttribute : Attribute
{
List<TAttribute> values = new List<TAttribute>();
MemberInfo[] members = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (MemberInfo member in members)
{
TAttribute attribute = Attribute.GetCustomAttribute(member, typeof(TAttribute)) as TAttribute;
if (attribute != null && !values.Contains(attribute))
values.Add(attribute);
}
return values;
}
/// <summary>
/// Gets a collection of attribute values from all enumerator values of a specified type.
/// </summary>
/// <typeparam name="TEnum">The type of the enumerator.</typeparam>
/// <typeparam name="TAttribute">The type of attribute to retrieve.</typeparam>
/// <typeparam name="TValue">The type of value to retrieve from the attribute.</typeparam>
/// <param name="selector">The selector to execute against the attribute.</param>
/// <returns>A <see cref="List{TValue}"/> containing the resulting attribute value list.</returns>
public static List<TValue> GetEnumeratorAttributes<TEnum, TAttribute, TValue>(Func<TAttribute, TValue> selector) where TAttribute : Attribute
{
List<TAttribute> attributes = GetEnumeratorAttributes<TEnum, TAttribute>();
List<TValue> values = new List<TValue>();
foreach (TAttribute attribute in attributes)
{
if (attribute == null)
continue;
values.Add(selector(attribute));
}
return values;
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Tor.Helpers
{
/// <summary>
/// A class containing methods to assist with string-based parsing.
/// </summary>
internal static class StringHelper
{
/// <summary>
/// Gets all blocks from a <see cref="System.String"/> where the delimiter is not included within quotations.
/// </summary>
/// <param name="data">The <see cref="System.String"/> to retrieve the blocks from.</param>
/// <param name="delimiter">The delimiter to search for.</param>
/// <returns>A <see cref="System.String"/> array containing the blocks.</returns>
public static string[] GetAll(string data, char delimiter)
{
if (data == null)
return null;
int index = 0;
string part = null;
List<string> blocks = new List<string>();
while ((part = GetNext(data, index, delimiter)) != null)
{
blocks.Add(part);
index += part.Length + 1;
}
return blocks.ToArray();
}
/// <summary>
/// Gets the next block from a <see cref="System.String"/> where the delimiter is not included within quotations.
/// </summary>
/// <param name="data">The <see cref="System.String"/> to retrieve the block from.</param>
/// <param name="start">The start index within the string.</param>
/// <param name="delimiter">The delimiter to search for.</param>
/// <returns>A <see cref="System.String"/> containing the block data.</returns>
public static string GetNext(string data, int start, char delimiter)
{
if (data == null)
return null;
if (data.Length <= start)
return null;
int index = start;
int length = data.Length;
bool escaped = false;
while (index < length)
{
char c = data[index++];
if (c == '"')
{
escaped = !escaped;
continue;
}
if (c == delimiter && !escaped)
{
index--;
break;
}
}
return data.Substring(start, index - start);
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Tor.Converters;
namespace Tor
{
/// <summary>
/// A structure containing information on a host, such as an address and/or port number.
/// </summary>
[Serializable]
[TypeConverter(typeof(HostTypeConverter))]
public struct Host
{
private string address;
private int port;
/// <summary>
/// Initializes a new instance of the <see cref="Host"/> struct.
/// </summary>
/// <param name="address">The address of the host.</param>
public Host(string address)
{
if (string.IsNullOrWhiteSpace(address))
throw new ArgumentException("A host address cannot be null or white-space", "address");
this.address = address;
this.port = -1;
}
/// <summary>
/// Initializes a new instance of the <see cref="Host"/> struct.
/// </summary>
/// <param name="address">The address of the host.</param>
/// <param name="port">The port number open on the host. A value of <c>-1</c> indicates an unspecified port number.</param>
public Host(string address, int port)
{
if (string.IsNullOrWhiteSpace(address))
throw new ArgumentException("A host address cannot be null or white-space", "address");
if (port != -1 && (port <= 0 || short.MaxValue < port))
throw new ArgumentOutOfRangeException("port", "A port number must fall within an acceptable range");
this.address = address;
this.port = port;
}
#region Properties
/// <summary>
/// Gets or sets the address of the host.
/// </summary>
public string Address
{
get { return address; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("A host address cannot be null or white-space");
address = value;
}
}
/// <summary>
/// Gets a value indicating whether the host is actually a null reference.
/// </summary>
public bool IsNull
{
get { return address == null; }
}
/// <summary>
/// Gets or sets the port number open on the host. A value of <c>-1</c> indicates an unspecified port number.
/// </summary>
public int Port
{
get { return port; }
set
{
if (port != -1 && (port <= 0 || short.MaxValue < port))
throw new ArgumentOutOfRangeException("value", "A port number must fall within an acceptable range");
port = value;
}
}
/// <summary>
/// Gets a <see cref="Host"/> object instance representing a <c>null</c> value.
/// </summary>
public static Host Null
{
get { return new Host() { address = null, port = -1 }; }
}
#endregion
#region System.Object
/// <summary>
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
/// </summary>
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
return obj != null && obj is Host && ((Host)obj).address == address && ((Host)obj).port == port;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + address.GetHashCode();
hash = hash * 23 + port;
return hash;
}
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
if (port == -1)
return address;
else
return string.Format("{0}:{1}", address, port);
}
#endregion
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Tor.Converters;
namespace Tor
{
/// <summary>
/// A structure containing credential information for a host connection.
/// </summary>
[Serializable]
[TypeConverter(typeof(HostAuthTypeConverter))]
public struct HostAuth
{
private string password;
private string username;
/// <summary>
/// Initializes a new instance of the <see cref="HostAuth"/> struct.
/// </summary>
/// <param name="username">The username of the credentials.</param>
/// <param name="password">The password of the credentials. A value of <c>null</c> indicates no password.</param>
public HostAuth(string username, string password)
{
this.password = password;
this.username = username;
}
#region Properties
/// <summary>
/// Gets a value indicating whether the host authentication is actually a null reference.
/// </summary>
public bool IsNull
{
get { return username == null && password == null; }
}
/// <summary>
/// Gets or sets the password used when authenticating. A value of <c>null</c> indicates no password.
/// </summary>
public string Password
{
get { return password; }
set { password = value; }
}
/// <summary>
/// Gets or sets the username used when authenticating.
/// </summary>
public string Username
{
get { return username; }
set { username = value; }
}
/// <summary>
/// Gets a <see cref="HostAuth"/> object instance representing a <c>null</c> value.
/// </summary>
public static HostAuth Null
{
get { return new HostAuth() { username = null, password = null }; }
}
#endregion
#region System.Object
/// <summary>
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
/// </summary>
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
return obj != null && obj is HostAuth && ((HostAuth)obj).password == password && ((HostAuth)obj).username == username;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + (username != null ? username.GetHashCode() : 0);
hash = hash * 23 + (password != null ? password.GetHashCode() : 0);
return hash;
}
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
if (username == null && password == null)
return "";
if (password == null)
return username;
return string.Format("{0}:{1}", username, password);
}
#endregion
}
}