using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; namespace ScreenConnect; public static class Extensions { public struct ArrayPoolRental(ArrayPool pool, int size) : IDisposable { private ArrayPool pool = pool; private T[]? rentedArray = pool.Rent(size); public T[] RentedArray => rentedArray ?? throw new ObjectDisposedException(GetType().Name); public void Dispose() { T[] array = Interlocked.Exchange(ref rentedArray, null); if (array != null) { pool.Return(array); } } } private class WrappedCollection { protected TInnerCollection InnerCollection { get; } public bool IsReadOnly => true; public WrappedCollection(TInnerCollection innerCollection) { InnerCollection = innerCollection; } public void Add(TItem item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Remove(TItem item) { throw new NotSupportedException(); } } private class Sublist : WrappedCollection>, IList, ICollection, IEnumerable, IEnumerable { private int offset; private int count; public int Count => count; public TItem this[int index] { get { return base.InnerCollection[index + offset]; } set { throw new NotSupportedException(); } } public Sublist(IList innerCollection, int offset, int count) : base(innerCollection) { this.offset = offset; this.count = count; } public IEnumerator GetEnumerator() { return base.InnerCollection.GetRange(offset, count).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Contains(TItem item) { throw new NotImplementedException(); } public void CopyTo(TItem[] array, int arrayIndex) { for (int i = 0; i < count; i++) { array[arrayIndex + i] = base.InnerCollection[offset + i]; } } public int IndexOf(TItem item) { throw new NotImplementedException(); } public void Insert(int index, TItem item) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } } private class DeferredCollection : WrappedCollection, ICollection, IEnumerable, IEnumerable where TInnerCollection : ICollection { protected Func Selector { get; } public int Count => base.InnerCollection.Count; public DeferredCollection(TInnerCollection innerCollection, Func selector) : base(innerCollection) { Selector = selector; } public IEnumerator GetEnumerator() { return base.InnerCollection.Select(Selector).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Contains(TResult item) { return base.InnerCollection.Select(Selector).Contains(item); } public void CopyTo(TResult[] array, int arrayIndex) { using IEnumerator enumerator = GetEnumerator(); int num = 0; while (enumerator.MoveNext()) { array[arrayIndex + num] = enumerator.Current; num++; } } } private class DeferredList : DeferredCollection, IList, ICollection, IEnumerable, IEnumerable where TInnerList : IList { public TResult this[int index] { get { return base.Selector(base.InnerCollection[index]); } set { throw new NotSupportedException(); } } public DeferredList(TInnerList innerList, Func selector) : base(innerList, selector) { } public int IndexOf(TResult item) { return base.InnerCollection.Select(base.Selector).IndexOf((Predicate)((TResult it) => object.Equals(it, item)), -1); } public void Insert(int index, TResult item) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } } private class CastedCollection : WrappedCollection, ICollection, IEnumerable, IEnumerable where TInnerCollection : ICollection { public int Count => base.InnerCollection.Count; public CastedCollection(TInnerCollection innerCollection) : base(innerCollection) { } public bool Contains(TItem item) { return base.InnerCollection.To().Cast().Contains(item); } public void CopyTo(TItem[] array, int arrayIndex) { base.InnerCollection.CopyTo(array, arrayIndex); } public IEnumerator GetEnumerator() { return base.InnerCollection.To().Cast().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return base.InnerCollection.GetEnumerator(); } } private class CastedList : CastedCollection, IList, ICollection, IEnumerable, IEnumerable where TInnerList : IList { public TItem this[int index] { get { return (TItem)base.InnerCollection[index]; } set { throw new NotSupportedException(); } } public CastedList(TInnerList innerList) : base(innerList) { } public int IndexOf(TItem item) { return base.InnerCollection.IndexOf(item); } public void Insert(int index, TItem item) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } } public static T AssertArgumentNonNull([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, [CallerArgumentExpression("this")] string? argumentName = null) { if (@this == null) { throw new InvalidOperationException("Argument " + argumentName + " cannot be null"); } return @this; } public static T AssertStateNonNull([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, [CallerArgumentExpression("this")] string? stateName = null) where T : class { return @this ?? throw new InvalidOperationException(stateName + " cannot be null"); } public static T AssertStateNonNull([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, [CallerArgumentExpression("this")] string? stateName = null) where T : struct { return @this ?? throw new InvalidOperationException(stateName + " cannot be null"); } public static void AssertStateTrue([DoesNotReturnIf(false)] this bool @this, [CallerArgumentExpression("this")] string? stateName = null) { if (!@this) { throw new InvalidOperationException(stateName + " expected to be true"); } } public static void AssertStateFalse([DoesNotReturnIf(true)] this bool @this, [CallerArgumentExpression("this")] string? stateName = null) { if (@this) { throw new InvalidOperationException(stateName + " expected to be false"); } } public static string AssertStateNonNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNull] this string? @this, [CallerArgumentExpression("this")] string? stateName = null) { if (!@this.IsNotNullOrEmpty()) { throw new InvalidOperationException(stateName + " cannot be null or empty"); } return @this; } public static T AssertStateNonNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, [CallerArgumentExpression("this")] string? stateName = null) where T : ICollection { if (@this == null || @this.Count == 0) { throw new InvalidOperationException(stateName + " cannot be null or empty"); } return @this; } public static void FixupAppDomain() { } public static void RunWithCrashOnException(Proc proc) { RunWithCrashOnException(proc.ProcToDefaultFunc()); } public static T RunWithCrashOnException(Func func) { try { return func(); } catch (Exception ex) { ScheduleCrashOnThreadPoolThread(ex); while (true) { Thread.Sleep(-1); } } } public static void ScheduleCrashOnThreadPoolThread(Exception ex) { TypeTrace.TraceException(ex); TryWriteExceptionToEventLog(ex, 1); Singleton.Instance.TryFreezeStackForRethrow(ex); ThreadPool.UnsafeQueueUserWorkItem(delegate { throw ex; }, null); } public static string AssertArgumentNonNullOrEmpty(this string? @this, string? argumentName = null) { if (string.IsNullOrEmpty(@this)) { throw (argumentName == null) ? new ArgumentException() : new ArgumentException("Argument " + argumentName + " cannot be null or empty."); } return @this; } public static string AssertNonNullOrEmpty(this string? @this, string fullErrorMessage, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (string.IsNullOrEmpty(@this)) { throw CreateException(exceptionType, fullErrorMessage); } return @this; } public static T AssertNonNullOrEmpty(this T? @this, string? fullErrorMessage = null, ExceptionType exceptionType = ExceptionType.InvalidOperationException) where T : ICollection { return @this.PassIf(delegate { throw CreateException(exceptionType, fullErrorMessage ?? "Cannot be null or empty"); }, (T it) => it.IsNullOrEmpty()); } public unsafe static void AssertArgumentNonNull(void* @this) { if (@this == null) { throw new ArgumentException(); } } public static T? AssertNull(this T? @this, string? fullErrorMessage = null, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (@this != null) { throw CreateException(exceptionType, fullErrorMessage ?? "Cannot be set"); } return @this; } public static T Assert(this T obj, Func tester, Func? errorMessageSelector = null, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (!tester(obj)) { throw CreateException(exceptionType, errorMessageSelector?.Invoke(obj) ?? "Assertion failed"); } return obj; } public static T? AssertNonNullIf(this T? obj, bool shouldAssert) { if (!shouldAssert) { return obj; } return obj.AssertNonNull(); } public static T AssertNonNull([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, string? fullErrorMessage = null, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (@this == null) { throw CreateException(exceptionType, fullErrorMessage ?? "Cannot be null"); } return @this; } public static T AssertValueNonNull([System.Diagnostics.CodeAnalysis.NotNull] this T? @this, string valueName, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (@this == null) { throw CreateException(exceptionType, valueName + " cannot be null"); } return @this; } public static string AssertValueNonNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNull] this string? @this, string valueName, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (!@this.IsNotNullOrEmpty()) { throw CreateException(exceptionType, valueName + " cannot be null or empty"); } return @this; } public unsafe static void AssertNonNull(void* ptr, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (ptr == null) { throw CreateException(exceptionType, "Cannot be null"); } } public unsafe static void AssertNonNull(void* ptr, string message, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (ptr == null) { throw CreateException(exceptionType, message); } } public static T AssertEquals(this T x, object y, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (!object.Equals(x, y)) { throw CreateException(exceptionType, $"Invalid value: {x} does not equal {y}"); } return x; } public static T AssertNotEquals(this T x, object y, ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (object.Equals(x, y)) { throw CreateException(exceptionType, $"Invalid value: {x} equals {y}"); } return x; } public static T AssertInRange(this T value, T minInclusive, T maxInclusive, ExceptionType exceptionType = ExceptionType.InvalidOperationException) where T : IComparable { if (value == null || value.CompareTo(minInclusive) < 0 || value.CompareTo(maxInclusive) > 0) { throw CreateException(exceptionType, $"Invalid value: {value} falls outside of range {minInclusive}-{maxInclusive}"); } return value; } public static T AssertTrue(this T obj, Predicate predicate) { predicate(obj).AssertTrue(); return obj; } public static bool AssertTrue([DoesNotReturnIf(false)] this bool b, string errorMessage = "Not true", ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (!b) { throw CreateException(exceptionType, errorMessage); } return b; } public static bool AssertFalse([DoesNotReturnIf(true)] this bool b, string errorMessage = "Not false", ExceptionType exceptionType = ExceptionType.InvalidOperationException) { if (b) { throw CreateException(exceptionType, errorMessage); } return b; } public static void AssertNativeResult(int result, params int[] allowedResults) { if (Array.IndexOf(allowedResults, result) == -1) { throw CreateException(ExceptionType.InvalidOperationException, "Error from native call: " + result); } } public static void AssertNativeResultZero(int result) { if (result != 0) { throw CreateException(ExceptionType.InvalidOperationException, "Error from native call: " + result); } } public static void AssertNativeResultZero(uint result) { AssertNativeResultZero((int)result); } public static TReturn Using(Func creator, Func func) where TDisposable : IDisposable { using TDisposable arg = creator(); return func(arg); } public static void Using(Func creator, Proc proc) where TDisposable : IDisposable { Using(creator, proc.ProcToDefaultFunc()); } public static Exception CreateException(ExceptionType type, string? message = null, Exception? innerException = null) { return type switch { ExceptionType.ArgumentOutOfRangeException => new ArgumentOutOfRangeException(message, innerException), ExceptionType.ArgumentNullException => new ArgumentNullException(message, innerException), ExceptionType.InvalidDataException => new InvalidDataException(message, innerException), ExceptionType.InvalidOperationException => new InvalidOperationException(message, innerException), _ => throw new ArgumentOutOfRangeException("type", type, null), }; } public static T CreateInstance(params object[] args) { return (T)Activator.CreateInstance(typeof(T), args); } public static string CombinePaths(string path1, params string[] otherPaths) { return otherPaths.Aggregate(path1, (string current, string next) => Path.Combine(current, next)); } public static T? WithTryLock(this object @this, Func func) { if (!Monitor.TryEnter(@this)) { return default(T); } try { return func(); } finally { Monitor.Exit(@this); } } public static void WithTryLock(this object @this, Proc proc) { @this.WithTryLock(proc.ProcToDefaultFunc()); } public static T WithLock(this object @this, Func func) { lock (@this) { return func(); } } public static void WithLock(this object @this, Proc proc) { @this.WithLock(proc.ProcToDefaultFunc()); } public static bool Exchange(ref bool location, bool value) { bool result = location; location = value; return result; } public static int PostIncrementBy(ref int value, int incrementBy) { int result = value; value += incrementBy; return result; } public static IDisposable Fixed(this T[] @this, out IntPtr address) { GCHandle gcHandle = GCHandle.Alloc(@this, GCHandleType.Pinned); address = Marshal.UnsafeAddrOfPinnedArrayElement((Array)@this, 0); return new ProcDisposable(delegate { gcHandle.Free(); }); } public static string GetHashCodeString(this object @this) { return @this?.GetHashCode().ToString("X8"); } public static long WriteTo(this Stream from, Stream to, long bufferSize = 1048576L, long maxCount = long.MaxValue) { return from.WriteTo(delegate(ArraySegment it) { Write(to, it); }, bufferSize, maxCount); } public static long WriteTo(this Stream from, Func, int> writeFunc, long bufferSize = 1048576L, long maxCount = long.MaxValue) { return from.WriteTo(delegate(ArraySegment writeArraySegment) { int num = writeArraySegment.Offset; int num2 = writeArraySegment.Count; while (num2 > 0) { int num3 = writeFunc(new ArraySegment(writeArraySegment.Array, num, num2)); num += num3; num2 -= num3; } }, bufferSize, maxCount); } public static long WriteTo(this Stream from, Proc> writeProc, long bufferSize = 1048576L, long maxCount = long.MaxValue) { byte[] array = new byte[Math.Min(from.CanSeek ? (from.Length - from.Position) : long.MaxValue, Math.Min(bufferSize, maxCount))]; long num = maxCount; long num2 = 0L; int num3; while (num > 0 && (num3 = from.Read(array, 0, (int)Math.Min(num, array.Length))) > 0) { writeProc(new ArraySegment(array, 0, num3)); num2 += num3; num -= num3; } return num2; } public static void ReadFully(this BinaryReader reader, byte[] buffer, int offset, int count) { while (count > 0) { int num = reader.Read(buffer, offset, count); if (num <= 0) { throw new EndOfStreamException(); } offset += num; count -= num; } } public static void ReadFully(this Stream stream, byte[] buffer, int offset, int count) { while (count > 0) { int num = stream.Read(buffer, offset, count); if (num <= 0) { throw new EndOfStreamException(); } offset += num; count -= num; } } public static void DisposeQuietly(ref T disposable) where T : class, IDisposable { disposable.DisposeQuietly(); disposable = null; } public static void DisposeQuietly(this IDisposable disposable) { Try(delegate { disposable?.Dispose(); }); } public static void DisposeQuietly(object disposable) { (disposable as IDisposable).DisposeQuietly(); } public static string SafeToString(this object obj) { return obj?.ToString() ?? string.Empty; } public static int DivUp(int numerator, int denominator) { int num = numerator / denominator; if (numerator % denominator != 0) { num++; } return num; } public static long DivUp(long numerator, long denominator) { long num = numerator / denominator; if (numerator % denominator != 0L) { num++; } return num; } public static IEnumerable Interleave(this IEnumerable @this, T interleaveWith) { bool flag = true; foreach (T item in @this) { if (!flag) { yield return interleaveWith; } yield return item; flag = false; } } public static T[] ToSingleElementArray(this T? obj) { if (obj != null) { return new T[1] { obj }; } return EmptyArray(); } public static T GetElementOrDefault(this T[] array, int index) { if (array.Length <= index) { return default(T); } return array[index]; } public static bool ShouldEscapeUrlCharacter(char c) { if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) { return false; } switch (c) { case '!': case '\'': case '(': case ')': case '*': case '-': case '.': case '_': return false; default: return true; } } public static char IntNibbleToHex(int n) { if (n <= 9) { return (char)(n + 48); } return (char)(n - 10 + 97); } public static int HexToIntNibble(char h) { if (h >= '0' && h <= '9') { return h - 48; } if (h >= 'a' && h <= 'f') { return h - 97 + 10; } if (h >= 'A' && h <= 'F') { return h - 65 + 10; } return -1; } public static string EncodeUrl(string baseUrl, NameValueCollection parameters) { if (parameters != null) { return baseUrl + "?" + parameters.EncodeQueryString(); } return baseUrl; } public static string EncodeUrl(string baseUrl, string param1Name, object param1Value) { return baseUrl + "?" + UrlEncode(param1Name) + "=" + param1Value.SafeNav((object p) => UrlEncode(p.ToString())); } public static string EncodeUrl(string baseUrl, string param1Name, object param1Value, string param2Name, object param2Value) { return baseUrl + "?" + UrlEncode(param1Name) + "=" + param1Value.SafeNav((object p) => UrlEncode(p.ToString())) + "&" + UrlEncode(param2Name) + "=" + param2Value.SafeNav((object p) => UrlEncode(p.ToString())); } public static string UrlEncode(string s, Func shouldEscapeCharacterFunc = null) { if (s.IsNullOrEmpty()) { return string.Empty; } if (shouldEscapeCharacterFunc == null) { shouldEscapeCharacterFunc = ShouldEscapeUrlCharacter; } StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { if (shouldEscapeCharacterFunc(c)) { byte[] bytes = Encoding.UTF8.GetBytes(new char[1] { c }); foreach (byte b in bytes) { stringBuilder.Append('%').Append(IntNibbleToHex((b >> 4) & 0xF)).Append(IntNibbleToHex(b & 0xF)); } } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } public static string UrlDecode(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length); List list = null; using (IEnumerator enumerator = s.ToCharArray().To>().GetEnumerator()) { while (enumerator.MoveNext()) { if (enumerator.Current == '%') { if (!enumerator.MoveNext()) { break; } int num = HexToIntNibble(enumerator.Current); if (!enumerator.MoveNext()) { break; } int num2 = HexToIntNibble(enumerator.Current); if (list == null) { list = new List(); } list.Add((byte)((num << 4) | num2)); } else { FlushUtf8ByteList(list, stringBuilder); stringBuilder.Append((enumerator.Current == '+') ? ' ' : enumerator.Current); } } } FlushUtf8ByteList(list, stringBuilder); return stringBuilder.ToString(); } public static string HtmlEncode(string s) { throw new NotImplementedException(); } public static void FlushUtf8ByteList(List bytes, StringBuilder builder) { if (bytes != null && bytes.Count != 0) { try { char[] chars = Encoding.UTF8.GetChars(bytes.ToArray()); builder.Append(chars); } catch { } bytes.Clear(); } } public static IEnumerable> GetEntries(this NameValueCollection nvc) { return from key in nvc.OfType() from value in nvc.GetValues(key).SafeEnumerate() select CreateKeyValuePair(key, value); } public static string EncodeQueryString(this NameValueCollection parameters, Func shouldEscapeCharacterFunc = null) { return parameters.GetEntries().EncodeQueryString(shouldEscapeCharacterFunc); } public static string EncodeQueryString(this KeyValuePair @this) { return @this.ToSingleElementArray().EncodeQueryString(null); } public static string EncodeQueryString(this IEnumerable> parameters) { return parameters.EncodeQueryString(null); } public static string EncodeQueryString(this IEnumerable> parameters, Func shouldEscapeCharacterFunc = null) { return (from it in parameters from value in it.Value select CreateKeyValuePair(it.Key, value)).EncodeQueryString(shouldEscapeCharacterFunc); } public static string EncodeQueryString(this IEnumerable> parameters, Func shouldEscapeCharacterFunc) { StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (KeyValuePair parameter in parameters) { if (flag) { flag = false; } else { stringBuilder.Append("&"); } string value = UrlEncode(parameter.Key, shouldEscapeCharacterFunc); stringBuilder.Append(value); if (parameter.Value != null) { stringBuilder.Append("="); string value2 = UrlEncode(parameter.Value, shouldEscapeCharacterFunc); stringBuilder.Append(value2); } } return stringBuilder.ToString(); } public static NameValueCollection DecodeQueryString(string queryString) { NameValueCollection nameValueCollection = new NameValueCollection(); if (string.IsNullOrEmpty(queryString)) { return nameValueCollection; } queryString = queryString.Trim(); if (queryString.StartsWith("?")) { queryString = queryString.Substring(1); } string[] array = queryString.Split(new char[1] { '&' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }); string name = UrlDecode(array2[0]); string value = ((array2.Length < 2) ? null : UrlDecode(array2[1])); nameValueCollection.Add(name, value); } return nameValueCollection; } public static UriBuilder WithAdditionalQueryParameters(this UriBuilder @this, params KeyValuePair[] additionalParameters) { NameValueCollection nameValueCollection = DecodeQueryString(@this.Query); for (int i = 0; i < additionalParameters.Length; i++) { KeyValuePair keyValuePair = additionalParameters[i]; nameValueCollection.Add(keyValuePair.Key, keyValuePair.Value); } @this.Query = nameValueCollection.EncodeQueryString(); return @this; } public static string DecodeDataUrlString(string dataUrl) { Match match = Regex.Match(dataUrl, "data:.*?,(.+)"); if (!match.Success) { return null; } string text = match.Groups[1].Value; if (text.Contains("%")) { text = UrlDecode(text); } return text.Pipe(ConvertFromBase64StringFlexible).Pipe(Encoding.UTF8.GetString); } public static T SafeNav(this T? obj) where T : class, new() { return obj ?? new T(); } public static TValue? SafeNav(this IDictionary? dictionary, TKey key) where TKey : notnull { return dictionary.SafeNav(key, (TValue it) => it); } public static TSelect? SafeNav(this IDictionary? dictionary, TKey key, Func selector) where TKey : notnull { if (dictionary == null || !dictionary.TryGetValue(key, out TValue value)) { return default(TSelect); } return selector(value); } public static void Invoke(Proc proc) { proc(); } public static T Invoke(Func func) { return func(); } public static bool Try(Proc proc, Func? shouldTraceExceptionFunc = null) { return TryWithException(proc, shouldTraceExceptionFunc) == null; } public static Exception? TryWithException(Proc proc, Func? shouldTraceExceptionFunc = null) { try { proc(); return null; } catch (Exception ex) { if (shouldTraceExceptionFunc == null || shouldTraceExceptionFunc(ex)) { TypeTrace.TraceException(ex); } return ex; } } public static DateTime ToUniversalTimeTreatingUnspecifiedAsUtc(this DateTime @this) { if (@this.Kind == DateTimeKind.Unspecified) { return DateTime.SpecifyKind(@this, DateTimeKind.Utc); } return @this.ToUniversalTime(); } public static DateTime SubtractDaysFromUtcNow(long days) { if (days <= new TimeSpan(DateTime.UtcNow.Ticks).Days) { return DateTime.UtcNow - TimeSpan.FromDays(Math.Max(0L, days)); } return DateTime.MinValue; } public static int CompareToConsideringKind(this DateTime @this, DateTime other) { if (@this.Kind == other.Kind || @this == DateTime.MinValue || @this == DateTime.MaxValue || other == DateTime.MinValue || other == DateTime.MaxValue) { return @this.CompareTo(other); } return @this.ToUniversalTime().CompareTo(other.ToUniversalTime()); } public static bool IsAfter(this DateTime @this, DateTime other) { return @this.CompareToConsideringKind(other) > 0; } public static bool IsBefore(this DateTime @this, DateTime other) { return @this.CompareToConsideringKind(other) < 0; } public static bool TryGet(Func func, [MaybeNullWhen(false)] out T value, bool shouldTraceException = true) { Exception exception; return Extensions.TryGet(func, out value, out exception, shouldTraceException); } public static bool TryGet(Func func, [MaybeNullWhen(false)] out T value, bool shouldTraceException = true) where TCatchException : Exception { TCatchException exception; return TryGet(func, out value, out exception, shouldTraceException); } public static bool TryGet(Func func, [MaybeNullWhen(false)] out T value, [MaybeNullWhen(true)] out Exception exception, bool shouldTraceException = true) { return Extensions.TryGet(func, out value, out exception, shouldTraceException); } public static bool TryGet(Func func, [MaybeNullWhen(false)] out T value, [MaybeNullWhen(true)] out TCatchException exception, bool shouldTraceException = true) where TCatchException : Exception { try { value = func(); exception = null; return true; } catch (TCatchException ex) { if (shouldTraceException) { TypeTrace.TraceException(ex); } value = default(T); exception = ex; return false; } } public static T? TryGet(Func func, bool shouldTraceException = true) { if (!Extensions.TryGet(func, out T value, out Exception _, shouldTraceException)) { return default(T); } return value; } public static T? TryGet(Func func, bool shouldTraceException = true) where TCatchException : Exception { if (!TryGet(func, out T value, out TCatchException _, shouldTraceException)) { return default(T); } return value; } public static T? TryGetNullable(Func func, bool shouldTraceException = true) where T : struct { if (!Extensions.TryGet(func, out T value, out Exception _, shouldTraceException)) { return null; } return value; } public static T? TryGetNullable(Func func, bool shouldTraceException = true) where T : struct where TCatchException : Exception { if (!TryGet(func, out T value, out TCatchException _, shouldTraceException)) { return null; } return value; } public static T TryGet(Func func, T defaultValue, bool shouldTraceException = true) { if (!Extensions.TryGet(func, out T value, out Exception _, shouldTraceException)) { return defaultValue; } return value; } public static T TryGet(Func func, T defaultValue, bool shouldTraceException = true) where TCatchException : Exception { if (!TryGet(func, out T value, out TCatchException _, shouldTraceException)) { return defaultValue; } return value; } public static T1 Demand(this Union @this) where T2 : Exception { return @this.Match((T1 t1Value) => t1Value, delegate(T2 t2Value) { throw t2Value; }); } public static T1? Try(this Union @this) where T2 : Exception { return @this.Match((T1 t1Value) => t1Value, (T2 _) => default(T1)); } public static bool ListEquals(this IList? x, IList? y, IEqualityComparer? equalityComparer = null) { if (x == null && y == null) { return true; } if (x?.Count != y?.Count) { return false; } for (int i = 0; i < x.Count; i++) { if (!(equalityComparer ?? EqualityComparer.Default).Equals(x[i], y[i])) { return false; } } return true; } [MethodImpl(MethodImplOptions.NoOptimization)] public static bool EqualsConstantTime(this byte[]? x, byte[]? y) { if (x == null && y == null) { return true; } if (x?.Length != y?.Length) { return false; } int num = 0; for (int i = 0; i < x.Length; i++) { num |= x[i] ^ y[i]; } return num == 0; } public static void RemoveAll(this IDictionary dictionary, Func predicate) { (from key in dictionary.Keys.ToList() where predicate(key, dictionary[key]) select key).ForEach2(delegate(TKey key) { dictionary.Remove(key); }); } public static void RaiseEvent(this object sender, EventHandler? eventHandler, T eventArgs) where T : EventArgs { eventHandler?.Invoke(sender, eventArgs); } public static bool RaiseEventShouldCancel(this object sender, EventHandler? cancelEventHandler, bool defaultCancel = false) { CancelEventArgs e = new CancelEventArgs(defaultCancel); cancelEventHandler?.Invoke(sender, e); return e.Cancel; } public static void SetTempPath(string path) { Environment.SetEnvironmentVariable("TMP", path); Environment.SetEnvironmentVariable("TEMP", path); } public static string GetClientServiceName(string instanceFingerprint) { return GetServiceName("ScreenConnect Client", instanceFingerprint); } public static string GetClientServiceName(ClientLaunchParameters supportSessionClientLaunchParameters) { if (supportSessionClientLaunchParameters.SessionType != SessionType.Access && !(supportSessionClientLaunchParameters.SessionID == Guid.Empty)) { return GetServiceName("ScreenConnect Client", supportSessionClientLaunchParameters.SessionID); } throw new ArgumentOutOfRangeException(); } public static string GetServiceName(string serviceName, object instance) { if (instance != null) { return $"{serviceName} ({instance})"; } return serviceName; } public static Guid GetCredentialProviderClassID(string serviceName) { byte[] bytes = Encoding.UTF8.GetBytes(serviceName); Guid credentialProviderBaseClassID = Constants.CredentialProviderBaseClassID; return DeriveGuid(bytes, credentialProviderBaseClassID.ToByteArray().ToArray(8)); } public static Guid DeriveGuid(byte[] keyToHash) { return DeriveGuid(keyToHash, null); } public static Guid DeriveGuid(byte[] keyToHash, byte[]? baseBytes) { int num = ((baseBytes != null) ? baseBytes.Length : 0); if (num >= 16) { throw new ArgumentOutOfRangeException("Base must be smaller than GUID size"); } byte[] array = new byte[16]; if (baseBytes != null) { Buffer.BlockCopy(baseBytes, 0, array, 0, num); } Buffer.BlockCopy(Singleton.Instance.ComputeMD5Hash(keyToHash), 0, array, num, 16 - num); return new Guid(array); } public static string GetUtf8String(this ArraySegment @this) { return Encoding.UTF8.GetString(@this.Array, @this.Offset, @this.Count); } public static bool IsNullOrEmpty([NotNullWhen(false)] this string? @this) { return string.IsNullOrEmpty(@this); } public static bool IsNullOrWhitespace([NotNullWhen(false)] this string? @this) { if (@this.IsNullOrEmpty()) { return true; } for (int i = 0; i < @this.Length; i++) { if (!char.IsWhiteSpace(@this[i])) { return false; } } return true; } public static bool IsNotNullOrEmpty([NotNullWhen(true)] this string? @this) { return !@this.IsNullOrEmpty(); } public static bool IsNotNullOrWhitespace([NotNullWhen(true)] this string? @this) { return !@this.IsNullOrWhitespace(); } public static string? IfNotWhitespace(this string? @this) { return @this?.If((string it) => it.IsNotNullOrWhitespace()); } public static bool IsNullOrNone([NotNullWhen(false)] this CoreVersion? @this) { if (!(@this == null)) { return @this == CoreVersion.None; } return true; } public static bool IsNotNullOrNone([NotNullWhen(true)] this CoreVersion? @this) { return !@this.IsNullOrNone(); } public static double GetTotalSeconds(this DateTime dateTime) { return new TimeSpan(dateTime.ToUniversalTime().Ticks).TotalSeconds; } public static DateTime FromTotalSeconds(double totalSeconds) { return new DateTime(TimeSpan.FromSeconds(totalSeconds).Ticks, DateTimeKind.Utc).ToUniversalTime(); } public static IList GetEnumValues() { return Enum.GetValues(typeof(T)).Cast(); } public static IList<(string Name, T Value)> GetEnumNamesAndValues() { return Enum.GetNames(typeof(T)).Zip(GetEnumValues()).ToArray(); } public static IList<(string Name, Enum Value)> GetEnumNamesAndValues(Type type) { return Enum.GetNames(type).Zip(Enum.GetValues(type).Cast()).ToArray(); } public static string? GetEnumName(this T @this) where T : Enum { return Enum.GetName(typeof(T), @this); } public static string? GetEnumName(object value) where T : Enum { return Enum.GetName(typeof(T), value); } public static bool AddSafe(ref IList? items, T item) { bool result = false; if (items == null) { items = new List(); result = true; } items.Add(item); return result; } public static bool ContainsSafe(ref IList items, T item) { return items?.Contains(item) ?? false; } public static bool AddUnique(this IList items, T item) { return items.AddUnique(item, (T x, T y) => EqualityComparer.Default.Equals(x, y)); } public static bool AddUnique(this IList items, T item, Func equalityComparer) { if (items.Any((T existingItem) => equalityComparer(item, existingItem))) { return false; } items.Add(item); return true; } public static bool AddUniqueSafe(ref IList items, T item) { if (items == null) { items = new List(); } else if (items.Contains(item)) { return false; } items.Add(item); return true; } [Obsolete("Use Distinct in LINQ")] public static List DistinctFor(this IEnumerable items, Func equalityComparer) { List list = new List(); foreach (T item in items) { list.AddUnique(item, equalityComparer); } return list; } public static T? CastOrDefault(this object? @this) { if (@this is T) { return (T)@this; } return default(T); } public static bool TryFirstOrDefault(this IEnumerable items, out T item) { using (IEnumerator enumerator = items.GetEnumerator()) { if (enumerator.MoveNext()) { item = enumerator.Current; return true; } } item = default(T); return false; } public static IEnumerable WhereNotNull(this IEnumerable items) where T : class { return items.Where((T it) => it != null); } public static IEnumerable WhereNotNull(this IEnumerable items) where T : struct { return from it in items where it.HasValue select it.Value; } public static IEnumerable WhereHasValue(this IEnumerable items) where T : struct { return from it in items where it.HasValue select it.Value; } public static IEnumerable WhereNotNullOrEmpty(this IEnumerable items) { return items.Where((string it) => !string.IsNullOrEmpty(it)); } public static IEnumerable WhereNotNullOrWhitespace(this IEnumerable items) { return items.Where((string it) => it.IsNotNullOrWhitespace()); } public static IEnumerable WhereNotDefault(this IEnumerable items) { return items.Where((T it) => !it.EqualsDefault()); } public static bool EqualsDefault(this T value) { return EqualityComparer.Default.Equals(value, default(T)); } public static IEnumerable Except(this IEnumerable items, T item) { return items.Where((T it) => !EqualityComparer.Default.Equals(it, item)); } public static IEnumerable SelectToString(this IEnumerable items) { return items.Select((T it) => it?.ToString()); } public static (TSource Item, int Index) Find(this IEnumerable @this, Predicate predicate) { int num = 0; foreach (TSource item in @this) { if (predicate(item)) { return (Item: item, Index: num); } num++; } return (Item: default(TSource), Index: -1); } public static (TType Item, int Index) FindOfType(this IEnumerable @this) { int num = 0; foreach (object item2 in @this) { if (!(item2 is TType item)) { num++; continue; } return (Item: item, Index: num); } return (Item: default(TType), Index: -1); } public static int IndexOf(this IEnumerable @this, Predicate predicate, int notFoundResult = -1) { int item = @this.Find(predicate).Index; if (item < 0) { return notFoundResult; } return item; } public static int LastIndexOf(this IEnumerable @this, Predicate predicate, int notFoundResult = -1) { List list = @this.ToList(); for (int num = list.Count - 1; num >= 0; num--) { if (predicate(list[num])) { return num; } } return notFoundResult; } public static int IndexOf(this Array array, T item) { return Array.IndexOf(array, item); } public static bool Remove(this ICollection items, Predicate predicate) { foreach (T item in items) { if (predicate(item)) { return items.Remove(item); } } return false; } public static void TryRemoveTraceListener(this TraceSource source) where T : TraceListener { Try(delegate { TraceSource traceSource = source; T val = ((traceSource != null) ? traceSource.Listeners.OfType().FirstOrDefault() : null); if (val != null) { source.Listeners.Remove(val); } }); } public static IEnumerable Chain(T firstItem, Func nextSelector) { for (T item = firstItem; item != null; item = nextSelector(item)) { yield return item; } } public static IEnumerable ToEnumerable(this Array items) { foreach (object item in items) { yield return (T)item; } } public static bool SequenceRangeEquals(this IEnumerable items, IEnumerable compareItems, int count = -1, IEqualityComparer equalityComparer = null) { if (count == 0) { return true; } if (equalityComparer == null) { equalityComparer = EqualityComparer.Default; } using (IEnumerator enumerator = items.GetEnumerator()) { using IEnumerator enumerator2 = compareItems.GetEnumerator(); for (int i = 0; count == -1 || i < count; i++) { bool flag = enumerator.MoveNext(); bool flag2 = enumerator2.MoveNext(); if (count == -1 && !flag2) { return true; } if (!flag || !flag2) { return false; } if (!equalityComparer.Equals(enumerator.Current, enumerator2.Current)) { return false; } } } return true; } public static bool RangeEquals(this T[] items, int itemsStartIndex, T[] compareItems, int compareItemsStartIndex, int count, IEqualityComparer equalityComparer = null) { if (equalityComparer == null) { equalityComparer = EqualityComparer.Default; } for (int i = 0; i < count; i++) { if (!equalityComparer.Equals(items[i + itemsStartIndex], compareItems[i + compareItemsStartIndex])) { return false; } } return true; } public static IEnumerable AsEnumerable(this ArraySegment @this) { for (int i = 0; i < @this.Count; i++) { yield return @this.Array[i + @this.Offset]; } } public static ArraySegment ToArraySegment(this T[] array) { return new ArraySegment(array, 0, array.Length); } public static T[] ToArray(this ArraySegment @this, bool forceCopy = false) { if (@this.Array == null || @this.Count == 0) { return EmptyArray(); } if (!forceCopy && @this.Offset == 0 && @this.Count == @this.Array.Length) { return @this.Array; } T[] array = new T[@this.Count]; Array.Copy(@this.Array, @this.Offset, array, 0, @this.Count); return array; } public static T[] ToArray(this IList> @this, bool forceCopy = false) { if (!forceCopy && @this.Count == 1 && @this[0].Offset == 0 && @this[0].Count == @this[0].Array?.Length) { return @this[0].Array; } T[] array = new T[@this.Sum((ArraySegment it) => it.Count)]; int num = 0; for (int num2 = 0; num2 < @this.Count; num2++) { Buffer.BlockCopy(@this[num2].Array, @this[num2].Offset, array, num, @this[num2].Count); num += @this[num2].Count; } return array; } public static ArraySegment EmptyArraySegment() { return new ArraySegment(EmptyArray()); } public static ArraySegment CreateArraySegment(int count) { return new ArraySegment(new T[count]); } public static MemoryStream ToMemoryStream(this ArraySegment byteArraySegment) { return new MemoryStream(byteArraySegment.Array, byteArraySegment.Offset, byteArraySegment.Count); } public static string QuoteWindowsCommandLine(params object[] args) { return QuoteWindowsCommandLine((IEnumerable)args); } public static string QuoteWindowsCommandLine(IEnumerable args) { return args.Select(QuoteForWindowsShellScript).Join(' '); } public static string QuoteForWindowsShellScript(object obj) { return "\"" + obj.ToString().Replace("\"", "\"\"") + "\""; } public static string QuotePosixCommandLine(params object[] args) { return args.Select(QuoteForPosixShellScript).Join(' '); } public static string QuoteForPosixShellScript(object obj) { return "'" + obj.ToString().Replace("'", "'\\''") + "'"; } public static int ConvertWaitMilliseconds(long waitMilliseconds) { if (waitMilliseconds <= 0) { return 0; } if (waitMilliseconds > int.MaxValue) { return -1; } return (int)waitMilliseconds; } public static long GetMillisecondsSince(long millisecondCount) { return Singleton.Instance.GetMillisecondCount() - millisecondCount; } public static IEnumerable GetPluginTypes(Type interfaceOrBaseClass = null) { foreach (Assembly pluginAssembly in Singleton.Instance.GetPluginAssemblies()) { foreach (Type item in pluginAssembly.GetTypesX()) { if (item.IsOfType(interfaceOrBaseClass)) { yield return item; } } } } [MethodImpl(MethodImplOptions.NoInlining)] public static DirectoryInfo GetExecutingAssemblyDirectory() { return new FileInfo(Assembly.GetCallingAssembly().Location).Directory; } public static void InitializeItem(T item) { foreach (Type pluginType in GetPluginTypes(typeof(IInitializeItem))) { ((IInitializeItem)Activator.CreateInstance(pluginType)).InitializeItem(item); } } [return: NotNullIfNotNull("defaultValue")] public static TValue? TryGetValue(this IDictionary dictionary, TKey key, TValue? defaultValue = default(TValue?)) where TKey : notnull { if (!dictionary.TryGetValue(key, out TValue value)) { return defaultValue; } return value; } public static T? TryGetValue(this IDictionary typeMap) { if (!typeMap.TryGetValue(typeof(T), out object value)) { return default(T); } return (T)value; } public static TValue? TryGetValueNullable(this IDictionary dictionary, TKey key) where TKey : notnull where TValue : struct { if (dictionary.TryGetValue(key, out var value)) { return value; } return null; } public static U? Select(this IDictionary typeMap, Func selector) { if (typeMap.TryGetValue(typeof(T), out object value)) { return selector((T)value); } return default(U); } public static void With(this IDictionary typeMap, Proc proc) { if (typeMap.TryGetValue(typeof(T), out object value)) { proc((T)value); } } public static void TrySetValue(this IDictionary typeMap, object item) where T : class { if (item is T) { typeMap[typeof(T)] = item; } } public static bool SetValue(ref T? location, T? newValue, IEqualityComparer? equalityComparer = null) { bool result = !Equals(location, newValue, equalityComparer); location = newValue; return result; } public static bool Equals(this T? @this, T? other, IEqualityComparer? equalityComparer = null) { return (equalityComparer ?? EqualityComparer.Default).Equals(@this, other); } public static void TryPulseAll(object sync) { if (Monitor.TryEnter(sync)) { Monitor.PulseAll(sync); Monitor.Exit(sync); } } public static string ToHexString(this IEnumerable bytes) { bytes.AssertNonNull(); StringBuilder stringBuilder = new StringBuilder(); foreach (byte @byte in bytes) { stringBuilder.AppendFormat("{0:x2}", @byte); } return stringBuilder.ToString(); } public static string ToBinaryString(this IEnumerable bits) { bits.AssertNonNull(); StringBuilder stringBuilder = new StringBuilder(); foreach (bool bit in bits) { stringBuilder.AppendFormat(bit ? "1" : "0", new object[0]); } return stringBuilder.ToString(); } public static byte[] ParseHexString(string hexString) { hexString.AssertNonNull(); byte[] array = new byte[hexString.Length / 2]; for (int i = 0; i < hexString.Length; i += 2) { array[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); } return array; } public static byte[] ParseBase32String(string base32String) { byte[] array = new byte[base32String.Length * 5 / 8]; int num = 0; for (int i = 0; i < base32String.Length; i++) { int num2 = base32String[i]; if (num2 < 91 && num2 > 64) { num2 -= 65; } else if (num2 < 56 && num2 > 49) { num2 -= 24; } else { if (num2 >= 123 || num2 <= 96) { throw new ArgumentException(); } num2 -= 97; } for (int num3 = 4; num3 >= 0; num3--) { array[num / 8] |= (byte)(((num2 >> num3) & 1) << 7 - num++ % 8); } } return array; } public static void ThrowIfNotNull(this Exception @this) { if (@this != null) { throw @this; } } public static T[] JoinSegments(IList> segments) { int num = 0; foreach (ArraySegment item in segments.AssertArgumentNonNull("segments")) { num += item.Count; } T[] array = new T[num]; int num2 = 0; foreach (ArraySegment segment in segments) { Array.Copy(segment.Array, segment.Offset, array, num2, segment.Count); num2 += segment.Count; } return array; } public static int? TryParseInt32Nullable(this string value) { if (!int.TryParse(value, out var result)) { return null; } return result; } public static long? TryParseInt64Nullable(this string value) { if (!long.TryParse(value, out var result)) { return null; } return result; } public static ulong? TryParseUInt64Nullable(this string value) { if (!ulong.TryParse(value, out var result)) { return null; } return result; } public static bool? TryParseBoolNullable(this string value) { if (!bool.TryParse(value, out var result)) { return null; } return result; } public static bool TryParseBool(this string boolString, bool defaultValue = false) { if (!bool.TryParse(boolString, out var result)) { return defaultValue; } return result; } public static DateTime TryParseDateTime(this string dateTimeString, DateTime defaultValue = default(DateTime)) { if (!DateTime.TryParse(dateTimeString, out var result)) { return defaultValue; } return result; } public static double TryParseDouble(this string doubleString, double defaultValue = 0.0) { if (!double.TryParse(doubleString, out var result)) { return defaultValue; } return result; } public static long TryParseInt64(this string int64String, long defaultValue = 0L) { if (!long.TryParse(int64String, out var result)) { return defaultValue; } return result; } public static int TryParseInt32(this string int32String, int defaultValue = 0) { if (!int.TryParse(int32String, out var result)) { return defaultValue; } return result; } public static Uri TryParseUri(string uriString) { Uri.TryCreate(uriString, UriKind.Absolute, out Uri result); return result; } public static TEnum? TryParseEnum(string enumString, bool ignoreCase = false) where TEnum : struct { if (!TryParseEnum(enumString, ignoreCase, out var value)) { return null; } return value; } public static TEnum TryParseEnum(string enumString, TEnum defaultValue) where TEnum : struct { if (!TryParseEnum(enumString, out var value)) { return defaultValue; } return value; } public static TEnum TryParseEnum(string enumString, bool ignoreCase, TEnum defaultValue) where TEnum : struct { if (!TryParseEnum(enumString, ignoreCase, out var value)) { return defaultValue; } return value; } public static bool TryParseEnum(string enumString, out TEnum value) where TEnum : struct { return TryParseEnum(enumString, ignoreCase: false, out value); } public static bool TryParseEnum(string enumString, bool ignoreCase, out TEnum value) where TEnum : struct { value = default(TEnum); if (string.IsNullOrEmpty(enumString)) { return false; } try { value = (TEnum)Enum.Parse(typeof(TEnum), enumString, ignoreCase); return true; } catch { return false; } } public static T ParseEnum(string enumString) { return (T)Enum.Parse(typeof(T), enumString); } public static T GetBoundedValue(T min, T value, T max) where T : IComparable { if (value.CompareTo(min) <= 0) { return min; } if (value.CompareTo(max) >= 0) { return max; } return value; } public static int GetBoundedValueMaxExclusive(int minInclusive, int value, int maxExclusive) { return GetBoundedValue(minInclusive, value, maxExclusive - 1); } public unsafe static Guid CreateGuid(byte[] buffer, int startIndex, int count) { fixed (byte* ptr = buffer) { return CreateGuid(ptr + startIndex, count); } } public unsafe static Guid CreateGuid(byte* b, int count) { if (count < 16) { throw new ArgumentOutOfRangeException(); } return new Guid((b[3] << 24) | (b[2] << 16) | (b[1] << 8) | *b, (short)((b[5] << 8) | b[4]), (short)((b[7] << 8) | b[6]), b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); } public static ArrayPoolRental RentEx(this ArrayPool @this, int size) { return new ArrayPoolRental(@this, size); } public static T PerformUnwrappingInnerException(Func func) { try { return func(); } catch (Exception ex) { if (ex.InnerException != null) { Singleton.Instance.TryFreezeStackForRethrow(ex.InnerException); throw ex.InnerException; } throw; } } public static Guid ByteToGuid(this byte value) { return new Guid(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, value); } public static Guid Int32ToGuid(this int value) { return new Guid(0, 0, 0, 0, 0, 0, 0, (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value); } public static int ToInt32(this Guid value) { return value.ToByteArray().Reverse().Pipe((byte[] it) => BitConverter.ToInt32(it, 0)); } public static T[] Reverse(this T[] values) { return Enumerable.Reverse(values).ToArray(); } public static string GetFingerprint(byte[] bytes) { byte[] array = Singleton.Instance.ComputeMD5Hash(bytes); byte[] array2 = new byte[8]; Array.Copy(array, array.Length - array2.Length, array2, 0, array2.Length); return array2.ToHexString(); } public static FILETIME ToFileTimeStruct(DateTime dateTime) { long num = dateTime.ToFileTimeUtc(); return new FILETIME { dwHighDateTime = (int)(num >> 32), dwLowDateTime = (int)num }; } public static DateTime FromFileTimeStruct(FILETIME fileTimeStruct) { long num = ((long)fileTimeStruct.dwHighDateTime << 32) | (uint)fileTimeStruct.dwLowDateTime; if (num <= 0 || num >= 2650467743999999999L) { return DateTime.MinValue; } return DateTime.FromFileTimeUtc(num); } public static byte[] CopyToNewBuffer(this ArraySegment @this) { return @this.Array.AssertNonNull().BlockCopy(@this.Offset, @this.Count); } public static byte[] CopyToNewBuffer(byte[] buffer, int offset, int count) { return buffer.BlockCopy(offset, count); } public static T[] BlockCopy(this T[] @this) where T : struct { return @this.BlockCopy(0, @this.Length); } public static T[] BlockCopy(this T[] @this, int offset, int count) where T : struct { T[] array = new T[count]; Buffer.BlockCopy(@this, offset, array, 0, count); return array; } public static string MakeValidFileName(string fileName) { char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { fileName = fileName.Replace(oldChar, '_'); } return fileName.Trim().TrimEnd(new char[1] { '.' }).IfNotEmpty() .Else("_"); } public unsafe static IntPtr AllocateZeroedMemory(int byteCount) { IntPtr result = Marshal.AllocHGlobal(byteCount); ZeroMemory(result.ToPointer(), byteCount); return result; } public unsafe static void ZeroMemory(void* ptr, int byteCount) { for (int i = 0; i < byteCount; i++) { ((sbyte*)ptr)[i] = 0; } } public unsafe static void CopyMemory(IntPtr src, IntPtr dst, int count) { CopyMemory((byte*)(void*)src, (byte*)(void*)dst, count); } public unsafe static void CopyMemory(byte* src, byte* dst, int count) { while (count >> 5 != 0) { *(long*)dst = *(long*)src; ((long*)dst)[1] = ((long*)src)[1]; ((long*)dst)[2] = ((long*)src)[2]; ((long*)dst)[3] = ((long*)src)[3]; src += 32; dst += 32; count -= 32; } while (count >> 3 != 0) { *(long*)dst = *(long*)src; src += 8; dst += 8; count -= 8; } while (count >> 1 != 0) { *(short*)dst = *(short*)src; src += 2; dst += 2; count -= 2; } while (count-- != 0) { *(dst++) = *(src++); } } public unsafe static bool CompareMemory(IntPtr ptr1, byte[] ptr2, int ptr2Offset, int count) { fixed (byte* ptr3 = ptr2) { return CompareMemory((byte*)(void*)ptr1, ptr3 + ptr2Offset, count); } } public unsafe static bool CompareMemory(IntPtr ptr1, IntPtr ptr2, int count) { return CompareMemory((byte*)(void*)ptr1, (byte*)(void*)ptr2, count); } public unsafe static bool CompareMemory(byte* ptr1, byte* ptr2, int count) { for (int i = 0; i < count; i++) { if (*(ptr1++) != *(ptr2++)) { return false; } } return true; } public static int CompareWidthThenHeight(this CoreSize first, CoreSize second) { int num = first.Width.CompareTo(second.Width); if (num == 0) { return first.Height.CompareTo(second.Height); } return num; } public static string GetUniqueTempPath(string tempDirectoryPath, string? suffix = null) { return Path.Combine(tempDirectoryPath, ConvertToBase64UrlString(Guid.NewGuid().ToByteArray().Take(9) .ToArray()) + suffix); } public static IEnumerable OrderByXThenY(this IEnumerable coreRectEnumerable) { return coreRectEnumerable.Sort((CoreRect first, CoreRect second) => first.CompareXThenY(second)); } public static IList Sort(this IEnumerable source, Comparison comparison = null) { TSource[] array = source.ToArray(); if (comparison == null) { Array.Sort(array); } else { Array.Sort(array, comparison); } return array; } public static TSource FirstOrDefault(this IEnumerable source, Func predicate, TSource defaultValue) { foreach (TSource item in source) { if (predicate == null || predicate(item)) { return item; } } return defaultValue; } public static TSource? FirstOrDefaultNullable(this IEnumerable @this) where TSource : struct { using (IEnumerator enumerator = @this.GetEnumerator()) { if (enumerator.MoveNext()) { return enumerator.Current; } } return null; } public static TSource? FirstOrDefault(this TSource[]? array) { if (array == null || array.Length == 0) { return default(TSource); } return array[0]; } [Obsolete("Use ToHashSet")] public static HashSet ToSet(this IEnumerable items, IEqualityComparer equalityComparer = null) { return items.ToHashSet(equalityComparer); } public static IEnumerable GetEmbeddedResourceNames(this Type classInAssembly, string optionalExtensionFilter = null) { IEnumerable enumerable = (from it in classInAssembly.GetAssemblyX().GetManifestResourceNames() select it.Split(new string[1] { ".Properties." }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault()).WhereNotNull(); if (optionalExtensionFilter != null) { return enumerable.Where((string it) => it.EndsWith(optionalExtensionFilter)); } return enumerable; } public static string ExtractEmbeddedResourceToString(this Type classInAssembly, string resourceName, Encoding encoding) { return classInAssembly.ExtractEmbeddedResource(resourceName, (Stream it) => new StreamReader(it, encoding).ReadToEnd()); } public static string ExtractEmbeddedResourceToString(this Type classInAssembly, string resourceName) { return classInAssembly.ExtractEmbeddedResource(resourceName, (Stream it) => new StreamReader(it).ReadToEnd()); } public static ArraySegment ExtractEmbeddedResourceToBytes(this Type classInAssembly, string resourceName) { return classInAssembly.ExtractEmbeddedResource(resourceName, (Stream it) => it.ReadAllBytes()); } public static T ExtractEmbeddedResource(this Type classInAssembly, string resourceName, Func selector) { using Stream stream = classInAssembly.ExtractEmbeddedResourceToStream(resourceName); return stream.SafePipe(selector); } public static Stream ExtractEmbeddedResourceToStream(this Type classInAssembly, string resourceName) { classInAssembly.AssertArgumentNonNull("classInAssembly"); resourceName.AssertArgumentNonNull("resourceName"); string name = classInAssembly.Namespace + ".Properties." + resourceName; return classInAssembly.GetAssemblyX().GetManifestResourceStream(name); } public static object GetDefaultValue(this Type type) { if (!type.IsValueTypeX()) { return null; } return Activator.CreateInstance(type); } public static string ToDurationString(this TimeSpan timeSpan) { if (timeSpan.Ticks < 0) { return "???"; } string text = string.Empty; if (timeSpan.Days != 0) { text = text + timeSpan.Days + "d "; } if (timeSpan.Hours != 0) { text = text + timeSpan.Hours + "h "; } text = text + timeSpan.Minutes + "m"; if (timeSpan.Days == 0 && timeSpan.Hours == 0) { text = text + " " + timeSpan.Seconds + "s"; } return text; } public static void DoWhile(this IEnumerable items, Func predicate) { items.DoUntil((T _) => !predicate(_)); } public static void DoUntil(this IEnumerable items, Func predicate) { foreach (T item in items) { if (predicate(item)) { break; } } } public static IEnumerable SafeEnumerate(this IEnumerable items) { if (items == null) { yield break; } foreach (object item in items) { yield return item; } } public static IEnumerable SafeEnumerate(this IEnumerable? items) { return items ?? EmptyArray(); } public static ICollection SafeEnumerate(this ICollection? items) { return items ?? EmptyArray(); } public static IList SafeEnumerate(this IList? items) { return items ?? EmptyArray(); } public static bool SafeAny(this IEnumerable items, Func predicate = null) { if (items == null) { return false; } if (predicate != null) { return items.Any(predicate); } return items.Any(); } public static IEnumerable TrySelect(this IEnumerable source, Func selector) { return source.TrySelect(selector, shouldTraceException: true); } public static IEnumerable TrySelect(this IEnumerable source, Func selector, bool shouldTraceException) { foreach (TSource element in source) { yield return TryGet(() => selector(element), shouldTraceException); } } public static void EnsureEndsWithChar(ref string s, char c) { s = s.EnsureEndsWithChar(c); } public static string EnsureEndsWithChar(this string s, char c) { if (string.IsNullOrEmpty(s) || s[s.Length - 1] != c) { return s + c; } return s; } public static string EnsureStartsWithChar(this string s, char c) { if (string.IsNullOrEmpty(s) || s[0] != c) { return c + s; } return s; } public static void ConvertBothSlashesToChar(ref string s, char c) { s = s.ConvertBothSlashesToChar(c); } public static string ConvertBothSlashesToChar(this string s, char c) { if (s == null) { return null; } if (c != '\\') { s = s.Replace('\\', c); } if (c != '/') { s = s.Replace('/', c); } return s; } public static string GetBasicAuthorizationHeaderString(string credentialsPart) { return "Basic " + credentialsPart; } public static string GetBasicAuthorizationHeaderString(string userName, string password) { return GetBasicAuthorizationHeaderString(GetBasicAuthenticationHeaderCredentialsPart(userName, password)); } public static string GetBasicAuthenticationHeaderCredentialsPart(string userName, string password) { return Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ":" + password)); } public static string WindowsDomainUserNameToString(string domain, string userName) { if (string.IsNullOrEmpty(domain)) { return userName; } if (domain.Length > 2 && domain.IndexOf('.') != -1) { return userName + "@" + domain; } return domain + "\\" + userName; } public static NetworkCredential ParseWindowsCredentials(string domainUserName, string password) { NetworkCredential networkCredential = new NetworkCredential(); if (domainUserName != null) { string text = domainUserName.Trim(); int num = text.IndexOf('\\'); int num2 = text.IndexOf('@'); if (num > 0) { networkCredential.Domain = text.Substring(0, num); networkCredential.UserName = text.Substring(num + 1); } else if (num2 > 0) { networkCredential.UserName = text.Substring(0, num2); networkCredential.Domain = text.Substring(num2 + 1); } else { networkCredential.UserName = text; } } networkCredential.Password = password; return networkCredential; } public static (string userName, string password) ParseCredentialsString(string credentialsString, bool isUrlEncoded) { if (string.IsNullOrEmpty(credentialsString)) { return default((string, string)); } int num = credentialsString.IndexOf(':'); string text = ((num == -1) ? credentialsString : credentialsString.Substring(0, num)); string text2 = ((num == -1) ? string.Empty : credentialsString.Substring(num + 1)); if (isUrlEncoded) { text = UrlDecode(text); text2 = UrlDecode(text2); } return (userName: text, password: text2); } public static Func ProcToDefaultFunc(this Proc proc) { return delegate { proc(); return (object)null; }; } public static Func ProcToDefaultFunc(this Proc proc) { return delegate(T1 arg1) { proc(arg1); return (object)null; }; } public static Func ProcToDefaultFunc(this Proc proc) { return delegate(T1 arg1, T2 arg2) { proc(arg1, arg2); return (object)null; }; } public static Func ProcToDefaultFunc(this Proc proc) { return delegate(T1 arg1, T2 arg2, T3 arg3) { proc(arg1, arg2, arg3); return (object)null; }; } public static Func ProcToDefaultFunc(this Proc proc) { return delegate(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { proc(arg1, arg2, arg3, arg4); return (object)null; }; } public static void ReadStructure(this Stream stream, ref T structure) { byte[] array = new byte[ReflectionExtensions.SizeOfType()]; stream.ReadFully(array, 0, array.Length); GetStructureFromBytes(array, ref structure); } public unsafe static void GetStructureFromBytes(byte[] bytes, ref T structure) { if (bytes.Length < ReflectionExtensions.SizeOfType()) { throw new ArgumentOutOfRangeException(); } fixed (byte* ptr = bytes) { structure = ReflectionExtensions.PtrToStructure((IntPtr)ptr); } } public static T GetStructureFromBytes(byte[] bytes) where T : new() { T structure = new T(); GetStructureFromBytes(bytes, ref structure); return structure; } public static void WriteStructure(this Stream stream, ref T structure) { byte[] bytesFromStructure = GetBytesFromStructure(ref structure); stream.Write(bytesFromStructure, 0, bytesFromStructure.Length); } public static byte[] GetBytesFromStructure(T structure) { return GetBytesFromStructure(ref structure); } public unsafe static byte[] GetBytesFromStructure(ref T structure) { byte[] array = new byte[ReflectionExtensions.SizeOfType()]; fixed (byte* ptr = array) { Marshal.StructureToPtr((object)structure, (IntPtr)ptr, false); } return array; } public unsafe static (int Complexity, int Hash) AnalyzeImage(this IBitmapData @this) { int num = 0; int num2 = 0; int width = @this.Width; int* ptr = (int*)@this.Scan0.ToPointer(); int num3 = 0; while (num3 < @this.Height) { for (int i = 0; i < width; i++) { if (i != 0 && ptr[i] != ptr[i - 1]) { num2++; } num = (num << 5) + (ptr[i] & 0xFFFFFF) + (num >> 2); } num3++; ptr = (int*)((byte*)ptr + @this.Stride); } return (Complexity: num2, Hash: num); } public static T PerformWithBits(this IBlittable @this, CoreRect bounds, Func func) { IBitmapData bitmapData = @this.AcquireBits(bounds); try { return func(bitmapData); } finally { @this.ReleaseBits(bitmapData); } } public static void PerformWithBits(this IBlittable @this, CoreRect bounds, Proc proc) { @this.PerformWithBits(bounds, proc.ProcToDefaultFunc()); } public unsafe static int CopyPixels(this IBitmapData from, IBitmapData to, bool alphaBlendish = false) { if (from.Width != to.Width || from.Height != to.Height) { throw new InvalidOperationException("Bitmap sections must match"); } if (from.PixelModel.BitsPerPixel != to.PixelModel.BitsPerPixel) { throw new InvalidOperationException("Pixel models must match"); } int width = from.Width; int count = DivUp(width * from.PixelModel.BitsPerPixel, 8); byte* ptr = (byte*)from.Scan0.ToPointer(); byte* ptr2 = (byte*)to.Scan0.ToPointer(); if (alphaBlendish) { if (!from.PixelModel.CanBlockCopyBgr32 || !to.PixelModel.CanBlockCopyBgr32) { throw new InvalidOperationException("Only 32-bit pixel models supported for alpha blend"); } int num = 0; int num2 = 0; while (num2 < from.Height) { uint* ptr3 = (uint*)ptr; uint* ptr4 = (uint*)ptr2; int num3 = 0; while (num3 < width) { if (*ptr3 != *ptr4 && (*ptr3 & 0xFF000000u) >= (*ptr4 & 0xFF000000u)) { *ptr4 = *ptr3; num++; } num3++; ptr3++; ptr4++; } num2++; ptr += from.Stride; ptr2 += to.Stride; } return num; } int num4 = 0; while (num4 < from.Height) { CopyMemory(ptr, ptr2, count); num4++; ptr += from.Stride; ptr2 += to.Stride; } return from.Width * from.Height; } public unsafe static void CopyPixelsAndPaddingAlpha(this IBitmapData from, IBitmapData to) { if (from.Width != to.Width || from.Height != to.Height) { throw new InvalidOperationException("Bitmap sections must match"); } if (from.PixelModel.BitsPerPixel != to.PixelModel.BitsPerPixel) { throw new InvalidOperationException("Pixel models must match"); } int width = from.Width; DivUp(width * from.PixelModel.BitsPerPixel, 8); byte* ptr = (byte*)from.Scan0.ToPointer(); byte* ptr2 = (byte*)to.Scan0.ToPointer(); int num = 0; while (num < from.Height) { uint* ptr3 = (uint*)ptr; uint* ptr4 = (uint*)ptr2; int num2 = 0; while (num2 < width) { if ((*ptr3 & 0xFFFFFF) != 0) { *ptr4 = *ptr3 | 0xFF000000u; } num2++; ptr3++; ptr4++; } num++; ptr += from.Stride; ptr2 += to.Stride; } } public static string Replace(this string s, string pattern, Func matchEvaluator) { return s.Replace(pattern, (Match m, int i) => matchEvaluator(m)); } public static string Replace(this string s, string pattern, Func matchEvaluator) { int replacementIndex = 0; return Regex.Replace(s, pattern, (Match m) => matchEvaluator(m, replacementIndex++)); } public static string ConvertToBase64UrlString(byte[] bytes) { return Convert.ToBase64String(bytes).Replace('+', '-').Replace('/', '_') .TrimEnd(new char[1] { '=' }); } public static byte[] ConvertFromBase64StringFlexible(string base64String) { if (base64String == null) { return null; } if (base64String == string.Empty) { return EmptyArray(); } string text = base64String.Replace('-', '+').Replace('_', '/').Replace("\r", "") .Replace("\n", "") .Replace(" ", ""); if (text.Length % 4 != 0) { text += new string('=', 4 - text.Length % 4); } return Convert.FromBase64String(text); } public static string EncodeUtf8AsBase64(this string @this) { return Convert.ToBase64String(Constants.UTF8EncodingWithoutPreamble.GetBytes(@this)); } public static byte[] ReadBytes(this Stream stream, int count) { byte[] array = new byte[count]; stream.ReadFully(array, 0, count); return array; } public static byte[] ReadAllBytesToArray(this Stream stream) { if (stream.CanSeek) { return stream.ReadBytes((int)(stream.Length - stream.Position)); } MemoryStream memoryStream = new MemoryStream(); stream.WriteTo(memoryStream, 1048576L); return memoryStream.ToArray(); } public static ArraySegment ReadAllBytes(this Stream stream) { return new ArraySegment(stream.ReadAllBytesToArray()); } public static ArraySegment GetAllBytes(this MemoryStream stream) { return Singleton.Instance.GetAllBytes(stream); } public static int Read(this Stream stream, ArraySegment bytes) { return stream.Read(bytes.Array, bytes.Offset, bytes.Count); } public static void Write(this Stream stream, ArraySegment bytes) { if (bytes.Count != 0) { stream.Write(bytes.Array, bytes.Offset, bytes.Count); } } public static void WriteAllBytes(this Stream stream, byte[] bytes) { if (bytes.Length != 0) { stream.Write(bytes, 0, bytes.Length); } } public static void WriteZeros(this Stream stream, long count) { stream.WriteAllBytes(new byte[count]); } public static void WriteNetworkShort(this Stream stream, short value) { stream.WriteAllBytes(new byte[2] { (byte)(value >> 8), (byte)value }); } public static void WriteNetworkInt(this Stream stream, int value) { stream.WriteAllBytes(new byte[4] { (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value }); } public static void WriteNetworkLong(this Stream stream, long value) { stream.WriteAllBytes(new byte[8] { (byte)(value >> 56), (byte)(value >> 48), (byte)(value >> 40), (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value }); } public static T CreateCryptographyAlgorithm() where T : new() { return CreateCryptographyAlgorithm(() => new T()); } public static T CreateCryptographyAlgorithm(Func creator) { try { return creator(); } catch { Try(delegate { FieldInfo field = typeof(CryptoConfig).GetField("s_fipsAlgorithmPolicy", BindingFlags.Static | BindingFlags.NonPublic); if ((object)field != null) { field.SetValue(null, false); } else { typeof(SymmetricAlgorithm).Assembly.GetType("System.Security.Cryptography.Utils").GetField("s_fipsAlgorithmPolicy", BindingFlags.Static | BindingFlags.NonPublic)?.SetValue(null, 0); } }); return creator(); } } public static byte[] SignData(this RSACryptoServiceProvider @this, byte[] data, Func hashAlgorithmCreator) { using HashAlgorithm halg = CreateCryptographyAlgorithm(hashAlgorithmCreator); return @this.SignData(data, halg); } public static bool VerifyData(this RSACryptoServiceProvider @this, byte[] data, Func hashAlgorithmCreator, byte[] signature) { using HashAlgorithm halg = CreateCryptographyAlgorithm(hashAlgorithmCreator); return @this.VerifyData(data, halg, signature); } public static IList DequeueWhile(this Queue queue, Func predicate) { return queue.DequeueUntil((T it) => !predicate(it)); } public static IList DequeueWhile(this Queue queue, Func predicate) { return queue.DequeueUntil((T it, int index) => !predicate(it, index)); } public static IList DequeueUntil(this Queue queue, Func predicate) { return queue.DequeueUntil((T it, int _) => predicate(it)); } public static IList DequeueUntil(this Queue queue, Func predicate) { return DequeueUntilInternal().ToList(); IEnumerable DequeueUntilInternal() { int i = 0; while (queue.Count != 0 && !predicate(queue.Peek(), i)) { yield return queue.Dequeue(); i++; } } } public static T? TryDequeue(this Queue queue) { if (queue.Count == 0) { return default(T); } return queue.Dequeue(); } public static void DeriveSecureRandomValuesForConnection(byte[] secretBytes, byte[] clientRandom, byte[] serverRandom, out byte[] clientWriteKey, out byte[] serverWriteKey, out byte[] clientWriteInitializationVector, out byte[] serverWriteInitializationVector) { if (secretBytes == null || secretBytes.Length == 0 || clientRandom == null || clientRandom.Length != 32 || serverRandom == null || serverRandom.Length != 32) { throw new ArgumentException(); } int num = secretBytes.Length * 2 + 32; MemoryStream memoryStream = new MemoryStream(num); byte[] array = new byte[clientRandom.Length + serverRandom.Length]; Buffer.BlockCopy(clientRandom, 0, array, 0, clientRandom.Length); Buffer.BlockCopy(serverRandom, 0, array, clientRandom.Length, serverRandom.Length); while (memoryStream.Position < num) { byte[] array2 = Singleton.Instance.ComputeHMACSHA256Hash(secretBytes, array); memoryStream.Write(array2, 0, Math.Min(array2.Length, memoryStream.Capacity - (int)memoryStream.Position)); array = array2; } memoryStream.Position = 0L; clientWriteKey = memoryStream.ReadBytes(secretBytes.Length); serverWriteKey = memoryStream.ReadBytes(secretBytes.Length); clientWriteInitializationVector = memoryStream.ReadBytes(16); serverWriteInitializationVector = memoryStream.ReadBytes(16); } public static string GetMoreFriendlyName(this Type type) { string name = type.Name; if (type.IsGenericTypeX()) { return (name.SplitFirstNullable('`')?.Key ?? name) + "<" + (from typeArg in type.GetGenericArgumentsX() select typeArg.GetMoreFriendlyName()).Join(", ") + ">"; } if (type.IsArray) { return type.GetElementType().GetMoreFriendlyName() + CreateFullArray(type.GetArrayRank(), "[]").Join(""); } return name; } public static IEnumerable AssertNoStringContains(this IEnumerable strings, char contains) { return strings.AssertNoStringContains(contains.ToString()); } public static IEnumerable AssertNoStringContains(this IEnumerable strings, string contains) { foreach (string @string in strings) { if (@string != null && @string.Contains(contains)) { throw new ArgumentException("Cannot contain '" + contains + "'"); } yield return @string; } } public static string JoinNonNullOrEmpty(char separator, params string[] strings) { return JoinNonNullOrEmpty(separator.ToString(), strings); } public static string JoinNonNullOrEmpty(string separator, params string[] strings) { return strings.Where((string s) => !string.IsNullOrEmpty(s)).Join(separator); } public static SessionConnectionInfo? TryGetCurrentConnectionInfo(this SessionInfoMessageOld5? @this) { return @this?.Connections?.FirstOrDefault((SessionConnectionInfo it) => it.ConnectionID == @this.CurrentConnectionID); } public static SessionConnectionInfo? TryGetCurrentConnectionInfo(this SessionInfoMessageOld8? @this) { return @this?.Connections?.FirstOrDefault((SessionConnectionInfo it) => it.ConnectionID == @this.CurrentConnectionID); } public static V GetValueAndCreateIfNotFound(this IDictionary dict, K key) where V : new() { return dict.GetValueAndCreateIfNotFound(key, () => new V()); } public static V GetValueAndCreateIfNotFound(this IDictionary dict, K key, Func createNewValue) { if (!dict.TryGetValue(key, out var value)) { value = (dict[key] = createNewValue()); } return value; } public static void OperateOnBits(this IBlittable blittable, CoreRect bounds, Proc proc) { IBitmapData bitmapData = null; try { bitmapData = blittable.AcquireBits(bounds); proc(bitmapData); } finally { if (bitmapData != null) { blittable.ReleaseBits(bitmapData); } } } public static T[] CreateFullArray(int size, T value) { T[] array = new T[size]; array.Fill(value); return array; } public static void Fill(this T[] array, T value) { for (int i = 0; i < array.Length; i++) { array[i] = value; } } public static int CeilingDivide(this int dividend, int divisor) { return dividend / divisor + Math.Sign(divisor) * Math.Sign(dividend % divisor); } public static uint CeilingDivide(this uint dividend, uint divisor) { return dividend / divisor + (uint)Math.Sign(dividend % divisor); } public static decimal SafeDivide(this decimal dividend, int divisor) { if (divisor != 0) { return dividend / (decimal)divisor; } return 0m; } public static void Swap(ref T obj1, ref T obj2) { T val = obj1; obj1 = obj2; obj2 = val; } public static IEnumerable ConcatBefore(this IEnumerable items1, IEnumerable items2) { return items2.Concat(items1); } public static bool ContainsAnyIgnoreCase(this string str, params string[] possibleSubstrings) { foreach (string value in possibleSubstrings) { if (str.IndexOf(value, StringComparison.OrdinalIgnoreCase) != -1) { return true; } } return false; } public static void ReleaseIntPtrIfNotNull(ref IntPtr reference, Func releaseFunc) { if (reference != IntPtr.Zero) { releaseFunc(reference); reference = IntPtr.Zero; } } public static IEnumerable GetAncestors(this T item, Func parentSelector, bool includeSelf = false) where T : class { for (T parent = (T)(includeSelf ? ((object)item) : ((object)parentSelector(item))); parent != null; parent = parentSelector(parent)) { yield return parent; } } public static IEnumerable GetDescendents(this T topItem, Func?> childrenSelector, bool includeSelf = true, Func? getDescendentsPredicate = null) { bool shouldGetDescendents = getDescendentsPredicate?.Invoke(topItem) ?? true; if (includeSelf) { yield return topItem; } if (!shouldGetDescendents) { yield break; } foreach (T item in childrenSelector(topItem).SafeEnumerate()) { foreach (T descendent in item.GetDescendents(childrenSelector, includeSelf: true, getDescendentsPredicate)) { yield return descendent; } } } public static KeyValuePair CreateKeyValuePair(TKey key, TValue value) { return new KeyValuePair(key, value); } public static KeyValuePair ToKeyValuePair(Tuple item) { return new KeyValuePair(item.Item1, item.Item2); } public static KeyValuePair Transform(this KeyValuePair kvp, Func keyCreator, Func valueCreator) { return CreateKeyValuePair(keyCreator(kvp.Key, kvp.Value), valueCreator(kvp.Key, kvp.Value)); } public static KeyValuePair WithKey(this KeyValuePair kvp, Func keyTransformer) { return kvp.Transform((TKey key, TValue value) => keyTransformer(key), (TKey key, TValue value) => value); } public static KeyValuePair WithValue(this KeyValuePair kvp, Func valueTransformer) { return kvp.Transform((TKey key, TValue value) => key, (TKey key, TValue value) => valueTransformer(value)); } public static IEnumerable> SelectValues(this IEnumerable> keyValuePairs, Func valueTransformer) { return keyValuePairs.Select((KeyValuePair kvp) => kvp.WithValue(valueTransformer)); } public static string Format(this string s, params object[] args) { return string.Format(s, args); } public static bool IsOfType(this Type type, Type testTypeTrueIfNull, bool ignoreTestException = true) { if ((object)type == null) { return false; } if ((object)testTypeTrueIfNull == null || (object)testTypeTrueIfNull == typeof(object)) { return true; } try { return testTypeTrueIfNull.IsAssignableFromX(type); } catch { if (!ignoreTestException) { throw; } return false; } } public static int FindSequence(this IList containingSequence, IList sequence) { for (int i = 0; i <= containingSequence.Count - sequence.Count; i++) { if (containingSequence.GetRange(i, sequence.Count).SequenceRangeEquals(sequence, sequence.Count)) { return i; } } return -1; } public static TResult UsingReader(byte[] buffer, Func func) { return UsingReader(buffer, 0, buffer.Length, func); } public static TResult UsingReader(byte[] buffer, int offset, Func func) { return UsingReader(buffer, offset, buffer.Length - offset, func); } public static TResult UsingReader(byte[] buffer, int offset, int count, Func func) { BinaryReader arg = new BinaryReader(new MemoryStream(buffer, offset, count)); return func(arg); } public static TResult UsingDecompressingReader(byte[] buffer, Func func) { using MemoryStream innerStream = new MemoryStream(buffer); using ZStandardDecoder coder = new ZStandardDecoder(); using CoderStream stream = CoderStream.Create(innerStream, coder, encodeOrDecode: false); using BinaryReader arg = new BinaryReader(stream); return func(arg); } public static ArraySegment UsingCompressingWriter(Proc proc) { using MemoryStream memoryStream = new MemoryStream(); using (ZStandardEncoder coder = new ZStandardEncoder(6, 28)) { using CoderStream stream = CoderStream.Create(memoryStream, coder, encodeOrDecode: true); using BinaryWriter arg = new BinaryWriter(stream); proc(arg); } return memoryStream.GetAllBytes(); } public static ArraySegment UsingWriter(Proc proc) { MemoryStream stream = new MemoryStream(); BinaryWriter arg = new BinaryWriter(stream); proc(arg); return stream.GetAllBytes(); } public static void UsingWriter(byte[] buffer, Proc proc) { UsingWriter(buffer, 0, buffer.Length, proc); } public static void UsingWriter(byte[] buffer, int offset, Proc proc) { UsingWriter(buffer, offset, buffer.Length - offset, proc); } public static void UsingWriter(byte[] buffer, int offset, int count, Proc proc) { BinaryWriter arg = new BinaryWriter(new MemoryStream(buffer, offset, count)); proc(arg); } public static IEnumerable GetRange(this IList items, int offset, int count) { int lastIndex = offset + count; for (int i = offset; i < lastIndex; i++) { yield return items[i]; } } public static string GetInstanceUrlScheme(string instanceFingerprint) { return "sc-" + instanceFingerprint; } public static string? GetInstanceFingerprintFromUrlScheme(string? scheme) { return scheme?.SplitFirstNullable('-')?.IfNullable((KeyValuePair it) => it.Key == "sc")?.Pipe((KeyValuePair it) => it.Value); } public static ArraySegment Save(this IStreamSave streamSave) { MemoryStream stream = new MemoryStream(); streamSave.Save(stream); return stream.GetAllBytes(); } public static long GetContentSize(object content) { if (content is IStreamSaveLength) { return ((IStreamSaveLength)content).GetSaveLength(); } if (content is IStreamSave) { CountingStream countingStream = new CountingStream(); ((IStreamSave)content).Save(countingStream); return countingStream.Length; } if (content is byte[]) { return ((byte[])content).Length; } if (content is ArraySegment arraySegment) { return arraySegment.Count; } if (content != null) { throw new InvalidOperationException("Content is not valid"); } return 0L; } public static void WriteContent(object content, Stream stream) { if (content is IStreamSave) { ((IStreamSave)content).Save(stream); } else if (content is byte[]) { stream.WriteAllBytes((byte[])content); } else if (content is ArraySegment) { Write(stream, (ArraySegment)content); } else if (content != null) { throw new InvalidOperationException("Content is not valid"); } } public static ArraySegment ExtractContent(object content) { if (content is IStreamSave) { return ((IStreamSave)content).Save(); } if (content is byte[]) { return new ArraySegment((byte[])content); } if (content is ArraySegment) { return (ArraySegment)content; } if (content == null) { return new ArraySegment(EmptyArray()); } throw new InvalidOperationException("Content is not valid"); } public static void SaveWithSeekable(this IStreamSave streamSave, Stream finalStream) { MemoryStream memoryStream = new MemoryStream(); streamSave.Save(memoryStream); memoryStream.Position = 0L; memoryStream.WriteTo(finalStream); } public static T[] Extend(this T[] source, int extendCount) { T[] array = new T[source.Length + extendCount]; Array.Copy(source, array, source.Length); return array; } public static KeyValuePair SplitLastPathElement(this string s) { int num = s.Length - 1; int num2; while (true) { num2 = s.LastIndexOfAny(new char[2] { '/', '\\' }, num); if (num2 == -1) { return CreateKeyValuePair(string.Empty, s.Substring(0, num + 1)); } if (num2 != num) { break; } num = num2 - 1; } return CreateKeyValuePair(s.Substring(0, num2), s.Substring(num2 + 1, num - num2)); } public static string TrimEnd(this string s, string endingString) { if (s == null || !s.EndsWith(endingString)) { return s; } return s.Substring(0, s.Length - endingString.Length); } [Obsolete("Use SplitFirstNullable")] public static KeyValuePair SplitFirst(this string s, params char[] separators) { return s.SplitFirstNullable(separators) ?? CreateKeyValuePair(s, string.Empty); } public static KeyValuePair? SplitFirstNullable(this string s, params char[] separators) { int num = s.IndexOfAny(separators); if (num == -1) { return null; } return CreateKeyValuePair(s.Substring(0, num), s.Substring(num + 1)); } [Obsolete("Use SplitLastNullable")] public static KeyValuePair SplitLast(this string s, params char[] separators) { return s.SplitLastNullable(separators) ?? CreateKeyValuePair(string.Empty, s); } public static KeyValuePair? SplitLastNullable(this string s, params char[] separators) { int num = s.LastIndexOfAny(separators); if (num == -1) { return null; } return CreateKeyValuePair(s.Substring(0, num), s.Substring(num + 1)); } public static string[] SafeSplitAndTrim(this string s, params char[] separator) { return (from it in (s ?? string.Empty).Split(separator) select it.Trim()).WhereNotNullOrEmpty().ToArray(); } public static void Deconstruct(this KeyValuePair pair, out TKey key, out TValue value) { key = pair.Key; value = pair.Value; } public static IEnumerable ReadLines(this TextReader reader) { while (true) { string text = reader.ReadLine(); if (string.IsNullOrEmpty(text)) { break; } yield return text; } } public static CoreRect Union(this IEnumerable rectangles) { return rectangles.Aggregate(new CoreRect(0, 0, 0, 0), CoreRect.UnionUnlessNoArea); } public static T EnsureFlags(this T value, T flags, bool setOrUnset) where T : unmanaged { return ToUnmanaged(ToUInt64(value).EnsureFlags(ToUInt64(flags), (ulong)(setOrUnset ? (-1) : 0))); } public static ulong EnsureFlags(this ulong value, ulong mask, ulong flags) { return (value & ~mask) | (flags & mask); } public static T EnsureFlags(this T value, T mask, T flags) where T : unmanaged { return ToUnmanaged(ToUInt64(value).EnsureFlags(ToUInt64(mask), ToUInt64(flags))); } public static T EnsureFlagsIf(this T value, T mask, T flags, bool shouldEnsure) where T : unmanaged { if (shouldEnsure) { return value.EnsureFlags(mask, flags); } return value; } public static bool AreFlagsSet(this T value, T flags) where T : unmanaged { ulong num = ToUInt64(value); ulong num2 = ToUInt64(flags); return (num & num2) == num2; } public static bool AreFlagsSet(this T value, params T[] flags) where T : unmanaged { ulong num = ToUInt64(value); ulong num2 = flags.Select(ToUInt64).Union(); return (num & num2) == num2; } public static bool AreAnyFlagsSet(this T value, T flags) where T : unmanaged { ulong num = ToUInt64(value); ulong num2 = ToUInt64(flags); return (num & num2) != 0; } public static bool AreAnyFlagsSet(this T value, params T[] flags) where T : unmanaged { ulong num = ToUInt64(value); ulong num2 = flags.Select(ToUInt64).Union(); return (num & num2) != 0; } public static IEnumerable GetSetFlags(this T value) where T : unmanaged { ulong ulongValue = ToUInt64(value); int i = 0; while (i < 64 && ulongValue != 0L) { if ((ulongValue & 1) != 0L) { yield return ToUnmanaged((ulong)(1L << i)); } i++; ulongValue >>= 1; } } public static T Union(this IEnumerable items) where T : unmanaged { return ToUnmanaged(items.Select(ToUInt64).Union()); } public static ulong Union(this IEnumerable flags) { ulong num = 0uL; foreach (ulong flag in flags) { num |= flag; } return num; } public static T Execute(this Func @this) { return @this(); } public static object ChangeType(this object value, Type toType) { if ((object)toType == typeof(Guid) && value is string g) { return new Guid(g); } if (toType.IsEnumX()) { return Enum.ToObject(toType, Convert.ToInt64(value)); } return Convert.ChangeType(value, toType); } public static T ChangeType(this object value) { return (T)value.ChangeType(typeof(T)); } public unsafe static ulong ToUInt64(T @this) where T : unmanaged { return sizeof(T) switch { 1 => *(byte*)(&@this), 2 => *(ushort*)(&@this), 4 => *(uint*)(&@this), 8 => *(ulong*)(&@this), _ => throw new ArgumentOutOfRangeException(), }; } public unsafe static T ToUnmanaged(ulong @this) where T : unmanaged { return *(T*)(&@this); } public static string FlagsToString(this T @this) where T : unmanaged { ulong num = 0uL; ulong num2 = ToUInt64(@this); StringBuilder stringBuilder = new StringBuilder(); foreach (var (value, num3) in from it in GetEnumNamesAndValues() select (Name: it.Name, Value: ToUInt64(it.Value)) into it where typeof(T).GetField(it.Name).GetCustomAttribute() == null orderby it.Value descending select it) { if ((num2 & num3) == num3 && (num & num3) == 0L && (num3 != 0L || num == 0L)) { num |= num3; stringBuilder.AppendIfNotEmpty(", "); stringBuilder.Append(value); } } if (num2 != num) { stringBuilder.AppendIfNotEmpty(", "); stringBuilder.Append(num2 & ~num); } return stringBuilder.ToString(); } public static ulong GetValueAtOffset(this T @this, int offset, int bitWidth) where T : unmanaged { return (ulong)((1L << bitWidth) - 1) & (ToUInt64(@this) >> offset); } public static T[] EmptyArray() { return new T[0]; } public static void AppendIfNotEmpty(this StringBuilder @this, string value) { if (@this.Length != 0) { @this.Append(value); } } public static string EnsureNotOverLength(this string s, int length, bool shouldUseEllipsis = false) { if (s.Length <= length) { return s; } string text = s.Substring(0, length).TrimEnd(new char[0]); if (shouldUseEllipsis) { text = ((text.Length >= length) ? (text.Substring(0, length - 1).TrimEnd(new char[0]) + "…") : (text + "…")); } return text; } public static void DisposeQuietly(this IEnumerable items) where T : IDisposable { foreach (T item in items.SafeEnumerate()) { item.DisposeQuietly(); } } public static T WithMeasuringMillisecondsTaken(Func func, Proc<(T Result, long MillisecondsTaken)> timeRecordingProc) { long millisecondCount = Singleton.Instance.GetMillisecondCount(); T val = func(); timeRecordingProc((val, Singleton.Instance.GetMillisecondCount() - millisecondCount)); return val; } public static uint CalculateCrc32Zip(ArraySegment bytes) { return CalculateCrc32(bytes, 79764919u, uint.MaxValue, refin: true, refout: true, uint.MaxValue); } public static uint CalculateCrc32Posix(ArraySegment bytes) { return CalculateCrc32(bytes, 79764919u, 0u, refin: false, refout: false, uint.MaxValue); } private static uint CalculateCrc32(ArraySegment p, uint poly, uint init, bool refin, bool refout, uint xorout) { int num = 32; uint num2 = (uint)(((1 << num - 1) - 1 << 1) | 1); uint num3 = (uint)(1 << num - 1); uint num4 = init; for (uint num5 = 0u; num5 < num; num5++) { uint num6 = num4 & 1; if (num6 != 0) { num4 ^= poly; } num4 >>= 1; if (num6 != 0) { num4 |= num3; } } num4 = num4; for (uint num5 = 0u; num5 < p.Count; num5++) { uint num7 = p.Array[p.Offset + num5]; if (refin) { num7 = ReflectCrc(num7, 8); } for (uint num8 = 128u; num8 != 0; num8 >>= 1) { uint num6 = num4 & num3; num4 <<= 1; if ((num7 & num8) != 0) { num4 |= 1; } if (num6 != 0) { num4 ^= poly; } } } for (uint num5 = 0u; num5 < num; num5++) { uint num6 = num4 & num3; num4 <<= 1; if (num6 != 0) { num4 ^= poly; } } if (refout) { num4 = ReflectCrc(num4, num); } num4 ^= xorout; return num4 & num2; } private static uint ReflectCrc(uint crc, int bitnum) { uint num = 1u; uint num2 = 0u; for (uint num3 = (uint)(1 << bitnum - 1); num3 != 0; num3 >>= 1) { if ((crc & num3) != 0) { num2 |= num; } num <<= 1; } return num2; } public static bool IsPhotographic(this ScreenCodecID codecID) { if (codecID == ScreenCodecID.WebP) { return true; } return false; } public static bool IsLocal(this ScreenCodecID codecID) { if (codecID == ScreenCodecID.TestCoder_ZStandard) { return true; } return false; } public static double DistanceBetween(double x1, double y1, double x2, double y2) { return Math.Sqrt(Math.Pow(x2 - x1, 2.0) + Math.Pow(y2 - y1, 2.0)); } public static void SendFeedback(string rating, string comments, string sourceHint) { using WebClient webClient = new WebClient(); webClient.UploadValues("https://feedback.screenconnect.com/Feedback.axd", new NameValueCollection { { "Rating", rating }, { "Comments", comments }, { "SourceHint", sourceHint } }); } public static void SendFeedback(string rating, string comments, string sourceHint, string email) { string comments2 = "COMMENTS: " + comments + " " + Environment.NewLine + " CONTACT: " + (email ?? "none provided"); SendFeedback(rating, comments2, sourceHint); } public static ScreenCodecID[] GetScreenCodecIDs(ScreenCodecID screenCodecID, ScreenCodecID alternateScreenCodecID) { if (screenCodecID != ScreenCodecID.Unknown) { if (alternateScreenCodecID != ScreenCodecID.Grayscale_DeflateDefault_ZlibWrapper && alternateScreenCodecID != ScreenCodecID.Unknown) { return new ScreenCodecID[2] { screenCodecID, alternateScreenCodecID }; } return new ScreenCodecID[1] { screenCodecID }; } return null; } public static bool IsAllowedToRespondToRequest(CredentialProviderScenarioType credentialProviderScenarioType, SessionConnectionInfoAttributes connectionAttributes) { return credentialProviderScenarioType switch { CredentialProviderScenarioType.Elevation => connectionAttributes.AreFlagsSet(SessionConnectionInfoAttributes.CanRespondToElevationRequest), CredentialProviderScenarioType.AdministrativeLogon => connectionAttributes.AreFlagsSet(SessionConnectionInfoAttributes.CanRespondToAdministrativeLogonRequest), _ => false, }; } public static void TrySubscribeToLogAppDomainException() { AppDomain.CurrentDomain.UnhandledException += delegate(object o, UnhandledExceptionEventArgs e) { TryWriteExceptionToEventLog(e.ExceptionObject, 1); }; } public static void TryWriteExceptionToEventLog(object exceptionObject, int eventID) { TryWriteErrorMessageToEventLog(exceptionObject.ToString(), eventID); } public static void TryWriteErrorMessageToEventLog(string errorMessage, int eventID) { Try(delegate { EventLog.WriteEntry(GetEventLogSourceName(), GetEventLogFullMessage(errorMessage), (EventLogEntryType)1, eventID); }); } public static void TryWriteInformationToEventLog(string message, int eventID) { Try(delegate { EventLog.WriteEntry(GetEventLogSourceName(), GetEventLogFullMessage(message), (EventLogEntryType)4, eventID); }); } public static string GetEventLogFullMessage(string message) { string[] commandLineArgs = Environment.GetCommandLineArgs(); StringWriter stringWriter = new StringWriter(); stringWriter.WriteLine(message); stringWriter.WriteLine(); stringWriter.WriteLine($"Version: {Constants.ProductVersion}"); stringWriter.WriteLine("Executable Path: " + commandLineArgs[0]); return stringWriter.ToString(); } public static string GetEventLogSourceName() { return "ScreenConnect"; } public static IDictionary? GetAnonymousDictionaryType(TKey key, TValue value) where TKey : notnull { return null; } public static U SafeNavLocked(this T objectToLock, Func func) { lock ((object)objectToLock) { return func(objectToLock); } } public static void SafeDoLocked(this T objectToLock, Proc proc) { lock ((object)objectToLock) { proc(objectToLock); } } public static bool None(this IEnumerable source, Func predicate) { return !source.Any(predicate); } public static int CopyTo(this IEnumerable items, IList destination, int index) { int num = index; foreach (T item in items) { destination[num++] = item; } return num - index; } public static TResult[] ToArray(this IList source, Func selector) { selector.AssertArgumentNonNull("selector"); int count = source.Count; TResult[] array = new TResult[count]; for (int i = 0; i < count; i++) { array[i] = selector(source[i], i); } return array; } public static void ForEach2(this IEnumerable source, Proc proc) { if (source == null) { return; } foreach (TSource item in source) { proc(item); } } public static void ForEach2(this IEnumerable source, Proc proc) { int num = 0; if (source == null) { return; } foreach (TSource item in source) { proc(item, num++); } } public static void Clear(this T[] array) { Array.Clear(array, 0, array.Length); } public static Queue ToQueue(this IEnumerable @this) { return new Queue(@this); } public static double NextDouble(this Random @this, double baseValue, double variance) { if (!(variance < 0.0)) { if (variance == 0.0) { return baseValue; } return baseValue + baseValue * variance * 2.0 * (@this.NextDouble() - 0.5); } throw new ArgumentOutOfRangeException("variance"); } public static byte[] NextBytes(this Random @this, int count) { byte[] array = new byte[count]; @this.NextBytes(array); return array; } public static uint NextUInt32(this Random @this) { return BitConverter.ToUInt32(@this.NextBytes(4), 0); } public static uint NextUInt32(this Random @this, uint minValueInclusive, uint maxValueExclusive) { return minValueInclusive + (uint)(@this.NextDouble() * (double)(maxValueExclusive - minValueInclusive)); } public static ulong NextUInt64(this Random @this) { return BitConverter.ToUInt64(@this.NextBytes(8), 0); } public static ulong NextUInt64(this Random @this, ulong minValueInclusive, ulong maxValueExclusive) { return minValueInclusive + (ulong)(@this.NextDouble() * (double)(maxValueExclusive - minValueInclusive)); } public static IntPtr NextIntPtr(this Random @this) { if (IntPtr.Size != 4) { return new IntPtr((long)@this.NextUInt64()); } return new IntPtr((int)@this.NextUInt32()); } public static IntPtr NextIntPtr(this Random @this, IntPtr minValueInclusive, IntPtr maxValueExclusive) { if (IntPtr.Size != 4) { return new IntPtr((long)@this.NextUInt64((ulong)minValueInclusive.ToInt64(), (ulong)maxValueExclusive.ToInt64())); } return new IntPtr((int)@this.NextUInt32((uint)minValueInclusive.ToInt32(), (uint)maxValueExclusive.ToInt32())); } public static IntPtr AlignTo(this IntPtr @this, uint alignment, bool alignUpOrDown = false) { return new IntPtr(checked(@this.ToInt64() + (alignUpOrDown ? (alignment - 1) : 0)) / alignment * alignment); } public static IntPtr Add(this IntPtr @this, long value) { return new IntPtr(@this.ToInt64() + value); } public static IntPtr Add(this IntPtr @this, IntPtr value) { return new IntPtr(@this.ToInt64() + value.ToInt64()); } public static IntPtr Subtract(this IntPtr @this, long value) { return new IntPtr(@this.ToInt64() - value); } public static IntPtr Subtract(this IntPtr @this, IntPtr value) { return new IntPtr(@this.ToInt64() - value.ToInt64()); } public static T[] ToArray(this IEnumerable @this, int count) { T[] array = new T[count]; int num = 0; foreach (T item in @this.Take(count)) { array[num++] = item; } return array; } public static U[] SelectToArray(this ICollection @this, Func selector) { return @this.SelectToCollection(selector).ToArray(); } public static TResult[] SelectToArray(this IGrouping @this, Func selector) { return @this.SelectToArrayInternal(selector); } private static TResult[] SelectToArrayInternal(this IEnumerable @this, Func selector) { if (!(@this is ICollection collection)) { return @this.Select(selector).ToArray(); } return collection.SelectToArray(selector); } public static ICollection AsCollection(this IEnumerable @this) { return (@this as ICollection) ?? @this.ToList(); } public static IList AsList(this IEnumerable @this) { return (@this as IList) ?? @this.ToList(); } public static IEnumerable<(T1, T2)> Zip(this IEnumerable items1, IEnumerable items2) { return items1.Zip(items2, (T1 item1, T2 item2) => (item1: item1, item2: item2)); } public static IEnumerable InsertAfter(this IEnumerable items, Func creator, Func predicate) { foreach (T item in items) { yield return item; if (predicate(item)) { yield return creator(); } } } public static string SafeSubstring(this string @this, long startIndex, long length) { int num = Math.Max(0, (int)startIndex); int num2 = Math.Min(@this.Length, (int)startIndex + (int)length); if (num2 > num) { return @this.Substring(num, num2 - num); } return string.Empty; } public static string MaskFull(this string @this) { return new string('*', @this.Length); } public static string MaskRear(this string @this, int visibleCharacterCount) { if (@this.Length > visibleCharacterCount) { return @this.Substring(0, visibleCharacterCount) + new string('*', @this.Length - visibleCharacterCount); } return @this; } public static string MaskFront(this string @this, int visibleCharacterCount) { if (@this.Length > visibleCharacterCount) { return new string('*', @this.Length - visibleCharacterCount) + @this.Substring(@this.Length - visibleCharacterCount, visibleCharacterCount); } return @this; } public static ICollection SelectToCollection(this ICollection @this, Func selector) { return new DeferredCollection>(@this, selector); } public static IList SelectToList(this IList @this, Func selector, bool shouldDeferSelection = false) { if (!shouldDeferSelection) { return @this.SelectToArray(selector); } return new DeferredList>(@this, selector); } public static ICollection Cast(this ICollection @this) { return new CastedCollection(@this); } public static IList Cast(this IList @this) { return new CastedList(@this); } public static IList ToSublist(this IList @this, int offset, int count) { return new Sublist(@this, offset, count); } public static string GetStackTraceString(int frameCount = 1, int skipFrameCount = 1) { StackTrace trace = new StackTrace(skipFrameCount + 1, fNeedFileInfo: true); return (from index in Enumerable.Range(0, frameCount) let frame = trace.GetFrame(index) let method = frame.GetMethod() select string.Format("{0}.{1} {2}:{3}", new object[4] { method.DeclaringType, method.Name, frame.GetFileName(), frame.GetFileLineNumber() })).Join("; "); } public static Uri AddUserInfo(this Uri uri, string userName, string password) { string userName2 = UrlEncode(userName); string password2 = UrlEncode(password); return new UriBuilder(uri) { UserName = userName2, Password = password2 }.Uri; } public static T PerformOperationWithRetry(Func func, OperationRetryOptions operationRetryOptions = default(OperationRetryOptions)) { int num = 0; while (true) { try { return func(); } catch (Exception ex) { TypeTrace.TraceException(ex); if (operationRetryOptions.RetryCount != -1 && num >= operationRetryOptions.RetryCount) { goto IL_0040; } Func? transientExceptionChecker = operationRetryOptions.TransientExceptionChecker; if (transientExceptionChecker != null && !transientExceptionChecker(ex)) { goto IL_0040; } if (operationRetryOptions.SleepMillisecondsBetweenRetries != 0) { Thread.Sleep(operationRetryOptions.SleepMillisecondsBetweenRetries); } goto end_IL_000c; IL_0040: throw; end_IL_000c:; } num++; } } public static void PerformOperationWithRetry(Proc proc, OperationRetryOptions operationRetryOptions = default(OperationRetryOptions)) { PerformOperationWithRetry(proc.ProcToDefaultFunc(), operationRetryOptions); } public static void Copy(this IBlittable source, CoreRect sourceBounds, IBlittable destination, CoreRect destinationBounds) { source.PerformWithBits(sourceBounds, (IBitmapData sourceBits) => destination.PerformWithBits(destinationBounds, (IBitmapData bitmapBits) => sourceBits.CopyPixels(bitmapBits))); } public static void WriteSizePrefixedBytes(this BinaryWriter @this, byte[] bytes) { @this.WriteSizePrefixedBytes(bytes.ToArraySegment()); } public static void WriteSizePrefixedBytes(this BinaryWriter @this, ArraySegment segment) { @this.Write(segment.Count); @this.Write(segment.Array, segment.Offset, segment.Count); } public static byte[] ReadSizePrefixedBytes(this BinaryReader @this) { return @this.ReadBytes(@this.ReadInt32()); } public static T Min(T x, T y) where T : IComparable { if (x.CompareTo(y) >= 0) { return y; } return x; } public static T Max(T x, T y) where T : IComparable { if (x.CompareTo(y) <= 0) { return y; } return x; } public static T Clamp(T value, T min, T max) where T : IComparable { if (value.CompareTo(min) >= 0) { if (value.CompareTo(max) <= 0) { return value; } return max; } return min; } public static bool WaitOneSafe(this WaitHandle waitHandle, long waitMilliseconds, long fromMillisecondCount = -1L) { long num = ((fromMillisecondCount < 0) ? waitMilliseconds : Math.Min(waitMilliseconds - (Singleton.Instance.GetMillisecondCount() - fromMillisecondCount), waitMilliseconds)); if (num <= 0) { return false; } return Singleton.Instance.WaitOneSafe(waitHandle, num); } }