Some functions are implemented as part of the Wizardry and Steamworks portable library class (PCL) and the full library can be retrieved from SVN by checking out the following repository:
The PCL targets:
Use the following one-liner to display a line of dashes that goes goes from one end of the terminal to the other:
new List<int>(new int[Console.WindowWidth]).ForEach(i => Console.Write("-"));
which creates an empty list of integers of size Console.WindowWidth
and then for each element it writes a dash to the console.
Assemblies can be loaded from a different directory by creating an ASSEMBLY.EXE.conf
file, where ASSEMBLY.EXE
is the application executable with the following contents:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="lib;bin"/> </assemblyBinding> </runtime> </configuration>
This will make the application to look for the assemblies in the lib/
and bin/
paths.
freeByes
will contain the amount of memory used by the current process in bytes.
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess(); int freeBytes = proc.PrivateMemorySize64;
Given the array:
[ 0, 1, 2, 3, 4, 5, ... ]
the following LINQ expression:
var a = data.Where((value, index) => (index % 2) == 0).ToArray();
will set a to the array:
[ 0, 2, 4, ... ]
Suppose that we have a C# structure that defines a person along with multiple properties for that person and that we want to create a method that will serialize this structure to the key-value data. The ToKeyValueData
function in the example below uses reflection to loop over the properties of the Person
structure and returns a key-value data compatible string.
public struct Person { ... public Person(string name, string address, ...) { this.name = name; this.address = address; } ... /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Serializes a structure to a Wizardry and Steamworks key-value data string. /// </summary> private string ToKeyValueData() { var sb = new StringBuilder(); object p = new Person(); foreach(var k in p.GetType().GetProperties()) { var v = GetType().GetProperty(k.Name).GetValue(this, null).ToString(); if(string.IsNullOrEmpty(v)) continue; sb.Append(string.Format("{0}={2}", k.Name, v); sb.Append(delimiter); } if(sb.Length != 0) sb.Length--; return sb.ToString(); } ... public string name { get; internal set; } public string address { get; internal set; } ... }
That is done by enumerating the properties of the Person
structure using GetProperties
on the type of the structure which gives us a propertyInfo
object from which we can extract the name of that property. In order to get the value of that property, we use GetProperty
on the name of property and get the value of the instance object (this
).
There are cases where you want a wrapper that can hold objects in order to avoid declaring temporary variables (from the series, "can I partially allocate an object?"). For example, you perform a loop and store data in the upper-scope:
int time = 0; int greeting = ""; foreach(var o in ...) { switch(o) { case ...: time = 10; break; case ...: greeting = "Good Day!"; break; } }
In such cases, a generic object array is more suitable:
object[2] data = new object[2]; foreach(var o in ...) { switch(o) { case ...: data[0] = 10; break; case ...: data[1] = "Good Day!"; break; } } if(data.Any(o => o == null)) { // data contains at least one null element }
This works great as a temporary structure, in order to avoid creating a new class or struct which would live much longer than the inlined generic object.
using System.Linq.Expressions; ... string ON; ... private static string GetName<T>(Expression<Func<T>> e) { return ((MemberExpression) e.Body).Member.Name; } ... Console.WriteLine(GetName(() => ON));
When you have to monitor files for changes or access times, C#
comes equipped for that task with the FileSystemWatcher
class. On UNIX
/ mono
, FileSystemWatcher
is implemented using gamin
as well as other mechanisms to provide the same functionality.
For example, the following filesystem watcher scans the current directory for:
installs a filter for ini
files and then when any ini
file in the current directory is changed, it will raise HandleDirectoryChange
. HandleDirectoryChange
will then print out the file name (in e.Name
) to the console:
FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = Directory.GetCurrentDirectory(); watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; watcher.Filter = "*.ini"; watched.Changed += HandleDirectoryChange; ... private static void HandleDirectoryChange(object sender, FileSystemEventArgs e) { Console.WriteLine(e.Name); }
Note that FileSystemWatcher
monitors directories and if you want to monitor just a file, you can set the Filter
to the file name, as in:
watcher.Path = Directory.GetCurrentDirectory(); watcher.Filter = "Corrade.ini";
TryParse
does not function on nullable types such as int?
. The following function can act as a substitute for int.TryParse
:
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Attempts to parse a string to a structure. /// </summary> /// <param name="input">the input string</param> /// <param name="variable">the variable holding the parsed type T</param> /// <returns>true if the variable could be parsed</returns> public static bool TryParseNullable<T>(string input, out T? variable) where T:struct { if (string.IsNullOrEmpty(input)) { variable = null; return false; } T? localVariable; try { IConvertible convertibleString = input; localVariable = (T)convertibleString.ToType(typeof(T), CultureInfo.CurrentCulture); } catch (Exception) { variable = null; return false; } variable = localVariable; return true; }
Can be done by using reflection:
foreach (FieldInfo fi in typeof(Molecules).GetFields(BindingFlags.Public | BindingFlags.Static)) { Console.WriteLine(fi.Name); Console.WriteLine(fi.GetValue(null)); }
Suppose you have a set of elements:
10, 20, 30, 40, 50
and that you want to create sub-sets from successive elements as pairs. Following the example, you want to create the pairs: , , out of the initial set preferably as key-value pairs.
In that case, there are several solutions, but if you want to use only one LINQ line, then the following expression will return the desired key-value pairs:
list.Select((o, p) => new {o = o, p = p}) .GroupBy(q => q.p/2, q => q.o) .Select(o => o.ToList()) .TakeWhile(o => o.Count % 2 == 0) .ToDictionary(o => o.First(), p => p.Last())
It does that by:
Given a comma-separated string (CSV
) such as:
Color, Red, Life, Good, Day, Sunday
where the even strings (Color
, Life
, Day
) represent keys and the odd strings (Red
, Good
, Sunday
) represent values, one can use regular expressions (System.Text.RegularExpressions
) to serialise the string into a dictionary of key-value pairs:
using System.Text.RegularExpressions; //... Dictionary<string, string> pairs = Regex.Matches(command.Attachments, @"\s*(?<key>.+?)\s*,\s*(?<value>.+?)\s*(,|$)") .Cast<Match>() .ToDictionary(m => m.Groups["key"].Value, m => m.Groups["value"].Value);
Note that the regex is sufficiently resistant to abuse, for example, it will work fine if the spaces around the strings are garbled:
Color , Red, Life,Good , Day , Sunday
Another, better variant is to use a splitting regular expression and then collect the even and odd keys with a bit of LINQ:
using System.Text.RegularExpressions; //... public static Regex CSVRegEx = new Regex(@"\s*,\s*(?=(?:[^\""]*\""[^\""]*\"")*(?![^\""]*\""))", RegexOptions.Compiled); //... foreach (KeyValuePair<string, string> a in CSVRegEx.Split(input).Select((value, index) => new {value, index}) .GroupBy(x => x.index/2, x => x.value) .Select(x => x.ToList()) .TakeWhile(o => o.Count % 2 == 0) .ToDictionary(o => o.First(), p => p.Last())) { Console.WriteLine(a); }
For more details, see group a sequence by pairs.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Converts a hash table to a dictionary. /// </summary> /// <typeparam name="K">key type</typeparam> /// <typeparam name="V">value type</typeparam> /// <param name="table">a hash table</param> /// <returns>a dictionary</returns> public static Dictionary<K, V> HashtableToDictionary<K, V>(Hashtable table) { return table.Cast<DictionaryEntry>() .ToDictionary(kvp => (K)kvp.Key, kvp => (V)kvp.Value); }
/// <summary> /// Calculates the length in bytes of an object /// and returns the size /// </summary> /// <param name="TestObject"></param> /// <returns></returns> private int GetObjectSize(object TestObject) { BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); byte[] Array; bf.Serialize(ms, TestObject); Array = ms.ToArray(); return Array.Length; }
Using the wasUNIXTimeStampToDateTime
function we can convert a UNIX timestamp to a DateTime
object:
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns a DateTime object from a given UNIX timestamp. /// </summary> /// <param name="timeStamp">the UNIX time stamp to convert</param> /// <returns>the DateTime object representing the timeStamp</returns> private static DateTime wasUNIXTimeStampToDateTime(double timeStamp) { return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timeStamp); }
an example call is:
DateTime date = wasUNIXTimeStampToDateTime(1406583923);
Given a DateTime
object, the wasDateTimeToUnixTimeStamp
function returns the UNIX timestamp.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns the UNIX time from a DateTime object. /// </summary> /// <param name="date"></param> /// <returns></returns> private static double wasDateTimeToUnixTimeStamp(DateTime date) { return date.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).Duration().TotalSeconds; }
Suppose you have an enumeration, with the following structure:
[Flags] private enum Days : uint { [Description("Monday")] ONE = 1, [Description("Tuesday")] TWO = 2 }
and you want to get the value (the uint
1
) of the field that has the description Monday
.
In that case, using wasGetEnumValueFromDescription
:
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Get enumeration value from its description. /// </summary> /// <typeparam name="T">the enumeration type</typeparam> /// <param name="description">the description of a member</param> /// <returns>the value or the default of T if case no description found</returns> private static T wasGetEnumValueFromDescription<T>(string description) { var field = typeof (T).GetFields() .SelectMany(f => f.GetCustomAttributes( typeof (DescriptionAttribute), false), ( f, a) => new {Field = f, Att = a}).SingleOrDefault(a => ((DescriptionAttribute) a.Att) .Description == description); return field != null ? (T) field.Field.GetRawConstantValue() : default(T); }
you would make a call such as:
uint day = (uint) wasGetEnumValueFromDescription(new Days(), "Monday");
such that the unit
day
will hold the value 1
after the call.
Suppose you have an enumeration, with the following structure:
[Flags] private enum Days : uint { [Description("Monday")] ONE = 1, [Description("Tuesday")] TWO = 2 }
and you want to get the description (Monday
) from the value 1
.
Using wasGetDescriptionFromEnumValue
:
/////////////////////////////////////////////////////////////////////////// // 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> private static string wasGetDescriptionFromEnumValue(Enum value) { DescriptionAttribute attribute = value.GetType() .GetField(value.ToString()) .GetCustomAttributes(typeof (DescriptionAttribute), false) .SingleOrDefault() as DescriptionAttribute; return attribute != null ? attribute.Description : string.Empty; }
you would make a call such as:
string day = wasGetDescriptionFromEnumValue((Days)1);
such that the string day
will hold the value Monday
after the call.
Suppose that you have a structure:
private struct Person { [Description("the name")] public string Name; [Description("the age")] public int Age; }
and that you have instantiated the structure as:
Person person = new Person { Name = "Mr. Sparky", Age = 34 }
and you want to get the description of the Age
member of the struct Person
.
In that case, using wasGetStructureMemberDescription
:
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Get the description of 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 wasGetStructureMemberDescription<T>(T structure, object item) where T : struct { var field = typeof(T).GetFields() .SelectMany(f => f.GetCustomAttributes(typeof(DescriptionAttribute), false), (f, a) => new { Field = f, Att = a }).SingleOrDefault(f => f.Field.GetValue(structure).Equals(item)); return field != null ? ((DescriptionAttribute)field.Att).Description : string.Empty; }
you would make a call such as:
string ageDescription = wasGetStructureMemberDescription(person, person.Age);
which will leave ageDescription
containing the string the age
after the call.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns all the field descriptions of an enumeration. /// </summary> /// <param name="enumeration">the enumeration</param> /// <returns>the field descriptions</returns> private static IEnumerable<string> wasGetEnumDescriptions(this Enum enumeration) { return from fi in enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public) select ((Enum) fi.GetValue(enumeration)).GetAttribute<DescriptionAttribute>() into attribute where attribute != null && !string.IsNullOrEmpty(attribute.Description) select attribute.Description; }
The following are functions that manipulate flag-type enumerations, such as:
[Flags] private enum Days : uint { Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 }
and are useful before the .NET release 4.0 which has built-in functions that can manipulate flags.
Sets a flag (or a flag mask) in a flag enumeration.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // Original by Dan Tao. /// <summary> /// Sets flag in flags. /// </summary> /// <param name="flags">an enumeration to set flags on</param> /// <param name="flag">a flag or mask to set on flags</param> private static void SetFlags<T>(ref T flags, T flag) where T : struct { flags = (T) (object) ((uint) (object) flags | (uint) (object) flag); }
For example, using the Days
structure:
Days d = new Days(); SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday);
Unsets a flag (or flag mask) in a flag enumeration.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // Original by Dan Tao. /// <summary> /// Unsets a flag. /// </summary> /// <param name="flags">an enumeration to unset flags on</param> /// <param name="flag">a flag or mask to unset of flags</param> private static void UnsetFlags<T>(ref T flags, T flag) where T : struct { flags = (T) (object) ((uint) (object) flags & (~(uint) (object) flag)); }
For example, using the Days
structure:
Days d = new Days(); UnsetFlags(ref d, Days.Friday);
or, for multiple flags:
Days d = new Days(); UnsetFlags(ref d, Days.Friday | Days.Sunday);
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Determines if the flags in flag are set in the flags structure. /// </summary> /// <param name="flags">the structure to check against</param> /// <param name="flag">a single flag or a mask to check</param> /// <returns>true if flag is set in flags</returns> private static bool IsSetFlags<T>(T flags, T flag) where T : struct { return Enum.GetValues(typeof (T)) .Cast<uint>() .Where(f => (f & (uint) (object) flag) == f) .All(set => ((uint) (object) flags & set) != 0); }
For example, using the Days
structure:
Days d = new Days(); SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); IsSetFlags(ref d, Days.Monday | Days.Friday);
the return value of IsSetFlags
will be True
.
Gets the values of set flags in an enumeration.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the flag values in flags. /// </summary> /// <param name="flags">an enumeration with certain flags set</param> /// <returns>the values of the flags set</returns> private static IEnumerable<uint> GetSetFlagValues<T>(T flags) where T : struct { return Enum.GetValues(typeof(T)).Cast<uint>().Where(f => (f & (uint)(object)flags) == f); }
For example, using the Days
structure:
Days d = new Days(); SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); List<uint> set = GetSetFlagValues(d).ToList(); foreach (uint value in set) { Console.WriteLine(value.ToString()); }
will print out:
1 16 64
Gets the names of set flags.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the names of the flags set in flags. /// </summary> /// <param name="flags">an enumeration with certain flags set</param> /// <returns>the names of the set flags</returns> private static IEnumerable<string> GetSetFlagNames<T>(T flags) where T : struct { return Enum.GetValues(typeof (T)) .Cast<uint>() .Where(f => (f & (uint)(object)flags) == f) .Select(f => ((T) (object) f).ToString()); }
For example, using the Days
structure:
Days d = new Days(); SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); List<string> set = GetSetFlagNames(d).ToList(); foreach (string name in set) { Console.WriteLine(name); }
will print out:
Monday Friday Sunday
Capturing the closing event of a console under Windows can be done by importing the SetConsoleCtrlHandler
function from Kernel32.dll
and has been discussed in the windows section. However, kernel32.dll
is not available under mono
and will not work on Unix platforms. In order to be able to capture both the console close and sending a termination signal such as SIGTERM
under Unix, the following variation branches on the platform and uses SetConsoleCtrlHandler
under Windows and signals under Unix:
// For Unix signals. using Mono.Unix; using Mono.Unix.Native; // For Windows events. using System.Runtime.InteropServices; //... /// <summary> /// Import console handler for windows. /// </summary> [DllImport("Kernel32.dll")] private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add); // A delegate for SetConsoleCtrlHandler. private delegate bool EventHandler(CtrlType ctrlType); // Set to static in order to avoid garbage collection. private static EventHandler ConsoleEventHandler; // An enumerated type for the control messages // sent to the handler routine. private enum CtrlType { CTRL_C_EVENT = 0, CTRL_BREAK_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT = 5, CTRL_SHUTDOWN_EVENT } private static bool ConsoleCtrlCheck(CtrlType ctrlType) { KeyValuePair<char, ManualResetEvent> semaphore = ConnectionSemaphores.FirstOrDefault(s => s.Key.Equals('u')); if (semaphore.Value != null) { semaphore.Value.Set(); } // Wait for threads to finish. Thread.Sleep(60000); return true; } // Main entry point. public static void Main() { // Branch on platform and set-up termination handlers. switch (Environment.OSVersion.Platform) { // SetConsoleCtrlHandler supported on Windows 2000 or later. case PlatformID.Win32NT: // Setup console handler. ConsoleEventHandler += ConsoleCtrlCheck; SetConsoleCtrlHandler(ConsoleEventHandler, true); break; // For Unix signals, catch SIGTERM (daemon). case PlatformID.Unix: UnixSignal[] signals = { new UnixSignal(Signum.SIGTERM) }; new Thread(() => { UnixSignal.WaitAny(signals, -1); KeyValuePair<char, ManualResetEvent> semaphore = ConnectionSemaphores.FirstOrDefault(s => s.Key.Equals('u')); if (semaphore.Value != null) { semaphore.Value.Set(); } }).Start(); break; } // Rest of the program // ... }
This method will branch on Environment.OSVersion.Platform
and decide what is suitable for each platform. Note, that if the coding is done on Windows, that the Mono.Posix.dll
library has to be added to the list of references in Visual Studio. This can be accomplished by downloading mono
for Windows and the DLL
can usually be found in: C:\Program Files (x86)\Mono-3.2.3\lib\mono\2.0
.
Using LINQ, this can be done by:
int groups = 2; IEnumerable<string> strings = data.Select((c, index) => new {c, index}) .GroupBy(x => x.index/groups) .Select(xg => string.Join("", xg.Select(x => x.c.ToString(CultureInfo.InvariantCulture)).ToArray()));
where groups
represents the number of groups to split a string into.
For example, for a string such as:
good day!
and groups
set to 2
, the resulting substrings will be:
go od d ay !
The Uri.EscapeDataString
function in C# has a 32766
character limit, after which the function will throw an UriFormatException
error (as per the MSDN documentation). The following functions are replacements for both Uri.EscapeDataString
and Uri.UnescapeDataString
that will accept longer strings.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary>URI Unescapes an RFC3986 string</summary> /// <param name="data">a string to unescape</param> /// <returns>the resulting string</returns> private static string wasUriUnescapeDataString(string data) { return Regex.Matches(data, @"%([0-9A-Fa-f]+?){2}") .Cast<Match>() .Select(m => m.Value) .Distinct() .Aggregate(data, (current, match) => current.Replace(match, ((char) int.Parse(match.Substring(1), NumberStyles.AllowHexSpecifier)).ToString( CultureInfo.InvariantCulture))); }
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary>RFC3986 URI Escapes a string</summary> /// <param name="data">a string to escape</param> /// <returns>an RFC3986 escaped string</returns> private static string wasUriEscapeDataString(string data) { StringBuilder result = new StringBuilder(); foreach (char c in data.Select(o => o)) { if(char.IsLetter(c) || char.IsDigit(c)) { result.Append(c); continue; } result.AppendFormat("%{0:X2}", (int) c); } return result.ToString(); }
As a translation of the lolcode variant, this Fibonacci number generator will return count
-sequential Fibonacci numbers starting with the initialization vector first
and second
(which can be either 0
, 1
or 1
, 1
).
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns count sequential Fibonacci numbers given the initialization /// vector parameters first and second which can be either 0, 1 or 1, 1. /// </summary> /// <param name="count">the amount of Fibonacci numbers </param> /// <param name="first">the first number, either 0 or 1</param> /// <param name="second">the second number has to be 1</param> /// <returns>count sequential Fibonacci numbers</returns> private static IEnumerable<ulong> wasFibonacci(ulong count, ulong first, ulong second) { if (count <= 0) yield break; yield return first; foreach(ulong f in wasFibonacci(--count, second, first + second)) yield return f; }
The function IsPowerOfTwo
returns true if the number n
is a power of two and false otherwise.
private static bool IsPowerOfTwo(uint n) { return (n & (n - 1)) == 0 && n != 0; }
This is actually very elegant in C# using the ref
operator which allows us to create a function wasXORSwap
that will swap the two integers q
and p
using the XOR swap algorithm.
/////////////////////////////////////////////////////////////////////////// // 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> private static void wasXORSwap(ref int q, ref int p) { q ^= p; p ^= q; q ^= p; }
One interesting problem is the following: suppose that you have a certain terrain, from the bottom-left corner to the top-right corner and that the domain of values for and is discrete. You want to measure the height for each coordinate in the rectangle whose diagonal is and store it in a flat array of values.
This is perhaps visualised better as a grid (or a matrix):
x x B x x x A x x
where each element has a certain height.
It is clear that this will turn out to be an algorithm because every single coordinate will have to be measured. However, if you benefit from threads, then depending on the number of threads that can be run in parallel, the complexity can be reduced considerably. In the visualisation above, we have to visit 9 different coordinates, and, were we to have 9 CPUs, then the entire algorithm could be reduced to an algorithm.
In order to write the algorithm, we are first going to compute the index of each element on the grid, in the order that we measure it by. From the visualisation, we have the following grid:
2 5 8 1 4 7 0 3 6
from at index to at index . We express the index of the array in function of our current and coordinate:
where:
Now we can write the algorithm:
// calculate the sizes for x and y int sx = x2 - x1 + 1; int sy = y2 - y1 + 1; // create an array of the total size (sx*sy) float[] data = new float[sx*sy]; // loop over the range of x, loop over the range of y Parallel.ForEach(Enumerable.Range(x1, sx), x => Parallel.ForEach(Enumerable.Range(y1, sy), y => { // if the height can be determined at a given // x and y, then set the height at the correct // index in the flat array of values. float height; data[sx * x + y] = Client.Network.CurrentSim.TerrainHeightAtPoint(x, y, out height) ? height : -1; }));
One of the nice remarks about this algorithm is that it does not use any form of locking - every single task works on one single index such that no locking is needed for insertion. Even if we were to use locks, we would have a problem, because we could not tell in what order the elements would be inserted. Using the formula however, we can make sure that each task can run independently of other tasks.
Using gzip
compression to compress a request:
using System.IO.Compression; // ... using (Stream requestStream = request.GetRequestStream()) { using(var zipStream = new GZipStream(requestStream, CompressionMode.Compress)) { zipStream.Write(byteData, 0, byteData.Length); } }
which is different from requesting a compressed response, which is more common.
wasReversePermuteArrayElements
and wasForwardPermuteArrayElements
permute an array by shifting their elements either in reverse or forward directions.
Suppose you have an array with the elements:
a b c
then a call such as wasReversePermuteArrayElements(array, 1)
will return the elements:
b c a
/////////////////////////////////////////////////////////////////////////// // 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> private static T[] wasReversePermuteArrayElements<T>(T[] input, int times) { if (times.Equals(0)) return input; T[] slice = new T[input.Length]; Array.Copy(input, 1, slice, 0, input.Length - 1); Array.Copy(input, 0, slice, input.Length - 1, 1); return wasReversePermuteAttayElements(slice, --times); }
Suppose you have an array with the elements:
a b c
then a call such as wasForwardPermuteArrayElements(array, 1)
will return the elements:
c a b
/////////////////////////////////////////////////////////////////////////// // 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> private static T[] wasForwardPermuteArrayElements<T>(T[] input, int times) { if (times.Equals(0)) return input; T[] slice = new T[input.Length]; Array.Copy(input, input.Length - 1, slice, 0, 1); Array.Copy(input, 0, slice, 1, input.Length - 1); return wasForwardPermuteArrayElements(slice, --times); }
The wasArraySwap
swaps two elements in an array.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Swaps two elements in an array. /// </summary> /// <typeparam name="T">the array type</typeparam> /// <param name="input">the array</param> /// <param name="p">first element</param> /// <param name="q">last element</param> /// <returns>the array with the elements swapped</returns> private static T[] wasArraySwap<T>(T[] input, T p, T q) { T[] swap = input.Clone() as T[]; int i = Array.IndexOf(input, p); int j = Array.IndexOf(input, q); Array.Copy(input, i, swap, j, 1); Array.Copy(input, j, swap, i, 1); return swap; }
Given several arrays as input, the wasConcatenateArrays
function returns a flat array with all the elements from the arrays concatenated.
/////////////////////////////////////////////////////////////////////////// // 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[] wasConcatenateArrays<T>(params T[][] arrays) { int resultLength = 0; foreach (T[] o in arrays) { resultLength += o.Length; } T[] result = new T[resultLength]; int offset = 0; for (int x = 0; x < arrays.Length; x++) { arrays[x].CopyTo(result, offset); offset += arrays[x].Length; } return result; }
Given an array, the wasDeleteSubArray
function deletes returns all the elements of the array that are not between the start
and stop
indices. Additionally, the wasDeleteSubArray
function allows -1
to be specified as the stop
index meaning the end of the array.
/////////////////////////////////////////////////////////////////////////// // 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[] wasDeleteSubArray<T>(T[] data, int start, int stop) { if (stop.Equals(-1)) stop = data.Length - 1; T[] 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; }
The wasGetSubArray
function takes as input an array and returns all the elements between the start
and stop
indices (inclusive). Additionally, the function supports passing -1
to the stop
index meaning the end of the array.
/////////////////////////////////////////////////////////////////////////// // 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[] wasGetSubArray<T>(T[] data, int start, int stop) { if (stop.Equals(-1)) stop = data.Length - 1; T[] result = new T[stop - start + 1]; Array.Copy(data, start, result, 0, stop - start + 1); return result; }
A list of cryptographic functions created by Wizardry and Steamworks:
that will help you encrypt and decrypt messages.
Suppose we have two sets:
var subset = new [] { 2 3 1 }; var set = new [] { 2 3 8 4 2 };
and we want to determine if set
contains all the elements of subset
.
In that case we can do:
bool contained = !subset.Except(set).Any();
after which contained
will be true if subset
is contained in set.
The alarm
function in Unix program is usually used to raise an event after a certain time and, additionally, by calling the alarm
function again, to reschedule the delivery of that event. In C#, .NET does not have a built-in alarm
-like class so the following is a quick implementation using System.Timers.Timer
:
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary>An alarm class similar to the UNIX alarm</summary> public class wasAlarm { private Timer alarm; public wasAlarm() { Signal = new ManualResetEvent(false); } public ManualResetEvent Signal { get; set; } public void Alarm(int deadline) { if (alarm == null) { alarm = new Timer(deadline); alarm.Elapsed += (o, p) => { Signal.Set(); alarm.Dispose(); }; alarm.Start(); return; } alarm.Interval = deadline; } }
Suppose that you have an event, that you do not know how many times it will be called before not being called again, in that case you would first create the alarm:
wasAlarm trigger = new wasAlarm();
then, in the event handler, you would reschedule the alarm, with:
trigger.Alarm(1000);
Finally, you would wait on the alarm to trigger using, for example, WaitOne
:
trigger.Signal.WaitOne(timeout, false);
This class is used throughout Corrade.
alarm()
is usually used under UNIX-like systems to deliver a signal once a certain time has elapsed. It is useful for asynchronous code where some tasks can be performed before the alarm is finally triggered. Commonly, the alarm is set at some point and then updated later in order to reschedule the event at an earlier time.
One of the short-comings of the UNIX alarm is that it does not explicitly consider past elapsed times. For example, suppose that you set and reset an alarm as some events happen. You would only reschedule the alarm with a fixed time, every time, regardless whether the previous event has been delivered much earlier than your alarm schedule.
wasAdaptiveAlarm
uses Pythagorean means (although this can be extended) to consider the reschedule interval as well as all the past elapsed times. It performs the mean between the current scheduling request and all the previous recorded elapsed times.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// An alarm class similar to the UNIX alarm with the added benefit /// of a decaying timer that tracks the time between rescheduling. /// </summary> /// <remarks> /// (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 /// </remarks> public class wasAdaptiveAlarm { [Flags] public enum DECAY_TYPE { NONE = 0, ARITHMETIC = 1, GEOMETRIC = 2, HARMONIC = 4 } private readonly DECAY_TYPE decay = DECAY_TYPE.NONE; private readonly Stopwatch elapsed = new Stopwatch(); private readonly HashSet<double> times = new HashSet<double>(); private System.Timers.Timer alarm; /// <summary> /// The default constructor using no decay. /// </summary> public wasAdaptiveAlarm() { Signal = new ManualResetEvent(false); } /// <summary> /// The constructor for the wasAdaptiveAlarm class taking as parameter a decay type. /// </summary> /// <param name="decay">the type of decay: arithmetic, geometric, harmonic, heronian or quadratic</param> public wasAdaptiveAlarm(DECAY_TYPE decay) { Signal = new ManualResetEvent(false); this.decay = decay; } public ManualResetEvent Signal { get; set; } public void Alarm(double deadline) { if (alarm == null) { alarm = new System.Timers.Timer(deadline); alarm.Elapsed += (o, p) => { Signal.Set(); times.Clear(); alarm.Dispose(); }; elapsed.Start(); alarm.Start(); return; } elapsed.Stop(); times.Add(elapsed.ElapsedMilliseconds); elapsed.Reset(); elapsed.Start(); switch (decay) { case DECAY_TYPE.ARITHMETIC: alarm.Interval = (deadline + times.Aggregate((a, b) => b + a)) / (1f + times.Count); break; case DECAY_TYPE.GEOMETRIC: alarm.Interval = Math.Pow(deadline * times.Aggregate((a, b) => b * a), 1f / (1f + times.Count)); break; case DECAY_TYPE.HARMONIC: alarm.Interval = (1f + times.Count) / (1f / deadline + times.Aggregate((a, b) => 1f / b + 1f / a)); break; default: alarm.Interval = deadline; break; } } }
As a practical example, wasAdaptiveAlarm
has been incorporated and used throughout Corrade in order to receive an unknown number events as fast as possible without raising the signal too soon and thereby losing events.
In .NET, Path.Combine
takes two parameters such that you cannot provide several path elements in order to construct a path. Instead the wasPathCombine
takes a variable number of parameters and combines them as a path:
/////////////////////////////////////////////////////////////////////////// // 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> private static string wasPathCombine(params string[] paths) { if (paths.Length.Equals(0)) return string.Empty; return paths.Length < 2 ? paths[0] : Path.Combine(Path.Combine(paths[0], paths[1]), wasPathCombine(paths.Skip(2).ToArray())); }
Inspired from Pavel Vladov's converter, wasIntegerToBase
is able to convert a decimal number to any base (up to base 68) by making use of all the printable characters in the ASCII character set.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// <summary> /// Converts the given decimal value to the numeral system with the /// specified base radix in the range [2, 68]. /// </summary> /// <param name="value">The value to convert.</param> /// <param name="radix">The radix of the destination numeral system (in the range [2, 68]).</param> /// <returns>a string containing the value in base radix</returns> public static string wasIntegerToBase(long value, int radix) { const string alphabet = @ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !#$%&'()*+,-./:;<=>?@[\]^_`(|)~"; if (radix < 2 || radix > alphabet.Length) throw new ArgumentException("The radix must be >= 2 and <= " + alphabet.Length.ToString(CultureInfo.InvariantCulture) + "."); if (value == 0) return "0"; char[] final = new char[64]; long n = Math.Abs(value); int i = 64; do { int remainder = (int)(n % radix); final[--i] = alphabet[remainder]; n = n / radix; } while (n != 0); StringBuilder sb = new StringBuilder(); if (value < 0) sb.Append("-"); sb.Append(final, i, 64 - i); return sb.ToString(); }
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// using System; namespace Fibonacci { public class Fibonacci { public static void Main(string[] args) { int f0 = 0; int f1 = 1; int i = 0; while(i < 10) { int s = f0; f0 = f1; f1 = s + f1; Console.WriteLine(s); i = i + 1; } } } }
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// public static int BinarySearch(int[] a, int i, int min, int max) { if(max < min) return -1; int mid = (min+max)/2; if(a[mid] > i) return BinarySearch(a, i, min, mid - 1); if(a[mid] < i) return BinarySearch(a, i, mid + 1, max); return i; }
/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// public static List<int> Quicksort(List<int> l) { if (l.Count <= 1) { return l; } int pivot = l[l.Count / 2]; List<int> less = new List<int>(); List<int> more = new List<int>(); foreach (int i in l) { if (i < pivot) { less.Add(i); } if (i > pivot) { more.Add(i); } } List<int> result = new List<int>(); result.AddRange(Quicksort(less)); result.Add(pivot); result.AddRange(Quicksort(more)); return result; }
The GetFP
extension will return either a value of a field in a class, the value of a property or null in case no field or properties matched.
/////////////////////////////////////////////////////////////////////////// // 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> /// <param name="flags">the binding flags to use</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, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public) where T : class { if (string.IsNullOrEmpty(path)) return null; if (o == null) return null; var components = path.Split('.'); var memberTypes = o.GetType().GetMember(components[0], flags); if (memberTypes.Length != 1) return null; switch (memberTypes[0].MemberType) { case MemberTypes.Field: return components.Length > 1 ? GetFP(o.GetType().GetField(components[0]).GetValue(o), components.Skip(1).Aggregate((a, i) => a + @"." + i), flags) : o.GetType().GetField(path).GetValue(o); case MemberTypes.Property: return components.Length > 1 ? GetFP(o.GetType().GetProperty(components[0], flags).GetValue(o), components.Skip(1).Aggregate((a, i) => a + @"." + i), flags) : o.GetType().GetProperty(path).GetValue(o); } return null; }
The search is performed by fully qualified name. For instance:
var o = object.GetFP("Class.Member.Class.Field");
Recursively and using generics.
using System; namespace Sorts.MergeSort.Recursive { public class MergeSort { private static int[] List { get; set; } public MergeSort(int[] list) { List = list; } public int[] Sort() { return Partition(List); } private static T[] Partition<T>(T[] list) where T : IComparable { if (list.Length <= 1) { return list; } var pivot = list.Length / 2; T[] l = new T[pivot]; Array.Copy(list, 0, l, 0, pivot); T[] r = new T[list.Length - pivot]; Array.Copy(list, pivot, r, 0, list.Length - pivot); return Merge(Partition(l), Partition(r)); } private static T[] Concatenate<T>(T[] a, T[] b) where T : IComparable { T[] rest = new T[a.Length + b.Length]; Array.Copy(a, 0, rest, 0, a.Length); Array.Copy(b, 0, rest, a.Length, b.Length); return rest; } private static T[] Concatenate<T>(T a, T[] l) where T : IComparable { T[] result = new T[l.Length + 1]; result[0] = a; Array.Copy(l, 0, result, 1, l.Length); return result; } private static T Car<T>(T[] l) where T : IComparable { return l[0]; } private static T[] Cdr<T>(T[] l) where T : IComparable { T[] cdr = new T[l.Length - 1]; Array.Copy(l, 1, cdr, 0, l.Length - 1); return cdr; } private static T[] Merge<T>(T[] l, T[] r) where T : IComparable { if (l.Length == 0 || r.Length == 0) { return Concatenate(l, r); } if (l[0].CompareTo(r[0]) > 0) { return Concatenate(Car(r), Merge(l, Cdr(r))); } return Concatenate(Car(l), Merge(Cdr(l), r)); } } }
May have stack issues so should be called by increasing the stack size:
var t = new Thread(() => { list = new MergeSort.Recursive.MergeSort(list).Sort(); }, 1024 * 1024 * 50); t.Start();
using System; namespace Sorts.MergeSort.Iterative { public class MergeSort { private static int[] List { get; set; } public MergeSort(int[] list) { List = list; } public int[] Sort() { return Sort(List); } private static T Min<T>(T x, T y) where T : IComparable { return x.CompareTo(y) < 0 ? x : y; } private static T[] Sort<T>(T[] a) where T : IComparable { T[] b = new T[a.Length]; for (int size = 1; size < a.Length; size *= 2) { for (int left = 0; left + size < a.Length; left += size * 2) { int l = left + size; int r = Min(l + size, a.Length); var k = left; var i = left; var j = l; while (i < l && j < r) { if (a[i].CompareTo(a[j]) < 0) { b[k] = a[i]; ++i; } else { b[k] = a[j]; ++j; } ++k; } while (i < l) { b[k] = a[i]; ++i; ++k; } while (j < r) { b[k] = a[j]; ++j; ++k; } for (k = left; k < r; ++k) { a[k] = b[k]; } } } return a; } } }
Some window forms controls do not expose the double buffering property such that the following static extension method will attempt to enable double buffering and return true on success or false otherwise.
/// <summary> /// Enable double buffering for an arbitrary control. /// </summary> /// <param name="control">the control to enable double buffering for</param> /// <returns>true on success</returns> /// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks> public static bool SetDoubleBuffered(this Control control) { if (SystemInformation.TerminalServerSession) { return false; } var dgvType = control.GetType(); var pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); if (pi == null) { return false; } pi.SetValue(control, true, null); return true; }
Enabling double buffering can be particularly beneficial for DataGridView
controls that seem to speed up noticeably.