wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 51  →  ?path2? @ 52
File deleted
/CSV.cs
File deleted
/KeyValue.cs
File deleted
/Linq.cs
File deleted
/Strings.cs
File deleted
/Geodesics/Distance.cs
File deleted
/Geodesics/Constants.cs
File deleted
/Geodesics/GeographicCoordinate.cs
File deleted
/Geodesics/GeodesicExtensions.cs
File deleted
/Numerics.cs
File deleted
/BitTwiddling.cs
File deleted
/NetHash.cs
File deleted
/IO.cs
File deleted
/XML.cs
File deleted
/Extensions.cs
File deleted
/Reflection.cs
File deleted
/Arrays.cs
File deleted
/Cryptography.cs
/Arrays/Arrays.cs
@@ -0,0 +1,133 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
 
namespace wasSharp
{
public static class Arrays
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Gets an array element at a given modulo index.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="index">a positive or negative index of the element</param>
/// <param name="data">the array</param>
/// <return>an array element</return>
public static T GetElementAt<T>(T[] data, int index)
{
return index < 0 ? data[(index % data.Length + data.Length) % data.Length] : data[index % data.Length];
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Gets a sub-array from an array.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="data">the array</param>
/// <param name="start">the start index</param>
/// <param name="stop">the stop index (-1 denotes the end)</param>
/// <returns>the array slice between start and stop</returns>
public static T[] GetSubArray<T>(T[] data, int start, int stop)
{
if (stop.Equals(-1))
stop = data.Length - 1;
var result = new T[stop - start + 1];
Array.Copy(data, start, result, 0, stop - start + 1);
return result;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Delete a sub-array and return the result.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="data">the array</param>
/// <param name="start">the start index</param>
/// <param name="stop">the stop index (-1 denotes the end)</param>
/// <returns>the array without elements between start and stop</returns>
public static T[] DeleteSubArray<T>(T[] data, int start, int stop)
{
if (stop.Equals(-1))
stop = data.Length - 1;
var result = new T[data.Length - (stop - start) - 1];
Array.Copy(data, 0, result, 0, start);
Array.Copy(data, stop + 1, result, start, data.Length - stop - 1);
return result;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Concatenate multiple arrays.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="arrays">multiple arrays</param>
/// <returns>a flat array with all arrays concatenated</returns>
public static T[] ConcatenateArrays<T>(params T[][] arrays)
{
var resultLength = 0;
foreach (var o in arrays)
{
resultLength += o.Length;
}
var result = new T[resultLength];
var offset = 0;
for (var x = 0; x < arrays.Length; x++)
{
arrays[x].CopyTo(result, offset);
offset += arrays[x].Length;
}
return result;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Permutes an array in reverse a given number of times.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="input">the array</param>
/// <param name="times">the number of times to permute</param>
/// <returns>the array with the elements permuted</returns>
public static T[] ReversePermuteArrayElements<T>(T[] input, int times)
{
if (times.Equals(0)) return input;
var slice = new T[input.Length];
Array.Copy(input, 1, slice, 0, input.Length - 1);
Array.Copy(input, 0, slice, input.Length - 1, 1);
return ReversePermuteArrayElements(slice, --times);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Permutes an array forward a given number of times.
/// </summary>
/// <typeparam name="T">the array type</typeparam>
/// <param name="input">the array</param>
/// <param name="times">the number of times to permute</param>
/// <returns>the array with the elements permuted</returns>
public static T[] ForwardPermuteArrayElements<T>(T[] input, int times)
{
if (times.Equals(0)) return input;
var slice = new T[input.Length];
Array.Copy(input, input.Length - 1, slice, 0, 1);
Array.Copy(input, 0, slice, 1, input.Length - 1);
return ForwardPermuteArrayElements(slice, --times);
}
}
}
/Bit/BitTwiddling.cs
@@ -0,0 +1,136 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.Collections.Generic;
using System.Linq;
 
namespace wasSharp
{
public static class BitTwiddling
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Swaps two integers passed by reference using XOR.
/// </summary>
/// <param name="q">first integer to swap</param>
/// <param name="p">second integer to swap</param>
public static void XORSwap(ref int q, ref int p)
{
q ^= p;
p ^= q;
q ^= p;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Checks whether a flag is set for a bitmask.
/// </summary>
/// <typeparam name="T">a data type</typeparam>
/// <typeparam name="U">a data type</typeparam>
/// <param name="mask">the mask to check the flag for</param>
/// <param name="flag">the flag to check</param>
/// <returns>true in case the flag is set</returns>
public static bool IsMaskFlagSet<T, U>(this T mask, U flag) where T : struct where U : struct
{
return unchecked(mask as dynamic & flag as dynamic) != 0;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Sets a flag for a bitmask.
/// </summary>
/// <typeparam name="T">a data type</typeparam>
/// <typeparam name="U">a data type</typeparam>
/// <param name="mask">the mask to set the flag on</param>
/// <param name="flag">the flag to set</param>
public static void SetMaskFlag<T, U>(ref T mask, U flag) where T : struct where U : struct
{
mask = unchecked(mask as dynamic | flag as dynamic);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Create a bitmask from multiple flags.
/// </summary>
/// <typeparam name="T">a data type</typeparam>
/// <param name="flag">the flags to set</param>
/// <returns>a bitmask</returns>
public static T CreateMask<T>(this IEnumerable<T> flag) where T : struct
{
return flag.Aggregate((o, p) => unchecked(o as dynamic | p as dynamic));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Unset a flag for a bitmask.
/// </summary>
/// <typeparam name="T">a data type</typeparam>
/// <typeparam name="U">a data type</typeparam>
/// <param name="mask">the mask to unset the flag on</param>
/// <param name="flag">the flag to unset</param>
public static void UnsetMaskFlag<T, U>(ref T mask, U flag)
{
mask = unchecked(mask as dynamic & ~(flag as dynamic));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Toggle a flag for a bitmask.
/// </summary>
/// <typeparam name="T">a data type</typeparam>
/// <typeparam name="U">a data type</typeparam>
/// <param name="mask">the mask to toggle the flag on</param>
/// <param name="flag">the flag to toggle</param>
public static void ToggleMaskFlag<T, U>(ref T mask, U flag)
{
mask = unchecked(mask as dynamic ^ flag as dynamic);
}
 
/// <summary>
/// Computes the previous power of two.
/// </summary>
/// <param name="x">the integer</param>
/// <returns>the previous power of two</returns>
/// <remarks>Adapted from Hacker's Delight ISBN-10:0201914654</remarks>
public static T PreviousPowerOfTwo<T>(this T x)
{
var y = x as dynamic;
unchecked
{
y = y | (y >> 1);
y = y | (y >> 2);
y = y | (y >> 4);
y = y | (y >> 8);
y = y | (y >> 16);
return y - (y >> 1);
}
}
 
/// <summary>
/// Determines if a number is a power of two.
/// </summary>
/// <typeparam name="T">the number type</typeparam>
/// <param name="x">the number</param>
/// <returns>true of the number is a power of two</returns>
public static bool IsPowerOfTwo<T>(this T x)
{
var y = x as dynamic;
return (y != 0) && ((y & (y - 1)) == 0);
}
}
}
/Cryptography/Cryptography.cs
@@ -0,0 +1,395 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace wasSharp
{
public static class Cryptography
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Encrypt or decrypt a message given a set of rotors, plugs and a reflector.
/// </summary>
/// <param name="message">the message to encyrpt or decrypt</param>
/// <param name="rotors">any combination of: 1, 2, 3, 4, 5, 6, 7, 8, b, g</param>
/// <param name="plugs">the letter representing the start character for the rotor</param>
/// <param name="reflector">any one of: B, b, C, c</param>
/// <returns>either a decrypted or encrypted string</returns>
public static string ENIGMA(string message, char[] rotors, char[] plugs, char reflector)
{
var def_rotors = new Dictionary<char, char[]>
{
{
'1', new[]
{
'e', 'k', 'm', 'f', 'l',
'g', 'd', 'q', 'v', 'z',
'n', 't', 'o', 'w', 'y',
'h', 'x', 'u', 's', 'p',
'a', 'i', 'b', 'r', 'c',
'j'
}
},
{
'2', new[]
{
'a', 'j', 'd', 'k', 's',
'i', 'r', 'u', 'x', 'b',
'l', 'h', 'w', 't', 'm',
'c', 'q', 'g', 'z', 'n',
'p', 'y', 'f', 'v', 'o',
'e'
}
},
{
'3', new[]
{
'b', 'd', 'f', 'h', 'j',
'l', 'c', 'p', 'r', 't',
'x', 'v', 'z', 'n', 'y',
'e', 'i', 'w', 'g', 'a',
'k', 'm', 'u', 's', 'q',
'o'
}
},
{
'4', new[]
{
'e', 's', 'o', 'v', 'p',
'z', 'j', 'a', 'y', 'q',
'u', 'i', 'r', 'h', 'x',
'l', 'n', 'f', 't', 'g',
'k', 'd', 'c', 'm', 'w',
'b'
}
},
{
'5', new[]
{
'v', 'z', 'b', 'r', 'g',
'i', 't', 'y', 'u', 'p',
's', 'd', 'n', 'h', 'l',
'x', 'a', 'w', 'm', 'j',
'q', 'o', 'f', 'e', 'c',
'k'
}
},
{
'6', new[]
{
'j', 'p', 'g', 'v', 'o',
'u', 'm', 'f', 'y', 'q',
'b', 'e', 'n', 'h', 'z',
'r', 'd', 'k', 'a', 's',
'x', 'l', 'i', 'c', 't',
'w'
}
},
{
'7', new[]
{
'n', 'z', 'j', 'h', 'g',
'r', 'c', 'x', 'm', 'y',
's', 'w', 'b', 'o', 'u',
'f', 'a', 'i', 'v', 'l',
'p', 'e', 'k', 'q', 'd',
't'
}
},
{
'8', new[]
{
'f', 'k', 'q', 'h', 't',
'l', 'x', 'o', 'c', 'b',
'j', 's', 'p', 'd', 'z',
'r', 'a', 'm', 'e', 'w',
'n', 'i', 'u', 'y', 'g',
'v'
}
},
{
'b', new[]
{
'l', 'e', 'y', 'j', 'v',
'c', 'n', 'i', 'x', 'w',
'p', 'b', 'q', 'm', 'd',
'r', 't', 'a', 'k', 'z',
'g', 'f', 'u', 'h', 'o',
's'
}
},
{
'g', new[]
{
'f', 's', 'o', 'k', 'a',
'n', 'u', 'e', 'r', 'h',
'm', 'b', 't', 'i', 'y',
'c', 'w', 'l', 'q', 'p',
'z', 'x', 'v', 'g', 'j',
'd'
}
}
};
 
var def_reflectors = new Dictionary<char, char[]>
{
{
'B', new[]
{
'a', 'y', 'b', 'r', 'c', 'u', 'd', 'h',
'e', 'q', 'f', 's', 'g', 'l', 'i', 'p',
'j', 'x', 'k', 'n', 'm', 'o', 't', 'z',
'v', 'w'
}
},
{
'b', new[]
{
'a', 'e', 'b', 'n', 'c', 'k', 'd', 'q',
'f', 'u', 'g', 'y', 'h', 'w', 'i', 'j',
'l', 'o', 'm', 'p', 'r', 'x', 's', 'z',
't', 'v'
}
},
{
'C', new[]
{
'a', 'f', 'b', 'v', 'c', 'p', 'd', 'j',
'e', 'i', 'g', 'o', 'h', 'y', 'k', 'r',
'l', 'z', 'm', 'x', 'n', 'w', 't', 'q',
's', 'u'
}
},
{
'c', new[]
{
'a', 'r', 'b', 'd', 'c', 'o', 'e', 'j',
'f', 'n', 'g', 't', 'h', 'k', 'i', 'v',
'l', 'm', 'p', 'w', 'q', 'z', 's', 'x',
'u', 'y'
}
}
};
 
// Setup rotors from plugs.
foreach (var rotor in rotors)
{
var plug = plugs[Array.IndexOf(rotors, rotor)];
var i = Array.IndexOf(def_rotors[rotor], plug);
if (i.Equals(0)) continue;
def_rotors[rotor] = Arrays.ConcatenateArrays(new[] { plug },
Arrays.GetSubArray(Arrays.DeleteSubArray(def_rotors[rotor], i, i), i, -1),
Arrays.GetSubArray(Arrays.DeleteSubArray(def_rotors[rotor], i + 1, -1), 0, i - 1));
}
 
var result = new StringBuilder();
foreach (var c in message)
{
if (!char.IsLetter(c))
{
result.Append(c);
continue;
}
 
// Normalize to lower.
var l = char.ToLower(c);
 
Action<char[]> rotate = o =>
{
var i = o.Length - 1;
do
{
def_rotors[o[0]] = Arrays.ForwardPermuteArrayElements(def_rotors[o[0]], 1);
if (i.Equals(0))
{
rotors = Arrays.ReversePermuteArrayElements(o, 1);
continue;
}
l = Arrays.GetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1);
o = Arrays.ReversePermuteArrayElements(o, 1);
} while (--i > -1);
};
 
// Forward pass through the Enigma's rotors.
rotate.Invoke(rotors);
 
// Reflect
var x = Array.IndexOf(def_reflectors[reflector], l);
l = (x + 1) % 2 == 0 ? def_reflectors[reflector][x - 1] : def_reflectors[reflector][x + 1];
 
// Reverse the order of the rotors.
Array.Reverse(rotors);
 
// Reverse pass through the Enigma's rotors.
rotate.Invoke(rotors);
 
if (char.IsUpper(c))
{
l = char.ToUpper(l);
}
result.Append(l);
}
 
return result.ToString();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Expand the VIGENRE key to the length of the input.
/// </summary>
/// <param name="input">the input to expand to</param>
/// <param name="enc_key">the key to expand</param>
/// <returns>the expanded key</returns>
public static string VIGENEREExpandKey(string input, string enc_key)
{
var exp_key = string.Empty;
int i = 0, j = 0;
do
{
var p = input[i];
if (!char.IsLetter(p))
{
exp_key += p;
++i;
continue;
}
var m = j % enc_key.Length;
exp_key += enc_key[m];
++j;
++i;
} while (i < input.Length);
return exp_key;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Encrypt using VIGENERE.
/// </summary>
/// <param name="input">the input to encrypt</param>
/// <param name="enc_key">the key to encrypt with</param>
/// <returns>the encrypted input</returns>
public static string EncryptVIGENERE(string input, string enc_key)
{
char[] a =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
 
enc_key = VIGENEREExpandKey(input, enc_key);
var result = string.Empty;
var i = 0;
do
{
var p = input[i];
if (!char.IsLetter(p))
{
result += p;
++i;
continue;
}
var q =
Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i]))[
Array.IndexOf(a, char.ToLowerInvariant(p))];
if (char.IsUpper(p))
{
q = char.ToUpperInvariant(q);
}
result += q;
++i;
} while (i < input.Length);
return result;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Decrypt using VIGENERE.
/// </summary>
/// <param name="input">the input to decrypt</param>
/// <param name="enc_key">the key to decrypt with</param>
/// <returns>the decrypted input</returns>
public static string DecryptVIGENERE(string input, string enc_key)
{
char[] a =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
 
enc_key = VIGENEREExpandKey(input, enc_key);
var result = string.Empty;
var i = 0;
do
{
var p = input[i];
if (!char.IsLetter(p))
{
result += p;
++i;
continue;
}
var q =
a[
Array.IndexOf(Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i])),
char.ToLowerInvariant(p))];
if (char.IsUpper(p))
{
q = char.ToUpperInvariant(q);
}
result += q;
++i;
} while (i < input.Length);
return result;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// An implementation of the ATBASH cypher for latin alphabets.
/// </summary>
/// <param name="data">the data to encrypt or decrypt</param>
/// <returns>the encrypted or decrypted data</returns>
public static string ATBASH(string data)
{
char[] a =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
 
var input = data.ToCharArray();
 
Parallel.ForEach(Enumerable.Range(0, data.Length), i =>
{
var e = input[i];
if (!char.IsLetter(e)) return;
var x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e));
if (!char.IsUpper(e))
{
input[i] = a[x];
return;
}
input[i] = char.ToUpperInvariant(a[x]);
});
 
return new string(input);
}
}
}
/Cryptography/Extensions.cs
@@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Text;
using System.Threading.Tasks;
 
namespace wasSharp
{
public static class Extensions
{
/// <summary>
/// Combine two UUIDs together by taking the MD5 hash of a byte array
/// containing both UUIDs
/// </summary>
/// <param name="first">First UUID to combine</param>
/// <param name="second">Second UUID to combine</param>
/// <returns>The UUID product of the combination</returns>
public static Guid CombineXOR(this Guid p, Guid q)
{
var l = p.ToByteArray();
var r = q.ToByteArray();
byte[] combine = new byte[16];
Parallel.For(0, 16, i =>
{
combine[i] = (byte)(l[i] ^ r[i]);
});
 
return new Guid(combine);
}
 
/// <summary>
/// Converts a byte array to a hexadecimal string.
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string ToHexString(this byte[] bytes)
{
StringBuilder str = new StringBuilder();
 
for (int i = 0; i < bytes.Length; i++)
str.AppendFormat("{0:X2}", bytes[i]);
 
return str.ToString();
}
}
}
/Cryptography/NetHash.cs
@@ -0,0 +1,43 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.Collections.Generic;
 
namespace wasSharp
{
public struct NetHash
{
private readonly int hashCode;
 
public NetHash(int hashCode = 17)
{
this.hashCode = hashCode;
}
 
public static NetHash Init => new NetHash();
 
public static implicit operator int(NetHash hashCode)
{
return hashCode.GetHashCode();
}
 
public NetHash Hash<T>(T obj)
{
var c = EqualityComparer<T>.Default;
var h = c.Equals(obj, default(T)) ? 0 : obj.GetHashCode();
unchecked
{
h += hashCode * 31;
}
return new NetHash(h);
}
 
public override int GetHashCode()
{
return hashCode;
}
}
}
/IO/IO.cs
@@ -0,0 +1,177 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace wasSharp
{
public static class IO
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Combine multiple paths.
/// </summary>
/// <param name="paths">an array of paths</param>
/// <returns>a combined path</returns>
public static string PathCombine(params string[] paths)
{
return paths.Aggregate((x, y) => Path.Combine(x, y));
}
 
/// <summary>
/// Strip characters that are incompatible with file names.
/// </summary>
/// <param name="fileName">the name of the file</param>
/// <returns>a clean string</returns>
private static string CleanFileName(string fileName)
{
return Path.GetInvalidFileNameChars()
.Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Compress a stream using Deflate compression.
/// </summary>
/// <param name="uncompressedSourceStream">the stream to compress</param>
/// <param name="compressedDestinationStream">the stream to write the compressed stream to</param>
/// <param name="leaveOpen">whether to leave the compression stream open</param>
/// <returns>an awaitable Task</returns>
public static async Task DeflateCompress(this Stream uncompressedSourceStream,
Stream compressedDestinationStream, bool leaveOpen = false)
{
using (
var compressionStream = new DeflateStream(compressedDestinationStream, CompressionMode.Compress,
leaveOpen))
{
await uncompressedSourceStream.CopyToAsync(compressionStream);
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Decompress a Deflate-compressed stream.
/// </summary>
/// <param name="compressedSourceStream">the compressed stream to decompress</param>
/// <param name="uncompressedDestinationStream">the stream to write the decompressed stream to</param>
/// <param name="leaveOpen">whether to leave the stream open after decompression</param>
/// <returns>an awaitable Task</returns>
public static async Task DeflateDecompress(this Stream compressedSourceStream,
Stream uncompressedDestinationStream, bool leaveOpen = false)
{
using (
var decompressionStream = new DeflateStream(compressedSourceStream, CompressionMode.Decompress,
leaveOpen))
{
await decompressionStream.CopyToAsync(uncompressedDestinationStream);
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Compress a stream using GZip compression.
/// </summary>
/// <param name="uncompressedSourceStream">the stream to compress</param>
/// <param name="compressedDestinationStream">the stream to write the compressed stream to</param>
/// <param name="leaveOpen">whether to leave the stream open after compressing</param>
/// <returns>an awaitable Task</returns>
public static async Task GZipCompress(this Stream uncompressedSourceStream, Stream compressedDestinationStream,
bool leaveOpen = false)
{
using (
var compressionStream = new GZipStream(compressedDestinationStream, CompressionMode.Compress, leaveOpen)
)
{
await uncompressedSourceStream.CopyToAsync(compressionStream);
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Decompress a GZiped stream.
/// </summary>
/// <param name="compressedSourceStream">the stream to decompress</param>
/// <param name="uncompressedDestinationStream">the stream to write the decompressed stream to</param>
/// <param name="leaveOpen">whether the decompression stream should be left open</param>
/// <returns>an awaitable Task</returns>
public static async Task GZipDecompress(this Stream compressedSourceStream, Stream uncompressedDestinationStream,
bool leaveOpen = false)
{
using (
var decompressionStream = new GZipStream(compressedSourceStream, CompressionMode.Decompress, leaveOpen))
{
await decompressionStream.CopyToAsync(uncompressedDestinationStream);
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Splits a path using a separator and an escape character.
/// </summary>
/// <param name="path">the path to split</param>
/// <param name="separator">the separator character</param>
/// <param name="escape">the escape character</param>
/// <param name="includeRootSeparator">true if the initial separator should be included</param>
/// <returns>path parts</returns>
public static IEnumerable<string> PathSplit(this string path, char separator, char? escape = null, bool includeRootSeparator = true)
{
var s = new Stack<char>();
var p = new StringBuilder();
foreach (var c in path)
{
if (c.Equals(escape))
{
s.Push(c);
continue;
}
if (c.Equals(separator))
{
if (s.Count.Equals(0) || !s.Peek().Equals(escape))
{
if (p.Length.Equals(0) && includeRootSeparator)
{
p.Append(c);
continue;
}
yield return p.ToString();
p = new StringBuilder();
continue;
}
s.Pop();
while (!s.Count.Equals(0))
{
p.Append(s.Pop());
}
p.Append(c);
continue;
}
p.Append(c);
}
while (!s.Count.Equals(0))
{
p.Append(s.Pop());
}
yield return p.ToString();
}
}
}
/Lambda/Linq.cs
@@ -0,0 +1,353 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace wasSharp.Linq
{
public static class Extensions
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// A functional implementation of a switch clause.
/// </summary>
/// <typeparam name="T">the type of items in the query</typeparam>
/// <param name="query">the selector query</param>
/// <param name="default">the function to execute when no case matches</param>
/// <param name="case">a list of predicates representing the switch cases,
/// where each predicate has to return True or False indicating whether
/// fallthrough should occur.
/// </param>
/// <remarks>when used, the default action must be explicitly specified
/// due to language restrictions
/// </remarks>
public static void Switch<T>(this IEnumerable<T> query,
// default
Action<T> @default,
// case
// case
// ...
params Predicate<T>[] @case)
{
if (@case.Length % 2 != 0)
throw new ArgumentException("Pairs of predicates expected.");
 
var enumerable = query as IList<T> ?? query.ToList();
using (var iter = enumerable.GetEnumerator())
{
while (iter.MoveNext())
{
var match = false;
for (var i = 0; i < @case.Length; i += 2)
{
if (!@case[i].Invoke(iter.Current))
continue;
 
if (@case[i + 1].Invoke(iter.Current))
return;
 
match = true;
}
 
if (!match)
@default.Invoke(iter.Current);
}
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// A functional implementation of a switch clause.
/// </summary>
/// <typeparam name="T">the type of the item to query</typeparam>
/// <param name="query">the selector query</param>
/// <param name="default">the function to execute when no case matches</param>
/// <param name="case">a list of predicates representing the switch cases,
/// where each predicate has to return True or False indicating whether
/// fallthrough should occur.
/// </param>
/// <remarks>when used, the default action must be explicitly specified
/// due to language restrictions
/// </remarks>
public static void Switch<T>(this T query,
// default
Action<T> @default,
// case
// case
// ...
params Predicate<T>[] @case)
{
if (@case.Length % 2 != 0)
throw new ArgumentException("Pairs of predicates expected.");
 
var match = false;
for (var i = 0; i < @case.Length; i += 2)
{
if (!@case[i].Invoke(query))
continue;
 
if (@case[i + 1].Invoke(query))
return;
 
match = true;
}
 
if (!match)
@default.Invoke(query);
 
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves, or ef otherwise.
/// </summary>
/// <typeparam name="T">the type of items in the query</typeparam>
/// <param name="query">the selector query</param>
/// <param name="p">the condition for invoking pf</param>
/// <param name="pf">the action to invoke in case p resolves</param>
/// <param name="q">the condition for invoking qf</param>
/// <param name="qf">the action to invoke in case q resolves</param>
/// <param name="ef">the action to invoke otherwise</param>
public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf, Action<T> ef)
{
query.ForAll(o =>
{
if (p.Invoke(o))
{
pf.Invoke(o);
}
else if (q.Invoke(o))
{
qf.Invoke(o);
}
else
{
ef.Invoke(o);
}
});
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves.
/// </summary>
/// <typeparam name="T">the type of items in the query</typeparam>
/// <param name="query">the selector query</param>
/// <param name="p">the condition for invoking pf</param>
/// <param name="pf">the action to invoke in case p resolves</param>
/// <param name="q">the condition for invoking qf</param>
/// <param name="qf">the action to invoke in case q resolves</param>
public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf)
{
query.ForAll(o =>
{
if (p.Invoke(o))
{
pf.Invoke(o);
return;
}
 
if (q.Invoke(o))
{
qf.Invoke(o);
return;
}
});
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pass if and only if predicate resovles or fail otherwise.
/// </summary>
/// <typeparam name="T">the type of items in the query</typeparam>
/// <param name="query">the selector query</param>
/// <param name="condition">the condition for invoking pf</param>
/// <param name="pass">the function to invoke in case the predicate resolves</param>
/// <param name="fail">the function to invoke otherwise</param>
public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> condition, Action<T> pass, Action<T> fail)
{
query.ForAll(o =>
{
switch (condition.Invoke(o))
{
case true:
pass.Invoke(o);
return;
 
default:
fail.Invoke(o);
return;
}
});
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pass if and only if condition holds or fail otherwise.
/// </summary>
/// <typeparam name="T">the return type of the pass and fail functions</typeparam>
/// <param name="condition">the branch condition</param>
/// <param name="pass">function with no parameters and return type T in case condition passes</param>
/// <param name="fail">function with no parameters and return type T in case condition fails</param>
/// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
public static T IfElse<T>(this bool condition, Func<T> pass, Func<T> fail)
{
return condition ? pass.Invoke() : fail.Invoke();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pass if and only if condition holds or fail otherwise.
/// </summary>
/// <typeparam name="U">the type of the argument to pass and fail</typeparam>
/// <typeparam name="V">the return type of pass and fail</typeparam>
/// <param name="condition">the branch condition</param>
/// <param name="pass">function that takes argument arg and returns type V in case condition holds</param>
/// <param name="fail">function that takes argument arg and returns type V in case condition fails</param>
/// <param name="arg">the argument passed to pass or fail functions</param>
/// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
public static V IfElse<U, V>(this bool condition, Func<U, V> pass, Func<U, V> fail, U arg = default(U))
{
return condition ? pass.Invoke(arg) : fail.Invoke(arg);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pass if and only if condition holds or fail otherwise.
/// </summary>
/// <typeparam name="T">the type of the argument to pass and fail</typeparam>
/// <param name="condition">the branch condition</param>
/// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
/// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
/// <param name="arg">the optional argument passed to pass or fail functions</param>
public static void IfElse<T>(this bool condition, Action<T> pass, Action<T> fail, T arg = default(T))
{
switch (condition)
{
case true:
pass.Invoke(arg);
return;
 
default:
fail.Invoke(arg);
return;
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Invokes pass if and only if condition holds or fail otherwise.
/// </summary>
/// <typeparam name="U">the type of the first argument to the pass or fail functions</typeparam>
/// <typeparam name="V">the type of the second argument to the pass or fail functions</typeparam>
/// <param name="condition">the branch condition</param>
/// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
/// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
/// <param name="arga">first optional argument passed to pass or fail functions</param>
/// <param name="argb">second optional argument passed to pass or fail functions</param>
public static void IfElse<U, V>(this bool condition, Action<U, V> pass, Action<U, V> fail, U arga = default(U), V argb = default(V))
{
switch (condition)
{
case true:
pass.Invoke(arga, argb);
return;
 
default:
fail.Invoke(arga, argb);
return;
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns true of an enumerable contains more than one element.
/// </summary>
/// <typeparam name="T">the type of the enumeration</typeparam>
/// <param name="e">the enumeration</param>
/// <returns>true if enumeration contains more than one element</returns>
/// <remarks>O(2) worst case</remarks>
public static bool Some<T>(this IEnumerable<T> e)
{
var i = 0;
using (var iter = e.GetEnumerator())
{
while (iter.MoveNext())
{
if (++i > 1)
return true;
}
return false;
}
}
 
/// <summary>
/// Sequentially removes all the elements from the first sequence that are in the second sequence
/// or all the elements from the second sequence that are in the first sequence.
/// </summary>
/// <typeparam name="T">the type o the collection</typeparam>
/// <param name="o">the first sequence to remove from</param>
/// <param name="p">the second sequence to remove</param>
/// <returns>the first sequence excluding the second sequence or the second sequence excluding the first sequence</returns>
public static IEnumerable<T> SequenceExceptAny<T>(this IEnumerable<T> o, IEnumerable<T> p) where T : IEquatable<T>
{
var l = new List<T>(o);
var r = new List<T>(p);
return l.Count > r.Count
? l.Zip(r, (x, y) => x.Equals(y) ? default(T) : y)
.Concat(l.Skip(r.Count))
.Where(q => q != null && !q.Equals(default(T)))
: r.Zip(l, (x, y) => x.Equals(y) ? default(T) : y)
.Concat(r.Skip(l.Count))
.Where(q => q != null && !q.Equals(default(T)));
}
 
/// <summary>
/// Sequentially removes all the elements from the first sequence that are in the second sequence.
/// </summary>
/// <typeparam name="T">the type o the collection</typeparam>
/// <param name="o">the first sequence to remove from</param>
/// <param name="p">the second sequence to remove</param>
/// <returns>the first sequence excluding the second sequence</returns>
public static IEnumerable<T> SequenceExcept<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T>
{
using (var ea = a.GetEnumerator())
{
using (var eb = b.GetEnumerator())
{
while (ea.MoveNext())
{
if (eb.MoveNext() && ea.Current.Equals(eb.Current))
continue;
yield return ea.Current;
}
}
}
}
}
}
/Languages/CSV.cs
@@ -0,0 +1,140 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace wasSharp
{
public static class CSV
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Converts a list of strings to a comma-separated values string.
/// </summary>
/// <returns>a commma-separated list of values</returns>
/// <remarks>compliant with RFC 4180</remarks>
public static string FromEnumerable(IEnumerable<string> input)
{
return string.Join(",",
input
.Select(o => o.Replace("\"", "\"\""))
.Select(o => o.IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) ? o : "\"" + o + "\""));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Converts a dictionary of strings to a comma-separated values string.
/// </summary>
/// <returns>a commma-separated list of values</returns>
/// <remarks>compliant with RFC 4180</remarks>
public static string FromDictionary<K, V>(Dictionary<K, V> input)
{
return string.Join(",", input.Keys.Select(o => o.ToString()).Zip(input.Values.Select(o => o.ToString()),
(o, p) =>
string.Join(",",
o.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1)
? o
: "\"" + o + "\"",
p.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1)
? p
: "\"" + p + "\"")));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Converts successive comma-separated values to key-value pairs.
/// </summary>
/// <returns>key-value pairs of successive comma-separate values</returns>
public static IEnumerable<KeyValuePair<string, string>> ToKeyValue(string input)
{
return ToEnumerable(input).AsParallel().Select((o, p) => new { o, p })
.GroupBy(q => q.p / 2, q => q.o)
.Select(o => o.ToArray())
.TakeWhile(o => o.Length % 2 == 0)
.Where(o => !string.IsNullOrEmpty(o[0]))
.Select(o => new KeyValuePair<string, string>(o[0], o[1]));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Converts a generic key value pair to a CSV.
/// </summary>
/// <returns>a commma-separated list of values</returns>
/// <remarks>compliant with RFC 4180</remarks>
public static string FromKeyValue<K, V>(KeyValuePair<K, V> input)
{
var key = input.Key.ToString();
var value = input.Value.ToString();
 
return string.Join(",", key
.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1)
? key
: "\"" + key + "\"", value
.Replace("\"", "\"\"")
.IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' })
.Equals(-1)
? value
: "\"" + value + "\"");
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Converts a comma-separated list of values to a list of strings.
/// </summary>
/// <param name="csv">a comma-separated list of values</param>
/// <returns>a list of strings</returns>
/// <remarks>compliant with RFC 4180</remarks>
public static IEnumerable<string> ToEnumerable(string csv)
{
var s = new Stack<char>();
var m = new StringBuilder();
for (var i = 0; i < csv.Length; ++i)
{
switch (csv[i])
{
case ',':
if (!s.Any() || !s.Peek().Equals('"'))
{
yield return m.ToString();
m = new StringBuilder();
continue;
}
m.Append(csv[i]);
continue;
case '"':
if (i + 1 < csv.Length && csv[i].Equals(csv[i + 1]))
{
m.Append(csv[i]);
++i;
continue;
}
if (!s.Any() || !s.Peek().Equals(csv[i]))
{
s.Push(csv[i]);
continue;
}
s.Pop();
continue;
}
m.Append(csv[i]);
}
 
yield return m.ToString();
}
}
}
/Languages/KeyValue.cs
@@ -0,0 +1,125 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace wasSharp
{
public static class KeyValue
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns the value of a key from a key-value data string.
/// </summary>
/// <returns>true if the key was found in data</returns>
public static string Get(string key, string data)
{
return data.Split('&')
.AsParallel()
.Select(o => o.Split('='))
.Where(o => o.Length.Equals(2) && string.Equals(o[0], key, StringComparison.Ordinal))
.Select(o => o[1])
.FirstOrDefault();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns a key-value data string with a key set to a given value.
/// </summary>
/// <returns>
/// a key-value data string or the empty string if either key or
/// value are empty
/// </returns>
public static string Set(string key, string value, string data)
{
return string.Join("&", string.Join("&", data.Split('&')
.AsParallel()
.Select(o => o.Split('='))
.Where(o => o.Length.Equals(2) && !string.Equals(o[0], key, StringComparison.Ordinal))
.Select(o => string.Join("=", o[0], o[1]))), string.Join("=", key, value));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Deletes a key-value pair from a string referenced by a key.
/// </summary>
/// <returns>a key-value pair string</returns>
public static string Delete(string key, string data)
{
return string.Join("&", data.Split('&')
.AsParallel()
.Select(o => o.Split('='))
.Where(o => o.Length.Equals(2) && !string.Equals(o[0], key, StringComparison.Ordinal))
.Select(o => string.Join("=", o[0], o[1])));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Decodes key-value pair data to a dictionary.
/// </summary>
/// <returns>a dictionary containing the keys and values</returns>
public static Dictionary<string, string> Decode(string data)
{
return data.Split('&')
.AsParallel()
.Select(o => o.Split('='))
.Where(o => o.Length.Equals(2))
.Select(o => new
{
k = o[0],
v = o[1]
})
.GroupBy(o => o.k)
.ToDictionary(o => o.Key, p => p.FirstOrDefault()?.v);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Serialises a dictionary to key-value data.
/// </summary>
/// <returns>a key-value data encoded string</returns>
public static string Encode(Dictionary<string, string> data)
{
return string.Join("&", data.AsParallel().Select(o => string.Join("=", o.Key, o.Value)));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Serialises a dictionary to key-value data.
/// </summary>
/// <returns>a key-value data encoded string</returns>
public static string Encode(IEnumerable<KeyValuePair<string, string>> data)
{
return string.Join("&", data.AsParallel().Select(o => string.Join("=", o.Key, o.Value)));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Escapes a dictionary's keys and values for sending as POST data.
/// </summary>
public static IEnumerable<KeyValuePair<string, string>> Escape(IEnumerable<KeyValuePair<string, string>> data,
Func<string, string> func)
{
return data.AsParallel().ToDictionary(o => func(o.Key), p => func(p.Value));
}
}
}
/Languages/XML.cs
@@ -0,0 +1,189 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
 
namespace wasSharp
{
public static class XML
{
private static readonly Func<string, bool> directIsSafeXML =
((Expression<Func<string, bool>>)
(data =>
Regex.Replace(data,
@"(" + string.Join(@"|", @"&amp;", @"&lt;", @"&gt;", @"&quot;", @"&apos;") + @")",
@"", RegexOptions.IgnoreCase | RegexOptions.Multiline)
.IndexOfAny(new[] { '&', '<', '>', '"', '\'' })
.Equals(-1))).Compile();
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Unescapes a string used in XML.
/// </summary>
/// <param name="s">the string to unescape</param>
/// <returns>an XML unescaped string</returns>
public static string UnescapeXML(string s)
{
var t = new Queue<char>();
var m = new StringBuilder();
foreach (var c in s)
{
switch (c)
{
case '&':
if (!t.Count.Equals(0))
{
m.Append(string.Join("", t.ToArray()));
t.Clear();
}
t.Enqueue(c);
break;
 
case ';':
if (!t.Count.Equals(0))
{
t.Enqueue(c);
var special = string.Join("", t.ToArray());
switch (special)
{
case "&apos;":
m.Append('\'');
break;
 
case "&quot;":
m.Append('"');
break;
 
case "&gt;":
m.Append('>');
break;
 
case "&lt;":
m.Append('<');
break;
 
case "&amp;":
m.Append('&');
break;
 
default: // Unrecognized escape sequence
m.Append(special);
break;
}
t.Clear();
break;
}
m.Append(c);
break;
 
default:
if (!t.Count.Equals(0))
{
t.Enqueue(c);
if (t.Count >= 6)
{
m.Append(string.Join("", t.ToArray()));
t.Clear();
}
break;
}
m.Append(c);
break;
}
}
return m.ToString();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Escapes a string to be used in XML.
/// </summary>
/// <param name="s">the string to escape</param>
/// <returns>an XML escaped string</returns>
public static string EscapeXML(string s)
{
if (string.IsNullOrEmpty(s)) return s;
 
var result = new string[s.Length];
Parallel.ForEach(Enumerable.Range(0, s.Length), o =>
{
switch (s[o])
{
case '&':
result[o] = @"&amp;";
break;
 
case '<':
result[o] = @"&lt;";
break;
 
case '>':
result[o] = @"&gt;";
break;
 
case '"':
result[o] = @"&quot;";
break;
 
case '\'':
result[o] = @"&apos;";
break;
 
default:
result[o] = s[o].ToString();
break;
}
});
return string.Join("", result);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Determines whether a string is safe to use in XML
/// </summary>
/// <param name="data">the string to check</param>
/// <returns>true in case the string is safe</returns>
public static bool IsSafeXML(string data)
{
return directIsSafeXML(data);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Recursively rename a node by name.
/// </summary>
/// <param name="root">the root from where to start</param>
/// <param name="name">the name to replace</param>
/// <param name="rename">the name to replace with</param>
public static void RenameNodes(XElement root, string name, string rename)
{
if (string.Equals(root.Name.LocalName, name, StringComparison.Ordinal))
{
root.Name = rename;
}
 
foreach (var xElement in root.Elements())
{
RenameNodes(xElement, name, rename);
}
}
}
}
/Reflection/Reflection.cs
@@ -0,0 +1,320 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
 
namespace wasSharp
{
public static class Reflection
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Retrieves an attribute of type T from an enumeration.
/// </summary>
/// <returns>an attribute of type T</returns>
public static T GetAttributeFromEnumValue<T>(Enum value) where T : Attribute
{
return (T)value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(T), false)
.SingleOrDefault();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the attributes of type T of an enumeration.
/// </summary>
/// <typeparam name="T">the attribute to retrieve</typeparam>
/// <returns>a list of attributes</returns>
public static IEnumerable<T> GetEnumAttributes<T>(Enum e) where T : Attribute
{
return e.GetType().GetRuntimeFields().ToArray()
.AsParallel()
.Select(o => GetAttributeFromEnumValue<T>((Enum)o.GetValue(Activator.CreateInstance<T>())));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the field names of an enumeration.
/// </summary>
/// <returns>the field names</returns>
public static IEnumerable<string> GetEnumNames<T>()
{
return
typeof(T).GetRuntimeFields().ToArray()
.AsParallel()
.Select(o => o.GetCustomAttribute(typeof(NameAttribute), false))
.Select(o => (o as NameAttribute)?.Name)
.Where(o => !string.IsNullOrEmpty(o))
.Select(o => o);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the values of an enumeration.
/// </summary>
/// <returns>the values of the enumeration</returns>
public static IEnumerable<T> GetEnumValues<T>()
{
return Enum.GetValues(typeof(T)).Cast<object>().Select(value => (T)value);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the name from an enumeration value.
/// </summary>
/// <param name="value">an enumeration value</param>
/// <returns>the description or the empty string</returns>
public static string GetNameFromEnumValue(Enum value)
{
var attribute = value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(NameAttribute), false)
.SingleOrDefault() as NameAttribute;
return attribute?.Name;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the description from an enumeration value.
/// </summary>
/// <param name="value">an enumeration value</param>
/// <returns>the description or the empty string</returns>
public static string GetDescriptionFromEnumValue(Enum value)
{
var attribute = value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.SingleOrDefault() as DescriptionAttribute;
return attribute?.Description;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get enumeration value from its name attribute.
/// </summary>
/// <typeparam name="T">the enumeration type</typeparam>
/// <param name="name">the description of a member</param>
/// <param name="comparison">the string comparison to use</param>
/// <returns>the value or the default of T if case no name attribute found</returns>
public static T GetEnumValueFromName<T>(string name,
StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
var field = typeof(T).GetRuntimeFields().ToArray()
.AsParallel().SelectMany(f => f.GetCustomAttributes(
typeof(NameAttribute), false), (
f, a) => new { Field = f, Att = a })
.SingleOrDefault(a => string.Equals(((NameAttribute)a.Att)
.Name, name, comparison));
return field != null ? (T)field.Field.GetValue(Activator.CreateInstance<T>()) : default(T);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the name of a structure member.
/// </summary>
/// <typeparam name="T">the type of the structure to search</typeparam>
/// <param name="structure">the structure to search</param>
/// <param name="item">the value of the item to search</param>
/// <returns>the description or the empty string</returns>
public static string GetStructureMemberName<T>(T structure, object item) where T : struct
{
var f = typeof(T).GetRuntimeFields();
var p = typeof(T).GetRuntimeProperties();
 
if (f != null)
{
var r = f.AsParallel()
.SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
(o, a) => new { Field = o, Att = a })
.SingleOrDefault(q => q.Field.GetValue(structure).Equals(item));
if (r != null)
return ((NameAttribute)r.Att).Name;
}
 
if (p != null)
{
var r = p.AsParallel()
.SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
(o, a) => new { Property = o, Att = a })
.SingleOrDefault(q => q.Property.GetValue(structure).Equals(item));
if (r != null)
return ((NameAttribute)r.Att).Name;
}
 
return string.Empty;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get field or property from a class by supplying a path.
/// </summary>
/// <typeparam name="T">the type of the object</typeparam>
/// <param name="o">the object</param>
/// <param name="path">the fully qualified path to the field of property</param>
/// <returns>
/// the last object in the fully qualified path or null in case the field or property could not be found
/// </returns>
public static object GetFP<T>(this T o, string path)
{
if (string.IsNullOrEmpty(path)) return null;
if (o == null) return null;
 
var memberType = o.GetType();
var components = path.Split('.');
 
var f = memberType.GetRuntimeField(components[0]);
var p = memberType.GetRuntimeProperty(components[0]);
 
if (f != null)
return components.Length > 1
? GetFP(f.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeField(path).GetValue(o);
 
if (p != null)
return components.Length > 1
? GetFP(p.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeProperty(path).GetValue(o);
 
return null;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get field or property info from a class by supplying a path.
/// </summary>
/// <typeparam name="T">the type of the object</typeparam>
/// <param name="o">the object</param>
/// <param name="path">the fully qualified path to the field of property</param>
/// <returns>
/// the field or property info of the last object in the path or null if the object cannot be found
/// </returns>
public static object GetFPInfo<T>(this T o, string path)
{
if (string.IsNullOrEmpty(path)) return null;
if (o == null) return null;
 
var memberType = o.GetType();
var components = path.Split('.');
 
var f = memberType.GetRuntimeField(components[0]);
var p = memberType.GetRuntimeProperty(components[0]);
 
if (f != null)
return components.Length > 1
? GetFPInfo(f.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeField(path);
 
if (p != null)
return components.Length > 1
? GetFPInfo(p.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeProperty(path);
 
return null;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>Return all the run-time properties for an object.</summary>
/// <param name="o">the object whose properties to return</param>
/// <returns>the property information for all the properties of the object</returns>
public static IEnumerable<PropertyInfo> GetPropertiesInfo<T>(this T o)
{
foreach (var p in o.GetType().GetRuntimeProperties())
yield return p;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>Return all the run-time properties for an object.</summary>
/// <param name="o">the object whose properties to return</param>
/// <returns>the property information for all the properties of the object</returns>
public static IEnumerable<FieldInfo> GetFieldsInfo<T>(this T o)
{
foreach (var p in o.GetType().GetRuntimeFields())
yield return p;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Enumerate all the base types recursively starting from a type.
/// </summary>
/// <param name="type">the type</param>
/// <returns>an enumeration of all base types</returns>
public static IEnumerable<Type> GetBaseTypes(this Type type)
{
var baseType = type.GetTypeInfo().BaseType;
if (baseType == null)
yield break;
yield return baseType;
foreach (var t in GetBaseTypes(baseType))
{
yield return t;
}
}
 
/// <summary>
/// A generic name attribute.
/// </summary>
public class NameAttribute : Attribute
{
protected readonly string name;
 
public NameAttribute(string name)
{
this.name = name;
}
 
public string Name => name;
}
 
/// <summary>
/// A generic description attribute.
/// </summary>
public class DescriptionAttribute : Attribute
{
protected readonly string description;
 
public DescriptionAttribute(string description)
{
this.description = description;
}
 
public string Description => description;
}
}
}
/Sciences/Geodesics/Constants.cs
@@ -0,0 +1,13 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
namespace wasSharp.Geo
{
public static class Constants
{
public static readonly Distance EARTH_MEAN_RADIUS = new Distance(6371000);
}
}
/Sciences/Geodesics/Distance.cs
@@ -0,0 +1,85 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
 
namespace wasSharp.Geo
{
public enum DistanceUnits
{
METERS = 1,
KILOMETERS = 2
}
 
public class Distance : IComparable<Distance>, IEquatable<Distance>
{
public Distance(double meters)
{
Meters = meters;
}
 
public double Kilometers => Meters / 1000d;
 
public double Meters { get; }
 
public int CompareTo(Distance other)
{
return Meters.CompareTo(other.Meters);
}
 
public bool Equals(Distance other)
{
return this == other;
}
 
public static bool operator >(Distance a, Distance b)
{
return a != null && b != null && a.Meters > b.Meters;
}
 
public static bool operator >=(Distance a, Distance b)
{
return (a == null && b == null) || (a != null && b != null && a.Meters >= b.Meters);
}
 
public static bool operator <(Distance a, Distance b)
{
return a != null && b != null && a.Meters < b.Meters;
}
 
public static bool operator <=(Distance a, Distance b)
{
return (a == null && b == null) || (a != null && b != null && a.Meters <= b.Meters);
}
 
public static bool operator ==(Distance a, Distance b)
{
return (ReferenceEquals(a, null) && ReferenceEquals(b, null)) ||
(!ReferenceEquals(a, null) && !ReferenceEquals(b, null) && a.Meters == b.Meters);
}
 
public static bool operator !=(Distance a, Distance b)
{
return !(a == b);
}
 
public override bool Equals(object obj)
{
if (obj == null)
return false;
 
if (obj is Distance)
return Equals(obj as Distance);
 
return ReferenceEquals(this, obj);
}
 
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
/Sciences/Geodesics/GeodesicExtensions.cs
@@ -0,0 +1,37 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
 
namespace wasSharp.Geo
{
public static class GeodesicExtensions
{
public static Distance HaversineDistanceTo(this GeographicCoordinate sourceGeographicCoordinate,
GeographicCoordinate targetGeographicCoordinate)
{
return HaversineDistanceTo(sourceGeographicCoordinate, targetGeographicCoordinate, DistanceUnits.KILOMETERS);
}
 
public static Distance HaversineDistanceTo(this GeographicCoordinate sourceGeographicCoordinate,
GeographicCoordinate targetGeographicCoordinate,
DistanceUnits distanceUnits)
{
var sourcePhi = Math.PI * sourceGeographicCoordinate.Latitude / 180;
var targetPhi = Math.PI * targetGeographicCoordinate.Latitude / 180;
var deltaPhi = Math.PI * (targetPhi - sourcePhi) / 180;
var deltaLam = Math.PI * (targetGeographicCoordinate.Longitude - sourceGeographicCoordinate.Longitude) / 180;
 
var a = Math.Sin(deltaPhi / 2) * Math.Sin(deltaPhi / 2) +
Math.Cos(sourcePhi) * Math.Cos(targetPhi) *
Math.Sin(deltaLam / 2) * Math.Sin(deltaLam / 2);
 
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
 
return new Distance(Constants.EARTH_MEAN_RADIUS.Meters * c);
}
}
}
/Sciences/Geodesics/GeographicCoordinate.cs
@@ -0,0 +1,21 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
namespace wasSharp.Geo
{
public class GeographicCoordinate
{
public GeographicCoordinate(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
 
public double Latitude { get; }
 
public double Longitude { get; }
}
}
/Sciences/Mathematics/Numerics.cs
@@ -0,0 +1,41 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
namespace wasSharp
{
public static class Numerics
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Given a value in a source value range and a target range, map
/// the value from the source range into the target range.
/// </summary>
/// <remarks>
/// value - the value to map
/// xMin - the lower bound of the source range
/// xMax - the upper bound of the source range
/// yMin - the lower bound of the target range
/// yMax - the upper bound of the target range
/// </remarks>
/// <returns>a value in x mapped in the range of y</returns>
public static double MapValueToRange(double value, double xMin, double xMax, double yMin, double yMax)
{
return yMin + (yMax - yMin) * (value - xMin) / (xMax - xMin);
}
 
public static bool IsNullOrDefault<T>(T value)
{
return Equals(value, default(T));
}
 
public static T DefaultOrValue<T>(this T initial, T value)
{
return Equals(initial, default(T)) ? value : initial;
}
}
}
/wasSharp.csproj
@@ -35,8 +35,6 @@
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="Arrays.cs" />
<Compile Include="BitTwiddling.cs" />
<Compile Include="Collections\Generic\CircularQueue.cs" />
<Compile Include="Collections\Specialized\ConcurrentHashSet.cs" />
<Compile Include="Collections\Specialized\ConcurrentList.cs" />
@@ -48,20 +46,6 @@
<Compile Include="Collections\Generic\RangeCollection.cs" />
<Compile Include="Collections\Generic\SerializableDictionary.cs" />
<Compile Include="Collections\Generic\SerializableSortedDictionary.cs" />
<Compile Include="Cryptography.cs" />
<Compile Include="CSV.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Geodesics\Constants.cs" />
<Compile Include="Geodesics\Distance.cs" />
<Compile Include="Geodesics\GeodesicExtensions.cs" />
<Compile Include="Geodesics\GeographicCoordinate.cs" />
<Compile Include="NetHash.cs" />
<Compile Include="IO.cs" />
<Compile Include="KeyValue.cs" />
<Compile Include="Linq.cs" />
<Compile Include="Numerics.cs" />
<Compile Include="Reflection.cs" />
<Compile Include="Strings.cs" />
<Compile Include="Timers\DecayingAlarm.cs" />
<Compile Include="Timers\Utilities\TimeExtensions.cs" />
<Compile Include="Timers\TimedThrottle.cs" />
@@ -71,9 +55,36 @@
<Compile Include="Web\QValueParsing.cs" />
<Compile Include="Web\Utilities\WebExtensions.cs" />
<Compile Include="Web\wasHTTPClient.cs" />
<Compile Include="XML.cs" />
<Compile Include="Sciences\Geodesics\Constants.cs" />
<Compile Include="Sciences\Geodesics\Distance.cs" />
<Compile Include="Sciences\Geodesics\GeodesicExtensions.cs" />
<Compile Include="Sciences\Geodesics\GeographicCoordinate.cs" />
<Compile Include="Sciences\Mathematics\Numerics.cs" />
<Compile Include="IO\IO.cs" />
<Compile Include="Languages\CSV.cs" />
<Compile Include="Languages\KeyValue.cs" />
<Compile Include="Languages\XML.cs" />
<Compile Include="Bit\BitTwiddling.cs" />
<Compile Include="Cryptography\Cryptography.cs" />
<Compile Include="Arrays\Arrays.cs" />
<Compile Include="Lambda\Linq.cs" />
<Compile Include="Reflection\Reflection.cs" />
<Compile Include="Cryptography\NetHash.cs" />
<Compile Include="Cryptography\Extensions.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="Sciences\" />
<Folder Include="Sciences\Geodesics\" />
<Folder Include="Sciences\Mathematics\" />
<Folder Include="IO\" />
<Folder Include="Languages\" />
<Folder Include="Bit\" />
<Folder Include="Cryptography\" />
<Folder Include="Arrays\" />
<Folder Include="Lambda\" />
<Folder Include="Reflection\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.