You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
8.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Runtime.InteropServices;
  7. using System.Security.Permissions;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. namespace Net3_Proxy
  12. {
  13. public static class Extensions
  14. {
  15. public static T GetCustomAttribute<T>(this ParameterInfo element) where T : Attribute
  16. => (T)GetCustomAttribute(element, typeof(T));
  17. public static T GetCustomAttribute<T>(this MethodInfo element) where T : Attribute
  18. => (T)GetCustomAttribute(element, typeof(T));
  19. public static T GetCustomAttribute<T>(this ConstructorInfo element) where T : Attribute
  20. => (T)GetCustomAttribute(element, typeof(T));
  21. public static T GetCustomAttribute<T>(this Type element) where T : Attribute
  22. => (T)GetCustomAttribute(element, typeof(T));
  23. public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType)
  24. => Attribute.GetCustomAttribute(element, attributeType);
  25. public static Attribute GetCustomAttribute(this ConstructorInfo element, Type attributeType)
  26. => Attribute.GetCustomAttribute(element, attributeType);
  27. public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType)
  28. => Attribute.GetCustomAttribute(element, attributeType);
  29. public static Attribute GetCustomAttribute(this Type element, Type attributeType)
  30. => Attribute.GetCustomAttribute(element, attributeType);
  31. public static StringBuilder Clear(this StringBuilder sb)
  32. => sb.Remove(0, sb.Length);
  33. public static bool HasFlag<E>(this E e, E o) where E : Enum
  34. {
  35. var ei = Convert.ToUInt64(e);
  36. var oi = Convert.ToUInt64(o);
  37. return (ei & oi) == oi;
  38. }
  39. }
  40. public static class DirectoryInfoExtensions
  41. {
  42. public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self)
  43. {
  44. return self.EnumerateFiles("*", SearchOption.TopDirectoryOnly);
  45. }
  46. public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern)
  47. {
  48. return self.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
  49. }
  50. public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo self, string searchPattern, SearchOption searchOption)
  51. {
  52. if (searchPattern == null)
  53. {
  54. throw new ArgumentNullException(nameof(searchPattern));
  55. }
  56. return CreateEnumerateFilesIterator(self, searchPattern, searchOption);
  57. }
  58. private static IEnumerable<FileInfo> CreateEnumerateFilesIterator(DirectoryInfo self, string searchPattern, SearchOption searchOption)
  59. {
  60. foreach (string fileName in Directory.GetFiles(self.FullName, searchPattern, searchOption))
  61. yield return new FileInfo(fileName);
  62. yield break;
  63. }
  64. }
  65. public static class StreamExtensions
  66. {
  67. [ComVisible(false)]
  68. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  69. public static Task CopyToAsync(this Stream src, Stream destination) => CopyToAsync(src, destination, 81920);
  70. [ComVisible(false)]
  71. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  72. public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize) => CopyToAsync(src, destination, bufferSize, CancellationToken.None);
  73. [ComVisible(false)]
  74. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  75. public static Task CopyToAsync(this Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken)
  76. {
  77. if (destination == null)
  78. {
  79. throw new ArgumentNullException(nameof(destination));
  80. }
  81. if (bufferSize <= 0)
  82. {
  83. throw new ArgumentOutOfRangeException(nameof(bufferSize), "Positive number required.");
  84. }
  85. if (!src.CanRead && !src.CanWrite)
  86. {
  87. throw new ObjectDisposedException(null, "Cannot access a closed Stream.");
  88. }
  89. if (!destination.CanRead && !destination.CanWrite)
  90. {
  91. throw new ObjectDisposedException("destination", "Cannot access a closed Stream.");
  92. }
  93. if (!src.CanRead)
  94. {
  95. throw new NotSupportedException("Stream does not support reading.");
  96. }
  97. if (!destination.CanWrite)
  98. {
  99. throw new NotSupportedException("Stream does not support writing.");
  100. }
  101. return CopyToAsyncInternal(src, destination, bufferSize, cancellationToken);
  102. }
  103. private static async Task CopyToAsyncInternal(Stream src, Stream destination, int bufferSize, CancellationToken cancellationToken)
  104. {
  105. byte[] buffer = new byte[bufferSize];
  106. int bytesRead;
  107. while ((bytesRead = await src.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) != 0)
  108. {
  109. await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken);
  110. }
  111. }
  112. [ComVisible(false)]
  113. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  114. public static Task<int> ReadAsync(this Stream src, byte[] buffer, int offset, int count)
  115. {
  116. return ReadAsync(src, buffer, offset, count, CancellationToken.None);
  117. }
  118. [ComVisible(false)]
  119. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  120. public static Task<int> ReadAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
  121. {
  122. if (!cancellationToken.IsCancellationRequested)
  123. {
  124. return BeginEndReadAsync(src, buffer, offset, count);
  125. }
  126. return new Task<int>(() => 0, cancellationToken);
  127. }
  128. private static Task<int> BeginEndReadAsync(Stream src, byte[] buffer, int offset, int count)
  129. => Task<int>.Factory.FromAsync(
  130. (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) =>
  131. src.BeginRead(buffer_, offset_, count_, callback, state),
  132. (IAsyncResult asyncResult) => src.EndRead(asyncResult),
  133. buffer,
  134. offset,
  135. count,
  136. new object());
  137. [ComVisible(false)]
  138. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  139. public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count)
  140. {
  141. return WriteAsync(src, buffer, offset, count, CancellationToken.None);
  142. }
  143. [ComVisible(false)]
  144. [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
  145. public static Task WriteAsync(this Stream src, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
  146. {
  147. if (!cancellationToken.IsCancellationRequested)
  148. {
  149. return BeginEndWriteAsync(src, buffer, offset, count);
  150. }
  151. return new Task<int>(() => 0, cancellationToken);
  152. }
  153. private static Task BeginEndWriteAsync(Stream src, byte[] buffer, int offset, int count)
  154. => Task.Factory.FromAsync(
  155. (byte[] buffer_, int offset_, int count_, AsyncCallback callback, object state) =>
  156. src.BeginWrite(buffer_, offset_, count_, callback, state),
  157. (IAsyncResult asyncResult) => src.EndWrite(asyncResult),
  158. buffer,
  159. offset,
  160. count,
  161. new object());
  162. }
  163. public static class SemaphoreSlimExtesnions
  164. { // TODO: finish the WaitAsync members
  165. /*public static Task WaitAsync(this SemaphoreSlim self)
  166. {
  167. return null;
  168. }*/
  169. }
  170. }