Browse Source

Minor changes for possibly improved .NET 3 support

4.0.0-beta
Anairkoen Schno 5 years ago
parent
commit
39d536b0c8
5 changed files with 270 additions and 268 deletions
  1. +1
    -0
      IPA.Loader/Loader/PluginExecutor.cs
  2. +3
    -0
      IPA.Loader/Loader/PluginMetadata.cs
  3. +182
    -182
      Net3-Proxy/Extensions.cs
  4. +29
    -29
      Net3-Proxy/IReadOnlyList.cs
  5. +55
    -57
      Net3-Proxy/Path.cs

+ 1
- 0
IPA.Loader/Loader/PluginExecutor.cs View File

@ -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;


+ 3
- 0
IPA.Loader/Loader/PluginMetadata.cs View File

@ -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
{


+ 182
- 182
Net3-Proxy/Extensions.cs View File

@ -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<T>(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<E>(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<FileInfo> EnumerateFiles(this DirectoryInfo self)
{
return self.EnumerateFiles("*", SearchOption.TopDirectoryOnly);
}
public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern)
{
return self.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
}
public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
{
throw new ArgumentNullException("searchPattern");
}
return CreateEnumerateFilesIterator(self, searchPattern, searchOption);
}
private static IEnumerable<FileInfo> 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<int> 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<int> ReadAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested)
{
return BeginEndReadAsync(src, buffer, offset, count);
}
return new Task<int>(() => 0, cancellationToken);
}
private static Task<int> BeginEndReadAsync(Stream src, byte[] buffer, int offset, int count)
=> Task<int>.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<int>(() => 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<T>(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<E>(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<FileInfo> EnumerateFiles(this DirectoryInfo self)
{
return self.EnumerateFiles("*", SearchOption.TopDirectoryOnly);
}
public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern)
{
return self.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
}
public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
{
throw new ArgumentNullException(nameof(searchPattern));
}
return CreateEnumerateFilesIterator(self, searchPattern, searchOption);
}
private static IEnumerable<FileInfo> 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<int> 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<int> ReadAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested)
{
return BeginEndReadAsync(src, buffer, offset, count);
}
return new Task<int>(() => 0, cancellationToken);
}
private static Task<int> BeginEndReadAsync(Stream src, byte[] buffer, int offset, int count)
=> Task<int>.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<int>(() => 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;
}*/
}
}

+ 29
- 29
Net3-Proxy/IReadOnlyList.cs View File

@ -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<T> : IEnumerable<T>
{
private IList<T> list;
private IReadOnlyList(IList<T> lst)
{
list = lst;
}
public IEnumerator<T> 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<T>(List<T> list) => new IReadOnlyList<T>(list);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Net3_Proxy
{
public class IReadOnlyList<T> : IEnumerable<T>
{
private IList<T> list;
private IReadOnlyList(IList<T> lst)
{
list = lst;
}
public IEnumerator<T> 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<T>(List<T> list) => new IReadOnlyList<T>(list);
}
}

+ 55
- 57
Net3-Proxy/Path.cs View File

@ -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;
}
}

Loading…
Cancel
Save