From 39d536b0c82bb6ec486c2f3993d1a9bbab20587a Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Sun, 5 Jan 2020 13:15:50 -0600 Subject: [PATCH] Minor changes for possibly improved .NET 3 support --- IPA.Loader/Loader/PluginExecutor.cs | 1 + IPA.Loader/Loader/PluginMetadata.cs | 3 + Net3-Proxy/Extensions.cs | 364 ++++++++++++++-------------- Net3-Proxy/IReadOnlyList.cs | 58 ++--- Net3-Proxy/Path.cs | 112 +++++---- 5 files changed, 270 insertions(+), 268 deletions(-) diff --git a/IPA.Loader/Loader/PluginExecutor.cs b/IPA.Loader/Loader/PluginExecutor.cs index e5196679..c3b74f83 100644 --- a/IPA.Loader/Loader/PluginExecutor.cs +++ b/IPA.Loader/Loader/PluginExecutor.cs @@ -10,6 +10,7 @@ using Task = System.Threading.Tasks.Task; using TaskEx = System.Threading.Tasks.Task; #endif #if NET3 +using System.Threading.Tasks; using Net3_Proxy; using Path = Net3_Proxy.Path; using File = Net3_Proxy.File; diff --git a/IPA.Loader/Loader/PluginMetadata.cs b/IPA.Loader/Loader/PluginMetadata.cs index c6a4f2fa..1f6deacd 100644 --- a/IPA.Loader/Loader/PluginMetadata.cs +++ b/IPA.Loader/Loader/PluginMetadata.cs @@ -5,6 +5,9 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using Version = SemVer.Version; +#if NET3 +using Net3_Proxy; +#endif namespace IPA.Loader { diff --git a/Net3-Proxy/Extensions.cs b/Net3-Proxy/Extensions.cs index 9dfd6653..56f92a03 100644 --- a/Net3-Proxy/Extensions.cs +++ b/Net3-Proxy/Extensions.cs @@ -1,182 +1,182 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security.Permissions; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Net3_Proxy -{ - public static class Extensions - { - public static T GetCustomAttribute(this ParameterInfo element) where T : Attribute - => (T)GetCustomAttribute(element, typeof(T)); - - public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType) - => Attribute.GetCustomAttribute(element, attributeType); - - public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType) - => Attribute.GetCustomAttribute(element, attributeType); - - public static StringBuilder Clear(this StringBuilder sb) - => sb.Remove(0, sb.Length); - - public static bool HasFlag(this E e, E o) where E : Enum - { - var ei = Convert.ToUInt64(e); - var oi = Convert.ToUInt64(o); - return (ei & oi) == oi; - } - } - - public static class DirectoryInfoExtensions - { - public static IEnumerable EnumerateFiles(this DirectoryInfo self) - { - return self.EnumerateFiles("*", SearchOption.TopDirectoryOnly); - } - - public static IEnumerable EnumerateFiles(this DirectoryInfo self, string searchPattern) - { - return self.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly); - } - - public static IEnumerable EnumerateFiles(this DirectoryInfo self, string searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - { - throw new ArgumentNullException("searchPattern"); - } - return CreateEnumerateFilesIterator(self, searchPattern, searchOption); - } - - - private static IEnumerable CreateEnumerateFilesIterator(DirectoryInfo self, string searchPattern, SearchOption searchOption) - { - foreach (string fileName in Directory.GetFiles(self.FullName, searchPattern, searchOption)) - yield return new FileInfo(fileName); - yield break; - } - } - - public static class StreamExtensions - { - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task CopyToAsync(this Stream src, Stream destination) => CopyToAsync(src, destination, 81920); - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize) => CopyToAsync(src, destination, bufferSize, CancellationToken.None); - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken) - { - if (destination == null) - { - throw new ArgumentNullException("destination"); - } - if (bufferSize <= 0) - { - throw new ArgumentOutOfRangeException("bufferSize", "Positive number required."); - } - if (!src.CanRead && !src.CanWrite) - { - throw new ObjectDisposedException(null, "Cannot access a closed Stream."); - } - if (!destination.CanRead && !destination.CanWrite) - { - throw new ObjectDisposedException("destination", "Cannot access a closed Stream."); - } - if (!src.CanRead) - { - throw new NotSupportedException("Stream does not support reading."); - } - if (!destination.CanWrite) - { - throw new NotSupportedException("Stream does not support writing."); - } - return CopyToAsyncInternal(src, destination, bufferSize, cancellationToken); - } - - private static async Task CopyToAsyncInternal(Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken) - { - byte[] buffer = new byte[bufferSize]; - int bytesRead; - while ((bytesRead = await src.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) != 0) - { - await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken); - } - } - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task ReadAsync(this Stream src, byte[] buffer, int offset, int count) - { - return ReadAsync(src, buffer, offset, count, CancellationToken.None); - } - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task ReadAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - if (!cancellationToken.IsCancellationRequested) - { - return BeginEndReadAsync(src, buffer, offset, count); - } - return new Task(() => 0, cancellationToken); - } - - private static Task BeginEndReadAsync(Stream src, byte[] buffer, int offset, int count) - => Task.Factory.FromAsync( - (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) => - src.BeginRead(buffer_, offset_, count_, callback, state), - (IAsyncResult asyncResult) => src.EndRead(asyncResult), - buffer, - offset, - count, - new object()); - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count) - { - return WriteAsync(src, buffer, offset, count, CancellationToken.None); - } - - [ComVisible(false)] - [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] - public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - if (!cancellationToken.IsCancellationRequested) - { - return BeginEndWriteAsync(src, buffer, offset, count); - } - return new Task(() => 0, cancellationToken); - } - - private static Task BeginEndWriteAsync(Stream src, byte[] buffer, int offset, int count) - => Task.Factory.FromAsync( - (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) => - src.BeginWrite(buffer_, offset_, count_, callback, state), - (IAsyncResult asyncResult) => src.EndWrite(asyncResult), - buffer, - offset, - count, - new object()); - - } - - public static class SemaphoreSlimExtesnions - { // TODO: finish the WaitAsync members - /*public static Task WaitAsync(this SemaphoreSlim self) - { - return null; - }*/ - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Net3_Proxy +{ + public static class Extensions + { + public static T GetCustomAttribute(this ParameterInfo element) where T : Attribute + => (T)GetCustomAttribute(element, typeof(T)); + + public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType) + => Attribute.GetCustomAttribute(element, attributeType); + + public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType) + => Attribute.GetCustomAttribute(element, attributeType); + + public static StringBuilder Clear(this StringBuilder sb) + => sb.Remove(0, sb.Length); + + public static bool HasFlag(this E e, E o) where E : Enum + { + var ei = Convert.ToUInt64(e); + var oi = Convert.ToUInt64(o); + return (ei & oi) == oi; + } + } + + public static class DirectoryInfoExtensions + { + public static IEnumerable EnumerateFiles(this DirectoryInfo self) + { + return self.EnumerateFiles("*", SearchOption.TopDirectoryOnly); + } + + public static IEnumerable EnumerateFiles(this DirectoryInfo self, string searchPattern) + { + return self.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly); + } + + public static IEnumerable EnumerateFiles(this DirectoryInfo self, string searchPattern, SearchOption searchOption) + { + if (searchPattern == null) + { + throw new ArgumentNullException(nameof(searchPattern)); + } + return CreateEnumerateFilesIterator(self, searchPattern, searchOption); + } + + + private static IEnumerable CreateEnumerateFilesIterator(DirectoryInfo self, string searchPattern, SearchOption searchOption) + { + foreach (string fileName in Directory.GetFiles(self.FullName, searchPattern, searchOption)) + yield return new FileInfo(fileName); + yield break; + } + } + + public static class StreamExtensions + { + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task CopyToAsync(this Stream src, Stream destination) => CopyToAsync(src, destination, 81920); + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize) => CopyToAsync(src, destination, bufferSize, CancellationToken.None); + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken) + { + if (destination == null) + { + throw new ArgumentNullException(nameof(destination)); + } + if (bufferSize <= 0) + { + throw new ArgumentOutOfRangeException(nameof(bufferSize), "Positive number required."); + } + if (!src.CanRead && !src.CanWrite) + { + throw new ObjectDisposedException(null, "Cannot access a closed Stream."); + } + if (!destination.CanRead && !destination.CanWrite) + { + throw new ObjectDisposedException("destination", "Cannot access a closed Stream."); + } + if (!src.CanRead) + { + throw new NotSupportedException("Stream does not support reading."); + } + if (!destination.CanWrite) + { + throw new NotSupportedException("Stream does not support writing."); + } + return CopyToAsyncInternal(src, destination, bufferSize, cancellationToken); + } + + private static async Task CopyToAsyncInternal(Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken) + { + byte[] buffer = new byte[bufferSize]; + int bytesRead; + while ((bytesRead = await src.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) != 0) + { + await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken); + } + } + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task ReadAsync(this Stream src, byte[] buffer, int offset, int count) + { + return ReadAsync(src, buffer, offset, count, CancellationToken.None); + } + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task ReadAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (!cancellationToken.IsCancellationRequested) + { + return BeginEndReadAsync(src, buffer, offset, count); + } + return new Task(() => 0, cancellationToken); + } + + private static Task BeginEndReadAsync(Stream src, byte[] buffer, int offset, int count) + => Task.Factory.FromAsync( + (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) => + src.BeginRead(buffer_, offset_, count_, callback, state), + (IAsyncResult asyncResult) => src.EndRead(asyncResult), + buffer, + offset, + count, + new object()); + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count) + { + return WriteAsync(src, buffer, offset, count, CancellationToken.None); + } + + [ComVisible(false)] + [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)] + public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (!cancellationToken.IsCancellationRequested) + { + return BeginEndWriteAsync(src, buffer, offset, count); + } + return new Task(() => 0, cancellationToken); + } + + private static Task BeginEndWriteAsync(Stream src, byte[] buffer, int offset, int count) + => Task.Factory.FromAsync( + (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) => + src.BeginWrite(buffer_, offset_, count_, callback, state), + (IAsyncResult asyncResult) => src.EndWrite(asyncResult), + buffer, + offset, + count, + new object()); + + } + + public static class SemaphoreSlimExtesnions + { // TODO: finish the WaitAsync members + /*public static Task WaitAsync(this SemaphoreSlim self) + { + return null; + }*/ + } +} diff --git a/Net3-Proxy/IReadOnlyList.cs b/Net3-Proxy/IReadOnlyList.cs index c1690ac0..b32792ea 100644 --- a/Net3-Proxy/IReadOnlyList.cs +++ b/Net3-Proxy/IReadOnlyList.cs @@ -1,29 +1,29 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Net3_Proxy -{ - - public class IReadOnlyList : IEnumerable - { - private IList list; - - private IReadOnlyList(IList lst) - { - list = lst; - } - - public IEnumerator GetEnumerator() => list.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)list).GetEnumerator(); - - public int Count => list.Count; - - public T this[int index] => list[index]; - - public static implicit operator IReadOnlyList(List list) => new IReadOnlyList(list); - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Net3_Proxy +{ + + public class IReadOnlyList : IEnumerable + { + private IList list; + + private IReadOnlyList(IList lst) + { + list = lst; + } + + public IEnumerator GetEnumerator() => list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)list).GetEnumerator(); + + public int Count => list.Count; + + public T this[int index] => list[index]; + + public static implicit operator IReadOnlyList(List list) => new IReadOnlyList(list); + } +} diff --git a/Net3-Proxy/Path.cs b/Net3-Proxy/Path.cs index e645bc6b..c6db8dd9 100644 --- a/Net3-Proxy/Path.cs +++ b/Net3-Proxy/Path.cs @@ -1,57 +1,55 @@ -using System; -using System.Linq; -using OgPath = System.IO.Path; - -namespace Net3_Proxy -{ - public static class Path - { - internal static void Validate(string path) - { - Path.Validate(path, "path"); - } - - internal static void Validate(string path, string parameterName) - { - if (path == null) - { - throw new ArgumentNullException(parameterName); - } - if (Utils.IsNullOrWhiteSpace(path)) - { - throw new ArgumentException("Path is empty"); - } - if (path.IndexOfAny(OgPath.GetInvalidPathChars()) != -1) - { - throw new ArgumentException("Path contains invalid chars"); - } - if (Environment.OSVersion.Platform < PlatformID.Unix) - { - int num = path.IndexOf(':'); - if (num >= 0 && num != 1) - { - throw new ArgumentException(parameterName); - } - } - } - - public static string GetFullPath(string p) => OgPath.GetFullPath(p); - public static string GetFileNameWithoutExtension(string p) => OgPath.GetFileNameWithoutExtension(p); - public static string GetFileName(string p) => OgPath.GetFileName(p); - public static string GetDirectoryName(string p) => OgPath.GetDirectoryName(p); - - public static string Combine(string s) => s; - public static string Combine(string s, string d) => OgPath.Combine(s, d); - public static string Combine(string s, string d, string f) => Combine(s, Combine(d, f)); - public static string Combine(string s, string d, string f, string g) => Combine(Combine(s, d), Combine(f, g)); - public static string Combine(params string[] parts) - { - if (parts.Length == 0) return ""; - var begin = parts[0]; - foreach (var p in parts.Skip(1)) - begin = Combine(begin, p); - return begin; - } - public static char PathSeparator => OgPath.PathSeparator; - } -} +using System; +using System.Linq; +using OgPath = System.IO.Path; + +namespace Net3_Proxy +{ + public static class Path + { + internal static void Validate(string path) + => Validate(path, nameof(path)); + + internal static void Validate(string path, string parameterName) + { + if (path == null) + { + throw new ArgumentNullException(parameterName); + } + if (Utils.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException("Path is empty"); + } + if (path.IndexOfAny(OgPath.GetInvalidPathChars()) != -1) + { + throw new ArgumentException("Path contains invalid chars"); + } + if (Environment.OSVersion.Platform < PlatformID.Unix) + { + int num = path.IndexOf(':'); + if (num >= 0 && num != 1) + { + throw new ArgumentException(parameterName); + } + } + } + + public static string GetFullPath(string p) => OgPath.GetFullPath(p); + public static string GetFileNameWithoutExtension(string p) => OgPath.GetFileNameWithoutExtension(p); + public static string GetFileName(string p) => OgPath.GetFileName(p); + public static string GetDirectoryName(string p) => OgPath.GetDirectoryName(p); + + public static string Combine(string s) => s; + public static string Combine(string s, string d) => OgPath.Combine(s, d); + public static string Combine(string s, string d, string f) => Combine(s, Combine(d, f)); + public static string Combine(string s, string d, string f, string g) => Combine(Combine(s, d), Combine(f, g)); + public static string Combine(params string[] parts) + { + if (parts.Length == 0) return ""; + var begin = parts[0]; + foreach (var p in parts.Skip(1)) + begin = Combine(begin, p); + return begin; + } + public static char PathSeparator => OgPath.PathSeparator; + } +}