BufferSegmentStream.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Threading;
  5. using Best.HTTP.Shared.PlatformSupport.Memory;
  6. namespace Best.HTTP.Shared.Streams
  7. {
  8. public class BufferSegmentStream : Stream
  9. {
  10. public override bool CanRead { get { return true; } }
  11. public override bool CanSeek { get { return false; } }
  12. public override bool CanWrite { get { return false; } }
  13. public override long Length { get { return this._length; } }
  14. protected long _length;
  15. public override long Position { get { return 0; } set { } }
  16. protected List<BufferSegment> bufferList = new List<BufferSegment>();
  17. private byte[] _tempByteArray = new byte[1];
  18. public override int ReadByte()
  19. {
  20. if (Read(this._tempByteArray, 0, 1) == 0)
  21. return -1;
  22. return this._tempByteArray[0];
  23. }
  24. public override int Read(byte[] buffer, int offset, int count)
  25. {
  26. int sumReadCount = 0;
  27. while (count > 0 && bufferList.Count > 0)
  28. {
  29. BufferSegment buff = this.bufferList[0];
  30. int readCount = Math.Min(count, buff.Count);
  31. Array.Copy(buff.Data, buff.Offset, buffer, offset, readCount);
  32. sumReadCount += readCount;
  33. offset += readCount;
  34. count -= readCount;
  35. this.bufferList[0] = buff = buff.Slice(buff.Offset + readCount);
  36. if (buff.Count == 0)
  37. {
  38. this.bufferList.RemoveAt(0);
  39. BufferPool.Release(buff.Data);
  40. }
  41. }
  42. Interlocked.Add(ref this._length, -sumReadCount);
  43. return sumReadCount;
  44. }
  45. public override void Write(byte[] buffer, int offset, int count) => Write(new BufferSegment(buffer, offset, count));
  46. public virtual void Write(BufferSegment bufferSegment)
  47. {
  48. this.bufferList.Add(bufferSegment);
  49. Interlocked.Add(ref this._length, bufferSegment.Count);
  50. }
  51. public virtual void Reset()
  52. {
  53. BufferPool.ReleaseBulk(this.bufferList);
  54. this.bufferList.Clear();
  55. Interlocked.Exchange(ref this._length, 0);
  56. }
  57. protected override void Dispose(bool disposing)
  58. {
  59. base.Dispose(disposing);
  60. Reset();
  61. }
  62. public override void Flush() { }
  63. public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
  64. public override void SetLength(long value) => throw new NotImplementedException();
  65. }
  66. }