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