Streams.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO
  6. {
  7. public static class Streams
  8. {
  9. private const int BufferSize = 4096;
  10. public static void Drain(Stream inStr)
  11. {
  12. inStr.CopyTo(Stream.Null, BufferSize);
  13. }
  14. /// <summary>Write the full contents of inStr to the destination stream outStr.</summary>
  15. /// <param name="inStr">Source stream.</param>
  16. /// <param name="outStr">Destination stream.</param>
  17. /// <exception cref="IOException">In case of IO failure.</exception>
  18. public static void PipeAll(Stream inStr, Stream outStr)
  19. {
  20. inStr.CopyTo(outStr, BufferSize);
  21. }
  22. /// <summary>Write the full contents of inStr to the destination stream outStr.</summary>
  23. /// <param name="inStr">Source stream.</param>
  24. /// <param name="outStr">Destination stream.</param>
  25. /// <param name="bufferSize">The size of temporary buffer to use.</param>
  26. /// <exception cref="IOException">In case of IO failure.</exception>
  27. public static void PipeAll(Stream inStr, Stream outStr, int bufferSize)
  28. {
  29. inStr.CopyTo(outStr, bufferSize);
  30. }
  31. /// <summary>
  32. /// Pipe all bytes from <c>inStr</c> to <c>outStr</c>, throwing <c>StreamFlowException</c> if greater
  33. /// than <c>limit</c> bytes in <c>inStr</c>.
  34. /// </summary>
  35. /// <param name="inStr">
  36. /// A <see cref="Stream"/>
  37. /// </param>
  38. /// <param name="limit">
  39. /// A <see cref="System.Int64"/>
  40. /// </param>
  41. /// <param name="outStr">
  42. /// A <see cref="Stream"/>
  43. /// </param>
  44. /// <returns>The number of bytes actually transferred, if not greater than <c>limit</c></returns>
  45. /// <exception cref="IOException"></exception>
  46. public static long PipeAllLimited(Stream inStr, long limit, Stream outStr)
  47. {
  48. var limited = new LimitedInputStream(inStr, limit);
  49. limited.CopyTo(outStr, BufferSize);
  50. return limit - limited.CurrentLimit;
  51. }
  52. public static byte[] ReadAll(Stream inStr)
  53. {
  54. MemoryStream buf = new MemoryStream();
  55. PipeAll(inStr, buf);
  56. return buf.ToArray();
  57. }
  58. public static byte[] ReadAll(MemoryStream inStr)
  59. {
  60. return inStr.ToArray();
  61. }
  62. public static byte[] ReadAllLimited(Stream inStr, int limit)
  63. {
  64. MemoryStream buf = new MemoryStream();
  65. PipeAllLimited(inStr, limit, buf);
  66. return buf.ToArray();
  67. }
  68. public static int ReadFully(Stream inStr, byte[] buf)
  69. {
  70. return ReadFully(inStr, buf, 0, buf.Length);
  71. }
  72. public static int ReadFully(Stream inStr, byte[] buf, int off, int len)
  73. {
  74. int totalRead = 0;
  75. while (totalRead < len)
  76. {
  77. int numRead = inStr.Read(buf, off + totalRead, len - totalRead);
  78. if (numRead < 1)
  79. break;
  80. totalRead += numRead;
  81. }
  82. return totalRead;
  83. }
  84. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  85. public static int ReadFully(Stream inStr, Span<byte> buffer)
  86. {
  87. int totalRead = 0;
  88. while (totalRead < buffer.Length)
  89. {
  90. int numRead = inStr.Read(buffer[totalRead..]);
  91. if (numRead < 1)
  92. break;
  93. totalRead += numRead;
  94. }
  95. return totalRead;
  96. }
  97. #endif
  98. public static void ValidateBufferArguments(byte[] buffer, int offset, int count)
  99. {
  100. if (buffer == null)
  101. throw new ArgumentNullException("buffer");
  102. int available = buffer.Length - offset;
  103. if ((offset | available) < 0)
  104. throw new ArgumentOutOfRangeException("offset");
  105. int remaining = available - count;
  106. if ((count | remaining) < 0)
  107. throw new ArgumentOutOfRangeException("count");
  108. }
  109. /// <exception cref="IOException"></exception>
  110. public static int WriteBufTo(MemoryStream buf, byte[] output, int offset)
  111. {
  112. #if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  113. if (buf.TryGetBuffer(out var buffer))
  114. {
  115. buffer.CopyTo(output, offset);
  116. return buffer.Count;
  117. }
  118. #endif
  119. int size = Convert.ToInt32(buf.Length);
  120. buf.WriteTo(new MemoryStream(output, offset, size));
  121. return size;
  122. }
  123. }
  124. }
  125. #pragma warning restore
  126. #endif