StreamExtension.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace WarcViewerBlazorWinForm.Backend.IO
  7. {
  8. internal static class StreamExtension
  9. {
  10. public static void SeekForwardStupid(this Stream stream, long bytes)
  11. {
  12. if (stream == null) throw new ArgumentNullException(nameof(stream));
  13. if (bytes < 0) throw new ArgumentOutOfRangeException(nameof(bytes));
  14. if (bytes == 0) return;
  15. if (stream.CanSeek)
  16. {
  17. var newPosition = stream.Position + bytes;
  18. if (newPosition < 0 || newPosition > stream.Length) throw new ArgumentOutOfRangeException(nameof(bytes), "Attempted to move the stream pointer beyond its limits.");
  19. stream.Seek(bytes, SeekOrigin.Current);
  20. }
  21. else
  22. {
  23. var buffer = new byte[4096];
  24. var remainingBytes = bytes;
  25. while (remainingBytes > 0)
  26. {
  27. var bytesRead = stream.Read(buffer, 0, (int)Math.Min(buffer.Length, remainingBytes));
  28. // Reached the end of the stream
  29. if (bytesRead == 0) throw new EndOfStreamException("Attempted to move the stream pointer beyond its limits.");
  30. remainingBytes -= bytesRead;
  31. }
  32. }
  33. }
  34. public static long GetLengthStupid(this Stream stream, int readAndDiscardBufferSize = 4096)
  35. {
  36. if (stream == null)
  37. {
  38. throw new ArgumentNullException(nameof(stream));
  39. }
  40. try
  41. {
  42. return stream.Length;
  43. }
  44. catch (NotSupportedException)
  45. {
  46. // Ignore if getting length is not supported
  47. }
  48. try
  49. {
  50. if (stream.Position != 0) throw new InvalidOperationException("The stream position must be 0 when getting length.");
  51. }
  52. catch (NotSupportedException)
  53. {
  54. // Ignore if getting position is not supported
  55. }
  56. var buf = new byte[readAndDiscardBufferSize];
  57. var totalRead = 0;
  58. do
  59. {
  60. var read = stream.Read(buf, 0, readAndDiscardBufferSize);
  61. if (read == 0) break;
  62. totalRead += read;
  63. } while (true);
  64. return totalRead;
  65. }
  66. }
  67. }